File: main_dlg.h

package info (click to toggle)
freefilesync 12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 8,432 kB
  • sloc: cpp: 64,801; ansic: 431; makefile: 217
file content (373 lines) | stat: -rw-r--r-- 17,434 bytes parent folder | download
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
361
362
363
364
365
366
367
368
369
370
371
372
373
// *****************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under    *
// * GNU General Public License: https://www.gnu.org/licenses/gpl-3.0          *
// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
// *****************************************************************************

#ifndef MAIN_DLG_H_8910481324545644545
#define MAIN_DLG_H_8910481324545644545

#include <map>
#include <memory>
#include <wx+/async_task.h>
#include <wx+/file_drop.h>
#include <wx/aui/aui.h>
#include "gui_generated.h"
#include "file_grid.h"
#include "tree_grid.h"
#include "sync_cfg.h"
#include "log_panel.h"
#include "folder_history_box.h"
#include "../config.h"
#include "../status_handler.h"
#include "../base/algorithm.h"
#include "../return_codes.h"


namespace fff
{
class FolderPairFirst;
class FolderPairPanel;
class CompareProgressPanel;
template <class GuiPanel> class FolderPairCallback;


class MainDialog : public MainDialogGenerated
{
public:
    //default behavior, application start, restores last used config
    static void create(const Zstring& globalConfigFilePath);

    //when loading dynamically assembled config,
    //when switching language,
    //or switching from batch run to GUI on warnings
    static void create(const Zstring& globalConfigFilePath,
                       const XmlGlobalSettings* globalSettings, //optional: take over ownership => save on exit
                       const XmlGuiConfig& guiCfg,
                       const std::vector<Zstring>& referenceFiles,
                       bool startComparison);

private:
    MainDialog(const Zstring& globalConfigFilePath,
               const XmlGuiConfig& guiCfg,
               const std::vector<Zstring>& referenceFiles,
               const XmlGlobalSettings& globalSettings); //take over ownership => save on exit
    ~MainDialog();

    void onBeforeSystemShutdown(); //last chance to do something useful before killing the application!

    friend class StatusHandlerTemporaryPanel;
    friend class StatusHandlerFloatingDialog;
    friend class FolderPairFirst;
    friend class FolderPairPanel;
    template <class GuiPanel>
    friend class FolderPairCallback;
    friend class PanelMoveWindow;

    //mitigate potential reentrancy in during window message pumping:
    void disableGuiElements(bool enableAbort); //dis-/enables all elements (except abort button) that might receive user input
    void enableGuiElements();                  //during long-running processes: comparison, deletion

    //configuration load/save
    void setLastUsedConfig(const XmlGuiConfig& guiConfig, const std::vector<Zstring>& cfgFilePaths);

    XmlGuiConfig getConfig() const;
    void setConfig(const XmlGuiConfig& newGuiCfg, const std::vector<Zstring>& referenceFiles);

    void setGlobalCfgOnInit(const XmlGlobalSettings& globalSettings); //messes with Maximize(), window sizes, so call just once!
    XmlGlobalSettings getGlobalCfgBeforeExit(); //destructive "get" thanks to "Iconize(false), Maximize(false)"

    bool loadConfiguration(const std::vector<Zstring>& filepaths, bool ignoreBrokenConfig = false); //"false": error/cancel

    bool trySaveConfig     (const Zstring* guiCfgPath);   //
    bool trySaveBatchConfig(const Zstring* batchCfgPath); //"false": error/cancel
    bool saveOldConfig();                                 //

    void updateGlobalFilterButton();

    void setViewFilterDefault();

    void cfgHistoryRemoveObsolete(const std::vector<Zstring>& filepaths);

    void insertAddFolderPair(const std::vector<LocalPairConfig>& newPairs, size_t pos);
    void moveAddFolderPairUp(size_t pos);
    void removeAddFolderPair(size_t pos);
    void setAddFolderPairs(const std::vector<LocalPairConfig>& newPairs);

    void updateGuiForFolderPair(); //helper method: add usability by showing/hiding buttons related to folder pairs
    void recalcMaxFolderPairsVisible();

    //main method for putting gridDataView on UI: updates data respecting current view settings
    void updateGui(); //kitchen-sink update
    void updateGuiDelayedIf(bool condition); //400 ms delay

    void updateGridViewData();     //
    void updateStatistics();       // more fine-grained updaters
    void updateUnsavedCfgStatus(); //

    std::vector<std::wstring> getJobNames() const;

