diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2019-05-12 22:44:22 +0000 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2019-05-12 22:44:22 +0000 |
commit | 2cb4599782d970f386a67dfd4f4dab0d531d4348 (patch) | |
tree | b873b15f50a981aacf8bb49fd646bfded2e7a73b | |
parent | Merge branch '10.11' into 'master' (diff) | |
parent | 10.12 (diff) | |
download | FreeFileSync-2cb4599782d970f386a67dfd4f4dab0d531d4348.tar.gz FreeFileSync-2cb4599782d970f386a67dfd4f4dab0d531d4348.tar.bz2 FreeFileSync-2cb4599782d970f386a67dfd4f4dab0d531d4348.zip |
Merge branch '10.12' into 'master'10.12
10.12
See merge request opensource-tracking/FreeFileSync!9
109 files changed, 533 insertions, 485 deletions
diff --git a/Changelog.txt b/Changelog.txt index f4a1c172..62f5a49d 100755 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,5 +1,18 @@ -FreeFileSync 10.11 ------------------- +FreeFileSync 10.12 [2019-05-12] +------------------------------- +Show sync start time and date in progress dialog title +Added duration of comparison to log +Show all total times in full HH:MM:SS format +Added sync start time to log file header +Add Windows Defender exclusions to fix CURLE_OPERATION_TIMEDOUT +New RealTimeSync option to hide console window +Support launching through symlink (Windows) +Dropped support for Windows XP, Server 2003, and Vista +Reduced installation size by 25% + + +FreeFileSync 10.11 [2019-04-11] +------------------------------- Last FreeFileSync version supporting Windows XP and Vista Fixed crash on multi-monitor set up Fixed dialogs not showing after opening UAC prompt diff --git a/FreeFileSync/Build/FreeFileSync.desktop b/FreeFileSync/Build/FreeFileSync.desktop index a9f0a0b3..a9f0a0b3 100644..100755 --- a/FreeFileSync/Build/FreeFileSync.desktop +++ b/FreeFileSync/Build/FreeFileSync.desktop diff --git a/FreeFileSync/Build/Languages/german.lng b/FreeFileSync/Build/Languages/german.lng index c77d82c4..929a8eb1 100755 --- a/FreeFileSync/Build/Languages/german.lng +++ b/FreeFileSync/Build/Languages/german.lng @@ -7,6 +7,155 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> +<source>Cannot read file %x.</source> +<target>Die Datei %x kann nicht gelesen werden.</target> + +<source> +Unexpected size of data stream. +Expected: %x bytes +Actual: %y bytes +</source> +<target> +Unerwartete Größe des Datenstroms. +Erwartet: %x bytes +Tatsächlich: %y bytes +</target> + +<source>Cannot write file %x.</source> +<target>Die Datei %x kann nicht geschrieben werden.</target> + +<source>Cannot write permissions of %x.</source> +<target>Die Berechtigungen von %x können nicht geschrieben werden.</target> + +<source>Operation not supported between different devices.</source> +<target>Der Vorgang wird zwischen unterschiedlichen Geräten nicht unterstützt.</target> + +<source>Cannot delete file %x.</source> +<target>Die Datei %x kann nicht gelöscht werden.</target> + +<source>Cannot delete symbolic link %x.</source> +<target>Die symbolischen Verknüpfung %x kann nicht gelöscht werden.</target> + +<source>Cannot delete directory %x.</source> +<target>Das Verzeichnis %x kann nicht gelöscht werden.</target> + +<source>Cannot move file %x to %y.</source> +<target>Die Datei %x kann nicht nach %y verschoben werden.</target> + +<source>Cannot copy symbolic link %x to %y.</source> +<target>Die symbolische Verknüpfung %x kann nicht nach %y kopiert werden.</target> + +<source>Error Code %x</source> +<target>Fehlercode %x</target> + +<source>Cannot read directory %x.</source> +<target>Das Verzeichnis %x kann nicht gelesen werden.</target> + +<source>Cannot write modification time of %x.</source> +<target>Die Änderungszeit von %x kann nicht geschrieben werden.</target> + +<source>Cannot read file attributes of %x.</source> +<target>Die Dateiattribute von %x können nicht gelesen werden.</target> + +<source>Cannot create directory %x.</source> +<target>Das Verzeichnis %x kann nicht erstellt werden.</target> + +<source>Cannot determine final path for %x.</source> +<target>Der endgültige Pfad für %x kann nicht ermittelt werden.</target> + +<source>Operation not supported by device.</source> +<target>Der Vorgang wird vom Gerät nicht unterstützt.</target> + +<source>Cannot resolve symbolic link %x.</source> +<target>Die symbolische Verknüpfung %x kann nicht aufgelöst werden.</target> + +<source>Unable to move %x to the recycle bin.</source> +<target>%x kann nicht in den Papierkorb verschoben werden.</target> + +<source>Authentication completed.</source> +<target>Authentifizierung abgeschlossen.</target> + +<source>You may close this page now and continue with FreeFileSync.</source> +<target>Sie können diese Seite nun schließen und mit FreeFileSync fortfahren.</target> + +<source>Authentication failed.</source> +<target>Authentifizierung fehlgeschlagen.</target> + +<source>Unable to connect to %x.</source> +<target>Es kann keine Verbindung zu %x aufgebaut werden.</target> + +<source>Cannot find %x.</source> +<target>%x wurde nicht gefunden.</target> + +<source>The name %x is used by more than one item in the folder.</source> +<target>Der Name %x wird von mehr als einem Element im Ordner verwendet.</target> + +<source>Please authorize access to user account %x.</source> +<target>Bitte autorisieren Sie den Zugriff auf das Nutzerkonto %x.</target> + +<source>Cannot open file %x.</source> +<target>Die Datei %x kann nicht geöffnet werden.</target> + +<source>The name %x is already used by another item.</source> +<target>Der Name %x wird bereits von einem anderen Element verwendet.</target> + +<source>Cannot determine free disk space for %x.</source> +<target>Der freie Speicherplatz für %x konnte nicht ermittelt werden.</target> + +<source>Unable to disconnect from %x.</source> +<target>Die Verbindung zu %x kann nicht getrennt werden.</target> + +<source>Unable to access %x.</source> +<target>Auf %x kann nicht zugegriffen werden.</target> + +<source>Failed to get information about server %x.</source> +<target>Informationen über den Server %x konnten nicht abgerufen werden.</target> + +<source>Cannot monitor directory %x.</source> +<target>Das Verzeichnis %x kann nicht überwacht werden.</target> + +<source>Cannot find device %x.</source> +<target>Das Gerät %x wurde nicht gefunden.</target> + +<source>Cannot open directory %x.</source> +<target>Das Verzeichnis %x kann nicht geöffnet werden.</target> + +<source>Unsupported item type.</source> +<target>Der Elementstyp wird nicht unterstützt.</target> + +<source>Incorrect command line:</source> +<target>Ungültige Befehlszeile:</target> + +<source>The server does not support authentication via %x.</source> +<target>Der Server unterstützt keine Authentifizierung über %x.</target> + +<source>Required:</source> +<target>Benötigt:</target> + +<source> +<pluralform>Operation timed out after 1 second.</pluralform> +<pluralform>Operation timed out after %x seconds.</pluralform> +</source> +<target> +<pluralform>Der Vorgang hat das Zeitlimit von 1 Sekunde überschritten.</pluralform> +<pluralform>Der Vorgang hat das Zeitlimit von %x Sekunden überschritten.</pluralform> +</target> + +<source> +<pluralform>Cannot wait on more than 1 connection at a time.</pluralform> +<pluralform>Cannot wait on more than %x connections at a time.</pluralform> +</source> +<target> +<pluralform>Auf mehr als 1 Verbindung kann nicht gleichzeitig gewartet werden.</pluralform> +<pluralform>Auf mehr als %x Verbindungen kann nicht gleichzeitig gewartet werden.</pluralform> +</target> + +<source>Active connections: %x</source> +<target>Aktive Verbindungen: %x</target> + +<source>Failed to open SFTP channel number %x.</source> +<target>Der SFTP Kanal Nummer %x konnte nicht geöffnet werden.</target> + <source>Both sides have changed since last synchronization.</source> <target>Beide Seiten wurden seit der letzten Synchronisation verändert.</target> @@ -109,9 +258,6 @@ <source>Installation files are corrupted. Please reinstall FreeFileSync.</source> <target>Die Installationsdateien sind beschädigt. Bitte installieren Sie FreeFileSync neu.</target> -<source>Cannot load file %x.</source> -<target>Die Datei %x kann nicht geladen werden.</target> - <source>Cannot find the following folders:</source> <target>Die folgenden Ordner wurden nicht gefunden:</target> @@ -139,6 +285,9 @@ <pluralform>%x Elemente gefunden</pluralform> </target> +<source>Time elapsed:</source> +<target>Vergangene Zeit:</target> + <source>File %x has an invalid date.</source> <target>Die Datei %x hat ein ungültiges Datum.</target> @@ -157,9 +306,6 @@ <source>Items differ in attributes only</source> <target>Die Elemente unterscheiden sich nur in Attributen</target> -<source>The name %x is used by more than one item in the folder.</source> -<target>Der Name %x wird von mehr als einem Element im Ordner verwendet.</target> - <source>Resolving symbolic link %x</source> <target>Folge der symbolischen Verknüpfung %x</target> @@ -220,6 +366,15 @@ <source>Out of memory.</source> <target>Nicht genügend Arbeitsspeicher.</target> +<source>Show in Explorer</source> +<target>Im Explorer anzeigen</target> + +<source>Open with default application</source> +<target>Mit Standardanwendung öffnen</target> + +<source>Browse directory</source> +<target>Verzeichnis öffnen</target> + <source>Database file %x is incompatible.</source> <target>Die Datenbankdatei %x ist nicht kompatibel.</target> @@ -232,12 +387,6 @@ <source>Database file is corrupted:</source> <target>Die Datenbankdatei ist beschädigt:</target> -<source>Cannot write file %x.</source> -<target>Die Datei %x kann nicht geschrieben werden.</target> - -<source>Cannot read file %x.</source> -<target>Die Datei %x kann nicht gelesen werden.</target> - <source>The database files do not yet contain information about the last synchronization.</source> <target>Die Datenbankdateien beinhalten noch keine Informationen zur letzten Synchronisation.</target> @@ -256,9 +405,6 @@ <source>Cannot get process information.</source> <target>Prozessinformationen können nicht gelesen werden.</target> -<source>Cannot read file attributes of %x.</source> -<target>Die Dateiattribute von %x können nicht gelesen werden.</target> - <source>Waiting while directory is locked:</source> <target>Warte während das Verzeichnis gesperrt ist:</target> @@ -385,27 +531,12 @@ <pluralform>%x Threads</pluralform> </target> -<source>Cannot read directory %x.</source> -<target>Das Verzeichnis %x kann nicht gelesen werden.</target> - <source>%x/sec</source> <target>%x/sek</target> <source>%x items</source> <target>%x Elemente</target> -<source>Show in Explorer</source> -<target>Im Explorer anzeigen</target> - -<source>Open with default application</source> -<target>Mit Standardanwendung öffnen</target> - -<source>Browse directory</source> -<target>Verzeichnis öffnen</target> - -<source>Unable to connect to %x.</source> -<target>Es kann keine Verbindung zu %x aufgebaut werden.</target> - <source>Completed successfully</source> <target>Erfolgreich abgeschlossen</target> @@ -451,9 +582,6 @@ <source>Cannot write file attributes of %x.</source> <target>Die Dateiattribute von %x können nicht geschrieben werden.</target> -<source>Cannot open file %x.</source> -<target>Die Datei %x kann nicht geöffnet werden.</target> - <source>%x and %y have different content.</source> <target>%x und %y haben unterschiedlichen Inhalt.</target> @@ -484,21 +612,12 @@ <source>Source item %x not found</source> <target>Das Quellelement %x wurde nicht gefunden.</target> -<source>Cannot move file %x to %y.</source> -<target>Die Datei %x kann nicht nach %y verschoben werden.</target> - <source>Parent folder %x is not existing.</source> <target>Der übergeordnete Ordner %x existiert nicht.</target> -<source>The name %x is already used by another item.</source> -<target>Der Name %x wird bereits von einem anderen Element verwendet.</target> - <source>Cannot copy file %x to %y.</source> <target>Die Datei %x kann nicht nach %y kopiert werden.</target> -<source>Cannot copy symbolic link %x to %y.</source> -<target>Die symbolische Verknüpfung %x kann nicht nach %y kopiert werden.</target> - <source>Creating a Volume Shadow Copy for %x...</source> <target>Erstelle eine Volumenschattenkopie für %x...</target> @@ -529,9 +648,6 @@ <source>Not enough free disk space available in:</source> <target>Nicht genügend freier Speicher verfügbar für:</target> -<source>Required:</source> -<target>Benötigt:</target> - <source>Available:</source> <target>Verfügbar:</target> @@ -565,122 +681,6 @@ <source>Unable to create time stamp for versioning:</source> <target>Der Zeitstempel für die Versionierung kann nicht erstellt werden:</target> -<source> -Unexpected size of data stream. -Expected: %x bytes -Actual: %y bytes -</source> -<target> -Unerwartete Größe des Datenstroms. -Erwartet: %x bytes -Tatsächlich: %y bytes -</target> - -<source>Cannot write permissions of %x.</source> -<target>Die Berechtigungen von %x können nicht geschrieben werden.</target> - -<source>Operation not supported between different devices.</source> -<target>Der Vorgang wird zwischen unterschiedlichen Geräten nicht unterstützt.</target> - -<source>Cannot delete file %x.</source> -<target>Die Datei %x kann nicht gelöscht werden.</target> - -<source>Cannot delete symbolic link %x.</source> -<target>Die symbolischen Verknüpfung %x kann nicht gelöscht werden.</target> - -<source>Cannot delete directory %x.</source> -<target>Das Verzeichnis %x kann nicht gelöscht werden.</target> - -<source>Error Code %x</source> -<target>Fehlercode %x</target> - -<source>Cannot write modification time of %x.</source> -<target>Die Änderungszeit von %x kann nicht geschrieben werden.</target> - -<source>Cannot create directory %x.</source> -<target>Das Verzeichnis %x kann nicht erstellt werden.</target> - -<source>Cannot determine final path for %x.</source> -<target>Der endgültige Pfad für %x kann nicht ermittelt werden.</target> - -<source>Operation not supported by device.</source> -<target>Der Vorgang wird vom Gerät nicht unterstützt.</target> - -<source>Cannot resolve symbolic link %x.</source> -<target>Die symbolische Verknüpfung %x kann nicht aufgelöst werden.</target> - -<source>Unable to move %x to the recycle bin.</source> -<target>%x kann nicht in den Papierkorb verschoben werden.</target> - -<source>Authentication completed.</source> -<target>Authentifizierung abgeschlossen.</target> - -<source>You may close this page now and continue with FreeFileSync.</source> -<target>Sie können diese Seite nun schließen und mit FreeFileSync fortfahren.</target> - -<source>Authentication failed.</source> -<target>Authentifizierung fehlgeschlagen.</target> - -<source>Cannot find %x.</source> -<target>%x wurde nicht gefunden.</target> - -<source>Please authorize access to user account %x.</source> -<target>Bitte autorisieren Sie den Zugriff auf das Nutzerkonto %x.</target> - -<source>Cannot determine free disk space for %x.</source> -<target>Der freie Speicherplatz für %x konnte nicht ermittelt werden.</target> - -<source>Unable to disconnect from %x.</source> -<target>Die Verbindung zu %x kann nicht getrennt werden.</target> - -<source>Unable to access %x.</source> -<target>Auf %x kann nicht zugegriffen werden.</target> - -<source>Failed to get information about server %x.</source> -<target>Informationen über den Server %x konnten nicht abgerufen werden.</target> - -<source>Cannot monitor directory %x.</source> -<target>Das Verzeichnis %x kann nicht überwacht werden.</target> - -<source>Cannot find device %x.</source> -<target>Das Gerät %x wurde nicht gefunden.</target> - -<source>Cannot open directory %x.</source> -<target>Das Verzeichnis %x kann nicht geöffnet werden.</target> - -<source>Unsupported item type.</source> -<target>Der Elementstyp wird nicht unterstützt.</target> - -<source>Incorrect command line:</source> -<target>Ungültige Befehlszeile:</target> - -<source>The server does not support authentication via %x.</source> -<target>Der Server unterstützt keine Authentifizierung über %x.</target> - -<source> -<pluralform>Operation timed out after 1 second.</pluralform> -<pluralform>Operation timed out after %x seconds.</pluralform> -</source> -<target> -<pluralform>Der Vorgang hat das Zeitlimit von 1 Sekunde überschritten.</pluralform> -<pluralform>Der Vorgang hat das Zeitlimit von %x Sekunden überschritten.</pluralform> -</target> - -<source> -<pluralform>Cannot wait on more than 1 connection at a time.</pluralform> -<pluralform>Cannot wait on more than %x connections at a time.</pluralform> -</source> -<target> -<pluralform>Auf mehr als 1 Verbindung kann nicht gleichzeitig gewartet werden.</pluralform> -<pluralform>Auf mehr als %x Verbindungen kann nicht gleichzeitig gewartet werden.</pluralform> -</target> - -<source>Active connections: %x</source> -<target>Aktive Verbindungen: %x</target> - -<source>Failed to open SFTP channel number %x.</source> -<target>Der SFTP Kanal Nummer %x konnte nicht geöffnet werden.</target> - <source>Drag && drop</source> <target>Drag && Drop</target> @@ -747,6 +747,9 @@ Tatsächlich: %y bytes <source>Command line:</source> <target>Befehlszeile:</target> +<source>&Hide console window</source> +<target>&Konsolenfenster verbergen</target> + <source> The command is triggered if: - files or subfolders change @@ -782,8 +785,8 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Waiting until directory is available:</source> <target>Warte bis Verzeichnis verfügbar ist:</target> -<source>&Restore</source> -<target>&Wiederherstellen</target> +<source>&Configure</source> +<target>&Konfigurieren</target> <source>&Show error message</source> <target>&Fehlermeldung zeigen</target> @@ -830,8 +833,8 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Nothing to synchronize</source> <target>Es gibt nichts zu synchronisieren</target> -<source>Executing command %x</source> -<target>Führe Befehl aus: %x</target> +<source>Executing command:</source> +<target>Führe Befehl aus:</target> <source>You can switch to FreeFileSync's main window to resolve this issue.</source> <target>Sie können auf FreeFileSyncs Hauptfenster wechseln, um das Problem zu beheben.</target> @@ -1273,9 +1276,6 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Time remaining:</source> <target>Verbleibende Zeit:</target> -<source>Time elapsed:</source> -<target>Vergangene Zeit:</target> - <source>Bytes</source> <target>Bytes</target> @@ -1567,12 +1567,6 @@ Dadurch wird ein konsistenter Datenstand auch bei schweren Fehlern garantiert. <source>&Delete</source> <target>&Löschen</target> -<source>Include all</source> -<target>Alle einschließen</target> - -<source>Exclude all</source> -<target>Alle ausschließen</target> - <source>Show icons:</source> <target>Symbole anzeigen:</target> @@ -1885,6 +1879,9 @@ Dadurch wird ein konsistenter Datenstand auch bei schweren Fehlern garantiert. <source>Minimum version count must be smaller than maximum count.</source> <target>Die minimale Anzahl der Versionen muss kleiner als die maximale sein.</target> +<source>&Restore</source> +<target>&Wiederherstellen</target> + <source>Files</source> <target>Dateien</target> @@ -1951,6 +1948,9 @@ Dadurch wird ein konsistenter Datenstand auch bei schweren Fehlern garantiert. <source>The file is locked by another process:</source> <target>Die Datei wird von einem anderen Prozess gesperrt:</target> +<source>Checking file permissions failed for folder %x.</source> +<target>Die Prüfung der Dateiberechtigungen für Ordner %x ist fehlgeschlagen.</target> + <source>Cannot read security context of %x.</source> <target>Der Sicherheitskontext von %x kann nicht gelesen werden.</target> @@ -2002,12 +2002,12 @@ Dadurch wird ein konsistenter Datenstand auch bei schweren Fehlern garantiert. <source>Cannot change process I/O priorities.</source> <target>Die Eingabe/Ausgabe Prioritäten für den Prozess können nicht geändert werden.</target> -<source>Unable to shut down the system.</source> -<target>Das System kann nicht heruntergefahren werden.</target> - <source>Checking recycle bin failed for folder %x.</source> <target>Die Prüfung des Papierkorbs für Ordner %x ist fehlgeschlagen.</target> +<source>Unable to shut down the system.</source> +<target>Das System kann nicht heruntergefahren werden.</target> + <source>Prepare installation</source> <target>Installation vorbereiten</target> diff --git a/FreeFileSync/Build/Resources.zip b/FreeFileSync/Build/Misc/Icons.zip Binary files differindex 12931409..052ce17c 100755 --- a/FreeFileSync/Build/Resources.zip +++ b/FreeFileSync/Build/Misc/Icons.zip diff --git a/FreeFileSync/Build/RealTimeSync.desktop b/FreeFileSync/Build/RealTimeSync.desktop index 789a9d35..789a9d35 100644..100755 --- a/FreeFileSync/Build/RealTimeSync.desktop +++ b/FreeFileSync/Build/RealTimeSync.desktop diff --git a/FreeFileSync/Source/Makefile b/FreeFileSync/Source/Makefile index 00411a86..89cb74a8 100755 --- a/FreeFileSync/Source/Makefile +++ b/FreeFileSync/Source/Makefile @@ -40,6 +40,7 @@ CPP_FILES+=base/algorithm.cpp CPP_FILES+=base/application.cpp CPP_FILES+=base/binary.cpp CPP_FILES+=base/comparison.cpp +CPP_FILES+=base/config.cpp CPP_FILES+=base/db_file.cpp CPP_FILES+=base/dir_lock.cpp CPP_FILES+=base/ffs_paths.cpp @@ -50,22 +51,21 @@ CPP_FILES+=base/icon_loader.cpp CPP_FILES+=base/localization.cpp CPP_FILES+=base/parallel_scan.cpp CPP_FILES+=base/path_filter.cpp -CPP_FILES+=base/process_xml.cpp CPP_FILES+=base/perf_check.cpp CPP_FILES+=base/resolve_path.cpp CPP_FILES+=base/status_handler.cpp CPP_FILES+=base/structures.cpp CPP_FILES+=base/synchronization.cpp CPP_FILES+=base/versioning.cpp -CPP_FILES+=fs/abstract.cpp -CPP_FILES+=fs/concrete.cpp -CPP_FILES+=fs/ftp.cpp -CPP_FILES+=fs/gdrive.cpp -CPP_FILES+=fs/init_curl_libssh2.cpp -CPP_FILES+=fs/native.cpp -CPP_FILES+=fs/sftp.cpp -CPP_FILES+=fs/libssh2/init_libssh2.cpp -CPP_FILES+=fs/libssh2/init_open_ssl.cpp +CPP_FILES+=afs/abstract.cpp +CPP_FILES+=afs/concrete.cpp +CPP_FILES+=afs/ftp.cpp +CPP_FILES+=afs/gdrive.cpp +CPP_FILES+=afs/init_curl_libssh2.cpp +CPP_FILES+=afs/native.cpp +CPP_FILES+=afs/sftp.cpp +CPP_FILES+=afs/libssh2/init_libssh2.cpp +CPP_FILES+=afs/libssh2/init_open_ssl.cpp CPP_FILES+=ui/batch_config.cpp CPP_FILES+=ui/abstract_folder_picker.cpp CPP_FILES+=ui/batch_status_handler.cpp diff --git a/FreeFileSync/Source/RealTimeSync/Makefile b/FreeFileSync/Source/RealTimeSync/Makefile index 1d15ab16..8ac2b0b9 100755 --- a/FreeFileSync/Source/RealTimeSync/Makefile +++ b/FreeFileSync/Source/RealTimeSync/Makefile @@ -14,13 +14,13 @@ CXXFLAGS += -isystem/usr/include/gtk-2.0 CPP_FILES= CPP_FILES+=application.cpp +CPP_FILES+=config.cpp CPP_FILES+=gui_generated.cpp CPP_FILES+=main_dlg.cpp CPP_FILES+=tray_menu.cpp CPP_FILES+=monitor.cpp -CPP_FILES+=xml_proc.cpp CPP_FILES+=folder_selector2.cpp -CPP_FILES+=../fs/abstract.cpp +CPP_FILES+=../afs/abstract.cpp CPP_FILES+=../base/icon_buffer.cpp CPP_FILES+=../base/icon_loader.cpp CPP_FILES+=../base/localization.cpp diff --git a/FreeFileSync/Source/RealTimeSync/application.cpp b/FreeFileSync/Source/RealTimeSync/application.cpp index 2366e521..9318bcce 100644 --- a/FreeFileSync/Source/RealTimeSync/application.cpp +++ b/FreeFileSync/Source/RealTimeSync/application.cpp @@ -14,7 +14,7 @@ #include <wx/tooltip.h> #include <wx+/popup_dlg.h> #include <wx+/image_resources.h> -#include "xml_proc.h" +#include "config.h" #include "../base/localization.h" #include "../base/ffs_paths.h" #include "../base/return_codes.h" @@ -49,7 +49,7 @@ bool Application::OnInit() SetAppName(L"RealTimeSync"); - initResourceImages(fff::getResourceDirPf() + Zstr("Resources.zip")); + initResourceImages(fff::getResourceDirPf() + Zstr("Misc") + FILE_NAME_SEPARATOR + Zstr("Icons.zip")); try { diff --git a/FreeFileSync/Source/RealTimeSync/xml_proc.cpp b/FreeFileSync/Source/RealTimeSync/config.cpp index 4cd8636f..bc28e767 100644 --- a/FreeFileSync/Source/RealTimeSync/xml_proc.cpp +++ b/FreeFileSync/Source/RealTimeSync/config.cpp @@ -4,7 +4,7 @@ // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * // ***************************************************************************** -#include "xml_proc.h" +#include "config.h" #include <zen/file_access.h> #include <zenxml/xml.h> #include <wx/intl.h> @@ -14,6 +14,10 @@ using namespace zen; using namespace rts; +//------------------------------------------------------------------------------------------------------------------------------- +const int XML_FORMAT_RTS_CFG = 1; //2019-05-10 +//------------------------------------------------------------------------------------------------------------------------------- + namespace zen { @@ -58,60 +62,70 @@ RtsXmlType getXmlTypeNoThrow(const XmlDoc& doc) //throw() } -void readConfig(const XmlIn& in, XmlRealConfig& config) +void readConfig(const XmlIn& in, XmlRealConfig& cfg, int formatVer) { - in["Directories"](config.directories); - in["Delay" ](config.delay); - in["Commandline"](config.commandline); + in["Directories"](cfg.directories); + in["Delay" ](cfg.delay); + in["Commandline"](cfg.commandline); + + //TODO: remove if clause after migration! 2019-05-10 + if (formatVer < 1) + ; + else + in["Commandline"].attribute("HideConsole", cfg.hideConsoleWindow); } -void writeConfig(const XmlRealConfig& config, XmlOut& out) + +void writeConfig(const XmlRealConfig& cfg, XmlOut& out) { - out["Directories"](config.directories); - out["Delay" ](config.delay); - out["Commandline"](config.commandline); + out["Directories"](cfg.directories); + out["Delay" ](cfg.delay); + out["Commandline"](cfg.commandline); + out["Commandline"].attribute("HideConsole", cfg.hideConsoleWindow); +} } -template <class ConfigType> -void readConfig(const Zstring& filePath, RtsXmlType type, ConfigType& cfg, std::wstring& warningMsg) //throw FileError +void rts::readConfig(const Zstring& filePath, XmlRealConfig& cfg, std::wstring& warningMsg) //throw FileError { XmlDoc doc = loadXml(filePath); //throw FileError - if (getXmlTypeNoThrow(doc) != type) //noexcept + if (getXmlTypeNoThrow(doc) != RtsXmlType::REAL) //noexcept throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath))); + int formatVer = 0; + /*bool success =*/ doc.root().getAttribute("XmlFormat", formatVer); + XmlIn in(doc); - ::readConfig(in, cfg); + ::readConfig(in, cfg, formatVer); try { checkXmlMappingErrors(in, filePath); //throw FileError + + //(try to) migrate old configuration automatically + if (formatVer < XML_FORMAT_RTS_CFG) + try { rts::writeConfig(cfg, filePath); /*throw FileError*/ } + catch (FileError&) { assert(false); } //don't bother user! } catch (const FileError& e) { warningMsg = e.toString(); } } -} - - -void rts::readConfig(const Zstring& filePath, XmlRealConfig& config, std::wstring& warningMsg) //throw FileError -{ - ::readConfig(filePath, RtsXmlType::REAL, config, warningMsg); //throw FileError -} -void rts::writeConfig(const XmlRealConfig& config, const Zstring& filepath) //throw FileError +void rts::writeConfig(const XmlRealConfig& cfg, const Zstring& filePath) //throw FileError { XmlDoc doc("FreeFileSync"); doc.root().setAttribute("XmlType", "REAL"); + doc.root().setAttribute("XmlFormat", XML_FORMAT_RTS_CFG); XmlOut out(doc); - ::writeConfig(config, out); + ::writeConfig(cfg, out); - saveXml(doc, filepath); //throw FileError + saveXml(doc, filePath); //throw FileError } -void rts::readRealOrBatchConfig(const Zstring& filePath, XmlRealConfig& config, std::wstring& warningMsg) //throw FileError +void rts::readRealOrBatchConfig(const Zstring& filePath, XmlRealConfig& cfg, std::wstring& warningMsg) //throw FileError { XmlDoc doc = loadXml(filePath); //throw FileError //quick exit if file is not an FFS XML @@ -137,17 +151,16 @@ void rts::readRealOrBatchConfig(const Zstring& filePath, XmlRealConfig& config, uniqueFolders.insert(folderPathPhraseRight); } - //don't consider failure a warning only: + //don't report failure as warning only: checkXmlMappingErrors(in, filePath); //throw FileError - //--------------------------------------------------------------------------------------- eraseIf(uniqueFolders, [](const Zstring& str) { return trimCpy(str).empty(); }); - config.directories.assign(uniqueFolders.begin(), uniqueFolders.end()); - config.commandline = Zstr('"') + fff::getFreeFileSyncLauncherPath() + Zstr("\" \"") + filePath + Zstr('"'); + cfg.directories.assign(uniqueFolders.begin(), uniqueFolders.end()); + cfg.commandline = Zstr('"') + fff::getFreeFileSyncLauncherPath() + Zstr("\" \"") + filePath + Zstr('"'); } else - return readConfig(filePath, config, warningMsg); //throw FileError + return readConfig(filePath, cfg, warningMsg); //throw FileError } diff --git a/FreeFileSync/Source/RealTimeSync/xml_proc.h b/FreeFileSync/Source/RealTimeSync/config.h index ebad3c7e..75d88aa5 100644 --- a/FreeFileSync/Source/RealTimeSync/xml_proc.h +++ b/FreeFileSync/Source/RealTimeSync/config.h @@ -17,11 +17,12 @@ struct XmlRealConfig { std::vector<Zstring> directories; Zstring commandline; + bool hideConsoleWindow = false; unsigned int delay = 10; }; void readConfig(const Zstring& filePath, XmlRealConfig& config, std::wstring& warningMsg); //throw FileError -void writeConfig(const XmlRealConfig& config, const Zstring& filepath); //throw FileError +void writeConfig(const XmlRealConfig& config, const Zstring& filePath); //throw FileError //reuse (some of) FreeFileSync's xml files diff --git a/FreeFileSync/Source/RealTimeSync/folder_selector2.cpp b/FreeFileSync/Source/RealTimeSync/folder_selector2.cpp index f32a6f6d..7900b5c5 100644 --- a/FreeFileSync/Source/RealTimeSync/folder_selector2.cpp +++ b/FreeFileSync/Source/RealTimeSync/folder_selector2.cpp @@ -13,7 +13,6 @@ #include "../base/resolve_path.h" #include <gtk/gtk.h> - using namespace zen; using namespace rts; diff --git a/FreeFileSync/Source/RealTimeSync/gui_generated.cpp b/FreeFileSync/Source/RealTimeSync/gui_generated.cpp index bcd592ac..2bdb9a56 100644 --- a/FreeFileSync/Source/RealTimeSync/gui_generated.cpp +++ b/FreeFileSync/Source/RealTimeSync/gui_generated.cpp @@ -87,11 +87,32 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer161->Add( bSizer16, 0, 0, 5 ); + wxBoxSizer* bSizer152; + bSizer152 = new wxBoxSizer( wxHORIZONTAL ); + m_staticText811 = new wxStaticText( this, wxID_ANY, _("To get started just import a \"ffs_batch\" file."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText811->Wrap( -1 ); m_staticText811->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); - bSizer161->Add( m_staticText811, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bSizer152->Add( m_staticText811, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_staticText10 = new wxStaticText( this, wxID_ANY, _("("), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText10->Wrap( -1 ); + m_staticText10->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); + + bSizer152->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 2 ); + + m_bitmapBatch = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer152->Add( m_bitmapBatch, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText11 = new wxStaticText( this, wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText11->Wrap( -1 ); + m_staticText11->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); + + bSizer152->Add( m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 2 ); + + + bSizer161->Add( bSizer152, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); bSizerMain->Add( bSizer161, 0, wxALL|wxEXPAND, 5 ); @@ -223,7 +244,13 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer13->Add( m_staticText6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer141->Add( bSizer13, 0, 0, 5 ); + bSizer13->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_checkBoxHideConsole = new wxCheckBox( m_panelMain, wxID_ANY, _("&Hide console window"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer13->Add( m_checkBoxHideConsole, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + bSizer141->Add( bSizer13, 0, wxEXPAND, 5 ); m_textCtrlCommand = new wxTextCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_textCtrlCommand->SetToolTip( _("The command is triggered if:\n- files or subfolders change\n- new folders arrive (e.g. USB stick insert)") ); diff --git a/FreeFileSync/Source/RealTimeSync/gui_generated.h b/FreeFileSync/Source/RealTimeSync/gui_generated.h index 080fd473..c51491f8 100644 --- a/FreeFileSync/Source/RealTimeSync/gui_generated.h +++ b/FreeFileSync/Source/RealTimeSync/gui_generated.h @@ -24,14 +24,15 @@ namespace zen { class BitmapTextButton; } #include <wx/settings.h> #include <wx/stattext.h> #include <wx/sizer.h> -#include <wx/statline.h> #include <wx/statbmp.h> +#include <wx/statline.h> #include <wx/bmpbuttn.h> #include <wx/button.h> #include <wx/textctrl.h> #include <wx/panel.h> #include <wx/scrolwin.h> #include <wx/spinctrl.h> +#include <wx/checkbox.h> #include <wx/frame.h> #include "zen/i18n.h" @@ -56,6 +57,9 @@ protected: wxStaticText* m_staticText4; wxStaticText* m_staticText5; wxStaticText* m_staticText811; + wxStaticText* m_staticText10; + wxStaticBitmap* m_bitmapBatch; + wxStaticText* m_staticText11; wxStaticLine* m_staticline2; wxPanel* m_panelMain; wxStaticBitmap* m_bitmapFolders; @@ -74,6 +78,7 @@ protected: wxStaticLine* m_staticline211; wxStaticBitmap* m_bitmapCommand; wxStaticText* m_staticText6; + wxCheckBox* m_checkBoxHideConsole; wxTextCtrl* m_textCtrlCommand; wxStaticLine* m_staticline5; zen::BitmapTextButton* m_buttonStart; diff --git a/FreeFileSync/Source/RealTimeSync/main_dlg.cpp b/FreeFileSync/Source/RealTimeSync/main_dlg.cpp index 37c04636..9eb1122f 100644 --- a/FreeFileSync/Source/RealTimeSync/main_dlg.cpp +++ b/FreeFileSync/Source/RealTimeSync/main_dlg.cpp @@ -14,7 +14,7 @@ #include <zen/file_access.h> #include <zen/build_info.h> #include <zen/time.h> -#include "xml_proc.h" +#include "config.h" #include "tray_menu.h" #include "app_icon.h" #include "../base/help_provider.h" @@ -78,14 +78,16 @@ MainDialog::MainDialog(const Zstring& cfgFileName) : setRelativeFontSize(*m_buttonStart, 1.5); m_txtCtrlDirectoryMain->SetMinSize(wxSize(fastFromDIP(300), -1)); - m_spinCtrlDelay->SetMinSize(wxSize(fastFromDIP(70), -1)); //Hack: set size (why does wxWindow::Size() not work?) + m_checkBoxHideConsole->Hide(); //only relevant on Windows m_bpButtonRemoveTopFolder->Hide(); m_panelMainFolder->Layout(); + m_bitmapBatch ->SetBitmap(getResourceImage(L"file_batch_sicon")); m_bitmapFolders->SetBitmap(fff::IconBuffer::genericDirIcon(fff::IconBuffer::SIZE_SMALL)); m_bitmapCommand->SetBitmap(shrinkImage(getResourceImage(L"command_line").ConvertToImage(), fastFromDIP(20))); + m_bpButtonAddFolder ->SetBitmapLabel(getResourceImage(L"item_add")); m_bpButtonRemoveTopFolder->SetBitmapLabel(getResourceImage(L"item_remove")); setBitmapTextLabel(*m_buttonStart, getResourceImage(L"startRts").ConvertToImage(), m_buttonStart->GetLabel(), fastFromDIP(5), fastFromDIP(8)); @@ -348,9 +350,9 @@ void MainDialog::setConfiguration(const XmlRealConfig& cfg) insertAddFolder(addFolderPaths, 0); - m_textCtrlCommand->SetValue(utfTo<wxString>(cfg.commandline)); - - m_spinCtrlDelay->SetValue(static_cast<int>(cfg.delay)); + m_textCtrlCommand ->SetValue(utfTo<wxString>(cfg.commandline)); + m_checkBoxHideConsole->SetValue(cfg.hideConsoleWindow); + m_spinCtrlDelay ->SetValue(static_cast<int>(cfg.delay)); } @@ -363,8 +365,9 @@ XmlRealConfig MainDialog::getConfiguration() for (const DirectoryPanel* dp : additionalFolderPanels_) output.directories.push_back(dp->getPath()); - output.commandline = utfTo<Zstring>(m_textCtrlCommand->GetValue()); - output.delay = m_spinCtrlDelay->GetValue(); + output.commandline = utfTo<Zstring>(m_textCtrlCommand->GetValue()); + output.hideConsoleWindow = m_checkBoxHideConsole->GetValue(); + output.delay = m_spinCtrlDelay->GetValue(); return output; } diff --git a/FreeFileSync/Source/RealTimeSync/tray_menu.cpp b/FreeFileSync/Source/RealTimeSync/tray_menu.cpp index 365f4779..8fba1101 100644 --- a/FreeFileSync/Source/RealTimeSync/tray_menu.cpp +++ b/FreeFileSync/Source/RealTimeSync/tray_menu.cpp @@ -274,7 +274,7 @@ rts::AbortReason rts::runFolderMonitor(const XmlRealConfig& config, const wxStri auto cmdLineExp = fff::expandMacros(cmdLine); try { - shellExecute(cmdLineExp, ExecutionType::SYNC); //throw FileError + shellExecute(cmdLineExp, ExecutionType::SYNC, config.hideConsoleWindow); //throw FileError } catch (const FileError& e) { diff --git a/FreeFileSync/Source/RealTimeSync/tray_menu.h b/FreeFileSync/Source/RealTimeSync/tray_menu.h index 79c63dc2..9c18fa08 100644 --- a/FreeFileSync/Source/RealTimeSync/tray_menu.h +++ b/FreeFileSync/Source/RealTimeSync/tray_menu.h @@ -8,7 +8,7 @@ #define TRAY_MENU_H_3967857420987534253245 #include <wx/string.h> -#include "xml_proc.h" +#include "config.h" namespace rts diff --git a/FreeFileSync/Source/fs/abstract.cpp b/FreeFileSync/Source/afs/abstract.cpp index d83344c8..4d8874fa 100644 --- a/FreeFileSync/Source/fs/abstract.cpp +++ b/FreeFileSync/Source/afs/abstract.cpp @@ -135,7 +135,7 @@ AFS::FileCopyResult AFS::copyFileAsStream(const AfsPath& afsPathSource, const St //catch file I/O bugs + read/write conflicts: (note: different check than inside AbstractFileSystem::OutputStream::finalize() => checks notifyUnbufferedIO()!) ZEN_ON_SCOPE_FAIL(try { removeFilePlain(apTarget); /*throw FileError*/ } - catch (FileError& e) { (void)e; }); //after finalize(): not guarded by ~AFS::OutputStream() anymore! + catch (FileError&) {}); //after finalize(): not guarded by ~AFS::OutputStream() anymore! if (totalBytesRead != makeSigned(attrSourceNew.fileSize)) throw FileError(replaceCpy(_("Cannot read file %x."), L"%x", fmtPath(getDisplayPath(afsPathSource))), diff --git a/FreeFileSync/Source/fs/abstract.h b/FreeFileSync/Source/afs/abstract.h index 83b237e7..5a2172aa 100644 --- a/FreeFileSync/Source/fs/abstract.h +++ b/FreeFileSync/Source/afs/abstract.h @@ -286,15 +286,15 @@ struct AbstractFileSystem //THREAD-SAFETY: "const" member functions must model t static uint64_t getFreeDiskSpace(const AbstractPath& ap) { return ap.afsDevice.ref().getFreeDiskSpace(ap.afsPath); } //throw FileError, returns 0 if not available - static bool supportsRecycleBin(const AbstractPath& ap, const std::function<void ()>& onUpdateGui) { return ap.afsDevice.ref().supportsRecycleBin(ap.afsPath, onUpdateGui); } //throw FileError + static bool supportsRecycleBin(const AbstractPath& ap) { return ap.afsDevice.ref().supportsRecycleBin(ap.afsPath); } //throw FileError struct RecycleSession { virtual ~RecycleSession() {} //- multi-threaded access: internally synchronized! - virtual void recycleItemIfExists(const AbstractPath& itemPath, const Zstring& logicalRelPath) = 0; //throw FileError; + virtual void recycleItemIfExists(const AbstractPath& itemPath, const Zstring& logicalRelPath) = 0; //throw FileError - virtual void tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus /*optional; currentItem may be empty*/) = 0; //throw FileError + virtual void tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus /*throw X*; displayPath may be empty*/) = 0; //throw FileError, X }; //precondition: supportsRecycleBin() must return true! @@ -396,7 +396,7 @@ private: //---------------------------------------------------------------------------------------------------------------- virtual uint64_t getFreeDiskSpace(const AfsPath& afsPath) const = 0; //throw FileError, returns 0 if not available - virtual bool supportsRecycleBin(const AfsPath& afsPath, const std::function<void ()>& onUpdateGui) const = 0; //throw FileError + virtual bool supportsRecycleBin(const AfsPath& afsPath) const = 0; //throw FileError virtual std::unique_ptr<RecycleSession> createRecyclerSession(const AfsPath& afsPath) const = 0; //throw FileError, return value must be bound! virtual void recycleItemIfExists(const AfsPath& afsPath) const = 0; //throw FileError }; @@ -445,7 +445,7 @@ AbstractFileSystem::OutputStream::~OutputStream() if (!finalizeSucceeded_) //transactional output stream! => clean up! //even needed for Google Drive: e.g. user might cancel during OutputStreamImpl::finalize(), just after file was written transactionally try { AbstractFileSystem::removeFilePlain(filePath_); /*throw FileError*/ } - catch (FileError& e) { (void)e; } + catch (FileError&) {} } diff --git a/FreeFileSync/Source/fs/abstract_impl.h b/FreeFileSync/Source/afs/abstract_impl.h index 7a175128..7a175128 100644 --- a/FreeFileSync/Source/fs/abstract_impl.h +++ b/FreeFileSync/Source/afs/abstract_impl.h diff --git a/FreeFileSync/Source/fs/concrete.cpp b/FreeFileSync/Source/afs/concrete.cpp index 941a536c..b78f14da 100644 --- a/FreeFileSync/Source/fs/concrete.cpp +++ b/FreeFileSync/Source/afs/concrete.cpp @@ -6,9 +6,9 @@ #include "concrete.h" #include "native.h" - #include "ftp.h" - #include "sftp.h" - #include "gdrive.h" +#include "ftp.h" +#include "sftp.h" +#include "gdrive.h" using namespace fff; diff --git a/FreeFileSync/Source/fs/concrete.h b/FreeFileSync/Source/afs/concrete.h index 3ff507dd..3ff507dd 100644 --- a/FreeFileSync/Source/fs/concrete.h +++ b/FreeFileSync/Source/afs/concrete.h diff --git a/FreeFileSync/Source/fs/ftp.cpp b/FreeFileSync/Source/afs/ftp.cpp index 02205263..554093bf 100644 --- a/FreeFileSync/Source/fs/ftp.cpp +++ b/FreeFileSync/Source/afs/ftp.cpp @@ -377,7 +377,6 @@ public: } options.emplace_back(CURLOPT_URL, curlPath.c_str()); - const auto username = utfTo<std::string>(sessionId_.username); const auto password = utfTo<std::string>(sessionId_.password); if (!username.empty()) //else: libcurl handles anonymous login for us (including fake email as password) @@ -2102,7 +2101,7 @@ private: uint64_t getFreeDiskSpace(const AfsPath& afsPath) const override { return 0; } //throw FileError, returns 0 if not available - bool supportsRecycleBin(const AfsPath& afsPath, const std::function<void ()>& onUpdateGui) const override { return false; } //throw FileError + bool supportsRecycleBin(const AfsPath& afsPath) const override { return false; } //throw FileError std::unique_ptr<RecycleSession> createRecyclerSession(const AfsPath& afsPath) const override //throw FileError, return value must be bound! { diff --git a/FreeFileSync/Source/fs/ftp.h b/FreeFileSync/Source/afs/ftp.h index 422487d1..422487d1 100644 --- a/FreeFileSync/Source/fs/ftp.h +++ b/FreeFileSync/Source/afs/ftp.h diff --git a/FreeFileSync/Source/fs/ftp_common.h b/FreeFileSync/Source/afs/ftp_common.h index edd3da54..edd3da54 100644 --- a/FreeFileSync/Source/fs/ftp_common.h +++ b/FreeFileSync/Source/afs/ftp_common.h diff --git a/FreeFileSync/Source/fs/gdrive.cpp b/FreeFileSync/Source/afs/gdrive.cpp index cc778456..ddf71696 100644 --- a/FreeFileSync/Source/fs/gdrive.cpp +++ b/FreeFileSync/Source/afs/gdrive.cpp @@ -55,7 +55,6 @@ namespace //Google Drive REST API Overview: https://developers.google.com/drive/api/v3/about-sdk //Google Drive REST API Reference: https://developers.google.com/drive/api/v3/reference -//Google Drive credentials https://console.developers.google.com/apis/credentials?project=freefilesync-217608 const char* GOOGLE_DRIVE_CLIENT_ID = ""; // => replace with live credentials const char* GOOGLE_DRIVE_CLIENT_SECRET = ""; // const Zchar* GOOGLE_REST_API_SERVER = Zstr("www.googleapis.com"); @@ -703,7 +702,7 @@ GoogleAccessInfo authorizeAccessToGoogleDrive(const Zstring& googleLoginHint, co if (!servinfo) throw SysError(L"getaddrinfo: empty server info"); - auto getBoundSocket = [&](const auto& /*::addrinfo*/ ai) + const auto getBoundSocket = [](const auto& /*::addrinfo*/ ai) { SocketType testSocket = ::socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol); if (testSocket == invalidSocket) @@ -754,7 +753,7 @@ GoogleAccessInfo authorizeAccessToGoogleDrive(const Zstring& googleLoginHint, co //[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~", with a minimum length of 43 characters and a maximum length of 128 characters. std::string codeChallenge = stringEncodeBase64(generateGUID() + generateGUID()); replace(codeChallenge, '+', '-'); // - replace(codeChallenge, '/', '.'); //code_verifier is almost a perfect fit for base64! + replace(codeChallenge, '/', '.'); //base64 is almost a perfect fit for code_verifier! replace(codeChallenge, '=', '_'); // assert(codeChallenge.size() == 44); @@ -2518,7 +2517,7 @@ private: struct OutputStreamGdrive : public AbstractFileSystem::OutputStreamImpl { OutputStreamGdrive(const GdrivePath& gdrivePath, - std::optional<uint64_t> streamSize, + std::optional<uint64_t> /*streamSize*/, std::optional<time_t> modTime, const IOCallback& notifyUnbufferedIO /*throw X*/) : gdrivePath_(gdrivePath), @@ -2529,7 +2528,7 @@ struct OutputStreamGdrive : public AbstractFileSystem::OutputStreamImpl //PathAccessLock? Not needed, because the AFS abstraction allows for "undefined behavior" - worker_ = InterruptibleThread([asyncStreamIn = this->asyncStreamOut_, gdrivePath, streamSize, modTime, pFileId = std::move(pFileId)]() mutable + worker_ = InterruptibleThread([asyncStreamIn = this->asyncStreamOut_, gdrivePath, modTime, pFileId = std::move(pFileId)]() mutable { setCurrentThreadName(("Ostream[Gdrive] " + utfTo<std::string>(getGoogleDisplayPath(gdrivePath))). c_str()); try @@ -2564,7 +2563,6 @@ struct OutputStreamGdrive : public AbstractFileSystem::OutputStreamImpl //gdriveUploadSmallFile(fileName, parentFolderId, *streamSize, modTime, readBlock, aai.accessToken) : //throw SysError, ThreadInterruption gdriveUploadFile (fileName, parentFolderId, modTime, readBlock, aai.accessToken); //throw SysError, ThreadInterruption assert(asyncStreamIn->getTotalBytesRead() == asyncStreamIn->getTotalBytesWritten()); - (void)streamSize; //buffer new file state ASAP (don't wait GOOGLE_DRIVE_SYNC_INTERVAL) GoogleFileItem newFileItem = {}; @@ -2976,7 +2974,7 @@ private: catch (const SysError& e) { throw FileError(replaceCpy(_("Cannot determine free disk space for %x."), L"%x", fmtPath(getDisplayPath(afsPath))), e.toString()); } } - bool supportsRecycleBin(const AfsPath& afsPath, const std::function<void ()>& onUpdateGui) const override { return true; } //throw FileError + bool supportsRecycleBin(const AfsPath& afsPath) const override { return true; } //throw FileError struct RecycleSessionGdrive : public RecycleSession { diff --git a/FreeFileSync/Source/fs/gdrive.h b/FreeFileSync/Source/afs/gdrive.h index d81620a3..d81620a3 100644 --- a/FreeFileSync/Source/fs/gdrive.h +++ b/FreeFileSync/Source/afs/gdrive.h diff --git a/FreeFileSync/Source/fs/init_curl_libssh2.cpp b/FreeFileSync/Source/afs/init_curl_libssh2.cpp index 8839fc39..dd0ecad5 100644 --- a/FreeFileSync/Source/fs/init_curl_libssh2.cpp +++ b/FreeFileSync/Source/afs/init_curl_libssh2.cpp @@ -32,9 +32,8 @@ void libsshCurlUnifiedInit() openSslInit(); libssh2Init(); - const CURLcode rc2 = ::curl_global_init(CURL_GLOBAL_NOTHING /*CURL_GLOBAL_DEFAULT = CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32*/); + [[maybe_unused]] const CURLcode rc2 = ::curl_global_init(CURL_GLOBAL_NOTHING /*CURL_GLOBAL_DEFAULT = CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32*/); assert(rc2 == CURLE_OK); - (void)rc2; } diff --git a/FreeFileSync/Source/fs/init_curl_libssh2.h b/FreeFileSync/Source/afs/init_curl_libssh2.h index 57204e78..57204e78 100644 --- a/FreeFileSync/Source/fs/init_curl_libssh2.h +++ b/FreeFileSync/Source/afs/init_curl_libssh2.h diff --git a/FreeFileSync/Source/fs/libcurl/curl_wrap.h b/FreeFileSync/Source/afs/libcurl/curl_wrap.h index 7a5a4f45..7a5a4f45 100644 --- a/FreeFileSync/Source/fs/libcurl/curl_wrap.h +++ b/FreeFileSync/Source/afs/libcurl/curl_wrap.h diff --git a/FreeFileSync/Source/fs/libssh2/init_libssh2.cpp b/FreeFileSync/Source/afs/libssh2/init_libssh2.cpp index 974e4f06..f64306bd 100644 --- a/FreeFileSync/Source/fs/libssh2/init_libssh2.cpp +++ b/FreeFileSync/Source/afs/libssh2/init_libssh2.cpp @@ -25,7 +25,7 @@ void zen::libssh2Init() { - const int rc = ::libssh2_init(0); + [[maybe_unused]] const int rc = ::libssh2_init(0); /* we need libssh2's crypto init: - there is other OpenSSL-related initialization which might be needed (and hopefully won't hurt...) @@ -35,7 +35,6 @@ void zen::libssh2Init() // - enable proper clean up of these variables in libssh2_exit() (otherwise: memory leaks!) */ assert(rc == 0); //libssh2 unconditionally returns 0 => why then have a return value in first place??? - (void)rc; } diff --git a/FreeFileSync/Source/fs/libssh2/init_libssh2.h b/FreeFileSync/Source/afs/libssh2/init_libssh2.h index a159850a..a159850a 100644 --- a/FreeFileSync/Source/fs/libssh2/init_libssh2.h +++ b/FreeFileSync/Source/afs/libssh2/init_libssh2.h diff --git a/FreeFileSync/Source/fs/libssh2/init_open_ssl.cpp b/FreeFileSync/Source/afs/libssh2/init_open_ssl.cpp index a40de204..4f1725e1 100644 --- a/FreeFileSync/Source/fs/libssh2/init_open_ssl.cpp +++ b/FreeFileSync/Source/afs/libssh2/init_open_ssl.cpp @@ -25,8 +25,8 @@ void zen::openSslInit() //see Curl_ossl_cleanup(): https://github.com/curl/curl/blob/master/lib/vtls/openssl.c //excplicitly init OpenSSL on main thread: they seem to initialize atomically! But it still might help to avoid issues: - if (::OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, nullptr) != 1) //https://www.openssl.org/docs/man1.1.0/ssl/OPENSSL_init_ssl.html - assert(false); + [[maybe_unused]] const int rv = ::OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, nullptr); + assert(rv == 1); //https://www.openssl.org/docs/man1.1.0/ssl/OPENSSL_init_ssl.html } diff --git a/FreeFileSync/Source/fs/libssh2/init_open_ssl.h b/FreeFileSync/Source/afs/libssh2/init_open_ssl.h index e3889a87..e3889a87 100644 --- a/FreeFileSync/Source/fs/libssh2/init_open_ssl.h +++ b/FreeFileSync/Source/afs/libssh2/init_open_ssl.h diff --git a/FreeFileSync/Source/fs/native.cpp b/FreeFileSync/Source/afs/native.cpp index 43a213ab..4e883279 100644 --- a/FreeFileSync/Source/fs/native.cpp +++ b/FreeFileSync/Source/afs/native.cpp @@ -279,10 +279,10 @@ void traverseFolderRecursiveNative(const std::vector<std::pair<Zstring, std::sha class RecycleSessionNative : public AbstractFileSystem::RecycleSession { public: - RecycleSessionNative(const Zstring baseFolderPath) : baseFolderPath_(baseFolderPath) {} + RecycleSessionNative(const Zstring& baseFolderPath) : baseFolderPath_(baseFolderPath) {} void recycleItemIfExists(const AbstractPath& itemPath, const Zstring& logicalRelPath) override; //throw FileError - void tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus) override; //throw FileError + void tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus /*throw X*/) override; //throw FileError, X private: const Zstring baseFolderPath_; //ends with path separator @@ -607,7 +607,7 @@ private: return zen::getFreeDiskSpace(getNativePath(afsPath)); //throw FileError } - bool supportsRecycleBin(const AfsPath& afsPath, const std::function<void ()>& onUpdateGui) const override //throw FileError + bool supportsRecycleBin(const AfsPath& afsPath) const override //throw FileError { return true; //truth be told: no idea!!! } @@ -615,7 +615,7 @@ private: std::unique_ptr<RecycleSession> createRecyclerSession(const AfsPath& afsPath) const override //throw FileError, return value must be bound! { initComForThread(); //throw FileError - assert(supportsRecycleBin(afsPath, nullptr)); + assert(supportsRecycleBin(afsPath)); return std::make_unique<RecycleSessionNative>(getNativePath(afsPath)); } @@ -646,7 +646,7 @@ void RecycleSessionNative::recycleItemIfExists(const AbstractPath& itemPath, con } -void RecycleSessionNative::tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus) //throw FileError +void RecycleSessionNative::tryCleanup(const std::function<void (const std::wstring& displayPath)>& notifyDeletionStatus /*throw X*/) //throw FileError, X { } } diff --git a/FreeFileSync/Source/fs/native.h b/FreeFileSync/Source/afs/native.h index 7c5b004e..7c5b004e 100644 --- a/FreeFileSync/Source/fs/native.h +++ b/FreeFileSync/Source/afs/native.h diff --git a/FreeFileSync/Source/fs/sftp.cpp b/FreeFileSync/Source/afs/sftp.cpp index f0a56e10..110ecfc3 100644 --- a/FreeFileSync/Source/fs/sftp.cpp +++ b/FreeFileSync/Source/afs/sftp.cpp @@ -1895,7 +1895,7 @@ private: #endif } - bool supportsRecycleBin(const AfsPath& afsPath, const std::function<void ()>& onUpdateGui) const override { return false; } //throw FileError + bool supportsRecycleBin(const AfsPath& afsPath) const override { return false; } //throw FileError std::unique_ptr<RecycleSession> createRecyclerSession(const AfsPath& afsPath) const override //throw FileError, return value must be bound! { diff --git a/FreeFileSync/Source/fs/sftp.h b/FreeFileSync/Source/afs/sftp.h index dbd73556..dbd73556 100644 --- a/FreeFileSync/Source/fs/sftp.h +++ b/FreeFileSync/Source/afs/sftp.h diff --git a/FreeFileSync/Source/base/algorithm.cpp b/FreeFileSync/Source/base/algorithm.cpp index d5b163a6..8ca51ce7 100644 --- a/FreeFileSync/Source/base/algorithm.cpp +++ b/FreeFileSync/Source/base/algorithm.cpp @@ -16,8 +16,8 @@ #include "db_file.h" #include "cmp_filetime.h" #include "status_handler_impl.h" -#include "../fs/concrete.h" -#include "../fs/native.h" +#include "../afs/concrete.h" +#include "../afs/native.h" using namespace zen; @@ -1509,7 +1509,7 @@ void categorize(const std::vector<FileSystemObject*>& rows, bool recSupported = false; tryReportingError([&]{ - recSupported = AFS::supportsRecycleBin(baseFolderPath, [&] { callback.reportStatus(msg); /*throw X*/ }); //throw FileError + recSupported = AFS::supportsRecycleBin(baseFolderPath); //throw FileError }, callback); //throw X recyclerSupported.emplace(baseFolderPath, recSupported); diff --git a/FreeFileSync/Source/base/algorithm.h b/FreeFileSync/Source/base/algorithm.h index 01ebca36..afb4303c 100644 --- a/FreeFileSync/Source/base/algorithm.h +++ b/FreeFileSync/Source/base/algorithm.h @@ -8,9 +8,9 @@ #define ALGORITHM_H_34218518475321452548 #include <functional> +#include "config.h" #include "file_hierarchy.h" #include "soft_filter.h" -#include "process_xml.h" #include "process_callback.h" diff --git a/FreeFileSync/Source/base/application.cpp b/FreeFileSync/Source/base/application.cpp index e2996a5c..65d51ac6 100644 --- a/FreeFileSync/Source/base/application.cpp +++ b/FreeFileSync/Source/base/application.cpp @@ -16,18 +16,18 @@ #include <wx+/image_resources.h> #include <wx/msgdlg.h> #include "comparison.h" +#include "config.h" #include "algorithm.h" #include "synchronization.h" #include "help_provider.h" -#include "process_xml.h" #include "fatal_error.h" #include "resolve_path.h" #include "generate_logfile.h" #include "../ui/batch_status_handler.h" #include "../ui/main_dlg.h" +#include "../afs/concrete.h" #include <gtk/gtk.h> - #include "../fs/concrete.h" using namespace zen; @@ -68,7 +68,7 @@ bool Application::OnInit() SetAppName(L"FreeFileSync"); //if not set, the default is the executable's name! - initResourceImages(getResourceDirPf() + Zstr("Resources.zip")); //parallel xBRZ-scaling! => run as early as possible + initResourceImages(getResourceDirPf() + Zstr("Misc") + FILE_NAME_SEPARATOR + Zstr("Icons.zip")); //parallel xBRZ-scaling! => run as early as possible try { @@ -94,7 +94,7 @@ int Application::OnExit() { releaseWxLocale(); cleanupResourceImages(); - teardownAfs(); //throw FileError + teardownAfs(); return wxApp::OnExit(); } diff --git a/FreeFileSync/Source/base/binary.h b/FreeFileSync/Source/base/binary.h index 66d8b09c..3c2db11a 100644 --- a/FreeFileSync/Source/base/binary.h +++ b/FreeFileSync/Source/base/binary.h @@ -7,7 +7,7 @@ #ifndef BINARY_H_3941281398513241134 #define BINARY_H_3941281398513241134 -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/base/cmp_filetime.h b/FreeFileSync/Source/base/cmp_filetime.h index 385fba6f..3f4a3e90 100644 --- a/FreeFileSync/Source/base/cmp_filetime.h +++ b/FreeFileSync/Source/base/cmp_filetime.h @@ -28,7 +28,7 @@ bool sameFileTime(time_t lhs, time_t rhs, int tolerance, const std::vector<unsig if (lhs <= rhs + tolerance) return true; - for (unsigned int minutes : ignoreTimeShiftMinutes) + for (const unsigned int minutes : ignoreTimeShiftMinutes) { assert(minutes > 0); const int shiftSec = static_cast<int>(minutes) * 60; diff --git a/FreeFileSync/Source/base/comparison.cpp b/FreeFileSync/Source/base/comparison.cpp index f560725e..f898cdce 100644 --- a/FreeFileSync/Source/base/comparison.cpp +++ b/FreeFileSync/Source/base/comparison.cpp @@ -7,6 +7,8 @@ #include "comparison.h" #include <zen/process_priority.h> #include <zen/perf.h> +#include <zen/time.h> +#include <wx/datetime.h> #include "algorithm.h" #include "parallel_scan.h" #include "dir_exist_async.h" @@ -14,7 +16,7 @@ #include "binary.h" #include "cmp_filetime.h" #include "status_handler_impl.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; using namespace fff; @@ -199,10 +201,10 @@ ComparisonBuffer::ComparisonBuffer(const std::set<DirectoryKey>& foldersToRead, return AFS::TraverserCallback::ON_ERROR_CONTINUE; }; - const std::wstring textScanning = _("Scanning:") + L" "; + const std::chrono::steady_clock::time_point compareStartTime = std::chrono::steady_clock::now(); int itemsReported = 0; - auto onStatusUpdate = [&](const std::wstring& statusLine, int itemsTotal) + auto onStatusUpdate = [&, textScanning = _("Scanning:") + L" "](const std::wstring& statusLine, int itemsTotal) { callback.updateDataProcessed(itemsTotal - itemsReported, 0); itemsReported = itemsTotal; @@ -215,7 +217,11 @@ ComparisonBuffer::ComparisonBuffer(const std::set<DirectoryKey>& foldersToRead, onError, onStatusUpdate, //throw X UI_UPDATE_INTERVAL / 2); //every ~50 ms - callback.reportInfo(_("Comparison finished:") + L" " + _P("1 item found", "%x items found", itemsReported)); //throw X + const int64_t totalTimeSec = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - compareStartTime).count(); + + callback.reportInfo(_("Comparison finished:") + L" " + + _P("1 item found", "%x items found", itemsReported) + L" | " + + _("Time elapsed:") + L" " + copyStringTo<std::wstring>(wxTimeSpan::Seconds(totalTimeSec).Format())); //throw X } diff --git a/FreeFileSync/Source/base/comparison.h b/FreeFileSync/Source/base/comparison.h index 55935eae..c5a126ab 100644 --- a/FreeFileSync/Source/base/comparison.h +++ b/FreeFileSync/Source/base/comparison.h @@ -7,8 +7,8 @@ #ifndef COMPARISON_H_8032178534545426 #define COMPARISON_H_8032178534545426 +#include "config.h" #include "file_hierarchy.h" -#include "process_xml.h" #include "process_callback.h" #include "norm_filter.h" #include "lock_holder.h" diff --git a/FreeFileSync/Source/base/process_xml.cpp b/FreeFileSync/Source/base/config.cpp index 56e192ac..517595ff 100644 --- a/FreeFileSync/Source/base/process_xml.cpp +++ b/FreeFileSync/Source/base/config.cpp @@ -4,14 +4,14 @@ // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * // ***************************************************************************** -#include "process_xml.h" +#include "config.h" #include <zenxml/xml.h> #include <zen/file_access.h> #include <zen/file_io.h> #include <zen/time.h> #include <wx/intl.h> #include "ffs_paths.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; @@ -22,8 +22,8 @@ using namespace fff; //functionally needed for correct overload resolution!!! namespace { //------------------------------------------------------------------------------------------------------------------------------- -const int XML_FORMAT_VER_GLOBAL = 12; //2019-02-09 -const int XML_FORMAT_VER_FFS_CFG = 14; //2018-08-13 +const int XML_FORMAT_GLOBAL_CFG = 12; //2019-02-09 +const int XML_FORMAT_SYNC_CFG = 14; //2018-08-13 //------------------------------------------------------------------------------------------------------------------------------- } @@ -1731,14 +1731,6 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& cfg, int formatVer) } -int getConfigFormatVersion(const XmlDoc& doc) -{ - int xmlFormatVer = 0; - /*bool success = */doc.root().getAttribute("XmlFormat", xmlFormatVer); - return xmlFormatVer; -} - - template <class ConfigType> void readConfig(const Zstring& filePath, XmlType type, ConfigType& cfg, int currentXmlFormatVer, std::wstring& warningMsg) //throw FileError { @@ -1747,7 +1739,8 @@ void readConfig(const Zstring& filePath, XmlType type, ConfigType& cfg, int curr if (getXmlTypeNoThrow(doc) != type) //noexcept throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath))); - const int formatVer = getConfigFormatVersion(doc); + int formatVer = 0; + /*bool success =*/ doc.root().getAttribute("XmlFormat", formatVer); XmlIn in(doc); ::readConfig(in, cfg, formatVer); @@ -1768,19 +1761,19 @@ void readConfig(const Zstring& filePath, XmlType type, ConfigType& cfg, int curr void fff::readConfig(const Zstring& filePath, XmlGuiConfig& cfg, std::wstring& warningMsg) { - ::readConfig(filePath, XML_TYPE_GUI, cfg, XML_FORMAT_VER_FFS_CFG, warningMsg); //throw FileError + ::readConfig(filePath, XML_TYPE_GUI, cfg, XML_FORMAT_SYNC_CFG, warningMsg); //throw FileError } void fff::readConfig(const Zstring& filePath, XmlBatchConfig& cfg, std::wstring& warningMsg) { - ::readConfig(filePath, XML_TYPE_BATCH, cfg, XML_FORMAT_VER_FFS_CFG, warningMsg); //throw FileError + ::readConfig(filePath, XML_TYPE_BATCH, cfg, XML_FORMAT_SYNC_CFG, warningMsg); //throw FileError } void fff::readConfig(const Zstring& filePath, XmlGlobalSettings& cfg, std::wstring& warningMsg) { - ::readConfig(filePath, XML_TYPE_GLOBAL, cfg, XML_FORMAT_VER_GLOBAL, warningMsg); //throw FileError + ::readConfig(filePath, XML_TYPE_GLOBAL, cfg, XML_FORMAT_GLOBAL_CFG, warningMsg); //throw FileError } @@ -1789,7 +1782,8 @@ namespace template <class XmlCfg> XmlCfg parseConfig(const XmlDoc& doc, const Zstring& filePath, int currentXmlFormatVer, std::wstring& warningMsg) //nothrow { - const int formatVer = getConfigFormatVersion(doc); + int formatVer = 0; + /*bool success =*/ doc.root().getAttribute("XmlFormat", formatVer); XmlIn in(doc); XmlCfg cfg; @@ -1809,7 +1803,6 @@ XmlCfg parseConfig(const XmlDoc& doc, const Zstring& filePath, int currentXmlFor if (warningMsg.empty()) warningMsg = e.toString(); } - return cfg; } } @@ -1832,7 +1825,7 @@ void fff::readAnyConfig(const std::vector<Zstring>& filePaths, XmlGuiConfig& cfg { case XML_TYPE_GUI: { - XmlGuiConfig guiCfg = parseConfig<XmlGuiConfig>(doc, filePath, XML_FORMAT_VER_FFS_CFG, warningMsg); //nothrow + XmlGuiConfig guiCfg = parseConfig<XmlGuiConfig>(doc, filePath, XML_FORMAT_SYNC_CFG, warningMsg); //nothrow if (firstItem) cfg = guiCfg; mainCfgs.push_back(guiCfg.mainCfg); @@ -1841,7 +1834,7 @@ void fff::readAnyConfig(const std::vector<Zstring>& filePaths, XmlGuiConfig& cfg case XML_TYPE_BATCH: { - XmlBatchConfig batchCfg = parseConfig<XmlBatchConfig>(doc, filePath, XML_FORMAT_VER_FFS_CFG, warningMsg); //nothrow + XmlBatchConfig batchCfg = parseConfig<XmlBatchConfig>(doc, filePath, XML_FORMAT_SYNC_CFG, warningMsg); //nothrow if (firstItem) cfg = convertBatchToGui(batchCfg); mainCfgs.push_back(batchCfg.mainCfg); @@ -2175,19 +2168,19 @@ void writeConfig(const ConfigType& cfg, XmlType type, int xmlFormatVer, const Zs void fff::writeConfig(const XmlGuiConfig& cfg, const Zstring& filePath) { - ::writeConfig(cfg, XML_TYPE_GUI, XML_FORMAT_VER_FFS_CFG, filePath); //throw FileError + ::writeConfig(cfg, XML_TYPE_GUI, XML_FORMAT_SYNC_CFG, filePath); //throw FileError } void fff::writeConfig(const XmlBatchConfig& cfg, const Zstring& filePath) { - ::writeConfig(cfg, XML_TYPE_BATCH, XML_FORMAT_VER_FFS_CFG, filePath); //throw FileError + ::writeConfig(cfg, XML_TYPE_BATCH, XML_FORMAT_SYNC_CFG, filePath); //throw FileError } void fff::writeConfig(const XmlGlobalSettings& cfg, const Zstring& filePath) { - ::writeConfig(cfg, XML_TYPE_GLOBAL, XML_FORMAT_VER_GLOBAL, filePath); //throw FileError + ::writeConfig(cfg, XML_TYPE_GLOBAL, XML_FORMAT_GLOBAL_CFG, filePath); //throw FileError } diff --git a/FreeFileSync/Source/base/process_xml.h b/FreeFileSync/Source/base/config.h index bdda02f1..361cdba0 100644 --- a/FreeFileSync/Source/base/process_xml.h +++ b/FreeFileSync/Source/base/config.h @@ -24,7 +24,6 @@ enum XmlType XML_TYPE_GLOBAL, XML_TYPE_OTHER }; - XmlType getXmlType(const Zstring& filePath); //throw FileError diff --git a/FreeFileSync/Source/base/db_file.cpp b/FreeFileSync/Source/base/db_file.cpp index f15657a7..680242f9 100644 --- a/FreeFileSync/Source/base/db_file.cpp +++ b/FreeFileSync/Source/base/db_file.cpp @@ -295,7 +295,7 @@ public: static std::shared_ptr<InSyncFolder> execute(bool leadStreamLeft, //throw FileError const ByteArray& streamL, const ByteArray& streamR, - const std::wstring& displayFilePathL, //used for diagnostics only + const std::wstring& displayFilePathL, //for diagnostics only const std::wstring& displayFilePathR) { auto decompStream = [&](const ByteArray& stream) -> ByteArray //throw FileError diff --git a/FreeFileSync/Source/base/dir_exist_async.h b/FreeFileSync/Source/base/dir_exist_async.h index db4b1814..4ea963d6 100644 --- a/FreeFileSync/Source/base/dir_exist_async.h +++ b/FreeFileSync/Source/base/dir_exist_async.h @@ -11,7 +11,7 @@ #include <zen/file_error.h> #include <zen/basic_math.h> #include "process_callback.h" -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/base/dir_lock.cpp b/FreeFileSync/Source/base/dir_lock.cpp index d910907b..39245bae 100644 --- a/FreeFileSync/Source/base/dir_lock.cpp +++ b/FreeFileSync/Source/base/dir_lock.cpp @@ -62,8 +62,7 @@ private: return; ZEN_ON_SCOPE_EXIT(::close(fileHandle)); - const ssize_t bytesWritten = ::write(fileHandle, " ", 1); - (void)bytesWritten; + /*const ssize_t bytesWritten =*/ ::write(fileHandle, " ", 1); } const Zstring lockFilePath_; //thread-local! diff --git a/FreeFileSync/Source/base/ffs_paths.cpp b/FreeFileSync/Source/base/ffs_paths.cpp index 76d1f484..03ef9dce 100644 --- a/FreeFileSync/Source/base/ffs_paths.cpp +++ b/FreeFileSync/Source/base/ffs_paths.cpp @@ -6,6 +6,7 @@ #include "ffs_paths.h" #include <zen/file_access.h> +#include <zen/thread.h> #include <wx/stdpaths.h> #include <wx/app.h> @@ -65,6 +66,12 @@ Zstring fff::getResourceDirPf() } +namespace +{ +std::once_flag onceFlagCreateCfgPath; +} + + Zstring fff::getConfigDirPathPf() { //make independent from wxWidgets global variable "appname"; support being called by RealTimeSync @@ -82,22 +89,14 @@ Zstring fff::getConfigDirPathPf() cfgFolderPath = appendSeparator(utfTo<Zstring>(wxStandardPaths::Get().GetUserConfigDir())) + "FreeFileSync"; } -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif - static int initOnce = [&] //"magic static" is the lesser evil in this wxWidgets context... + std::call_once(onceFlagCreateCfgPath, [&] { try //create the config folder if not existing + create "Logs" subfolder while we're at it { createDirectoryIfMissingRecursion(appendSeparator(cfgFolderPath) + Zstr("Logs")); //throw FileError } catch (FileError&) { assert(false); } - return 0; - }(); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif + }); return appendSeparator(cfgFolderPath); } diff --git a/FreeFileSync/Source/base/file_hierarchy.h b/FreeFileSync/Source/base/file_hierarchy.h index 0d6758dd..408eb40e 100644 --- a/FreeFileSync/Source/base/file_hierarchy.h +++ b/FreeFileSync/Source/base/file_hierarchy.h @@ -18,7 +18,7 @@ #include <zen/file_id_def.h> #include "structures.h" #include "path_filter.h" -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff @@ -340,7 +340,7 @@ public: DerefIter() {} DerefIter(IterImpl it) : it_(it) {} - DerefIter(const DerefIter& other) : it_(other.it_) {} + //DerefIter(const DerefIter& other) : it_(other.it_) {} DerefIter& operator++() { ++it_; return *this; } DerefIter& operator--() { --it_; return *this; } inline friend DerefIter operator++(DerefIter& it, int) { return it++; } diff --git a/FreeFileSync/Source/base/generate_logfile.cpp b/FreeFileSync/Source/base/generate_logfile.cpp index 3ce4fbf2..aed62371 100644 --- a/FreeFileSync/Source/base/generate_logfile.cpp +++ b/FreeFileSync/Source/base/generate_logfile.cpp @@ -8,7 +8,7 @@ #include <zen/file_io.h> #include <wx/datetime.h> #include "ffs_paths.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; using namespace fff; @@ -24,9 +24,11 @@ std::wstring generateLogHeader(const ProcessSummary& s, const ErrorLog& log, con const std::wstring tabSpace(4, L' '); //4, the one true space count for tabs - std::wstring headerLine = formatTime<std::wstring>(FORMAT_DATE); //+ L" [" + formatTime<std::wstring>(FORMAT_TIME, startTime + L"]"; + const TimeComp tc = getLocalTime(std::chrono::system_clock::to_time_t(s.startTime)); //returns empty string on failure + + std::wstring headerLine = formatTime<std::wstring>(FORMAT_DATE, tc) + L" [" + formatTime<std::wstring>(FORMAT_TIME, tc) + L"]"; if (!s.jobName.empty()) - headerLine += L" " + s.jobName; + headerLine += L" | " + s.jobName; summary.push_back(headerLine); summary.push_back(L""); @@ -113,7 +115,6 @@ const Zchar STATUS_END_TOKEN = Zstr(']'); AbstractPath saveNewLogFile(const ProcessSummary& summary, //throw FileError const ErrorLog& log, const AbstractPath& logFolderPath, - const std::chrono::system_clock::time_point& syncStartTime, const std::function<void(const std::wstring& msg)>& notifyStatus /*throw X*/) { //create logfile folder if required @@ -123,12 +124,12 @@ AbstractPath saveNewLogFile(const ProcessSummary& summary, //throw FileError //=> too many issues, most notably cmd.exe is not Unicode-aware: https://freefilesync.org/forum/viewtopic.php?t=1679 //assemble logfile name - const TimeComp tc = getLocalTime(std::chrono::system_clock::to_time_t(syncStartTime)); + const TimeComp tc = getLocalTime(std::chrono::system_clock::to_time_t(summary.startTime)); if (tc == TimeComp()) - throw FileError(L"Failed to determine current time: " + numberTo<std::wstring>(syncStartTime.time_since_epoch().count())); + throw FileError(L"Failed to determine current time: " + numberTo<std::wstring>(summary.startTime.time_since_epoch().count())); - const auto timeMs = std::chrono::duration_cast<std::chrono::milliseconds>(syncStartTime.time_since_epoch()).count() % 1000; - assert(std::chrono::duration_cast<std::chrono::seconds>(syncStartTime.time_since_epoch()).count() == std::chrono::system_clock::to_time_t(syncStartTime)); + const auto timeMs = std::chrono::duration_cast<std::chrono::milliseconds>(summary.startTime.time_since_epoch()).count() % 1000; + assert(std::chrono::duration_cast<std::chrono::seconds>(summary.startTime.time_since_epoch()).count() == std::chrono::system_clock::to_time_t(summary.startTime)); Zstring logFileName; @@ -283,7 +284,6 @@ Zstring fff::getDefaultLogFolderPath() { return getConfigDirPathPf() + Zstr("Log AbstractPath fff::saveLogFile(const ProcessSummary& summary, //throw FileError const ErrorLog& log, - const std::chrono::system_clock::time_point& syncStartTime, const Zstring& altLogFolderPathPhrase, //optional int logfilesMaxAgeDays, const std::set<AbstractPath>& logFilePathsToKeep, @@ -297,7 +297,7 @@ AbstractPath fff::saveLogFile(const ProcessSummary& summary, //throw FileError std::exception_ptr firstError; try { - logFilePath = saveNewLogFile(summary, log, logFolderPath, syncStartTime, notifyStatus); //throw FileError, X + logFilePath = saveNewLogFile(summary, log, logFolderPath, notifyStatus); //throw FileError, X } catch (const FileError&) { if (!firstError) firstError = std::current_exception(); }; diff --git a/FreeFileSync/Source/base/generate_logfile.h b/FreeFileSync/Source/base/generate_logfile.h index 9892fa83..52cc7780 100644 --- a/FreeFileSync/Source/base/generate_logfile.h +++ b/FreeFileSync/Source/base/generate_logfile.h @@ -11,7 +11,7 @@ #include <zen/error_log.h> #include "return_codes.h" #include "status_handler.h" -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff @@ -21,7 +21,6 @@ Zstring getDefaultLogFolderPath(); AbstractPath saveLogFile(const ProcessSummary& summary, //throw FileError const zen::ErrorLog& log, - const std::chrono::system_clock::time_point& syncStartTime, const Zstring& altLogFolderPathPhrase, //optional int logfilesMaxAgeDays, const std::set<AbstractPath>& logFilePathsToKeep, diff --git a/FreeFileSync/Source/base/icon_buffer.cpp b/FreeFileSync/Source/base/icon_buffer.cpp index e10d25ab..1fc89766 100644 --- a/FreeFileSync/Source/base/icon_buffer.cpp +++ b/FreeFileSync/Source/base/icon_buffer.cpp @@ -322,6 +322,7 @@ int IconBuffer::getSize(IconSize sz) return fastFromDIP(24); case IconBuffer::SIZE_MEDIUM: return fastFromDIP(48); + case IconBuffer::SIZE_LARGE: return fastFromDIP(128); } diff --git a/FreeFileSync/Source/base/icon_buffer.h b/FreeFileSync/Source/base/icon_buffer.h index 2f5e4e60..c088a56a 100644 --- a/FreeFileSync/Source/base/icon_buffer.h +++ b/FreeFileSync/Source/base/icon_buffer.h @@ -11,7 +11,7 @@ #include <memory> #include <zen/zstring.h> #include <wx/bitmap.h> -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/base/icon_loader.cpp b/FreeFileSync/Source/base/icon_loader.cpp index 71b783a2..f7792118 100644 --- a/FreeFileSync/Source/base/icon_loader.cpp +++ b/FreeFileSync/Source/base/icon_loader.cpp @@ -165,9 +165,7 @@ ImageHolder fff::getThumbnailImage(const Zstring& filePath, int pixelSize) //ret { gint width = 0; gint height = 0; - if (GdkPixbufFormat* fmt = ::gdk_pixbuf_get_file_info(filePath.c_str(), &width, &height)) - { - (void)fmt; + if (/*GdkPixbufFormat* fmt =*/ ::gdk_pixbuf_get_file_info(filePath.c_str(), &width, &height)) if (width > 0 && height > 0 && pixelSize > 0) { int trgWidth = width; @@ -185,7 +183,6 @@ ImageHolder fff::getThumbnailImage(const Zstring& filePath, int pixelSize) //ret return copyToImageHolder(pixBuf); } } - } } return ImageHolder(); diff --git a/FreeFileSync/Source/base/localization.cpp b/FreeFileSync/Source/base/localization.cpp index 52ed7fdf..2a24fff5 100644 --- a/FreeFileSync/Source/base/localization.cpp +++ b/FreeFileSync/Source/base/localization.cpp @@ -508,8 +508,7 @@ void fff::setLanguage(wxLanguage lng) //throw FileError }; wxtrans->SetLanguage(lng); //!= wxLocale's language, which could be wxLANGUAGE_DEFAULT (see wxWidgetsLocale) wxtrans->SetLoader(new MemoryTranslationLoader(lng, std::move(transMapping))); - const bool catalogAdded = wxtrans->AddCatalog(wxString()); - (void)catalogAdded; + [[maybe_unused]] const bool catalogAdded = wxtrans->AddCatalog(wxString()); assert(catalogAdded || lng == wxLANGUAGE_ENGLISH_US); } } diff --git a/FreeFileSync/Source/base/parallel_scan.cpp b/FreeFileSync/Source/base/parallel_scan.cpp index 6ed8b453..3570d077 100644 --- a/FreeFileSync/Source/base/parallel_scan.cpp +++ b/FreeFileSync/Source/base/parallel_scan.cpp @@ -128,9 +128,8 @@ public: { std::lock_guard dummy(lockCurrentStatus_); - const auto it = activeThreadIdxs_.emplace(threadIdx, parallelOps); + [[maybe_unused]] const auto it = activeThreadIdxs_.emplace(threadIdx, parallelOps); assert(it.second); - (void)it; notifyingThreadIdx_ = activeThreadIdxs_.begin()->first; } @@ -140,9 +139,8 @@ public: { std::lock_guard dummy(lockCurrentStatus_); - const size_t no = activeThreadIdxs_.erase(threadIdx); + [[maybe_unused]] const size_t no = activeThreadIdxs_.erase(threadIdx); assert(no == 1); - (void)no; notifyingThreadIdx_ = activeThreadIdxs_.empty() ? 0 : activeThreadIdxs_.begin()->first; } diff --git a/FreeFileSync/Source/base/parse_lng.h b/FreeFileSync/Source/base/parse_lng.h index e1e5e57d..e675864b 100644 --- a/FreeFileSync/Source/base/parse_lng.h +++ b/FreeFileSync/Source/base/parse_lng.h @@ -274,7 +274,7 @@ public: return Token(Token::TK_END); Token out(Token::TK_TEXT); - out.text = text; + out.text = std::move(text); return out; } diff --git a/FreeFileSync/Source/base/parse_plural.h b/FreeFileSync/Source/base/parse_plural.h index d80a0dca..7d4971b0 100644 --- a/FreeFileSync/Source/base/parse_plural.h +++ b/FreeFileSync/Source/base/parse_plural.h @@ -342,7 +342,7 @@ private: nextToken(); //throw ParsingError std::shared_ptr<Expression> rhs = parseRelational(); - if (t == Token::TK_EQUAL) return makeBiExp<std::equal_to<>, int64_t>(e, rhs); //throw ParsingError + if (t == Token::TK_EQUAL) return makeBiExp<std:: equal_to<>, int64_t>(e, rhs); //throw ParsingError if (t == Token::TK_NOT_EQUAL) return makeBiExp<std::not_equal_to<>, int64_t>(e, rhs); // } return e; diff --git a/FreeFileSync/Source/base/process_callback.h b/FreeFileSync/Source/base/process_callback.h index 34c4c7e5..bceec7b6 100644 --- a/FreeFileSync/Source/base/process_callback.h +++ b/FreeFileSync/Source/base/process_callback.h @@ -81,7 +81,7 @@ struct ProcessCallback virtual Response reportError (const std::wstring& msg, size_t retryNumber) = 0; //throw X; recoverable error situation virtual void reportFatalError(const std::wstring& msg) = 0; //throw X; non-recoverable error situation - virtual void abortProcessNow() = 0; //will throw an exception => don't call while in a C GUI callstack + [[noreturn]] virtual void abortProcessNow() = 0; //will throw an exception => don't call while in a C GUI callstack }; } diff --git a/FreeFileSync/Source/base/resolve_path.cpp b/FreeFileSync/Source/base/resolve_path.cpp index 5acf4355..89000583 100644 --- a/FreeFileSync/Source/base/resolve_path.cpp +++ b/FreeFileSync/Source/base/resolve_path.cpp @@ -1,3 +1,9 @@ +// ***************************************************************************** +// * 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 * +// ***************************************************************************** + #include "resolve_path.h" #include <set> //not necessarily included by <map>! #include <map> diff --git a/FreeFileSync/Source/base/status_handler.h b/FreeFileSync/Source/base/status_handler.h index 59d5c80c..faeeaf06 100644 --- a/FreeFileSync/Source/base/status_handler.h +++ b/FreeFileSync/Source/base/status_handler.h @@ -71,9 +71,10 @@ struct Statistics struct ProcessSummary { + std::chrono::system_clock::time_point startTime; SyncResult finalStatus = SyncResult::ABORTED; std::wstring jobName; //may be empty - ProgressStats statsProcessed ; + ProgressStats statsProcessed; ProgressStats statsTotal; std::chrono::milliseconds totalTime{}; }; @@ -126,14 +127,14 @@ public: requestUiRefresh(); //throw X } - void abortProcessNow() override + [[noreturn]] void abortProcessNow() override { if (!abortRequested_) abortRequested_ = AbortTrigger::PROGRAM; forceUiRefreshNoThrow(); throw AbortProcess(); } - void userAbortProcessNow() + [[noreturn]] void userAbortProcessNow() { abortRequested_ = AbortTrigger::USER; //may overwrite AbortTrigger::PROGRAM forceUiRefreshNoThrow(); //flush GUI to show new abort state diff --git a/FreeFileSync/Source/base/structures.cpp b/FreeFileSync/Source/base/structures.cpp index c900206a..1f2e0fa1 100644 --- a/FreeFileSync/Source/base/structures.cpp +++ b/FreeFileSync/Source/base/structures.cpp @@ -11,7 +11,7 @@ #include <zen/i18n.h> #include <zen/time.h> #include "path_filter.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; using namespace fff; diff --git a/FreeFileSync/Source/base/structures.h b/FreeFileSync/Source/base/structures.h index 372d48b5..6cbf645b 100644 --- a/FreeFileSync/Source/base/structures.h +++ b/FreeFileSync/Source/base/structures.h @@ -11,7 +11,7 @@ #include <memory> #include <chrono> #include <zen/zstring.h> -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/base/synchronization.cpp b/FreeFileSync/Source/base/synchronization.cpp index ed65977a..97894be6 100644 --- a/FreeFileSync/Source/base/synchronization.cpp +++ b/FreeFileSync/Source/base/synchronization.cpp @@ -16,8 +16,8 @@ #include "status_handler_impl.h" #include "versioning.h" #include "binary.h" -#include "../fs/concrete.h" -#include "../fs/native.h" +#include "../afs/concrete.h" +#include "../afs/native.h" #include <unistd.h> //fsync #include <fcntl.h> //open @@ -2348,7 +2348,7 @@ void fff::synchronize(const std::chrono::system_clock::time_point& syncStartTime bool recSupported = false; tryReportingError([&] { - recSupported = AFS::supportsRecycleBin(baseFolderPath, [&]{ callback.requestUiRefresh(); /*may throw*/ }); //throw FileError + recSupported = AFS::supportsRecycleBin(baseFolderPath); //throw FileError }, callback); //throw X recyclerSupported.emplace(baseFolderPath, recSupported); diff --git a/FreeFileSync/Source/base/synchronization.h b/FreeFileSync/Source/base/synchronization.h index b904390f..c0c5df35 100644 --- a/FreeFileSync/Source/base/synchronization.h +++ b/FreeFileSync/Source/base/synchronization.h @@ -8,8 +8,8 @@ #define SYNCHRONIZATION_H_8913470815943295 #include <chrono> +#include "config.h" #include "file_hierarchy.h" -#include "process_xml.h" #include "process_callback.h" diff --git a/FreeFileSync/Source/base/versioning.cpp b/FreeFileSync/Source/base/versioning.cpp index bdc357a5..aab48df1 100644 --- a/FreeFileSync/Source/base/versioning.cpp +++ b/FreeFileSync/Source/base/versioning.cpp @@ -1,3 +1,9 @@ +// ***************************************************************************** +// * 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 * +// ***************************************************************************** + #include "versioning.h" #include "parallel_scan.h" #include "status_handler_impl.h" @@ -83,7 +89,7 @@ AbstractPath FileVersioner::generateVersionedPath(const Zstring& relativePath) c versionedRelPath = relativePath + Zstr(' ') + timeStamp_ + getDotExtension(relativePath); assert(impl::parseVersionedFileName(afterLast(versionedRelPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL)) == std::pair(syncStartTime_, afterLast(relativePath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL))); - (void)syncStartTime_; //silence clang's "unused variable" arning + (void)syncStartTime_; //clang: -Wunused-private-field break; } return AFS::appendRelPath(versioningFolderPath_, versionedRelPath); diff --git a/FreeFileSync/Source/base/versioning.h b/FreeFileSync/Source/base/versioning.h index fe6c3a65..035a2254 100644 --- a/FreeFileSync/Source/base/versioning.h +++ b/FreeFileSync/Source/base/versioning.h @@ -12,7 +12,7 @@ #include <zen/file_error.h> #include "structures.h" #include "algorithm.h" -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/ui/abstract_folder_picker.h b/FreeFileSync/Source/ui/abstract_folder_picker.h index b8d9f1ed..c7da13f6 100644 --- a/FreeFileSync/Source/ui/abstract_folder_picker.h +++ b/FreeFileSync/Source/ui/abstract_folder_picker.h @@ -8,7 +8,7 @@ #define ABSTRACT_FOLDER_PICKER_HEADER_324872346895690 #include <wx/window.h> -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/ui/batch_config.h b/FreeFileSync/Source/ui/batch_config.h index 9a6804ca..7bb406b3 100644 --- a/FreeFileSync/Source/ui/batch_config.h +++ b/FreeFileSync/Source/ui/batch_config.h @@ -8,7 +8,7 @@ #define BATCH_CONFIG_H_3921674832168945 #include <wx/window.h> -#include "../base/process_xml.h" +#include "../base/config.h" namespace fff diff --git a/FreeFileSync/Source/ui/batch_status_handler.cpp b/FreeFileSync/Source/ui/batch_status_handler.cpp index 4d6d0376..51441ddc 100644 --- a/FreeFileSync/Source/ui/batch_status_handler.cpp +++ b/FreeFileSync/Source/ui/batch_status_handler.cpp @@ -11,7 +11,7 @@ #include <wx/app.h> #include "../base/resolve_path.h" #include "../base/generate_logfile.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; using namespace fff; @@ -33,7 +33,7 @@ BatchStatusHandler::BatchStatusHandler(bool showProgress, automaticRetryCount_(automaticRetryCount), automaticRetryDelay_(automaticRetryDelay), progressDlg_(createProgressDialog(*this, [this] { this->onProgressDialogTerminate(); }, *this, nullptr /*parentWindow*/, showProgress, autoCloseDialog, -jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, [&] +startTime, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, [&] { switch (postSyncAction) { @@ -97,7 +97,7 @@ BatchStatusHandler::Result BatchStatusHandler::reportFinalStatus(const Zstring& const ProcessSummary summary { - finalStatus, jobName_, + startTime_, finalStatus, jobName_, getStatsCurrent(currentPhase()), getStatsTotal (currentPhase()), totalTime @@ -129,7 +129,7 @@ BatchStatusHandler::Result BatchStatusHandler::reportFinalStatus(const Zstring& trim(commandLine); if (!commandLine.empty()) - errorLog_.logMsg(replaceCpy(_("Executing command %x"), L"%x", fmtPath(commandLine)), MSG_TYPE_INFO); + errorLog_.logMsg(_("Executing command:") + L" " + utfTo<std::wstring>(commandLine), MSG_TYPE_INFO); //----------------- always save log under %appdata%\FreeFileSync\Logs ------------------------ //create not before destruction: 1. avoid issues with FFS trying to sync open log file 2. simplify transactional retry on failure 3. include status in log file name without rename @@ -139,7 +139,7 @@ BatchStatusHandler::Result BatchStatusHandler::reportFinalStatus(const Zstring& { //do NOT use tryReportingError()! saving log files should not be cancellable! auto notifyStatusNoThrow = [&](const std::wstring& msg) { try { reportStatus(msg); /*throw X*/ } catch (...) {} }; - logFilePath = saveLogFile(summary, errorLog_, startTime_, altLogFolderPathPhrase, logfilesMaxAgeDays, logFilePathsToKeep, notifyStatusNoThrow /*throw X*/); //throw FileError + logFilePath = saveLogFile(summary, errorLog_, altLogFolderPathPhrase, logfilesMaxAgeDays, logFilePathsToKeep, notifyStatusNoThrow /*throw X*/); //throw FileError } catch (const FileError& e) { errorLog_.logMsg(e.toString(), MSG_TYPE_ERROR); } @@ -151,7 +151,7 @@ BatchStatusHandler::Result BatchStatusHandler::reportFinalStatus(const Zstring& ::wxSetEnv(L"logfile_path", AFS::getDisplayPath(logFilePath)); //---------------------------------------------------------------------- //use ExecutionType::ASYNC until there is a reason not to: https://freefilesync.org/forum/viewtopic.php?t=31 - shellExecute(expandMacros(commandLine), ExecutionType::ASYNC); //throw FileError + shellExecute(expandMacros(commandLine), ExecutionType::ASYNC, false/*hideConsole*/); //throw FileError } catch (const FileError& e) { errorLog_.logMsg(e.toString(), MSG_TYPE_ERROR); } diff --git a/FreeFileSync/Source/ui/batch_status_handler.h b/FreeFileSync/Source/ui/batch_status_handler.h index e3a73a78..b8b8e25d 100644 --- a/FreeFileSync/Source/ui/batch_status_handler.h +++ b/FreeFileSync/Source/ui/batch_status_handler.h @@ -10,9 +10,8 @@ #include <chrono> #include <zen/error_log.h> #include "progress_indicator.h" +#include "../base/config.h" #include "../base/status_handler.h" -#include "../base/process_xml.h" -//#include "../base/return_codes.h" namespace fff diff --git a/FreeFileSync/Source/ui/cfg_grid.cpp b/FreeFileSync/Source/ui/cfg_grid.cpp index 3d5023b4..d0f9877f 100644 --- a/FreeFileSync/Source/ui/cfg_grid.cpp +++ b/FreeFileSync/Source/ui/cfg_grid.cpp @@ -15,7 +15,7 @@ #include <wx/settings.h> #include "../base/icon_buffer.h" #include "../base/ffs_paths.h" -//#include "../fs/mtp.h" +//#include "../afs/mtp.h" using namespace zen; using namespace fff; diff --git a/FreeFileSync/Source/ui/cfg_grid.h b/FreeFileSync/Source/ui/cfg_grid.h index 3983df06..5e14aca0 100644 --- a/FreeFileSync/Source/ui/cfg_grid.h +++ b/FreeFileSync/Source/ui/cfg_grid.h @@ -11,7 +11,7 @@ #include <wx+/dc.h> #include <zen/zstring.h> #include "../base/return_codes.h" -#include "../fs/native.h" +#include "../afs/native.h" namespace fff diff --git a/FreeFileSync/Source/ui/folder_selector.cpp b/FreeFileSync/Source/ui/folder_selector.cpp index 86ae2e16..379cf5b2 100644 --- a/FreeFileSync/Source/ui/folder_selector.cpp +++ b/FreeFileSync/Source/ui/folder_selector.cpp @@ -12,12 +12,12 @@ #include <wx+/popup_dlg.h> #include <wx+/context_menu.h> #include <wx+/image_resources.h> -#include "../fs/concrete.h" -#include "../fs/native.h" +#include "small_dlgs.h" //includes structures.h, which defines "AFS" +#include "../afs/concrete.h" +#include "../afs/native.h" #include "../base/icon_buffer.h" - #include "small_dlgs.h" //includes structures.h, which defines "AFS" using namespace zen; using namespace fff; diff --git a/FreeFileSync/Source/ui/folder_selector.h b/FreeFileSync/Source/ui/folder_selector.h index 3039cd40..2e4c4073 100644 --- a/FreeFileSync/Source/ui/folder_selector.h +++ b/FreeFileSync/Source/ui/folder_selector.h @@ -12,7 +12,7 @@ #include <wx/button.h> #include <wx+/file_drop.h> #include "folder_history_box.h" -#include "../fs/abstract.h" +#include "../afs/abstract.h" namespace fff diff --git a/FreeFileSync/Source/ui/gui_status_handler.cpp b/FreeFileSync/Source/ui/gui_status_handler.cpp index 52d6ff69..28d6cc2b 100644 --- a/FreeFileSync/Source/ui/gui_status_handler.cpp +++ b/FreeFileSync/Source/ui/gui_status_handler.cpp @@ -13,7 +13,7 @@ #include "main_dlg.h" #include "../base/generate_logfile.h" #include "../base/resolve_path.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" using namespace zen; using namespace fff; @@ -145,7 +145,7 @@ StatusHandlerTemporaryPanel::Result StatusHandlerTemporaryPanel::reportFinalStat const ProcessSummary summary { - finalStatus, {} /*jobName*/, + startTime_, finalStatus, {} /*jobName*/, getStatsCurrent(currentPhase()), getStatsTotal (currentPhase()), totalTime @@ -321,13 +321,13 @@ StatusHandlerFloatingDialog::StatusHandlerFloatingDialog(wxFrame* parentDlg, PostSyncCondition postSyncCondition, bool& autoCloseDialog) : progressDlg_(createProgressDialog(*this, [this] { this->onProgressDialogTerminate(); }, *this, parentDlg, true /*showProgress*/, autoCloseDialog, -jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, PostSyncAction2::NONE)), - automaticRetryCount_(automaticRetryCount), - automaticRetryDelay_(automaticRetryDelay), - jobName_(jobName), - startTime_(startTime), - postSyncCommand_(postSyncCommand), - postSyncCondition_(postSyncCondition), +startTime, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, PostSyncAction2::NONE)), + automaticRetryCount_(automaticRetryCount), + automaticRetryDelay_(automaticRetryDelay), + jobName_(jobName), + startTime_(startTime), + postSyncCommand_(postSyncCommand), + postSyncCondition_(postSyncCondition), autoCloseDialogOut_(autoCloseDialog) {} @@ -366,7 +366,7 @@ StatusHandlerFloatingDialog::Result StatusHandlerFloatingDialog::reportFinalStat const ProcessSummary summary { - finalStatus, jobName_, + startTime_, finalStatus, jobName_, getStatsCurrent(currentPhase()), getStatsTotal (currentPhase()), totalTime @@ -398,7 +398,7 @@ StatusHandlerFloatingDialog::Result StatusHandlerFloatingDialog::reportFinalStat trim(commandLine); if (!commandLine.empty()) - errorLog_.logMsg(replaceCpy(_("Executing command %x"), L"%x", fmtPath(commandLine)), MSG_TYPE_INFO); + errorLog_.logMsg(_("Executing command:") + L" " + utfTo<std::wstring>(commandLine), MSG_TYPE_INFO); //----------------- always save log under %appdata%\FreeFileSync\Logs ------------------------ AbstractPath logFilePath = getNullPath(); @@ -406,7 +406,7 @@ StatusHandlerFloatingDialog::Result StatusHandlerFloatingDialog::reportFinalStat { //do NOT use tryReportingError()! saving log files should not be cancellable! auto notifyStatusNoThrow = [&](const std::wstring& msg) { try { reportStatus(msg); /*throw X*/ } catch (...) {} }; - logFilePath = saveLogFile(summary, errorLog_, startTime_, altLogFolderPathPhrase, logfilesMaxAgeDays, logFilePathsToKeep, notifyStatusNoThrow /*throw (X)*/); //throw FileError + logFilePath = saveLogFile(summary, errorLog_, altLogFolderPathPhrase, logfilesMaxAgeDays, logFilePathsToKeep, notifyStatusNoThrow /*throw (X)*/); //throw FileError } catch (const FileError& e) { errorLog_.logMsg(e.toString(), MSG_TYPE_ERROR); } @@ -418,7 +418,7 @@ StatusHandlerFloatingDialog::Result StatusHandlerFloatingDialog::reportFinalStat ::wxSetEnv(L"logfile_path", AFS::getDisplayPath(logFilePath)); //---------------------------------------------------------------------- //use ExecutionType::ASYNC until there is reason not to: https://freefilesync.org/forum/viewtopic.php?t=31 - shellExecute(expandMacros(commandLine), ExecutionType::ASYNC); //throw FileError + shellExecute(expandMacros(commandLine), ExecutionType::ASYNC, false/*hideConsole*/); //throw FileError } catch (const FileError& e) { errorLog_.logMsg(e.toString(), MSG_TYPE_ERROR); } diff --git a/FreeFileSync/Source/ui/main_dlg.cpp b/FreeFileSync/Source/ui/main_dlg.cpp index 9da4658c..86b68bfc 100644 --- a/FreeFileSync/Source/ui/main_dlg.cpp +++ b/FreeFileSync/Source/ui/main_dlg.cpp @@ -37,10 +37,10 @@ #include "batch_config.h" #include "triple_splitter.h" #include "app_icon.h" +#include "../afs/concrete.h" #include "../base/comparison.h" #include "../base/synchronization.h" #include "../base/algorithm.h" -#include "../fs/concrete.h" #include "../base/resolve_path.h" #include "../base/ffs_paths.h" #include "../base/help_provider.h" @@ -540,7 +540,6 @@ MainDialog::MainDialog(const Zstring& globalConfigFilePath, //file grid: context menu m_gridMainL->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onMainGridContextL), nullptr, this); - m_gridMainC->Connect(EVENT_GRID_MOUSE_RIGHT_DOWN, GridClickEventHandler(MainDialog::onMainGridContextC), nullptr, this); m_gridMainR->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onMainGridContextR), nullptr, this); m_gridMainL->Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(MainDialog::onGridDoubleClickL), nullptr, this); @@ -1433,7 +1432,7 @@ void invokeCommandLine(const Zstring& commandLinePhrase, //throw FileError replace(command, Zstr("%local_path%"), localPath); replace(command, Zstr("%local_path2%"), localPath2); - shellExecute(command, selection.size() > EXT_APP_MASS_INVOKE_THRESHOLD ? ExecutionType::SYNC : ExecutionType::ASYNC); //throw FileError + shellExecute(command, selection.size() > EXT_APP_MASS_INVOKE_THRESHOLD ? ExecutionType::SYNC : ExecutionType::ASYNC, false/*hideConsole*/); //throw FileError } } } @@ -2243,29 +2242,6 @@ void MainDialog::onTreeGridContext(GridClickEvent& event) } -void MainDialog::onMainGridContextC(GridClickEvent& event) -{ - warn_static("do we still need this???") -#if 0 - ContextMenu menu; - - menu.addItem(_("Include all"), [&] - { - setActiveStatus(true, folderCmp_); - updateGui(); - }, nullptr, filegrid::getDataView(*m_gridMainC).rowsTotal() > 0); - - menu.addItem(_("Exclude all"), [&] - { - setActiveStatus(false, folderCmp_); - updateGuiDelayedIf(!m_bpButtonShowExcluded->isActive()); //show update GUI before removing rows - }, nullptr, filegrid::getDataView(*m_gridMainC).rowsTotal() > 0); - - menu.popup(*m_gridMainC, event.mousePos_); -#endif -} - - void MainDialog::onMainGridContextL(GridClickEvent& event) { onMainGridContextRim(true /*leftSide*/, event); @@ -4278,9 +4254,8 @@ void MainDialog::setLastOperationLog(const ProcessSummary& summary, const std::s const int64_t totalTimeSec = std::chrono::duration_cast<std::chrono::seconds>(summary.totalTime).count(); - m_staticTextTotalTime->SetLabel(totalTimeSec < 3600 ? - wxTimeSpan::Seconds(totalTimeSec).Format( L"%M:%S") : - wxTimeSpan::Seconds(totalTimeSec).Format(L"%H:%M:%S")); + m_staticTextTotalTime->SetLabel(wxTimeSpan::Seconds(totalTimeSec).Format(L"%H:%M:%S")); + //totalTimeSec < 3600 ? wxTimeSpan::Seconds(totalTimeSec).Format(L"%M:%S") -> let's use full precision for max. clarity: https://freefilesync.org/forum/viewtopic.php?t=6308 logPanel_->setLog(errorLog); m_panelLog->Layout(); diff --git a/FreeFileSync/Source/ui/main_dlg.h b/FreeFileSync/Source/ui/main_dlg.h index 410767b7..7447f9cc 100644 --- a/FreeFileSync/Source/ui/main_dlg.h +++ b/FreeFileSync/Source/ui/main_dlg.h @@ -163,7 +163,6 @@ private: //context menu handler methods void onMainGridContextL(zen::GridClickEvent& event); - void onMainGridContextC(zen::GridClickEvent& event); void onMainGridContextR(zen::GridClickEvent& event); void onMainGridContextRim(bool leftSide, zen::GridClickEvent& event); diff --git a/FreeFileSync/Source/ui/progress_indicator.cpp b/FreeFileSync/Source/ui/progress_indicator.cpp index 48104bc3..5a1243f6 100644 --- a/FreeFileSync/Source/ui/progress_indicator.cpp +++ b/FreeFileSync/Source/ui/progress_indicator.cpp @@ -392,8 +392,7 @@ void CompareProgressDialog::Impl::updateProgressGui() const int64_t timeElapSec = std::chrono::duration_cast<std::chrono::seconds>(timeElapsed).count(); - setText(*m_staticTextTimeElapsed, - timeElapSec < 3600 ? + setText(*m_staticTextTimeElapsed, timeElapSec < 3600 ? wxTimeSpan::Seconds(timeElapSec).Format( L"%M:%S") : wxTimeSpan::Seconds(timeElapSec).Format(L"%H:%M:%S"), &layoutChanged); @@ -663,6 +662,7 @@ public: wxFrame* parentFrame, bool showProgress, bool autoCloseDialog, + const std::chrono::system_clock::time_point& syncStartTime, const wxString& jobName, const Zstring& soundFileSyncComplete, bool ignoreErrors, @@ -720,6 +720,7 @@ private: SyncProgressPanelGenerated& pnl_; //wxPanel containing the GUI controls of *this + const std::chrono::system_clock::time_point& syncStartTime_; const wxString jobName_; const Zstring soundFileSyncComplete_; StopWatch stopWatch_; @@ -767,6 +768,7 @@ SyncProgressDialogImpl<TopLevelDialog>::SyncProgressDialogImpl(long style, //wxF wxFrame* parentFrame, bool showProgress, bool autoCloseDialog, + const std::chrono::system_clock::time_point& syncStartTime, const wxString& jobName, const Zstring& soundFileSyncComplete, bool ignoreErrors, @@ -774,6 +776,7 @@ SyncProgressDialogImpl<TopLevelDialog>::SyncProgressDialogImpl(long style, //wxF PostSyncAction2 postSyncAction) : TopLevelDialog(parentFrame, wxID_ANY, wxString(), wxDefaultPosition, wxDefaultSize, style), //title is overwritten anyway in setExternalStatus() pnl_(*new SyncProgressPanelGenerated(this)), //ownership passed to "this" + syncStartTime_(syncStartTime), jobName_ (jobName), soundFileSyncComplete_(soundFileSyncComplete), parentFrame_(parentFrame), @@ -1013,17 +1016,22 @@ template <class TopLevelDialog> void SyncProgressDialogImpl<TopLevelDialog>::setExternalStatus(const wxString& status, const wxString& progress) //progress may be empty! { //sys tray: order "top-down": jobname, status, progress - wxString systrayTooltip = jobName_.empty() ? status : L'"' + jobName_ + L"\"\n" + status; + wxString systrayTooltip = jobName_.empty() ? status : jobName_ + L"\n" + status; if (!progress.empty()) systrayTooltip += L" " + progress; //window caption/taskbar; inverse order: progress, status, jobname wxString title = progress.empty() ? status : progress + SPACED_DASH + status; + if (!jobName_.empty()) - title += wxString(SPACED_DASH) + L'"' + jobName_ + L'"'; + title += wxString(SPACED_DASH) + jobName_; + + const TimeComp tc = getLocalTime(std::chrono::system_clock::to_time_t(syncStartTime_)); //returns empty string on failure + title += SPACED_DASH + formatTime<std::wstring>(FORMAT_DATE_TIME, tc); + //--------------------------------------------------------------------------- //systray tooltip, if window is minimized - if (trayIcon_.get()) + if (trayIcon_) trayIcon_->setToolTip(systrayTooltip); //show text in dialog title (and at the same time in taskbar) @@ -1031,7 +1039,7 @@ void SyncProgressDialogImpl<TopLevelDialog>::setExternalStatus(const wxString& s if (parentFrame_->GetTitle() != title) parentFrame_->SetTitle(title); - //always set a title: we don't wxGTK to show "nameless window" instead + //always set a title: we don't want wxGTK to show "nameless window" instead if (this->GetTitle() != title) this->SetTitle(title); } @@ -1163,8 +1171,7 @@ void SyncProgressDialogImpl<TopLevelDialog>::updateProgressGui(bool allowYield) const int64_t timeElapSec = std::chrono::duration_cast<std::chrono::seconds>(timeElapsed).count(); - setText(*pnl_.m_staticTextTimeElapsed, - timeElapSec < 3600 ? + setText(*pnl_.m_staticTextTimeElapsed, timeElapSec < 3600 ? wxTimeSpan::Seconds(timeElapSec).Format( L"%M:%S") : wxTimeSpan::Seconds(timeElapSec).Format(L"%H:%M:%S"), &layoutChanged); @@ -1354,6 +1361,11 @@ void SyncProgressDialogImpl<TopLevelDialog>::showSummary(SyncResult finalStatus, //hide remaining time pnl_.m_panelTimeRemaining->Hide(); + const int64_t totalTimeSec = std::chrono::duration_cast<std::chrono::seconds>(stopWatch_.elapsed()).count(); + setText(*pnl_.m_staticTextTimeElapsed, wxTimeSpan::Seconds(totalTimeSec).Format(L"%H:%M:%S")); + //totalTimeSec < 3600 ? wxTimeSpan::Seconds(totalTimeSec).Format(L"%M:%S") -> let's use full precision for max. clarity: https://freefilesync.org/forum/viewtopic.php?t=6308 + //maybe also should rename to "Total time"!? + resumeFromSystray(); //if in tray mode... //------- change class state ------- @@ -1433,9 +1445,8 @@ void SyncProgressDialogImpl<TopLevelDialog>::showSummary(SyncResult finalStatus, const size_t pagePosProgress = 0; const size_t pagePosLog = 1; - const bool wasDetached = pnl_.bSizerRoot->Detach(pnl_.m_panelProgress); + [[maybe_unused]] const bool wasDetached = pnl_.bSizerRoot->Detach(pnl_.m_panelProgress); assert(wasDetached); - (void)wasDetached; pnl_.m_panelProgress->Reparent(pnl_.m_notebookResult); pnl_.m_notebookResult->AddPage(pnl_.m_panelProgress, _("Progress"), true /*bSelect*/); @@ -1635,6 +1646,7 @@ SyncProgressDialog* fff::createProgressDialog(AbortCallback& abortCb, wxFrame* parentWindow, //may be nullptr bool showProgress, bool autoCloseDialog, + const std::chrono::system_clock::time_point& syncStartTime, const wxString& jobName, const Zstring& soundFileSyncComplete, bool ignoreErrors, @@ -1647,13 +1659,13 @@ SyncProgressDialog* fff::createProgressDialog(AbortCallback& abortCb, //https://groups.google.com/forum/#!topic/wx-users/J5SjjLaBOQE return new SyncProgressDialogImpl<wxDialog>(wxDEFAULT_DIALOG_STYLE | wxMAXIMIZE_BOX | wxMINIMIZE_BOX | wxRESIZE_BORDER, [&](wxDialog& progDlg) { return parentWindow; }, - abortCb, notifyWindowTerminate, syncStat, parentWindow, showProgress, autoCloseDialog, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, postSyncAction); + abortCb, notifyWindowTerminate, syncStat, parentWindow, showProgress, autoCloseDialog, syncStartTime, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, postSyncAction); } else //FFS batch job { auto dlg = new SyncProgressDialogImpl<wxFrame>(wxDEFAULT_FRAME_STYLE, [](wxFrame& progDlg) { return &progDlg; }, - abortCb, notifyWindowTerminate, syncStat, parentWindow, showProgress, autoCloseDialog, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, postSyncAction); + abortCb, notifyWindowTerminate, syncStat, parentWindow, showProgress, autoCloseDialog, syncStartTime, jobName, soundFileSyncComplete, ignoreErrors, automaticRetryCount, postSyncAction); //only top level windows should have an icon: dlg->SetIcon(getFfsIcon()); diff --git a/FreeFileSync/Source/ui/progress_indicator.h b/FreeFileSync/Source/ui/progress_indicator.h index 5c6dae86..e2db0533 100644 --- a/FreeFileSync/Source/ui/progress_indicator.h +++ b/FreeFileSync/Source/ui/progress_indicator.h @@ -11,8 +11,8 @@ #include <zen/error_log.h> #include <zen/zstring.h> #include <wx/frame.h> +#include "../base/config.h" #include "../base/status_handler.h" -#include "../base/process_xml.h" #include "../base/return_codes.h" @@ -90,6 +90,7 @@ SyncProgressDialog* createProgressDialog(AbortCallback& abortCb, wxFrame* parentWindow, //may be nullptr bool showProgress, bool autoCloseDialog, + const std::chrono::system_clock::time_point& syncStartTime, const wxString& jobName, const Zstring& soundFileSyncComplete, bool ignoreErrors, @@ -102,7 +103,7 @@ template <class ProgressDlg> class PauseTimers { public: - PauseTimers(ProgressDlg& ss) : ss_(ss), timerWasRunning_(ss.timerIsRunning()) { ss_.timerSetStatus(false); } + explicit PauseTimers(ProgressDlg& ss) : ss_(ss), timerWasRunning_(ss.timerIsRunning()) { ss_.timerSetStatus(false); } ~PauseTimers() { ss_.timerSetStatus(timerWasRunning_); } //restore previous state: support recursive calls private: ProgressDlg& ss_; diff --git a/FreeFileSync/Source/ui/small_dlgs.cpp b/FreeFileSync/Source/ui/small_dlgs.cpp index 871dd33e..2abaa3e5 100644 --- a/FreeFileSync/Source/ui/small_dlgs.cpp +++ b/FreeFileSync/Source/ui/small_dlgs.cpp @@ -27,6 +27,7 @@ #include "gui_generated.h" #include "folder_selector.h" #include "version_check.h" +#include "abstract_folder_picker.h" #include "../base/algorithm.h" #include "../base/synchronization.h" #include "../base/help_provider.h" @@ -35,15 +36,13 @@ #include "../base/generate_logfile.h" #include "../base/icon_buffer.h" #include "../version/version.h" +#include "../afs/concrete.h" +#include "../afs/gdrive.h" +#include "../afs/sftp.h" +#include "../afs/ftp.h" - #include "abstract_folder_picker.h" - #include "../fs/concrete.h" - #include "../fs/gdrive.h" - #include "../fs/sftp.h" - #include "../fs/ftp.h" - //#include "../fs/ftp_common.h" using namespace zen; using namespace fff; diff --git a/FreeFileSync/Source/ui/small_dlgs.h b/FreeFileSync/Source/ui/small_dlgs.h index 27292afd..3607b593 100644 --- a/FreeFileSync/Source/ui/small_dlgs.h +++ b/FreeFileSync/Source/ui/small_dlgs.h @@ -8,7 +8,7 @@ #define SMALL_DLGS_H_8321790875018750245 #include <wx/window.h> -#include "../base/process_xml.h" +#include "../base/config.h" #include "../base/synchronization.h" @@ -53,7 +53,6 @@ ReturnSmallDlg::ButtonPressed showSelectTimespanDlg(wxWindow* parent, time_t& ti ReturnSmallDlg::ButtonPressed showCfgHighlightDlg(wxWindow* parent, int& cfgHistSyncOverdueDays); - ReturnSmallDlg::ButtonPressed showCloudSetupDialog(wxWindow* parent, Zstring& folderPathPhrase, size_t& parallelOps, const std::wstring* parallelOpsDisabledReason /*optional: disable control + show text*/); diff --git a/FreeFileSync/Source/ui/sync_cfg.cpp b/FreeFileSync/Source/ui/sync_cfg.cpp index 35df2b01..8a13dcec 100644 --- a/FreeFileSync/Source/ui/sync_cfg.cpp +++ b/FreeFileSync/Source/ui/sync_cfg.cpp @@ -23,7 +23,7 @@ #include "../base/help_provider.h" #include "../base/norm_filter.h" #include "../base/generate_logfile.h" -#include "../fs/concrete.h" +#include "../afs/concrete.h" diff --git a/FreeFileSync/Source/ui/taskbar.cpp b/FreeFileSync/Source/ui/taskbar.cpp index c4bc7bec..f4e95212 100644 --- a/FreeFileSync/Source/ui/taskbar.cpp +++ b/FreeFileSync/Source/ui/taskbar.cpp @@ -64,11 +64,14 @@ public: } private: + Impl (const Impl&) = delete; + Impl& operator=(const Impl&) = delete; + UnityLauncherEntry* const tbEntry_; }; #else //no taskbar support -class Taskbar::Impl +class Taskbar::Impl //throw TaskbarNotAvailable { public: Impl(const wxFrame& window) { throw TaskbarNotAvailable(); } diff --git a/FreeFileSync/Source/ui/taskbar.h b/FreeFileSync/Source/ui/taskbar.h index 667d8afd..a731b9db 100644 --- a/FreeFileSync/Source/ui/taskbar.h +++ b/FreeFileSync/Source/ui/taskbar.h @@ -11,7 +11,7 @@ #include <wx/frame.h> /* -Windows 7; show progress in windows superbar via ITaskbarList3 Interface: https://msdn.microsoft.com/en-us/library/dd391692 +Windows 7; show progress in Windows superbar via ITaskbarList3 Interface: https://docs.microsoft.com/de-de/windows/desktop/api/shobjidl_core/nn-shobjidl_core-itaskbarlist3 Ubuntu: use Unity interface (optional) diff --git a/FreeFileSync/Source/version/version.h b/FreeFileSync/Source/version/version.h index b67a37eb..3934bc90 100644 --- a/FreeFileSync/Source/version/version.h +++ b/FreeFileSync/Source/version/version.h @@ -3,7 +3,7 @@ namespace fff { -const char ffsVersion[] = "10.11"; //internal linkage! +const char ffsVersion[] = "10.12"; //internal linkage! const char FFS_VERSION_SEPARATOR = '.'; } diff --git a/wx+/graph.cpp b/wx+/graph.cpp index 9cacd1bf..3df8888a 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -621,10 +621,10 @@ void Graph2D::render(wxDC& dc) const maxX = std::max(maxX, rangeX.second); } - const wxSize minimalBlockSizePx = dc.GetTextExtent(L"00"); - if (minX <= maxX && maxX - minX < std::numeric_limits<double>::infinity()) //valid x-range { + const wxSize minimalBlockSizePx = dc.GetTextExtent(L"00"); + int blockCountX = 0; //enlarge minX, maxX to a multiple of a "useful" block size if (attr_.labelposX != LABEL_X_NONE && attr_.labelFmtX.get()) @@ -675,7 +675,9 @@ void Graph2D::render(wxDC& dc) const minimalBlockSizePx.GetHeight() * 3, *attr_.labelFmtY); - if (graphArea.width <= 1 || graphArea.height <= 1) return; + if (graphArea.width <= 1 || graphArea.height <= 1) + return; + const ConvertCoord cvrtX(minX, maxX, graphArea.width - 1); //map [minX, maxX] to [0, pixelWidth - 1] const ConvertCoord cvrtY(maxY, minY, graphArea.height - 1); //map [minY, maxY] to [pixelHeight - 1, 0] @@ -710,7 +712,7 @@ void Graph2D::render(wxDC& dc) const } //update active mouse selection - if (activeSel_.get() && graphArea.width > 0 && graphArea.height > 0) + if (activeSel_) { auto widen = [](double* low, double* high) { diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 114bb82d..2838f575 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -1177,9 +1177,10 @@ private: int pixelsPerUnitY = 0; wnd_.refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); - if (pixelsPerUnitY <= 0) return; + if (pixelsPerUnitY <= 0) + return; - const double mouseDragSpeedIncScrollU = pixelsPerUnitY > 0 ? MOUSE_DRAG_ACCELERATION_DIP * wnd_.rowLabelWin_.getRowHeight() / pixelsPerUnitY : 0; //unit: [scroll units / (DIP * sec)] + const double mouseDragSpeedIncScrollU = MOUSE_DRAG_ACCELERATION_DIP * wnd_.rowLabelWin_.getRowHeight() / pixelsPerUnitY; //unit: [scroll units / (DIP * sec)] auto autoScroll = [&](int overlapPix, double& toScroll) { @@ -1797,7 +1798,7 @@ void Grid::setColumnConfig(const std::vector<Grid::ColAttributes>& attr) } //"ownership" of visible columns is now within Grid - visibleCols_ = visCols; + visibleCols_ = std::move(visCols); updateWindowSizes(); Refresh(); diff --git a/wx+/popup_dlg.h b/wx+/popup_dlg.h index 2aedf9b8..0acd2a95 100644 --- a/wx+/popup_dlg.h +++ b/wx+/popup_dlg.h @@ -15,7 +15,7 @@ namespace zen { //parent window, optional: support correct dialog placement above parent on multiple monitor systems -//this module requires error, warning and info image files in resources.zip, see <wx+/image_resources.h> +//this module requires error, warning and info image files in Icons.zip, see <wx+/image_resources.h> struct PopupDialogCfg; diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index 03025049..142c9b7f 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -31,7 +31,7 @@ public: //Suse Linux/X11: needs parent window, else there are z-order issues SetSizeHints(wxDefaultSize, wxDefaultSize); - SetExtraStyle(this->GetExtraStyle() | wxWS_EX_TRANSIENT); + SetExtraStyle(this->GetExtraStyle() | wxWS_EX_TRANSIENT); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOBK)); //both required: on Ubuntu background is black, foreground white! SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT)); // diff --git a/xBRZ/src/xbrz.cpp b/xBRZ/src/xbrz.cpp index f37d1a01..4c47575f 100644 --- a/xBRZ/src/xbrz.cpp +++ b/xBRZ/src/xbrz.cpp @@ -377,7 +377,7 @@ void blendPixel(const Kernel_3x3& ker, unsigned char blendInfo, //result of preprocessing all four corners of pixel "e" const xbrz::ScalerCfg& cfg) { -#define a get_a<rotDeg>(ker) +//#define a get_a<rotDeg>(ker) #define b get_b<rotDeg>(ker) #define c get_c<rotDeg>(ker) #define d get_d<rotDeg>(ker) @@ -388,8 +388,6 @@ void blendPixel(const Kernel_3x3& ker, #define i get_i<rotDeg>(ker) - (void)a; //silence Clang's -Wunused-function - const unsigned char blend = rotateBlendInfo<rotDeg>(blendInfo); if (getBottomR(blend) >= BLEND_NORMAL) @@ -446,7 +444,7 @@ void blendPixel(const Kernel_3x3& ker, Scaler::blendCorner(px, out); } -#undef a +//#undef a #undef b #undef c #undef d diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 4536ec36..8ac9eb3b 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -453,7 +453,7 @@ void copySecurityContext(const Zstring& source, const Zstring& target, ProcSymli { security_context_t contextSource = nullptr; const int rv = procSl == ProcSymlink::FOLLOW ? - ::getfilecon(source.c_str(), &contextSource) : + ::getfilecon (source.c_str(), &contextSource) : ::lgetfilecon(source.c_str(), &contextSource); if (rv < 0) { @@ -715,3 +715,5 @@ FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& target return result; } + + diff --git a/zen/file_access.h b/zen/file_access.h index fc4b5833..8fdbde68 100644 --- a/zen/file_access.h +++ b/zen/file_access.h @@ -96,6 +96,7 @@ struct FileCopyResult FileCopyResult copyNewFile(const Zstring& sourceFile, const Zstring& targetFile, bool copyFilePermissions, //throw FileError, ErrorTargetExisting, ErrorFileLocked, X //accummulated delta != file size! consider ADS, sparse, compressed files const IOCallback& notifyUnbufferedIO /*throw X*/); + } #endif //FILE_ACCESS_H_8017341345614857 diff --git a/zen/file_traverser.h b/zen/file_traverser.h index 5c1683f8..e49219f9 100644 --- a/zen/file_traverser.h +++ b/zen/file_traverser.h @@ -18,7 +18,7 @@ struct FileInfo { Zstring itemName; Zstring fullPath; - uint64_t fileSize; //[bytes] + uint64_t fileSize = 0; //[bytes] time_t modTime = 0; //number of seconds since Jan. 1st 1970 UTC }; @@ -28,7 +28,6 @@ namespace zen { - //issue with wxStopWatch? https://freefilesync.org/forum/viewtopic.php?t=1426 // => wxStopWatch implementation uses QueryPerformanceCounter: https://github.com/wxWidgets/wxWidgets/blob/17d72a48ffd4d8ff42eed070ac48ee2de50ceabd/src/common/stopwatch.cpp // => whatever the problem was, it's almost certainly not caused by QueryPerformanceCounter(): diff --git a/zen/recycler.h b/zen/recycler.h index 0e5ebbb1..ad96aa53 100644 --- a/zen/recycler.h +++ b/zen/recycler.h @@ -21,7 +21,7 @@ namespace zen Windows ------- --> Recycler API always available: during runtime either SHFileOperation or IFileOperation (since Vista) will be dynamically selected +-> Recycler API (IFileOperation) always available -> COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize Linux diff --git a/zen/ring_buffer.h b/zen/ring_buffer.h index e3dbd55f..8cce8e80 100644 --- a/zen/ring_buffer.h +++ b/zen/ring_buffer.h @@ -182,7 +182,7 @@ public: Iterator(Container& container, size_t offset) : container_(&container), offset_(offset) {} Iterator& operator++() { ++offset_; return *this; } - Iterator& operator+=(ptrdiff_t offset) { offset_ += offset; } + Iterator& operator+=(ptrdiff_t offset) { offset_ += offset; return *this; } inline friend bool operator==(const Iterator& lhs, const Iterator& rhs) { assert(lhs.container_ == rhs.container_); return lhs.offset_ == rhs.offset_; } inline friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return !(lhs == rhs); } inline friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) { return lhs.offset_ - rhs.offset_; } diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 9eff6c1f..3a79d841 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -38,7 +38,7 @@ enum class ScopeGuardRunMode //partially specialize scope guard destructor code and get rid of those pesky MSVC "4127 conditional expression is constant" template <typename F> inline -void runScopeGuardDestructor(F& fun, int /*exeptionCountOld*/, std::integral_constant<ScopeGuardRunMode, ScopeGuardRunMode::ON_EXIT>) +void runScopeGuardDestructor(F& fun, int /*exeptionCountOld*/, std::integral_constant<ScopeGuardRunMode, ScopeGuardRunMode::ON_EXIT>) noexcept { try { fun(); } catch (...) { assert(false); } //consistency: don't expect exceptions for ON_EXIT even if "!failed"! @@ -55,7 +55,7 @@ void runScopeGuardDestructor(F& fun, int exeptionCountOld, std::integral_constan template <typename F> inline -void runScopeGuardDestructor(F& fun, int exeptionCountOld, std::integral_constant<ScopeGuardRunMode, ScopeGuardRunMode::ON_FAIL>) +void runScopeGuardDestructor(F& fun, int exeptionCountOld, std::integral_constant<ScopeGuardRunMode, ScopeGuardRunMode::ON_FAIL>) noexcept { const bool failed = std::uncaught_exceptions() > exeptionCountOld; if (failed) @@ -104,8 +104,8 @@ auto makeGuard(F&& fun) { return ScopeGuard<runMode, std::decay_t<F>>(std::forwa #define ZEN_CHECK_CASE_FOR_CONSTANT_IMPL(X) L ## X -#define ZEN_ON_SCOPE_EXIT(X) auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_EXIT >([&]{ X; }); (void)ZEN_CONCAT(scopeGuard, __LINE__); -#define ZEN_ON_SCOPE_FAIL(X) auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_FAIL >([&]{ X; }); (void)ZEN_CONCAT(scopeGuard, __LINE__); -#define ZEN_ON_SCOPE_SUCCESS(X) auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_SUCCESS>([&]{ X; }); (void)ZEN_CONCAT(scopeGuard, __LINE__); +#define ZEN_ON_SCOPE_EXIT(X) [[maybe_unused]] auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_EXIT >([&]{ X; }); +#define ZEN_ON_SCOPE_FAIL(X) [[maybe_unused]] auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_FAIL >([&]{ X; }); +#define ZEN_ON_SCOPE_SUCCESS(X) [[maybe_unused]] auto ZEN_CONCAT(scopeGuard, __LINE__) = zen::makeGuard<zen::ScopeGuardRunMode::ON_SUCCESS>([&]{ X; }); #endif //SCOPE_GUARD_H_8971632487321434 diff --git a/zen/shell_execute.h b/zen/shell_execute.h index 98824d70..19945a0b 100644 --- a/zen/shell_execute.h +++ b/zen/shell_execute.h @@ -27,7 +27,7 @@ namespace { -void shellExecute(const Zstring& command, ExecutionType type) //throw FileError +void shellExecute(const Zstring& command, ExecutionType type, bool hideConsole) //throw FileError { /* we cannot use wxExecute due to various issues: @@ -35,14 +35,13 @@ void shellExecute(const Zstring& command, ExecutionType type) //throw FileError - does not provide any reasonable error information - uses a zero-sized dummy window as a hack to keep focus which leaves a useless empty icon in ALT-TAB list in Windows */ - if (type == ExecutionType::SYNC) { //Posix ::system() - execute a shell command const int rv = ::system(command.c_str()); //do NOT use std::system as its documentation says nothing about "WEXITSTATUS(rv)", etc... if (rv == -1 || WEXITSTATUS(rv) == 127) throw FileError(_("Incorrect command line:") + L"\n" + utfTo<std::wstring>(command)); - //http://linux.die.net/man/3/system "In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127)" + //http://linux.die.net/man/3/system "In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127)" //Bonus: For an incorrect command line /bin/sh also returns with 127! } else @@ -73,7 +72,7 @@ void shellExecute(const Zstring& command, ExecutionType type) //throw FileError inline void openWithDefaultApplication(const Zstring& itemPath) //throw FileError { - shellExecute("xdg-open \"" + itemPath + '"', ExecutionType::ASYNC); // + shellExecute("xdg-open \"" + itemPath + '"', ExecutionType::ASYNC, false/*hideConsole*/); // } } diff --git a/zen/shutdown.cpp b/zen/shutdown.cpp index aecd4121..4fc687d6 100644 --- a/zen/shutdown.cpp +++ b/zen/shutdown.cpp @@ -18,7 +18,7 @@ void zen::shutdownSystem() //throw FileError //https://linux.die.net/man/2/reboot => needs admin rights! //"systemctl" should work without admin rights: - shellExecute("systemctl poweroff", ExecutionType::SYNC); //throw FileError + shellExecute("systemctl poweroff", ExecutionType::SYNC, false/*hideConsole*/); //throw FileError } @@ -26,7 +26,7 @@ void zen::shutdownSystem() //throw FileError void zen::suspendSystem() //throw FileError { //"systemctl" should work without admin rights: - shellExecute("systemctl suspend", ExecutionType::SYNC); //throw FileError + shellExecute("systemctl suspend", ExecutionType::SYNC, false/*hideConsole*/); //throw FileError } diff --git a/zen/shutdown.h b/zen/shutdown.h index 2d66d1e8..20354a14 100644 --- a/zen/shutdown.h +++ b/zen/shutdown.h @@ -14,7 +14,7 @@ namespace zen { void shutdownSystem(); //throw FileError void suspendSystem(); // -void terminateProcess(int exitCode); //will NOT return! +[[noreturn]] void terminateProcess(int exitCode); } #endif //SHUTDOWN_H_3423847870238407783265 diff --git a/zen/socket.h b/zen/socket.h index c77a4084..0b4c823d 100644 --- a/zen/socket.h +++ b/zen/socket.h @@ -46,7 +46,7 @@ public: if (!servinfo) throw SysError(L"getaddrinfo: empty server info"); - auto getConnectedSocket = [&](const auto& /*::addrinfo*/ ai) + const auto getConnectedSocket = [](const auto& /*::addrinfo*/ ai) { SocketType testSocket = ::socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol); if (testSocket == invalidSocket) @@ -180,7 +180,7 @@ size_t getUtf8Len(Char8 ch) //ch must be first code unit! returns 0 on error! return 3; if (ch >> 3 == 0x1e) return 4; - return 0; //innvalid begin of UTF8 encoding + return 0; //invalid begin of UTF8 encoding } diff --git a/zen/zlib_wrap.cpp b/zen/zlib_wrap.cpp index 9eb4302f..ff5799c3 100644 --- a/zen/zlib_wrap.cpp +++ b/zen/zlib_wrap.cpp @@ -77,9 +77,8 @@ public: ~Impl() { - const int rv = ::deflateEnd(&gzipStream_); + [[maybe_unused]] const int rv = ::deflateEnd(&gzipStream_); assert(rv == Z_OK); - (void)rv; } size_t read(void* buffer, size_t bytesToRead) //throw ZlibInternalError, X; return "bytesToRead" bytes unless end of stream! diff --git a/zen/zstring.cpp b/zen/zstring.cpp index 62a0caef..3b33a21b 100644 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -38,9 +38,8 @@ Zstring makeUpperCopy(const Zstring& str) return output; } - catch (const SysError& e) + catch (SysError&) { - (void)e; assert(false); return str; } @@ -64,9 +63,8 @@ Zstring getUnicodeNormalForm(const Zstring& str) return outStr; } - catch (const SysError& e) + catch (SysError&) { - (void)e; assert(false); return str; } @@ -102,7 +100,7 @@ Zstring replaceCpyAsciiNoCase(const Zstring& str, const Zstring& oldTerm, const /* -MSDN "Handling Sorting in Your Applications": https://msdn.microsoft.com/en-us/library/windows/desktop/dd318144 +https://docs.microsoft.com/de-de/windows/desktop/Intl/handling-sorting-in-your-applications Perf test: compare strings 10 mio times; 64 bit build ----------------------------------------------------- @@ -160,7 +158,6 @@ int compareNoCaseUtf8(const char* lhs, size_t lhsLen, const char* rhs, size_t rh //unsigned underflow is well-defined! } } - } diff --git a/zen/zstring.h b/zen/zstring.h index 42487670..d5a8c29b 100644 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -66,7 +66,7 @@ struct LessNativePath { bool operator()(const Zstring& lhs, const Zstring& rhs) //------------------------------------------------------------------------------------------ int compareNatural(const Zstring& lhs, const Zstring& rhs); -struct LessNaturalSort { bool operator()(const Zstring& lhs, const Zstring rhs) const { return compareNatural(lhs, rhs) < 0; } }; +struct LessNaturalSort { bool operator()(const Zstring& lhs, const Zstring& rhs) const { return compareNatural(lhs, rhs) < 0; } }; //------------------------------------------------------------------------------------------ @@ -148,4 +148,8 @@ const wchar_t MULT_SIGN = L'\u00D7'; //fancy "x" //ZEN macro consistency checks: +#if defined ZEN_WIN_PRE_VISTA || defined ZEN_WIN_VISTA_AND_LATER + #error these macros are obsolete! +#endif + #endif //ZSTRING_H_73425873425789 diff --git a/zenXml/zenxml/dom.h b/zenXml/zenxml/dom.h index d95f5aa1..0f456822 100644 --- a/zenXml/zenxml/dom.h +++ b/zenXml/zenxml/dom.h @@ -153,7 +153,7 @@ public: using reference = T&; PtrIter(IterTy it) : it_(it) {} - PtrIter(const PtrIter& other) : it_(other.it_) {} + //PtrIter(const PtrIter& other) : it_(other.it_) {} PtrIter& operator++() { ++it_; return *this; } PtrIter operator++(int) { PtrIter tmp(*this); operator++(); return tmp; } inline friend bool operator==(const PtrIter& lhs, const PtrIter& rhs) { return lhs.it_ == rhs.it_; } |