summaryrefslogtreecommitdiff
path: root/library/CustomGrid.h
blob: 7a0d1b1009f0c82120509dd3de14f08728e5b1f2 (plain)
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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html       *
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de)                    *
// **************************************************************************
//
#ifndef CUSTOMGRID_H_INCLUDED
#define CUSTOMGRID_H_INCLUDED

#include <vector>
#include <wx/grid.h>
#include "processXml.h"
#include <map>
#include <memory>
#include <set>

class CustomGridTableRim;
class CustomGridTableLeft;
class CustomGridTableRight;
class CustomGridTableMiddle;
class GridCellRendererMiddle;
class wxTimer;
class CustomTooltip;
class CustomGridRim;
class CustomGridLeft;
class CustomGridMiddle;
class CustomGridRight;


namespace FreeFileSync
{
class GridView;

const wxBitmap& getSyncOpImage(SyncOperation syncOp);
}
//##################################################################################

/*
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() {}

    void initSettings(CustomGridLeft*   gridLeft,
                      CustomGridMiddle* gridMiddle,
                      CustomGridRight*  gridRight,
                      const FreeFileSync::GridView* gridDataView);

    std::set<unsigned int> getAllSelectedRows() const;

    //set sort direction indicator on UI
    typedef int SortColumn;

    enum SortDirection
    {
        ASCENDING,
        DESCENDING
    };

    typedef std::pair<SortColumn, SortDirection> SortMarker;
    void setSortMarker(SortMarker marker);

    bool isLeadGrid() const;

protected:
    void RefreshCell(int row, int col);

    virtual void DrawColLabel(wxDC& dc, int col);

private:
    virtual void setGridDataTable(const FreeFileSync::GridView* gridDataView) = 0;

    //this method is called when grid view changes: useful for parallel updating of multiple grids
    void OnPaintGrid(wxEvent& event);

    virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight) = 0;

    void onGridAccess(wxEvent& event);
    void adjustGridHeights(wxEvent& event);

    CustomGrid* m_gridLeft;
    CustomGrid* m_gridMiddle;
    CustomGrid* m_gridRight;

    bool isLeading; //identify grid that has user focus

    SortMarker m_marker;
};


template <bool showFileIcons>
class GridCellRenderer;


//-----------------------------------------------------------
#ifdef FFS_WIN
class IconUpdater : private wxEvtHandler //update file icons periodically: use SINGLE instance to coordinate left and right grid at once
{
public:
    IconUpdater(CustomGridLeft* leftGrid, CustomGridRight* rightGrid);
    ~IconUpdater(); //non-inline destructor for std::auto_ptr to work with forward declaration

private:
    void loadIconsAsynchronously(wxEvent& event); //loads all (not yet) drawn icons

    CustomGridRim* m_leftGrid;
    CustomGridRim* m_rightGrid;

    std::auto_ptr<wxTimer> m_timer; //user timer event to periodically update icons: better than idle event because also active when scrolling! :)
};
#endif


//############## SPECIALIZATIONS ###################
class CustomGridRim : public CustomGrid
{
    friend class IconUpdater;
    template <bool showFileIcons>
    friend class GridCellRenderer;

public:
    CustomGridRim(wxWindow *parent,
                  wxWindowID id,
                  const wxPoint& pos,
                  const wxSize& size,
                  long style,
                  const wxString& name);

    //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);

    void autoSizeColumns();        //performance optimized column resizer
    void autoSizeColumns(int col, bool doRefresh = true); //

#ifdef FFS_WIN
    void enableFileIcons(const bool value);
#endif

private:
    CustomGridTableRim* getGridDataTable();
    virtual const CustomGridTableRim* getGridDataTable() const = 0;

#ifdef FFS_WIN
    //asynchronous icon loading
    void getIconsToBeLoaded(std::vector<Zstring>& newLoad); //loads all (not yet) drawn icons

    typedef unsigned int FromRow;
    typedef unsigned int ToRow;
    typedef std::pair<FromRow, ToRow> VisibleRowRange;
    VisibleRowRange getVisibleRows();


    typedef unsigned int RowNumber;
    typedef bool         IconLoaded;
    typedef std::map<RowNumber, IconLoaded> LoadSuccess;
    LoadSuccess loadIconSuccess; //save status of last icon load when drawing on GUI

    bool fileIconsAreEnabled;
#endif

    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);

    virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);

private:
    virtual void setGridDataTable(const FreeFileSync::GridView* gridDataView);
    virtual const CustomGridTableRim* getGridDataTable() const;

    //this method is called when grid view changes: useful for parallel updating of multiple grids
    virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);

    CustomGridTableLeft* gridDataTable;
};


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);

    virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);

private:
    virtual void setGridDataTable(const FreeFileSync::GridView* gridDataView);
    virtual const CustomGridTableRim* getGridDataTable() const;

    //this method is called when grid view changes: useful for parallel updating of multiple grids
    virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);

    CustomGridTableRight* gridDataTable;
};


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(); //non-inline destructor for std::auto_ptr to work with forward declaration

    virtual bool CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode = wxGrid::wxGridSelectCells);

    void enableSyncPreview(bool value);

    //notify wxGrid that underlying table size has changed
    void updateGridSizes();

private:
#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

    virtual void setGridDataTable(const FreeFileSync::GridView* gridDataView);

    //this method is called when grid view changes: useful for parallel updating of multiple grids
    virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);

    virtual void DrawColLabel(wxDC& dc, int col);

    void OnMouseMovement(wxMouseEvent& event);
    void OnLeaveWindow(wxMouseEvent& event);
    void OnLeftMouseDown(wxMouseEvent& event);
    void OnLeftMouseUp(wxMouseEvent& event);

    void showToolTip(int rowNumber, wxPoint pos);

    //small helper methods
    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;

    std::auto_ptr<CustomTooltip> toolTip;
};

//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
bgstack15