    //context menu functions
    std::vector<FileSystemObject*> getGridSelection(bool fromLeft = true, bool fromRight = true) const;
    std::vector<FileSystemObject*> getTreeSelection() const;

    void setSyncDirManually (const std::vector<FileSystemObject*>& selection, SyncDirection direction);
    void setIncludedManually(const std::vector<FileSystemObject*>& selection, bool setIncluded);
    void copyGridSelectionToClipboard(const zen::Grid& grid);
    void copyPathsToClipboard(const std::vector<FileSystemObject*>& selectionL,
                              const std::vector<FileSystemObject*>& selectionR);

    void copyToAlternateFolder(const std::vector<FileSystemObject*>& selectionL,
                               const std::vector<FileSystemObject*>& selectionR);

    void deleteSelectedFiles(const std::vector<FileSystemObject*>& selectionL,
                             const std::vector<FileSystemObject*>& selectionR, bool moveToRecycler);

    void openExternalApplication(const Zstring& commandLinePhrase, bool leftSide,
                                 const std::vector<FileSystemObject*>& selectionL,
                                 const std::vector<FileSystemObject*>& selectionR); //selection may be empty

    void setStatusBarFileStats(FileView::FileStats statsLeft, FileView::FileStats statsRight);

    void setStatusInfo(const wxString& text, bool highlight); //(permanently) set status bar center text
    void flashStatusInfo(const wxString& text); //temporarily show different status
    void popStatusInfo();

    //events
    void onGridKeyEvent(wxKeyEvent& event, zen::Grid& grid, bool leftSide);

    void onTreeKeyEvent    (wxKeyEvent& event);
    void onSetLayoutContext(wxMouseEvent& event);
    void onLocalKeyEvent   (wxKeyEvent& event);

    void applyCompareConfig(bool setDefaultViewType);

    //context menu handler methods
    void onGridContextRim(zen::GridContextMenuEvent& event, bool leftSide);

    void onGridGroupContextRim(zen::GridClickEvent& event, bool leftSide);

    void onGridContextRim(const std::vector<FileSystemObject*>& selection,
                          const std::vector<FileSystemObject*>& selectionL,
                          const std::vector<FileSystemObject*>& selectionR, bool leftSide, wxPoint mousePos);

    void onTreeGridContext(zen::GridContextMenuEvent& event);

    void onTreeGridSelection(zen::GridSelectEvent& event);

    void onDialogFilesDropped(zen::FileDropEvent& event);

    void onDirSelected(wxCommandEvent& event);
    void onDirManualCorrection(wxCommandEvent& event);

    void onCheckRows       (CheckRowsEvent&     event);
    void onSetSyncDirection(SyncDirectionEvent& event);

    void swapSides();

    void onGridDoubleClickRim(zen::GridClickEvent& event, bool leftSide);

    void onGridLabelLeftClickRim(zen::GridLabelClickEvent& event, bool onLeft);
    void onGridLabelLeftClickC  (zen::GridLabelClickEvent& event);

    void onGridLabelContextRim(zen::GridLabelClickEvent& event, bool leftSide);
    void onGridLabelContextC  (zen::GridLabelClickEvent& event);

    void onToggleViewType  (wxCommandEvent& event) override;
    void onToggleViewButton(wxCommandEvent& event) override;

    void onViewTypeContextMouse  (wxMouseEvent&   event) override;
    void onViewFilterContext     (wxCommandEvent& event) override { onViewFilterContext(static_cast<wxEvent&>(event)); }
    void onViewFilterContextMouse(wxMouseEvent&   event) override { onViewFilterContext(static_cast<wxEvent&>(event)); }
    void onViewFilterContext(wxEvent& event);

    void onConfigNew     (wxCommandEvent& event) override;
    void onConfigSave    (wxCommandEvent& event) override;
    void onConfigSaveAs  (wxCommandEvent& event) override { trySaveConfig(nullptr); }
    void onSaveAsBatchJob(wxCommandEvent& event) override { trySaveBatchConfig(nullptr); }
    void onConfigLoad    (wxCommandEvent& event) override;

    void onCfgGridSelection  (zen::GridSelectEvent& event);
    void onCfgGridDoubleClick(zen::GridClickEvent& event);
    void onCfgGridKeyEvent            (wxKeyEvent& event);
    void onCfgGridContext       (zen::GridContextMenuEvent& event);
    void onCfgGridLabelContext  (zen::GridLabelClickEvent& event);
    void onCfgGridLabelLeftClick(zen::GridLabelClickEvent& event);

