1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
#ifndef CUSTOMGRID_H_INCLUDED
#define CUSTOMGRID_H_INCLUDED
#include <vector>
#include <wx/grid.h>
#include "../structures.h"
#include "processXml.h"
class CustomGridTable;
class CustomGridTableRim;
class CustomGridTableMiddle;
class GridCellRendererMiddle;
namespace FreeFileSync
{
class GridView;
}
//##################################################################################
/*
class hierarchy:
CustomGrid
/|\
____________|____________
| |
CustomGridRim |
/|\ |
________|_______ |
| | |
CustomGridLeft CustomGridRight CustomGridMiddle
*/
class CustomGrid : public wxGrid
{
public:
CustomGrid(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxWANTS_CHARS,
const wxString& name = wxGridNameStr);
virtual ~CustomGrid() {}
virtual void DrawColLabel(wxDC& dc, int col);
std::set<int> getAllSelectedRows() const;
//set sort direction indicator on UI
void setSortMarker(const int sortColumn, const wxBitmap* bitmap = &wxNullBitmap);
bool isLeadGrid() const;
protected:
CustomGrid* m_gridLeft;
CustomGrid* m_gridMiddle;
CustomGrid* m_gridRight;
private:
void onGridAccess(wxEvent& event);
void adjustGridHeights(wxEvent& event);
bool isLeading; //identify grid that has user focus
int currentSortColumn;
const wxBitmap* sortMarker;
};
//############## SPECIALIZATIONS ###################
class CustomGridRim : public CustomGrid
{
public:
CustomGridRim(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name) :
CustomGrid(parent, id, pos, size, style, name),
gridDataTable(NULL) {}
~CustomGridRim() {}
void initSettings(const bool showFileIcons, //workaround: though this coding better belongs into a constructor
CustomGrid* gridLeft, //this is not possible due to source code generation (information not available at time of construction)
CustomGrid* gridRight,
CustomGrid* gridMiddle,
const FreeFileSync::GridView* gridDataView);
//notify wxGrid that underlying table size has changed
void updateGridSizes();
//set visibility, position and width of columns
static xmlAccess::ColumnAttributes getDefaultColumnAttributes();
xmlAccess::ColumnAttributes getColumnAttributes();
void setColumnAttributes(const xmlAccess::ColumnAttributes& attr);
xmlAccess::ColumnTypes getTypeAtPos(unsigned pos) const;
static wxString getTypeName(xmlAccess::ColumnTypes colType);
virtual void enableFileIcons(const bool value) = 0;
protected:
CustomGridTableRim* gridDataTable;
private:
xmlAccess::ColumnAttributes columnSettings; //set visibility, position and width of columns
};
class CustomGridLeft : public CustomGridRim
{
public:
CustomGridLeft(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxWANTS_CHARS,
const wxString& name = wxGridNameStr);
~CustomGridLeft() {}
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
virtual void enableFileIcons(const bool value);
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void DoPrepareDC(wxDC& dc);
};
class CustomGridRight : public CustomGridRim
{
public:
CustomGridRight(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxWANTS_CHARS,
const wxString& name = wxGridNameStr);
~CustomGridRight() {}
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
virtual void enableFileIcons(const bool value);
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void DoPrepareDC(wxDC& dc);
};
class CustomGridMiddle : public CustomGrid
{
friend class GridCellRendererMiddle;
public:
CustomGridMiddle(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxWANTS_CHARS,
const wxString& name = wxGridNameStr);
~CustomGridMiddle() {}
virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);
void initSettings(CustomGrid* gridLeft, //workaround: though this coding better belongs into a constructor
CustomGrid* gridRight, //this is not possible due to source code generation (information not available at time of construction)
CustomGrid* gridMiddle,
const FreeFileSync::GridView* gridDataView);
void enableSyncPreview(bool value);
//notify wxGrid that underlying table size has changed
void updateGridSizes();
#ifdef FFS_WIN //get rid of scrollbars; Windows: overwrite virtual method
virtual void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh = true);
#endif
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void DoPrepareDC(wxDC& dc);
private:
void OnMouseMovement(wxMouseEvent& event);
void OnLeaveWindow(wxMouseEvent& event);
void OnLeftMouseDown(wxMouseEvent& event);
void OnLeftMouseUp(wxMouseEvent& event);
//small helper methods
void RefreshRow(int row);
enum BlockPosition //each cell can be divided into four blocks concerning mouse selections
{
BLOCKPOS_CHECK_BOX,
BLOCKPOS_LEFT,
BLOCKPOS_MIDDLE,
BLOCKPOS_RIGHT
};
int mousePosToRow(const wxPoint pos, BlockPosition* block = NULL);
//variables for selecting sync direction
int selectionRowBegin;
BlockPosition selectionPos;
//variables for highlightning on mouse-over
int highlightedRow;
BlockPosition highlightedPos;
CustomGridTableMiddle* gridDataTable;
};
//custom events for middle grid:
//--------------------------------------------------------------------------------------------
//(UN-)CHECKING ROWS FROM SYNCHRONIZATION
extern const wxEventType FFS_CHECK_ROWS_EVENT; //define new event type
class FFSCheckRowsEvent : public wxCommandEvent
{
public:
FFSCheckRowsEvent(const int from, const int to) :
wxCommandEvent(FFS_CHECK_ROWS_EVENT),
rowFrom(from),
rowTo(to) {}
virtual wxEvent* Clone() const
{
return new FFSCheckRowsEvent(rowFrom, rowTo);
}
const int rowFrom;
const int rowTo;
};
typedef void (wxEvtHandler::*FFSCheckRowsEventFunction)(FFSCheckRowsEvent&);
#define FFSCheckRowsEventHandler(func) \
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(FFSCheckRowsEventFunction, &func)
//--------------------------------------------------------------------------------------------
//SELECTING SYNC DIRECTION
extern const wxEventType FFS_SYNC_DIRECTION_EVENT; //define new event type
class FFSSyncDirectionEvent : public wxCommandEvent
{
public:
FFSSyncDirectionEvent(const int from, const int to, const FreeFileSync::SyncDirection dir) :
wxCommandEvent(FFS_SYNC_DIRECTION_EVENT),
rowFrom(from),
rowTo(to),
direction(dir) {}
virtual wxEvent* Clone() const
{
return new FFSSyncDirectionEvent(rowFrom, rowTo, direction);
}
const int rowFrom;
const int rowTo;
const FreeFileSync::SyncDirection direction;
};
typedef void (wxEvtHandler::*FFSSyncDirectionEventFunction)(FFSSyncDirectionEvent&);
#define FFSSyncDirectionEventHandler(func) \
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(FFSSyncDirectionEventFunction, &func)
#endif // CUSTOMGRID_H_INCLUDED
|