diff --git a/uppsrc/DropGrid/DropGrid.cpp b/uppsrc/DropGrid/DropGrid.cpp index eeedc57e5..4d163222b 100644 --- a/uppsrc/DropGrid/DropGrid.cpp +++ b/uppsrc/DropGrid/DropGrid.cpp @@ -73,19 +73,19 @@ DropGrid::DropGrid() rowid = -1; trowid = -2; notnull = false; - format_columns = true; + display_columns = true; drop_enter = false; data_action = false; Searching(true); - always_drop = true; must_change = false; null_action = true; display = this; change = false; nodrop = false; clear_button = false; + + must_change_str = t_("Select a value."); - EnableDrop(always_drop); clear.SetButton(1); clear <<= THISBACK(DoClearValue); } @@ -191,7 +191,7 @@ void DropGrid::Paint(Draw& w) } else clear.Hide(); - + w.DrawRect(sz, SColorPaper()); GridDisplay &disp = display ? *display : list.GetDisplay(); bool hf = HasFocus(); @@ -221,7 +221,7 @@ void DropGrid::LeftDown(Point p, dword keyflags) if(nodrop) SetFocus(); else - Drop(); + Drop(); } void DropGrid::GotFocus() @@ -247,7 +247,7 @@ bool DropGrid::Accept() return false; if(must_change && !change) { - Exclamation(t_("Select a value.")); + Exclamation(must_change_str); SetWantFocus(); return false; } @@ -259,6 +259,17 @@ Size DropGrid::GetMinSize() const return drop.GetMinSize(); } +void DropGrid::State(int reason) +{ + if(reason == ENABLE) + { + bool b = IsEnabled(); + for(int i = 0; i < drop.GetButtonCount(); i++) + drop.GetButton(i).Enable(b); + } + Ctrl::State(reason); +} + void DropGrid::Paint0(Draw &w, int lm, int rm, int x, int y, int cx, int cy, const Value &val, dword style, Color &fg, Color &bg, Font &fnt, bool found, int fs, int fe) { w.DrawRect(x, y, cx, cy, bg); @@ -278,7 +289,10 @@ void DropGrid::Paint0(Draw &w, int lm, int rm, int x, int y, int cx, int cy, con Size isz = GridImg::Dots2().GetSize(); for(int i = 0; i < cnt; i++) { - fnt.Bold((i + 1) & 1); + bool iscol = (i + 1) & 1; + if(!display_columns && iscol) + continue; + fnt.Bold(iscol); Size tsz = GetTextSize(v[i], fnt); DrawText(w, nx, x + lm + tcx, ny, tcx + tsz.cx > ncx - isz.cx ? ncx - tcx: tsz.cx + isz.cx, cy, @@ -298,13 +312,13 @@ void DropGrid::Paint(Draw &w, int x, int y, int cx, int cy, const Value &val, dw DropGrid& DropGrid::Width(int w) { - list_width = w; + list_width = Ctrl::VertLayoutZoom(w); return *this; } DropGrid& DropGrid::Height(int h) { - list_height = h; + list_height = Ctrl::VertLayoutZoom(h); return *this; } @@ -396,9 +410,9 @@ DropGrid& DropGrid::SetDisplay(GridDisplay &d) return *this; } -DropGrid& DropGrid::FormatColumns(bool b /* = true*/) +DropGrid& DropGrid::DisplayColumns(bool b /* = true*/) { - format_columns = b; + display_columns = b; return *this; } @@ -421,16 +435,11 @@ DropGrid& DropGrid::Searching(bool b /* = true*/) return *this; } -DropGrid& DropGrid::AlwaysDrop(bool b /* = true*/) -{ - always_drop = b; - EnableDrop(); - return *this; -} - -DropGrid& DropGrid::MustChange(bool b /* = true*/) +DropGrid& DropGrid::MustChange(bool b /* = true*/, const char* s /* = NULL*/) { must_change = b; + if(s) + must_change_str = s; return *this; } @@ -447,7 +456,7 @@ DropGrid& DropGrid::ClearButton(bool b /* = true*/) Ctrl::Add(clear); else Ctrl::RemoveChild(&clear); - + return *this; } @@ -498,6 +507,14 @@ Vector DropGrid::FindVector(const Value& v) const return MakeVector(r); } +bool DropGrid::FindMove(const Value& v) +{ + int r = list.Find(v, key_col); + if(r >= 0) + list.Move(r); + return r >= 0; +} + Value DropGrid::GetKey() const { return rowid >= 0 ? list.Get(key_col) : Null; @@ -533,8 +550,9 @@ void DropGrid::DoAction(int row, bool action, bool chg) change = chg; rowid = rid; trowid = -2; + Update(); if(action) - UpdateAction(); + Action(); } } @@ -561,31 +579,34 @@ GridCtrl::ItemRect& DropGrid::AddIndex(Id id) MultiButton::SubButton& DropGrid::AddButton(int type, const Callback &cb) { MultiButton::SubButton& btn = drop.InsertButton(1); - + + Image img; switch(type) { case BTN_PLUS: - btn.SetImage(GridImg::SelPlus); + img = GridImg::SelPlus; break; case BTN_SELECT: - btn.SetImage(GridImg::SelDots); + img = GridImg::SelDots; break; case BTN_LEFT: - btn.SetImage(GridImg::SelLeft); + img = GridImg::SelLeft; break; case BTN_RIGHT: - btn.SetImage(GridImg::SelRight); + img = GridImg::SelRight; break; case BTN_UP: - btn.SetImage(GridImg::SelUp); + img = GridImg::SelUp; break; case BTN_DOWN: - btn.SetImage(GridImg::SelDn); + img = GridImg::SelDn; break; case BTN_CLEAN: - btn.SetImage(GridImg::SelCross); + img = GridImg::SelCross; break; } + btn.SetImage(img); + btn.SetMonoImage(Grayscale(img)); btn.WhenPush = cb; return btn; } @@ -647,14 +668,17 @@ void DropGrid::Reset() list.Reset(); ClearValue(); value_cols.Clear(); - EnableDrop(always_drop); } void DropGrid::Clear() { list.Clear(); ClearValue(); - EnableDrop(always_drop); +} + +void DropGrid::Ready(bool b /* = true*/) +{ + list.Ready(b); } Value DropGrid::Get(int c) const @@ -702,11 +726,14 @@ void DropGrid::Set(int r, const Vector &v, int data_offset, int column_of list.Set(r, v, data_offset, column_offset); } -void DropGrid::Add(const Vector &v, int data_offset, int column_offset) +void DropGrid::Add(const Vector &v, int offset, int count, bool hidden) { - list.AddRow(); - list.Set(v, data_offset, column_offset); - EnableDrop(always_drop); + list.Add(v, offset, count, hidden); +} + +String DropGrid::GetString(Id id) +{ + return list.GetString(id); } Value& DropGrid::operator() (int r, int c) @@ -778,7 +805,7 @@ void DropGrid::Change(int dir) else c = list.GetCursor() + dir; - if(list.IsValidCursor(c)) + if(list.IsValidCursor(c) && list.IsRowClickable(c)) { list.SetCursor(c); UpdateValue(); @@ -904,6 +931,11 @@ bool DropGrid::IsInit() return !change; } +void DropGrid::ClearChange() +{ + change = false; +} + Vector DropGrid::MakeVector(int r) const { Vector v; @@ -972,16 +1004,8 @@ Value DropGrid::Format(const Value& q) const return Format0(q, -1); } -void DropGrid::EnableDrop(bool b) -{ - if(IsEnabled() == b) - return; - Enable(b); -} - GridCtrl::ItemRect& DropGrid::AddRow(int n, int size) { - EnableDrop(always_drop); return list.AddRow(n, size); } @@ -994,7 +1018,6 @@ DropGrid& DropGrid::AddSeparator(Color c) #define E__Addv0(I) list.Set(q, I - 1, p##I) #define E__AddF0(I) \ DropGrid& DropGrid::Add(__List##I(E__Value)) { \ - EnableDrop(true); \ int q = AddColumns(I); \ __List##I(E__Addv0); \ return *this; \ @@ -1004,7 +1027,6 @@ __Expand(E__AddF0) #define E__Addv1(I) list.Set(q, I - 1, p##I) #define E__AddF1(I) \ GridCtrl::ItemRect& DropGrid::AddRow(__List##I(E__Value)) { \ - EnableDrop(true); \ int q = AddColumns(I); \ GridCtrl::ItemRect& ir = list.AddRow(); \ __List##I(E__Addv1); \ diff --git a/uppsrc/DropGrid/DropGrid.h b/uppsrc/DropGrid/DropGrid.h index afc4f5722..66132b151 100644 --- a/uppsrc/DropGrid/DropGrid.h +++ b/uppsrc/DropGrid/DropGrid.h @@ -52,7 +52,7 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl GridButton clear; private: - + int rowid; int trowid; Value value; @@ -66,17 +66,18 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl bool header:1; bool valuekey:1; bool notnull:1; - bool format_columns:1; + bool display_columns:1; bool drop_enter:1; bool data_action:1; bool searching:1; - bool always_drop:1; bool must_change:1; bool null_action:1; bool clear_button:1; bool nodrop:1; GridDisplay *display; + + String must_change_str; void Change(int dir); void SearchCursor(); @@ -85,7 +86,6 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl Value MakeValue(int r = -1, bool columns = true) const; void UpdateValue(); Value Format0(const Value& q, int rowid) const; - void EnableDrop(bool b = true); public: @@ -113,12 +113,11 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl DropGrid& NotNull(bool b = true); DropGrid& ValueAsKey(bool b = true); DropGrid& SetDisplay(GridDisplay &d); - DropGrid& FormatColumns(bool b = true); + DropGrid& DisplayColumns(bool b = true); DropGrid& DropEnter(bool b = true); DropGrid& DataAction(bool b = true); DropGrid& Searching(bool b = true); - DropGrid& AlwaysDrop(bool b = true); - DropGrid& MustChange(bool b = true); + DropGrid& MustChange(bool b = true, const char* s = NULL); DropGrid& NullAction(bool b = true); DropGrid& ClearButton(bool b = true); DropGrid& NoDrop(bool b = true); @@ -134,9 +133,8 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl MultiButton::SubButton& AddEdit(const Callback &cb); MultiButton::SubButton& AddClear(); MultiButton::SubButton& AddText(const char* label, const Callback& cb); - MultiButton::SubButton& GetButton(int n); - + int AddColumns(int cnt); void GoTop(); @@ -148,6 +146,7 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl void Reset(); void Clear(); + void Ready(bool b = true); void ClearValue(); void DoClearValue(); @@ -158,6 +157,7 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl Value GetValue(int r) const; Value FindValue(const Value& v) const; Vector FindVector(const Value& v) const; + bool FindMove(const Value& v); Value GetKey() const; virtual bool Key(dword k, int); @@ -168,6 +168,7 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl virtual void Serialize(Stream& s); virtual bool Accept(); virtual Size GetMinSize() const; + virtual void State(int reason); void Paint0(Draw &w, int lm, int rm, int x, int y, int cx, int cy, const Value &val, dword style, Color &fg, Color &bg, Font &fnt, bool found = false, int fs = 0, int fe = 0); virtual void Paint(Draw &w, int x, int y, int cx, int cy, const Value &val, dword style, Color &fg, Color &bg, Font &fnt, bool found = false, int fs = 0, int fe = 0); @@ -181,7 +182,8 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl void Set(int r, int c, const Value& v); void Set(int r, Id id, const Value& v); void Set(int r, const Vector &v, int data_offset = 0, int column_offset = 0); - void Add(const Vector &v, int data_offset = 0, int column_offset = 0); + void Add(const Vector &v, int offset = 0, int count = -1, bool hidden = false); + String GetString(Id id); Value& operator() (int r, int c); Value& operator() (int c); @@ -194,6 +196,8 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl bool IsEmpty(); bool IsChange(); bool IsInit(); + + void ClearChange(); int Find(const Value& v, int col = 0, int opt = 0); int Find(const Value& v, Id id, int opt = 0); @@ -204,7 +208,7 @@ class DropGrid : public Convert, public GridDisplay, public Ctrl GridCtrl& GetList() { return list; } virtual Value Format(const Value& q) const; - + Callback WhenLeftDown; GridCtrl::ItemRect& AddRow(int n = 1, int size = GridCtrl::GD_ROW_HEIGHT); diff --git a/uppsrc/DropGrid/DropGrid.upp b/uppsrc/DropGrid/DropGrid.upp index 9bfd221a6..aae745006 100644 --- a/uppsrc/DropGrid/DropGrid.upp +++ b/uppsrc/DropGrid/DropGrid.upp @@ -12,3 +12,4 @@ file mainconfig "" = "GUI"; + diff --git a/uppsrc/DropGrid/main.cpp b/uppsrc/DropGrid/main.cpp index 9d8eac0e1..a21b86a56 100644 --- a/uppsrc/DropGrid/main.cpp +++ b/uppsrc/DropGrid/main.cpp @@ -13,7 +13,7 @@ struct App : public TopWindow Sizeable().Zoomable(); SetRect(Size(600, 100)); Title("DropGrid"); - + drop.ClearButton(); drop.AddPlus(THISBACK(Action)); @@ -22,11 +22,11 @@ struct App : public TopWindow drop.AddColumn("ID"); drop.AddColumn("Value"); drop.AddColumn("Description"); - + drop.AddText("Add person", THISBACK(Action)); drop.AddText("Add client", THISBACK(Action)).Left().SetImage(GridImg::Append()); drop.AddSelect(THISBACK(Action)).Left(); - + for(int i = 0; i < 20; i++) drop.Add(i, Format("Hello %d", i), Format("How are you mr Hello %d", i)); @@ -41,7 +41,7 @@ struct App : public TopWindow void Action() { } - + typedef App CLASSNAME; }; diff --git a/uppsrc/GridCtrl/GridBase.cpp b/uppsrc/GridCtrl/GridBase.cpp index 08463566f..beb9ed069 100644 --- a/uppsrc/GridCtrl/GridBase.cpp +++ b/uppsrc/GridCtrl/GridBase.cpp @@ -124,10 +124,17 @@ GridCtrl::ItemRect& GridCtrl::ItemRect::Edit(Ctrl &ctrl) return *this; } -//GridCtrl::ItemRect& GridCtrl::ItemRect::EditConvert(Ctrl &ctrl) -//{ -// return Edit(ctrl).SetConvert(ctrl); -//} +GridCtrl::ItemRect& GridCtrl::ItemRect::EditInsert(bool b /* = true*/) +{ + edit_insert = b; + return *this; +} + +GridCtrl::ItemRect& GridCtrl::ItemRect::EditUpdate(bool b /* = true*/) +{ + edit_update = b; + return *this; +} void GridCtrl::ItemRect::ChangeSortMode(bool idsort) { diff --git a/uppsrc/GridCtrl/GridCtrl.cpp b/uppsrc/GridCtrl/GridCtrl.cpp index e55d55146..1d7b992ba 100644 --- a/uppsrc/GridCtrl/GridCtrl.cpp +++ b/uppsrc/GridCtrl/GridCtrl.cpp @@ -157,6 +157,7 @@ GridCtrl::GridCtrl() : holder(*this) full_col_resizing = true; full_row_resizing = false; chameleon = false; + summary_row = false; mouse_move = false; row_modified = 0; @@ -222,8 +223,8 @@ GridCtrl::GridCtrl() : holder(*this) join_group = 0; - curSplitCol = -1; - curSplitRow = -1; + curSplitCol = oldSplitCol = -1; + curSplitRow = oldSplitRow = -1; moveCol = moveRow = -1; find_offset = 0; @@ -288,10 +289,10 @@ void GridCtrl::StdToolBar(Bar &bar) bar.Add(c, t_("Insert "), GridImg::Insert(), StdInsert); if(duplicating) - bar.Add(d, t_("Duplicate"), GridImg::Duplicate(), StdDuplicate); + bar.Add(d && !ctrls, t_("Duplicate"), GridImg::Duplicate(), StdDuplicate); if(removing) - bar.Add(d, t_("Delete "), GridImg::Delete(), StdRemove); + bar.Add(d/* && !IsNewRow()*/, t_("Delete "), GridImg::Delete(), StdRemove); if(editing) { @@ -699,7 +700,7 @@ void GridCtrl::SetClipboard(bool all, bool silent) Color c0 = bg_select; Color c1 = White; Color c2 = bg_focus; - + for(int i = 0; i < 256; i += 64) { bg_select = Blend(c0, c1, i); @@ -707,7 +708,7 @@ void GridCtrl::SetClipboard(bool all, bool silent) Refresh(); Sync(); Sleep(1); } - + for(int i = 0; i < 256; i += 32) { bg_select = Blend(c1, c0, i); @@ -763,7 +764,7 @@ void GridCtrl::Paste(int mode) Vector lines; if(is_tc && !is_gc) - lines = Upp::Split(ReadClipboardText(), '\n'); + lines = Upp::Split(FromUnicode(ReadClipboardUnicodeText()), '\n'); if(mode == 1) { @@ -788,7 +789,7 @@ void GridCtrl::Paste(int mode) for(int i = 0; i < lines.GetCount(); i++) { - Vector cells = Upp::Split(lines[i], '\t'); + Vector cells = Upp::Split(lines[i], '\t', false); for(int j = 0; j < cells.GetCount(); j++) { int r = i; @@ -811,7 +812,11 @@ void GridCtrl::Paste(int mode) if(fixed_paste && new_row) break; - Set0(lr, lc, cells[j], true); + + String& s = cells[j]; +// WhenPasteCell(i, j, s); + + Set0(lr, lc, s, true); } if(i == lines.GetCount() - 1 && j == cells.GetCount() - 1) @@ -993,13 +998,13 @@ void GridCtrl::Paint(Draw &w) Size sz = GetSize(); Rect rc = Rect(sz); //w.GetClip() - it always returns view rect now. bug?? - + if(!ready) { w.DrawRect(rc, SColorPaper); return; } - + int i, j, cx, cy, x, y; bool skip; Rect r; @@ -1039,7 +1044,7 @@ void GridCtrl::Paint(Draw &w) w.End(); } - r.Set(fixed_width, 0, sz.cx, fixed_height); + r.Set(fixed_width, 0, sz.cx, summary_row ? sz.cy : fixed_height); LG("painting %d, tc %d", (int)w.IsPainting(r), total_cols); LG("%d, %d, %d, %d", r.left, r.top, r.right, r.bottom); @@ -1059,7 +1064,9 @@ void GridCtrl::Paint(Draw &w) { for(j = jfc; j < total_cols; j++) { - if(hitems[j].hidden) + ItemRect& hi = hitems[j]; + + if(hi.hidden) continue; int jj = j; @@ -1074,20 +1081,45 @@ void GridCtrl::Paint(Draw &w) { GridDisplay * gd = it.display ? it.display : display; - dword style = hitems[j].style | hitems[j].halign; + dword style = hi.style | hi.halign; if(i > 0) style &= ~GD::HIGHLIGHT; if(chameleon) style |= GD::CHAMELEON; - gd->SetLeftImage(hitems[j].img); + gd->SetLeftImage(hi.img); gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, - i == 0 ? it.val : GetConvertedColumn(hitems[j].id, it.val), + i == 0 ? it.val : GetConvertedColumn(hi.id, it.val), style | en, stdfont, false, false, - i == 0 ? hitems[j].sortmode : 0, - hitems[j].sortcol, + i == 0 ? hi.sortmode : 0, + hi.sortcol, sortOrder.GetCount(), true); } + + if(summary_row && i == 0) + { + cy = GD_HDR_HEIGHT; + y = sz.cy - cy; + if(w.IsPainting(x, y, cx, cy)) + { + Item &it = summary[hi.id]; + GridDisplay * gd = it.display ? it.display : display; + + dword style = hi.halign; + if(chameleon) + style |= GD::CHAMELEON; + + String s; + if(hi.sop != SOP_NONE && !hi.sopfrm.IsEmpty() && !IsNull(it.val)) + s = Format(hi.sopfrm, it.val); + s = IsString(it.val) ? it.val : StdConvert().Format(it.val); + gd->SetLeftImage(Null); + gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, s, + style | en, stdfont, false, false, 0, -1, 0, true); + + } + } + } } if(rx < sz.cx || chameleon) @@ -1120,7 +1152,7 @@ void GridCtrl::Paint(Draw &w) y = vitems[total_rows - 1].nBottom(sby); if(y < sz.cy) - w.DrawRect(Rect(0, y, fixed_width, sz.cy), SColorPaper); + w.DrawRect(Rect(0, y, fixed_width, sz.cy - summary_height), SColorPaper); for(i = 0; i < fixed_cols; i++) { @@ -1154,8 +1186,31 @@ void GridCtrl::Paint(Draw &w) GetConvertedColumn(id, it.val), style | en, stdfont, indicator, false, 0, -1, 0, false); - } + } } + + if(summary_row) + { + j = 0; + Item &it = GetItemSize(j, i, x, y, cx, cy, skip, false, true); + cy = GD_HDR_HEIGHT; + y = sz.cy - cy; + if(w.IsPainting(x, y, cx, cy)) + { + Item& it = summary[hitems[i].id]; + GridDisplay * gd = it.display ? it.display : display; + + dword style = vitems[j].style; + if(chameleon) + style |= GD::CHAMELEON; + + gd->PaintFixed(w, firstx, true, x, y, cx, cy, + GetConvertedColumn(id, it.val), + style | en, stdfont, + false, false, 0, -1, 0, false); + + } + } } w.End(); @@ -1163,7 +1218,7 @@ void GridCtrl::Paint(Draw &w) //--------------------------------------------------------------------------------------- - r.Set(fixed_width, fixed_height, sz.cx, sz.cy); + r.Set(fixed_width, fixed_height, sz.cx, sz.cy - summary_height); if(can_paint && w.IsPainting(r)) { @@ -1183,8 +1238,7 @@ void GridCtrl::Paint(Draw &w) } */ - bool hasfocus = HasFocusDeep(); - + bool hasfocus = HasFocus/*Deep*/() || holder.HasFocusDeep(); for(i = max(firstRow, fixed_rows); i < total_rows; i++) { @@ -1341,6 +1395,9 @@ void GridCtrl::Paint(Draw &w) gd->Paint(w, x, y, cx, cy, val, style | en, fg, bg, fnt, it.style & GD::FOUND, it.fs, it.fe); + + it.rcx = gd->real_size.cx; + it.rcy = gd->real_size.cy; if(vert_grid) { @@ -1452,6 +1509,12 @@ String GridCtrl::GetStdConvertedColumn(int col, const Value &v) const return IsString(val) ? val : StdConvert().Format(val); } +String GridCtrl::GetString(Id id) const +{ + int c = aliases.Get(id); + return GetStdConvertedColumn(c, Get0(rowidx, c)); +} + GridCtrl::ItemRect& GridCtrl::InsertColumn(int pos, const char *name, int size, bool idx) { return hitems[0]; @@ -1498,8 +1561,9 @@ GridCtrl::ItemRect& GridCtrl::AddColumn(const char *name, int size, bool idx) vitems[0].size = vitems[0].nsize = 0; vitems[0].hidden = true; } - + edits.Add(); + summary.Add(); String lname(name); aliases.Add(ToLower(lname), ib.id); @@ -1573,7 +1637,7 @@ void GridCtrl::SetColCount(int n, int size) void GridCtrl::MouseMove(Point p, dword keyflags) { - //LG("MouseMove"); + LG("MouseMove"); mouse_move = true; if(resizing) @@ -1692,6 +1756,7 @@ void GridCtrl::MouseMove(Point p, dword keyflags) else SetCursor0(-1, -1, false, true); } + if(HasCapture()) { if(!moving_body) @@ -1783,6 +1848,43 @@ void GridCtrl::MouseMove(Point p, dword keyflags) } } } + else if(!IsPopUp()) + { + int c = GetMouseCol(p); + int r = GetMouseRow(p); + + bool new_cell = false; + + if(r != oldSplitRow) + { + oldSplitRow = r; + new_cell = true; + } + if(c != oldSplitCol) + { + oldSplitCol = c; + new_cell = true; + } + + if(c >= 0 && r >= 0) + { + Item& it = GetItem(r, c); + if(it.rcx > 0 || it.rcy > 0) + { + popup.text = GetStdConvertedColumn(c, it.val); + Point p = GetMousePos(); + Point p0 = GetMouseViewPos(); + int x = hitems[c].npos + p.x - p0.x - 1 - sbx.Get(); + int y = vitems[r].npos + p.y - p0.y - 1 - sby.Get(); + popup.PopUp(this, x, y, max(it.rcx + 10, hitems[c].nsize + 1), max(it.rcy + 10, vitems[r].nsize + 1)); + popup.Refresh(); + } + else + popup.Close(); + } + else + popup.Close(); + } } void GridCtrl::LeftDown(Point p, dword keyflags) @@ -1856,8 +1958,17 @@ void GridCtrl::LeftDown(Point p, dword keyflags) if(select) { - shiftpos = curpos; - SelectRange(curpos, curpos, !vitems[curpos.y].IsSelect(), select_row); + if(IsValidCursor(oldcur) && selected_items == 0 && cs.IsNew()) + { + shiftpos = oldcur; + SelectRange(oldcur, select_row ? oldcur : curpos, true, select_row); + SelectRange(curpos, curpos, !vitems[curpos.y].IsSelect(), select_row); + } + else + { + shiftpos = curpos; + SelectRange(curpos, curpos, !vitems[curpos.y].IsSelect(), select_row); + } selecting = true; } } @@ -1950,7 +2061,7 @@ void GridCtrl::LeftUp(Point p, dword keyflags) sortOrder.Remove(colidx); cnt--; } - + if(WhenSort) WhenSort(); else @@ -1988,7 +2099,7 @@ void GridCtrl::LeftUp(Point p, dword keyflags) sortCol = newSortCol; sortOrder.Clear(); - + if(WhenSort) WhenSort(); else @@ -2070,6 +2181,7 @@ void GridCtrl::RightDown(Point p, dword keyflags) //UpdateCtrls(UC_HIDE | UC_CTRLS); } + RebuildToolBar(); SetFocus(); //jak nie bedzie menu to fokous zostanie na danym wierszu MenuBar::Execute(WhenMenuBar); } @@ -2084,6 +2196,7 @@ void GridCtrl::Init() UpdateSizes(); UpdateSb(); UpdateHolder(true); + SyncSummary(); SyncCtrls(); } @@ -2230,7 +2343,7 @@ Rect& GridCtrl::AlignRect(Rect &r, int i) { if(align & GD::HCENTER) { - int d = (r.Width() - sx) / 2; + int d = (r.Width() - sx - 1) / 2; r.left += d; r.right -= d; } @@ -2255,7 +2368,7 @@ Rect& GridCtrl::AlignRect(Rect &r, int i) { if(align & GD::VCENTER) { - int d = (r.Height() - sy) / 2; + int d = (r.Height() - sy - 1) / 2; r.top += d; r.bottom -= d; } @@ -2316,7 +2429,7 @@ void GridCtrl::Scroll() } if(delta.cy != 0) { - ScrollView(Rect(0, fixed_height, fixed_width, sz.cy), 0, delta.cy); + ScrollView(Rect(0, fixed_height, fixed_width, sz.cy - summary_height), 0, delta.cy); } } if(live_cursor) @@ -2363,6 +2476,8 @@ void GridCtrl::Set0(int r, int c, const Value &val, bool paste) if(r > total_rows - 1) AddRow(r - total_rows + 1); + vitems[r].operation = GridOperation::UPDATE; + int ri = vitems[r].id; Item &it = items[ri][c]; @@ -2416,6 +2531,7 @@ void GridCtrl::Set(Id id, const Value &val) void GridCtrl::Set(int r, const Vector &v, int data_offset /* = 0*/, int column_offset /* = 0*/) { r += fixed_rows; + vitems[r].operation = GridOperation::UPDATE; int cnt = min(v.GetCount(), total_cols - fixed_cols); int r0 = vitems[r].id; int c = fixed_cols + column_offset; @@ -2572,6 +2688,28 @@ Value& GridCtrl::operator() (int r, const char * alias) return items[vitems[r + fixed_rows].id][aliases.Get(alias)].val; } +void GridCtrl::SetSummary(int c, const Value& val) +{ + summary[c].val = val; + RefreshSummary(); +} + +void GridCtrl::SetSummary(Id id, const Value& val) +{ + summary[aliases.Get(id)].val = val; + RefreshSummary(); +} + +Value GridCtrl::GetSummary(int c) +{ + return summary[c + fixed_cols].val; +} + +Value GridCtrl::GetSummary(Id id) +{ + return summary[aliases.Get(id)].val; +} + bool GridCtrl::IsModified(int r, int c) { return items[vitems[r + fixed_rows].id][c + fixed_cols].modified; @@ -2601,9 +2739,9 @@ Vector GridCtrl::ReadRow(int n) const return v; } -GridCtrl& GridCtrl::Add(const Vector &v, int offset, int count) +GridCtrl& GridCtrl::Add(const Vector &v, int offset, int count, bool hidden) { - Append0(1, GD_ROW_HEIGHT); + Append0(1, hidden ? 0 : GD_ROW_HEIGHT); int cnt = min(count < 0 ? v.GetCount() : count, total_cols - fixed_cols); @@ -2684,6 +2822,9 @@ int GridCtrl::GetMouseCol(Point &p, bool relative, bool fixed, bool full) int first_col = fixed ? 0 : max(firstVisCol, fixed_cols); int last_col = max(lastVisCol, fixed_cols - 1); + if(!fixed && last_col >= total_cols) + return -1; + for(int i = first_col; i <= last_col; i++) { if(p.x >= hitems[i].nLeft(dx) && @@ -2705,6 +2846,9 @@ int GridCtrl::GetMouseRow(Point &p, bool relative, bool fixed, bool full) int first_row = fixed ? 0 : max(firstVisRow, fixed_rows); int last_row = max(lastVisRow, fixed_rows - 1); + + if(!fixed && last_row >= total_rows) + return -1; for(int i = first_row; i <= last_row; i++) { @@ -2823,7 +2967,7 @@ void GridCtrl::UpdateHolder(bool force) if(fixed_size_changed || force) { holder.SetOffset(Point(fixed_width, fixed_height)); - holder.HSizePos(fixed_width, 0).VSizePos(fixed_height, 0); + holder.HSizePos(fixed_width, 0).VSizePos(fixed_height, summary_height); fixed_size_changed = false; } } @@ -2838,7 +2982,7 @@ GridCtrl::CurState GridCtrl::SetCursor0(Point p, bool mouse, bool highlight, int CurState cs; if(!row_changing) return cs; - + WhenCursor(); if(cancel_cursor) { @@ -2912,15 +3056,15 @@ GridCtrl::CurState GridCtrl::SetCursor0(Point p, bool mouse, bool highlight, int int idy = vitems[tmpcur.y].id; Item &it = items[idy][idx]; - + newvalid = it.clickable; - if(newvalid && ctrlmode) + if(newvalid && ctrlmode) { Ctrl * ctrl = it.ctrl; if(!ctrl && ctrls) ctrl = edits[idx].ctrl; - + if(ctrl && it.editable && ctrl->IsEnabled()) break; } @@ -3336,7 +3480,7 @@ void GridCtrl::CalcIntPos(RectItems &its, int n, int maxsize, int cnt, int resiz if(renumber) its[i].n = hidden; - + if(its[i].hidden) hidden++; else @@ -3357,6 +3501,8 @@ bool GridCtrl::UpdateSizes() { total_width = total_cols ? hitems[total_cols - 1].nRight() : 0; total_height = total_rows ? vitems[total_rows - 1].nRight() : 0; + + summary_height = summary_row ? GD_HDR_HEIGHT : 0; int new_fixed_width = fixed_cols ? hitems[fixed_cols - 1].nRight() : 0; int new_fixed_height = fixed_rows ? vitems[fixed_rows - 1].nRight() : 0; @@ -3434,7 +3580,7 @@ bool GridCtrl::Recalc(bool horizontal, RectItems &its, int resize_mode) int tcnt = cnt; its[0].pos = 0; - + if(!horizontal && !header) its[0].size = 0; @@ -3587,7 +3733,7 @@ int GridCtrl::GetSplitRow(const Point &p, int splitSize, bool full) int diff = 0; if(p.y > fixed_height || moving_body || moving_header) { - if(!full && !moving_header && !full_row_resizing && p.x >= fixed_width) + if(!full && !moving_header && !moving_body && !full_row_resizing && p.x >= fixed_width) return -1; diff = sby; } @@ -3657,13 +3803,28 @@ bool GridCtrl::IsValidCursor(int c) const return c >= fixed_rows && c < total_rows; } -bool GridCtrl::IsRowEditable() +bool GridCtrl::IsRowEditable(int r) { - return vitems[curpos.y].editable && + if(r < 0) + r = curpos.y; + else + r += fixed_rows; + + return vitems[r].editable && hitems[curpos.x].editable && (select_row || (!select_row && edits[curid.x].ctrl)); } +bool GridCtrl::IsRowClickable(int r /* = -1*/) +{ + if(r < 0) + r = curpos.y; + else + r += fixed_rows; + + return vitems[r].clickable && hitems[curpos.x].clickable; +} + void GridCtrl::SetItemCursor(Point p, bool b, bool highlight) { if(highlight) @@ -3769,6 +3930,12 @@ void GridCtrl::RefreshLeft() Refresh(0, fixed_height, fixed_width, GetSize().cy - fixed_height); } +void GridCtrl::RefreshSummary() +{ + Size sz = GetSize(); + Refresh(0, sz.cy - GD_HDR_HEIGHT, sz.cx, GD_HDR_HEIGHT); +} + bool GridCtrl::IsMouseBody(Point &p) { return p.x >= fixed_width && p.x < total_width && p.y >= fixed_height && p.y < total_height; @@ -3862,7 +4029,7 @@ int GridCtrl::Find(const Value &v0, Id id0, const Value&v1, Id id1, int opt) con { int col0 = aliases.Get(id0); int col1 = aliases.Get(id1); - + for(int i = fixed_rows; i < total_rows; i++) { if(opt & GF::SKIP_CURRENT_ROW && i == rowidx) @@ -3986,6 +4153,9 @@ bool GridCtrl::GetCtrlsData(bool samerow, bool doall, bool updates) } } } + + if(row_modified) + vitems[curid.y].operation = GridOperation::UPDATE; WhenAcceptRow(); if(cancel_accept) @@ -4006,7 +4176,6 @@ bool GridCtrl::GetCtrlsData(bool samerow, bool doall, bool updates) } else if(row_modified) { - vitems[curid.y].operation = GridOperation::UPDATE; row_data = true; SetModify(); @@ -4132,6 +4301,20 @@ void GridCtrl::UpdateCtrls(int opt /*= UC_CHECK_VIS | UC_SHOW | UC_CURSOR | UC_F continue; Ctrl * ctrl = GetCtrl(cp.y, i, show == false); + + if(show) + { + if(newrow_appended || newrow_inserted) + { + if(!hitems[i].edit_insert) + continue; + } + else + { + if(!hitems[i].edit_update) + continue; + } + } if(!ctrl) continue; @@ -4290,6 +4473,76 @@ void GridCtrl::SyncCtrls(int row) sync_flag = 1 - sync_flag; } +void GridCtrl::SyncSummary() +{ + if(WhenUpdateSummary) + { + WhenUpdateSummary(); + } + else + { + for(int i = fixed_cols; i < total_cols; i++) + { + Value t; + + int idx = hitems[i].id; + + int sop = hitems[i].sop; + + if(sop == SOP_NONE) + continue; + + if(sop == SOP_CNT) + { + t = total_rows - fixed_rows; + } + else + { + int n = 0; + for(int j = fixed_rows; j < total_rows; j++) + { + int idy = vitems[j].id; + + const Value& v = items[idy][idx].val; + + if(IsNull(v)) + continue; + + ++n; + + if(j == fixed_rows) + t = v; + + if(IsNumber(v)) + { + switch(sop) + { + case SOP_MIN: + if(double(v) < double(t)) + t = v; + break; + case SOP_MAX: + if(double(v) > double(t)) + t = v; + break; + case SOP_SUM: + case SOP_AVG: + t = double(t) + double(v); + } + } + } + if(sop == SOP_AVG) + t = double(t) / double(n); + } + + summary[idx].val = t; + } + } + + if(summary_row) + RefreshSummary(); +} + bool GridCtrl::HasCtrls() { return edit_ctrls || genr_ctrls; @@ -4434,6 +4687,9 @@ void GridCtrl::Split(int state, bool sync) bool GridCtrl::TabKey(bool enter_mode) { + if(!HasFocus() && !holder.HasFocusDeep()) + return false; + bool has_ctrls = HasCtrls(); if(has_ctrls) @@ -4688,6 +4944,9 @@ bool GridCtrl::Key(dword key, int) return true; } return false; + case K_CTRL_W: + //WriteClipboardText(GetColumnWidths()); + return true; default: if(searching && !ctrls && Search(key)) return true; @@ -5099,14 +5358,14 @@ void GridCtrl::Clear(bool columns) UpdateSizes(); UpdateSb(); - + if(ready) { UpdateHolder(); - + oldpos.x = sbx; oldpos.y = sby; - + RebuildToolBar(); Refresh(); } @@ -5119,6 +5378,18 @@ void GridCtrl::Reset() Clear(true); } +void GridCtrl::ClearOperations() +{ + for(int i = fixed_rows; i < total_rows; i++) + vitems[i].operation.Clear(); +} + +void GridCtrl::ClearVersions() +{ + for(int i = fixed_rows; i < total_rows; i++) + vitems[i].operation.ClearVersion(); +} + void GridCtrl::Begin() { bkp_rowidx = rowidx; @@ -5151,6 +5422,11 @@ void GridCtrl::Prev() --rowidx; } +void GridCtrl::Move(int r) +{ + rowidx = r + fixed_rows; +} + bool GridCtrl::IsNext() { return rowidx < total_rows - 1; @@ -5359,7 +5635,7 @@ bool GridCtrl::Go0(int jump, bool scroll, bool goleft, bool ctrlmode) if(goleft) GoCursorLeftRight(); else - sy = total_height - fixed_height; + sy = total_height - fixed_height - summary_height; break; } @@ -5371,7 +5647,7 @@ bool GridCtrl::Go0(int jump, bool scroll, bool goleft, bool ctrlmode) return false; int b = vitems[curpos.y].nBottom(sby); - int r = sz.cy; + int r = sz.cy - summary_height; if(b > r) sy = sby + b - r; @@ -5750,7 +6026,7 @@ void GridCtrl::UpdateSb(bool horz, bool vert) if(vert) { - sby.SetTotal(resize_row_mode == 0 ? total_height - fixed_height : 0); + sby.SetTotal(resize_row_mode == 0 ? total_height - fixed_height + summary_height: 0); sby.SetPage(GetSize().cy - fixed_height); } } @@ -5773,9 +6049,9 @@ bool GridCtrl::StartEdit(bool mouse) return false; ctrls = true; - + WhenStartEdit(); - + SetCtrlsData(); int opt = UC_SHOW | UC_FOCUS | UC_GOFIRST | UC_CURSOR | UC_CTRLS; if(mouse) @@ -5809,6 +6085,7 @@ bool GridCtrl::EndEdit(bool accept, bool doall, bool remove_row) } } WhenEndEdit(); + SyncSummary(); return true; } @@ -5858,6 +6135,7 @@ void GridCtrl::Insert0(int row, int cnt /* = 1*/, bool recalc /* = true*/, bool if(refresh) { UpdateSb(); + SyncSummary(); SyncCtrls(); RefreshFrom(row); } @@ -5882,12 +6160,16 @@ bool GridCtrl::Remove0(int row, int cnt /* = 1*/, bool recalc /* = true*/, bool int rid = row + i; rowidx = remove_hides ? rid : row; + if(vitems[rowidx].locked) + continue; + int id = vitems[rowidx].id; int op = vitems[rowidx].operation; + vitems[rowidx].operation = GridOperation::REMOVE; + if(remove_hides) { - vitems[rowidx].operation = GridOperation::REMOVE; vitems[rowidx].hidden = true; vitems[rowidx].tsize = vitems[rowidx].size; vitems[rowidx].size = 0; @@ -5977,6 +6259,7 @@ bool GridCtrl::Remove0(int row, int cnt /* = 1*/, bool recalc /* = true*/, bool if(refresh) { UpdateSb(); + SyncSummary(); SyncCtrls(); RefreshFrom(row); @@ -6040,6 +6323,7 @@ int GridCtrl::Append0(int cnt, int size, bool refresh) if(resize_row_mode > 0) UpdateRows(true); UpdateSb(); + SyncSummary(); SyncCtrls(); RefreshFrom(k); } @@ -6099,6 +6383,7 @@ void GridCtrl::Duplicate0(int row, int cnt, bool recalc, bool refresh) if(refresh) { UpdateSb(); + SyncSummary(); SyncCtrls(); RefreshFrom(nrow); } @@ -6482,7 +6767,7 @@ void GridCtrl::DoDuplicate0() WhenDuplicateRow(); if(cy > 0) - SetCursor0(curpos.x < 0 ? firstVisCol : curpos.x, max(fixed_rows, min(total_rows - 1, cy))); + SetCursor0(curpos.x < 0 ? firstVisCol : curpos.x, max(fixed_rows, min(total_rows - 1, cy))); } void GridCtrl::DoRemove() @@ -6495,7 +6780,7 @@ void GridCtrl::DoRemove() if(ask_remove) { - if(!PromptYesNo(Format(t_("Do you really want to delete selected %s ?"), selected_rows > 0 ? t_("rows") : t_("row")))) + if(!PromptYesNo(Format(t_("Do you really want to delete selected %s ?"), selected_rows > 1 ? t_("rows") : t_("row")))) return; } @@ -6627,6 +6912,9 @@ GridCtrl& GridCtrl::ShowRow(int n, bool refresh) GridCtrl& GridCtrl::HideRow(int n, bool refresh) { + if(n < 0) + n = rowidx; + if(vitems[n].hidden) return *this; vitems[n].hidden = true; @@ -7135,7 +7423,7 @@ void GridPopUp::PopUp(Ctrl *owner, int x, int y, int width, int height) SetRect(Rect(x, y, x + width, y + height)); if(open) return; - Ctrl::PopUp(owner, true, true, GUI_DropShadows()); + Ctrl::PopUp(owner, true, false, GUI_DropShadows()); SetAlpha(230); open = true; } @@ -7198,7 +7486,7 @@ void GridCtrl::UpdateHighlighting(int mode, Point p) RefreshRow(0, 0, 1); } -#ifdef GRIDSQL +#ifdef flagGRIDSQL void GridCtrl::FieldLayout(FieldOperator& f) { for(int i = 1; i < total_cols; i++) @@ -7224,6 +7512,25 @@ SqlSet GridCtrl::GetColumnList(bool skip_hidden) const return s; } +String GridCtrl::GetColumnWidths() +{ + String s; + for(int i = fixed_cols; i < total_cols; i++) + { + s += AsString(hitems[i].nsize); + if(i < total_cols - 1) + s += " "; + } + return s; +} + +void GridCtrl::ColumnWidths(const char* s) +{ + Vector w = UPP::Split(s, ' '); + for(int i = 0; i < min(w.GetCount(), GetColumnCount()); i++) + hitems[i + fixed_cols].Width(atoi(w[i])); +} + #endif @@ -7300,7 +7607,7 @@ void GridButton::Paint(Draw& w) &GridImg::Btn0N, &GridImg::Btn0H, &GridImg::Btn0P, &GridImg::Btn1N, &GridImg::Btn1H, &GridImg::Btn1P }; - + Size sz = GetSize(); w.DrawImage(0, 0, sz.cx, sz.cy, vimg[img + n * 3]); } diff --git a/uppsrc/GridCtrl/GridCtrl.h b/uppsrc/GridCtrl/GridCtrl.h index 8f4a5446b..41d4120a0 100644 --- a/uppsrc/GridCtrl/GridCtrl.h +++ b/uppsrc/GridCtrl/GridCtrl.h @@ -1,8 +1,7 @@ #ifndef _GridCtrl_GridCtrl_h_ #define _GridCtrl_GridCtrl_h_ -//#define GRIDSQL #include -#ifdef GRIDSQL +#ifdef flagGRIDSQL #include #endif @@ -69,7 +68,7 @@ class GridButton : public Ctrl private: int img; int n; - + public: typedef GridButton CLASSNAME; GridButton(); @@ -133,28 +132,31 @@ class GridOperation private: int operation; + int version; public: - GridOperation() : operation(NONE) {} + GridOperation() : operation(NONE), version(1) {} void SetOperation(int op) { switch(operation) { - case NONE: operation = op; break; + case NONE: operation = op; ++version; break; case UPDATE: if(op == REMOVE || op == NONE) - op = NONE; + Clear(); break; case INSERT: if(op == REMOVE || op == NONE) - operation = NONE; + Clear(); break; } } - void Clear() { operation = NONE; } + void Clear() { operation = NONE; } + void ClearVersion() { version = 0; } + int GetVersion() { return version; } GridOperation& operator=(const int op) { @@ -165,7 +167,6 @@ class GridOperation operator int() { return operation; } bool operator!=(int op) { return operation != op; } bool operator==(int op) { return operation == op; } - }; @@ -178,6 +179,7 @@ class CtrlsHolder : public Ctrl CtrlsHolder(Ctrl &p) : parent(p) { Transparent(); + WantFocus(false); } virtual void LeftUp(Point p, dword flags) { parent.LeftUp(p + offset, flags); } virtual void LeftDown(Point p, dword flags) { parent.LeftDown(p + offset, flags); } @@ -255,7 +257,7 @@ class GridCtrl : public Ctrl private: - enum + enum GridCursor { GO_PREV, GO_NEXT, @@ -267,7 +269,7 @@ class GridCtrl : public Ctrl GO_PAGEDN }; - enum + enum GridControlState { UC_SHOW = BIT(0), UC_HIDE = BIT(1), @@ -283,6 +285,16 @@ class GridCtrl : public Ctrl UC_UPDATES = BIT(11), UC_OLDCUR = BIT(12) }; + + enum GridSummaryOperation + { + SOP_NONE = 0, + SOP_MIN = 1, + SOP_MAX = 2, + SOP_SUM = 3, + SOP_CNT = 4, + SOP_AVG = 5, + }; enum GridState { @@ -352,6 +364,9 @@ class GridCtrl : public Ctrl cy = 0; group = -1; isjoined = false; + + rcx = 0; + rcy = 0; modified = false; sync_flag = -1; @@ -378,6 +393,7 @@ class GridCtrl : public Ctrl bool IsJoined() { return isjoined; } int idx, idy, cx, cy, group; + int rcx, rcy; bool isjoined:1; int fs, fe; dword style; @@ -397,6 +413,7 @@ class GridCtrl : public Ctrl public: Value val; + //String cache; Item& Editable(bool b); Item& NoEditable(); @@ -409,7 +426,7 @@ class GridCtrl : public Ctrl typedef Vector< Vector > Items; typedef Vector< Edit > Edits; - class ItemRect : public Moveable + public: class ItemRect : public Moveable { friend class GridCtrl; @@ -427,8 +444,11 @@ class GridCtrl : public Ctrl index = false; convertion = true; editable = true; + edit_insert = true; + edit_update = true; sortable = true; clickable = true; + locked = false; skip = false; ignore_display = false; style = 0; @@ -454,6 +474,7 @@ class GridCtrl : public Ctrl found = false; level = 0; + sop = SOP_NONE; operation = GridOperation::NONE; } @@ -470,8 +491,8 @@ class GridCtrl : public Ctrl Convert *convert; GridDisplay *display; - Callback1&> factory; - + Callback1&> factory; + static VectorMap *aliases; double pos, size, prop; @@ -482,6 +503,9 @@ class GridCtrl : public Ctrl double tsize; int join; + + int sop; + String sopfrm; bool hidden; bool index; @@ -489,8 +513,11 @@ class GridCtrl : public Ctrl bool editable; bool sortable; bool clickable; + bool locked; bool found:1; bool skip:1; + bool edit_insert:1; + bool edit_update:1; Value defval; @@ -587,6 +614,8 @@ class GridCtrl : public Ctrl ItemRect& EditConvert(T &ctrl) { return Edit(ctrl).SetConvert(ctrl); } template ItemRect& EditConvertDisplay(T &ctrl) { return Edit(ctrl).SetConvert(ctrl).SetDisplay(ctrl); } + ItemRect& EditInsert(bool b = true); + ItemRect& EditUpdate(bool b = true); ItemRect& SetConvert(Convert &c); ItemRect& NoConvert(); ItemRect& SetFormat(const char *fmt); @@ -662,8 +691,17 @@ class GridCtrl : public Ctrl ItemRect& Clickable(bool b) { clickable = b; return *this; } ItemRect& NoClickable() { clickable = false; return *this; } + + ItemRect& Locked(bool b) { locked = b; return *this; } + ItemRect& NoLocked(bool b) { locked = false; return *this; } ItemRect& Skip(bool b) { skip = b; return *this; } + + ItemRect& DoAvg(const char *s = NULL) { sop = SOP_AVG; sopfrm = s; return *this; } + ItemRect& DoSum(const char *s = NULL) { sop = SOP_SUM; sopfrm = s; return *this; } + ItemRect& DoMin(const char *s = NULL) { sop = SOP_MIN; sopfrm = s; return *this; } + ItemRect& DoMax(const char *s = NULL) { sop = SOP_MAX; sopfrm = s; return *this; } + ItemRect& DoCount(const char *s = NULL) { sop = SOP_CNT; sopfrm = s; return *this; } int GetId() { return id; } int GetNumber() { return id - parent->fixed_cols; } @@ -688,7 +726,8 @@ class GridCtrl : public Ctrl Items items; HItems hitems; VItems vitems; - + + Vector summary; Vector rowbkp; VectorMap aliases; @@ -774,6 +813,7 @@ class GridCtrl : public Ctrl bool full_row_resizing:1; bool chameleon:1; + bool summary_row:1; bool search_hide:1; bool search_highlight:1; @@ -848,6 +888,9 @@ class GridCtrl : public Ctrl int fixed_cols, fixed_rows; int total_width, total_height; int fixed_width, fixed_height; + int summary_height; + + int oldSplitCol, oldSplitRow; int selected_rows; int selected_items; @@ -906,11 +949,11 @@ class GridCtrl : public Ctrl GridPopUpHeader pophdr; - int sortCol; + int sortCol; Vector sortOrder; public: - + struct SortOrder : Moveable { int id; @@ -1019,6 +1062,7 @@ class GridCtrl : public Ctrl GridCtrl& FullColResizing(bool b = true) { full_col_resizing = b; return *this; } GridCtrl& FullRowResizing(bool b = true) { full_row_resizing = b; return *this; } GridCtrl& Chameleon(bool b = true) { chameleon = b; return *this; } + GridCtrl& SummaryRow(bool b = true) { summary_row = b; return *this; } GridCtrl& SearchOffset(int offset) { find_offset = offset; return *this; } GridCtrl& SearchMoveCursor(bool b = true) { search_move_cursor = b; return *this; } @@ -1118,7 +1162,7 @@ class GridCtrl : public Ctrl ItemRect& GetRow(); Item& GetCell(int n, int m); Item& GetCell(int n, Id id); - + bool IsColumn(const Id& id); int GetCurrentRow() const; @@ -1161,6 +1205,10 @@ class GridCtrl : public Ctrl Value& operator() (int r, Id id); Value& operator() (const char * alias); Value& operator() (int r, const char * alias); + void SetSummary(int c, const Value& val); + void SetSummary(Id id, const Value& val); + Value GetSummary(int c); + Value GetSummary(Id id); using Ctrl::IsModified; @@ -1180,10 +1228,12 @@ class GridCtrl : public Ctrl bool IsUpdatedRow() { return vitems[rowidx].operation == GridOperation::UPDATE; } bool IsInsertedRow() { return vitems[rowidx].operation == GridOperation::INSERT; } bool IsRemovedRow() { return vitems[rowidx].operation == GridOperation::REMOVE; } + bool IsChangedRow() { return IsUpdatedRow() || IsInsertedRow(); } + bool IsVersionedRow() { return vitems[rowidx].operation.GetVersion() > 0; } int GetRowOperation() { return vitems[rowidx].operation; } Vector ReadRow(int n = -1) const; - GridCtrl& Add(const Vector &v, int offset = 0, int count = -1); + GridCtrl& Add(const Vector &v, int offset = 0, int count = -1, bool hidden = false); void SetFixedRows(int n = 1); void SetFixedCols(int n = 1); @@ -1199,6 +1249,7 @@ class GridCtrl : public Ctrl void RefreshTop(); void RefreshLeft(); + void RefreshSummary(); void Repaint(bool recalc_cols = false, bool recalc_rows = false); void Ready(bool b); @@ -1243,11 +1294,15 @@ class GridCtrl : public Ctrl void ClearRow(int r = -1, int column_offset = 0); void Clear(bool columns = false); void Reset(); + + void ClearOperations(); + void ClearVersions(); void Begin(); void Next(); void Prev(); void End(); + void Move(int r); bool IsEnd(); bool IsFirst(); @@ -1329,7 +1384,7 @@ class GridCtrl : public Ctrl bool IsSelected(int n, bool relative = true); bool IsSelected(int n, int m, bool relative = true); bool IsSelected(); - + void Copy(bool all = false) { SetClipboard(all, true); } void CopyAll() { Copy(true); } @@ -1389,7 +1444,8 @@ class GridCtrl : public Ctrl bool IsDataChanged() { return row_data; } bool IsChanged() { return row_order || row_data; } - bool IsRowEditable(); + bool IsRowEditable(int r = -1); + bool IsRowClickable(int r = -1); void Serialize(Stream &s); @@ -1413,7 +1469,7 @@ class GridCtrl : public Ctrl void ClearSort(); void MarkSort(int col, int sort_mode); void MarkSort(Id id, int sort_mode); - + Vector GetSortOrder() const; Vector GetSortOrderId() const; @@ -1422,6 +1478,7 @@ class GridCtrl : public Ctrl Value GetConvertedColumn(int col, const Value &v) const; String GetStdConvertedColumn(int col, const Value &v) const; + String GetString(Id id) const; bool Search(dword key); int GetResizePanelHeight() const; @@ -1431,7 +1488,9 @@ class GridCtrl : public Ctrl void SetCtrlFocus(int col); void SetCtrlFocus(Id id); - #ifdef GRIDSQL + String GetColumnWidths(); + void ColumnWidths(const char* s); + #ifdef flagGRIDSQL void FieldLayout(FieldOperator& f); operator Fields() { return THISBACK(FieldLayout); } operator SqlSet() const { return GetColumnList(); } @@ -1478,6 +1537,7 @@ class GridCtrl : public Ctrl void SyncCtrls(int r = -1); private: void UpdateCtrls(int opt = UC_CHECK_VIS | UC_SHOW | UC_CURSOR | UC_FOCUS); + void SyncSummary(); void SetCtrlsData(); bool GetCtrlsData(bool samerow = false, bool doall = false, bool updates = true); @@ -1606,6 +1666,8 @@ class GridCtrl : public Ctrl Callback WhenCancelNewRow; Callback WhenUpdateCell; + + Callback WhenUpdateSummary; Callback WhenNewRow; Callback WhenChangeCol; @@ -1624,8 +1686,10 @@ class GridCtrl : public Ctrl Callback StdRemove; Callback StdDuplicate; Callback StdEdit; - + Callback WhenSort; + + Callback3 WhenPasteCell; }; class GridText : Ctrl diff --git a/uppsrc/GridCtrl/GridDisplay.cpp b/uppsrc/GridCtrl/GridDisplay.cpp index 8d3eb1881..8001ba61e 100644 --- a/uppsrc/GridCtrl/GridDisplay.cpp +++ b/uppsrc/GridCtrl/GridDisplay.cpp @@ -73,18 +73,18 @@ void GridDisplay::Paint(Draw &w, int x, int y, int cx, int cy, const Value &val, if(!leftImg.IsEmpty()) { Size isz = leftImg.GetSize(); - w.DrawImage(nx, ny + (cy - isz.cy) / 2, leftImg); + w.DrawImage(nx, ny + (cy - isz.cy) / 2, style & GD::READONLY ? Grayscale(leftImg) : leftImg); nx += isz.cx + 3; } if(!rightImg.IsEmpty()) { Size isz = rightImg.GetSize(); - w.DrawImage(nx + ncx - isz.cx, y + (cy - isz.cy) / 2, rightImg); + w.DrawImage(nx + ncx - isz.cx, y + (cy - isz.cy) / 2, style & GD::READONLY ? Grayscale(rightImg) : rightImg); } if(!centerImg.IsEmpty()) { Size isz = centerImg.GetSize(); - w.DrawImage(x + (cx - isz.cx) / 2, y + (cy - isz.cy) / 2, centerImg); + w.DrawImage(x + (cx - isz.cx) / 2, y + (cy - isz.cy) / 2, style & GD::READONLY ? Grayscale(centerImg) : centerImg); } if(!(style & GD::NOTEXT)) @@ -297,9 +297,13 @@ void GridDisplay::DrawText(Draw &w, int mx, int x, int y, int cx, int cy, int al p = s; } + Size isz = GridImg::Dots2().GetSize(); int gcx = cx - (wrap ? 0 : isz.cx); + real_size.cx = 0; + real_size.cy = lines > 1 ? lines * tcy : 0; + while(true) { bool nextline = *p == '\n'; @@ -359,6 +363,8 @@ void GridDisplay::DrawText(Draw &w, int mx, int x, int y, int cx, int cy, int al bool dots = !wrap && tsz.cx > gcx; if(dots) { + real_size.cx = max(real_size.cx, tsz.cx); + w.Clip(x, y, cx, cy); w.DrawImage(x + cx - isz.cx, ty + font.Info().GetAscent() - isz.cy, GridImg::Dots2, tfg); w.End(); diff --git a/uppsrc/GridCtrl/GridDisplay.h b/uppsrc/GridCtrl/GridDisplay.h index be24d9441..d3e811982 100644 --- a/uppsrc/GridCtrl/GridDisplay.h +++ b/uppsrc/GridCtrl/GridDisplay.h @@ -19,6 +19,7 @@ namespace GD FOCUS = BIT(3), READONLY = BIT(4), FOUND = BIT(5), + MARKED = CURSOR | SELECT | LIVE | READONLY | FOUND, HIGHLIGHT = BIT(6), EVEN = BIT(7), ODD = BIT(8), @@ -61,6 +62,8 @@ class GridDisplay { SetDefault(); } + + Size real_size; void SetDefault(); diff --git a/uppsrc/GridCtrl/GridSort.cpp b/uppsrc/GridCtrl/GridSort.cpp index 778c892dc..2a9f8391e 100644 --- a/uppsrc/GridCtrl/GridSort.cpp +++ b/uppsrc/GridCtrl/GridSort.cpp @@ -152,7 +152,7 @@ void GridCtrl::MarkSort(int col, int sort_mode, bool refresh) sortCol = col; hitems[col].sortmode = sort_mode; hitems[col].sortcol = sortOrder.GetCount(); - + if(refresh) RefreshTop(); } @@ -178,7 +178,7 @@ GridCtrl& GridCtrl::Sort(int sort_col, int sort_mode, bool multisort, bool repai sortOrder.Clear(); ClearSorted(); } - + sortOrder.Add(col); MarkSort(col, sort_mode, false); diff --git a/uppsrc/GridCtrl/GridUtils.h b/uppsrc/GridCtrl/GridUtils.h index 84fcd4608..5302aea61 100644 --- a/uppsrc/GridCtrl/GridUtils.h +++ b/uppsrc/GridCtrl/GridUtils.h @@ -40,11 +40,11 @@ inline int32 Round(double a) } #ifdef flagDEBUG -#define LG //LogCon +#define LG LogGui #else #define LG #endif -#define LGR //LogCon +#define LGR LogGui extern LineEdit *dlog; extern DropList *dlev; diff --git a/uppsrc/GridCtrl/changelog.txt b/uppsrc/GridCtrl/changelog.txt index 02b2225ce..93fb6d5f4 100644 --- a/uppsrc/GridCtrl/changelog.txt +++ b/uppsrc/GridCtrl/changelog.txt @@ -257,7 +257,7 @@ + added Get*Align() to ItemRect after 2008.1beta2 - + - hiding/showing columns works again in proportional mode (R) - align value from AttrText was inproperly passed to cell style + added Header(bool) - to turn on/off the header @@ -266,3 +266,17 @@ + added GetSortOrderId and GetSortOrder - fixed Clear(false) and highlighting -> now it dosn't clear hcol + added Copy and CopyAll + + after 2008.1rc1/rc2 + + * first click with ctrl selects previous row too now + + added WhenSort callback which is called every time sort action takes place + + MarkSort() + + Resort(); + + after 2008.1final + + + summary row + - toolbar wasn't rebuilded after right mouse click on row + + \ No newline at end of file