    void removeSelectedCfgHistoryItems(bool removeFromDisk);
    void renameSelectedCfgHistoryItem();

    void onStartupUpdateCheck(wxIdleEvent& event);
    void onLayoutWindowAsync (wxIdleEvent& event);

    void onResizeLeftFolderWidth(wxEvent& event);
    void onResizeTopButtonPanel (wxEvent& event);
    void onResizeConfigPanel    (wxEvent& event);
    void onResizeViewPanel      (wxEvent& event);
    void onToggleLog            (wxCommandEvent& event) override;
    void onCompare              (wxCommandEvent& event) override;
    void onStartSync            (wxCommandEvent& event) override;
    void onClose                (wxCloseEvent&   event) override;
    void onSwapSides            (wxCommandEvent& event) override { swapSides(); }

    void startSyncForSelecction(const std::vector<FileSystemObject*>& selection);

    void onCmpSettings    (wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::compare, -1); }
    void onSyncSettings   (wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::sync,    -1); }
    void onConfigureFilter(wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::filter,  -1); }

    void onCompSettingsContext     (wxCommandEvent& event) override { onCompSettingsContext(static_cast<wxEvent&>(event)); }
    void onCompSettingsContextMouse(wxMouseEvent&   event) override { onCompSettingsContext(static_cast<wxEvent&>(event)); }
    void onSyncSettingsContext     (wxCommandEvent& event) override { onSyncSettingsContext(static_cast<wxEvent&>(event)); }
    void onSyncSettingsContextMouse(wxMouseEvent&   event) override { onSyncSettingsContext(static_cast<wxEvent&>(event)); }
    void onGlobalFilterContext     (wxCommandEvent& event) override { onGlobalFilterContext(static_cast<wxEvent&>(event)); }
    void onGlobalFilterContextMouse(wxMouseEvent&   event) override { onGlobalFilterContext(static_cast<wxEvent&>(event)); }

    void onCompSettingsContext(wxEvent& event);
    void onSyncSettingsContext(wxEvent& event);
    void onGlobalFilterContext(wxEvent& event);

    void showConfigDialog(SyncConfigPanel panelToShow, int localPairIndexToShow);

    void updateConfigLastRunStats(time_t lastRunTime, SyncResult result, const AbstractPath& logFilePath);

    void setLastOperationLog(const ProcessSummary& summary, const std::shared_ptr<const zen::ErrorLog>& errorLog);
    void showLogPanel(bool show);

    void filterExtension(const Zstring& extension, bool include);
    void filterShortname(const FileSystemObject& fsObj, bool include);
    void filterItems(const std::vector<FileSystemObject*>& selection, bool include);
    void addFilterPhrase(const Zstring& phrase, bool include, bool requireNewLine);

    void onTopFolderPairAdd   (wxCommandEvent& event) override;
    void onTopFolderPairRemove(wxCommandEvent& event) override;
    void onRemoveFolderPair   (wxCommandEvent& event);
    void onShowFolderPairOptions(wxEvent& event);

    void onTopLocalCompCfg  (wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::compare, 0); }
    void onTopLocalSyncCfg  (wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::sync,       0); }
    void onTopLocalFilterCfg(wxCommandEvent& event) override { showConfigDialog(SyncConfigPanel::filter,     0); }

    void onLocalCompCfg  (wxCommandEvent& event);
    void onLocalSyncCfg  (wxCommandEvent& event);
    void onLocalFilterCfg(wxCommandEvent& event);

    void onTopFolderPairKeyEvent(wxKeyEvent& event);
    void onAddFolderPairKeyEvent(wxKeyEvent& event);

    void applyFilterConfig();
    void applySyncDirections();

    void showFindPanel(bool show); //CTRL + F
    void startFindNext(bool searchAscending); //F3

    void resetLayout();

    void onSearchGridEnter(wxCommandEvent& event) override;
    void onHideSearchPanel(wxCommandEvent& event) override;
    void onSearchPanelKeyPressed(wxKeyEvent& event);

    //menu events
    void onOpenMenuTools(wxMenuEvent& event);
    void onMenuOptions        (wxCommandEvent& event) override;
    void onMenuExportFileList (wxCommandEvent& event) override;
    void onMenuResetLayout    (wxCommandEvent& event) override { resetLayout(); }
    void onMenuFindItem       (wxCommandEvent& event) override { showFindPanel(true /*show*/); } //CTRL + F
    void onMenuCheckVersion   (wxCommandEvent& event) override;
    void onMenuCheckVersionAutomatically(wxCommandEvent& event) override;
    void onMenuAbout          (wxCommandEvent& event) override;
    void onShowHelp           (wxCommandEvent& event) override { wxLaunchDefaultBrowser(L"https://freefilesync.org/manual.php?topic=freefilesync"); }
    void onMenuQuit           (wxCommandEvent& event) override { Close(); }

    void switchProgramLanguage(wxLanguage langId);

    std::set<wxMenuItem*> detachedMenuItems_; //owning pointers!!!
    //alternatives: 1. std::set<unique_ptr<>>? key is const => no support for moving items out! 2. std::map<wxMenuItem*, unique_ptr<>>: redundant info, inconvenient use

    void clearGrid(ptrdiff_t pos = -1);

    //***********************************************
    //application variables are stored here:

    //global settings shared by GUI and batch mode
    XmlGlobalSettings globalCfg_;

    const Zstring globalConfigFilePath_;

    //-------------------------------------
    //program configuration
    XmlGuiConfig currentCfg_; //caveat: some parts are owned by GUI controls! see setConfig()

    //used when saving configuration
    std::vector<Zstring> activeConfigFiles_; //name of currently loaded config files: NOT owned by m_gridCfgHistory, see onCfgGridSelection()

    XmlGuiConfig lastSavedCfg_; //support for: "Save changed configuration?" dialog

    const Zstring lastRunConfigPath_ = getLastRunConfigPath(); //let's not use another static...
    //-------------------------------------

    //the prime data structure of this tool *bling*:
    FolderComparison folderCmp_; //optional!: sync button not available if empty
    std::shared_ptr<const zen::ErrorLog> errorLogCmp_;

    //folder pairs:
    std::unique_ptr<FolderPairFirst> firstFolderPair_; //always bound!!!
    std::vector<FolderPairPanel*> additionalFolderPairs_; //additional pairs to the first pair

    std::optional<double> addPairCountLast_;

    //-------------------------------------
    //fight sluggish GUI: FolderPairPanel are too expensive to casually throw away and recreate!
    struct DeleteWxWindow { void operator()(wxWindow* win) const { win->Destroy(); } };

    std::vector<std::unique_ptr<FolderPairPanel, DeleteWxWindow>> folderPairScrapyard_;
    //-------------------------------------

    //***********************************************
    //status bar center text
    std::vector<wxString> statusTxts_; //the first one is the original/non-flash status message
    bool statusTxtHighlightFirst_ = false;

    //compare status panel (hidden on start, shown when comparing)
    std::unique_ptr<CompareProgressPanel> compareStatus_; //always bound

    LogPanel* logPanel_ = nullptr;

    //toggle to display configuration preview instead of comparison result:
    //for read access use: m_bpButtonViewType->isActive()
    //when changing value use:
    void setGridViewType(GridViewType vt);

    wxAuiManager auiMgr_; //implement dockable GUI design

    wxString defaultPerspective_;

    time_t manualTimeSpanFrom_ = 0;
    time_t manualTimeSpanTo_   = 0; //buffer manual time span selection at session level

    //regenerate view filter button labels only when necessary:
    std::unordered_map<const zen::ToggleButton*, int /*itemCount*/> buttonLabelItemCount_;

    const std::shared_ptr<HistoryList> folderHistoryLeft_;  //shared by all wxComboBox dropdown controls
    const std::shared_ptr<HistoryList> folderHistoryRight_; //

    zen::AsyncGuiQueue guiQueue_; //schedule and run long-running tasks asynchronously, but process results on GUI queue

    wxWindowID focusAfterCloseLog_    = wxID_ANY; //
    wxWindowID focusAfterCloseSearch_ = wxID_ANY; //restore focus after panel is closed
    //don't save wxWindow* to arbitrary window: might not exist anymore when hideFindPanel() uses it!!! (e.g. some folder pair panel)

    //mitigate reentrancy:
    bool localKeyEventsEnabled_ = true;
    bool operationInProgress_  = false; //e.g. do NOT allow dialog exit while sync is running => crash!!!

    TempFileBuffer tempFileBuf_; //buffer temporary copies of non-native files for %local_path%

    const wxImage imgTrashSmall_;
    const wxImage imgFileManagerSmall_;

    const zen::SharedRef<std::function<void()>> onBeforeSystemShutdownCookie_ = zen::makeSharedRef<std::function<void()>>([this] { onBeforeSystemShutdown(); });
};
}

#endif //MAIN_DLG_H_8910481324545644545