From 6226345236dcecf4bc7785c02bd813289fd7685f Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 30 Sep 2011 10:30:00 +0000 Subject: [PATCH] CtrlLib: ArrayCtrl::AsText, SetClipboard, AsQtf, AsCsv git-svn-id: svn://ultimatepp.org/upp/trunk@3933 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Util.cpp | 16 +++++ uppsrc/Core/Util.h | 2 + uppsrc/CtrlLib/ArrayCtrl.cpp | 69 +++++++++++++++++++++- uppsrc/CtrlLib/ArrayCtrl.h | 11 +++- uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp | 53 +++++++++++++++++ uppsrc/RichText/EncodeQtf.cpp | 16 ++--- uppsrc/RichText/RichText.h | 2 + uppsrc/ide/Debuggers/Gdb.lay | 16 ++--- 8 files changed, 165 insertions(+), 20 deletions(-) diff --git a/uppsrc/Core/Util.cpp b/uppsrc/Core/Util.cpp index 43d6529bc..af72cace1 100644 --- a/uppsrc/Core/Util.cpp +++ b/uppsrc/Core/Util.cpp @@ -635,6 +635,22 @@ String NormalizeSpaces(const char *s, const char *end) return r; } +String CsvString(const String& text) +{ + String r; + r << '\"'; + const char *s = text; + while(*s) { + if(*s == '\"') + r << "\"\""; + else + r.Cat(*s); + s++; + } + r << '\"'; + return r; +} + int ChNoInvalid(int c) { return c == DEFAULTCHAR ? '_' : c; diff --git a/uppsrc/Core/Util.h b/uppsrc/Core/Util.h index 786cc427a..291d298cb 100644 --- a/uppsrc/Core/Util.h +++ b/uppsrc/Core/Util.h @@ -107,6 +107,8 @@ int MemICmp(const void *dest, const void *src, int count); String NormalizeSpaces(const char *s); String NormalizeSpaces(const char *begin, const char *end); +String CsvString(const String& text); + #ifndef PLATFORM_WIN32 void Sleep(int msec); #endif diff --git a/uppsrc/CtrlLib/ArrayCtrl.cpp b/uppsrc/CtrlLib/ArrayCtrl.cpp index f90442f04..73e19c627 100644 --- a/uppsrc/CtrlLib/ArrayCtrl.cpp +++ b/uppsrc/CtrlLib/ArrayCtrl.cpp @@ -506,9 +506,9 @@ Value ArrayCtrl::GetColumn(int row, int col) const { return vm; } -Value ArrayCtrl::GetConvertedColumn(int i, int col) { +Value ArrayCtrl::GetConvertedColumn(int i, int col) const { LTIMING("GetConvertedColumn"); - Column& m = column[col]; + const Column& m = column[col]; Value v = GetColumn(i, col); if(!m.convert) return v; if(m.cache.Is< Vector >() && i < m.cache.Get< Vector >().GetCount()) { @@ -2706,6 +2706,71 @@ void ArrayCtrl::InsertDrop(int line, PasteClip& d) InsertDrop(line, GetInternal(d), d); } +String ArrayCtrl::AsText(String (*format)(const Value&), bool sel, + const char *tab, const char *row, + const char *hdrtab, const char *hdrrow) const +{ + String txt; + if(hdrtab) { + for(int i = 0; i < GetColumnCount(); i++) { + if(i) + txt << hdrtab; + txt << (*format)(HeaderTab(i).GetText()); + } + if(hdrrow) + txt << hdrrow; + } + bool next = false; + for(int r = 0; r < GetCount(); r++) + if(!sel || IsSel(r)) { + if(next) + txt << row; + for(int i = 0; i < GetColumnCount(); i++) { + if(i) + txt << tab; + txt << (*format)(GetConvertedColumn(r, i)); + } + next = true; + } + return txt; +} + +void ArrayCtrl::SetClipboard(bool sel, bool hdr) const +{ + ClearClipboard(); + AppendClipboardText(AsText(AsString, sel, "\t", "\r\n", hdr ? "\t" : NULL, "\r\n")); +} + +static String sQtfFormat(const Value& v) +{ + return "\1" + AsString(v) + "\1"; +} + +String ArrayCtrl::AsQtf(bool sel, bool hdr) +{ + String qtf; + qtf << "{{"; + for(int i = 0; i < GetColumnCount(); i++) { + if(i) + qtf << ":"; + qtf << header.GetTabWidth(i); + } + if(hdr) + qtf << "@L [*"; + return qtf << ' ' << AsText(sQtfFormat, sel, ":: ", ":: ", hdr ? ":: " : NULL, "::@W ]") << "}}"; +} + +static String sCsvFormat(const Value& v) +{ + return IsNumber(v) ? AsString(v) : CsvString(AsString(v)); +} + +String ArrayCtrl::AsCsv(bool sel, int sep, bool hdr) +{ + char h[2] = { sep, 0 }; + return AsText(sCsvFormat, sel, h, "\r\n", hdr ? h : NULL, "\r\n"); +} + ArrayCtrl::ArrayCtrl() { cursor = -1; Reset(); diff --git a/uppsrc/CtrlLib/ArrayCtrl.h b/uppsrc/CtrlLib/ArrayCtrl.h index 1b4f1a1ae..e8688bab4 100644 --- a/uppsrc/CtrlLib/ArrayCtrl.h +++ b/uppsrc/CtrlLib/ArrayCtrl.h @@ -66,7 +66,7 @@ public: int margin; bool cached; bool clickedit; - Any cache; + mutable Any cache; const ValueOrder *order; int (*cmp)(const Value& a, const Value& b); @@ -408,7 +408,7 @@ public: void Set(Id id, const Value& v); Value GetColumn(int row, int col) const; - Value GetConvertedColumn(int row, int col); + Value GetConvertedColumn(int row, int col) const; int GetSelectCount() const; bool IsSelection() const { return GetSelectCount(); } @@ -555,6 +555,13 @@ public: void ScrollEnd() { sb.End(); } void ScrollBegin() { sb.Begin(); } + String AsText(String (*format)(const Value&), bool sel = false, + const char *tab = "\t", const char *row = "\r\n", + const char *hdrtab = "\t", const char *hdrrow = "\r\n") const; + void SetClipboard(bool sel = false, bool hdr = true) const; + String AsQtf(bool sel = false, bool hdr = true); + String AsCsv(bool sel = false, int sep = ';', bool hdr = true); + String RowFormat(const char *s); ArrayCtrl& RowName(const char *s) { row_name = s; return *this; } diff --git a/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp b/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp index 652cc057e..390e76cc3 100644 --- a/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp +++ b/uppsrc/CtrlLib/src.tpp/ArrayCtrl$en-us.tpp @@ -2104,6 +2104,14 @@ output values.&] [s0; [* Cursor and selection management]&] [s3; &] [s0; &] +[s5;:ArrayCtrl`:`:ScrollUp`(`):%- [@(0.0.255) void]_[* ScrollUp]()&] +[s5;:ArrayCtrl`:`:ScrollDown`(`):%- [@(0.0.255) void]_[* ScrollDown]()&] +[s5;:ArrayCtrl`:`:ScrollPageUp`(`):%- [@(0.0.255) void]_[* ScrollPageUp]()&] +[s5;:ArrayCtrl`:`:ScrollPageDown`(`):%- [@(0.0.255) void]_[* ScrollPageDown]()&] +[s5;:ArrayCtrl`:`:ScrollEnd`(`):%- [@(0.0.255) void]_[* ScrollEnd]()&] +[s5;:ArrayCtrl`:`:ScrollBegin`(`):%- [@(0.0.255) void]_[* ScrollBegin]()&] +[s2; Scrolls the content of ArrayCtrl.&] +[s3; &] [s4;%- &] [s5;:ArrayCtrl`:`:GetSelectCount`(`)const:%- [@(0.0.255) int]_[* GetSelectCount]()_[@(0.0.255) c onst]&] @@ -2411,6 +2419,51 @@ and opened for editation.&] committed, [* false] when not&] [s3; &] [s0; &] +[s0; &] +[s0; [* Content export]&] +[s0;* &] +[s3;%- &] +[s5;:ArrayCtrl`:`:AsText`(String`(`*`)`(const Value`&`)`,bool`,const char`*`,const char`*`,const char`*`,const char`*`)const:%- [_^String^ S +tring]_[* AsText]([_^String^ String]_(`*[*@3 format])([@(0.0.255) const]_Value[@(0.0.255) `& +]), [@(0.0.255) bool]_[*@3 sel]_`=_[@(0.0.255) false], [@(0.0.255) const]_[@(0.0.255) char]_ +`*[*@3 tab]_`=_`"`\t`", [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 row]_`=_`"`\r`\n`", +[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 hdrtab]_`=_`"`\t`", [@(0.0.255) const]_[@(0.0.255) c +har]_`*[*@3 hdrrow]_`=_`"`\r`\n`")_[@(0.0.255) const]&] +[s2; Generic function for conversion of ArrayCtrl content to text. +The content visible on screen is exported (means, it exports +columns defined using AddColumn, not indicies). Cells are converted +to output format using [%-*@3 format] function. If [%-*@3 sel] is +true, only rows with IsSel true are exported. [%-*@3 tab] represents +a separator text between cells in a row, [%-*@3 row] separator +of rows. [%-*@3 hdrtab] is separator of header cells (those are +texts of ArrayCtrl header) `- if NULL, no header is exported. +[%-*@3 hdrrow].is separator of header and data rows.&] +[s3; &] +[s4;%- &] +[s5;:ArrayCtrl`:`:SetClipboard`(bool`,bool`)const:%- [@(0.0.255) void]_[* SetClipboard]([@(0.0.255) b +ool]_[*@3 sel]_`=_[@(0.0.255) false], [@(0.0.255) bool]_[*@3 hdr]_`=_[@(0.0.255) true])_[@(0.0.255) c +onst]&] +[s2; Puts ArrayCtrl content to clipboard in text format, `"`\t`" +and `"`\r`\n`" as separators. If [%-*@3 sel] is true, only rows +with IsSel true are exported, [%-*@3 hdr] controls whether header +is exported.&] +[s3; &] +[s4;%- &] +[s5;:ArrayCtrl`:`:AsQtf`(bool`,bool`):%- [_^String^ String]_[* AsQtf]([@(0.0.255) bool]_[*@3 s +el]_`=_[@(0.0.255) false], [@(0.0.255) bool]_[*@3 hdr]_`=_[@(0.0.255) true])&] +[s2; Returns ArrayCtrl content in QTF format. If [%-*@3 sel] is true, +only rows with IsSel true are exported, [%-*@3 hdr] controls whether +header is exported.&] +[s3; &] +[s4;%- &] +[s5;:ArrayCtrl`:`:AsCsv`(bool`,int`,bool`):%- [_^String^ String]_[* AsCsv]([@(0.0.255) bool +]_[*@3 sel]_`=_[@(0.0.255) false], [@(0.0.255) int]_[*@3 sep]_`=_`';`', +[@(0.0.255) bool]_[*@3 hdr]_`=_[@(0.0.255) true])&] +[s2; Returns ArrayCtrl content in csv format, using [%-*@3 sep] as +separator. If [%-*@3 sel] is true, only rows with IsSel true are +exported, [%-*@3 hdr] controls whether header is exported.&] +[s0; &] +[s0; &] [s0; [* Notification callbacks]&] [s3; &] [s0; &] diff --git a/uppsrc/RichText/EncodeQtf.cpp b/uppsrc/RichText/EncodeQtf.cpp index 0ccf310e3..4df5f07eb 100644 --- a/uppsrc/RichText/EncodeQtf.cpp +++ b/uppsrc/RichText/EncodeQtf.cpp @@ -11,7 +11,7 @@ void SeparateNumber(String& s) s.Cat(';'); } -String FmtColor(Color c) +String QtfFormat(Color c) { if(IsNull(c)) return "N"; for(int i = 0; i < 10; i++) @@ -63,9 +63,9 @@ void CharFmt(String& fmt, const RichPara::CharFormat& a, const RichPara::CharFor if(a.indexentry != b.indexentry) fmt << 'I' << DeQtf(ToUtf8(b.indexentry)) << ';'; if(a.ink != b.ink) - fmt << "@" << FmtColor(b.ink); + fmt << "@" << QtfFormat(b.ink); if(a.paper != b.paper) - fmt << "$" << FmtColor(b.paper); + fmt << "$" << QtfFormat(b.paper); if(a.GetHeight() != b.GetHeight()) { for(int i = 0; i < 10; i++) if(b.GetHeight() == QTFFontHeight[i]) { @@ -96,7 +96,7 @@ void QTFEncodeParaFormat(String& qtf, const RichPara::Format& format, const Rich FmtNumber(qtf, 'i', style.indent, format.indent); FmtNumber(qtf, 'H', style.ruler, format.ruler); if(style.rulerink != format.rulerink) - qtf << "h" << FmtColor(format.rulerink); + qtf << "h" << QtfFormat(format.rulerink); FmtNumber(qtf, 'b', style.before, format.before); FmtNumber(qtf, 'a', style.after, format.after); if(style.newpage != format.newpage) @@ -386,10 +386,10 @@ void QTFEncodeTxt(String& qtf, const RichTxt& text, const RichStyles& styles, co if(f.keep) qtf << "K"; if(f.framecolor != d.framecolor) - qtf << 'F' << FmtColor(f.framecolor); + qtf << 'F' << QtfFormat(f.framecolor); FmtNumber(qtf, 'g', d.grid, f.grid); if(f.gridcolor != d.gridcolor) - qtf << 'G' << FmtColor(f.gridcolor); + qtf << 'G' << QtfFormat(f.gridcolor); FmtNumber(qtf, 'h', d.header, f.header); RichCell::Format cf = Single(); for(int i = 0; i < ny; i++) { @@ -414,9 +414,9 @@ void QTFEncodeTxt(String& qtf, const RichTxt& text, const RichStyles& styles, co FmtNumber2(qtf, 'b', cf.border.bottom, f.border.bottom, cf.margin.bottom, f.margin.bottom); FmtNumber(qtf, 'H', cf.minheight, f.minheight); if(f.color != cf.color) - qtf << '@' << FmtColor(f.color); + qtf << '@' << QtfFormat(f.color); if(f.bordercolor != cf.bordercolor) - qtf << 'R' << FmtColor(f.bordercolor); + qtf << 'R' << QtfFormat(f.bordercolor); cf = f; if(c.hspan) qtf << '-' << c.hspan; diff --git a/uppsrc/RichText/RichText.h b/uppsrc/RichText/RichText.h index 7409c470c..67786da7a 100644 --- a/uppsrc/RichText/RichText.h +++ b/uppsrc/RichText/RichText.h @@ -392,6 +392,8 @@ struct RichCellPos { String DeQtf(const char *s); String DeQtfLf(const char *s); +String QtfFormat(Color c); + struct QtfRichObject { RichObject obj; diff --git a/uppsrc/ide/Debuggers/Gdb.lay b/uppsrc/ide/Debuggers/Gdb.lay index f29edb929..fc204fb05 100644 --- a/uppsrc/ide/Debuggers/Gdb.lay +++ b/uppsrc/ide/Debuggers/Gdb.lay @@ -1,20 +1,20 @@ LAYOUT(RegistersLayout, 224, 88) ITEM(Label, dv___0, SetLabel(t_("EAX")).LeftPosZ(4, 26).TopPosZ(4, 19)) - ITEM(Label, eax, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(33, 72).TopPosZ(4, 19)) + ITEM(Label, eax, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(33, 72).TopPosZ(4, 19)) ITEM(Label, dv___2, SetLabel(t_("EBX")).LeftPosZ(4, 26).TopPosZ(24, 19)) - ITEM(Label, ebx, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(33, 72).TopPosZ(24, 19)) + ITEM(Label, ebx, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(33, 72).TopPosZ(24, 19)) ITEM(Label, dv___4, SetLabel(t_("ECX")).LeftPosZ(4, 26).TopPosZ(44, 19)) - ITEM(Label, ecx, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(33, 72).TopPosZ(44, 19)) + ITEM(Label, ecx, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(33, 72).TopPosZ(44, 19)) ITEM(Label, dv___6, SetLabel(t_("EDX")).LeftPosZ(4, 26).TopPosZ(64, 19)) - ITEM(Label, edx, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(33, 72).TopPosZ(64, 19)) + ITEM(Label, edx, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(33, 72).TopPosZ(64, 19)) ITEM(Label, dv___8, SetLabel(t_("ESI")).LeftPosZ(120, 26).TopPosZ(4, 19)) - ITEM(Label, esi, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(148, 72).TopPosZ(4, 19)) + ITEM(Label, esi, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(148, 72).TopPosZ(4, 19)) ITEM(Label, dv___10, SetLabel(t_("EDI")).LeftPosZ(120, 26).TopPosZ(24, 19)) - ITEM(Label, edi, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(148, 72).TopPosZ(24, 19)) + ITEM(Label, edi, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(148, 72).TopPosZ(24, 19)) ITEM(Label, dv___12, SetLabel(t_("EBP")).LeftPosZ(120, 26).TopPosZ(44, 19)) - ITEM(Label, ebp, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(148, 72).TopPosZ(44, 19)) + ITEM(Label, ebp, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(148, 72).TopPosZ(44, 19)) ITEM(Label, dv___14, SetLabel(t_("ESP")).LeftPosZ(120, 26).TopPosZ(64, 19)) - ITEM(Label, esp, SetLabel(t_("00000000")).SetFont(ScreenFixedZ(11)).LeftPosZ(148, 72).TopPosZ(64, 19)) + ITEM(Label, esp, SetLabel(t_("00000000")).SetFont(MonospaceZ(11)).LeftPosZ(148, 72).TopPosZ(64, 19)) END_LAYOUT LAYOUT(QuickwatchLayout, 400, 200)