1 template <class T>
DefaultCtrlFactoryFn(One<Ctrl> & ctrl)2 void DefaultCtrlFactoryFn(One<Ctrl>& ctrl)
3 {
4 	ctrl.Create<T>();
5 }
6 
7 template <class T>
DefaultCtrlFactory()8 Callback1<One<Ctrl>&> DefaultCtrlFactory()
9 {
10 	return callback(DefaultCtrlFactoryFn<T>);
11 }
12 
13 class ArrayCtrl : public Ctrl {
14 public:
15 	virtual void  CancelMode();
16 	virtual bool  Accept();
17 	virtual void  Reject();
18 	virtual void  Paint(Draw& w);
19 	virtual void  Layout();
20 	virtual bool  Key(dword key, int);
21 	virtual void  LeftDown(Point p, dword);
22 	virtual void  LeftDouble(Point p, dword);
23 	virtual void  LeftDrag(Point p, dword);
24 	virtual void  LeftUp(Point p, dword flags);
25 	virtual void  RightDown(Point p, dword);
26 	virtual void  MouseMove(Point p, dword);
27 	virtual void  MouseLeave();
28 	virtual void  MouseWheel(Point p, int zdelta, dword keyflags);
29 	virtual Image CursorImage(Point p, dword);
30 	virtual void  DragAndDrop(Point p, PasteClip& d);
31 	virtual void  DragRepeat(Point p);
32 	virtual void  DragLeave();
33 	virtual void  GotFocus();
34 	virtual void  LostFocus();
35 	virtual void  ChildGotFocus();
36 	virtual void  ChildLostFocus();
37 	virtual void  Serialize(Stream& s);
38 
39 public:
40 	struct IdInfo {
41 		Value           insertval;
42 		ValueGen       *insertgen;
43 		int            (*accel)(int);
44 
InsertValueIdInfo45 		IdInfo& InsertValue(const Value& v)  { insertval = v; return *this; }
InsertValueIdInfo46 		IdInfo& InsertValue(ValueGen& g)     { insertgen = &g; return *this; }
AccelIdInfo47 		IdInfo& Accel(int (*filter)(int))    { accel = filter; return *this; }
AccelIdInfo48 		IdInfo& Accel()                      { return Accel(CharFilterDefaultToUpperAscii); }
49 
GetInsertValueIdInfo50 		Value   GetInsertValue()             { return insertgen ? insertgen->Get() : insertval; }
51 
IdInfoIdInfo52 		IdInfo()                             { insertgen = NULL; accel = NULL; }
53 	};
54 
55 	class Column : FormatConvert {
56 		ArrayCtrl            *arrayctrl;
57 		int                   index;
58 		Mitor<int>            pos;
59 		const Convert        *convert;
60 		Function<Value(const Value&)> convertby;
61 		Ptr<Ctrl>             edit;
62 		const Display        *display;
63 		Event<int, One<Ctrl>&> factory;
64 		Event<One<Ctrl>&>     factory1;
65 		int                 (*accel)(int);
66 		int                   margin;
67 		bool                  cached;
68 		bool                  clickedit;
69 		mutable Any           cache;
70 		const ValueOrder     *order;
71 		Function<int (const Value& a, const Value& b)> cmp;
72 		Gate<int, int>        line_order;
73 
74 
75 		void   InvalidateCache(int i);
76 		void   InsertCache(int i, int n);
77 		void   RemoveCache(int i);
78 		void   ClearCache();
79 		void   Sorts();
80 
81 		typedef Column CLASSNAME;
82 
83 		friend class ArrayCtrl;
84 
85 	public:
Add(int _pos)86 		Column& Add(int _pos)                      { pos.Add(_pos); return *this; }
Add(const Id & id)87 		Column& Add(const Id& id)                  { pos.Add(-arrayctrl->AsNdx(id)); return *this; }
AddIndex(const Id & id)88 		Column& AddIndex(const Id& id)             { arrayctrl->AddIndex(id); return Add(id); }
AddIndex()89 		Column& AddIndex()                         { Add(arrayctrl->GetIndexCount()); arrayctrl->AddIndex(); return *this; }
90 
91 		Column& SetConvert(const Convert& c);
92 		Column& ConvertBy(Function<Value(const Value&)> cv);
93 		Column& SetFormat(const char *fmt);
94 		Column& SetDisplay(const Display& d);
95 		Column& NoEdit();
96 		Column& Edit(Ctrl& e);
97 		template <class T>
Ctrls()98 		Column& Ctrls()                            { return Ctrls(DefaultCtrlFactory<T>()); }
99 		Column& WithLined(Event<int, One<Ctrl>&> factory);
100 		Column& With(Event<One<Ctrl>&> factory);
101 		Column& InsertValue(const Value& v);
102 		Column& InsertValue(ValueGen& g);
NoClickEdit()103 		Column& NoClickEdit()                      { clickedit = false; return *this; }
104 		Column& Cache();
Accel(int (* filter)(int))105 		Column& Accel(int (*filter)(int))          { accel = filter; return *this; }
Accel()106 		Column& Accel()                            { return Accel(CharFilterDefaultToUpperAscii); }
107 
108 		Column& Sorting();
109 		Column& Sorting(const ValueOrder& o);
110 		Column& SortingLined(Gate<int, int> line_order);
111 		Column& SortingBy(Function<int (const Value& a, const Value& b)> cmp);
112 		Column& SortDefault(bool desc = false);
113 
Margin(int m)114 		Column& Margin(int m)                      { margin = m; return *this; }
115 
116 		HeaderCtrl::Column& HeaderTab();
117 		const HeaderCtrl::Column& HeaderTab() const;
Tip(const char * tip)118 		Column& Tip(const char *tip)               { HeaderTab().Tip(tip); return *this; }
119 
120 		Column();
121 
122 // deprecated (due to overloading issues)
123 		Column& Ctrls(Callback1<One<Ctrl>&> factory);
Ctrls(void (* factory)(One<Ctrl> &))124 		Column& Ctrls(void (*factory)(One<Ctrl>&)) { return Ctrls(Event<int, One<Ctrl>&>([=](int, One<Ctrl>& h) { factory(h); })); }
125 		Column& Ctrls(Event<int, One<Ctrl>&> factory);
Ctrls(void (* factory)(int,One<Ctrl> &))126 		Column& Ctrls(void (*factory)(int, One<Ctrl>&)) { return Ctrls(Event<int, One<Ctrl>&>([=](int a, One<Ctrl>& b){ factory(a, b); })); }
Sorting(Gate<int,int> order)127 		Column& Sorting(Gate<int, int> order) { return SortingLined(order); }
Sorting(int (* c)(const Value & a,const Value & b))128 		Column& Sorting(int (*c)(const Value& a, const Value& b)) { return SortingBy(c); }
129 	};
130 
131 	struct Order {
132 		virtual bool operator()(const Vector<Value>& row1, const Vector<Value>& row2) const = 0;
~OrderOrder133 		virtual ~Order() {}
134 	};
135 
136 private:
137 	struct ItemOrder;
138 	struct RowOrder;
139 	struct SortPredicate;
140 
141 	struct Control : Moveable<Control> {
142 		int   pos;
143 		Ctrl *ctrl;
144 	};
145 
146 	struct CellCtrl : ParentCtrl {
147 		virtual void LeftDown(Point, dword);
148 
149 		bool       owned;
150 		bool       value;
151 		Ctrl      *ctrl;
152 	};
153 
154 	struct CellInfo : Moveable<CellInfo> {
155 		BitAndPtr ptr;
156 
157 		void           Free();
158 		void           Set(Ctrl *ctrl, bool owned, bool value);
IsCtrlCellInfo159 		bool           IsCtrl() const             { return ptr.GetBit(); }
GetCtrlCellInfo160 		CellCtrl&      GetCtrl() const            { ASSERT(IsCtrl()); return *(CellCtrl *)ptr.GetPtr(); }
161 
SetCellInfo162 		void           Set(const Display& d)      { ASSERT(!IsCtrl()); ptr.Set0((void *)&d); }
IsDisplayCellInfo163 		bool           IsDisplay() const          { return !ptr.GetBit() && ptr.GetPtr(); }
GetDisplayCellInfo164 		const Display& GetDisplay() const         { ASSERT(IsDisplay()); return *(const Display *)ptr.GetPtr(); }
165 
166 		CellInfo(CellInfo&& s);
CellInfoCellInfo167 		CellInfo() {}
168 		~CellInfo();
169 	};
170 
171 	friend class Column;
172 	friend struct SortPredicate;
173 
174 	struct Ln : Moveable<Ln> {
175 		int y;
176 		int cy;
LnLn177 		Ln()               { cy = Null; }
178 	};
179 
180 	struct Line : Moveable<Line> {
181 		bool          select:1;
182 		bool          enabled:1;
183 		bool          visible:1;
184 		Color         paper;
185 		Vector<Value> line;
186 
LineLine187 		Line() { select = false; enabled = true; visible = true; paper = Null; }
188 	};
189 
StdValueCompare(const Value & a,const Value & b)190 	static int StdValueCompare(const Value& a, const Value& b) { return Upp::StdValueCompare(a, b); }
191 
192 
193 	Vector<Line>               array;
194 	HeaderCtrl                 header;
195 	ScrollBar                  sb;
196 	Scroller                   scroller;
197 	Array<Column>              column;
198 	Vector<Control>            control;
199 	ArrayMap<Id, IdInfo>       idx;
200 	Vector<Ln>                 ln;
201 	Vector< Vector<CellInfo> > cellinfo;
202 	Vector<bool>               modify;
203 	FrameBottom<ParentCtrl>    scrollbox;
204 	Vector<int>                column_width, column_pos;
205 	DisplayPopup               info;
206 	const Order               *columnsortsecondary;
207 	int                        min_visible_line, max_visible_line;
208 	int                        ctrl_low, ctrl_high;
209 	int                        sorting_from;
210 	Index<String>              id_ndx;
211 
212 	int   keypos;
213 	int   cursor;
214 	int   anchor;
215 	int   linecy;
216 	int   virtualcount;
217 	Point clickpos;
218 	int   dropline, dropcol;
219 	int   sortcolumn;
220 	bool  sortcolumndescending;
221 	bool  columnsortfindkey;
222 	int   acceptingrow;
223 
224 	mutable int   selectcount;
225 
226 	String row_name;
227 	Color  gridcolor;
228 	Color  evenpaper, evenink, oddpaper, oddink;
229 
230 	bool  horzgrid:1;
231 	bool  vertgrid:1;
232 	bool  nocursor:1;
233 	bool  mousemove:1;
234 	bool  editmode:1;
235 	bool  insertmode:1;
236 
237 	bool  inserting:1;
238 	bool  appending:1;
239 	bool  appendline:1;
240 	bool  noinsertappend:1;
241 	bool  autoappend:1;
242 	bool  removing:1;
243 	bool  moving:1;
244 	bool  askremove:1;
245 	bool  duplicating:1;
246 	bool  multiselect:1;
247 	bool  hasctrls:1;
248 	bool  headerctrls:1;
249 	bool  popupex:1;
250 	bool  nobg:1;
251 	bool  focussetcursor:1;
252 	bool  allsorting:1;
253 	bool  spanwidecells:1;
254 
255 	mutable bool  selectiondirty:1;
256 
257 	unsigned  bains:2;
258 
259 	Image cursor_override;
260 
261 	bool  isdrag:1;
262 	bool  selclick:1;
263 
264 	int    Pos(int np) const;
265 
266 	void   InsertCache(int i);
267 	void   RemoveCache(int i);
268 
269 	void   SetSb();
270 	void   MinMaxLine();
271 	void   SyncColumnsPos();
272 	void   HeaderLayout();
273 	void   HeaderScroll();
274 	void   Scroll();
275 	int    FindEnabled(int i, int dir);
276 	void   Page(int q);
277 
278 	void   DoPoint(Point p, bool dosel = true);
279 	void   DoClick(Point p, dword flags);
280 	int    GetClickColumn(int ii, Point p);
281 	void   ClickColumn(Point p);
282 	void   ClickSel(dword flags);
283 
284 	Point           FindCellCtrl(Ctrl *c);
285 	Ctrl           *SyncLineCtrls(int i, Ctrl *p = NULL);
286 	void            SyncPageCtrls();
287 	void            SyncCtrls();
288 	bool            IsCtrl(int i, int j) const;
289 	const CellCtrl& GetCellCtrl(int i, int j) const;
290 	CellCtrl&       GetCellCtrl(int i, int j);
291 	void            SetCtrlValue(int i, int ii, const Value& v);
292 
293 	void   PlaceEdits();
294 	void   EndEdit();
295 	void   ColEditSetData(int col);
296 	void   CtrlSetData(int col);
297 	Value  Get0(int i, int ii) const;
298 	void   Set0(int i, int ii, const Value& v);
299 	void   AfterSet(int i);
300 
301 	void   Reline(int i, int y);
302 	void   Remove0(int i);
303 	void   DisableCtrls();
304 	void   SetCtrls();
305 	void   DoRemovem();
306 	bool   KillCursor0();
307 
308 	const Display& GetCellInfo(int i, int j, bool f0, Value& v, Color& fg, Color& bg, dword& st);
309 	Ctrl&  SetCtrl(int i, int j, Ctrl *newctrl, bool owned, bool value);
310 	Size   DoPaint(Draw& w, bool sample);
311 	void   SpanWideCell(const Display& d, const Value& q, int cm, int& cw, Rect& r, int i, int& j);
312 
313 	bool   TestKey(int i, int key);
314 
315 	bool   SetCursor0(int i, bool dosel = true);
316 
317 	void   SyncSelection() const;
318 	void   KeyMultiSelect(int aanchor, dword key);
319 
320 	void   HeaderScrollVisibility();
321 
322 	void   RefreshSel();
323 	bool   DnDInsert(int line, int py, PasteClip& d, int q);
324 	void   DnD(int line, int col);
325 	enum { DND_INSERTLINE = -1, DND_LINE = -2 };
326 
327 	bool   ColumnSortPred(int i1, int i2, int column, const ValueOrder *o);
328 	bool   OrderPred(int i1, int i2, const ArrayCtrl::Order *o);
329 	bool   DescendingPred(int i1, int i2, const Gate<int, int> *pred);
330 	void   SyncInfo();
331 	void   SortA();
332 	void   SortB(const Vector<int>& o);
333 
334 	void   SelectOne(int i, bool sel = true, bool raise = true);
335 
AsNdx(const String & id)336 	int    AsNdx(const String& id)              { return id_ndx.FindAdd(id); }
337 
338 	using Ctrl::IsModified;
339 
340 	// These are listed here as private because name has changed to SetMap/AddMap
341 	void       Set(int i, const ValueMap& m);
342 	void       Add(const ValueMap& m);
343 
IsLineVisible0(int i)344 	bool       IsLineVisible0(int i) const { return i < 0 ? false : i < array.GetCount() ? array[i].visible : true; }
345 
346 public: // temporary (TRC 06/07/28) // will be removed!
SetCtrl(int i,int j,Ctrl * newctrl)347 	Ctrl&  SetCtrl(int i, int j, Ctrl *newctrl) { return SetCtrl(i, j, newctrl, true, true); }
348 
349 protected:
350 	virtual bool UpdateRow();
351 	virtual void RejectRow();
352 
353 	void   ClearModify();
354 
355 public:
356 	Event<>           WhenSel; // the most usual ArrayCtrl event
357 
358 	Event<>           WhenLeftDouble;
359 	Event<Point>      WhenMouseMove;
360 	Event<>           WhenEnterKey;
361 	Event<>           WhenLeftClick;
362 	Event<Bar&>       WhenBar;
363 	Gate<>            WhenAcceptRow;
364 	Event<>           WhenUpdateRow;
365 	Event<>           WhenArrayAction;
366 	Event<>           WhenStartEdit;
367 	Event<>           WhenAcceptEdit;
368 	Event<>           WhenCtrlsAction;
369 	Event<>           WhenScroll;
370 	Event<>           WhenHeaderLayout;
371 	Event<>           WhenColumnSorted;
372 
373 	Event<int, bool&> WhenLineEnabled;
374 	Event<int, bool&> WhenLineVisible;
375 
376 	Event<>                     WhenDrag;
377 	Event<int, int, PasteClip&> WhenDropCell;
378 	Event<int, PasteClip&>      WhenDropInsert;
379 	Event<int, PasteClip&>      WhenDropLine;
380 	Event<PasteClip&>           WhenDrop;
381 
382 	//Deprecated - use WhenSel
383 	Event<>           WhenEnterRow;
384 	Event<>           WhenKillCursor;
385 	Event<>           WhenCursor;
386 	Event<>           WhenSelection;
387 
388 	IdInfo&    IndexInfo(int ii);
389 	IdInfo&    IndexInfo(const Id& id);
390 	IdInfo&    AddIndex(const Id& id);
391 	IdInfo&    AddIndex();
GetIndexCount()392 	int        GetIndexCount() const        { return idx.GetCount(); }
GetId(int ii)393 	Id         GetId(int ii) const          { return idx.GetKey(ii); }
GetPos(const Id & id)394 	int        GetPos(const Id& id) const   { return idx.Find(id); }
395 	IdInfo&    SetId(int ii, const Id& id);
AddKey(const Id & id)396 	IdInfo&    AddKey(const Id& id)         { ASSERT(idx.GetCount() == 0); return AddIndex(id); }
AddKey()397 	IdInfo&    AddKey()                     { ASSERT(idx.GetCount() == 0); return AddIndex(); }
GetKeyId()398 	Id         GetKeyId() const             { return idx.GetKey(0); }
399 
400 	Column&    AddColumn(const char *text = NULL, int w = 0);
401 	Column&    AddColumn(const Id& id, const char *text, int w = 0);
402 	Column&    AddColumnAt(int ii, const char *text, int w = 0);
403 	Column&    AddColumnAt(const Id& id, const char *text, int w = 0);
404 	Column&    AddRowNumColumn(const char *text = NULL, int w = 0);
405 
GetColumnCount()406 	int                       GetColumnCount() const   { return column.GetCount(); }
407 	int                       FindColumnWithPos(int pos) const;
408 	int                       FindColumnWithId(const Id& id) const;
ColumnAt(int i)409 	Column&                   ColumnAt(int i)          { return column[i]; }
ColumnAt(const Id & id)410 	Column&                   ColumnAt(const Id& id)   { return column[FindColumnWithId(id)]; }
HeaderTab(int i)411 	HeaderCtrl::Column&       HeaderTab(int i)         { return header.Tab(i); }
HeaderTab(const Id & id)412 	HeaderCtrl::Column&       HeaderTab(const Id& id)  { return header.Tab(FindColumnWithId(id)); }
ColumnAt(int i)413 	const Column&             ColumnAt(int i) const    { return column[i]; }
ColumnAt(const Id & id)414 	const Column&             ColumnAt(const Id& id) const   { return column[FindColumnWithId(id)]; }
HeaderTab(int i)415 	const HeaderCtrl::Column& HeaderTab(int i) const   { return header.Tab(i); }
HeaderTab(const Id & id)416 	const HeaderCtrl::Column& HeaderTab(const Id& id) const   { return header.Tab(FindColumnWithId(id)); }
417 
HeaderObject()418 	const HeaderCtrl&         HeaderObject() const     { return header; }
HeaderObject()419 	HeaderCtrl&               HeaderObject()           { return header; }
420 
SerializeHeader(Stream & s)421 	void       SerializeHeader(Stream& s)    { header.Serialize(s); } // deprecated
422 	void       SerializeSettings(Stream& s);
423 
424 	IdInfo&    AddCtrl(Ctrl& ctrl);
425 	IdInfo&    AddCtrl(const Id& id, Ctrl& ctrl);
AddIdCtrl(Ctrl & ctrl)426 	IdInfo&    AddIdCtrl(Ctrl& ctrl)         { return AddCtrl(ctrl.GetLayoutId(), ctrl); }
427 	void       AddCtrlAt(int ii, Ctrl& ctrl);
428 	void       AddCtrlAt(const Id& id, Ctrl& ctrl);
429 	void       AddRowNumCtrl(Ctrl& ctrl);
430 
431 	void       SetCount(int c);
432 	void       SetVirtualCount(int c);
433 	int        GetCount() const;
434 	void       Clear();
435 	void       Shrink();
436 	Value      Get(int i, int ii) const;
437 	Value      Get(int i, const Id& id) const;
438 	void       Set(int i, int ii, const Value& v);
439 	void       Set(int i, const Id& id, const Value& v);
440 
441 	Value      Get(int ii) const;
442 	Value      Get(const Id& id) const;
443 	Value      GetOriginal(int ii) const;
444 	Value      GetOriginal(const Id& id) const;
445 	bool       IsModified(int ii) const;
446 	bool       IsModified(const Id& id) const;
447 	Value      GetKey() const;
448 	Value      GetOriginalKey() const;
449 	void       Set(int ii, const Value& v);
450 	void       Set(const Id& id, const Value& v);
451 
452 	Value      GetColumn(int row, int col) const;
453 	Value      GetConvertedColumn(int row, int col) const;
454 
455 	int        GetSelectCount() const;
IsSelection()456 	bool       IsSelection() const                              { return GetSelectCount(); }
457 	void       Select(int i, bool sel = true)                   { SelectOne(i, sel); }
458 	void       Select(int i, int count, bool sel = true);
IsSelected(int i)459 	bool       IsSelected(int i) const                          { return i < array.GetCount() && array[i].select; }
460 	void       ClearSelection(bool raise = true);
461 	bool       IsSel(int i) const;
462 	Vector<int> GetSelKeys() const;
463 
464 	void       EnableLine(int i, bool e);
DisableLine(int i)465 	void       DisableLine(int i)                               { EnableLine(i, false); }
466 	bool       IsLineEnabled(int i) const;
IsLineDisabled(int i)467 	bool       IsLineDisabled(int i) const                      { return !IsLineEnabled(i); }
468 
469 	void       ShowLine(int i, bool e);
HideLine(int i)470 	void       HideLine(int i)                                  { ShowLine(i, false); }
471 	bool       IsLineVisible(int i) const;
472 
473 	Vector<Value> ReadRow(int i) const; // deprecated name
GetLine(int i)474 	Vector<Value> GetLine(int i) const                          { return ReadRow(i); }
475 
476 	void       Set(int i, const Vector<Value>& v);
477 	void       Set(int i, const VectorMap<String, Value>& m);
478 
479 	void       Add();
480 
481 #define  E__Add(I)      void Add(__List##I(E__Value));
482 	__Expand(E__Add)
483 #undef   E__Add
484 
485 	void       Add(const Vector<Value>& v);
Add(const Nuller & null)486 	void       Add(const Nuller& null)                          { Add((Value)Null); }
487 	void       Add(const VectorMap<String, Value>& m);
488 //$-void Add(const Value& [, const Value& ]...);
489 	template <typename... Args>
Add(const Args &...args)490 	void       Add(const Args& ...args)                         { Add(gather<Vector<Value>>(args...)); }
491 //$+
492 
493 	void       SetMap(int i, const ValueMap& m);
494 	void       AddMap(const ValueMap& m);
495 	ValueMap   GetMap(int i) const;
496 
497 	void       SetArray(int i, const ValueArray& va);
498 	void       AddArray(const ValueArray& va);
499 	ValueArray GetArray(int i) const;
500 
501 	void       AddSeparator();
502 
503 	void       Insert(int i);
504 	void       Insert(int i, int count);
505 	void       Insert(int i, const Vector<Value>& v);
506 	void       Insert(int i, const Vector< Vector<Value> >& v);
507 
508 	void       Remove(int i);
509 
510 	void       RemoveSelection();
511 
512 	Image      GetDragSample();
513 
514 	void       InsertDrop(int line, const Vector<Vector<Value>>& data, PasteClip& d, bool self);
515 	void       InsertDrop(int line, const Vector<Value>& data, PasteClip& d, bool self);
516 	void       InsertDrop(int line, const Value& data, PasteClip& d, bool self);
517 	void       InsertDrop(int line, const ArrayCtrl& src, PasteClip& d);
518 	void       InsertDrop(int line, PasteClip& d);
519 
IsCursor()520 	bool       IsCursor() const                        { return cursor >= 0; }
521 	bool       SetCursor(int i);
522 	bool       KillCursor();
523 	void       CancelCursor();
GetCursor()524 	int        GetCursor() const                       { return cursor; }
525 	void       GoBegin();
526 	void       GoEnd();
527 	int        GetCursorSc() const;
528 	void       ScCursor(int a);
529 	void       CenterCursor();
530 	void       ScrollInto(int line);
531 	void       ScrollIntoCursor();
532 	void       SetCursorEditFocus();
533 	int        GetScroll() const;
534 	void       ScrollTo(int sc);
535 	void       ShowAppendLine();
536 	bool       AcceptRow();
537 
538 	void       Move(int d);
539 	void       SwapUp();
540 	void       SwapDown();
541 
542 	int        Find(const Value& v, int ii = 0, int from = 0) const;
543 	int        Find(const Value& v, const Id& id, int from = 0) const;
544 
545 	bool       FindSetCursor(const Value& val, int ii = 0, int from = 0);
546 	bool       FindSetCursor(const Value& val, const Id& id, int from = 0);
547 
548 	void       ReArrange(const Vector<int>& order);
549 
550 	void       Sort(int from, int count, Gate<int, int> order);
551 	void       Sort(Gate<int, int> order);
552 	void       Sort(const ArrayCtrl::Order& order);
553 	void       Sort(int from, int count, const ArrayCtrl::Order& order);
554 	void       Sort(int (*compare)(const Vector<Value>& v1, const Vector<Value>& v2));
555 	void       Sort(int from, int count,
556 	                int (*compare)(const Vector<Value>& v1, const Vector<Value>& v2));
557 	void       Sort(int ii, int (*compare)(const Value& v1, const Value& v2)
558 	                = StdValueCompare);
559 	void       Sort(const Id& id, int (*compare)(const Value& v1, const Value& v2)
560 	                = StdValueCompare);
Sort()561 	void       Sort()                                  { Sort(0); }
562 
563 	void       ColumnSort(int column, Gate<int, int> order);
564 	void       ColumnSort(int column, const ValueOrder& order);
565 	void       ColumnSort(int column, int (*compare)(const Value& a, const Value& b) = StdValueCompare);
566 
567 	void       SetSortColumn(int ii, bool descending = false);
568 	void       ToggleSortColumn(int ii);
569 	void       DoColumnSort();
GetSortColumn()570 	int        GetSortColumn() const                   { return sortcolumn; }
IsSortDescending()571 	bool       IsSortDescending() const                { return sortcolumndescending; }
572 
IsInsert()573 	bool       IsInsert() const                        { return insertmode; }
574 
575 	void            SetDisplay(int i, int col, const Display& d);
576 	void            SetRowDisplay(int i, const Display& d);
577 	void            SetColumnDisplay(int j, const Display& d);
578 	const Display&  GetDisplay(int row, int col);
579 	const Display&  GetDisplay(int col);
580 
581 	void       RefreshRow(int i);
582 
583 	void       SetCtrl(int i, int col, Ctrl& ctrl, bool value = true);
584 	Ctrl      *GetCtrl(int i, int col);
585 	template <class T>
586 	T&         CreateCtrl(int i, int col, bool value = true) { T *c = new T; SetCtrl(i, col, c, true, value); SyncLineCtrls(i); return *c; }
587 
588 	ArrayCtrl& SetLineCy(int cy);
589 	void       SetLineCy(int i, int cy);
GetLineCy()590 	int        GetLineCy() const                       { return linecy; }
591 	int        GetLineY(int i) const;
592 	int        GetLineCy(int i) const;
593 	int        GetTotalCy() const;
594 	int        GetLineAt(int y) const;
595 
596 	void       SetLineColor(int i, Color c);
597 
598 	Rect       GetCellRect(int i, int col) const;
599 	Rect       GetCellRectM(int i, int col) const;
600 	Rect       GetScreenCellRect(int i, int col) const;
601 	Rect       GetScreenCellRectM(int i, int col) const;
602 
GetClickPos()603 	Point      GetClickPos() const                     { return clickpos; }
GetClickColumn()604 	int        GetClickColumn() const                  { return clickpos.x; }
GetClickRow()605 	int        GetClickRow() const                     { return clickpos.y; }
606 
607 	bool       StartEdit(int d = 0);
608 	int        GetEditColumn() const;
IsEdit()609 	bool       IsEdit() const                          { return editmode; }
610 
611 	void       DoEdit();
612 	void       DoInsert(int cursor);
613 	void       DoInsertBefore();
614 	void       DoInsertAfter();
615 	void       DoAppend();
616 	bool       DoRemove();
617 	void       DoDuplicate();
618 	void       DoSelectAll();
619 	void       StdBar(Bar& menu);
620 
621 	bool       IsEditing() const;
622 	bool       AcceptEnter();
623 
624 	void       ClearCache();
625 	void       InvalidateCache(int i);
626 
ScrollUp()627 	void       ScrollUp()                              { sb.PrevLine(); }
ScrollDown()628 	void       ScrollDown()                            { sb.NextLine(); }
ScrollPageUp()629 	void       ScrollPageUp()                          { sb.PrevPage(); }
ScrollPageDown()630 	void       ScrollPageDown()                        { sb.NextPage(); }
ScrollEnd()631 	void       ScrollEnd()                             { sb.End(); }
ScrollBegin()632 	void       ScrollBegin()                           { sb.Begin(); }
633 
634 	String     AsText(String (*format)(const Value&), bool sel = false,
635 	                  const char *tab = "\t", const char *row = "\r\n",
636 	                  const char *hdrtab = "\t", const char *hdrrow = "\r\n") const;
637 	void       SetClipboard(bool sel = false, bool hdr = true) const;
638 	String     AsQtf(bool sel = false, bool hdr = true);
639 	String     AsCsv(bool sel = false, int sep = ';', bool hdr = true);
640 
641 	String     RowFormat(const char *s);
642 
RowName(const char * s)643 	ArrayCtrl& RowName(const char *s)                  { row_name = s; return *this; }
644 	ArrayCtrl& AppendLine(bool b = true)               { appendline = b; return *this; }
NoAppendLine()645 	ArrayCtrl& NoAppendLine()                          { return AppendLine(false); }
IsAppendLine()646 	bool       IsAppendLine() const                    { return appendline; }
647 	ArrayCtrl& Inserting(bool b = true)                { inserting = b; return AppendLine(b); }
NoInserting()648 	ArrayCtrl& NoInserting()                           { return Inserting(false); }
IsInserting()649 	bool       IsInserting() const                     { return inserting; }
650 	ArrayCtrl& Removing(bool b = true)                 { removing = b; return *this; }
NoRemoving()651 	ArrayCtrl& NoRemoving()                            { return Removing(false); }
IsRemoving()652 	bool       IsRemoving() const                      { return removing; }
653 	ArrayCtrl& Appending(bool b = true)                { appending = b; return *this; }
IsAppending()654 	bool       IsAppending() const                     { return appending || autoappend; }
655 	ArrayCtrl& AutoAppending(bool b = true)            { autoappend = b; return *this; }
IsAutoAppending()656 	bool       IsAutoAppending() const                 { return autoappend; }
657 	ArrayCtrl& BeforeAfterInserting(int q = 1)         { bains = 1; return *this; }
658 	ArrayCtrl& AfterBeforeInserting(int q = 2)         { bains = 2; return *this; }
659 	ArrayCtrl& Duplicating(bool b = true)              { duplicating = b; return *this; }
660 	ArrayCtrl& NoInsertAppend(bool b = true)           { noinsertappend = b; return *this; }
IsDuplicating()661 	bool       IsDuplicating() const                   { return duplicating; }
662 	ArrayCtrl& Moving(bool b = true)                   { moving = b; return *this; }
IsMoving()663 	bool       IsMoving() const                        { return moving; }
NoDuplicating()664 	ArrayCtrl& NoDuplicating()                         { return Duplicating(false); }
665 	ArrayCtrl& AskRemove(bool b = true)                { askremove = b; return *this; }
NoAskRemove()666 	ArrayCtrl& NoAskRemove()                           { return AskRemove(false); }
IsAskRemove()667 	bool       IsAskRemove() const                     { return askremove; }
668 
669 	ArrayCtrl& Header(bool b = true)                   { header.Invisible(!b); return *this; }
NoHeader()670 	ArrayCtrl& NoHeader()                              { return Header(false); }
671 	ArrayCtrl& Track(bool b = true)                    { header.Track(b); return *this; }
NoTrack()672 	ArrayCtrl& NoTrack()                               { return Track(false); }
673 	ArrayCtrl& VertGrid(bool b = true)                 { vertgrid = b; Refresh(); return *this; }
NoVertGrid()674 	ArrayCtrl& NoVertGrid()                            { return VertGrid(false); }
675 	ArrayCtrl& HorzGrid(bool b = true)                 { horzgrid = b; Refresh(); return *this; }
NoHorzGrid()676 	ArrayCtrl& NoHorzGrid()                            { return HorzGrid(false); }
677 	ArrayCtrl& Grid(bool b = true)                     { return VertGrid(b).HorzGrid(b); }
NoGrid()678 	ArrayCtrl& NoGrid()                                { return Grid(false); }
GridColor(Color c)679 	ArrayCtrl& GridColor(Color c)                      { gridcolor = c; return *this; }
680 	ArrayCtrl& EvenRowColor(Color paper = Blend(SColorMark, SColorPaper, 220), Color ink = SColorText);
681 	ArrayCtrl& OddRowColor(Color paper = SColorInfo, Color ink = SColorText);
682 	ArrayCtrl& NoCursor(bool b = true)                 { nocursor = b; return *this; }
683 	ArrayCtrl& MouseMoveCursor(bool b = true)          { mousemove = b; return *this; }
NoMouseMoveCursor()684 	ArrayCtrl& NoMouseMoveCursor()                     { return MouseMoveCursor(false); }
685 	ArrayCtrl& AutoHideSb(bool b = true)               { sb.AutoHide(b); return *this; }
NoAutoHideSb()686 	ArrayCtrl& NoAutoHideSb()                          { return AutoHideSb(false); }
687 	ArrayCtrl& HideSb(bool b = true)                   { sb.Show(!b); return *this; }
688 	ArrayCtrl& AutoHideHorzSb(bool b = true)           { header.AutoHideSb(b); return *this; }
NoAutoHideHorzSb()689 	ArrayCtrl& NoAutoHideHorzSb()                      { return AutoHideHorzSb(false); }
690 	ArrayCtrl& HideHorzSb(bool b = true)               { header.HideSb(b); return *this; }
691 
692 	ArrayCtrl& MultiSelect(bool b = true)              { multiselect = b; return *this; }
IsMultiSelect()693 	bool       IsMultiSelect() const                   { return multiselect; }
694 	ArrayCtrl& NoBackground(bool b = true)             { nobg = b; Transparent(); Refresh(); return *this; }
695 	ArrayCtrl& PopUpEx(bool b = true)                  { popupex = b; SyncInfo(); return *this; }
NoPopUpEx()696 	ArrayCtrl& NoPopUpEx()                             { return PopUpEx(false); }
NoFocusSetCursor()697 	ArrayCtrl& NoFocusSetCursor()                      { focussetcursor = false; return *this; }
MovingHeader(bool b)698 	ArrayCtrl& MovingHeader(bool b)                    { header.Moving(b); return *this; }
NoMovingHeader()699 	ArrayCtrl& NoMovingHeader()                        { return MovingHeader(false); }
700 	ArrayCtrl& ColumnSortFindKey(bool b = true)        { columnsortfindkey = b; return *this; }
701 	ArrayCtrl& AllSorting();
ColumnSortSecondary(const Order & order)702 	ArrayCtrl& ColumnSortSecondary(const Order& order) { columnsortsecondary = &order; return *this; }
NoColumnSortSecondary()703 	ArrayCtrl& NoColumnSortSecondary()                 { columnsortsecondary = NULL; return *this; }
SortingFrom(int from)704 	ArrayCtrl& SortingFrom(int from)                   { sorting_from = from; return *this; }
705 
706 	ArrayCtrl& ColumnWidths(const char *s);
707 	String     GetColumnWidths();
708 
SetScrollBarStyle(const ScrollBar::Style & s)709 	ArrayCtrl& SetScrollBarStyle(const ScrollBar::Style& s)   { sb.SetStyle(s); header.SetScrollBarStyle(s); return *this; }
SetHeaderCtrlStyle(const HeaderCtrl::Style & s)710 	ArrayCtrl& SetHeaderCtrlStyle(const HeaderCtrl::Style& s) { header.SetStyle(s); return *this; }
711 
CursorOverride(const Image & arrow)712 	ArrayCtrl& CursorOverride(const Image& arrow)             { cursor_override = arrow; return *this; }
NoCursorOverride()713 	ArrayCtrl& NoCursorOverride()                             { return CursorOverride(Null); }
714 
715 	ArrayCtrl& SpanWideCells(bool b = true)                   { spanwidecells = b; Refresh(); return *this; }
716 
717 	void Reset();
718 
719 	typedef ArrayCtrl CLASSNAME;
720 
721 	ArrayCtrl();
722 	virtual ~ArrayCtrl();
723 };
724 
725 class ArrayOption : public Display, public Pte<ArrayOption> {
726 public:
727 	typedef ArrayOption CLASSNAME;
728 	ArrayOption();
729 	virtual ~ArrayOption();
730 
731 	virtual void       Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const;
732 
733 	void               Connect(ArrayCtrl& ac, int ii = 0);
Connect(ArrayCtrl & ac,const Id & id)734 	void               Connect(ArrayCtrl& ac, const Id& id)        { Connect(ac, ac.GetPos(id)); }
735 
736 	void               Disconnect();
737 
738 	ArrayCtrl::Column& AddColumn(ArrayCtrl& ac, const char *text = NULL, int w = 0);
739 	ArrayCtrl::Column& AddColumn(ArrayCtrl& ac, const Id& id, const char *text, int w = 0);
740 
TrueFalse(Value _t,Value _f)741 	ArrayOption&       TrueFalse(Value _t, Value _f)               { t = _t; f = _f; return *this; }
GetFalse()742 	Value              GetFalse() const                            { return f; }
GetTrue()743 	Value              GetTrue() const                             { return t; }
744 	ArrayOption&       ThreeState(bool b = true)                   { threestate = b; return *this; }
NoThreeState()745 	ArrayOption&       NoThreeState()                              { return ThreeState(false); }
IsThreeState()746 	bool               IsThreeState() const                        { return threestate; }
747 
748 	ArrayOption&       HSwitch(bool hs = true)                     { hswitch = hs; return *this; }
NoHSwitch()749 	ArrayOption&       NoHSwitch()                                 { return HSwitch(false); }
IsHSwitch()750 	bool               IsHSwitch() const                           { return hswitch; }
751 
752 	ArrayOption&       VSwitch(bool vs = true)                     { vswitch = vs; return *this; }
NoVSwitch()753 	ArrayOption&       NoVSwitch()                                 { return VSwitch(false); }
IsVSwitch()754 	bool               IsVSwitch() const                           { return vswitch; }
755 
756 	ArrayOption&       Frame(bool frm = true)                      { frame = frm; return *this; }
NoFrame()757 	ArrayOption&       NoFrame()                                   { return Frame(false); }
IsFrame()758 	bool               IsFrame() const                             { return frame; }
759 
760 	void               Click();
761 
762 public:
763 	Event<>            WhenAction;
764 
765 	Event<>            operator <<= (Event<>  cb)                  { return WhenAction = cb; }
766 
767 private:
768 	Vector<int>        index;
769 	ArrayCtrl         *array;
770 	Value              t, f;
771 	bool               hswitch, vswitch;
772 	bool               threestate;
773 	bool               frame;
774 };
775