summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@debian.org>2018-03-01 22:42:01 +0000
committerThomas Preud'homme <robotux@debian.org>2018-03-01 22:42:01 +0000
commit3958fa914c8a524ed4b6a5b035b794e12708fa1d (patch)
tree417868397f3c2c7386773f55096a9aa5f8856990
Import ultracopier_1.4.0.4.orig.tar.xz
[dgit import orig ultracopier_1.4.0.4.orig.tar.xz]
-rw-r--r--COPYING674
-rw-r--r--CliParser.cpp197
-rw-r--r--CliParser.h55
-rw-r--r--CompilerInfo.h15
-rw-r--r--CopyEngineManager.cpp385
-rw-r--r--CopyEngineManager.h105
-rw-r--r--CopyListener.cpp480
-rw-r--r--CopyListener.h123
-rw-r--r--Core.cpp1161
-rw-r--r--Core.h197
-rw-r--r--DebugEngine.cpp395
-rw-r--r--DebugEngine.h131
-rw-r--r--DebugEngineMacro.h28
-rw-r--r--DebugModel.cpp158
-rw-r--r--Environment.h21
-rw-r--r--EventDispatcher.cpp699
-rw-r--r--EventDispatcher.h97
-rw-r--r--ExtraSocket.cpp60
-rw-r--r--ExtraSocket.h30
-rw-r--r--FacilityEngine.cpp251
-rw-r--r--FacilityEngine.h76
-rw-r--r--HelpDialog.cpp145
-rw-r--r--HelpDialog.h48
-rw-r--r--HelpDialog.ui191
-rw-r--r--InternetUpdater.cpp110
-rw-r--r--InternetUpdater.h33
-rw-r--r--LanguagesManager.cpp287
-rw-r--r--LanguagesManager.h78
-rw-r--r--LocalListener.cpp348
-rw-r--r--LocalListener.h65
-rw-r--r--LocalPluginOptions.cpp59
-rw-r--r--LocalPluginOptions.h42
-rw-r--r--LogThread.cpp296
-rw-r--r--LogThread.h98
-rw-r--r--OSSpecific.cpp58
-rw-r--r--OSSpecific.h29
-rw-r--r--OSSpecific.ui108
-rw-r--r--OptionDialog.cpp1015
-rw-r--r--OptionDialog.h122
-rw-r--r--OptionDialog.ui988
-rw-r--r--OptionEngine.cpp242
-rw-r--r--OptionEngine.h87
-rw-r--r--PlatformMacro.h59
-rw-r--r--PluginInformation.cpp120
-rw-r--r--PluginInformation.h42
-rw-r--r--PluginInformation.ui136
-rw-r--r--PluginLoader.cpp339
-rw-r--r--PluginLoader.h82
-rw-r--r--PluginsManager.cpp932
-rw-r--r--PluginsManager.h157
-rw-r--r--README46
-rw-r--r--README.sources32
-rw-r--r--ResourcesManager.cpp216
-rw-r--r--ResourcesManager.h54
-rw-r--r--SessionLoader.cpp171
-rw-r--r--SessionLoader.h61
-rw-r--r--StructEnumDefinition.h153
-rw-r--r--StructEnumDefinition_UltracopierSpecific.h55
-rw-r--r--SystrayIcon.cpp559
-rw-r--r--SystrayIcon.h144
-rw-r--r--ThemesManager.cpp291
-rw-r--r--ThemesManager.h87
-rw-r--r--Variable.h50
-rw-r--r--cpp11addition.cpp531
-rw-r--r--cpp11addition.h203
-rw-r--r--cpp11additionstringtointcpp.cpp485
-rw-r--r--interface/FacilityInterface.h44
-rw-r--r--interface/OptionInterface.h36
-rw-r--r--interface/PluginInterface_CopyEngine.h208
-rw-r--r--interface/PluginInterface_Listener.h56
-rw-r--r--interface/PluginInterface_PluginLoader.h39
-rw-r--r--interface/PluginInterface_SessionLoader.h39
-rw-r--r--interface/PluginInterface_Themes.h115
-rw-r--r--lib/qt-tar-xz/QTarDecode.cpp174
-rw-r--r--lib/qt-tar-xz/QTarDecode.h36
-rw-r--r--lib/qt-tar-xz/QXzDecode.cpp146
-rw-r--r--lib/qt-tar-xz/QXzDecode.h40
-rw-r--r--lib/qt-tar-xz/QXzDecodeThread.cpp48
-rw-r--r--lib/qt-tar-xz/QXzDecodeThread.h37
-rw-r--r--lib/qt-tar-xz/xz.h273
-rw-r--r--lib/qt-tar-xz/xz_config.h123
-rw-r--r--lib/qt-tar-xz/xz_crc32.c52
-rw-r--r--lib/qt-tar-xz/xz_dec_bcj.c564
-rw-r--r--lib/qt-tar-xz/xz_dec_lzma2.c1175
-rw-r--r--lib/qt-tar-xz/xz_dec_stream.c822
-rw-r--r--lib/qt-tar-xz/xz_lzma2.h204
-rw-r--r--lib/qt-tar-xz/xz_private.h159
-rw-r--r--lib/qt-tar-xz/xz_stream.h57
-rw-r--r--main.cpp149
-rw-r--r--other-pro/static.pro33
-rw-r--r--other-pro/supercopier-core.pro3
-rw-r--r--other-pro/ultracopier-core.pro131
-rw-r--r--other-pro/ultracopier-static.pro6
-rw-r--r--plugins-alternative/Listener/dbus/Catchcopy.cpp17
-rw-r--r--plugins-alternative/Listener/dbus/Catchcopy.h20
-rw-r--r--plugins-alternative/Listener/dbus/DebugEngineMacro.h28
-rw-r--r--plugins-alternative/Listener/dbus/Environment.h10
-rw-r--r--plugins-alternative/Listener/dbus/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/Listener/dbus/Variable.h15
-rw-r--r--plugins-alternative/Listener/dbus/documentation.dox36
-rw-r--r--plugins-alternative/Listener/dbus/informations.xml26
-rw-r--r--plugins-alternative/Listener/dbus/listener.cpp85
-rw-r--r--plugins-alternative/Listener/dbus/listener.h49
-rw-r--r--plugins-alternative/Listener/dbus/listener.pro19
-rw-r--r--plugins-alternative/Listener/dbus/plugin.json1
-rw-r--r--plugins-alternative/PluginLoader/keybinding/DebugEngineMacro.h28
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Environment.h10
-rw-r--r--plugins-alternative/PluginLoader/keybinding/KeyBind.cpp11
-rw-r--r--plugins-alternative/PluginLoader/keybinding/KeyBind.h18
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/ar/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/de/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/el/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/en/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/es/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/fr/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/hi/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/hu/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/id/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/it/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/ja/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/ko/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/nl/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/no/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/pl/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/pt/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/ru/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/th/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/tr/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Languages/zh/translation.ts4
-rw-r--r--plugins-alternative/PluginLoader/keybinding/OptionsWidget.cpp55
-rw-r--r--plugins-alternative/PluginLoader/keybinding/OptionsWidget.h31
-rw-r--r--plugins-alternative/PluginLoader/keybinding/OptionsWidget.ui31
-rw-r--r--plugins-alternative/PluginLoader/keybinding/PlatformMacro.h1
-rw-r--r--plugins-alternative/PluginLoader/keybinding/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/PluginLoader/keybinding/Variable.h16
-rw-r--r--plugins-alternative/PluginLoader/keybinding/documentation.dox33
-rw-r--r--plugins-alternative/PluginLoader/keybinding/informations.xml27
-rw-r--r--plugins-alternative/PluginLoader/keybinding/plugin.json1
-rw-r--r--plugins-alternative/PluginLoader/keybinding/pluginLoader.cpp61
-rw-r--r--plugins-alternative/PluginLoader/keybinding/pluginLoader.h47
-rw-r--r--plugins-alternative/PluginLoader/keybinding/pluginLoader.pro50
-rw-r--r--plugins-alternative/SessionLoader/KDE4/DebugEngineMacro.h28
-rw-r--r--plugins-alternative/SessionLoader/KDE4/Environment.h10
-rw-r--r--plugins-alternative/SessionLoader/KDE4/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/SessionLoader/KDE4/Variable.h15
-rw-r--r--plugins-alternative/SessionLoader/KDE4/documentation.dox32
-rw-r--r--plugins-alternative/SessionLoader/KDE4/informations.xml26
-rw-r--r--plugins-alternative/SessionLoader/KDE4/plugin.json1
-rw-r--r--plugins-alternative/SessionLoader/KDE4/sessionLoader.cpp58
-rw-r--r--plugins-alternative/SessionLoader/KDE4/sessionLoader.h33
-rw-r--r--plugins-alternative/SessionLoader/KDE4/sessionLoader.pro15
-rw-r--r--plugins-alternative/Themes/Clean/Languages/ar/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/de/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/el/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/en/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/es/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/fr/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/hi/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/hu/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/id/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/it/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/ja/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/ko/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/nl/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/no/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/pl/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/ru/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/th/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/tr/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/Languages/zh/translation.ts55
-rw-r--r--plugins-alternative/Themes/Clean/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/Themes/Clean/documentation.dox28
-rw-r--r--plugins-alternative/Themes/Clean/factory.cpp65
-rw-r--r--plugins-alternative/Themes/Clean/factory.h39
-rw-r--r--plugins-alternative/Themes/Clean/informations.xml26
-rw-r--r--plugins-alternative/Themes/Clean/interface.cpp426
-rw-r--r--plugins-alternative/Themes/Clean/interface.h141
-rw-r--r--plugins-alternative/Themes/Clean/interface.pro46
-rw-r--r--plugins-alternative/Themes/Clean/interface.ui131
-rw-r--r--plugins-alternative/Themes/Clean/plugin.json1
-rw-r--r--plugins-alternative/Themes/Clean/resources.qrc5
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/informations.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Caught_Unix.pngbin0 -> 1093 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Caught_Windows.pngbin0 -> 623 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Semiuncaught_Unix.pngbin0 -> 1296 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Semiuncaught_Windows.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Uncaught_Unix.pngbin0 -> 754 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources/SystemTrayIcon/systray_Uncaught_Windows.pngbin0 -> 485 bytes
-rw-r--r--plugins-alternative/Themes/Clean/resources_unix.qrc7
-rw-r--r--plugins-alternative/Themes/Clean/resources_windows.qrc7
-rw-r--r--plugins-alternative/Themes/Teracopy/DebugEngineMacro.h28
-rw-r--r--plugins-alternative/Themes/Teracopy/Environment.h10
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/ar/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/de/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/el/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/en/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/es/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/fr/translation.ts94
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/hi/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/hu/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/id/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/it/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/ja/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/ko/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/nl/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/no/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/pl/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/ru/translation.ts93
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/th/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/tr/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/Languages/zh/translation.ts89
-rw-r--r--plugins-alternative/Themes/Teracopy/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/Themes/Teracopy/TransferModel.cpp528
-rw-r--r--plugins-alternative/Themes/Teracopy/TransferModel.h92
-rw-r--r--plugins-alternative/Themes/Teracopy/Variable.h15
-rw-r--r--plugins-alternative/Themes/Teracopy/documentation.dox28
-rw-r--r--plugins-alternative/Themes/Teracopy/factory.cpp70
-rw-r--r--plugins-alternative/Themes/Teracopy/factory.h42
-rw-r--r--plugins-alternative/Themes/Teracopy/informations.xml26
-rw-r--r--plugins-alternative/Themes/Teracopy/interface.cpp500
-rw-r--r--plugins-alternative/Themes/Teracopy/interface.h176
-rw-r--r--plugins-alternative/Themes/Teracopy/interface.pro50
-rw-r--r--plugins-alternative/Themes/Teracopy/interface.ui394
-rw-r--r--plugins-alternative/Themes/Teracopy/plugin.json1
-rw-r--r--plugins-alternative/Themes/Teracopy/resources.qrc12
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/add.pngbin0 -> 552 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/exit.pngbin0 -> 874 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/informations.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/options.pngbin0 -> 624 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Caught_Unix.pngbin0 -> 1093 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Caught_Windows.pngbin0 -> 623 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Semiuncaught_Unix.pngbin0 -> 1296 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Semiuncaught_Windows.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Uncaught_Unix.pngbin0 -> 754 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/SystemTrayIcon/systray_Uncaught_Windows.pngbin0 -> 485 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/checkbox.pngbin0 -> 619 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/main.pngbin0 -> 623 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/player_pause.pngbin0 -> 640 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources/player_play.pngbin0 -> 673 bytes
-rw-r--r--plugins-alternative/Themes/Teracopy/resources_unix.qrc7
-rw-r--r--plugins-alternative/Themes/Teracopy/resources_windows.qrc7
-rw-r--r--plugins-alternative/Themes/Windows/DebugEngineMacro.h28
-rw-r--r--plugins-alternative/Themes/Windows/Environment.h10
-rw-r--r--plugins-alternative/Themes/Windows/Languages/ar/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/de/translation.ts124
-rw-r--r--plugins-alternative/Themes/Windows/Languages/el/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/en/translation.ts124
-rw-r--r--plugins-alternative/Themes/Windows/Languages/es/translation.ts124
-rw-r--r--plugins-alternative/Themes/Windows/Languages/fr/translation.ts124
-rw-r--r--plugins-alternative/Themes/Windows/Languages/hi/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/hu/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/id/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/it/translation.ts125
-rw-r--r--plugins-alternative/Themes/Windows/Languages/ja/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/ko/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/nl/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/no/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/pl/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/ru/translation.ts127
-rw-r--r--plugins-alternative/Themes/Windows/Languages/th/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/tr/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/Languages/zh/translation.ts121
-rw-r--r--plugins-alternative/Themes/Windows/StructEnumDefinition.h1
-rw-r--r--plugins-alternative/Themes/Windows/TransferModel.cpp286
-rw-r--r--plugins-alternative/Themes/Windows/TransferModel.h90
-rw-r--r--plugins-alternative/Themes/Windows/Variable.h15
-rw-r--r--plugins-alternative/Themes/Windows/documentation.dox28
-rw-r--r--plugins-alternative/Themes/Windows/factory.cpp74
-rw-r--r--plugins-alternative/Themes/Windows/factory.h45
-rw-r--r--plugins-alternative/Themes/Windows/informations.xml26
-rw-r--r--plugins-alternative/Themes/Windows/interface.cpp414
-rw-r--r--plugins-alternative/Themes/Windows/interface.h165
-rw-r--r--plugins-alternative/Themes/Windows/interface.pro48
-rw-r--r--plugins-alternative/Themes/Windows/interface.ui415
-rw-r--r--plugins-alternative/Themes/Windows/plugin.json1
-rw-r--r--plugins-alternative/Themes/Windows/resources.qrc10
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/informations.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Caught_Unix.pngbin0 -> 1093 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Caught_Windows.pngbin0 -> 623 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Semiuncaught_Unix.pngbin0 -> 1296 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Semiuncaught_Windows.pngbin0 -> 841 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Uncaught_Unix.pngbin0 -> 754 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/SystemTrayIcon/systray_Uncaught_Windows.pngbin0 -> 485 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/arrow-down.pngbin0 -> 598 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/arrow-up.pngbin0 -> 602 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/empty.pngbin0 -> 95 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/icon-top.pngbin0 -> 2437 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/icon-top.xcfbin0 -> 4398 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources/icon.pngbin0 -> 379 bytes
-rw-r--r--plugins-alternative/Themes/Windows/resources_unix.qrc7
-rw-r--r--plugins-alternative/Themes/Windows/resources_windows.qrc7
-rw-r--r--plugins/CopyEngine/Rsync/Rsync.pro2
-rw-r--r--plugins/CopyEngine/Rsync/informations.xml23
-rw-r--r--plugins/CopyEngine/Ultracopier/AvancedQFile.cpp208
-rw-r--r--plugins/CopyEngine/Ultracopier/AvancedQFile.h45
-rw-r--r--plugins/CopyEngine/Ultracopier/CompilerInfo.h1
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngine-collision-and-error.cpp568
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngine.cpp1253
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngine.h382
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngine.pro106
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngineFactory.cpp700
-rw-r--r--plugins/CopyEngine/Ultracopier/CopyEngineFactory.h133
-rw-r--r--plugins/CopyEngine/Ultracopier/DebugDialog.cpp54
-rw-r--r--plugins/CopyEngine/Ultracopier/DebugDialog.h39
-rw-r--r--plugins/CopyEngine/Ultracopier/DebugEngineMacro.h28
-rw-r--r--plugins/CopyEngine/Ultracopier/DiskSpace.cpp53
-rw-r--r--plugins/CopyEngine/Ultracopier/DiskSpace.h29
-rw-r--r--plugins/CopyEngine/Ultracopier/DiskSpace.ui68
-rw-r--r--plugins/CopyEngine/Ultracopier/DriveManagement.cpp105
-rw-r--r--plugins/CopyEngine/Ultracopier/DriveManagement.h34
-rw-r--r--plugins/CopyEngine/Ultracopier/Environment.h11
-rw-r--r--plugins/CopyEngine/Ultracopier/FileErrorDialog.cpp163
-rw-r--r--plugins/CopyEngine/Ultracopier/FileErrorDialog.h51
-rw-r--r--plugins/CopyEngine/Ultracopier/FileExistsDialog.cpp244
-rw-r--r--plugins/CopyEngine/Ultracopier/FileExistsDialog.h60
-rw-r--r--plugins/CopyEngine/Ultracopier/FileIsSameDialog.cpp194
-rw-r--r--plugins/CopyEngine/Ultracopier/FileIsSameDialog.h57
-rw-r--r--plugins/CopyEngine/Ultracopier/FilterRules.cpp193
-rw-r--r--plugins/CopyEngine/Ultracopier/FilterRules.h46
-rw-r--r--plugins/CopyEngine/Ultracopier/FilterRules.ui162
-rw-r--r--plugins/CopyEngine/Ultracopier/Filters.cpp460
-rw-r--r--plugins/CopyEngine/Ultracopier/Filters.h45
-rw-r--r--plugins/CopyEngine/Ultracopier/Filters.ui194
-rw-r--r--plugins/CopyEngine/Ultracopier/FolderExistsDialog.cpp205
-rw-r--r--plugins/CopyEngine/Ultracopier/FolderExistsDialog.h57
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/ar/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/de/translation.ts1290
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/el/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/en/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/es/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/fr/translation.ts1294
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/hi/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/hu/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/id/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/it/translation.ts1299
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/ja/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/ko/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/nl/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/no/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/pl/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/pt/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/ru/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/th/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/tr/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/Languages/zh/translation.ts1289
-rw-r--r--plugins/CopyEngine/Ultracopier/ListThread.cpp2399
-rw-r--r--plugins/CopyEngine/Ultracopier/ListThread.h432
-rw-r--r--plugins/CopyEngine/Ultracopier/ListThread_InodeAction.cpp64
-rw-r--r--plugins/CopyEngine/Ultracopier/MkPath.cpp517
-rw-r--r--plugins/CopyEngine/Ultracopier/MkPath.h106
-rw-r--r--plugins/CopyEngine/Ultracopier/ReadThread.cpp687
-rw-r--r--plugins/CopyEngine/Ultracopier/ReadThread.h147
-rw-r--r--plugins/CopyEngine/Ultracopier/RenamingRules.cpp85
-rw-r--r--plugins/CopyEngine/Ultracopier/RenamingRules.h34
-rw-r--r--plugins/CopyEngine/Ultracopier/RenamingRules.ui129
-rw-r--r--plugins/CopyEngine/Ultracopier/ScanFileOrFolder.cpp688
-rw-r--r--plugins/CopyEngine/Ultracopier/ScanFileOrFolder.h108
-rw-r--r--plugins/CopyEngine/Ultracopier/StructEnumDefinition.h1
-rw-r--r--plugins/CopyEngine/Ultracopier/StructEnumDefinition_CopyEngine.h124
-rw-r--r--plugins/CopyEngine/Ultracopier/TransferThread.cpp2091
-rw-r--r--plugins/CopyEngine/Ultracopier/TransferThread.h288
-rw-r--r--plugins/CopyEngine/Ultracopier/Variable.h43
-rw-r--r--plugins/CopyEngine/Ultracopier/WriteThread.cpp968
-rw-r--r--plugins/CopyEngine/Ultracopier/WriteThread.h160
-rw-r--r--plugins/CopyEngine/Ultracopier/copyEngineOptions.ui762
-rw-r--r--plugins/CopyEngine/Ultracopier/copyEngineResources.qrc8
-rw-r--r--plugins/CopyEngine/Ultracopier/debugDialog.ui98
-rw-r--r--plugins/CopyEngine/Ultracopier/documentation.dox39
-rw-r--r--plugins/CopyEngine/Ultracopier/fileErrorDialog.ui264
-rw-r--r--plugins/CopyEngine/Ultracopier/fileExistsDialog.ui412
-rw-r--r--plugins/CopyEngine/Ultracopier/fileIsSameDialog.ui214
-rw-r--r--plugins/CopyEngine/Ultracopier/folderExistsDialog.ui309
-rw-r--r--plugins/CopyEngine/Ultracopier/informations-rsync.xml26
-rw-r--r--plugins/CopyEngine/Ultracopier/informations.xml26
-rw-r--r--plugins/CopyEngine/Ultracopier/plugin.json1
-rw-r--r--plugins/CopyEngine/Ultracopier/resources/add.pngbin0 -> 552 bytes
-rw-r--r--plugins/CopyEngine/Ultracopier/resources/edit.pngbin0 -> 623 bytes
-rw-r--r--plugins/CopyEngine/Ultracopier/resources/filter.pngbin0 -> 685 bytes
-rw-r--r--plugins/CopyEngine/Ultracopier/resources/remove.pngbin0 -> 683 bytes
-rw-r--r--plugins/Languages/ar/flag.pngbin0 -> 585 bytes
-rw-r--r--plugins/Languages/ar/informations.xml32
-rw-r--r--plugins/Languages/ar/translation.ts1256
-rw-r--r--plugins/Languages/de/flag.pngbin0 -> 712 bytes
-rw-r--r--plugins/Languages/de/informations.xml32
-rw-r--r--plugins/Languages/de/translation.ts1277
-rw-r--r--plugins/Languages/el/flag.pngbin0 -> 726 bytes
-rw-r--r--plugins/Languages/el/informations.xml32
-rw-r--r--plugins/Languages/el/translation.ts1256
-rw-r--r--plugins/Languages/es/flag.pngbin0 -> 726 bytes
-rw-r--r--plugins/Languages/es/informations.xml32
-rw-r--r--plugins/Languages/es/translation.ts1266
-rw-r--r--plugins/Languages/fr/flag.pngbin0 -> 699 bytes
-rw-r--r--plugins/Languages/fr/informations.xml35
-rw-r--r--plugins/Languages/fr/translation.ts1265
-rw-r--r--plugins/Languages/hi/flag.pngbin0 -> 728 bytes
-rw-r--r--plugins/Languages/hi/informations.xml32
-rw-r--r--plugins/Languages/hi/translation.ts1256
-rw-r--r--plugins/Languages/hu/flag.pngbin0 -> 810 bytes
-rw-r--r--plugins/Languages/hu/informations.xml29
-rw-r--r--plugins/Languages/hu/translation.ts1263
-rw-r--r--plugins/Languages/id/flag.pngbin0 -> 691 bytes
-rw-r--r--plugins/Languages/id/informations.xml32
-rw-r--r--plugins/Languages/id/translation.ts1256
-rw-r--r--plugins/Languages/it/flag.pngbin0 -> 675 bytes
-rw-r--r--plugins/Languages/it/informations.xml32
-rw-r--r--plugins/Languages/it/translation.ts1270
-rw-r--r--plugins/Languages/ja/flag.pngbin0 -> 595 bytes
-rw-r--r--plugins/Languages/ja/informations.xml33
-rw-r--r--plugins/Languages/ja/translation.ts1256
-rw-r--r--plugins/Languages/ko/flag.pngbin0 -> 650 bytes
-rw-r--r--plugins/Languages/ko/informations.xml30
-rw-r--r--plugins/Languages/ko/translation.ts1260
-rw-r--r--plugins/Languages/nl/flag.pngbin0 -> 709 bytes
-rw-r--r--plugins/Languages/nl/informations.xml32
-rw-r--r--plugins/Languages/nl/translation.ts1256
-rw-r--r--plugins/Languages/no/flag.pngbin0 -> 715 bytes
-rw-r--r--plugins/Languages/no/informations.xml32
-rw-r--r--plugins/Languages/no/translation.ts1256
-rw-r--r--plugins/Languages/pl/flag.pngbin0 -> 586 bytes
-rw-r--r--plugins/Languages/pl/informations.xml32
-rw-r--r--plugins/Languages/pl/translation.ts1256
-rw-r--r--plugins/Languages/pt/flag.pngbin0 -> 686 bytes
-rw-r--r--plugins/Languages/pt/informations.xml32
-rw-r--r--plugins/Languages/pt/translation.ts1256
-rw-r--r--plugins/Languages/ru/flag.pngbin0 -> 721 bytes
-rw-r--r--plugins/Languages/ru/informations.xml32
-rw-r--r--plugins/Languages/ru/translation.ts1260
-rw-r--r--plugins/Languages/th/flag.pngbin0 -> 731 bytes
-rw-r--r--plugins/Languages/th/informations.xml32
-rw-r--r--plugins/Languages/th/translation.ts1256
-rw-r--r--plugins/Languages/tr/flag.pngbin0 -> 634 bytes
-rw-r--r--plugins/Languages/tr/informations.xml32
-rw-r--r--plugins/Languages/tr/translation.ts1256
-rw-r--r--plugins/Languages/zh/flag.pngbin0 -> 538 bytes
-rw-r--r--plugins/Languages/zh/informations.xml35
-rw-r--r--plugins/Languages/zh/translation.ts1256
-rw-r--r--plugins/Languages/zh_TW/flag.pngbin0 -> 616 bytes
-rw-r--r--plugins/Languages/zh_TW/informations.xml32
-rw-r--r--plugins/Languages/zh_TW/translation.ts1256
-rw-r--r--plugins/Listener/catchcopy-v0002/DebugEngineMacro.h28
-rw-r--r--plugins/Listener/catchcopy-v0002/Environment.h10
-rw-r--r--plugins/Listener/catchcopy-v0002/StructEnumDefinition.h1
-rw-r--r--plugins/Listener/catchcopy-v0002/Variable.h15
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.cpp379
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ClientCatchcopy.h113
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.cpp38
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ExtraSocketCatchcopy.h31
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.cpp740
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/ServerCatchcopy.h144
-rw-r--r--plugins/Listener/catchcopy-v0002/catchcopy-api-0002/VariablesCatchcopy.h13
-rw-r--r--plugins/Listener/catchcopy-v0002/documentation.dox32
-rw-r--r--plugins/Listener/catchcopy-v0002/informations.xml26
-rw-r--r--plugins/Listener/catchcopy-v0002/listener.cpp123
-rw-r--r--plugins/Listener/catchcopy-v0002/listener.h59
-rw-r--r--plugins/Listener/catchcopy-v0002/listener.pro26
-rw-r--r--plugins/Listener/catchcopy-v0002/plugin.json1
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/DebugEngineMacro.h28
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Environment.h10
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/ar/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/de/translation.ts18
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/el/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/en/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/es/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/fr/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/hi/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/hu/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/id/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/it/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/ja/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/ko/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/nl/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/no/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/pl/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/pt/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/ru/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/th/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/tr/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Languages/zh/translation.ts17
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/OptionsWidget.cpp39
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/OptionsWidget.h30
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/OptionsWidget.ui48
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/PlatformMacro.h1
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/StructEnumDefinition.h1
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/Variable.h16
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/documentation.dox33
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/informations.xml26
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/plugin.json1
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/pluginLoader.cpp450
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/pluginLoader.h64
-rw-r--r--plugins/PluginLoader/catchcopy-v0002/pluginLoader.pro53
-rw-r--r--plugins/SessionLoader/Windows/DebugEngineMacro.h28
-rw-r--r--plugins/SessionLoader/Windows/Environment.h10
-rw-r--r--plugins/SessionLoader/Windows/StructEnumDefinition.h1
-rw-r--r--plugins/SessionLoader/Windows/Variable.h15
-rw-r--r--plugins/SessionLoader/Windows/documentation.dox32
-rw-r--r--plugins/SessionLoader/Windows/informations.xml26
-rw-r--r--plugins/SessionLoader/Windows/plugin.json1
-rw-r--r--plugins/SessionLoader/Windows/sessionLoader.cpp80
-rw-r--r--plugins/SessionLoader/Windows/sessionLoader.h33
-rw-r--r--plugins/SessionLoader/Windows/sessionLoader.pro16
-rw-r--r--plugins/Themes/Oxygen/DebugEngineMacro.h28
-rw-r--r--plugins/Themes/Oxygen/Environment.h10
-rw-r--r--plugins/Themes/Oxygen/Languages/ar/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/de/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/el/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/en/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/es/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/fr/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/hi/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/hu/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/id/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/it/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/ja/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/ko/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/nl/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/no/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/pl/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/pt/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/ru/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/th/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/tr/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/Languages/zh/translation.ts341
-rw-r--r--plugins/Themes/Oxygen/StructEnumDefinition.h1
-rw-r--r--plugins/Themes/Oxygen/ThemesFactory.cpp481
-rw-r--r--plugins/Themes/Oxygen/ThemesFactory.h86
-rw-r--r--plugins/Themes/Oxygen/TransferModel.cpp588
-rw-r--r--plugins/Themes/Oxygen/TransferModel.h96
-rw-r--r--plugins/Themes/Oxygen/Variable.h18
-rw-r--r--plugins/Themes/Oxygen/documentation.dox31
-rw-r--r--plugins/Themes/Oxygen/informations.xml26
-rw-r--r--plugins/Themes/Oxygen/interface.cpp1497
-rw-r--r--plugins/Themes/Oxygen/interface.h222
-rw-r--r--plugins/Themes/Oxygen/interface.pro8
-rw-r--r--plugins/Themes/Oxygen/interface.ui848
-rw-r--r--plugins/Themes/Oxygen/interfaceInclude.pri51
-rw-r--r--plugins/Themes/Oxygen/interfaceResources.qrc22
-rw-r--r--plugins/Themes/Oxygen/interfaceResources_unix.qrc7
-rw-r--r--plugins/Themes/Oxygen/interfaceResources_windows.qrc7
-rw-r--r--plugins/Themes/Oxygen/options.ui290
-rw-r--r--plugins/Themes/Oxygen/plugin.json1
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/add.pngbin0 -> 552 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/exit.pngbin0 -> 874 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/informations.pngbin0 -> 841 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/options.pngbin0 -> 624 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Caught_Unix.pngbin0 -> 1093 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Caught_Windows.pngbin0 -> 623 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Semiuncaught_Unix.pngbin0 -> 1174 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Semiuncaught_Windows.pngbin0 -> 677 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Uncaught_Unix.pngbin0 -> 665 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/SystemTrayIcon/systray_Uncaught_Windows.pngbin0 -> 439 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/add.pngbin0 -> 552 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/cancel.pngbin0 -> 874 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/export-transfer-list.pngbin0 -> 455 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/import-transfer-list.pngbin0 -> 454 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/main.pngbin0 -> 623 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/moveDown.pngbin0 -> 466 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/moveUp.pngbin0 -> 466 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/player_end.pngbin0 -> 696 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/player_pause.pngbin0 -> 640 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/player_play.pngbin0 -> 673 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/putOnBottom.pngbin0 -> 676 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/putOnTop.pngbin0 -> 681 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/remove.pngbin0 -> 683 bytes
-rw-r--r--plugins/Themes/Oxygen/resources/search.pngbin0 -> 781 bytes
-rw-r--r--plugins/Themes/Oxygen/themesOptions.ui426
-rw-r--r--plugins/Themes/Supercopier/informations.xml26
-rw-r--r--plugins/Themes/Supercopier/interface.pro10
-rw-r--r--plugins/Themes/Supercopier/interfaceResources.qrc24
-rw-r--r--plugins/Themes/Supercopier/interfaceResources_unix.qrc7
-rw-r--r--plugins/Themes/Supercopier/interfaceResources_windows.qrc7
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/add.pngbin0 -> 246 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/exit.pngbin0 -> 545 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/informations.pngbin0 -> 281 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/options.pngbin0 -> 275 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Caught_Unix.pngbin0 -> 147 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Caught_Windows.pngbin0 -> 148 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Semiuncaught_Unix.pngbin0 -> 147 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Semiuncaught_Windows.pngbin0 -> 148 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Uncaught_Unix.pngbin0 -> 141 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/SystemTrayIcon/systray_Uncaught_Windows.pngbin0 -> 139 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/add.pngbin0 -> 240 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/cancel.pngbin0 -> 284 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/export-transfer-list.pngbin0 -> 264 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/import-transfer-list.pngbin0 -> 316 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/main.pngbin0 -> 148 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/moveDown.pngbin0 -> 191 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/moveUp.pngbin0 -> 190 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/player_end.pngbin0 -> 226 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/player_pause.pngbin0 -> 207 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/player_play.pngbin0 -> 208 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/progressbarleft.pngbin0 -> 133 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/progressbarright.pngbin0 -> 132 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/putOnBottom.pngbin0 -> 206 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/putOnTop.pngbin0 -> 208 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/remove.pngbin0 -> 254 bytes
-rw-r--r--plugins/Themes/Supercopier/resources/search.pngbin0 -> 237 bytes
-rw-r--r--plugins/static-plugins-oxygen.qrc6
-rw-r--r--plugins/static-plugins-windows.qrc6
-rw-r--r--plugins/static-plugins.qrc12
-rw-r--r--resources/Languages/en/flag.pngbin0 -> 741 bytes
-rw-r--r--resources/Languages/en/informations.xml29
-rw-r--r--resources/Languages/en/translation.ts1256
-rw-r--r--resources/bug-128x128.pngbin0 -> 6042 bytes
-rw-r--r--resources/img-src/application-exit.svgzbin0 -> 6400 bytes
-rw-r--r--resources/img-src/applications-development.svgzbin0 -> 7861 bytes
-rw-r--r--resources/img-src/arrow-down-double.svgzbin0 -> 5704 bytes
-rw-r--r--resources/img-src/arrow-down.svgzbin0 -> 5072 bytes
-rw-r--r--resources/img-src/arrow-up-double.svgzbin0 -> 5698 bytes
-rw-r--r--resources/img-src/arrow-up.svgzbin0 -> 5071 bytes
-rw-r--r--resources/img-src/checkbox.svgzbin0 -> 3936 bytes
-rw-r--r--resources/img-src/document-encrypt.svgzbin0 -> 20939 bytes
-rw-r--r--resources/img-src/document-preview.svgzbin0 -> 19169 bytes
-rw-r--r--resources/img-src/document-save_16.svgzbin0 -> 4954 bytes
-rw-r--r--resources/img-src/document-save_22.svgzbin0 -> 30302 bytes
-rw-r--r--resources/img-src/drive-removable-media-usb.svgzbin0 -> 4247 bytes
-rw-r--r--resources/img-src/help-about.svgzbin0 -> 13549 bytes
-rw-r--r--resources/img-src/kbugbuster.svgzbin0 -> 20091 bytes
-rw-r--r--resources/img-src/list-add.svgzbin0 -> 4165 bytes
-rw-r--r--resources/img-src/media-playback-pause.svgzbin0 -> 2054 bytes
-rw-r--r--resources/img-src/media-playback-start.svgzbin0 -> 1916 bytes
-rw-r--r--resources/img-src/media-skip-forward.svgzbin0 -> 2065 bytes
-rw-r--r--resources/img-src/process-stop.svgzbin0 -> 4174 bytes
-rw-r--r--resources/img-src/system-shutdown.svgzbin0 -> 6070 bytes
-rw-r--r--resources/img-src/text-formatting.svg11924
-rw-r--r--resources/moveDown.pngbin0 -> 466 bytes
-rw-r--r--resources/moveUp.pngbin0 -> 466 bytes
-rw-r--r--resources/none-128x128.pngbin0 -> 4942 bytes
-rw-r--r--resources/options.pngbin0 -> 624 bytes
-rw-r--r--resources/qt.conf2
-rw-r--r--resources/resources-windows-qt-plugin.qrc5
-rw-r--r--resources/resources-windows.rc36
-rw-r--r--resources/supercopier-128x128.pngbin0 -> 5041 bytes
-rw-r--r--resources/supercopier-16x16.pngbin0 -> 148 bytes
-rw-r--r--resources/supercopier-all-in-one.icobin0 -> 786 bytes
-rw-r--r--resources/supercopier.icnsbin0 -> 32304 bytes
-rw-r--r--resources/supercopier.icobin0 -> 1078 bytes
-rw-r--r--resources/systray_Caught_Unix.pngbin0 -> 1093 bytes
-rw-r--r--resources/systray_Caught_Windows.pngbin0 -> 623 bytes
-rw-r--r--resources/systray_Semiuncaught_Unix.pngbin0 -> 1296 bytes
-rw-r--r--resources/systray_Semiuncaught_Windows.pngbin0 -> 841 bytes
-rw-r--r--resources/systray_Uncaught_Unix.pngbin0 -> 754 bytes
-rw-r--r--resources/systray_Uncaught_Windows.pngbin0 -> 485 bytes
-rw-r--r--resources/ultracopier-128x128.pngbin0 -> 4928 bytes
-rw-r--r--resources/ultracopier-16x16.pngbin0 -> 685 bytes
-rw-r--r--resources/ultracopier-all-in-one.icobin0 -> 2594 bytes
-rw-r--r--resources/ultracopier-resources.qrc15
-rw-r--r--resources/ultracopier-resources_unix.qrc7
-rw-r--r--resources/ultracopier-resources_windows.qrc7
-rw-r--r--resources/ultracopier.desktop20
-rw-r--r--resources/ultracopier.icnsbin0 -> 36804 bytes
-rw-r--r--resources/ultracopier.icobin0 -> 34118 bytes
-rw-r--r--resources/warning.pngbin0 -> 511 bytes
-rw-r--r--tools/doc/Doxyfile1790
-rw-r--r--tools/doc/Doxyfile-plugin-template1789
-rw-r--r--tools/doc/footer.html2
-rw-r--r--tools/doc/ultracopier-logo.pngbin0 -> 3834 bytes
-rw-r--r--tools/scripts/UltraCP28
-rw-r--r--tools/scripts/UltraMV28
-rwxr-xr-xtools/to-pack/1-pre-send.sh55
-rwxr-xr-xtools/to-pack/1-update-translation.sh37
-rwxr-xr-xtools/to-pack/2-compil-wine32.sh39
-rwxr-xr-xtools/to-pack/2-compil-wine64.sh38
-rwxr-xr-xtools/to-pack/2-send-sources.sh12
-rwxr-xr-xtools/to-pack/3-compil-mac.sh37
-rwxr-xr-xtools/to-pack/4-clean-all.sh35
-rwxr-xr-xtools/to-pack/4-upload.sh38
-rwxr-xr-xtools/to-pack/5-upload.sh35
-rwxr-xr-xtools/to-pack/6-sendmail.sh35
-rwxr-xr-xtools/to-pack/data/windows/install-static.nsi162
-rwxr-xr-xtools/to-pack/data/windows/install.nsi162
-rw-r--r--tools/to-pack/data/windows/resources-windows-ultracopier-plugins.rc27
-rwxr-xr-xtools/to-pack/data/windows/ultracopier.icobin0 -> 34118 bytes
-rwxr-xr-xtools/to-pack/grouped.sh12
-rwxr-xr-xtools/to-pack/old-3-compil-linux.sh37
-rwxr-xr-xtools/to-pack/sub-script/assemble-source-version.sh129
-rw-r--r--tools/to-pack/sub-script/assemble-windows-version-32.sh153
-rw-r--r--tools/to-pack/sub-script/assemble-windows-version-64.sh149
-rw-r--r--tools/to-pack/sub-script/assemble.sh219
-rwxr-xr-xtools/to-pack/sub-script/clean-all.sh16
-rw-r--r--tools/to-pack/sub-script/compil-windows32.sh211
-rw-r--r--tools/to-pack/sub-script/compil-windows64.sh200
-rw-r--r--tools/to-pack/sub-script/compil.sh429
-rw-r--r--tools/to-pack/sub-script/doc.sh119
-rw-r--r--tools/to-pack/sub-script/linux.sh275
-rw-r--r--tools/to-pack/sub-script/mac.sh275
-rw-r--r--tools/to-pack/sub-script/sendmail.sh17
-rw-r--r--tools/to-pack/sub-script/test.sh40
-rw-r--r--tools/to-pack/sub-script/translation-local.sh30
-rwxr-xr-xtools/to-pack/sub-script/translation.sh53
-rw-r--r--tools/to-pack/sub-script/upload-local.sh33
-rw-r--r--tools/to-pack/sub-script/upload.sh80
-rwxr-xr-xtools/to-pack/test.sh55
-rw-r--r--tools/unit-tester/copyEngine.cpp1386
-rw-r--r--tools/unit-tester/copyEngine.h263
-rw-r--r--tools/unit-tester/copyEngineUnitTester.cpp104
-rw-r--r--tools/unit-tester/copyEngineUnitTester.h46
-rw-r--r--tools/unit-tester/main.cpp8
-rw-r--r--tools/unit-tester/unit-tester.pro42
-rw-r--r--ultracopier.dox39
-rw-r--r--ultracopier.pro137
700 files changed, 136115 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..818433e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/CliParser.cpp b/CliParser.cpp
new file mode 100644
index 0000000..7d375ac
--- /dev/null
+++ b/CliParser.cpp
@@ -0,0 +1,197 @@
+/** \file CliParser.cpp
+\brief To group into one class, the CLI parsing
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "CliParser.h"
+#include "cpp11addition.h"
+#include "Core.h"
+
+#include <QDebug>
+
+CliParser::CliParser(QObject *parent) :
+ QObject(parent)
+{
+ //this->core=core;
+}
+
+/** \brief method to parse the ultracopier arguments
+ \param ultracopierArguments the argument list
+ \param external true if the arguments come from other instance of ultracopier
+*/
+void CliParser::cli(const std::vector<std::string> &ultracopierArguments,const bool &external,const bool &onlyCheck)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ultracopierArguments: "+stringimplode(ultracopierArguments,';'));
+ if(ultracopierArguments.size()==1)
+ {
+ if(external)
+ {
+ //if(!core->startNewTransferOneUniqueCopyEngine())
+ {
+ #ifdef Q_OS_WIN32
+ QString message(tr("Ultracopier is already running, right click on its system tray icon (near the clock) to use it or just copy and paste"));
+ #else
+ QString message(tr("Ultracopier is already running, view all notification area icons (near the clock), right click on its system tray icon to use it or just copy and paste"));
+ #endif
+
+ QMessageBox::warning(NULL,tr("Warning"),message);
+ showSystrayMessage(message.toStdString());
+ }
+ }
+ // else do nothing, is normal starting without arguements
+ return;
+ }
+ else if(ultracopierArguments.size()==2)
+ {
+ if(ultracopierArguments.back()=="quit")
+ {
+ if(onlyCheck)
+ return;
+ QCoreApplication::exit();
+ return;
+ }
+ else if(ultracopierArguments.back()=="--help")
+ {
+ showHelp(false);
+ return;
+ }
+ else if(ultracopierArguments.back()=="--options")
+ {
+ emit showOptions();
+ return;
+ }
+ else if(stringEndsWith(ultracopierArguments.back(),".urc"))
+ {
+ tryLoadPlugin(ultracopierArguments.back());
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Command line not understand");
+ showHelp();
+ return;
+ }
+ else if(ultracopierArguments.size()==3)
+ {
+ if(ultracopierArguments.at(1)=="Transfer-list")
+ {
+ if(onlyCheck)
+ return;
+ QFile transferFile(QString::fromStdString(ultracopierArguments.back()));
+ if(transferFile.open(QIODevice::ReadOnly))
+ {
+ QString content;
+ QByteArray data=transferFile.readLine(64);
+ if(data.size()<=0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Problem reading file, or file size is 0");
+ QMessageBox::warning(NULL,tr("Warning"),tr("Problem reading file, or file size is 0"));
+ transferFile.close();
+ return;
+ }
+ content=QString::fromUtf8(data);
+ std::vector<std::string> transferListArguments=stringsplit(content.toStdString(),';');
+ transferListArguments[3].erase(std::remove(transferListArguments[3].begin(), transferListArguments[3].end(),'\n'),transferListArguments[3].end());
+ if(transferListArguments.at(0)!="Ultracopier" ||
+ transferListArguments.at(1)!="Transfer-list" ||
+ (transferListArguments.at(2)!="Transfer" && transferListArguments.at(2)!="Copy" && transferListArguments.at(2)!="Move")
+ )
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"This file is not supported transfer list");
+ QMessageBox::warning(NULL,tr("Warning"),tr("This file is not supported transfer list"));
+ transferFile.close();
+ return;
+ }
+ transferFile.close();
+ emit newTransferList(transferListArguments.at(3),transferListArguments.at(2),ultracopierArguments.back());
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to open the transfer list file: "+transferFile.errorString().toStdString());
+ QMessageBox::warning(NULL,tr("Warning"),tr("Unable to open the transfer list file"));
+ return;
+ }
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Command line not understand");
+ showHelp();
+ return;
+ }
+ else if(ultracopierArguments.size()>3)
+ {
+ if(ultracopierArguments.at(1)=="Copy" || ultracopierArguments.at(1)=="cp")
+ {
+ if(onlyCheck)
+ return;
+ std::vector<std::string> transferList=ultracopierArguments;
+ transferList.erase(transferList.cbegin());
+ transferList.erase(transferList.cbegin());
+ if(transferList.back()=="?")
+ {
+ transferList.erase(transferList.cbegin());
+ emit newCopyWithoutDestination(transferList);
+ }
+ else
+ {
+ std::string destination=transferList.back();
+ transferList.erase(transferList.cbegin());
+ emit newCopy(transferList,destination);
+ }
+ return;
+ }
+ else if(ultracopierArguments.at(1)=="Move" || ultracopierArguments.at(1)=="mv")
+ {
+ if(onlyCheck)
+ return;
+ std::vector<std::string> transferList=ultracopierArguments;
+ transferList.erase(transferList.cbegin());
+ transferList.erase(transferList.cbegin());
+ if(transferList.back()=="?")
+ {
+ transferList.erase(transferList.cbegin());
+ emit newMoveWithoutDestination(transferList);
+ }
+ else
+ {
+ std::string destination=transferList.back();
+ transferList.erase(transferList.cbegin());
+ emit newMove(transferList,destination);
+ }
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Command line not understand");
+ showHelp();
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Command line not understand");
+ showHelp();
+}
+
+/** \brief show the help
+ *\param incorrectArguments if the help is call because the arguments are wrong */
+void CliParser::showHelp(const bool &incorrectArguments)
+{
+ if(incorrectArguments)
+ qDebug() << "Incorrect arguments detected";
+ qDebug() << tr("The arguments possible are:");
+ qDebug() << "--help : "+tr("To display this help");
+ qDebug() << "--options : "+tr("To display the options");
+ qDebug() << "quit : "+tr("To quit the other instances (if running)");
+ qDebug() << "Transfer-list [transfer list file] : "+tr("Open transfer list");
+ qDebug() << "cp [source [source2]] [destination] : "+tr("To copy sources to destination, separated by space. If destination is \"?\", ultracopier will ask the user");
+ qDebug() << "mv [source [source2]] [destination] : "+tr("To move sources to destination, separated by space. If destination is \"?\", ultracopier will ask the user");
+
+ QString message;
+ if(incorrectArguments)
+ message+="<b>"+tr("Command not valid")+"</b><br />\n";
+ message+=+"<b></b>"+tr("The arguments possible are:")+"\n<ul>";
+ message+="<li><b>--help</b> : "+tr("To display this help")+"</li>\n";
+ message+="<li><b>--options</b> : "+tr("To display the options")+"</li>\n";
+ message+="<li><b>quit</b> : "+tr("To quit the other instances (if running)")+"</li>\n";
+ message+="<li><b>Transfer-list [transfer list file]</b> : "+tr("Open transfer list")+"</li>\n";
+ message+="<li><b>cp [source [source2]] [destination]</b> : "+tr("To copy sources to destination, separated by space. If destination is \"?\", ultracopier will ask the user")+"</li>\n";
+ message+="<li><b>mv [source [source2]] [destination]</b> : "+tr("To move sources to destination, separated by space. If destination is \"?\", ultracopier will ask the user")+"</li>\n";
+ message+=+"</ul>";
+ if(incorrectArguments)
+ QMessageBox::warning(NULL,tr("Warning"),message);
+ else
+ QMessageBox::information(NULL,tr("Help"),message);
+}
diff --git a/CliParser.h b/CliParser.h
new file mode 100644
index 0000000..edcf115
--- /dev/null
+++ b/CliParser.h
@@ -0,0 +1,55 @@
+/** \file CliParser.h
+\brief To group into one class, the CLI parsing
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef CLIPARSER_H
+#define CLIPARSER_H
+
+#include <QObject>
+#include <QMessageBox>
+#include <QCoreApplication>
+#include <QFile>
+
+#include "Environment.h"
+
+class Core;
+/** \brief class to parse all command line options */
+class CliParser : public QObject
+{
+ Q_OBJECT
+public:
+ explicit CliParser(/*Core *core,*/QObject *parent = 0);
+public slots:
+ /** \brief method to parse the ultracopier arguments
+ \param ultracopierArguments the argument list
+ \param external true if the arguments come from other instance of ultracopier
+ */
+ void cli(const std::vector<std::string> &ultracopierArguments,const bool &external,const bool &onlyCheck);
+signals:
+ /** new copy without destination have been pased by the CLI */
+ void newCopyWithoutDestination(std::vector<std::string> sources) const;
+ /** new copy with destination have been pased by the CLI */
+ void newCopy(std::vector<std::string> sources,std::string destination) const;
+ /** new move without destination have been pased by the CLI */
+ void newMoveWithoutDestination(std::vector<std::string> sources) const;
+ /** new move with destination have been pased by the CLI */
+ void newMove(std::vector<std::string> sources,std::string destination) const;
+ /** new transfer list pased by the CLI */
+ void newTransferList(std::string engine,std::string mode,std::string file) const;
+
+ void tryLoadPlugin(const std::string &file) const;
+ /// \brief Show the help option
+ void showOptions() const;
+
+ /// \brief For show a message linked to the systray icon
+ void showSystrayMessage(const std::string& text);
+private:
+ /** \brief show the help
+ *\param incorrectArguments if the help is call because the arguments are wrong */
+ void showHelp(const bool &incorrectArguments=true);
+
+ //Core *core;
+};
+
+#endif // CLIPARSER_H
diff --git a/CompilerInfo.h b/CompilerInfo.h
new file mode 100644
index 0000000..78ba379
--- /dev/null
+++ b/CompilerInfo.h
@@ -0,0 +1,15 @@
+/** \file CompilerInfo.h
+\brief Define the compiler info
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+/// \def COMPILERINFO the string to identify the compiler
+#if defined(Q_CC_GNU)
+ #define COMPILERINFO std::string("GCC ")+std::to_string(__GNUC__)+"."+std::to_string(__GNUC_MINOR__)+"."+std::to_string(__GNUC_PATCHLEVEL__)+" build: "+__DATE__+" "+__TIME__
+#else
+ #if defined(__DATE__) && defined(__TIME__)
+ #define COMPILERINFO std::string("Unknown compiler: ")+__DATE__+" "+__TIME__
+ #else
+ #define COMPILERINFO std::string("Unknown compiler")
+ #endif
+#endif
diff --git a/CopyEngineManager.cpp b/CopyEngineManager.cpp
new file mode 100644
index 0000000..a3934b3
--- /dev/null
+++ b/CopyEngineManager.cpp
@@ -0,0 +1,385 @@
+/** \file CopyEngineManager.cpp
+\brief Define the copy engine manager
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QMessageBox>
+
+#include "CopyEngineManager.h"
+#include "LanguagesManager.h"
+#include "cpp11addition.h"
+
+#ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+#include "plugins/CopyEngine/Ultracopier/CopyEngineFactory.h"
+#endif
+
+CopyEngineManager::CopyEngineManager(OptionDialog *optionDialog)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ this->optionDialog=optionDialog;
+ //setup the ui layout
+ PluginsManager::pluginsManager->lockPluginListEdition();
+ connect(this,&CopyEngineManager::previouslyPluginAdded, this,&CopyEngineManager::onePluginAdded,Qt::QueuedConnection);
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginAdded, this,&CopyEngineManager::onePluginAdded,Qt::QueuedConnection);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginWillBeRemoved, this,&CopyEngineManager::onePluginWillBeRemoved,Qt::DirectConnection);
+ #endif
+ connect(PluginsManager::pluginsManager,&PluginsManager::pluginListingIsfinish, this,&CopyEngineManager::allPluginIsloaded,Qt::QueuedConnection);
+ std::vector<PluginsAvailable> list=PluginsManager::pluginsManager->getPluginsByCategory(PluginType_CopyEngine);
+ foreach(PluginsAvailable currentPlugin,list)
+ emit previouslyPluginAdded(currentPlugin);
+ PluginsManager::pluginsManager->unlockPluginListEdition();
+ //load the options
+ isConnected=false;
+}
+
+void CopyEngineManager::onePluginAdded(const PluginsAvailable &plugin)
+{
+ if(plugin.category!=PluginType_CopyEngine)
+ return;
+ //setFileName
+ std::string pluginPath=plugin.path+PluginsManager::getResolvedPluginName("copyEngine");
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ /*more IO
+ if(!QFile(pluginPath).exists())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The plugin binary is missing: "+pluginPath);
+ return;
+ }*/
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+pluginPath);
+ //search into loaded session
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).pluginPath==pluginPath)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Engine already found!");
+ return;
+ }
+ index++;
+ }
+ CopyEnginePlugin newItem;
+ newItem.pluginPath=pluginPath;
+ newItem.path=plugin.path;
+ newItem.name=plugin.name;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ newItem.pointer=new QPluginLoader(QString::fromStdString(newItem.pluginPath));
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ QObjectList objectList=QPluginLoader::staticInstances();
+ index=0;
+ QObject *pluginObject;
+ while(index<objectList.size())
+ {
+ pluginObject=objectList.at(index);
+ newItem.factory = qobject_cast<PluginInterface_CopyEngineFactory *>(pluginObject);
+ if(newItem.factory!=NULL)
+ break;
+ index++;
+ }
+ if(index==objectList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"static copy engine not found");
+ return;
+ }
+ #else
+ QObject *pluginObject = newItem.pointer->instance();
+ if(pluginObject==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to load the plugin: "+newItem.pointer->errorString().toStdString());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to load the plugin for "+newItem.pluginPath);
+ newItem.pointer->unload();
+ return;
+ }
+ newItem.factory = qobject_cast<PluginInterface_CopyEngineFactory *>(pluginObject);
+ //check if found
+ index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).factory==newItem.factory)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Plugin already found");
+ newItem.pointer->unload();
+ return;
+ }
+ index++;
+ }
+ if(newItem.factory==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to cast the plugin: "+newItem.pointer->errorString().toStdString());
+ newItem.pointer->unload();
+ return;
+ }
+ #endif
+ #else
+ newItem.factory=new CopyEngineFactory();
+ #endif
+
+ #ifdef ULTRACOPIER_DEBUG
+ connect(newItem.factory,&PluginInterface_CopyEngineFactory::debugInformation,this,&CopyEngineManager::debugInformation,Qt::QueuedConnection);
+ #endif // ULTRACOPIER_DEBUG
+ newItem.options=new LocalPluginOptions("CopyEngine-"+newItem.name);
+ newItem.factory->setResources(newItem.options,plugin.writablePath,plugin.path,&FacilityEngine::facilityEngine,ULTRACOPIER_VERSION_PORTABLE_BOOL);
+ newItem.optionsWidget=newItem.factory->options();
+ newItem.supportedProtocolsForTheSource=newItem.factory->supportedProtocolsForTheSource();
+ newItem.supportedProtocolsForTheDestination=newItem.factory->supportedProtocolsForTheDestination();
+ newItem.canDoOnlyCopy=newItem.factory->canDoOnlyCopy();
+ newItem.type=newItem.factory->getCopyType();
+ newItem.transferListOperation=newItem.factory->getTransferListOperation();
+ optionDialog->addPluginOptionWidget(PluginType_CopyEngine,newItem.name,newItem.optionsWidget);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"plugin: "+newItem.name+" loaded, send options");
+ //emit newCopyEngineOptions(plugin.path,newItem.name,newItem.optionsWidget);
+ pluginList.push_back(newItem);
+ connect(LanguagesManager::languagesManager,&LanguagesManager::newLanguageLoaded,newItem.factory,&PluginInterface_CopyEngineFactory::newLanguageLoaded);
+ if(PluginsManager::pluginsManager->allPluginHaveBeenLoaded())
+ allPluginIsloaded();
+ if(isConnected)
+ emit addCopyEngine(newItem.name,newItem.canDoOnlyCopy);
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+void CopyEngineManager::onePluginWillBeRemoved(const PluginsAvailable &plugin)
+{
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).path==plugin.path)
+ {
+ if(pluginList.at(index).intances.size()<=0)
+ {
+ emit removeCopyEngine(pluginList.at(index).name);
+ pluginList.erase(pluginList.begin()+index);
+ allPluginIsloaded();
+ return;
+ }
+ }
+ index++;
+ }
+}
+
+void CopyEngineManager::onePluginWillBeUnloaded(const PluginsAvailable &plugin)
+{
+ if(plugin.category!=PluginType_CopyEngine)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).path==plugin.path)
+ {
+ delete pluginList.at(index).options;
+ delete pluginList.at(index).factory;
+ pluginList.at(index).pointer->unload();
+ return;
+ }
+ index++;
+ }
+}
+#endif
+
+CopyEngineManager::returnCopyEngine CopyEngineManager::getCopyEngine(const Ultracopier::CopyMode &mode,
+ const std::vector<std::string> &protocolsUsedForTheSources,const std::string &protocolsUsedForTheDestination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, pluginList.size(): "+std::to_string(pluginList.size())+", mode: "+std::to_string((int)mode)+", and particular protocol");
+ returnCopyEngine temp;
+ unsigned int index=0;
+ bool isTheGoodEngine=false;
+ while(index<pluginList.size())
+ {
+ const CopyEnginePlugin &copyEnginePlugin=pluginList.at(index);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"pluginList.at("+std::to_string(index)+").name: "+copyEnginePlugin.name);
+ isTheGoodEngine=false;
+ if(mode!=Ultracopier::Move || !copyEnginePlugin.canDoOnlyCopy)
+ {
+ if(protocolsUsedForTheSources.size()==0)
+ isTheGoodEngine=true;
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"copyEnginePlugin.supportedProtocolsForTheDestination: "+stringimplode(copyEnginePlugin.supportedProtocolsForTheDestination,";"));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"protocolsUsedForTheDestination: "+protocolsUsedForTheDestination);
+ if(protocolsUsedForTheDestination.empty() || vectorcontainsAtLeastOne(copyEnginePlugin.supportedProtocolsForTheDestination,protocolsUsedForTheDestination))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"copyEnginePlugin.supportedProtocolsForTheSource: "+stringimplode(copyEnginePlugin.supportedProtocolsForTheSource,";"));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"protocolsUsedForTheSources.at(indexProto): "+stringimplode(protocolsUsedForTheSources,";"));
+ isTheGoodEngine=true;
+ unsigned int indexProto=0;
+ while(indexProto<protocolsUsedForTheSources.size())
+ {
+ if(!vectorcontainsAtLeastOne(copyEnginePlugin.supportedProtocolsForTheSource,protocolsUsedForTheSources.at(indexProto)))
+ {
+ isTheGoodEngine=false;
+ break;
+ }
+ indexProto++;
+ }
+ }
+ }
+ }
+ if(isTheGoodEngine)
+ {
+ pluginList[index].intances.push_back(pluginList.at(index).factory->getInstance());
+ temp.engine=pluginList.at(index).intances.back();
+ temp.canDoOnlyCopy=pluginList.at(index).canDoOnlyCopy;
+ temp.type=pluginList.at(index).type;
+ temp.transferListOperation=pluginList.at(index).transferListOperation;
+ return temp;
+ }
+ index++;
+ }
+ if(mode==Ultracopier::Move)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Cannot find any copy engine with move support");
+ QMessageBox::critical(NULL,tr("Warning"),tr("Cannot find any copy engine with move support"));
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Cannot find any compatible engine!");
+ QMessageBox::critical(NULL,tr("Warning"),tr("Cannot find any compatible engine!"));
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"protocolsUsedForTheSources: "+stringimplode(protocolsUsedForTheSources,";")+", protocolsUsedForTheDestination: "+protocolsUsedForTheDestination);
+
+ temp.engine=NULL;
+ temp.type=Ultracopier::File;
+ temp.canDoOnlyCopy=true;
+ return temp;
+}
+
+CopyEngineManager::returnCopyEngine CopyEngineManager::getCopyEngine(const Ultracopier::CopyMode &mode,const std::string &name)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, pluginList.size(): "+std::to_string(pluginList.size())+", with mode: "+std::to_string((int)mode)+", and name: "+name);
+ returnCopyEngine temp;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Check matching: "+pluginList.at(index).name);
+ if(pluginList.at(index).name==name || name.empty())
+ {
+ if(mode==Ultracopier::Move && pluginList.at(index).canDoOnlyCopy)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"This copy engine does not support move: pluginList.at(index).canDoOnlyCopy: "+std::to_string(pluginList.at(index).canDoOnlyCopy));
+ QMessageBox::critical(NULL,tr("Warning"),tr("This copy engine does not support move"));
+ temp.engine=NULL;
+ return temp;
+ }
+ pluginList[index].intances.push_back(pluginList.at(index).factory->getInstance());
+ temp.engine=pluginList.at(index).intances.back();
+ temp.canDoOnlyCopy=pluginList.at(index).canDoOnlyCopy;
+ temp.type=pluginList.at(index).type;
+ temp.transferListOperation=pluginList.at(index).transferListOperation;
+ return temp;
+ }
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Cannot find any engine with this name: "+name);
+ QMessageBox::critical(NULL,tr("Warning"),tr("Cannot find any engine with this name: %1").arg(QString::fromStdString(name)));
+ temp.engine=NULL;
+ temp.type=Ultracopier::File;
+ temp.canDoOnlyCopy=true;
+ return temp;
+}
+
+#ifdef ULTRACOPIER_DEBUG
+void CopyEngineManager::debugInformation(const Ultracopier::DebugLevel &level,const std::string& fonction,const std::string& text,const std::string& file,const int& ligne)
+{
+ DebugEngine::addDebugInformationStatic(level,fonction,text,file,ligne,"Copy Engine plugin");
+}
+#endif // ULTRACOPIER_DEBUG
+
+/// \brief To notify when new value into a group have changed
+void CopyEngineManager::newOptionValue(const std::string &groupName,const std::string &variableName,const std::string &value)
+{
+ if(groupName=="CopyEngine" && variableName=="List")
+ {
+ Q_UNUSED(value)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"start(\""+groupName+"\",\""+variableName+"\",\""+value+"\")");
+ allPluginIsloaded();
+ }
+}
+
+void CopyEngineManager::setIsConnected()
+{
+ /* ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ prevent bug, I don't know why, in one case it bug here
+ */
+ isConnected=true;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ emit addCopyEngine(pluginList.at(index).name,pluginList.at(index).canDoOnlyCopy);
+ index++;
+ }
+}
+
+void CopyEngineManager::allPluginIsloaded()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ std::vector<std::string> actualList;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ actualList.push_back(pluginList.at(index).name);
+ index++;
+ }
+ std::vector<std::string> preferedList=stringsplit(OptionEngine::optionEngine->getOptionValue("CopyEngine","List"),';');
+ vectorRemoveDuplicatesForSmallList(preferedList);
+ vectorRemoveDuplicatesForSmallList(actualList);
+ index=0;
+ while(index<preferedList.size())
+ {
+ if(!vectorcontainsAtLeastOne(actualList,preferedList.at(index)))
+ {
+ preferedList.erase(preferedList.cbegin()+index);
+ index--;
+ }
+ index++;
+ }
+ index=0;
+ while(index<actualList.size())
+ {
+ if(!vectorcontainsAtLeastOne(preferedList,actualList.at(index)))
+ preferedList.push_back( actualList.at(index));
+ index++;
+ }
+ OptionEngine::optionEngine->setOptionValue("CopyEngine","List",stringimplode(preferedList,';'));
+ std::vector<CopyEnginePlugin> newPluginList;
+ index=0;
+ while(index<preferedList.size())
+ {
+ unsigned int pluginListIndex=0;
+ while(pluginListIndex<pluginList.size())
+ {
+ if(preferedList.at(index)==pluginList.at(pluginListIndex).name)
+ {
+ newPluginList.push_back(pluginList.at(pluginListIndex));
+ break;
+ }
+ pluginListIndex++;
+ }
+ index++;
+ }
+ pluginList=newPluginList;
+}
+
+bool CopyEngineManager::protocolsSupportedByTheCopyEngine(PluginInterface_CopyEngine * engine,const std::vector<std::string> &protocolsUsedForTheSources,const std::string &protocolsUsedForTheDestination)
+{
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ const CopyEnginePlugin &copyEnginePlugin=pluginList.at(index);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"pluginList.at("+std::to_string(index)+").name: "+copyEnginePlugin.name);
+ if(vectorcontainsAtLeastOne(copyEnginePlugin.intances,engine))
+ {
+ if(!vectorcontainsAtLeastOne(copyEnginePlugin.supportedProtocolsForTheDestination,protocolsUsedForTheDestination))
+ return false;
+ unsigned int indexProto=0;
+ while(indexProto<protocolsUsedForTheSources.size())
+ {
+ if(!vectorcontainsAtLeastOne(copyEnginePlugin.supportedProtocolsForTheSource,protocolsUsedForTheSources.at(indexProto)))
+ return false;
+ indexProto++;
+ }
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/CopyEngineManager.h b/CopyEngineManager.h
new file mode 100644
index 0000000..904508c
--- /dev/null
+++ b/CopyEngineManager.h
@@ -0,0 +1,105 @@
+/** \file CopyEngineManager.h
+\brief Define the copy engine manager
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef COPYENGINEMANAGER_H
+#define COPYENGINEMANAGER_H
+
+#include <QObject>
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+#include <QPluginLoader>
+#endif
+#include <QList>
+#include <QWidget>
+#include <QString>
+
+#include "Environment.h"
+#include "LocalPluginOptions.h"
+#include "OptionDialog.h"
+#include "interface/PluginInterface_CopyEngine.h"
+#include "FacilityEngine.h"
+
+namespace Ui {
+ class CopyEngineOptions;
+}
+
+/** \brief Manage copy engine plugins and their instance */
+class CopyEngineManager : public QObject
+{
+ Q_OBJECT
+public:
+ /** \brief internal structure to return one copy engine instance */
+ struct returnCopyEngine
+ {
+ PluginInterface_CopyEngine * engine; ///< The copy engine instance
+ bool canDoOnlyCopy; ///< true if can do only the copy (not move)
+ Ultracopier::CopyType type; ///< Kind of copy what it can do
+ Ultracopier::TransferListOperation transferListOperation;
+ };
+ explicit CopyEngineManager(OptionDialog *optionDialog);
+ /** \brief return copy engine instance when know the sources and destinations
+ \param mode the mode (copy/move)
+ \param protocolsUsedForTheSources list of sources used
+ \param protocolsUsedForTheDestination list of destination used
+ \see getCopyEngine()
+ */
+ returnCopyEngine getCopyEngine(const Ultracopier::CopyMode &mode,const std::vector<std::string> &protocolsUsedForTheSources,const std::string &protocolsUsedForTheDestination);
+ /** \brief return copy engine instance with specific engine
+ \param mode the mode (copy/move)
+ \param name name of the engine needed
+ \see getCopyEngine()
+ */
+ returnCopyEngine getCopyEngine(const Ultracopier::CopyMode &mode,const std::string &name);
+ //bool currentEngineCanDoOnlyCopy(std::vector<std::string> protocolsUsedForTheSources,std::string protocolsUsedForTheDestination="");
+ //CopyType currentEngineGetCopyType(std::vector<std::string> protocolsUsedForTheSources,std::string protocolsUsedForTheDestination="");
+ /** \brief to send all signal because all object is connected on it */
+ void setIsConnected();
+ /** \brief check if the protocols given is supported by the copy engine
+ \see Core::newCopy()
+ \see Core::newMove()
+ */
+ bool protocolsSupportedByTheCopyEngine(PluginInterface_CopyEngine * engine,const std::vector<std::string> &protocolsUsedForTheSources,const std::string &protocolsUsedForTheDestination);
+private slots:
+ void onePluginAdded(const PluginsAvailable &plugin);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ void onePluginWillBeRemoved(const PluginsAvailable &plugin);
+ void onePluginWillBeUnloaded(const PluginsAvailable &plugin);
+ #endif
+ #ifdef ULTRACOPIER_DEBUG
+ void debugInformation(const Ultracopier::DebugLevel &level, const std::string& fonction, const std::string& text, const std::string& file, const int& ligne);
+ #endif // ULTRACOPIER_DEBUG
+ /// \brief To notify when new value into a group have changed
+ void newOptionValue(const std::string &groupName,const std::string &variableName,const std::string &value);
+ void allPluginIsloaded();
+private:
+ /// \brief the option interface
+ struct CopyEnginePlugin
+ {
+ std::string path;
+ std::string name;
+ std::string pluginPath;
+ std::vector<std::string> supportedProtocolsForTheSource;
+ std::vector<std::string> supportedProtocolsForTheDestination;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ QPluginLoader * pointer;
+ #endif
+ PluginInterface_CopyEngineFactory * factory;
+ std::vector<PluginInterface_CopyEngine *> intances;
+ bool canDoOnlyCopy;
+ Ultracopier::CopyType type;
+ Ultracopier::TransferListOperation transferListOperation;
+ LocalPluginOptions *options;
+ QWidget *optionsWidget;
+ };
+ std::vector<CopyEnginePlugin> pluginList;
+ OptionDialog *optionDialog;
+ bool isConnected;
+signals:
+ //void newCopyEngineOptions(std::string,std::string,QWidget *);
+ void addCopyEngine(std::string name,bool canDoOnlyCopy) const;
+ void removeCopyEngine(std::string name) const;
+ void previouslyPluginAdded(PluginsAvailable) const;
+};
+
+#endif // COPYENGINEMANAGER_H
diff --git a/CopyListener.cpp b/CopyListener.cpp
new file mode 100644
index 0000000..3c72695
--- /dev/null
+++ b/CopyListener.cpp
@@ -0,0 +1,480 @@
+/** \file CopyListener.h
+\brief Define the copy listener
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "CopyListener.h"
+#include "LanguagesManager.h"
+#include "cpp11addition.h"
+
+#ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+#include "plugins/Listener/catchcopy-v0002/listener.h"
+#endif
+
+#include <QRegularExpression>
+#include <QMessageBox>
+
+CopyListener::CopyListener(OptionDialog *optionDialog)
+{
+ stopIt=false;
+ this->optionDialog=optionDialog;
+ pluginLoader=new PluginLoader(optionDialog);
+ //load the options
+ tryListen=false;
+ PluginsManager::pluginsManager->lockPluginListEdition();
+ std::vector<PluginsAvailable> list=PluginsManager::pluginsManager->getPluginsByCategory(PluginType_Listener);
+ connect(this,&CopyListener::previouslyPluginAdded, this,&CopyListener::onePluginAdded,Qt::QueuedConnection);
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginAdded, this,&CopyListener::onePluginAdded,Qt::QueuedConnection);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginWillBeRemoved, this,&CopyListener::onePluginWillBeRemoved,Qt::DirectConnection);
+ #endif
+ connect(PluginsManager::pluginsManager,&PluginsManager::pluginListingIsfinish, this,&CopyListener::allPluginIsloaded,Qt::QueuedConnection);
+ connect(pluginLoader,&PluginLoader::pluginLoaderReady, this,&CopyListener::pluginLoaderReady);
+ foreach(PluginsAvailable currentPlugin,list)
+ emit previouslyPluginAdded(currentPlugin);
+ PluginsManager::pluginsManager->unlockPluginListEdition();
+ last_state=Ultracopier::NotListening;
+ last_have_plugin=false;
+ last_inWaitOfReply=false;
+ stripSeparatorRegex=std::regex("[\\\\/]+$");
+}
+
+CopyListener::~CopyListener()
+{
+ stopIt=true;
+ if(pluginLoader!=NULL)
+ {
+ delete pluginLoader;
+ pluginLoader=NULL;
+ }
+}
+
+void CopyListener::resendState()
+{
+ if(PluginsManager::pluginsManager->allPluginHaveBeenLoaded())
+ {
+ sendState(true);
+ if(pluginLoader!=NULL)
+ pluginLoader->resendState();
+ }
+}
+
+void CopyListener::onePluginAdded(const PluginsAvailable &plugin)
+{
+ if(plugin.category!=PluginType_Listener)
+ return;
+ PluginListener newPluginListener;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"try load: "+plugin.path+PluginsManager::getResolvedPluginName("listener"));
+ //setFileName
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ PluginInterface_Listener *listen;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ QObjectList objectList=QPluginLoader::staticInstances();
+ int index=0;
+ QObject *pluginObject;
+ while(index<objectList.size())
+ {
+ pluginObject=objectList.at(index);
+ listen = qobject_cast<PluginInterface_Listener *>(pluginObject);
+ if(listen!=NULL)
+ break;
+ index++;
+ }
+ if(index==objectList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"static listener not found");
+ return;
+ }
+ #else
+ listen=new Listener();
+ #endif
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ newPluginListener.pluginLoader=NULL;
+ #endif
+ #else
+ QPluginLoader *pluginOfPluginLoader=new QPluginLoader(QString::fromStdString(plugin.path+PluginsManager::getResolvedPluginName("listener")));
+ QObject *pluginInstance = pluginOfPluginLoader->instance();
+ if(!pluginInstance)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to load the plugin: "+pluginOfPluginLoader->errorString().toStdString());
+ return;
+ }
+ PluginInterface_Listener *listen = qobject_cast<PluginInterface_Listener *>(pluginInstance);
+ if(!listen)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to load the plugin: "+pluginOfPluginLoader->errorString().toStdString());
+ return;
+ }
+ //check if found
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).listenInterface==listen)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Plugin already found "+pluginList.at(index).path+" for "+plugin.path);
+ pluginOfPluginLoader->unload();
+ return;
+ }
+ index++;
+ }
+ newPluginListener.pluginLoader = pluginOfPluginLoader;
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Plugin correctly loaded");
+ #ifdef ULTRACOPIER_DEBUG
+ connect(listen,&PluginInterface_Listener::debugInformation,this,&CopyListener::debugInformation,Qt::DirectConnection);
+ #endif // ULTRACOPIER_DEBUG
+ connect(listen,&PluginInterface_Listener::error, this,&CopyListener::error,Qt::DirectConnection);
+ connect(listen,&PluginInterface_Listener::newCopyWithoutDestination, this,&CopyListener::newPluginCopyWithoutDestination,Qt::DirectConnection);
+ connect(listen,&PluginInterface_Listener::newCopy, this,&CopyListener::newPluginCopy,Qt::DirectConnection);
+ connect(listen,&PluginInterface_Listener::newMoveWithoutDestination, this,&CopyListener::newPluginMoveWithoutDestination,Qt::DirectConnection);
+ connect(listen,&PluginInterface_Listener::newMove, this,&CopyListener::newPluginMove,Qt::DirectConnection);
+ connect(listen,&PluginInterface_Listener::newClientList, this,&CopyListener::reloadClientList,Qt::DirectConnection);
+ newPluginListener.listenInterface = listen;
+
+ newPluginListener.path = plugin.path+PluginsManager::getResolvedPluginName("listener");
+ newPluginListener.state = Ultracopier::NotListening;
+ newPluginListener.inWaitOfReply = false;
+ newPluginListener.options=new LocalPluginOptions("Listener-"+plugin.name);
+ newPluginListener.listenInterface->setResources(newPluginListener.options,plugin.writablePath,plugin.path,ULTRACOPIER_VERSION_PORTABLE_BOOL);
+ optionDialog->addPluginOptionWidget(PluginType_Listener,plugin.name,newPluginListener.listenInterface->options());
+ connect(LanguagesManager::languagesManager,&LanguagesManager::newLanguageLoaded,newPluginListener.listenInterface,&PluginInterface_Listener::newLanguageLoaded,Qt::DirectConnection);
+ pluginList.push_back(newPluginListener);
+ connect(pluginList.back().listenInterface,&PluginInterface_Listener::newState,this,&CopyListener::newState,Qt::DirectConnection);
+ if(tryListen)
+ {
+ pluginList.back().inWaitOfReply=true;
+ listen->listen();
+ }
+}
+
+#ifdef ULTRACOPIER_DEBUG
+void CopyListener::debugInformation(const Ultracopier::DebugLevel &level, const std::string& fonction, const std::string& text, const std::string& file, const int& ligne)
+{
+ DebugEngine::addDebugInformationStatic(level,fonction,text,file,ligne,"Listener plugin");
+}
+#endif // ULTRACOPIER_DEBUG
+
+void CopyListener::error(const std::string &error)
+{
+ QMessageBox::critical(NULL,tr("Error"),tr("Error during the reception of the copy/move list\n%1").arg(QString::fromStdString(error)));
+}
+
+bool CopyListener::oneListenerIsLoaded()
+{
+ return (pluginList.size()>0);
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+void CopyListener::onePluginWillBeRemoved(const PluginsAvailable &plugin)
+{
+ if(plugin.category!=PluginType_Listener)
+ return;
+ unsigned int indexPlugin=0;
+ while(indexPlugin<pluginList.size())
+ {
+ if((plugin.path+PluginsManager::getResolvedPluginName("listener"))==pluginList.at(indexPlugin).path)
+ {
+ unsigned int index=0;
+ while(index<copyRunningList.size())
+ {
+ if(copyRunningList.at(index).listenInterface==pluginList.at(indexPlugin).listenInterface)
+ copyRunningList[index].listenInterface=NULL;
+ index++;
+ }
+ if(pluginList.at(indexPlugin).listenInterface!=NULL)
+ {
+ pluginList.at(indexPlugin).listenInterface->close();
+ delete pluginList.at(indexPlugin).listenInterface;
+ }
+ if(pluginList.at(indexPlugin).pluginLoader!=NULL)
+ {
+ pluginList.at(indexPlugin).pluginLoader->unload();
+ delete pluginList.at(indexPlugin).options;
+ }
+ pluginList.erase(pluginList.cbegin()+indexPlugin);
+ sendState();
+ return;
+ }
+ indexPlugin++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"not found");
+}
+#endif
+
+void CopyListener::newState(const Ultracopier::ListeningState &state)
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ PluginInterface_Listener *temp=qobject_cast<PluginInterface_Listener *>(QObject::sender());
+ if(temp==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"listener not located!");
+ return;
+ }
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(temp==pluginList.at(index).listenInterface)
+ {
+ pluginList[index].state=state;
+ pluginList[index].inWaitOfReply=false;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"new state for the plugin "+std::to_string(index)+": "+std::to_string((int)state));
+ sendState(true);
+ return;
+ }
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"listener not found!");
+}
+
+void CopyListener::listen()
+{
+ tryListen=true;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ pluginList[index].inWaitOfReply=true;
+ pluginList.at(index).listenInterface->listen();
+ index++;
+ }
+ if(pluginLoader!=NULL)
+ pluginLoader->load();
+}
+
+void CopyListener::close()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ tryListen=false;
+ if(pluginLoader!=NULL)
+ pluginLoader->unload();
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ pluginList[index].inWaitOfReply=true;
+ pluginList.at(index).listenInterface->close();
+ index++;
+ }
+ copyRunningList.clear();
+}
+
+std::vector<std::string> CopyListener::stripSeparator(std::vector<std::string> sources)
+{
+ unsigned int index=0;
+ while(index<sources.size())
+ {
+ std::regex_replace(sources[index],stripSeparatorRegex,"");
+ index++;
+ }
+ return sources;
+}
+
+/** new copy without destination have been pased by the CLI */
+void CopyListener::copyWithoutDestination(std::vector<std::string> sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ std::vector<std::string> list;
+ list.push_back("file");
+ emit newCopyWithoutDestination(incrementOrderId(),list,stripSeparator(sources));
+}
+
+/** new copy with destination have been pased by the CLI */
+void CopyListener::copy(std::vector<std::string> sources,std::string destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ std::vector<std::string> list;
+ list.push_back("file");
+ emit newCopy(incrementOrderId(),list,stripSeparator(sources),"file",destination);
+}
+
+/** new move without destination have been pased by the CLI */
+void CopyListener::moveWithoutDestination(std::vector<std::string> sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ std::vector<std::string> list;
+ list.push_back("file");
+ emit newMoveWithoutDestination(incrementOrderId(),list,stripSeparator(sources));
+}
+
+/** new move with destination have been pased by the CLI */
+void CopyListener::move(std::vector<std::string> sources,std::string destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ std::vector<std::string> list;
+ list.push_back("file");
+ emit newMove(incrementOrderId(),list,stripSeparator(sources),"file",destination);
+}
+
+void CopyListener::copyFinished(const quint32 & orderId,const bool &withError)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<copyRunningList.size())
+ {
+ if(orderId==copyRunningList.at(index).orderId)
+ {
+ vectorRemoveAll(orderList,orderId);
+ if(copyRunningList.at(index).listenInterface!=NULL)
+ copyRunningList.at(index).listenInterface->transferFinished(copyRunningList.at(index).pluginOrderId,withError);
+ copyRunningList.erase(copyRunningList.cbegin()+index);
+ return;
+ }
+ index++;
+ }
+}
+
+void CopyListener::copyCanceled(const uint32_t & orderId)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<copyRunningList.size())
+ {
+ if(orderId==copyRunningList.at(index).orderId)
+ {
+ vectorRemoveAll(orderList,orderId);
+ if(copyRunningList.at(index).listenInterface!=NULL)
+ copyRunningList.at(index).listenInterface->transferCanceled(copyRunningList.at(index).pluginOrderId);
+ copyRunningList.erase(copyRunningList.cbegin()+index);
+ return;
+ }
+ index++;
+ }
+}
+
+void CopyListener::newPluginCopyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sources: "+stringimplode(sources,";"));
+ PluginInterface_Listener *plugin = qobject_cast<PluginInterface_Listener *>(sender());
+ CopyRunning newCopyInformation;
+ newCopyInformation.listenInterface = plugin;
+ newCopyInformation.pluginOrderId = orderId;
+ newCopyInformation.orderId = incrementOrderId();
+ copyRunningList.push_back(newCopyInformation);
+ std::vector<std::string> stringList;stringList.push_back("file");
+ emit newCopyWithoutDestination(orderId,stringList,stripSeparator(sources));
+}
+
+void CopyListener::newPluginCopy(const quint32 &orderId,const std::vector<std::string> &sources,const std::string &destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sources: "+stringimplode(sources,";")+", destination: "+destination);
+ PluginInterface_Listener *plugin = qobject_cast<PluginInterface_Listener *>(sender());
+ CopyRunning newCopyInformation;
+ newCopyInformation.listenInterface = plugin;
+ newCopyInformation.pluginOrderId = orderId;
+ newCopyInformation.orderId = incrementOrderId();
+ copyRunningList.push_back(newCopyInformation);
+ std::vector<std::string> stringList;stringList.push_back("file");
+ emit newCopy(orderId,stringList,stripSeparator(sources),"file",destination);
+}
+
+void CopyListener::newPluginMoveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sources: "+stringimplode(sources,";"));
+ PluginInterface_Listener *plugin = qobject_cast<PluginInterface_Listener *>(sender());
+ CopyRunning newCopyInformation;
+ newCopyInformation.listenInterface = plugin;
+ newCopyInformation.pluginOrderId = orderId;
+ newCopyInformation.orderId = incrementOrderId();
+ copyRunningList.push_back(newCopyInformation);
+ std::vector<std::string> stringList;stringList.push_back("file");
+ emit newMoveWithoutDestination(orderId,stringList,stripSeparator(sources));
+}
+
+void CopyListener::newPluginMove(const quint32 &orderId,const std::vector<std::string> &sources,const std::string &destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sources: "+stringimplode(sources,";")+", destination: "+destination);
+ PluginInterface_Listener *plugin = qobject_cast<PluginInterface_Listener *>(sender());
+ CopyRunning newCopyInformation;
+ newCopyInformation.listenInterface = plugin;
+ newCopyInformation.pluginOrderId = orderId;
+ newCopyInformation.orderId = incrementOrderId();
+ copyRunningList.push_back(newCopyInformation);
+ std::vector<std::string> stringList;stringList.push_back("file");
+ emit newMove(orderId,stringList,stripSeparator(sources),"file",destination);
+}
+
+uint32_t CopyListener::incrementOrderId()
+{
+ do
+ {
+ nextOrderId++;
+ if(nextOrderId>2000000)
+ nextOrderId=0;
+ } while(vectorcontainsAtLeastOne(orderList,nextOrderId));
+ return nextOrderId;
+}
+
+void CopyListener::allPluginIsloaded()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"with value: "+std::to_string(pluginList.size()>0));
+ sendState(true);
+ reloadClientList();
+}
+
+void CopyListener::reloadClientList()
+{
+ if(!PluginsManager::pluginsManager->allPluginHaveBeenLoaded())
+ return;
+ std::vector<std::string> clients;
+ unsigned int indexPlugin=0;
+ while(indexPlugin<pluginList.size())
+ {
+ if(pluginList.at(indexPlugin).listenInterface!=NULL)
+ {
+ const PluginListener &pluginListener=pluginList.at(indexPlugin);
+ const std::vector<std::string> &clientsList=pluginListener.listenInterface->clientsList();
+ clients.insert(clients.cbegin(),clientsList.cbegin(),clientsList.cend());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ask client to: "+pluginList.at(indexPlugin).path);
+ }
+ indexPlugin++;
+ }
+ emit newClientList(clients);
+}
+
+void CopyListener::sendState(bool force)
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, pluginList.size(): "+std::to_string(pluginList.size())+", force: "+std::to_string(force));
+ Ultracopier::ListeningState current_state=Ultracopier::NotListening;
+ bool found_not_listen=false,found_listen=false,found_inWaitOfReply=false;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(current_state==Ultracopier::NotListening)
+ {
+ if(pluginList.at(index).state==Ultracopier::SemiListening)
+ current_state=Ultracopier::SemiListening;
+ else if(pluginList.at(index).state==Ultracopier::NotListening)
+ found_not_listen=true;
+ else if(pluginList.at(index).state==Ultracopier::FullListening)
+ found_listen=true;
+ }
+ if(pluginList.at(index).inWaitOfReply)
+ found_inWaitOfReply=true;
+ index++;
+ }
+ if(current_state==Ultracopier::NotListening)
+ {
+ if(found_not_listen && found_listen)
+ current_state=Ultracopier::SemiListening;
+ else if(found_not_listen)
+ current_state=Ultracopier::NotListening;
+ else if(!found_not_listen && found_listen)
+ current_state=Ultracopier::FullListening;
+ else
+ current_state=Ultracopier::SemiListening;
+ }
+ bool have_plugin=pluginList.size()>0;
+ if(force || current_state!=last_state || have_plugin!=last_have_plugin || found_inWaitOfReply!=last_inWaitOfReply)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"send listenerReady("+std::to_string(current_state)+","+std::to_string(have_plugin)+","+std::to_string(found_inWaitOfReply)+")");
+ emit listenerReady(current_state,have_plugin,found_inWaitOfReply);
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Skip the signal sending");
+ last_state=current_state;
+ last_have_plugin=have_plugin;
+ last_inWaitOfReply=found_inWaitOfReply;
+}
diff --git a/CopyListener.h b/CopyListener.h
new file mode 100644
index 0000000..3003aec
--- /dev/null
+++ b/CopyListener.h
@@ -0,0 +1,123 @@
+/** \file CopyListener.h
+\brief Define the class to load the plugin and lunch it
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef COPYLISTENER_H
+#define COPYLISTENER_H
+
+#include <QObject>
+#include <QList>
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+#include <QPluginLoader>
+#endif
+
+#include "interface/PluginInterface_Listener.h"
+#include "Environment.h"
+#include "PluginLoader.h"
+#include "OptionDialog.h"
+
+/** \brief to load all the listener and parse all event */
+class CopyListener : public QObject
+{
+ Q_OBJECT
+ public:
+ explicit CopyListener(OptionDialog *optionDialog);
+ ~CopyListener();
+ /** \brief send of one listener is loaded */
+ bool oneListenerIsLoaded();
+ /** \brief to resend the state */
+ void resendState();
+ private slots:
+ //void newPlugin();
+ void newPluginCopyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources);
+ void newPluginCopy(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination);
+ void newPluginMoveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &sources);
+ void newPluginMove(const uint32_t &orderId,const std::vector<std::string> &sources,const std::string &destination);
+ void onePluginAdded(const PluginsAvailable &plugin);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ void onePluginWillBeRemoved(const PluginsAvailable &plugin);
+ #endif
+ void newState(const Ultracopier::ListeningState &state);
+ #ifdef ULTRACOPIER_DEBUG
+ void debugInformation(const Ultracopier::DebugLevel &level,const std::string& fonction,const std::string& text,const std::string& file,const int& ligne);
+ #endif // ULTRACOPIER_DEBUG
+ void error(const std::string &error);
+ void allPluginIsloaded();
+ void reloadClientList();
+ public slots:
+ /** \brief the copy is finished
+ \param orderId id used when it have send the copy
+ \param withError true if it have found error
+ \see newCopy()
+ \see newMove()
+ */
+ void copyFinished(const uint32_t & orderId,const bool &withError);
+ /** \brief the copy is canceled by the user
+ \param orderId id used when it have send the copy
+ \see newCopy()
+ \see newMove()
+ */
+ void copyCanceled(const uint32_t & orderId);
+ /** \brief try listen, to get copy/move from external source (mainly the file manager)
+ \see close()
+ */
+ void listen();
+ /** \brief stop listen, to get copy/move from external source (mainly the file manager)
+ \see listen()
+ */
+ void close();
+ /** new copy without destination have been pased by the CLI */
+ void copyWithoutDestination(std::vector<std::string> sources);
+ /** new copy with destination have been pased by the CLI */
+ void copy(std::vector<std::string> sources,std::string destination);
+ /** new move without destination have been pased by the CLI */
+ void moveWithoutDestination(std::vector<std::string> sources);
+ /** new move with destination have been pased by the CLI */
+ void move(std::vector<std::string> sources,std::string destination);
+ signals:
+ void newCopyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources) const;
+ void newCopy(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination) const;
+ void newMoveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources) const;
+ void newMove(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination) const;
+ void listenerReady(const Ultracopier::ListeningState &state,const bool &havePlugin,const bool &someAreInWaitOfReply) const;
+ void pluginLoaderReady(const Ultracopier::CatchState &state,const bool &havePlugin,const bool &someAreInWaitOfReply) const;
+ void previouslyPluginAdded(const PluginsAvailable &) const;
+ void newClientList(const std::vector<std::string> &clientsList) const;
+ private:
+ struct PluginListener
+ {
+ PluginInterface_Listener *listenInterface;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ QPluginLoader *pluginLoader;
+ #endif
+ std::string path;
+ Ultracopier::ListeningState state;
+ bool inWaitOfReply;
+ LocalPluginOptions *options;
+ };
+ std::vector<PluginListener> pluginList;
+ //for the options
+ uint32_t nextOrderId;
+ std::vector<uint32_t> orderList;
+ //for the copy as suspend
+ struct CopyRunning
+ {
+ PluginInterface_Listener *listenInterface;
+ uint32_t pluginOrderId;
+ uint32_t orderId;
+ };
+ std::vector<CopyRunning> copyRunningList;
+ uint32_t incrementOrderId();
+ bool tryListen;
+ PluginLoader *pluginLoader;
+ Ultracopier::ListeningState last_state;
+ bool last_have_plugin,last_inWaitOfReply;
+ void sendState(bool force=false);
+ std::vector<std::string> stripSeparator(std::vector<std::string> sources);
+ OptionDialog *optionDialog;
+ bool stopIt;
+ std::regex stripSeparatorRegex;
+};
+
+#endif // COPYLISTENER_H
diff --git a/Core.cpp b/Core.cpp
new file mode 100644
index 0000000..9f0e8eb
--- /dev/null
+++ b/Core.cpp
@@ -0,0 +1,1161 @@
+/** \file Core.cpp
+\brief Define the class for the core
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QMessageBox>
+#include <QtPlugin>
+#include <cmath>
+
+#include "Core.h"
+#include "ThemesManager.h"
+#include "cpp11addition.h"
+
+Core::Core(CopyEngineManager *copyEngineList)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ this->copyEngineList=copyEngineList;
+ nextId=0;
+ forUpateInformation.setInterval(ULTRACOPIER_TIME_INTERFACE_UPDATE);
+ loadInterface();
+ //connect(&copyEngineList, &CopyEngineManager::newCanDoOnlyCopy, this, &Core::newCanDoOnlyCopy);
+ connect(ThemesManager::themesManager, &ThemesManager::theThemeNeedBeUnloaded, this, &Core::unloadInterface);
+ connect(ThemesManager::themesManager, &ThemesManager::theThemeIsReloaded, this, &Core::loadInterface, Qt::QueuedConnection);
+ connect(&forUpateInformation, &QTimer::timeout, this, &Core::periodicSynchronization);
+}
+
+Core::~Core()
+{
+ unsigned int index=0;
+ while(index<copyList.size())
+ {
+ copyList[index].engine->cancel();
+ delete copyList.at(index).nextConditionalSync;
+ delete copyList.at(index).interface;
+ delete copyList.at(index).engine;
+ index++;
+ }
+}
+
+void Core::newCopyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ if(openNewCopyEngineInstance(Ultracopier::Copy,false,protocolsUsedForTheSources)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ copyList.back().orderId.push_back(orderId);
+ copyList.back().engine->newCopy(sources);
+ copyList.back().interface->haveExternalOrder();
+}
+
+void Core::newTransfer(const Ultracopier::CopyMode &mode,const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+stringimplode(sources,";")+", dest: "+destination+", mode: "+std::to_string(mode));
+ //search to group the window
+ int GroupWindowWhen=stringtoint32(OptionEngine::optionEngine->getOptionValue("Ultracopier","GroupWindowWhen"));
+ bool haveSameSource=false,haveSameDestination=false;
+ if(GroupWindowWhen!=0)
+ {
+ bool needConfirmation=stringtobool(OptionEngine::optionEngine->getOptionValue("Ultracopier","confirmToGroupWindows"));
+ unsigned int index=0;
+ while(index<copyList.size())
+ {
+ bool rightMode=false;
+ if(mode==Ultracopier::Copy)
+ rightMode=copyList.at(index).mode==Ultracopier::Copy;
+ else
+ rightMode=copyList.at(index).mode==Ultracopier::Move;
+ if(!copyList.at(index).ignoreMode && rightMode && !copyList.at(index).canceled)
+ {
+ if(GroupWindowWhen!=5)
+ {
+ if(GroupWindowWhen!=2)
+ haveSameSource=copyList.at(index).engine->haveSameSource(sources);
+ if(GroupWindowWhen!=1)
+ haveSameDestination=copyList.at(index).engine->haveSameDestination(destination);
+ }
+ if(
+ GroupWindowWhen==5 ||
+ (GroupWindowWhen==1 && haveSameSource) ||
+ (GroupWindowWhen==2 && haveSameDestination) ||
+ (GroupWindowWhen==3 && (haveSameSource && haveSameDestination)) ||
+ (GroupWindowWhen==4 && (haveSameSource || haveSameDestination))
+ )
+ {
+ /*protocols are same*/
+ if(copyEngineList->protocolsSupportedByTheCopyEngine(copyList.at(index).engine,protocolsUsedForTheSources,protocolsUsedForTheDestination))
+ {
+ bool confirmed=true;
+ if(needConfirmation)
+ {
+ QMessageBox::StandardButton reply = QMessageBox::question(copyList.at(index).interface,tr("Group window"),tr("Do you want group the transfer with another actual running transfer?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::No);
+ confirmed=(reply==QMessageBox::Yes);
+ }
+ if(confirmed)
+ {
+ copyList[index].orderId.push_back(orderId);
+ if(mode==Ultracopier::Copy)
+ copyList.at(index).engine->newCopy(sources,destination);
+ else
+ copyList.at(index).engine->newMove(sources,destination);
+ copyList.at(index).interface->haveExternalOrder();
+ return;
+ }
+ }
+ }
+ }
+ index++;
+ }
+ }
+ //else open new windows
+ if(openNewCopyEngineInstance(mode,false,protocolsUsedForTheSources,protocolsUsedForTheDestination)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a engine instance"));
+ return;
+ }
+ copyList.back().orderId.push_back(orderId);
+ if(mode==Ultracopier::Copy)
+ copyList.back().engine->newCopy(sources,destination);
+ else
+ copyList.back().engine->newMove(sources,destination);
+ copyList.back().interface->haveExternalOrder();
+}
+
+void Core::newCopy(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination)
+{
+ newTransfer(Ultracopier::Copy,orderId,protocolsUsedForTheSources,sources,protocolsUsedForTheDestination,destination);
+}
+
+void Core::newMove(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination)
+{
+ newTransfer(Ultracopier::Move,orderId,protocolsUsedForTheSources,sources,protocolsUsedForTheDestination,destination);
+}
+
+void Core::newMoveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources)
+{
+ if(openNewCopyEngineInstance(Ultracopier::Move,false,protocolsUsedForTheSources)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ copyList.back().orderId.push_back(orderId);
+ copyList.back().engine->newMove(sources);
+ copyList.back().interface->haveExternalOrder();
+}
+
+/// \brief name to open the right copy engine
+void Core::addWindowCopyMove(const Ultracopier::CopyMode &mode,const std::string &name)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+name);
+ if(openNewCopyEngineInstance(mode,false,name)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ ActionOnManualOpen ActionOnManualOpen_value=static_cast<ActionOnManualOpen>(stringtoint32(OptionEngine::optionEngine->getOptionValue("Ultracopier","ActionOnManualOpen")));
+ if(ActionOnManualOpen_value!=ActionOnManualOpen_Nothing)
+ {
+ if(ActionOnManualOpen_value==ActionOnManualOpen_Folder)
+ copyList.back().engine->userAddFolder(mode);
+ else
+ copyList.back().engine->userAddFile(mode);
+ }
+}
+
+/// \brief name to open the right copy engine
+void Core::addWindowTransfer(const std::string &name)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"+name);
+ if(openNewCopyEngineInstance(Ultracopier::Copy,true,name)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+}
+
+/** new transfer list pased by the CLI */
+void Core::newTransferList(std::string engine,std::string mode,std::string file)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"engine: "+engine+", mode: "+mode+", file: "+file);
+ if(mode=="Transfer")
+ {
+ if(openNewCopyEngineInstance(Ultracopier::Copy,true,engine)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ }
+ else if(mode=="Copy")
+ {
+ if(openNewCopyEngineInstance(Ultracopier::Copy,false,engine)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ }
+ else if(mode=="Move")
+ {
+ if(openNewCopyEngineInstance(Ultracopier::Move,false,engine)==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return;
+ }
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"The argument for the mode is not valid");
+ QMessageBox::critical(NULL,tr("Error"),tr("The argument for the mode is not valid"));
+ return;
+ }
+ copyList.back().engine->newTransferList(file);
+}
+
+bool Core::startNewTransferOneUniqueCopyEngine()
+{
+ if(copyList.size()!=1)
+ return false;
+
+ if(openNewCopyEngineInstance(Ultracopier::Copy,true,std::string())==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to get a copy engine instance");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to get a copy engine instance"));
+ return false;
+ }
+ return true;
+}
+
+void Core::loadInterface()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ //load the extra files to check the themes availability
+ if(copyList.size()>0)
+ {
+ bool error=false;
+ unsigned int index=0;
+ while(index<copyList.size())
+ {
+ copyList[index].interface=ThemesManager::themesManager->getThemesInstance();
+ if(copyList.at(index).interface==NULL)
+ {
+ copyInstanceCanceledByIndex(index);
+ error=true;
+ }
+ else
+ {
+ if(!copyList.at(index).ignoreMode)
+ copyList.at(index).interface->forceCopyMode(copyList.at(index).mode);
+ connectInterfaceAndSync(static_cast<unsigned int>(copyList.size()-1));
+ copyList.at(index).engine->syncTransferList();
+ index++;
+ }
+ }
+ if(error)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to load the interface, copy aborted");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to load the interface, copy aborted"));
+ }
+ }
+}
+
+void Core::unloadInterface()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ size_t index=0;
+ while(index<copyList.size())
+ {
+ if(copyList.at(index).interface!=NULL)
+ {
+ //disconnectInterface(index);
+ delete copyList.at(index).interface;
+ copyList[index].interface=NULL;
+ copyList[index].copyEngineIsSync=false;
+ }
+ index++;
+ }
+}
+
+unsigned int Core::incrementId()
+{
+ do
+ {
+ nextId++;
+ if(nextId>2000000)
+ nextId=0;
+ } while(vectorcontainsAtLeastOne(idList,nextId));
+ return nextId;
+}
+
+/** open with specific source/destination
+\param move Copy or move
+\param ignoreMode if need ignore the mode
+\param protocolsUsedForTheSources protocols used for sources
+\param protocolsUsedForTheDestination protocols used for destination
+*/
+int Core::openNewCopyEngineInstance(const Ultracopier::CopyMode &mode,const bool &ignoreMode,
+ const std::vector<std::string> &protocolsUsedForTheSources,const std::string &protocolsUsedForTheDestination)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ CopyEngineManager::returnCopyEngine returnInformations=copyEngineList->getCopyEngine(mode,protocolsUsedForTheSources,protocolsUsedForTheDestination);
+ if(returnInformations.engine==NULL)
+ return -1;
+ return connectCopyEngine(mode,ignoreMode,returnInformations);
+}
+
+/** open with specific copy engine
+\param move Copy or move
+\param ignoreMode if need ignore the mode
+\param protocolsUsedForTheSources protocols used for sources
+\param protocolsUsedForTheDestination protocols used for destination
+*/
+int Core::openNewCopyEngineInstance(const Ultracopier::CopyMode &mode,const bool &ignoreMode,const std::string &name)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, mode: "+std::to_string(mode)+", name: "+name);
+ CopyEngineManager::returnCopyEngine returnInformations=copyEngineList->getCopyEngine(mode,name);
+ if(returnInformations.engine==NULL)
+ return -1;
+ return connectCopyEngine(mode,ignoreMode,returnInformations);
+}
+
+/** Connect the copy engine instance provided previously to the management */
+int Core::connectCopyEngine(const Ultracopier::CopyMode &mode,bool ignoreMode,const CopyEngineManager::returnCopyEngine &returnInformations)
+{
+ if(returnInformations.canDoOnlyCopy)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Mode force for unknow reason");
+ ignoreMode=false;//force mode if need, normaly not used
+ }
+ CopyInstance newItem;
+ newItem.engine=returnInformations.engine;
+ if(newItem.engine!=NULL)
+ {
+ PluginInterface_Themes *theme=ThemesManager::themesManager->getThemesInstance();
+ if(theme!=NULL)
+ {
+ newItem.id=incrementId();
+ newItem.lastProgression=0;
+ newItem.interface=theme;
+ newItem.ignoreMode=ignoreMode;
+ newItem.mode=mode;
+ newItem.type=returnInformations.type;
+ newItem.transferListOperation=returnInformations.transferListOperation;
+ newItem.numberOfFile=0;
+ newItem.numberOfTransferedFile=0;
+ newItem.currentProgression=0;
+ newItem.totalProgression=0;
+ newItem.action=Ultracopier::Idle;
+ newItem.lastProgression=0;//store the real byte transfered, used in time remaining calculation
+ newItem.isPaused=false;
+ newItem.isRunning=false;
+ newItem.haveError=false;
+ newItem.lastConditionalSync.start();
+ newItem.nextConditionalSync=new QTimer();
+ newItem.nextConditionalSync->setSingleShot(true);
+ newItem.copyEngineIsSync=true;
+ newItem.canceled=false;
+
+ switch(stringtoint32(OptionEngine::optionEngine->getOptionValue("Ultracopier","remainingTimeAlgorithm")))
+ {
+ default:
+ case 0:
+ newItem.remainingTimeAlgo=Ultracopier::RemainingTimeAlgo_Traditional;
+ break;
+ case 1:
+ newItem.remainingTimeAlgo=Ultracopier::RemainingTimeAlgo_Logarithmic;
+ {
+ int index=0;
+ while(index<ULTRACOPIER_MAXREMAININGTIMECOL)
+ {
+ RemainingTimeLogarithmicColumn remainingTimeLogarithmicColumn;
+ remainingTimeLogarithmicColumn.totalSize=0;
+ remainingTimeLogarithmicColumn.transferedSize=0;
+ newItem.remainingTimeLogarithmicValue.push_back(remainingTimeLogarithmicColumn);
+ index++;
+ }
+ }
+ break;
+ }
+
+ if(!ignoreMode)
+ {
+ newItem.interface->forceCopyMode(mode);
+ newItem.engine->forceMode(mode);
+ }
+ if(copyList.size()==0)
+ forUpateInformation.start();
+ copyList.push_back(newItem);
+ connectEngine(static_cast<unsigned int>(copyList.size()-1));
+ connectInterfaceAndSync(static_cast<unsigned int>(copyList.size()-1));
+ return static_cast<int>(newItem.id);
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to load the interface, copy aborted");
+ delete newItem.engine;
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to load the interface, copy aborted"));
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to load the copy engine, copy aborted");
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to load the copy engine, copy aborted"));
+ }
+ return -1;
+}
+
+void Core::resetSpeedDetectedEngine()
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ resetSpeedDetected(static_cast<unsigned int>(index));
+}
+
+void Core::resetSpeedDetectedInterface()
+{
+ int index=indexCopySenderInterface();
+ if(index!=-1)
+ resetSpeedDetected(static_cast<unsigned int>(index));
+}
+
+void Core::resetSpeedDetected(const unsigned int &bindex)
+{
+ const size_t &index=bindex;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start on "+std::to_string(index));
+ switch(copyList.at(index).remainingTimeAlgo)
+ {
+ case Ultracopier::RemainingTimeAlgo_Logarithmic:
+ {
+ size_t sub_index=0;
+ while(sub_index<ULTRACOPIER_MAXREMAININGTIMECOL)
+ {
+ copyList[index].remainingTimeLogarithmicValue[sub_index].lastProgressionSpeed.clear();
+ copyList[index].remainingTimeLogarithmicValue[sub_index].totalSize=0;
+ copyList[index].remainingTimeLogarithmicValue[sub_index].transferedSize=0;
+ sub_index++;
+ }
+ }
+ break;
+ default:
+ case Ultracopier::RemainingTimeAlgo_Traditional:
+ copyList[index].lastSpeedDetected.clear();
+ copyList[index].lastSpeedTime.clear();
+ copyList[index].lastAverageSpeedDetected.clear();
+ copyList[index].lastAverageSpeedTime.clear();
+ break;
+ }
+}
+
+void Core::doneTime(const std::vector<std::pair<uint64_t,uint32_t> > &timeList)
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ CopyInstance &copyInstance=copyList[index];
+ switch(copyInstance.remainingTimeAlgo)
+ {
+ case Ultracopier::RemainingTimeAlgo_Logarithmic:
+ if(copyInstance.remainingTimeLogarithmicValue.size()<ULTRACOPIER_MAXREMAININGTIMECOL)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"bug, copyInstance.remainingTimeLogarithmicValue.size() "+std::to_string(copyInstance.remainingTimeLogarithmicValue.size())+" <ULTRACOPIER_MAXREMAININGTIMECOL");
+ else
+ {
+ unsigned int sub_index=0;
+ while(sub_index<timeList.size())
+ {
+ const std::pair<uint64_t,uint32_t> &timeUnit=timeList.at(sub_index);
+ const uint8_t &col=fileCatNumber(timeUnit.first);
+ RemainingTimeLogarithmicColumn &remainingTimeLogarithmicColumn=copyInstance.remainingTimeLogarithmicValue[col];
+ if(copyInstance.remainingTimeLogarithmicValue.size()<=col)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"bug, copyInstance.remainingTimeLogarithmicValue.size() "+std::to_string(copyInstance.remainingTimeLogarithmicValue.size())+" < col %2"+std::to_string(col));
+ break;
+ }
+ else
+ {
+ if(timeUnit.second>0)
+ {
+ remainingTimeLogarithmicColumn.lastProgressionSpeed.push_back(static_cast<unsigned int>(timeUnit.first/timeUnit.second));
+ if(remainingTimeLogarithmicColumn.lastProgressionSpeed.size()>ULTRACOPIER_MAXVALUESPEEDSTORED)
+ remainingTimeLogarithmicColumn.lastProgressionSpeed.pop_back();
+ }
+ }
+ sub_index++;
+ }
+ }
+ break;
+ default:
+ case Ultracopier::RemainingTimeAlgo_Traditional:
+ break;
+ }
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the interface sender");
+}
+
+void Core::actionInProgess(const Ultracopier::EngineActionInProgress &action)
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"action: "+std::to_string(action)+", from "+std::to_string(index));
+ //drop here the duplicate action
+ if(copyList.at(index).action==action)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"The copy engine have send 2x the same EngineActionInProgress");
+ return;
+ }
+ //update time runing for time remaning caculation
+ if(action==Ultracopier::Copying || action==Ultracopier::CopyingAndListing)
+ {
+ if(!copyList.at(index).isRunning)
+ copyList[index].isRunning=true;
+ }
+ else
+ {
+ if(copyList.at(index).isRunning)
+ copyList[index].isRunning=false;
+ }
+ //do sync
+ periodicSynchronizationWithIndex(index);
+ copyList[index].action=action;
+ if(copyList.at(index).interface!=NULL)
+ copyList.at(index).interface->actionInProgess(action);
+ if(action==Ultracopier::Idle)
+ {
+ unsigned int index_sub_loop=0;
+ while(index_sub_loop<copyList.at(index).orderId.size())
+ {
+ emit copyCanceled(copyList.at(index).orderId.at(index_sub_loop));
+ index_sub_loop++;
+ }
+ copyList[index].orderId.clear();
+ resetSpeedDetected(index);
+ }
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the interface sender");
+}
+
+void Core::newFolderListing(const std::string &path)
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ copyList[index].folderListing=path;
+ copyList.at(index).interface->newFolderListing(path);
+ }
+}
+
+void Core::isInPause(const bool &isPaused)
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ if(!isPaused)
+ resetSpeedDetected(index);
+ copyList[index].isPaused=isPaused;
+ copyList.at(index).interface->isInPause(isPaused);
+ }
+}
+
+/// \brief get the right copy instance (copy engine + interface), by signal emited from copy engine
+int Core::indexCopySenderCopyEngine()
+{
+ const QObject * senderObject=sender();
+ if(senderObject==NULL)
+ {
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Qt sender() NULL");
+ return -1;
+ }
+ unsigned int index=0;
+ while(index<copyList.size())
+ {
+ if(copyList.at(index).engine==senderObject)
+ return index;
+ index++;
+ }
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Sender not located in the list");
+ return -1;
+}
+
+/// \brief get the right copy instance (copy engine + interface), by signal emited from interface
+int Core::indexCopySenderInterface()
+{
+ QObject * senderObject=sender();
+ if(senderObject==NULL)
+ {
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Qt sender() NULL");
+ return -1;
+ }
+ unsigned int index=0;
+ while(index<copyList.size())
+ {
+ if(copyList.at(index).interface==senderObject)
+ return index;
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to locate QObject * sender");
+ PluginInterface_Themes * interface = qobject_cast<PluginInterface_Themes *>(senderObject);
+ if(interface==NULL)
+ {
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Qt sender themes NULL");
+ return -1;
+ }
+ index=0;
+ while(index<copyList.size())
+ {
+ if(copyList.at(index).interface==interface)
+ return index;
+ index++;
+ }
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Sender not located in the list");
+ return -1;
+}
+
+void Core::connectEngine(const unsigned int &index)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start with index: "+std::to_string(index)+": "+std::to_string((uint64_t)sender()));
+ //disconnectEngine(index);
+
+ CopyInstance& currentCopyInstance=copyList[index];
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::newFolderListing, this,&Core::newFolderListing,Qt::QueuedConnection))//to check to change
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for newFolderListing()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::actionInProgess, this,&Core::actionInProgess,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for actionInProgess()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::isInPause, this,&Core::isInPause,Qt::QueuedConnection))//to check to change
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for isInPause()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::cancelAll, this,&Core::copyInstanceCanceledByEngine,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for cancelAll()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::error, this,&Core::error,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for error()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::rmPath, this,&Core::rmPath,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for rmPath()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::mkPath, this,&Core::mkPath,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for mkPath()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::syncReady, this,&Core::syncReady,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for syncReady()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::canBeDeleted, this,&Core::deleteCopyEngine,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for syncReady()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::doneTime, this,&Core::doneTime,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the engine can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for doneTime()");
+}
+
+void Core::connectInterfaceAndSync(const unsigned int &index)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start with index: "+std::to_string(index)+": "+std::to_string((uint64_t)sender()));
+ //disconnectInterface(index);
+
+ CopyInstance& currentCopyInstance=copyList[index];
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::pause, currentCopyInstance.engine,&PluginInterface_CopyEngine::pause))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for pause()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::resume, currentCopyInstance.engine,&PluginInterface_CopyEngine::resume))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for resume()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::skip, currentCopyInstance.engine,&PluginInterface_CopyEngine::skip))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for skip()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::newSpeedLimitation, currentCopyInstance.engine,&PluginInterface_CopyEngine::setSpeedLimitation))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for newSpeedLimitation()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::userAddFolder, currentCopyInstance.engine,&PluginInterface_CopyEngine::userAddFolder))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for userAddFolder()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::userAddFile, currentCopyInstance.engine,&PluginInterface_CopyEngine::userAddFile))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for userAddFile()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::removeItems, currentCopyInstance.engine,&PluginInterface_CopyEngine::removeItems))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for removeItems()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::moveItemsOnTop, currentCopyInstance.engine,&PluginInterface_CopyEngine::moveItemsOnTop))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for moveItemsOnTop()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::moveItemsUp, currentCopyInstance.engine,&PluginInterface_CopyEngine::moveItemsUp))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for moveItemsUp()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::moveItemsDown, currentCopyInstance.engine,&PluginInterface_CopyEngine::moveItemsDown))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for moveItemsDown()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::moveItemsOnBottom, currentCopyInstance.engine,&PluginInterface_CopyEngine::moveItemsOnBottom))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for moveItemsOnBottom()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::exportTransferList, currentCopyInstance.engine,&PluginInterface_CopyEngine::exportTransferList))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for exportTransferList()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::exportErrorIntoTransferList, currentCopyInstance.engine,&PluginInterface_CopyEngine::exportErrorIntoTransferList))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for exportErrorIntoTransferList()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::importTransferList, currentCopyInstance.engine,&PluginInterface_CopyEngine::importTransferList))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for importTransferList()");
+
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::newSpeedLimitation, this,&Core::resetSpeedDetectedInterface))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for newSpeedLimitation()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::resume, this,&Core::resetSpeedDetectedInterface))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for resume()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::cancel, this,&Core::copyInstanceCanceledByInterface,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for cancel()");
+ if(!connect(currentCopyInstance.interface,&PluginInterface_Themes::urlDropped, this,&Core::urlDropped,Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for urlDropped()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::newActionOnList,this,&Core::getActionOnList, Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for newActionOnList()");
+
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::pushFileProgression, currentCopyInstance.interface,&PluginInterface_Themes::setFileProgression, Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for pushFileProgression()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::pushGeneralProgression, currentCopyInstance.interface,&PluginInterface_Themes::setGeneralProgression, Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for pushGeneralProgression()");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::pushGeneralProgression, this,&Core::pushGeneralProgression, Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for pushGeneralProgression() for this");
+ if(!connect(currentCopyInstance.engine,&PluginInterface_CopyEngine::errorToRetry, currentCopyInstance.interface,&PluginInterface_Themes::errorToRetry, Qt::QueuedConnection))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"error at connect, the interface can not work correctly: "+std::to_string(index)+": "+std::to_string((uint64_t)sender())+" for errorToRetry() for this");
+
+ currentCopyInstance.interface->setSupportSpeedLimitation(currentCopyInstance.engine->supportSpeedLimitation());
+ currentCopyInstance.interface->setCopyType(currentCopyInstance.type);
+ currentCopyInstance.interface->setTransferListOperation(currentCopyInstance.transferListOperation);
+ currentCopyInstance.interface->actionInProgess(currentCopyInstance.action);
+ currentCopyInstance.interface->isInPause(currentCopyInstance.isPaused);
+ if(currentCopyInstance.haveError)
+ currentCopyInstance.interface->errorDetected();
+ QWidget *tempWidget=currentCopyInstance.interface->getOptionsEngineWidget();
+ if(tempWidget!=NULL)
+ currentCopyInstance.interface->getOptionsEngineEnabled(currentCopyInstance.engine->getOptionsEngine(tempWidget));
+ //important, to have the modal dialog
+ currentCopyInstance.engine->setInterfacePointer(currentCopyInstance.interface);
+
+ //put entry into the interface
+ currentCopyInstance.engine->syncTransferList();
+
+ //force the updating, without wait the timer
+ periodicSynchronizationWithIndex(index);
+}
+
+void Core::periodicSynchronization()
+{
+ unsigned int index_sub_loop=0;
+ while(index_sub_loop<copyList.size())
+ {
+ if(copyList.at(index_sub_loop).action==Ultracopier::Copying || copyList.at(index_sub_loop).action==Ultracopier::CopyingAndListing)
+ periodicSynchronizationWithIndex(index_sub_loop);
+ index_sub_loop++;
+ }
+}
+
+void Core::periodicSynchronizationWithIndex(const int &index)
+{
+ CopyInstance& currentCopyInstance=copyList[index];
+ if(currentCopyInstance.engine==NULL || currentCopyInstance.interface==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"some thread is null");
+ return;
+ }
+
+ /** ***************** Do time calcul ******************* **/
+ if(!currentCopyInstance.isPaused)
+ {
+ //calcul the last difference of the transfere
+ realByteTransfered=currentCopyInstance.engine->realByteTransfered();
+ quint64 diffCopiedSize=0;
+ if(realByteTransfered>=currentCopyInstance.lastProgression)
+ diffCopiedSize=realByteTransfered-currentCopyInstance.lastProgression;
+ currentCopyInstance.lastProgression=realByteTransfered;
+
+ // algo 1:
+ // ((double)currentProgression)/totalProgression -> example: done 80% -> 0.8
+ // baseTime+runningTime -> example: done into 80s, remaining time: 80/0.8-80=80*(1/0.8-1)=20s
+ // algo 2 (not used):
+ // remaining byte/current speed
+
+ //remaining time: (total byte - lastProgression)/byte per ms since the start
+ /*if(currentCopyInstance.totalProgression==0 || currentCopyInstance.currentProgression==0)
+ currentCopyInstance.interface->remainingTime(-1);
+ else if((currentCopyInstance.totalProgression-currentCopyInstance.currentProgression)>1024)
+ currentCopyInstance.interface->remainingTime(transferAddedTime*((double)currentCopyInstance.totalProgression/(double)currentCopyInstance.currentProgression-1)/1000);*/
+
+ //do the speed calculation
+ if(lastProgressionTime.isNull())
+ lastProgressionTime.start();
+ else
+ {
+ if((currentCopyInstance.action==Ultracopier::Copying || currentCopyInstance.action==Ultracopier::CopyingAndListing))
+ {
+ currentCopyInstance.lastSpeedTime.push_back(lastProgressionTime.elapsed());
+ currentCopyInstance.lastSpeedDetected.push_back(diffCopiedSize);
+ currentCopyInstance.lastAverageSpeedTime.push_back(lastProgressionTime.elapsed());
+ currentCopyInstance.lastAverageSpeedDetected.push_back(diffCopiedSize);
+ while(currentCopyInstance.lastSpeedTime.size()>ULTRACOPIER_MAXVALUESPEEDSTORED)
+ currentCopyInstance.lastSpeedTime.erase(currentCopyInstance.lastSpeedTime.cbegin());
+ while(currentCopyInstance.lastSpeedDetected.size()>ULTRACOPIER_MAXVALUESPEEDSTORED)
+ currentCopyInstance.lastSpeedDetected.erase(currentCopyInstance.lastSpeedDetected.cbegin());
+ while(currentCopyInstance.lastAverageSpeedTime.size()>ULTRACOPIER_MAXVALUESPEEDSTOREDTOREMAININGTIME)
+ currentCopyInstance.lastAverageSpeedTime.erase(currentCopyInstance.lastAverageSpeedTime.cbegin());
+ while(currentCopyInstance.lastAverageSpeedDetected.size()>ULTRACOPIER_MAXVALUESPEEDSTOREDTOREMAININGTIME)
+ currentCopyInstance.lastAverageSpeedDetected.erase(currentCopyInstance.lastAverageSpeedDetected.cbegin());
+ double totTime=0,totAverageTime=0;
+ double totSpeed=0,totAverageSpeed=0;
+
+ //current speed
+ unsigned int index_sub_loop=0;
+ while(index_sub_loop<currentCopyInstance.lastSpeedDetected.size())
+ {
+ totTime+=currentCopyInstance.lastSpeedTime.at(index_sub_loop);
+ totSpeed+=currentCopyInstance.lastSpeedDetected.at(index_sub_loop);
+ index_sub_loop++;
+ }
+ totTime/=1000;
+
+ //speed to calculate the remaining time
+ index_sub_loop=0;
+ while(index_sub_loop<currentCopyInstance.lastAverageSpeedDetected.size())
+ {
+ totAverageTime+=currentCopyInstance.lastAverageSpeedTime.at(index_sub_loop);
+ totAverageSpeed+=currentCopyInstance.lastAverageSpeedDetected.at(index_sub_loop);
+ index_sub_loop++;
+ }
+ totAverageTime/=1000;
+
+ if(totTime>0)
+ if(currentCopyInstance.lastAverageSpeedDetected.size()>=ULTRACOPIER_MINVALUESPEED)
+ currentCopyInstance.interface->detectedSpeed(totSpeed/totTime);
+
+ if(totAverageTime>0)
+ if(currentCopyInstance.lastAverageSpeedDetected.size()>=ULTRACOPIER_MINVALUESPEEDTOREMAININGTIME)
+ {
+ if(currentCopyInstance.remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Traditional)
+ {
+ if(totSpeed>0)
+ {
+ //remaining time: (total byte - lastProgression)/byte per ms since the start
+ if(currentCopyInstance.totalProgression==0 || currentCopyInstance.currentProgression==0)
+ currentCopyInstance.interface->remainingTime(-1);
+ else if((currentCopyInstance.totalProgression-currentCopyInstance.currentProgression)>1024)
+ currentCopyInstance.interface->remainingTime((currentCopyInstance.totalProgression-currentCopyInstance.currentProgression)/(totAverageSpeed/totAverageTime));
+ }
+ else
+ currentCopyInstance.interface->remainingTime(-1);
+ }
+ else if(currentCopyInstance.remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ int remainingTimeValue=0;
+ //calculate for each file class
+ index_sub_loop=0;
+ while(index_sub_loop<currentCopyInstance.remainingTimeLogarithmicValue.size())
+ {
+ const RemainingTimeLogarithmicColumn &remainingTimeLogarithmicColumn=currentCopyInstance.remainingTimeLogarithmicValue.at(index_sub_loop);
+ //normal detect
+ const quint64 &remainingSize=remainingTimeLogarithmicColumn.totalSize-remainingTimeLogarithmicColumn.transferedSize;
+ if(remainingTimeLogarithmicColumn.lastProgressionSpeed.size()>=ULTRACOPIER_MINVALUESPEED)
+ {
+ int average_speed=0;
+ unsigned int temp_loop_index=0;
+ while(temp_loop_index<remainingTimeLogarithmicColumn.lastProgressionSpeed.size())
+ {
+ average_speed+=remainingTimeLogarithmicColumn.lastProgressionSpeed.at(temp_loop_index);
+ temp_loop_index++;
+ }
+ average_speed/=remainingTimeLogarithmicColumn.lastProgressionSpeed.size();
+ remainingTimeValue+=remainingSize/average_speed;
+ }
+ //fallback
+ else
+ {
+ if(totSpeed>0)
+ {
+ //remaining time: (total byte - lastProgression)/byte per ms since the start
+ if(currentCopyInstance.totalProgression==0 || currentCopyInstance.currentProgression==0)
+ remainingTimeValue+=1;
+ else if((currentCopyInstance.totalProgression-currentCopyInstance.currentProgression)>1024)
+ remainingTimeValue+=remainingSize/totAverageSpeed;
+ }
+ else
+ remainingTimeValue+=1;
+ }
+ index_sub_loop++;
+ }
+ currentCopyInstance.interface->remainingTime(remainingTimeValue);
+ }
+ else
+ {}//error case
+ }
+ }
+ lastProgressionTime.restart();
+ }
+ }
+}
+
+uint8_t Core::fileCatNumber(uint64_t size)
+{
+ //all is in base 10 to understand more easily
+ //drop the big value
+ if(size>ULTRACOPIER_REMAININGTIME_BIGFILEMEGABYTEBASE10*1000*1000)
+ size=ULTRACOPIER_REMAININGTIME_BIGFILEMEGABYTEBASE10*1000*1000;
+ size=size/100;//to group all the too small file into the value 0
+ return log10(size);
+}
+
+/// \brief the copy engine have canceled the transfer
+void Core::copyInstanceCanceledByEngine()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ copyInstanceCanceledByIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
+
+/// \brief the interface have canceled the transfer
+void Core::copyInstanceCanceledByInterface()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ int index=indexCopySenderInterface();
+ if(index!=-1)
+ copyInstanceCanceledByIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
+
+/// \brief the transfer have been canceled
+void Core::copyInstanceCanceledByIndex(const unsigned int &index)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, remove with the index: "+std::to_string(index));
+ //disconnectEngine(index);
+ //disconnectInterface(index);
+ copyList[index].canceled=true;
+ CopyInstance& currentCopyInstance=copyList[index];
+ currentCopyInstance.engine->cancel();
+ delete currentCopyInstance.nextConditionalSync;
+ delete currentCopyInstance.interface;
+ unsigned int index_sub_loop=0;
+ while(index_sub_loop<currentCopyInstance.orderId.size())
+ {
+ emit copyCanceled(currentCopyInstance.orderId.at(index_sub_loop));
+ index_sub_loop++;
+ }
+ currentCopyInstance.orderId.clear();
+ copyList.erase(copyList.cbegin()+index);
+ if(copyList.size()==0)
+ forUpateInformation.stop();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"copyList.size(): "+std::to_string(copyList.size()));
+}
+
+/// \brief only when the copy engine say it's ready to delete them self, it call this
+void Core::deleteCopyEngine()
+{
+ QObject * senderObject=sender();
+ if(senderObject==NULL)
+ {
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Qt sender() NULL");
+ return;
+ }
+ PluginInterface_CopyEngine * copyEngine = static_cast<PluginInterface_CopyEngine *>(senderObject);
+ if(copyEngine==NULL)
+ {
+ //QMessageBox::critical(NULL,tr("Internal error"),tr("A communication error occured between the interface and the copy plugin. Please report this bug."));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Qt sender() NULL");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, delete the copy engine");
+ delete copyEngine;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"stop, delete the copy engine");
+}
+
+//error occurred
+void Core::error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error)
+{
+ log.error(path,size,mtime,error);
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ copyList[index].haveError=true;
+ copyList.at(index).interface->errorDetected();
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
+
+//for the extra logging
+void Core::rmPath(const std::string &path)
+{
+ log.rmPath(path);
+}
+
+void Core::mkPath(const std::string &path)
+{
+ log.mkPath(path);
+}
+
+/// \brief to rsync after a new interface connection
+void Core::syncReady()
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ copyList[index].copyEngineIsSync=true;
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
+
+void Core::getActionOnList(const std::vector<Ultracopier::ReturnActionOnCopyList> &actionList)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ //send the the interface
+ const int &index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start2");
+ if(copyList.at(index).copyEngineIsSync)
+ copyList.at(index).interface->getActionOnList(actionList);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start3");
+ //log to the file and compute the remaining time
+ if(log.logTransfer() || copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start4");
+ unsigned int sub_index=0;
+ if(log.logTransfer() && copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start5");
+ while(sub_index<actionList.size())
+ {
+ const Ultracopier::ReturnActionOnCopyList &returnAction=actionList.at(sub_index);
+ switch(returnAction.type)
+ {
+ case Ultracopier::PreOperation:
+ log.newTransferStart(returnAction.addAction);
+ break;
+ case Ultracopier::RemoveItem:
+ if(returnAction.userAction.moveAt==0)
+ log.newTransferStop(returnAction.addAction);
+ else
+ log.transferSkip(returnAction.addAction);
+ if(copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ const quint8 &col=fileCatNumber(returnAction.addAction.size);
+ copyList[index].remainingTimeLogarithmicValue[col].transferedSize+=returnAction.addAction.size;
+ }
+ break;
+ case Ultracopier::AddingItem:
+ if(copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ const quint8 &col=fileCatNumber(returnAction.addAction.size);
+ copyList[index].remainingTimeLogarithmicValue[col].totalSize+=returnAction.addAction.size;
+ }
+ break;
+ default:
+ break;
+ }
+ sub_index++;
+ }
+ }
+ else if(log.logTransfer())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start6");
+ while(sub_index<actionList.size())
+ {
+ const Ultracopier::ReturnActionOnCopyList &returnAction=actionList.at(sub_index);
+ switch(returnAction.type)
+ {
+ case Ultracopier::PreOperation:
+ log.newTransferStart(returnAction.addAction);
+ break;
+ case Ultracopier::RemoveItem:
+ if(returnAction.userAction.moveAt==0)
+ log.newTransferStop(returnAction.addAction);
+ else
+ log.transferSkip(returnAction.addAction);
+ if(copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ const quint8 &col=fileCatNumber(returnAction.addAction.size);
+ copyList[index].remainingTimeLogarithmicValue[col].transferedSize+=returnAction.addAction.size;
+ }
+ break;
+ default:
+ break;
+ }
+ sub_index++;
+ }
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start7");
+ while(sub_index<actionList.size())
+ {
+ const Ultracopier::ReturnActionOnCopyList &returnAction=actionList.at(sub_index);
+ switch(returnAction.type)
+ {
+ case Ultracopier::RemoveItem:
+ if(copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ const quint8 &col=fileCatNumber(returnAction.addAction.size);
+ copyList[index].remainingTimeLogarithmicValue[col].transferedSize+=returnAction.addAction.size;
+ }
+ break;
+ case Ultracopier::AddingItem:
+ if(copyList.at(index).remainingTimeAlgo==Ultracopier::RemainingTimeAlgo_Logarithmic)
+ {
+ const quint8 &col=fileCatNumber(returnAction.addAction.size);
+ copyList[index].remainingTimeLogarithmicValue[col].totalSize+=returnAction.addAction.size;
+ }
+ break;
+ default:
+ break;
+ }
+ sub_index++;
+ }
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start8");
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start9");
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start end");
+}
+
+void Core::pushGeneralProgression(const uint64_t &current,const uint64_t &total)
+{
+ int index=indexCopySenderCopyEngine();
+ if(index!=-1)
+ {
+ copyList[index].currentProgression=current;
+ copyList[index].totalProgression=total;
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
+
+/// \brief used to drag and drop files
+void Core::urlDropped(const std::vector<std::string> &urls)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ int bindex=indexCopySenderInterface();
+ if(bindex!=-1)
+ {
+ const unsigned int &index=static_cast<unsigned int>(bindex);
+ std::vector<std::string> sources;
+ unsigned int index_loop=0;
+ while(index_loop<urls.size())
+ {
+ if(!urls.at(index_loop).empty())
+ sources.push_back(urls.at(index_loop));
+ index_loop++;
+ }
+ if(sources.size()==0)
+ return;
+ else
+ {
+ if(copyList.at(index).ignoreMode)
+ {
+ QMessageBox::StandardButton reply=QMessageBox::question(copyList.at(index).interface,tr("Transfer mode"),tr("Do you want to copy? If no, it will be moved."),QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,QMessageBox::Cancel);
+ if(reply==QMessageBox::Yes)
+ copyList.at(index).engine->newCopy(sources);
+ if(reply==QMessageBox::No)
+ copyList.at(index).engine->newMove(sources);
+ }
+ else
+ {
+ if(copyList.at(index).mode==Ultracopier::Copy)
+ copyList.at(index).engine->newCopy(sources);
+ else
+ copyList.at(index).engine->newMove(sources);
+ }
+ }
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to locate the copy engine sender");
+}
diff --git a/Core.h b/Core.h
new file mode 100644
index 0000000..cd8733e
--- /dev/null
+++ b/Core.h
@@ -0,0 +1,197 @@
+/** \file Core.h
+\brief Define the class definition for core, the Copy of each copy/move window
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef CORE_H
+#define CORE_H
+
+#include <QObject>
+#include <QStringList>
+#include <QString>
+#include <QList>
+#include <QTimer>
+#include <QTime>
+#include <QFile>
+#include <QUrl>
+
+#include "Environment.h"
+#include "StructEnumDefinition.h"
+#include "CopyEngineManager.h"
+#include "LogThread.h"
+#include "interface/PluginInterface_CopyEngine.h"
+#include "interface/PluginInterface_Themes.h"
+
+/** \brief Define the class definition for core, the Copy of each copy/move window
+
+This class provide a core for dispatch the event of signal/slot, it checks too if not other instance is running */
+class Core : public QObject
+{
+ Q_OBJECT
+ public:
+ /// \brief Initate the core of one copy or move window, dispatch the event specific at this window
+ Core(CopyEngineManager *copyEngineList);
+ ~Core();
+ private:
+ CopyEngineManager *copyEngineList;
+ struct RunningTransfer
+ {
+ Ultracopier::ItemOfCopyList item;
+ bool progression;
+ };
+ struct RemainingTimeLogarithmicColumn
+ {
+ std::vector<int> lastProgressionSpeed;
+ uint64_t totalSize;
+ uint64_t transferedSize;
+ };
+
+ struct CopyInstance
+ {
+ unsigned int id;
+ PluginInterface_CopyEngine * engine;
+ PluginInterface_Themes * interface;
+ bool ignoreMode;
+ Ultracopier::CopyMode mode;
+ uint64_t numberOfFile;
+ uint64_t numberOfTransferedFile;
+ uint64_t currentProgression,totalProgression;//store the file byte transfered, used into the remaining time
+ Ultracopier::EngineActionInProgress action;
+ uint64_t lastProgression;//store the real byte transfered, used in speed calculation
+ std::vector<RunningTransfer> transferItemList;//full info of started item, to have wich progression to poll
+ std::vector<uint32_t> orderId;//external order send via listener plugin
+ std::string folderListing;
+ std::string collisionAction;
+ std::string errorAction;
+ bool isPaused;
+ bool isRunning;
+ Ultracopier::CopyType type;
+ Ultracopier::TransferListOperation transferListOperation;
+ bool haveError;
+ QTime lastConditionalSync;
+ QTimer *nextConditionalSync;
+ bool copyEngineIsSync;
+ bool canceled;//to not try groun when is in canceling
+
+ Ultracopier::RemainingTimeAlgo remainingTimeAlgo;
+
+ /** for RemainingTimeAlgo_Traditional **/
+ //this speed is for instant speed
+ std::vector<uint64_t> lastSpeedDetected;//stored in bytes
+ std::vector<double> lastSpeedTime;//stored in ms
+ //this speed is average speed on more time to calculate the remaining time
+ std::vector<uint64_t> lastAverageSpeedDetected;//stored in bytes
+ std::vector<double> lastAverageSpeedTime;//stored in ms
+
+ /** for RemainingTimeAlgo_Logarithmic **/
+ std::vector<RemainingTimeLogarithmicColumn> remainingTimeLogarithmicValue;
+ };
+ std::vector<CopyInstance> copyList;
+ /** open with specific source/destination
+ \param move Copy or move
+ \param ignoreMode if need ignore the mode
+ \param protocolsUsedForTheSources protocols used for sources
+ \param protocolsUsedForTheDestination protocols used for destination
+ */
+ int openNewCopyEngineInstance(const Ultracopier::CopyMode &mode,const bool &ignoreMode,const std::vector<std::string> &protocolsUsedForTheSources=std::vector<std::string>(),const std::string &protocolsUsedForTheDestination="");
+ /** open with specific copy engine
+ \param move Copy or move
+ \param ignoreMode if need ignore the mode
+ \param name protocols used for sources
+ */
+ int openNewCopyEngineInstance(const Ultracopier::CopyMode &mode,const bool &ignoreMode,const std::string &name);
+
+ /// \brief get the right copy instance (copy engine + interface), by signal emited from copy engine
+ int indexCopySenderCopyEngine();
+ /// \brief get the right copy instance (copy engine + interface), by signal emited from interface
+ int indexCopySenderInterface();
+
+ void connectEngine(const unsigned int &index);
+ void connectInterfaceAndSync(const unsigned int &index);
+ //void disconnectEngine(const int &index);
+ //void disconnectInterface(const int &index);
+
+ /** \brief update at periodic interval, the synchronization between copy engine and interface, but for specific entry
+ \see forUpateInformation */
+ void periodicSynchronizationWithIndex(const int &index);
+
+ //for the internal management
+ unsigned int incrementId();
+ unsigned int nextId;
+ std::vector<unsigned int> idList;
+ QTime lastProgressionTime;
+ QTimer forUpateInformation;///< used to call \see periodicSynchronization()
+ void resetSpeedDetected(const unsigned int &bindex);
+
+ /** Connect the copy engine instance provided previously to the management */
+ int connectCopyEngine(const Ultracopier::CopyMode &mode,bool ignoreMode,const CopyEngineManager::returnCopyEngine &returnInformations);
+
+ LogThread log;///< To save the log like mkpath, rmpath, error, copy, ...
+ uint64_t realByteTransfered;
+
+ static uint8_t fileCatNumber(uint64_t size);
+ signals:
+ void copyFinished(const uint32_t & orderId,bool withError) const;
+ void copyCanceled(const uint32_t & orderId) const;
+ public slots:
+ /** \brief do copy with sources, but ask the destination */
+ void newCopyWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources);
+ void newTransfer(const Ultracopier::CopyMode &mode,const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination);
+ /** \brief do copy with sources and destination */
+ void newCopy(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination);
+ /** \brief do move with sources, but ask the destination */
+ void newMoveWithoutDestination(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources);
+ /** \brief do move with sources and destination */
+ void newMove(const uint32_t &orderId,const std::vector<std::string> &protocolsUsedForTheSources,const std::vector<std::string> &sources,const std::string &protocolsUsedForTheDestination,const std::string &destination);
+ /** \brief open copy/move windows with specific engine */
+ void addWindowCopyMove(const Ultracopier::CopyMode &mode,const std::string &name);
+ /** \brief open transfer (copy+move) windows with specific engine */
+ void addWindowTransfer(const std::string &name);
+ /** new transfer list pased by the CLI */
+ void newTransferList(std::string engine,std::string mode,std::string file);
+
+ bool startNewTransferOneUniqueCopyEngine();
+ private slots:
+ /// \brief the copy engine have canceled the transfer
+ void copyInstanceCanceledByEngine();
+ /// \brief the interface have canceled the transfer
+ void copyInstanceCanceledByInterface();
+ /// \brief the transfer have been canceled
+ void copyInstanceCanceledByIndex(const unsigned int &index);
+ /// \brief only when the copy engine say it's ready to delete them self, it call this
+ void deleteCopyEngine();
+
+ // some stat update
+ void actionInProgess(const Ultracopier::EngineActionInProgress &action);
+ void newFolderListing(const std::string &path);
+ void isInPause(const bool&);
+
+ /** \brief update at periodic interval, the synchronization between copy engine and interface
+ \see forUpateInformation */
+ void periodicSynchronization();
+
+ //reset some information
+ void resetSpeedDetectedEngine();
+ void resetSpeedDetectedInterface();
+
+ //load the interface
+ void loadInterface();
+ void unloadInterface();
+
+ //error occurred
+ void error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error);
+ //for the extra logging
+ void rmPath(const std::string &path);
+ void mkPath(const std::string &path);
+
+ /// \brief used to drag and drop files
+ void urlDropped(const std::vector<std::string> &urls);
+ /// \brief to rsync after a new interface connection
+ void syncReady();
+ void doneTime(const std::vector<std::pair<uint64_t,uint32_t> > &timeList);
+
+ void getActionOnList(const std::vector<Ultracopier::ReturnActionOnCopyList> & actionList);
+ void pushGeneralProgression(const uint64_t &current,const uint64_t &total);
+};
+
+#endif // CORE_H
diff --git a/DebugEngine.cpp b/DebugEngine.cpp
new file mode 100644
index 0000000..2168210
--- /dev/null
+++ b/DebugEngine.cpp
@@ -0,0 +1,395 @@
+/** \file DebugEngine.cpp
+\brief Define the class for the debug
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QDir>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QLocalSocket>
+#include <regex>
+#include <iostream>
+
+#include "Variable.h"
+#include "DebugEngine.h"
+#include "ExtraSocket.h"
+#include "cpp11addition.h"
+
+#ifdef WIN32
+# define __func__ __FUNCTION__
+#endif
+
+/// \brief The local macro: ULTRACOPIER_DEBUGCONSOLE
+#if defined (__FILE__) && defined (__LINE__)
+# define ULTRACOPIER_DEBUGCONSOLE(a,b) addDebugInformation(a,__func__,b,__FILE__,__LINE__)
+#else
+# define ULTRACOPIER_DEBUGCONSOLE(a,b) addDebugInformation(a,__func__,b)
+#endif
+
+#ifdef ULTRACOPIER_DEBUG
+
+/// \brief initiate the ultracopier event dispatcher and check if no other session is running
+DebugEngine::DebugEngine()
+{
+ //fileNameCleaner=std::regex("\\.\\.?[/\\\\]([^/]+[/\\\\])?");
+ quit=false;
+ QStringList ultracopierArguments=QCoreApplication::arguments();
+ if(ultracopierArguments.size()==2)
+ if(ultracopierArguments.last()=="quit")
+ quit=true;
+ addDebugInformationCallNumber=0;
+ //Load the first content
+ debugHtmlContent+="<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
+ debugHtmlContent+="<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">";
+ debugHtmlContent+="<head>";
+ debugHtmlContent+="<meta name=\"Language\" content=\"en\" />";
+ debugHtmlContent+="<meta http-equiv=\"content-language\" content=\"english\" />";
+ debugHtmlContent+="<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />";
+ debugHtmlContent+="<style type=\"text/css\">";
+ debugHtmlContent+="body{font-family:\"DejaVu Sans Mono\";font-size:9pt;}";
+ debugHtmlContent+=".Information td{color:#7485df;}";
+ debugHtmlContent+=".Critical td{color:#ff0c00;background-color:#FFFE8C;}";
+ debugHtmlContent+=".Warning td{color:#efa200;}";
+ debugHtmlContent+=".Notice td{color:#999;}";
+ debugHtmlContent+=".time{font-weight:bold;}";
+ debugHtmlContent+=".Note{font-weight:bold;font-size:1.5em}";
+ debugHtmlContent+=".function{font-style:italic;text-decoration:underline}";
+ debugHtmlContent+=".location{padding-right:15px;}";
+ debugHtmlContent+="td {white-space:nowrap;}";
+ debugHtmlContent+="</style>";
+ debugHtmlContent+="<title>";
+ debugHtmlContent+="Ultracopier";
+ debugHtmlContent+=" "+std::string(ULTRACOPIER_VERSION)+" "+ULTRACOPIER_PLATFORM_NAME.toStdString()+", debug report</title>";
+ debugHtmlContent+="</head>";
+ debugHtmlContent+="<body>";
+ debugHtmlContent+="<table>";
+ //Load the start time at now
+ startTime.start();
+ //Load the log file end
+ endOfLogFile="</table></body></html>";
+ //check if other instance is running, then switch to memory backend
+ if(tryConnect())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_custom_Notice,"currentBackend: File because other session is runing");
+ currentBackend=Memory;
+ return;
+ }
+ //The lock and log file path is not defined
+ bool fileNameIsLoaded=false;
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ #ifdef ULTRACOPIER_VERSION_PORTABLEAPPS
+ //Load the data folder path
+ QDir dir(QCoreApplication::applicationDirPath());
+ dir.cdUp();
+ dir.cdUp();
+ dir.cd("Data");
+ logFile.setFileName(dir.absolutePath()+FacilityEngine::separator()+"log.html");
+ lockFile.setFileName(dir.absolutePath()+FacilityEngine::separator()+"ultracopier.lock");
+ fileNameIsLoaded=true;
+ #else
+ //Load the ultracopier path
+ QDir dir(QCoreApplication::applicationDirPath());
+ logFile.setFileName(dir.absolutePath()+FacilityEngine::separator()+"log.html");
+ lockFile.setFileName(dir.absolutePath()+FacilityEngine::separator()+"ultracopier.lock");
+ fileNameIsLoaded=true;
+ #endif
+ #else
+ #ifdef Q_OS_WIN32
+ #define EXTRA_HOME_PATH "\\ultracopier\\"
+ #else
+ #define EXTRA_HOME_PATH "/.config/Ultracopier/"
+ #endif
+ //Load the user path only if exists and writable
+ QDir dir(QDir::homePath()+EXTRA_HOME_PATH);
+ bool errorFound=false;
+ //If user's directory not exists create it
+ if(!dir.exists())
+ {
+ //If failed not load the file
+ if(!dir.mkpath(dir.absolutePath()))
+ {
+ errorFound=true;
+ puts(qPrintable("Unable to make path: "+dir.absolutePath()+", disable file log"));
+ }
+ }
+ //If no error found set the file name
+ if(errorFound==false)
+ {
+ fileNameIsLoaded=true;
+ logFile.setFileName(dir.absolutePath()+QDir::separator()+"log.html");
+ lockFile.setFileName(dir.absolutePath()+QDir::separator()+"ultracopier.lock");
+ }
+ //errorFound=false;
+ #endif
+ //If the file name is loaded
+ if(fileNameIsLoaded)
+ {
+ //If the previous file is here, then crash previous, ask if the user want to save
+ if(lockFile.exists() && logFile.exists() && !quit)
+ {
+ //Try open the file as read only to propose save it as the user
+ //Don't ask it if unable to write, because unable to remove, then alert at all start
+ if(removeTheLockFile())
+ {
+ //Ask to the user
+ QMessageBox::StandardButton reply = QMessageBox::question(NULL,"Save the previous report",
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ QString("Supercopier")+
+ #else
+ QString("Ultracopier")+
+ #endif
+ " seam have crashed, do you want save the previous report for report it to the forum?",QMessageBox::Yes|QMessageBox::No,QMessageBox::No);
+ if(reply==QMessageBox::Yes)
+ saveBugReport();
+ }
+ else
+ puts(qPrintable(logFile.fileName()+" unable to open it as read"));
+ }
+ //Now try to create and open the log file and lock file
+ if(!lockFile.open(QIODevice::WriteOnly|QIODevice::Truncate|QIODevice::Unbuffered))
+ {
+ currentBackend=Memory;
+ puts(qPrintable(lockFile.fileName()+" unable to open it as write, log into file disabled"));
+ }
+ else
+ {
+ if(!logFile.open(QIODevice::ReadWrite|QIODevice::Truncate|QIODevice::Unbuffered))
+ {
+ currentBackend=Memory;
+ puts(qPrintable(logFile.fileName()+" unable to open it as write, log into file disabled"));
+ removeTheLockFile();
+ }
+ else
+ {
+ logFile.resize(0);
+ currentBackend=File;
+ logFile.write(debugHtmlContent.data(),static_cast<qint64>(debugHtmlContent.size()));
+ }
+ }
+ }
+}
+
+/// \brief Destroy the ultracopier event dispatcher
+DebugEngine::~DebugEngine()
+{
+ if(currentBackend==File)
+ {
+ removeTheLockFile();
+ //Finalize the log file
+ logFile.write(endOfLogFile.data(),static_cast<qint64>(endOfLogFile.size()));
+ logFile.close();
+ }
+}
+
+/// \brief ask to the user where save the bug report
+void DebugEngine::saveBugReport()
+{
+ bool errorFound;
+ do
+ {
+ errorFound=false;
+ //Ask where it which save it
+ QString fileName = QFileDialog::getSaveFileName(NULL,"Save file","ultracopier-bug-report.log.html","Log file (*.log.html)");
+ if(fileName!="")
+ {
+ if(QFile::exists(fileName))
+ {
+ if(!QFile::remove(fileName))
+ {
+ errorFound=true;
+ puts(qPrintable(fileName+" unable remove it"));
+ QMessageBox::critical(NULL,"Error","Unable to save the bug report");
+ }
+ }
+ if(!errorFound)
+ {
+ //Open the destination as write
+ if(!logFile.copy(fileName))
+ {
+ errorFound=true;
+ puts(qPrintable(fileName+" unable to open it as write: "+logFile.errorString()));
+ QMessageBox::critical(NULL,"Error","Unable to save the bug report"+logFile.errorString());
+ }
+ }
+ }
+ } while(errorFound!=false);
+}
+
+/// \brief Internal function to remove the lock file
+bool DebugEngine::removeTheLockFile()
+{
+ //close the file and remove it
+ lockFile.close();
+ if(!lockFile.remove())
+ {
+ puts(qPrintable(lockFile.fileName()+" unable to remove it, crash report at the next start"));
+ return false;
+ }
+ else
+ return true;
+}
+
+void DebugEngine::addDebugInformationStatic(const Ultracopier::DebugLevel &level,const std::string& function,const std::string& text,const std::string& file,const int& ligne,const std::string& location)
+{
+ if(DebugEngine::debugEngine==NULL)
+ {
+ std::cerr << "After close: " << function << file << ligne;
+ return;
+ }
+ DebugLevel_custom tempLevel=DebugLevel_custom_Information;
+ switch(level)
+ {
+ case Ultracopier::DebugLevel_Information:
+ tempLevel=DebugLevel_custom_Information;
+ break;
+ case Ultracopier::DebugLevel_Critical:
+ tempLevel=DebugLevel_custom_Critical;
+ break;
+ case Ultracopier::DebugLevel_Warning:
+ tempLevel=DebugLevel_custom_Warning;
+ break;
+ case Ultracopier::DebugLevel_Notice:
+ tempLevel=DebugLevel_custom_Notice;
+ break;
+ default:
+ tempLevel=DebugLevel_custom_Notice;
+ }
+ DebugEngine::debugEngine->addDebugInformation(tempLevel,function,text,file,ligne,location);
+}
+
+void DebugEngine::addDebugNote(const std::string& text)
+{
+ if(DebugEngine::debugEngine==NULL)
+ return;
+ DebugEngine::debugEngine->addDebugInformation(DebugLevel_custom_UserNote,"",text,"",-1,"Core");
+}
+
+/// \brief For add message info, this function is thread safe
+void DebugEngine::addDebugInformation(const DebugLevel_custom &level,const std::string& function,const std::string& text,std::string file,const int& ligne,const std::string& location)
+{
+ if(DebugEngine::debugEngine==NULL)
+ {
+ std::cerr << "After close: " << function << file << ligne;
+ return;
+ }
+ //Remove the compiler extra patch generated
+ //file=file.remove(fileNameCleaner);don't clean, too many performance heart
+ std::string addDebugInformation_lignestring=std::to_string(ligne);
+ std::string addDebugInformation_fileString=file;
+ if(ligne!=-1)
+ addDebugInformation_fileString+=":"+addDebugInformation_lignestring;
+ //Load the time from start
+ std::string addDebugInformation_time = std::to_string(startTime.elapsed());
+ std::string addDebugInformation_htmlFormat;
+ bool important=true;
+ switch(level)
+ {
+ case DebugLevel_custom_Information:
+ addDebugInformation_htmlFormat="<tr class=\"Information\"><td class=\"time\">";
+ break;
+ case DebugLevel_custom_Critical:
+ addDebugInformation_htmlFormat="<tr class=\"Critical\"><td class=\"time\">";
+ break;
+ case DebugLevel_custom_Warning:
+ addDebugInformation_htmlFormat="<tr class=\"Warning\"><td class=\"time\">";
+ break;
+ case DebugLevel_custom_Notice:
+ {
+ addDebugInformation_htmlFormat="<tr class=\"Notice\"><td class=\"time\">";
+ important=false;
+ }
+ break;
+ case DebugLevel_custom_UserNote:
+ addDebugInformation_htmlFormat="<tr class=\"Note\"><td class=\"time\">";
+ break;
+ }
+ addDebugInformation_htmlFormat+=addDebugInformation_time+"</span></td><td>"+addDebugInformation_fileString+"</td><td class=\"function\">"+function+"()</td><td class=\"location\">"+location+"</td><td>"+htmlEntities(text)+"</td></tr>\n";
+ //To prevent access of string in multi-thread
+ {
+ //Show the text in console
+ std::string addDebugInformation_textFormat;
+ if(addDebugInformation_time.size()<8)
+ addDebugInformation_time=std::string(8-addDebugInformation_time.size(),' ')+addDebugInformation_time;
+ addDebugInformation_textFormat = "("+addDebugInformation_time+") ";
+ if(!file.empty() && ligne!=-1)
+ addDebugInformation_textFormat += file+":"+addDebugInformation_lignestring+":";
+ addDebugInformation_textFormat += function+"(), (location: "+location+"): "+text;
+ QMutexLocker lock_mutex(&mutex);
+ if(currentBackend==File)
+ {
+ if(logFile.size()<ULTRACOPIER_DEBUG_MAX_ALL_SIZE*1024*1024 || (important && logFile.size()<ULTRACOPIER_DEBUG_MAX_IMPORTANT_SIZE*1024*1024))
+ {
+ std::cout << addDebugInformation_textFormat << std::endl;
+ logFile.write(addDebugInformation_htmlFormat.data(),static_cast<qint64>(addDebugInformation_htmlFormat.size()));
+ }
+ }
+ else
+ {
+ if(debugHtmlContent.size()<ULTRACOPIER_DEBUG_MAX_ALL_SIZE*1024*1024 || (important && debugHtmlContent.size()<ULTRACOPIER_DEBUG_MAX_IMPORTANT_SIZE*1024*1024))
+ {
+ std::cout << addDebugInformation_textFormat << std::endl;
+ debugHtmlContent+=addDebugInformation_htmlFormat;
+ }
+ }
+ //Send the new line
+ if(addDebugInformationCallNumber<ULTRACOPIER_DEBUG_MAX_GUI_LINE)
+ {
+ addDebugInformationCallNumber++;
+ DebugModel::debugModel->addDebugInformation(startTime.elapsed(),level,function,text,file,static_cast<const unsigned int>(ligne),location);
+ }
+ }
+}
+
+/// \brief Get the html text info for re-show it
+std::string DebugEngine::getTheDebugHtml()
+{
+ if(currentBackend==File)
+ {
+ logFile.seek(0);
+ if(!logFile.isOpen())
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_custom_Warning,"The log file is not open");
+ const QByteArray &data=logFile.readAll();
+ return std::string(data.constData(),static_cast<size_t>(data.size()))+endOfLogFile;
+ }
+ else
+ return debugHtmlContent+endOfLogFile;
+}
+
+/// \brief Get the html end
+std::string DebugEngine::getTheDebugEnd()
+{
+ return endOfLogFile;
+}
+
+/// \brief Drop the html entities
+std::string DebugEngine::htmlEntities(const std::string &text)
+{
+ std::string newText(text);
+ stringreplaceAll(newText,"&","&amp;");
+ /*stringreplaceAll(newText,"\"","&quot;");
+ stringreplaceAll(newText,"\\","&#039;");*/
+ stringreplaceAll(newText,"<","&lt;");
+ stringreplaceAll(newText,">","&gt;");
+ return newText;
+}
+
+/// \brief return the current backend
+DebugEngine::Backend DebugEngine::getCurrentBackend()
+{
+ return currentBackend;
+}
+
+bool DebugEngine::tryConnect()
+{
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString::fromStdString(ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME)),QIODevice::WriteOnly|QIODevice::Unbuffered);
+ if(localSocket.waitForConnected(1000))
+ {
+ localSocket.disconnectFromServer();
+ return true;
+ }
+ else
+ return false;
+}
+
+#endif
diff --git a/DebugEngine.h b/DebugEngine.h
new file mode 100644
index 0000000..7a75264
--- /dev/null
+++ b/DebugEngine.h
@@ -0,0 +1,131 @@
+/** \file DebugEngine.h
+\brief Define the class for the debug
+\author alpha_one_x86
+\note This class don't need be thread safe because ultracopier is done with one thread, but I have implement some basic thread protection
+\licence GPL3, see the file COPYING */
+
+#ifndef DEBUG_ENGINE_H
+#define DEBUG_ENGINE_H
+
+#include <QObject>
+#include <QString>
+#include <string>
+#include <QFile>
+#include <QMutex>
+#include <QTime>
+#include <QTimer>
+#include <QList>
+#include <QCoreApplication>
+#include <QAbstractTableModel>
+#include <QRegularExpression>
+#include <regex>
+
+#include "Variable.h"
+#include "PlatformMacro.h"
+#include "StructEnumDefinition.h"
+#include "StructEnumDefinition_UltracopierSpecific.h"
+
+#ifdef ULTRACOPIER_DEBUG
+
+class DebugModel : public QAbstractTableModel
+{
+ Q_OBJECT
+public:
+ /// \brief the transfer item displayed
+ struct DebugItem
+ {
+ unsigned int time;
+ DebugLevel_custom level;
+ std::string function;
+ std::string text;
+ std::string file;
+ std::string location;
+ };
+
+ static DebugModel *debugModel;
+ DebugModel();
+ ~DebugModel();
+
+ virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual bool setData(const QModelIndex&, const QVariant&, int = Qt::EditRole);
+
+ void addDebugInformation(const int &time, const DebugLevel_custom &level, const std::string& function, const std::string& text, const std::string &file="", const unsigned int& ligne=0, const std::string& location="Core");
+ void setupTheTimer();
+ QTimer *updateDisplayTimer;
+ bool displayed;
+ bool inWaitOfDisplay;
+private:
+ std::vector<DebugItem> list;
+private slots:
+ void updateDisplay();
+};
+
+/** \brief Define the class for the debug
+
+This class provide all needed for the debug mode of ultracopier */
+class DebugEngine : public QObject
+{
+ Q_OBJECT
+ public:
+ /// \brief Initiate the ultracopier event dispatcher and check if no other session is running
+ DebugEngine();
+ /** \brief Destroy the ultracopier event dispatcher
+ \note This function is thread safe */
+ ~DebugEngine();
+ /** \brief Get the html text info for re-show it
+ \note This function is thread safe */
+ std::string getTheDebugHtml();
+ /// \brief Enumeration of backend
+ enum Backend
+ {
+ Memory, //Do intensive usage of memory, used only if the file backend is not available
+ File //Store all directly into file, at crash the backtrace is into the file
+ };
+ /// \brief return the current backend
+ Backend getCurrentBackend();
+ /// \brief Get the html end
+ std::string getTheDebugEnd();
+ /** \brief For add message info, this function
+ \note This function is reentrant */
+ static void addDebugInformationStatic(const Ultracopier::DebugLevel &level,const std::string& function,const std::string& text,const std::string& file="",const int& ligne=-1,const std::string& location="Core");
+ static void addDebugNote(const std::string& text);
+ static DebugEngine *debugEngine;
+ public slots:
+ /** \brief ask to the user where save the bug report
+ \warning This function can be only call by the graphical thread */
+ void saveBugReport();
+ void addDebugInformation(const DebugLevel_custom &level,const std::string& fonction,const std::string& text,std::string file="",const int& ligne=-1,const std::string& location="Core");
+ private:
+ /// \brief Path for log file
+ QFile logFile;
+ /// \brief Path for lock file
+ QFile lockFile;
+ /// \brief Internal function to remove the lock file
+ bool removeTheLockFile();
+ /** \brief Do thread safe part for the addDebugInformation()
+ \see addDebugInformation() */
+ QMutex mutex;
+ QMutex mutexList;
+ /// \brief For record the start time
+ QTime startTime;
+ /// \brief String for the end of log file
+ std::string endOfLogFile;
+ /// \brief Drop the html entities
+ std::string htmlEntities(const std::string &text);
+ /// \brief To store the debug informations
+ std::string debugHtmlContent;
+ /// \brief The current backend
+ Backend currentBackend;
+ /// try connect to send to the current running instance the arguements
+ bool tryConnect();
+ int addDebugInformationCallNumber;
+ bool quit;
+ //std::regex fileNameCleaner;don't clean, too many performance heart
+};
+
+#endif // ULTRACOPIER_DEBUG
+
+#endif // DEBUG_ENGINE_H
diff --git a/DebugEngineMacro.h b/DebugEngineMacro.h
new file mode 100644
index 0000000..c3822cd
--- /dev/null
+++ b/DebugEngineMacro.h
@@ -0,0 +1,28 @@
+/** \file DebugEngineMacro.h
+\brief Define the macro for the debug
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef DEBUGENGINEMACRO_H
+#define DEBUGENGINEMACRO_H
+
+#ifdef WIN32
+# define __func__ __FUNCTION__
+#endif
+
+/// \brief Macro for the debug log
+#ifdef ULTRACOPIER_DEBUG
+# include "DebugEngine.h"
+# if defined (__FILE__) && defined (__LINE__)
+# define ULTRACOPIER_DEBUGCONSOLE(a,b) DebugEngine::addDebugInformationStatic(a,__func__,b,__FILE__,__LINE__)
+# else
+# define ULTRACOPIER_DEBUGCONSOLE(a,b) DebugEngine::addDebugInformationStatic(a,__func__,b)
+# endif
+#else // ULTRACOPIER_DEBUG
+# define ULTRACOPIER_DEBUGCONSOLE(a,b) void()
+#endif // ULTRACOPIER_DEBUG
+
+#endif // DEBUGENGINEMACRO_H
+
+
+
diff --git a/DebugModel.cpp b/DebugModel.cpp
new file mode 100644
index 0000000..5afa3ba
--- /dev/null
+++ b/DebugModel.cpp
@@ -0,0 +1,158 @@
+#include "DebugEngine.h"
+
+#include <QColor>
+
+#ifdef ULTRACOPIER_DEBUG
+
+#define COLUMN_COUNT 5
+
+// Model
+
+DebugModel::DebugModel()
+{
+ displayed = false;
+ inWaitOfDisplay = false;
+ updateDisplayTimer = NULL;
+}
+
+DebugModel::~DebugModel()
+{
+ if(updateDisplayTimer!=NULL)
+ delete updateDisplayTimer;
+}
+
+int DebugModel::columnCount( const QModelIndex& parent ) const
+{
+ return parent == QModelIndex() ? COLUMN_COUNT : 0;
+}
+
+QVariant DebugModel::data( const QModelIndex& index, int role ) const
+{
+ int row,column;
+ row=index.row();
+ column=index.column();
+ if(index.parent()!=QModelIndex() || row < 0 || row >= (int)list.size() || column < 0 || column >= COLUMN_COUNT)
+ return QVariant();
+
+ const DebugItem& item = list.at(row);
+ if(role==Qt::UserRole)
+ return row;
+ else if(role==Qt::DisplayRole)
+ {
+ switch(column)
+ {
+ case 0:
+ return item.time;
+ break;
+ case 1:
+ return QString::fromStdString(item.file);
+ break;
+ case 2:
+ return QString::fromStdString(item.function);
+ break;
+ case 3:
+ return QString::fromStdString(item.location);
+ break;
+ case 4:
+ return QString::fromStdString(item.text);
+ break;
+ default:
+ return QVariant();
+ }
+ }
+ else if(role==Qt::DecorationRole)
+ return QVariant();
+ else if(role==Qt::ForegroundRole)
+ {
+ switch(item.level)
+ {
+ case DebugLevel_custom_Information:
+ return QColor(94,165,255);
+ break;
+ case DebugLevel_custom_Critical:
+ return QColor(255,0,0);
+ break;
+ case DebugLevel_custom_Warning:
+ return QColor(255,178,0);
+ break;
+ case DebugLevel_custom_Notice:
+ return QColor(128,128,128);
+ break;
+ case DebugLevel_custom_UserNote:
+ return QColor(0,0,0);
+ break;
+ }
+ return QVariant();
+ }
+ return QVariant();
+}
+
+int DebugModel::rowCount( const QModelIndex& parent ) const
+{
+ return parent == QModelIndex() ? list.size() : 0;
+}
+
+QVariant DebugModel::headerData( int section, Qt::Orientation orientation, int role ) const
+{
+ if ( role == Qt::DisplayRole && orientation == Qt::Horizontal && section >= 0 && section < COLUMN_COUNT ) {
+ switch ( section ) {
+ case 0:
+ return QStringLiteral("Time");
+ case 1:
+ return QStringLiteral("File");
+ case 2:
+ return QStringLiteral("Function");
+ case 3:
+ return QStringLiteral("Location");
+ case 4:
+ return QStringLiteral("Text");
+ }
+ }
+
+ return QAbstractTableModel::headerData( section, orientation, role );
+}
+
+bool DebugModel::setData( const QModelIndex&, const QVariant&, int)
+{
+ return false;
+}
+
+void DebugModel::addDebugInformation(const int &time, const DebugLevel_custom &level, const std::string &function, const std::string &text, const std::string &file, const unsigned int& ligne, const std::string &location)
+{
+ DebugItem item;
+ item.time=time;
+ item.level=level;
+ item.function=function;
+ item.text=text;
+ item.file=file+":"+std::to_string(ligne);
+ item.location=location;
+ list.push_back(item);
+ if(!displayed)
+ {
+ displayed=true;
+ emit layoutChanged();
+ }
+ else
+ inWaitOfDisplay=true;
+}
+
+void DebugModel::setupTheTimer()
+{
+ if(updateDisplayTimer!=NULL)
+ return;
+ updateDisplayTimer=new QTimer();
+ connect(updateDisplayTimer,&QTimer::timeout,this,&DebugModel::updateDisplay);
+ updateDisplayTimer->start(100);
+}
+
+void DebugModel::updateDisplay()
+{
+ displayed=false;
+ if(!inWaitOfDisplay)
+ {
+ inWaitOfDisplay=false;
+ displayed=true;
+ emit layoutChanged();
+ }
+}
+#endif
diff --git a/Environment.h b/Environment.h
new file mode 100644
index 0000000..d653c5f
--- /dev/null
+++ b/Environment.h
@@ -0,0 +1,21 @@
+/** \file Environment.h
+\brief Define the environment variable and global function
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "Variable.h"
+/// \brief The global include
+#include "StructEnumDefinition.h"
+#include "StructEnumDefinition_UltracopierSpecific.h"
+#include "PlatformMacro.h"
+#include "DebugEngineMacro.h"
+
+#ifdef ULTRACOPIER_VERSION_PORTABLE
+ #define ULTRACOPIER_VERSION_PORTABLE_BOOL true
+#else
+ #define ULTRACOPIER_VERSION_PORTABLE_BOOL false
+#endif
+
+#ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+#undef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+#endif
diff --git a/EventDispatcher.cpp b/EventDispatcher.cpp
new file mode 100644
index 0000000..b2595fb
--- /dev/null
+++ b/EventDispatcher.cpp
@@ -0,0 +1,699 @@
+/** \file EventDispatcher.cpp
+\brief Define the class of the event dispatcher
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QCoreApplication>
+#include <QMessageBox>
+#include <QWidget>
+#include <QStorageInfo>
+#include <iostream>
+
+#include "EventDispatcher.h"
+#include "ExtraSocket.h"
+#include "CompilerInfo.h"
+#include "ThemesManager.h"
+#include "cpp11addition.h"
+
+#ifdef Q_OS_UNIX
+ #include <unistd.h>
+ #include <sys/types.h>
+#endif
+#ifdef Q_OS_WIN32
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+ #include <windows.h>
+ #include <tchar.h>
+ #include <stdio.h>
+ #include <strsafe.h>
+ typedef void (WINAPI *PGNSI) (LPSYSTEM_INFO);
+ typedef BOOL (WINAPI *PGPI) (DWORD, DWORD, DWORD, DWORD, PDWORD);
+#endif
+#ifdef Q_OS_MAC
+#include <QStringList>
+#include <QFile>
+#include <QDomDocument>
+#include <QDomElement>
+#endif
+
+#ifdef ULTRACOPIER_VERSION_ULTIMATE
+#include <QInputDialog>
+#endif
+
+/// \brief Initiate the ultracopier event dispatcher and check if no other session is running
+EventDispatcher::EventDispatcher()
+{
+ qRegisterMetaType<QList<Ultracopier::ReturnActionOnCopyList> >("QList<Ultracopier::ReturnActionOnCopyList>");
+ qRegisterMetaType<QList<Ultracopier::ProgressionItem> >("QList<Ultracopier::ProgressionItem>");
+ qRegisterMetaType<Ultracopier::EngineActionInProgress>("Ultracopier::EngineActionInProgress");
+ qRegisterMetaType<QList<QUrl> >("QList<QUrl>");
+ qRegisterMetaType<Ultracopier::ItemOfCopyList>("Ultracopier::ItemOfCopyList");
+ qRegisterMetaType<std::string>("std::string");
+ qRegisterMetaType<uint64_t>("uint64_t");
+ qRegisterMetaType<std::vector<Ultracopier::ProgressionItem> >("std::vector<Ultracopier::ProgressionItem>");
+ qRegisterMetaType<std::vector<Ultracopier::ReturnActionOnCopyList> >("std::vector<Ultracopier::ReturnActionOnCopyList>");
+ qRegisterMetaType<std::vector<std::string> >("std::vector<std::string>");
+
+ copyServer=new CopyListener(&optionDialog);
+ if(!connect(&localListener, &LocalListener::cli, &cliParser, &CliParser::cli,Qt::QueuedConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(ThemesManager::themesManager, &ThemesManager::newThemeOptions, &optionDialog, &OptionDialog::newThemeOptions))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(&cliParser, &CliParser::newCopyWithoutDestination, copyServer, &CopyListener::copyWithoutDestination))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(&cliParser, &CliParser::newCopy, copyServer, &CopyListener::copy))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(&cliParser, &CliParser::newMoveWithoutDestination, copyServer, &CopyListener::moveWithoutDestination))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(&cliParser, &CliParser::newMove, copyServer, &CopyListener::move))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::newClientList, &optionDialog, &OptionDialog::newClientList))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ if(!connect(&cliParser, &CliParser::tryLoadPlugin, PluginsManager::pluginsManager, &PluginsManager::tryLoadPlugin))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #endif
+ copyMoveEventIdIndex=0;
+ backgroundIcon=NULL;
+ stopIt=false;
+
+
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ sessionloader=new SessionLoader(&optionDialog);
+ #endif
+ copyEngineList=new CopyEngineManager(&optionDialog);
+ core=new Core(copyEngineList);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ //show the ultracopier information
+ #if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Windows version: "+GetOSDisplayString());
+ #endif
+ #ifdef __STDC_VERSION__
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"__STDC_VERSION__: "+std::to_string(__STDC_VERSION__));
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,std::string("ULTRACOPIER_VERSION: ")+ULTRACOPIER_VERSION);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,std::string("Qt version: ")+qVersion()+" "+std::to_string(QT_VERSION));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,std::string("ULTRACOPIER_PLATFORM_NAME: ")+ULTRACOPIER_PLATFORM_NAME.toStdString());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Application path: "+QCoreApplication::applicationFilePath().toStdString()+" "+std::to_string(QCoreApplication::applicationPid()));
+ //ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,COMPILERINFO);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Local socket: "+ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME));
+ #if defined(ULTRACOPIER_DEBUG) && defined(ULTRACOPIER_PLUGIN_ALL_IN_ONE)
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Version as all in one");
+ QObjectList objectList=QPluginLoader::staticInstances();
+ int index=0;
+ while(index<objectList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"static plugin: "+objectList.at(index)->metaObject()->className().toStdString());
+ index++;
+ }
+ #else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Version as all in one, direct");
+ #endif
+ #endif
+
+ {
+ const QList<QStorageInfo> mountedVolumesList=QStorageInfo::mountedVolumes();
+ int index=0;
+ while(index<mountedVolumesList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"mountSysPoint: "+mountedVolumesList.at(index).rootPath().toStdString());
+ index++;
+ }
+ if(mountedVolumesList.isEmpty())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"mountSysPoint is empty");
+ }
+
+ //To lunch some initialization after QApplication::exec() to quit eventually
+ lunchInitFunction.setInterval(0);
+ lunchInitFunction.setSingleShot(true);
+ connect(&lunchInitFunction,&QTimer::timeout,this,&EventDispatcher::initFunction,Qt::QueuedConnection);
+ lunchInitFunction.start();
+ if(OptionEngine::optionEngine->getOptionValue("Ultracopier","Last_version_used")!="na" && OptionEngine::optionEngine->getOptionValue("Ultracopier","Last_version_used")!=ULTRACOPIER_VERSION)
+ {
+ //then ultracopier have been updated
+ }
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","Last_version_used",ULTRACOPIER_VERSION);
+ unsigned int a=stringtouint32(OptionEngine::optionEngine->getOptionValue("Ultracopier","ActionOnManualOpen"));
+ if(a>2)
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","ActionOnManualOpen","1");
+ a=stringtouint32(OptionEngine::optionEngine->getOptionValue("Ultracopier","GroupWindowWhen"));
+ if(a>5)
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","GroupWindowWhen","0");
+
+ #ifdef ULTRACOPIER_VERSION_ULTIMATE
+ #ifdef ULTRACOPIER_ILLEGAL
+ static bool crackedVersion=true;
+ #else
+ static bool crackedVersion=false;
+ #endif
+ if(!crackedVersion)
+ {
+ while(1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ultimate key");
+ QString key=QString::fromStdString(OptionEngine::optionEngine->getOptionValue("Ultracopier","key"));
+ if(!key.isEmpty())
+ {
+ QCryptographicHash hash(QCryptographicHash::Sha224);
+ hash.addData(QStringLiteral("U2NgvbKVrVwlaXnx").toUtf8());
+ hash.addData(key.toUtf8());
+ const QByteArray &result=hash.result();
+ if(!result.isEmpty() && result.at(0)==0x00 && result.at(1)==0x00)
+ break;
+ }
+ key=QInputDialog::getText(NULL,tr("Key"),tr("Give the key of this software, more information on <a href=\"http://ultracopier.first-world.info/\">ultracopier.first-world.info</a>"));
+ if(key.isEmpty())
+ {
+ QCoreApplication::quit();
+ stopIt=true;
+ return;
+ }
+ {
+ QCryptographicHash hash(QCryptographicHash::Sha224);
+ hash.addData(QStringLiteral("U2NgvbKVrVwlaXnx").toUtf8());
+ hash.addData(key.toUtf8());
+ const QByteArray &result=hash.result();
+ if(!result.isEmpty() && result.at(0)==0x00 && result.at(1)==0x00)
+ {
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","key",key.toStdString());
+ break;
+ }
+ }
+ }
+ }
+ #endif
+
+ connect(&cliParser, &CliParser::newTransferList,core, &Core::newTransferList);
+}
+
+/// \brief Destroy the ultracopier event dispatcher
+EventDispatcher::~EventDispatcher()
+{
+ if(core!=NULL)
+ {
+ delete core;
+ core=NULL;
+ }
+ if(copyEngineList!=NULL)
+ {
+ delete copyEngineList;
+ copyEngineList=NULL;
+ }
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ if(sessionloader!=NULL)
+ {
+ delete sessionloader;
+ sessionloader=NULL;
+ }
+ #endif
+ if(backgroundIcon!=NULL)
+ {
+ delete backgroundIcon;
+ backgroundIcon=NULL;
+ }
+ if(copyServer!=NULL)
+ {
+ delete copyServer;
+ copyServer=NULL;
+ }
+}
+
+/// \brief return if need be close
+bool EventDispatcher::shouldBeClosed()
+{
+ return stopIt;
+}
+
+/// \brief Quit ultracopier
+void EventDispatcher::quit()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Will quit ultracopier");
+ //disconnect(QCoreApplication::instance(),SIGNAL(aboutToQuit()),this,SLOT(quit()));
+ QCoreApplication::exit();
+}
+
+/// \brief Called when event loop is setup
+void EventDispatcher::initFunction()
+{
+ if(core==NULL || copyEngineList==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Unable to initialize correctly the software");
+ return;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Initialize the variable of event loop");
+ if(!connect(copyServer, &CopyListener::newCopyWithoutDestination, core, &Core::newCopyWithoutDestination,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::newCopy, core, &Core::newCopy,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::newMoveWithoutDestination, core, &Core::newMoveWithoutDestination,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::newMove, core, &Core::newMove,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(core, &Core::copyFinished, copyServer, &CopyListener::copyFinished,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(core, &Core::copyCanceled, copyServer, &CopyListener::copyCanceled,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(localListener.tryConnect())
+ {
+ stopIt=true;
+ QCoreApplication::exit(1);//by 1, return process is in progress
+ return;
+ }
+ localListener.listenServer();
+ //load the systray icon
+ if(backgroundIcon==NULL)
+ {
+ backgroundIcon=new SystrayIcon();
+ //connect the slot
+ //quit is for this object
+// connect(core, &Core::newCanDoOnlyCopy, backgroundIcon, &SystrayIcon::newCanDoOnlyCopy,Qt::DirectConnection);
+ if(!connect(backgroundIcon, &SystrayIcon::quit,this,&EventDispatcher::quit))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ //show option is for OptionEngine object
+ if(!connect(backgroundIcon, &SystrayIcon::showOptions, &optionDialog, &OptionDialog::show,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(&cliParser, &CliParser::showOptions, &optionDialog, &OptionDialog::show,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::listenerReady, backgroundIcon, &SystrayIcon::listenerReady,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyServer, &CopyListener::pluginLoaderReady, backgroundIcon, &SystrayIcon::pluginLoaderReady,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(backgroundIcon, &SystrayIcon::tryCatchCopy, copyServer, &CopyListener::listen,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(backgroundIcon, &SystrayIcon::tryUncatchCopy, copyServer, &CopyListener::close,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(stringtobool(OptionEngine::optionEngine->getOptionValue("CopyListener","CatchCopyAsDefault")))
+ copyServer->listen();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"copyServer.oneListenerIsLoaded(): "+std::to_string(copyServer->oneListenerIsLoaded()));
+ //backgroundIcon->readyToListen(copyServer.oneListenerIsLoaded());
+
+ #ifdef ULTRACOPIER_DEBUG
+ if(!connect(backgroundIcon, &SystrayIcon::saveBugReport, DebugEngine::debugEngine, &DebugEngine::saveBugReport,Qt::QueuedConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #endif
+ if(!connect(backgroundIcon, &SystrayIcon::addWindowCopyMove, core, &Core::addWindowCopyMove,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(backgroundIcon, &SystrayIcon::addWindowTransfer, core, &Core::addWindowTransfer,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyEngineList, &CopyEngineManager::addCopyEngine, backgroundIcon, &SystrayIcon::addCopyEngine,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ if(!connect(copyEngineList, &CopyEngineManager::removeCopyEngine, backgroundIcon, &SystrayIcon::removeCopyEngine,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #ifdef ULTRACOPIER_INTERNET_SUPPORT
+ if(!connect(&internetUpdater,&InternetUpdater::newUpdate, backgroundIcon, &SystrayIcon::newUpdate))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #endif
+ copyEngineList->setIsConnected();
+ copyServer->resendState();
+
+ connect(&cliParser, &CliParser::showSystrayMessage, backgroundIcon,&SystrayIcon::showSystrayMessage,Qt::QueuedConnection);
+ }
+ //conntect the last chance signal before quit
+ if(!connect(QCoreApplication::instance(),&QCoreApplication::aboutToQuit,this,&EventDispatcher::quit,Qt::DirectConnection))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ //connect the slot for the help dialog
+ if(!connect(backgroundIcon,&SystrayIcon::showHelp,&theHelp,&HelpDialog::show))
+ {
+ std::cerr << "connect error at " << __FILE__ << ":" << std::to_string(__LINE__) << std::endl;
+ abort();
+ }
+ #ifdef ULTRACOPIER_DEBUG
+ DebugModel::debugModel->setupTheTimer();
+ #endif
+}
+
+#ifdef Q_OS_WIN32
+std::string EventDispatcher::GetOSDisplayString()
+{
+ QString Os;
+ OSVERSIONINFOEX osvi;
+ SYSTEM_INFO si;
+ PGNSI pGNSI;
+ PGPI pGPI;
+ BOOL bOsVersionInfoEx;
+ DWORD dwType;
+
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi);
+
+ if(bOsVersionInfoEx == 0)
+ return "Os detection blocked";
+
+ // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+
+ pGNSI = (PGNSI) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")),
+ "GetNativeSystemInfo");
+ if(NULL != pGNSI)
+ pGNSI(&si);
+ else GetSystemInfo(&si);
+
+ if(VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion>4)
+ {
+ if(osvi.dwMajorVersion==6)
+ {
+ switch(osvi.dwMinorVersion)
+ {
+ case 0:
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows Vista ");
+ else Os+=QStringLiteral("Windows Server 2008 ");
+ break;
+ case 1:
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows 7 ");
+ else Os+=QStringLiteral("Windows Server 2008 R2 ");
+ break;
+ case 2:
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows 8 ");
+ else Os+=QStringLiteral("Windows Server 2012 ");
+ break;
+ default:
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ else Os+=QStringLiteral("Windows Server (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ break;
+ }
+
+ pGPI = (PGPI) GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")),
+ "GetProductInfo");
+
+ pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
+
+ switch(dwType)
+ {
+ case PRODUCT_ULTIMATE:
+ Os+=QStringLiteral("Ultimate Edition");
+ break;
+ case PRODUCT_PROFESSIONAL:
+ Os+=QStringLiteral("Professional");
+ break;
+ case PRODUCT_HOME_PREMIUM:
+ Os+=QStringLiteral("Home Premium Edition");
+ break;
+ case PRODUCT_HOME_BASIC:
+ Os+=QStringLiteral("Home Basic Edition");
+ break;
+ case PRODUCT_ENTERPRISE:
+ Os+=QStringLiteral("Enterprise Edition");
+ break;
+ case PRODUCT_BUSINESS:
+ Os+=QStringLiteral("Business Edition");
+ break;
+ case PRODUCT_STARTER:
+ Os+=QStringLiteral("Starter Edition");
+ break;
+ case PRODUCT_CLUSTER_SERVER:
+ Os+=QStringLiteral("Cluster Server Edition");
+ break;
+ case PRODUCT_DATACENTER_SERVER:
+ Os+=QStringLiteral("Datacenter Edition");
+ break;
+ case PRODUCT_DATACENTER_SERVER_CORE:
+ Os+=QStringLiteral("Datacenter Edition (core installation)");
+ break;
+ case PRODUCT_ENTERPRISE_SERVER:
+ Os+=QStringLiteral("Enterprise Edition");
+ break;
+ case PRODUCT_ENTERPRISE_SERVER_CORE:
+ Os+=QStringLiteral("Enterprise Edition (core installation)");
+ break;
+ case PRODUCT_ENTERPRISE_SERVER_IA64:
+ Os+=QStringLiteral("Enterprise Edition for Itanium-based Systems");
+ break;
+ case PRODUCT_SMALLBUSINESS_SERVER:
+ Os+=QStringLiteral("Small Business Server");
+ break;
+ case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
+ Os+=QStringLiteral("Small Business Server Premium Edition");
+ break;
+ case PRODUCT_STANDARD_SERVER:
+ Os+=QStringLiteral("Standard Edition");
+ break;
+ case PRODUCT_STANDARD_SERVER_CORE:
+ Os+=QStringLiteral("Standard Edition (core installation)");
+ break;
+ case PRODUCT_WEB_SERVER:
+ Os+=QStringLiteral("Web Server Edition");
+ break;
+ }
+ }
+ else if(osvi.dwMajorVersion==5)
+ {
+ switch(osvi.dwMinorVersion)
+ {
+ case 0:
+ Os+=QStringLiteral("Windows 2000 ");
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Professional");
+ else
+ {
+ if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ Os+=QStringLiteral("Datacenter Server");
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ Os+=QStringLiteral("Advanced Server");
+ else Os+=QStringLiteral("Server");
+ }
+ break;
+ case 1:
+ Os+=QStringLiteral("Windows XP ");
+ if(osvi.wSuiteMask & VER_SUITE_PERSONAL)
+ Os+=QStringLiteral("Home Edition");
+ else Os+=QStringLiteral("Professional");
+ break;
+ case 2:
+ if(GetSystemMetrics(SM_SERVERR2))
+ Os+=QStringLiteral("Windows Server 2003 R2, ");
+ else if(osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER )
+ Os+=QStringLiteral("Windows Storage Server 2003");
+ else if(osvi.wSuiteMask & VER_SUITE_WH_SERVER )
+ Os+=QStringLiteral("Windows Home Server");
+ else if(osvi.wProductType==VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ Os+=QStringLiteral("Windows XP Professional x64 Edition");
+ else Os+=QStringLiteral("Windows Server 2003, ");
+ // Test for the server type.
+ if(osvi.wProductType!=VER_NT_WORKSTATION )
+ {
+ if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)
+ {
+ if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
+ Os+=QStringLiteral("Datacenter Edition for Itanium-based Systems");
+ else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
+ Os+=QStringLiteral("Enterprise Edition for Itanium-based Systems");
+ }
+ else if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ {
+ if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ Os+=QStringLiteral("Datacenter x64 Edition");
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ Os+=QStringLiteral("Enterprise x64 Edition");
+ else Os+=QStringLiteral("Standard x64 Edition");
+ }
+ else
+ {
+ if(osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
+ Os+=QStringLiteral("Compute Cluster Edition");
+ else if( osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ Os+=QStringLiteral("Datacenter Edition");
+ else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ Os+=QStringLiteral("Enterprise Edition");
+ else if(osvi.wSuiteMask & VER_SUITE_BLADE)
+ Os+=QStringLiteral("Web Edition");
+ else Os+=QStringLiteral("Standard Edition");
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ else Os+=QStringLiteral("Windows Server (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ }
+
+ // Include service pack (if any) and build number.
+ QString QszCSDVersion=QString::fromUtf16((ushort*)osvi.szCSDVersion);
+ if(!QszCSDVersion.isEmpty())
+ Os+=QStringLiteral(" %1").arg(QszCSDVersion);
+ Os+=QStringLiteral(" (build %1)").arg(osvi.dwBuildNumber);
+ if(osvi.dwMajorVersion >= 6)
+ {
+ if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ Os+=QStringLiteral(", 64-bit");
+ else if(si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL)
+ Os+=QStringLiteral(", 32-bit");
+ }
+ }
+ else
+ {
+ if(osvi.wProductType==VER_NT_WORKSTATION)
+ Os+=QStringLiteral("Windows (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ else Os+=QStringLiteral("Windows Server (dwMajorVersion: %1, dwMinorVersion: %2)").arg(osvi.dwMinorVersion).arg(osvi.dwMinorVersion);
+ }
+ return Os.toStdString();
+}
+#endif
+
+#ifdef Q_OS_MAC
+std::string EventDispatcher::GetOSDisplayString()
+{
+ QStringList key;
+ QStringList string;
+ QFile xmlFile(QStringLiteral("/System/Library/CoreServices/SystemVersion.plist"));
+ if(xmlFile.open(QIODevice::ReadOnly))
+ {
+ QString content=xmlFile.readAll();
+ xmlFile.close();
+ QString errorStr;
+ int errorLine;
+ int errorColumn;
+ QDomDocument domDocument;
+ if (!domDocument.setContent(content, false, &errorStr,&errorLine,&errorColumn))
+ return "Mac OS X";
+ else
+ {
+ QDomElement root = domDocument.documentElement();
+ if(root.tagName()!=QStringLiteral("plist"))
+ return "Mac OS X";
+ else
+ {
+ if(root.isElement())
+ {
+ QDomElement SubChild=root.firstChildElement(QStringLiteral("dict"));
+ while(!SubChild.isNull())
+ {
+ if(SubChild.isElement())
+ {
+ QDomElement SubChild2=SubChild.firstChildElement(QStringLiteral("key"));
+ while(!SubChild2.isNull())
+ {
+ if(SubChild2.isElement())
+ key << SubChild2.text();
+ else
+ return "Mac OS X";
+ SubChild2 = SubChild2.nextSiblingElement(QStringLiteral("key"));
+ }
+ SubChild2=SubChild.firstChildElement(QStringLiteral("string"));
+ while(!SubChild2.isNull())
+ {
+ if(SubChild2.isElement())
+ string << SubChild2.text();
+ else
+ return "Mac OS X";
+ SubChild2 = SubChild2.nextSiblingElement(QStringLiteral("string"));
+ }
+ }
+ else
+ return "Mac OS X";
+ SubChild = SubChild.nextSiblingElement(QStringLiteral("property"));
+ }
+ }
+ else
+ return "Mac OS X";
+ }
+ }
+ }
+ if(key.size()!=string.size())
+ return "Mac OS X";
+ int index=0;
+ while(index<key.size())
+ {
+ if(key.at(index)==QStringLiteral("ProductVersion"))
+ return "Mac OS X "+string.at(index).toStdString();
+ index++;
+ }
+ return "Mac OS X";
+}
+#endif
diff --git a/EventDispatcher.h b/EventDispatcher.h
new file mode 100644
index 0000000..77b1948
--- /dev/null
+++ b/EventDispatcher.h
@@ -0,0 +1,97 @@
+/** \file EventDispatcher.h
+\brief Define the class of the event dispatcher
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef EVENT_DISPATCHER_H
+#define EVENT_DISPATCHER_H
+
+#include <QObject>
+#include <QStringList>
+#include <QString>
+#include <QTimer>
+#include <QList>
+#include <QUrl>
+
+#include "Environment.h"
+#include "Core.h"
+#include "SystrayIcon.h"
+#include "OptionEngine.h"
+#include "HelpDialog.h"
+#ifndef ULTRACOPIER_VERSION_PORTABLE
+#include "SessionLoader.h"
+#endif
+#ifdef ULTRACOPIER_INTERNET_SUPPORT
+#include "InternetUpdater.h"
+#endif
+#include "CopyListener.h"
+#include "OptionDialog.h"
+#include "CopyEngineManager.h"
+#include "LocalListener.h"
+#include "CliParser.h"
+
+/** \brief Define the class of the event dispatcher
+
+This class provide a core for dispatch the event of signal/slot, it checks too if not other instance is running */
+class EventDispatcher : public QObject
+{
+ Q_OBJECT
+ public:
+ /// \brief Initiate the ultracopier event dispatcher and check if no other session is running
+ EventDispatcher();
+ /// \brief Destroy the ultracopier event dispatcher
+ ~EventDispatcher();
+ /// \brief return if need be close
+ bool shouldBeClosed();
+ #if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
+ static std::string GetOSDisplayString();
+ #endif
+ public slots:
+ /// \brief Quit ultracopier
+ void quit();
+ signals:
+ /** \brief Send that's caught state have changed for CatchedState::Uncatched or CatchedState::Semicatched or CatchedState::Catched
+ \see CatchState
+ \see tryCatchCopy()
+ \see tryUncatchCopy()
+ \param State is the new state */
+ void catchCopyStateChanged(Ultracopier::CatchState state) const;
+ /** \brief Send that's copy/move task is finished in returning the copyMoveEventId
+ \see routeCopyMoveEvent()
+ \param copyMoveEventId The task id generated by routeCopyMoveEvent() */
+ void copyMoveEventIsFinish(int copyMoveEventId) const;
+ private:
+ /// \brief To have counter for increment the copyMoveEventId at each request
+ int copyMoveEventIdIndex;
+ /// \brief To store windows windows session
+ struct CoreSession
+ {
+ Core * CoreWindow;
+ std::vector<int> copyMoveEventIdManaged;
+ };
+ /// \brief the systray icon
+ SystrayIcon *backgroundIcon;
+ /// \brief To lunch event only when the event loop is setup
+ QTimer lunchInitFunction;
+ /// \brief the help dialog
+ HelpDialog theHelp;
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ /// \brief the session loader
+ SessionLoader *sessionloader;
+ #endif
+ bool stopIt;
+ CopyListener *copyServer;
+ Core *core;
+ OptionDialog optionDialog;
+ #ifdef ULTRACOPIER_INTERNET_SUPPORT
+ InternetUpdater internetUpdater;
+ #endif
+ CopyEngineManager *copyEngineList;
+ LocalListener localListener;
+ CliParser cliParser;
+ private slots:
+ /// \brief Called when event loop is setup
+ void initFunction();
+};
+
+#endif // EVENT_DISPATCHER_H
diff --git a/ExtraSocket.cpp b/ExtraSocket.cpp
new file mode 100644
index 0000000..ef196fa
--- /dev/null
+++ b/ExtraSocket.cpp
@@ -0,0 +1,60 @@
+/** \file ExtraSocket.h
+\brief Define the socket of ultracopier
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "ExtraSocket.h"
+#include <QByteArray>
+#include <stdio.h>
+
+std::string ExtraSocket::pathSocket(const std::string &name)
+{
+#ifdef Q_OS_UNIX
+ return name+"-"+std::to_string(getuid());
+#else
+ QString userName;
+
+ /* bad way for catchcopy compatibility
+ char uname[1024];
+ DWORD len=1023;
+ if(GetUserNameA(uname, &len)!=FALSE)
+ userName=toHex(uname);*/
+
+ QChar charTemp;
+ DWORD size=255;
+ WCHAR * userNameW=new WCHAR[size];
+ if(GetUserNameW(userNameW,&size))
+ {
+ QByteArray tempArray;
+ userName=QString::fromWCharArray(userNameW,size-1);
+ int index=0;
+ while(index<userName.size())
+ {
+ tempArray+=userName.at(index).cell();
+ tempArray+=userName.at(index).row();
+ index++;
+ }
+ userName=tempArray.toHex();
+ }
+ delete userNameW;
+ return name+"-"+userName.toStdString();
+#endif
+}
+
+// Dump UTF16 (little endian)
+char * ExtraSocket::toHex(const char *str)
+{
+ char *p, *sz;
+ size_t len;
+ if (str==NULL)
+ return NULL;
+ len= strlen(str);
+ p = sz = (char *) malloc((len+1)*4);
+ for (size_t i=0; i<len; i++)
+ {
+ sprintf(p, "%.2x00", str[i]);
+ p+=4;
+ }
+ *p=0;
+ return sz;
+}
diff --git a/ExtraSocket.h b/ExtraSocket.h
new file mode 100644
index 0000000..c8d44c5
--- /dev/null
+++ b/ExtraSocket.h
@@ -0,0 +1,30 @@
+/** \file ExtraSocket.h
+\brief Define the socket for ultracopier
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef EXTRASOCKET_H
+#define EXTRASOCKET_H
+
+#include <QString>
+
+#ifdef Q_OS_UNIX
+ #include <unistd.h>
+ #include <sys/types.h>
+#else
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+ #include <windows.h>
+#endif
+
+/** \brief class to have general socket options */
+class ExtraSocket
+{
+public:
+ /** \brief class to return always the same socket resolution */
+ static std::string pathSocket(const std::string &name);
+ static char * toHex(const char *str);
+};
+
+#endif // EXTRASOCKET_H
diff --git a/FacilityEngine.cpp b/FacilityEngine.cpp
new file mode 100644
index 0000000..8356f05
--- /dev/null
+++ b/FacilityEngine.cpp
@@ -0,0 +1,251 @@
+/** \file FacilityEngine.cpp
+\brief To implement the facility engine, the interface is defined into FacilityInterface()
+\see FacilityInterface()
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "FacilityEngine.h"
+
+#if defined (Q_OS_WIN32)
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+ #include <windows.h>
+#endif
+
+FacilityEngine FacilityEngine::facilityEngine;
+
+FacilityEngine::FacilityEngine()
+{
+ retranslate();
+}
+
+/// \brief separator native to the current OS
+std::string FacilityEngine::separator()
+{
+ #ifdef Q_OS_WIN32
+ return "\\";
+ #else
+ return "/";
+ #endif
+}
+
+/// \brief To force the text re-translation
+void FacilityEngine::retranslate()
+{
+ //undirect translated string
+ Translation_perSecond="/"+tr("s").toStdString();
+ Translation_tooBig=tr("Too big").toStdString();
+ Translation_B=tr("B").toStdString();
+ Translation_KB=tr("KB").toStdString();
+ Translation_MB=tr("MB").toStdString();
+ Translation_GB=tr("GB").toStdString();
+ Translation_TB=tr("TB").toStdString();
+ Translation_PB=tr("PB").toStdString();
+ Translation_EB=tr("EB").toStdString();
+ Translation_ZB=tr("ZB").toStdString();
+ Translation_YB=tr("YB").toStdString();
+ Translation_SimplifiedRemaningTime_LessThan10s=tr("Less than %10 seconds").toStdString();
+ Translation_SimplifiedRemaningTime_AboutSeconds=tr("About %10 seconds remaining").toStdString();
+ Translation_SimplifiedRemaningTime_AboutMinutes=tr("About %1 minutes remaining").toStdString();
+ Translation_SimplifiedRemaningTime_AboutHours=tr("About %1 hours remaining").toStdString();
+ //load the translations tab
+ translations["Copy engine"]=tr("Copy engine").toStdString();
+ //: a copy
+ translations["Copy"]=tr("Copy").toStdString();
+ //: a transfer
+ translations["Transfer"]=tr("Transfer").toStdString();
+ //: a move
+ translations["Move"]=tr("Move").toStdString();
+ translations["Start"]=tr("Start").toStdString();
+ translations["Pause"]=tr("Pause").toStdString();
+ translations["Resume"]=tr("Resume").toStdString();
+ translations["Skip"]=tr("Skip").toStdString();
+ translations["Unlimited"]=tr("Unlimited").toStdString();
+ translations["Source"]=tr("Source").toStdString();
+ translations["Size"]=tr("Size").toStdString();
+ translations["Destination"]=tr("Destination").toStdString();
+ translations["Quit"]=tr("Quit").toStdString();
+ translations["Target"]=tr("Target").toStdString();
+ translations["Time remaining:"]=tr("Time remaining:").toStdString();
+ translations["Listing"]=tr("Listing").toStdString();
+ translations["Copying"]=tr("Copying").toStdString();
+ translations["Listing and copying"]=tr("Listing and copying").toStdString();
+ translations["Time remaining:"]=tr("Time remaining:").toStdString();
+ //for copy engine
+ translations["Ask"]=tr("Ask").toStdString();
+ translations["Skip"]=tr("Skip").toStdString();
+ translations["Overwrite"]=tr("Overwrite").toStdString();
+ translations["Overwrite if newer"]=tr("Overwrite if newer").toStdString();
+ translations["Overwrite if the last modification dates are different"]=tr("Overwrite if the last modification dates are different").toStdString();
+ translations["Rename"]=tr("Rename").toStdString();
+ translations["Put to the end of the list"]=tr("Put to the end of the list").toStdString();
+ translations["Select source directory"]=tr("Select source directory").toStdString();
+ translations["Select destination directory"]=tr("Select destination directory").toStdString();
+ translations["Internal error"]=tr("Internal error").toStdString();
+ translations["Select one or more files to open"]=tr("Select one or more files to open").toStdString();
+ translations["All files"]=tr("All files").toStdString();
+ translations["Save transfer list"]=tr("Save transfer list").toStdString();
+ translations["Open transfer list"]=tr("Open transfer list").toStdString();
+ translations["Transfer list"]=tr("Transfer list").toStdString();
+ translations["Error"]=tr("Error").toStdString();
+ translations["Not supported on this platform"]=tr("Not supported on this platform").toStdString();
+ translations["Completed in %1"]=tr("Completed in %1").toStdString();
+}
+
+/// \brief convert size in Byte to String
+std::string FacilityEngine::sizeToString(const double &size) const
+{
+ double size_temp=size;
+ if(size_temp<1024)
+ return std::to_string((unsigned int)size_temp)+sizeUnitToString(Ultracopier::SizeUnit_byte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_KiloByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_MegaByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_GigaByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_TeraByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_PetaByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_ExaByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_ZettaByte);
+ if((size_temp=size_temp/1024)<1024)
+ return adaptString(static_cast<float>(size_temp))+sizeUnitToString(Ultracopier::SizeUnit_YottaByte);
+ return Translation_tooBig;
+}
+
+std::string FacilityEngine::adaptString(const float &size) const
+{
+ if(size>=100)
+ return QString::number(static_cast<double>(size),'f',0).toStdString();
+ else
+ return QString::number(static_cast<double>(size),'g',3).toStdString();
+}
+
+
+/// \brief convert size unit to String
+std::string FacilityEngine::sizeUnitToString(const Ultracopier::SizeUnit &sizeUnit) const
+{
+ switch(sizeUnit)
+ {
+ case Ultracopier::SizeUnit_byte:
+ return Translation_B;
+ case Ultracopier::SizeUnit_KiloByte:
+ return Translation_KB;
+ case Ultracopier::SizeUnit_MegaByte:
+ return Translation_MB;
+ case Ultracopier::SizeUnit_GigaByte:
+ return Translation_GB;
+ case Ultracopier::SizeUnit_TeraByte:
+ return Translation_TB;
+ case Ultracopier::SizeUnit_PetaByte:
+ return Translation_PB;
+ case Ultracopier::SizeUnit_ExaByte:
+ return Translation_EB;
+ case Ultracopier::SizeUnit_ZettaByte:
+ return Translation_ZB;
+ case Ultracopier::SizeUnit_YottaByte:
+ return Translation_YB;
+ default:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"sizeUnit: "+std::to_string(sizeUnit));
+ return "???";
+ }
+}
+
+/// \brief translate the text
+std::string FacilityEngine::translateText(const std::string &text) const
+{
+ if(translations.find(text)!=translations.cend())
+ return translations.at(text);
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"translation not found: "+text);
+ return text;
+ }
+}
+
+/// \brief speed to string in byte per seconds
+std::string FacilityEngine::speedToString(const double &speed) const
+{
+ return sizeToString(speed)+Translation_perSecond;
+}
+/// \brief Decompose the time in second
+Ultracopier::TimeDecomposition FacilityEngine::secondsToTimeDecomposition(const uint32_t &seconds) const
+{
+ quint32 seconds_temp=seconds;
+ Ultracopier::TimeDecomposition returnValue;
+ returnValue.second=static_cast<uint16_t>(seconds_temp%60);
+ seconds_temp-=returnValue.second;
+ seconds_temp/=60;
+ returnValue.minute=static_cast<uint16_t>(seconds_temp%60);
+ seconds_temp-=returnValue.minute;
+ seconds_temp/=60;
+ returnValue.hour=static_cast<uint16_t>(seconds_temp);
+ return returnValue;
+}
+
+/// \brief have the functionality
+bool FacilityEngine::haveFunctionality(const std::string &fonctionnality) const
+{
+ #if defined (Q_OS_WIN32)
+ if(fonctionnality=="shutdown")
+ return true;
+ #endif
+ Q_UNUSED(fonctionnality);
+ return false;
+}
+
+/// \brief call the fonctionnality
+std::string FacilityEngine::callFunctionality(const std::string &fonctionnality,const std::vector<std::string> &args)
+{
+ #if defined (Q_OS_WIN32)
+ ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,0);
+ system("shutdown /s /f /t 0");
+ #endif
+ Q_UNUSED(fonctionnality);
+ Q_UNUSED(args);
+ return std::string();
+}
+
+/// \brief Do the simplified time
+std::string FacilityEngine::simplifiedRemainingTime(const uint32_t &seconds) const
+{
+ if(seconds<50)
+ {
+ if(seconds<10)
+ return QString::fromStdString(Translation_SimplifiedRemaningTime_LessThan10s).arg(seconds/10+1).toStdString();
+ else
+ return QString::fromStdString(Translation_SimplifiedRemaningTime_AboutSeconds).arg(seconds/10+1).toStdString();
+ }
+ if(seconds<3600)
+ return QString::fromStdString(Translation_SimplifiedRemaningTime_AboutMinutes).arg(seconds/60).toStdString();
+ return QString::fromStdString(Translation_SimplifiedRemaningTime_AboutHours).arg(seconds/3600).toStdString();
+}
+
+/// \brief Return ultimate url, empty is not found or already ultimate
+std::string FacilityEngine::ultimateUrl() const
+{
+ #ifdef ULTRACOPIER_VERSION_ULTIMATE
+ return std::string();
+ #else
+ #if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
+ return "http://ultracopier.first-world.info/shop.html";
+ #else
+ return std::string();
+ #endif
+ #endif
+}
+
+/// \brief Return the software name
+std::string FacilityEngine::softwareName() const
+{
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ return "Supercopier";
+ #else
+ return "Ultracopier";
+ #endif
+}
diff --git a/FacilityEngine.h b/FacilityEngine.h
new file mode 100644
index 0000000..5b6c6a9
--- /dev/null
+++ b/FacilityEngine.h
@@ -0,0 +1,76 @@
+/** \file FacilityEngine.h
+\brief To implement the facility engine, the interface is defined into FacilityInterface()
+\see FacilityInterface()
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef FACILITYENGINE_H
+#define FACILITYENGINE_H
+
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+#include "interface/FacilityInterface.h"
+#include "Environment.h"
+
+/** \brief Class to group general function for the plugin
+
+This class is used into some plugin like copy engine plugin, to all into one place all common function, group the traduction, and all what it can grouped across all plugin into Ultracopier core application.
+*/
+class FacilityEngine : public FacilityInterface
+{
+ Q_OBJECT
+public:
+ explicit FacilityEngine();
+ /// \brief convert size in Byte to String
+ std::string sizeToString(const double &size) const;
+ /// \brief convert size unit to String
+ std::string sizeUnitToString(const Ultracopier::SizeUnit &sizeUnit) const;
+ /// \brief translate the text
+ std::string translateText(const std::string &text) const;
+ /// \brief speed to string in byte per seconds
+ std::string speedToString(const double &speed) const;
+ /// \brief Decompose the time in second
+ Ultracopier::TimeDecomposition secondsToTimeDecomposition(const uint32_t &seconds) const;
+ /// \brief have the fonctionnality
+ bool haveFunctionality(const std::string &fonctionnality) const;
+ /// \brief call the fonctionnality
+ std::string callFunctionality(const std::string &fonctionnality,const std::vector<std::string> &args=std::vector<std::string>());
+ /// \brief Do the simplified time
+ std::string simplifiedRemainingTime(const uint32_t &seconds) const;
+ /// \brief Return ultimate url, empty is not found or already ultimate
+ std::string ultimateUrl() const;
+ /// \brief Return the software name
+ std::string softwareName() const;
+ /// \brief separator native to the current OS
+ static std::string separator();
+
+ static FacilityEngine facilityEngine;
+private:
+ //undirect translated string
+ std::string Translation_perSecond;
+ std::string Translation_tooBig;
+ std::string Translation_B;
+ std::string Translation_KB;
+ std::string Translation_MB;
+ std::string Translation_GB;
+ std::string Translation_TB;
+ std::string Translation_PB;
+ std::string Translation_EB;
+ std::string Translation_ZB;
+ std::string Translation_YB;
+ //simplified remaining time
+ std::string Translation_SimplifiedRemaningTime_LessThan10s;
+ std::string Translation_SimplifiedRemaningTime_AboutSeconds;
+ std::string Translation_SimplifiedRemaningTime_AboutMinutes;
+ std::string Translation_SimplifiedRemaningTime_AboutHours;
+ //internal fonction
+ inline std::string adaptString(const float &nb) const;
+ std::unordered_map<std::string,std::string> translations;
+public slots:
+ /// \brief To force the text re-translation
+ void retranslate();
+};
+
+#endif // FACILITYENGINE_H
diff --git a/HelpDialog.cpp b/HelpDialog.cpp
new file mode 100644
index 0000000..0e266e4
--- /dev/null
+++ b/HelpDialog.cpp
@@ -0,0 +1,145 @@
+/** \file HelpDialog.cpp
+\brief Define the help dialog
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "HelpDialog.h"
+
+#include <QTreeWidgetItem>
+#include <QApplication>
+
+/// \brief Construct the object
+HelpDialog::HelpDialog() :
+ ui(new Ui::HelpDialog)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ ui->setupUi(this);
+ reloadTextValue();
+ #ifdef ULTRACOPIER_DEBUG
+ ui->debugView->setModel(DebugModel::debugModel);
+ connect(ui->pushButtonSaveBugReport,&QPushButton::clicked,DebugEngine::debugEngine,&DebugEngine::saveBugReport);
+ #else // ULTRACOPIER_DEBUG
+ ui->lineEditInsertDebug->hide();
+ ui->debugView->hide();
+ ui->pushButtonSaveBugReport->hide();
+ ui->pushButtonCrash->hide();
+ this->setMaximumSize(QSize(500,128));
+ /*timeToSetText.setInterval(250);
+ timeToSetText.setSingleShot(true);
+ connect(&timeToSetText,QTimer::timeout,this,&DebugEngine::showDebugText);*/
+ ui->pushButtonClose->hide();
+ #endif // ULTRACOPIER_DEBUG
+ //connect the about Qt
+ connect(ui->pushButtonAboutQt,&QPushButton::toggled,&QApplication::aboutQt);
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ setWindowTitle(tr("About Supercopier"));
+ #else
+ setWindowTitle(tr("About Ultracopier"));
+ #endif
+}
+
+/// \brief Destruct the object
+HelpDialog::~HelpDialog()
+{
+ delete ui;
+}
+
+/// \brief To re-translate the ui
+void HelpDialog::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ ui->retranslateUi(this);
+ reloadTextValue();
+ break;
+ default:
+ break;
+ }
+}
+
+/// \brief To reload the text value
+void HelpDialog::reloadTextValue()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ QString text=ui->label_ultracopier->text();
+ #ifdef ULTRACOPIER_VERSION_ULTIMATE
+ text=text.replace(QStringLiteral("%1"),QStringLiteral("Ultimate %1").arg(ULTRACOPIER_VERSION));
+ #else
+ text=text.replace(QStringLiteral("%1"),ULTRACOPIER_VERSION);
+ #endif
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ text=text.replace(QStringLiteral("Ultracopier"),QStringLiteral("Supercopier"),Qt::CaseInsensitive);
+ #endif
+ ui->label_ultracopier->setText(text);
+
+ text=ui->label_description->text();
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ #ifdef ULTRACOPIER_VERSION_PORTABLEAPPS
+ text=text.replace(QStringLiteral("%1"),tr("For http://portableapps.com/"));
+ #else
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ text=text.replace(QStringLiteral("%1"),tr("Portable and all in one version"));
+ #else
+ text=text.replace(QStringLiteral("%1"),tr("Portable version"));
+ #endif
+ #endif
+ #else
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ text=text.replace(QStringLiteral("%1"),tr("All in one version"));
+ #else
+ text=text.replace(QStringLiteral("%1"),tr("Normal version"));
+ #endif
+ #endif
+ ui->label_description->setText(text);
+
+ text=ui->label_site->text();
+ //: This site need be the official site of ultracopier, into the right languages, english if not exists
+ text=text.replace("%1",QString::fromStdString(getWebSite()));
+ ui->label_site->setText(text);
+
+ text=ui->label_platform->text();
+ text=text.replace(QStringLiteral("%1"),ULTRACOPIER_PLATFORM_NAME);
+ ui->label_platform->setText(text);
+}
+
+std::string HelpDialog::getWebSite()
+{
+ return tr("http://ultracopier.first-world.info/").toStdString();
+}
+
+
+std::string HelpDialog::getUpdateUrl()
+{
+ #if defined(ULTRACOPIER_VERSION_ULTIMATE)
+ return tr("http://ultracopier.first-world.info/shop.html").toStdString();
+ #else
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ return tr("http://ultracopier.first-world.info/").toStdString()+"supercopier.html";
+ #else
+ return tr("http://ultracopier.first-world.info/download.html").toStdString();
+ #endif
+ #endif
+}
+
+#ifdef ULTRACOPIER_DEBUG
+void HelpDialog::on_lineEditInsertDebug_returnPressed()
+{
+ DebugEngine::addDebugNote(ui->lineEditInsertDebug->text().toStdString());
+ ui->lineEditInsertDebug->clear();
+ ui->debugView->scrollToBottom();
+}
+#endif // ULTRACOPIER_DEBUG
+
+void HelpDialog::on_pushButtonAboutQt_clicked()
+{
+ QApplication::aboutQt();
+}
+
+void HelpDialog::on_pushButtonCrash_clicked()
+{
+ int a=0;
+ int *b=NULL;
+ *b=3/a;
+}
diff --git a/HelpDialog.h b/HelpDialog.h
new file mode 100644
index 0000000..91e5dbc
--- /dev/null
+++ b/HelpDialog.h
@@ -0,0 +1,48 @@
+/** \file HelpDialog.h
+\brief Define the help dialog
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include <QDialog>
+#include <QString>
+#include <QTimer>
+#include <QColor>
+#include <QBrush>
+
+#include "ui_HelpDialog.h"
+#include "Environment.h"
+
+namespace Ui {
+ class HelpDialog;
+}
+
+/** \brief Help dialog, and some user oriented repport/debug function */
+class HelpDialog : public QDialog {
+ Q_OBJECT
+ public:
+ /// \brief Construct the object
+ HelpDialog();
+ /// \brief Destruct the object
+ ~HelpDialog();
+ static std::string getWebSite();
+ static std::string getUpdateUrl();
+ protected:
+ /// \brief To re-translate the ui
+ void changeEvent(QEvent *e);
+ private:
+ Ui::HelpDialog *ui;
+ /// \brief To reload the text value
+ void reloadTextValue();
+ private slots:
+ #ifdef ULTRACOPIER_DEBUG
+ /// \brief Add debug text
+ void on_lineEditInsertDebug_returnPressed();
+ #endif // ULTRACOPIER_DEBUG
+ void on_pushButtonAboutQt_clicked();
+ void on_pushButtonCrash_clicked();
+};
+
+#endif // DIALOG_H
diff --git a/HelpDialog.ui b/HelpDialog.ui
new file mode 100644
index 0000000..5d42f18
--- /dev/null
+++ b/HelpDialog.ui
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HelpDialog</class>
+ <widget class="QDialog" name="HelpDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>681</width>
+ <height>389</height>
+ </rect>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777214</height>
+ </size>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources/ultracopier-resources.qrc">
+ <normaloff>:/ultracopier-16x16.png</normaloff>:/ultracopier-16x16.png</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="minimumSize">
+ <size>
+ <width>128</width>
+ <height>128</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>128</width>
+ <height>128</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="resources/ultracopier-resources.qrc">:/ultracopier-128x128.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_ultracopier">
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string notr="true">Ultracopier %1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_description">
+ <property name="text">
+ <string extracomment="%1 will be replaced by a variable content (normal, debug, ...)">Based on Qt. Advanced utility to copy files under GPL3 license.
+This version is compiled as version: %1.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_site">
+ <property name="text">
+ <string extracomment="%1 will be remplaced by the website into the corresponding languages">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;For more information see the website &lt;a href=&quot;%1&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;%1&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_platform">
+ <property name="text">
+ <string extracomment="%1 will be replaced by the platform (windows, mac, linux, ...)">Platform: %1</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditInsertDebug">
+ <property name="toolTip">
+ <string notr="true">Insert debug note to annotate some special action at current time</string>
+ </property>
+ <property name="statusTip">
+ <string notr="true">Insert debug note to annotate some special action at current time</string>
+ </property>
+ <property name="placeholderText">
+ <string notr="true">Insert debug note to annotate some special action at current time</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeView" name="debugView">
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayoutButton">
+ <item>
+ <widget class="QPushButton" name="pushButtonAboutQt">
+ <property name="text">
+ <string>About Qt</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonCrash">
+ <property name="text">
+ <string>Do a crash</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonSaveBugReport">
+ <property name="text">
+ <string>Save bug report</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>debugView</tabstop>
+ <tabstop>lineEditInsertDebug</tabstop>
+ <tabstop>pushButtonAboutQt</tabstop>
+ <tabstop>pushButtonSaveBugReport</tabstop>
+ <tabstop>pushButtonClose</tabstop>
+ </tabstops>
+ <resources>
+ <include location="resources/ultracopier-resources.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>pushButtonClose</sender>
+ <signal>clicked()</signal>
+ <receiver>HelpDialog</receiver>
+ <slot>hide()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>387</x>
+ <y>216</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>329</x>
+ <y>212</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/InternetUpdater.cpp b/InternetUpdater.cpp
new file mode 100644
index 0000000..a3dbded
--- /dev/null
+++ b/InternetUpdater.cpp
@@ -0,0 +1,110 @@
+#include "InternetUpdater.h"
+#include "EventDispatcher.h"
+#include "OptionEngine.h"
+#include "cpp11addition.h"
+
+#ifdef ULTRACOPIER_INTERNET_SUPPORT
+
+#include <QNetworkRequest>
+#include <QUrl>
+
+#include "PluginsManager.h"
+
+InternetUpdater::InternetUpdater(QObject *parent) :
+ QObject(parent)
+{
+ connect(&newUpdateTimer,&QTimer::timeout,this,&InternetUpdater::downloadFile);
+ connect(&firstUpdateTimer,&QTimer::timeout,this,&InternetUpdater::downloadFile);
+ newUpdateTimer.start(1000*3600);
+ firstUpdateTimer.setSingleShot(true);
+ firstUpdateTimer.start(1000*60);
+}
+
+void InternetUpdater::downloadFile()
+{
+ if(!stringtobool(OptionEngine::optionEngine->getOptionValue("Ultracopier","checkTheUpdate")))
+ return;
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ std::string name="Supercopier";
+ #else
+ std::string name="Ultracopier";
+ #endif
+ std::string ultracopierVersion;
+ #ifdef ULTRACOPIER_VERSION_ULTIMATE
+ ultracopierVersion=name+" Ultimate/"+ULTRACOPIER_VERSION;
+ #else
+ ultracopierVersion=name+"/"+ULTRACOPIER_VERSION;
+ #endif
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ ultracopierVersion+=" portable/all-in-one";
+ #else
+ ultracopierVersion+=" portable";
+ #endif
+ #else
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ ultracopierVersion+=" all-in-one";
+ #endif
+ #endif
+ #if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
+ ultracopierVersion+=" (OS: "+EventDispatcher::GetOSDisplayString()+")";
+ #endif
+ ultracopierVersion+=" "+std::string(ULTRACOPIER_PLATFORM_CODE);
+ QNetworkRequest networkRequest(QStringLiteral(ULTRACOPIER_UPDATER_URL));
+ networkRequest.setHeader(QNetworkRequest::UserAgentHeader,QString::fromStdString(ultracopierVersion));
+ networkRequest.setRawHeader("Connection", "Close");
+ reply = qnam.get(networkRequest);
+ connect(reply, &QNetworkReply::finished, this, &InternetUpdater::httpFinished);
+}
+
+void InternetUpdater::httpFinished()
+{
+ QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (!reply->isFinished())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"get the new update failed: not finished");
+ reply->deleteLater();
+ return;
+ }
+ else if (reply->error())
+ {
+ newUpdateTimer.stop();
+ newUpdateTimer.start(1000*3600*24);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"get the new update failed: "+reply->errorString().toStdString());
+ reply->deleteLater();
+ return;
+ } else if (!redirectionTarget.isNull()) {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"redirection denied to: "+redirectionTarget.toUrl().toString().toStdString());
+ reply->deleteLater();
+ return;
+ }
+ QString newVersion=QString::fromUtf8(reply->readAll());
+ if(newVersion.isEmpty())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"version string is empty");
+ reply->deleteLater();
+ return;
+ }
+ newVersion.remove("\n");
+ if(!newVersion.contains(QRegularExpression(QLatin1Literal("^[0-9]+(\\.[0-9]+)+$"))))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"version string don't match: "+newVersion.toStdString());
+ reply->deleteLater();
+ return;
+ }
+ if(newVersion==ULTRACOPIER_VERSION)
+ {
+ reply->deleteLater();
+ return;
+ }
+ if(PluginsManager::compareVersion(newVersion.toStdString(),"<=",ULTRACOPIER_VERSION))
+ {
+ reply->deleteLater();
+ return;
+ }
+ newUpdateTimer.stop();
+ emit newUpdate(newVersion.toStdString());
+ reply->deleteLater();
+}
+
+#endif
diff --git a/InternetUpdater.h b/InternetUpdater.h
new file mode 100644
index 0000000..25b13f4
--- /dev/null
+++ b/InternetUpdater.h
@@ -0,0 +1,33 @@
+#ifndef INTERNETUPDATER_H
+#define INTERNETUPDATER_H
+
+#include "Environment.h"
+
+#include <QObject>
+#include <QString>
+#include <QTimer>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+
+#ifdef ULTRACOPIER_INTERNET_SUPPORT
+
+class InternetUpdater : public QObject
+{
+ Q_OBJECT
+public:
+ explicit InternetUpdater(QObject *parent = 0);
+signals:
+ void newUpdate(const std::string &version) const;
+private:
+ QTimer newUpdateTimer;
+ QTimer firstUpdateTimer;
+ QNetworkAccessManager qnam;
+ QNetworkReply *reply;
+private slots:
+ void downloadFile();
+ void httpFinished();
+};
+
+#endif
+
+#endif // INTERNETUPDATER_H
diff --git a/LanguagesManager.cpp b/LanguagesManager.cpp
new file mode 100644
index 0000000..a8849c4
--- /dev/null
+++ b/LanguagesManager.cpp
@@ -0,0 +1,287 @@
+/** \file LanguagesManager.cpp
+\brief Define the class to manage and load the languages
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QDir>
+#include <QLibraryInfo>
+
+#include "LanguagesManager.h"
+#include "FacilityEngine.h"
+#include "cpp11addition.h"
+
+/// \brief Create the manager and load the defaults variables
+LanguagesManager::LanguagesManager()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ //load the rest
+ std::vector<std::string> resourcesPaths=ResourcesManager::resourcesManager->getReadPath();
+ unsigned int index=0;
+ while(index<resourcesPaths.size())
+ {
+ std::string composedTempPath=resourcesPaths.at(index)+"Languages"+FacilityEngine::separator();
+ QDir LanguagesConfiguration(QString::fromStdString(composedTempPath));
+ if(LanguagesConfiguration.exists())
+ languagePath.push_back(composedTempPath);
+ index++;
+ }
+ //load the plugins
+ PluginsManager::pluginsManager->lockPluginListEdition();
+ connect(this,&LanguagesManager::previouslyPluginAdded, this, &LanguagesManager::onePluginAdded,Qt::QueuedConnection);
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginAdded,this, &LanguagesManager::onePluginAdded,Qt::QueuedConnection);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginWillBeRemoved, this, &LanguagesManager::onePluginWillBeRemoved,Qt::DirectConnection);
+ #endif
+ connect(PluginsManager::pluginsManager,&PluginsManager::pluginListingIsfinish, this, &LanguagesManager::allPluginIsLoaded,Qt::QueuedConnection);
+ std::vector<PluginsAvailable> list=PluginsManager::pluginsManager->getPluginsByCategory(PluginType_Languages);
+ foreach(PluginsAvailable currentPlugin,list)
+ emit previouslyPluginAdded(currentPlugin);
+ PluginsManager::pluginsManager->unlockPluginListEdition();
+ //load the GUI option
+ std::vector<std::pair<std::string, std::string> > KeysList;
+ KeysList.push_back(std::pair<std::string, std::string>("Language","en"));
+ KeysList.push_back(std::pair<std::string, std::string>("Language_force","false"));
+ OptionEngine::optionEngine->addOptionGroup("Language",KeysList);
+// connect(this, &LanguagesManager::newLanguageLoaded, plugins,&PluginsManager::refreshPluginList);
+// connect(this, &LanguagesManager::newLanguageLoaded, this,&LanguagesManager::retranslateTheUI);
+ connect(OptionEngine::optionEngine,&OptionEngine::newOptionValue, this, &LanguagesManager::newOptionValue,Qt::QueuedConnection);
+ connect(this, &LanguagesManager::newLanguageLoaded, PluginsManager::pluginsManager,&PluginsManager::newLanguageLoaded,Qt::QueuedConnection);
+}
+
+/// \brief Destroy the language manager
+LanguagesManager::~LanguagesManager()
+{
+}
+
+/// \brief load the language selected, return the main short code like en, fr, ..
+std::string LanguagesManager::getTheRightLanguage() const
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ if(LanguagesAvailableList.size()==0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"empty combobox list, failing back to english");
+ return "en";
+ }
+ else
+ {
+ if(!stringtobool(OptionEngine::optionEngine->getOptionValue("Language","Language_force")))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"language auto-detection, QLocale::system().name(): "+QLocale::system().name().toStdString()+", QLocale::languageToString(QLocale::system().language()): "+QLocale::languageToString(QLocale::system().language()).toStdString());
+ std::string tempLanguage=getMainShortName(QLocale::languageToString(QLocale::system().language()).toStdString());
+ if(!tempLanguage.empty())
+ return tempLanguage;
+ else
+ {
+ tempLanguage=getMainShortName(QLocale::system().name().toStdString());
+ if(!tempLanguage.empty())
+ return tempLanguage;
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Autodetection of the language failed, QLocale::languageToString(QLocale::system().language()): "+QLocale::languageToString(QLocale::system().language()).toStdString()+", QLocale::system().name(): "+QLocale::system().name().toStdString()+", failing back to english");
+ return OptionEngine::optionEngine->getOptionValue("Language","Language");
+ }
+ }
+ }
+ else
+ return OptionEngine::optionEngine->getOptionValue("Language","Language");
+ }
+}
+
+/* \brief To set the current language
+\param newLanguage Should be short name code found into informations.xml of language file */
+void LanguagesManager::setCurrentLanguage(const std::string &newLanguage)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+newLanguage);
+ //protection for re-set the same language
+ if(currentLanguage==newLanguage)
+ return;
+ //store the language
+ PluginsManager::pluginsManager->setLanguage(newLanguage);
+ //unload the old language
+ if(currentLanguage!="en")
+ {
+ unsigned int indexTranslator=0;
+ while(indexTranslator<installedTranslator.size())
+ {
+ QCoreApplication::removeTranslator(installedTranslator.at(indexTranslator));
+ delete installedTranslator.at(indexTranslator);
+ indexTranslator++;
+ }
+ installedTranslator.clear();
+ }
+ unsigned int index=0;
+ while(index<LanguagesAvailableList.size())
+ {
+ if(LanguagesAvailableList.at(index).mainShortName==newLanguage)
+ {
+ //load the new language
+ if(newLanguage!="en")
+ {
+ QTranslator *temp;
+ std::vector<std::string> fileToLoad;
+ //load the language main
+ if(newLanguage=="en")
+ fileToLoad.push_back(":/Languages/en/translation.qm");
+ else
+ fileToLoad.push_back(LanguagesAvailableList.at(index).path+"translation.qm");
+ //load the language plugin
+ std::vector<PluginsAvailable> listLoadedPlugins=PluginsManager::pluginsManager->getPlugins();
+ unsigned int indexPluginIndex=0;
+ while(indexPluginIndex<listLoadedPlugins.size())
+ {
+ if(listLoadedPlugins.at(indexPluginIndex).category!=PluginType_Languages)
+ {
+ std::string tempPath=listLoadedPlugins.at(indexPluginIndex).path+"Languages"+FacilityEngine::separator()+LanguagesAvailableList.at(index).mainShortName+FacilityEngine::separator()+"translation.qm";
+ if(QFile::exists(QString::fromStdString(tempPath)))
+ fileToLoad.push_back(tempPath);
+ }
+ indexPluginIndex++;
+ }
+ unsigned int indexTranslationFile=0;
+ while(indexTranslationFile<fileToLoad.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Translation to load: "+fileToLoad.at(indexTranslationFile));
+ temp=new QTranslator();
+ if(!temp->load(QString::fromStdString(fileToLoad.at(indexTranslationFile))) || temp->isEmpty())
+ {
+ delete temp;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to load the translation file: "+fileToLoad.at(indexTranslationFile));
+ }
+ else
+ {
+ QCoreApplication::installTranslator(temp);
+ installedTranslator.push_back(temp);
+ }
+ indexTranslationFile++;
+ }
+ temp=new QTranslator();
+ if(temp->load(QString("qt_")+QString::fromStdString(newLanguage), QLibraryInfo::location(QLibraryInfo::TranslationsPath)) && !temp->isEmpty())
+ {
+ QCoreApplication::installTranslator(temp);
+ installedTranslator.push_back(temp);
+ }
+ else
+ {
+ if(!temp->load(QString::fromStdString(LanguagesAvailableList.at(index).path)+"qt.qm") || temp->isEmpty())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to load the translation file: qt.qm, into: "+LanguagesAvailableList.at(index).path);
+ delete temp;
+ }
+ else
+ {
+ QCoreApplication::installTranslator(temp);
+ installedTranslator.push_back(temp);
+ }
+ }
+ }
+ currentLanguage=newLanguage;
+ FacilityEngine::facilityEngine.retranslate();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"emit newLanguageLoaded()");
+ emit newLanguageLoaded(currentLanguage);
+ return;
+ }
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to found language: "+newLanguage+", LanguagesAvailableList.size(): "+std::to_string(LanguagesAvailableList.size()));
+}
+
+/// \brief check if short name is found into language
+std::string LanguagesManager::getMainShortName(const std::string &shortName) const
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<LanguagesAvailableList.size())
+ {
+ const LanguagesAvailable &languagesAvailable=LanguagesAvailableList.at(index);
+ if(languagesAvailable.shortName.find(shortName)!=languagesAvailable.shortName.cend() || languagesAvailable.fullName==shortName)
+ return languagesAvailable.mainShortName;
+ index++;
+ }
+ return "";
+}
+
+/// \brief load the language in languagePath
+void LanguagesManager::allPluginIsLoaded()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ setCurrentLanguage(getTheRightLanguage());
+}
+
+const std::string LanguagesManager::autodetectedLanguage() const
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"language auto-detection, QLocale::system().name(): "+QLocale::system().name().toStdString()+", QLocale::languageToString(QLocale::system().language()): "+QLocale::languageToString(QLocale::system().language()).toStdString());
+ std::string tempLanguage=getMainShortName(QLocale::languageToString(QLocale::system().language()).toStdString());
+ if(!tempLanguage.empty())
+ return tempLanguage;
+ else
+ {
+ tempLanguage=getMainShortName(QLocale::system().name().toStdString());
+ if(!tempLanguage.empty())
+ return tempLanguage;
+ }
+ return std::string();
+}
+
+void LanguagesManager::onePluginAdded(const PluginsAvailable &plugin)
+{
+ if(plugin.category!=PluginType_Languages)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ QDomElement child = plugin.categorySpecific.firstChildElement(QStringLiteral("fullName"));
+ LanguagesAvailable temp;
+ if(!child.isNull() && child.isElement())
+ temp.fullName=child.text().toStdString();
+ child = plugin.categorySpecific.firstChildElement(QStringLiteral("shortName"));
+ while(!child.isNull())
+ {
+ if(child.isElement())
+ {
+ if(child.hasAttribute("mainCode") && child.attribute(QStringLiteral("mainCode"))==QStringLiteral("true"))
+ temp.mainShortName=child.text().toStdString();
+ temp.shortName.insert(child.text().toStdString());
+ }
+ child = child.nextSiblingElement(QStringLiteral("shortName"));
+ }
+ temp.path=plugin.path;
+ if(temp.fullName.empty())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"fullName empty for: "+plugin.path);
+ else if(temp.path.empty())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"path empty for: "+plugin.path);
+ else if(temp.mainShortName.empty())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"mainShortName empty for: "+plugin.path);
+ else if(temp.shortName.size()<=0)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"temp.shortName.size()<=0 for: "+plugin.path);
+ else if(!QFile::exists(QString::fromStdString(temp.path)+QStringLiteral("flag.png")))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"flag file not found for: "+plugin.path);
+ else if(!QFile::exists(QString::fromStdString(temp.path)+QStringLiteral("translation.qm")) && temp.mainShortName!="en")
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"translation not found for: "+plugin.path);
+ else
+ LanguagesAvailableList.push_back(temp);
+ if(PluginsManager::pluginsManager->allPluginHaveBeenLoaded())
+ setCurrentLanguage(getTheRightLanguage());
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+void LanguagesManager::onePluginWillBeRemoved(const PluginsAvailable &plugin)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<LanguagesAvailableList.size())
+ {
+ if(plugin.path==LanguagesAvailableList.at(index).path)
+ {
+ return;
+ }
+ index++;
+ }
+}
+#endif
+
+void LanguagesManager::newOptionValue(const std::string &group)
+{
+ if(group=="Language")
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"group: "+group);
+ setCurrentLanguage(getTheRightLanguage());
+ }
+}
diff --git a/LanguagesManager.h b/LanguagesManager.h
new file mode 100644
index 0000000..e7c715e
--- /dev/null
+++ b/LanguagesManager.h
@@ -0,0 +1,78 @@
+/** \file LanguagesManager.h
+\brief Define the class to manage and load the languages
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef LANGUAGES_MANAGER_H
+#define LANGUAGES_MANAGER_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QList>
+#include <QLocale>
+#include <QTranslator>
+#include <QByteArray>
+#include <QCoreApplication>
+#include <QDir>
+#include <unordered_set>
+
+#include "Environment.h"
+#include "OptionEngine.h"
+#include "ResourcesManager.h"
+#include "PluginsManager.h"
+
+/** \brief Define the class to manage and load the resources linked with the themes
+
+This class provide a core load and manage the resources */
+class LanguagesManager : public QObject
+{
+ Q_OBJECT
+ //public:
+ // QString getMainShortName();
+ public:
+ const std::string autodetectedLanguage() const;
+ static LanguagesManager *languagesManager;
+ /// \brief Create the manager and load the defaults variables
+ LanguagesManager();
+ /// \brief Destroy the language manager
+ ~LanguagesManager();
+ private:
+ /** \brief To set the current language
+ \param newLanguage Should be short name code found into informations.xml of language file */
+ void setCurrentLanguage(const std::string &newLanguage);
+ /// \brief Structure of language
+ struct LanguagesAvailable
+ {
+ std::string path;
+ std::string fullName;
+ std::string mainShortName;
+ std::unordered_set<std::string> shortName;
+ };
+ /// \brief To store the language path
+ std::vector<std::string> languagePath;
+ /// \brief To store the language detected
+ std::vector<LanguagesAvailable> LanguagesAvailableList;
+ /// \brief check if short name is found into language
+ std::string getMainShortName(const std::string &shortName) const;
+ /// \brief list of installed translator
+ std::vector<QTranslator *> installedTranslator;
+ std::string currentLanguage;
+ /// \brief load the language selected
+ std::string getTheRightLanguage() const;
+ private slots:
+ /// \brief load the language in languagePath
+ void allPluginIsLoaded();
+ //plugin management
+ void onePluginAdded(const PluginsAvailable &plugin);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ void onePluginWillBeRemoved(const PluginsAvailable &plugin);
+ #endif
+ void newOptionValue(const std::string &group);
+ signals:
+ //send the language is loaded or the new language is loaded
+ void newLanguageLoaded(const std::string &mainShortName) const;
+ void previouslyPluginAdded(PluginsAvailable) const;
+};
+
+#endif // LANGUAGES_MANAGER_H
diff --git a/LocalListener.cpp b/LocalListener.cpp
new file mode 100644
index 0000000..4a418aa
--- /dev/null
+++ b/LocalListener.cpp
@@ -0,0 +1,348 @@
+/** \file LocalListener.cpp
+\brief The have local server, to have unique instance, and send arguments to the current running instance
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "LocalListener.h"
+#include "PluginsManager.h"
+
+#include <QLocalSocket>
+#include <QDir>
+
+LocalListener::LocalListener(QObject *parent) :
+ QObject(parent)
+{
+ //for detect the timeout on QLocalSocket
+ TimeOutQLocalSocket.setInterval(500);
+ TimeOutQLocalSocket.setSingleShot(true);
+ connect(&TimeOutQLocalSocket, &QTimer::timeout, this, &LocalListener::timeoutDectected);
+ connect(PluginsManager::pluginsManager,&PluginsManager::pluginListingIsfinish,this, &LocalListener::allPluginIsloaded,Qt::QueuedConnection);
+}
+
+LocalListener::~LocalListener()
+{
+ if(localServer.isListening())
+ {
+ localServer.close();
+ if(!QLocalServer::removeServer(QString::fromStdString(ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME))))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to remove the listening server");
+ }
+}
+
+bool LocalListener::tryConnect()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ QStringList ultracopierArguments=QCoreApplication::arguments();
+ //remove excutable path because is useless (unsafe to use)
+ ultracopierArguments.removeFirst();
+ //add the current path to file full path resolution if needed
+ ultracopierArguments.insert(0,QDir::currentPath());
+
+ std::vector<std::string> ultracopierArgumentsStd;
+ {
+ int index=0;
+ while(index<ultracopierArguments.size())
+ {
+ ultracopierArgumentsStd.push_back(ultracopierArguments.at(index).toStdString());
+ index++;
+ }
+ }
+
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString::fromStdString(ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME)),QIODevice::WriteOnly);
+ if(localSocket.waitForConnected(1000))
+ {
+ if(!localSocket.isValid())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"localSocket is not valid!");
+ return false;
+ }
+ emit cli(ultracopierArgumentsStd,false,true);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"connection succes, number arguments given: "+std::to_string(ultracopierArgumentsStd.size()));
+ #ifdef ULTRACOPIER_DEBUG
+ for (int i = 0; i < ultracopierArguments.size(); ++i) {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"argument["+std::to_string(i)+"]: "+ultracopierArgumentsStd.at(i));
+ }
+ #endif // ULTRACOPIER_DEBUG
+ //cut string list and send it as block of 32KB
+ QByteArray block;
+ QDataStream out(&block, QIODevice::WriteOnly);
+ //for total size
+ out << int(0);
+ //send the arguments
+ out << ultracopierArguments;
+ //write the size content
+ out.device()->seek(0);
+ out << block.size();
+ do
+ {
+ QByteArray blockToSend;
+ blockToSend=block.left(32*1024);//32KB
+ block.remove(0,blockToSend.size());
+ #ifdef ULTRACOPIER_DEBUG
+ int byteWriten =
+ #endif
+ localSocket.write(blockToSend);
+ #ifdef ULTRACOPIER_DEBUG
+ if(!localSocket.isValid())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"localSocket is not valid!");
+ if(localSocket.errorString()!="Unknown error" && localSocket.errorString()!="")
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"localSocket->errorString(): "+localSocket.errorString().toStdString());
+ if(blockToSend.size()!=byteWriten)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"blockToSend("+std::to_string(blockToSend.size())+
+ ")!=byteWriten("+std::to_string(byteWriten)+")");
+ #endif // ULTRACOPIER_DEBUG
+ if(localSocket.waitForBytesWritten(200))
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Block send correctly");
+ }
+ else
+ {
+ QMessageBox::critical(NULL,"Alert","No arguments send because timeout detected!");
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Block not send correctly");
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"blockToSend: "+blockToSend.toHex().toStdString());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"byteWriten: "+std::to_string(byteWriten)+
+ ", size sending: "+std::to_string(blockToSend.size()));
+ }
+ while(block.size());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"disconnect the socket");
+ localSocket.disconnectFromServer();
+ return true;
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"connection failed, continue...");
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ultracopierArguments: "+ultracopierArguments.join(";").toStdString());
+ return false;
+ }
+}
+
+/// the listen server
+void LocalListener::listenServer()
+{
+ if(!QLocalServer::removeServer(QString::fromStdString(ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME))))
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to remove the listening server");
+ #ifndef Q_OS_MAC
+ localServer.setSocketOptions(QLocalServer::UserAccessOption);
+ #endif
+ if(!localServer.listen(QString::fromStdString(ExtraSocket::pathSocket(ULTRACOPIER_SOCKETNAME))))
+ {
+ #ifndef Q_OS_MAC
+ //QMessageBox::critical(NULL,"Alert",QStringLiteral("Ultracopier have not able to lock unique instance: %1").arg(localServer.errorString()));
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Ultracopier have not able to lock unique instance: "+localServer.errorString().toStdString()+
+ ", error code: "+std::to_string((int32_t)localServer.serverError()));
+ }
+ else
+ connect(&localServer, &QLocalServer::newConnection, this, &LocalListener::newConnexion);
+}
+
+//the time is done
+void LocalListener::timeoutDectected()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"start");
+ if(clientList.size()>0)
+ {
+ unsigned int index=0;
+ bool haveData=false;
+ while(index<clientList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"clientList.first().size: "+std::to_string(clientList.front().size));
+ if(!clientList.at(index).data.isEmpty() || clientList.at(index).haveData)
+ {
+ haveData=true;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Timeout while recomposing data from connected clients: "+clientList.at(index).data.toHex().toStdString());
+ clientList.erase(clientList.cbegin());
+ }
+ else
+ index++;
+ }
+ if(haveData)
+ QMessageBox::warning(NULL,tr("Warning"),tr("Timeout while recomposing data from connected clients"));
+ }
+}
+
+/// \brief Data is incomming
+void LocalListener::dataIncomming()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"start");
+ // 1 : we get packets from client
+
+ //Which client send the message (Search of the QLocalSocket of client)
+ QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
+ if (socket == 0) // If not found
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"bad socket");
+ return;
+ }
+
+ int index=-1;
+ for (unsigned int i=0;i<clientList.size(); ++i) {
+ if(clientList.at(i).socket==socket)
+ index=i;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"socket->bytesAvailable() "+std::to_string(socket->bytesAvailable()));
+ if(index!=-1)
+ {
+ if(!clientList.at(index).haveData)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"tempComposed index found, but no have data, create new entry");
+ // If all is ok we get the message
+ QDataStream in(socket);
+ in.setVersion(QDataStream::Qt_4_4);
+
+ if (socket->bytesAvailable() < (int)sizeof(quint32)*2) // We have not receveive all the message, ignore because first int is cuted!
+ {
+ /*socket->readAll();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"wrong size for set the message size");*/
+ return;
+ }
+ in >> clientList[index].size; // Store the size of the message
+ clientList[index].size-=sizeof(int);
+
+ // Check if all the message size is the same as the size given
+ if(socket->bytesAvailable() < clientList.at(index).size) // If not all get then stop it
+ {
+ clientList[index].haveData=true;
+ clientList[index].data.append(socket->readAll());
+ TimeOutQLocalSocket.start();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Need wait to recomposite: "+std::to_string(clientList.at(index).data.size())+
+ ", targeted: "+std::to_string(clientList.at(index).size));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"tempComposed.data: "+clientList.at(index).data.toHex().toStdString());
+ }
+ else if(socket->bytesAvailable() == clientList.at(index).size) //if the size match
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"socket->bytesAvailable(): "+std::to_string(socket->bytesAvailable())+
+ ", for total of: "+std::to_string(socket->bytesAvailable()+sizeof(uint32_t)));
+ QStringList ultracopierArguments;
+ in >> ultracopierArguments;
+ std::vector<std::string> ultracopierArgumentsStd;
+ {
+ int index=0;
+ while(index<ultracopierArguments.size())
+ {
+ ultracopierArgumentsStd.push_back(ultracopierArguments.at(index).toStdString());
+ index++;
+ }
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ultracopierArguments: "+ultracopierArguments.join(";").toStdString());
+ emit cli(ultracopierArgumentsStd,true,false);
+ clientList[index].data.clear();
+ clientList[index].haveData=false;
+ TimeOutQLocalSocket.stop();
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"socket->bytesAvailable(): "+std::to_string(socket->bytesAvailable())+" > clientList.at(index).size!: "+std::to_string(clientList.at(index).size));
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Query recomposed with this size: "+std::to_string(clientList.at(index).data.size()));
+ clientList[index].data.append(socket->readAll());
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Query recomposed with this size: "+std::to_string(clientList.at(index).data.size()));
+ if(clientList.at(index).data.size()==clientList.at(index).size)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"QByteArray reconstruction finished");
+ QDataStream in(clientList.at(index).data);
+ QStringList ultracopierArguments;
+ in >> ultracopierArguments;
+ std::vector<std::string> ultracopierArgumentsStd;
+ {
+ int index=0;
+ while(index<ultracopierArguments.size())
+ {
+ ultracopierArgumentsStd.push_back(ultracopierArguments.at(index).toStdString());
+ index++;
+ }
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"ultracopierArguments: "+ultracopierArguments.join(";").toStdString());
+ emit cli(ultracopierArgumentsStd,true,false);
+ clientList[index].data.clear();
+ clientList[index].haveData=false;
+ TimeOutQLocalSocket.stop();
+ }
+ else
+ {
+ TimeOutQLocalSocket.start();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Need wait to recomposite: "+std::to_string(clientList.at(index).data.size())+", targeted: "+std::to_string(clientList.at(index).size));
+ return;
+ }
+ }
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Socket not found???");
+}
+
+/// \brief Deconnexion client
+/// \todo Remove the data in wait linker with this socket
+void LocalListener::deconnectClient()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+
+ // Wich client leave
+ QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
+ if (socket == 0) // If not found
+ return;
+ for (unsigned int i = 0; i < clientList.size(); ++i) {
+ if(clientList.at(i).socket==socket)
+ clientList.erase(clientList.cbegin()+i);
+ }
+ socket->deleteLater();
+}
+
+/// LocalListener New connexion
+void LocalListener::newConnexion()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"start");
+ ComposedData newClient;
+ newClient.socket = localServer.nextPendingConnection();
+ #ifdef ULTRACOPIER_DEBUG
+ connect(newClient.socket, static_cast<void(QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error), this, &LocalListener::error);
+ //connect(newClient.socket, &QLocalSocket::error, this, &LocalListener::error);
+ //connect(newClient.socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(error(QLocalSocket::LocalSocketError)));
+ #endif
+ connect(newClient.socket, &QLocalSocket::readyRead, this, &LocalListener::dataIncomming);
+ connect(newClient.socket, &QLocalSocket::disconnected, this, &LocalListener::deconnectClient);
+ newClient.size=-1;
+ newClient.haveData=false;
+ clientList.push_back(newClient);
+}
+
+#ifdef ULTRACOPIER_DEBUG
+/** \brief If error occured at socket
+\param theErrorDefine The error define */
+void LocalListener::error(const QLocalSocket::LocalSocketError &theErrorDefine)
+{
+ if(theErrorDefine!=QLocalSocket::PeerClosedError)
+ {
+ QLocalSocket *client=qobject_cast<QLocalSocket *>(QObject::sender());
+ if(client!=NULL)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Value:"+std::to_string(theErrorDefine)+", Error message: "+client->errorString().toStdString());
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Value:"+std::to_string(theErrorDefine));
+ }
+}
+#endif
+
+/// \can now parse the cli
+void LocalListener::allPluginIsloaded()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ QStringList ultracopierArguments=QCoreApplication::arguments();
+ //remove excutable path because is useless (unsafe to use)
+ ultracopierArguments.removeFirst();
+ //add the current path to file full path resolution if needed
+ ultracopierArguments.insert(0,QDir::currentPath());
+
+ std::vector<std::string> ultracopierArgumentsStd;
+ {
+ int index=0;
+ while(index<ultracopierArguments.size())
+ {
+ ultracopierArgumentsStd.push_back(ultracopierArguments.at(index).toStdString());
+ index++;
+ }
+ }
+
+ emit cli(ultracopierArgumentsStd,false,false);
+}
diff --git a/LocalListener.h b/LocalListener.h
new file mode 100644
index 0000000..9f91a95
--- /dev/null
+++ b/LocalListener.h
@@ -0,0 +1,65 @@
+/** \file LocalListener.h
+\brief The have local server, to have unique instance, and send arguments to the current running instance
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef LOCALLISTENER_H
+#define LOCALLISTENER_H
+
+#include <QObject>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include <QStringList>
+#include <QString>
+#include <QCoreApplication>
+#include <QMessageBox>
+#include <QTimer>
+#include <QList>
+#include <QByteArray>
+
+#include "Environment.h"
+#include "ExtraSocket.h"
+
+/** \brief To have unique instance, and pass arguments to the existing instance if needed */
+class LocalListener : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LocalListener(QObject *parent = 0);
+ ~LocalListener();
+public slots:
+ /// try connect to existing server
+ bool tryConnect();
+ /// the listen server
+ void listenServer();
+private:
+ QLocalServer localServer;
+ QTimer TimeOutQLocalSocket;/// \todo by client
+ typedef struct {
+ QLocalSocket * socket;
+ QByteArray data;
+ int size;
+ bool haveData;
+ } ComposedData;
+ std::vector<ComposedData> clientList;
+private slots:
+ //the time is done
+ void timeoutDectected();
+ /// \brief Data is incomming
+ void dataIncomming();
+ /// \brief Deconnexion client
+ void deconnectClient();
+ /// LocalListener New connexion
+ void newConnexion();
+ #ifdef ULTRACOPIER_DEBUG
+ /** \brief If error occured at socket
+ \param theErrorDefine The error define */
+ void error(const QLocalSocket::LocalSocketError &theErrorDefine);
+ #endif
+ /// can now parse the cli
+ void allPluginIsloaded();
+signals:
+ void cli(const std::vector<std::string> &ultracopierArguments,const bool &external,const bool &onlyCheck) const;
+};
+
+#endif // LOCALLISTENER_H
diff --git a/LocalPluginOptions.cpp b/LocalPluginOptions.cpp
new file mode 100644
index 0000000..f981e0b
--- /dev/null
+++ b/LocalPluginOptions.cpp
@@ -0,0 +1,59 @@
+/** \file LocalPluginOptions.cpp
+\brief To bind the options of the plugin, into unique group options
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "LocalPluginOptions.h"
+
+LocalPluginOptions::LocalPluginOptions(const std::string &group)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start(\""+group+"\",[...])");
+ groupOptionAdded=false;
+ this->group=group;
+ connect(OptionEngine::optionEngine,&OptionEngine::resetOptions,this,&OptionInterface::resetOptions);
+}
+
+LocalPluginOptions::~LocalPluginOptions()
+{
+ if(groupOptionAdded)
+ {
+ if(OptionEngine::optionEngine!=NULL)
+ OptionEngine::optionEngine->removeOptionGroup(group);
+ }
+}
+
+/// \brief To add option group to options
+bool LocalPluginOptions::addOptionGroup(const std::vector<std::pair<std::string, std::string> > &KeysList)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start(\""+group+"\",[...])");
+ if(groupOptionAdded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Group already added!");
+ return false;
+ }
+ else
+ {
+ groupOptionAdded=true;
+ return OptionEngine::optionEngine->addOptionGroup(group,KeysList);
+ }
+}
+
+/// \brief To get option value
+std::string LocalPluginOptions::getOptionValue(const std::string &variableName) const
+{
+ return OptionEngine::optionEngine->getOptionValue(group,variableName);
+}
+
+/// \brief To set option value
+void LocalPluginOptions::setOptionValue(const std::string &variableName,const std::string &value)
+{
+ OptionEngine::optionEngine->setOptionValue(group,variableName,value);
+}
+
+/*-> disabled because the value will not externaly changed, then useless notification
+void LocalPluginOptions::newOptionValue(QString group,QString variable,QVariant value)
+{
+ if(group==this->group)
+ emit newOptionValue(variable,value);
+}*/
+
diff --git a/LocalPluginOptions.h b/LocalPluginOptions.h
new file mode 100644
index 0000000..9f30f2f
--- /dev/null
+++ b/LocalPluginOptions.h
@@ -0,0 +1,42 @@
+/** \file LocalPluginOptions.h
+\brief To bind the options of the plugin, into unique group options
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef LOCALPLUGINOPTIONS_H
+#define LOCALPLUGINOPTIONS_H
+
+#include <QObject>
+
+#include "interface/OptionInterface.h"
+#include "OptionEngine.h"
+
+/** \brief To store the options
+
+ That's allow to have mutualised way to store the options. Then the plugins just keep Ultracopier manage it, the portable version will store on the disk near the application, and the normal version will keep at the normal location.
+
+ \see OptionEngine::OptionEngine()
+*/
+class LocalPluginOptions : public OptionInterface
+{
+ Q_OBJECT
+public:
+ explicit LocalPluginOptions(const std::string &group);
+ ~LocalPluginOptions();
+ /// \brief To add option group to options
+ bool addOptionGroup(const std::vector<std::pair<std::string, std::string> > &KeysList);
+ /*/// \brief To remove option group to options, removed to the load plugin
+ bool removeOptionGroup();*/
+ /// \brief To get option value
+ std::string getOptionValue(const std::string &variableName) const;
+ /// \brief To set option value
+ void setOptionValue(const std::string &variableName,const std::string &value);
+protected:
+ //for the options
+ std::string group;
+ bool groupOptionAdded;
+/*public slots:-> disabled because the value will not externaly changed, then useless notification
+ void newOptionValue(QString group,QString variable,QVariant value);*/
+};
+
+#endif // LOCALPLUGINOPTIONS_H
diff --git a/LogThread.cpp b/LogThread.cpp
new file mode 100644
index 0000000..234ccbf
--- /dev/null
+++ b/LogThread.cpp
@@ -0,0 +1,296 @@
+/** \file LogThread.cpp
+\brief The thread to do the log but not block the main thread
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "LogThread.h"
+#include "ResourcesManager.h"
+#include "OptionEngine.h"
+#include "cpp11addition.h"
+
+#ifdef Q_OS_WIN32
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+ #include <windows.h>
+#endif
+#include <QMessageBox>
+
+std::string LogThread::text_header_copy="[Copy] ";
+std::string LogThread::text_header_move="[Move] ";
+std::string LogThread::text_header_skip="[Skip] ";
+std::string LogThread::text_header_stop="[Stop] ";
+std::string LogThread::text_header_error="[Error] ";
+std::string LogThread::text_header_MkPath="[MkPath] ";
+std::string LogThread::text_header_RmPath="[RmPath] ";
+
+std::string LogThread::text_var_source="%source%";
+std::string LogThread::text_var_size="%size%";
+std::string LogThread::text_var_destination="%destination%";
+std::string LogThread::text_var_path="%path%";
+std::string LogThread::text_var_error="%error%";
+std::string LogThread::text_var_mtime="%mtime%";
+std::string LogThread::text_var_time="%time%";
+std::string LogThread::text_var_timestring="%dd.MM.yyyy h:m:s%";
+#ifdef Q_OS_WIN32
+std::string LogThread::text_var_computer="%computer%";
+std::string LogThread::text_var_user="%user%";
+#endif
+std::string LogThread::text_var_operation="%operation%";
+std::string LogThread::text_var_rmPath="%rmPath%";
+std::string LogThread::text_var_mkPath="%mkPath%";
+
+LogThread::LogThread()
+{
+ sync=false;
+
+ connect(OptionEngine::optionEngine,&OptionEngine::newOptionValue, this, &LogThread::newOptionValue);
+
+ enabled=false;
+
+ moveToThread(this);
+ start(QThread::IdlePriority);
+
+ connect(this, &LogThread::newData, this,&LogThread::realDataWrite,Qt::QueuedConnection);
+
+ newOptionValue("Write_log", "transfer", OptionEngine::optionEngine->getOptionValue("Write_log","transfer"));
+ newOptionValue("Write_log", "error", OptionEngine::optionEngine->getOptionValue("Write_log","error"));
+ newOptionValue("Write_log", "folder", OptionEngine::optionEngine->getOptionValue("Write_log","folder"));
+ newOptionValue("Write_log", "sync", OptionEngine::optionEngine->getOptionValue("Write_log","sync"));
+ newOptionValue("Write_log", "transfer_format", OptionEngine::optionEngine->getOptionValue("Write_log","transfer_format"));
+ newOptionValue("Write_log", "error_format", OptionEngine::optionEngine->getOptionValue("Write_log","error_format"));
+ newOptionValue("Write_log", "folder_format", OptionEngine::optionEngine->getOptionValue("Write_log","folder_format"));
+ newOptionValue("Write_log", "sync", OptionEngine::optionEngine->getOptionValue("Write_log","sync"));
+ newOptionValue("Write_log", "enabled", OptionEngine::optionEngine->getOptionValue("Write_log","enabled"));
+ #ifdef Q_OS_WIN32
+ DWORD size=0;
+ WCHAR * computerNameW=new WCHAR[size];
+ if(GetComputerNameW(computerNameW,&size))
+ computer=QString::fromWCharArray(computerNameW,size-1).toStdString();
+ else
+ computer="Unknown computer";
+ delete computerNameW;
+
+ WCHAR * userNameW=new WCHAR[size];
+ if(GetUserNameW(userNameW,&size))
+ user=QString::fromWCharArray(userNameW,size-1).toStdString();
+ else
+ user="Unknown user";
+ delete userNameW;
+ #endif
+
+ #ifdef Q_OS_WIN32
+ lineReturn="\r\n";
+ #else
+ lineReturn="\n";
+ #endif
+}
+
+LogThread::~LogThread()
+{
+ closeLogs();
+ quit();
+ wait();
+}
+
+bool LogThread::logTransfer() const
+{
+ return enabled && log_enable_transfer;
+}
+
+void LogThread::openLogs()
+{
+ if(stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled"))==false)
+ return;
+ if(log.isOpen())
+ {
+ QMessageBox::critical(NULL,tr("Error"),tr("Log file already open, error: %1").arg(log.errorString()));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"log file already open, error: "+log.errorString().toStdString());
+ return;
+ }
+ log.setFileName(QString::fromStdString(OptionEngine::optionEngine->getOptionValue("Write_log","file")));
+ if(sync)
+ {
+ if(!log.open(QIODevice::WriteOnly|QIODevice::Unbuffered))
+ {
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to open the log file, error: %1").arg(log.errorString()));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to open the log file, error: "+log.errorString().toStdString());
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"opened log: "+OptionEngine::optionEngine->getOptionValue("Write_log","file"));
+ }
+ else
+ {
+ if(!log.open(QIODevice::WriteOnly))
+ {
+ QMessageBox::critical(NULL,tr("Error"),tr("Unable to open the log file, error: %1").arg(log.errorString()));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Unable to open the log file, error: "+log.errorString().toStdString());
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"opened log: "+OptionEngine::optionEngine->getOptionValue("Write_log","file"));
+ }
+}
+
+void LogThread::closeLogs()
+{
+ if(log.isOpen() && data.size()>0)
+ log.write(data.data(),data.size());
+ log.close();
+}
+
+void LogThread::newTransferStart(const Ultracopier::ItemOfCopyList &item)
+{
+ if(!logTransfer())
+ return;
+ std::string text;
+ if(item.mode==Ultracopier::Copy)
+ text=LogThread::text_header_copy+transfer_format+lineReturn;
+ else
+ text=LogThread::text_header_move+transfer_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %source%, %size%, %destination%
+ stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath);
+ stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size));
+ stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath);
+ stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString());
+ emit newData(text);
+}
+
+/** method called when new transfer is started */
+void LogThread::transferSkip(const Ultracopier::ItemOfCopyList &item)
+{
+ if(!logTransfer())
+ return;
+ std::string text=LogThread::text_header_skip+transfer_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %source%, %size%, %destination%
+ stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath);
+ stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size));
+ stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath);
+ stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString());
+ emit newData(text);
+}
+
+void LogThread::newTransferStop(const Ultracopier::ItemOfCopyList &item)
+{
+ if(!logTransfer())
+ return;
+ std::string text=LogThread::text_header_stop+transfer_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %source%, %size%, %destination%
+ stringreplaceAll(text,LogThread::text_var_source,item.sourceFullPath);
+ stringreplaceAll(text,LogThread::text_var_size,std::to_string(item.size));
+ stringreplaceAll(text,LogThread::text_var_destination,item.destinationFullPath);
+ stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString());
+ emit newData(text);
+}
+
+void LogThread::error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error)
+{
+ if(!log_enable_error)
+ return;
+ std::string text=LogThread::text_header_error+error_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %path%, %size%, %mtime%, %error%
+ stringreplaceAll(text,LogThread::text_var_path,path);
+ stringreplaceAll(text,LogThread::text_var_size,std::to_string(size));
+ stringreplaceAll(text,LogThread::text_var_mtime,QDateTime::fromTime_t(static_cast<unsigned int>(mtime)).toString(Qt::ISODate).toStdString());
+ stringreplaceAll(text,LogThread::text_var_error,error);
+ stringreplaceAll(text,LogThread::text_var_time,QDateTime::fromTime_t(static_cast<unsigned int>(mtime)).toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString());
+ emit newData(text);
+}
+
+void LogThread::run()
+{
+ exec();
+}
+
+void LogThread::realDataWrite(const std::string &text)
+{
+ #ifdef ULTRACOPIER_DEBUG
+ if(!log.isOpen())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"transfer log not open");
+ return;
+ }
+ #endif // ULTRACOPIER_DEBUG
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ if(log.write(text.data(),text.size())==-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to write into transfer log: "+log.errorString().toStdString());
+ return;
+ }
+ if(sync)
+ log.flush();
+}
+
+void LogThread::newOptionValue(const std::string &group,const std::string &name,const std::string &value)
+{
+ if(group!="Write_log")
+ return;
+
+ if(name=="transfer_format")
+ transfer_format=value;
+ else if(name=="error_format")
+ error_format=value;
+ else if(name=="folder_format")
+ folder_format=value;
+ else if(name=="sync")
+ {
+ sync=stringtobool(value);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"sync flag is set on: "+value);
+ if(sync)
+ {
+ if(log.isOpen())
+ log.flush();
+ }
+ }
+ else if(name=="transfer")
+ log_enable_transfer=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value);
+ else if(name=="error")
+ log_enable_error=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value);
+ else if(name=="folder")
+ log_enable_folder=stringtobool(OptionEngine::optionEngine->getOptionValue("Write_log","enabled")) && stringtobool(value);
+ if(name=="enabled")
+ {
+ enabled=stringtobool(value);
+ if(enabled)
+ openLogs();
+ else
+ closeLogs();
+ }
+}
+
+std::string LogThread::replaceBaseVar(std::string text)
+{
+ stringreplaceAll(text,LogThread::text_var_time,QDateTime::currentDateTime().toString(QString::fromStdString(LogThread::text_var_timestring)).toStdString());
+ #ifdef Q_OS_WIN32
+ stringreplaceAll(text,LogThread::text_var_computer,computer);
+ stringreplaceAll(text,LogThread::text_var_user,user);
+ #endif
+ return text;
+}
+
+void LogThread::rmPath(const std::string &path)
+{
+ if(!logTransfer())
+ return;
+ std::string text=LogThread::text_header_RmPath+folder_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %operation% %path%
+ stringreplaceAll(text,LogThread::text_var_path,path);
+ stringreplaceAll(text,LogThread::text_var_operation,LogThread::text_var_rmPath);
+ emit newData(text);
+}
+
+void LogThread::mkPath(const std::string &path)
+{
+ if(!logTransfer())
+ return;
+ std::string text=LogThread::text_header_MkPath+folder_format+lineReturn;
+ text=replaceBaseVar(text);
+ //Variable is %operation% %path%
+ stringreplaceAll(text,LogThread::text_var_path,path);
+ stringreplaceAll(text,LogThread::text_var_operation,LogThread::text_var_mkPath);
+ emit newData(text);
+}
diff --git a/LogThread.h b/LogThread.h
new file mode 100644
index 0000000..40f9154
--- /dev/null
+++ b/LogThread.h
@@ -0,0 +1,98 @@
+/** \file LogThread.h
+\brief The thread to do the log but not block the main thread
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef LOGTHREAD_H
+#define LOGTHREAD_H
+
+#include <QThread>
+#include <QString>
+#include <QDateTime>
+#include <QVariant>
+#include <QFile>
+
+#include "Environment.h"
+#include "StructEnumDefinition.h"
+
+/** \brief Log all the user oriented activity
+
+It use thread based storage to prevent gui thread freeze on log file writing when is out of the disk buffer. That's allow to async the event.
+*/
+class LogThread : public QThread
+{
+ Q_OBJECT
+public:
+ explicit LogThread();
+ ~LogThread();
+ bool logTransfer() const;
+public slots:
+ /** method called when new transfer is started */
+ void newTransferStart(const Ultracopier::ItemOfCopyList &item);
+ /** method called when transfer is stopped */
+ void newTransferStop(const Ultracopier::ItemOfCopyList &item);
+ /** method called when new transfer is started */
+ void transferSkip(const Ultracopier::ItemOfCopyList &item);
+ /** method called when new error is occurred */
+ void error(const std::string &path,const uint64_t &size,const uint64_t &mtime,const std::string &error);
+ /** method called when the log file need be created */
+ void openLogs();
+ /** method called when the log file need be closed */
+ void closeLogs();
+ /** method called when one folder is removed */
+ void rmPath(const std::string &path);
+ /** method called when one folder is created */
+ void mkPath(const std::string &path);
+private slots:
+ /** write the data into the file */
+ void realDataWrite(const std::string &text);
+ /** update the options value */
+ void newOptionValue(const std::string &group,const std::string &name,const std::string &value);
+signals:
+ void newData(const std::string &text) const;
+private:
+ std::string data;
+ std::string transfer_format;
+ std::string error_format;
+ std::string folder_format;
+ QFile log;
+ std::string lineReturn;
+ std::string replaceBaseVar(std::string text);
+ #ifdef Q_OS_WIN32
+ std::string computer;
+ std::string user;
+ #endif
+ bool sync;
+ bool enabled;
+ bool log_enable_transfer;
+ bool log_enable_error;
+ bool log_enable_folder;
+
+ static std::string text_header_copy;
+ static std::string text_header_move;
+ static std::string text_header_skip;
+ static std::string text_header_stop;
+ static std::string text_header_error;
+ static std::string text_header_MkPath;
+ static std::string text_header_RmPath;
+
+ static std::string text_var_source;
+ static std::string text_var_size;
+ static std::string text_var_destination;
+ static std::string text_var_path;
+ static std::string text_var_error;
+ static std::string text_var_mtime;
+ static std::string text_var_time;
+ static std::string text_var_timestring;
+ #ifdef Q_OS_WIN32
+ static std::string text_var_computer;
+ static std::string text_var_user;
+ #endif
+ static std::string text_var_operation;
+ static std::string text_var_rmPath;
+ static std::string text_var_mkPath;
+protected:
+ void run();
+};
+
+#endif // LOGTHREAD_H
diff --git a/OSSpecific.cpp b/OSSpecific.cpp
new file mode 100644
index 0000000..ada8d68
--- /dev/null
+++ b/OSSpecific.cpp
@@ -0,0 +1,58 @@
+#include "OSSpecific.h"
+#include "ui_OSSpecific.h"
+
+OSSpecific::OSSpecific(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::OSSpecific)
+{
+ ui->setupUi(this);
+ if(!QIcon::fromTheme(QStringLiteral("dialog-warning")).isNull())
+ setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
+ updateText();
+}
+
+OSSpecific::~OSSpecific()
+{
+ delete ui;
+}
+
+void OSSpecific::updateText()
+{
+ QString text;
+ #if defined(Q_OS_LINUX)
+ text=tr("The replacement of default copy/move system is not supported by the file manager (Dolphin, Nautilus, ...).<br />Ask the developer to support it.<br />You need do the copy/move manually.");
+ #elif defined(Q_OS_WIN32)
+ text=tr("Reboot the system if previously had similar software installed (like Teracopy, Supercopier or an earlier version of Ultracopier).");
+ #elif defined(Q_OS_MAC)
+ text=tr("The replacement of default copy/move system is not supported and blocked by finder of Mac OS X.<br />You need do the copy/move manually by right clicking on the system tray icon near the clock (not the dock icon).");
+ #else
+ text=tr("The replacement of default copy/move system should be not supported by the file manager.<br />Ask to the developer to support it.<br />You need do the copy/move manually.");
+ #endif
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ text+=QStringLiteral("<br />")+tr("Consider Supercopier as deprecated, prefer Ultracopier");
+ #endif
+ ui->label->setText(text);
+}
+
+void OSSpecific::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ updateText();
+ break;
+ default:
+ break;
+ }
+}
+
+bool OSSpecific::dontShowAgain()
+{
+ return ui->dontShowAgain->isChecked();
+}
+
+void OSSpecific::on_pushButton_clicked()
+{
+ close();
+}
diff --git a/OSSpecific.h b/OSSpecific.h
new file mode 100644
index 0000000..0b6ffcb
--- /dev/null
+++ b/OSSpecific.h
@@ -0,0 +1,29 @@
+#ifndef OSSPECIFIC_H
+#define OSSPECIFIC_H
+
+#include "Environment.h"
+
+#include <QDialog>
+
+namespace Ui {
+class OSSpecific;
+}
+
+class OSSpecific : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit OSSpecific(QWidget *parent = 0);
+ ~OSSpecific();
+ bool dontShowAgain();
+private slots:
+ void on_pushButton_clicked();
+ void updateText();
+protected slots:
+ void changeEvent(QEvent *e);
+private:
+ Ui::OSSpecific *ui;
+};
+
+#endif // OSSPECIFIC_H
diff --git a/OSSpecific.ui b/OSSpecific.ui
new file mode 100644
index 0000000..3d0d89e
--- /dev/null
+++ b/OSSpecific.ui
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OSSpecific</class>
+ <widget class="QDialog" name="OSSpecific">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>88</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Warning</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources/ultracopier-resources.qrc">
+ <normaloff>:/warning.png</normaloff>:/warning.png</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="dontShowAgain">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Don't show again</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>Ok</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="resources/ultracopier-resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/OptionDialog.cpp b/OptionDialog.cpp
new file mode 100644
index 0000000..4c64875
--- /dev/null
+++ b/OptionDialog.cpp
@@ -0,0 +1,1015 @@
+/** \file OptionDialog.cpp
+\brief To have an interface to control the options
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "OptionDialog.h"
+#include "ui_OptionDialog.h"
+#include "OSSpecific.h"
+#include "LanguagesManager.h"
+#include "cpp11addition.h"
+
+#include <QDomElement>
+#include <QFileDialog>
+#include <QMessageBox>
+
+OptionDialog::OptionDialog() :
+ ui(new Ui::OptionDialog)
+{
+ quit=false;
+ QStringList ultracopierArguments=QCoreApplication::arguments();
+ if(ultracopierArguments.size()==2)
+ if(ultracopierArguments.last()==QStringLiteral("quit"))
+ quit=true;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ ignoreCopyEngineListEdition=false;
+ allPluginsIsLoaded=false;
+ oSSpecific=NULL;
+ ui->setupUi(this);
+ ui->treeWidget->topLevelItem(0)->setSelected(true);
+ ui->treeWidget->topLevelItem(4)->setTextColor(0,QColor(150, 150, 150, 255));
+ ui->treeWidget->topLevelItem(5)->setTextColor(0,QColor(150, 150, 150, 255));
+ ui->treeWidget->expandAll();
+ ui->pluginList->expandAll();
+ number_of_listener=0;
+ ui->labelCatchCopyDefault->setEnabled(number_of_listener>0);
+ ui->CatchCopyAsDefault->setEnabled(number_of_listener>0);
+ ui->Language->setEnabled(false);
+ on_treeWidget_itemSelectionChanged();
+
+ //load the plugins
+ PluginsManager::pluginsManager->lockPluginListEdition();
+ connect(this, &OptionDialog::previouslyPluginAdded, this, &OptionDialog::onePluginAdded,Qt::QueuedConnection);
+ connect(PluginsManager::pluginsManager, &PluginsManager::onePluginAdded, this, &OptionDialog::onePluginAdded);
+ connect(PluginsManager::pluginsManager, &PluginsManager::onePluginInErrorAdded, this, &OptionDialog::onePluginAdded);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ connect(PluginsManager::pluginsManager, &PluginsManager::onePluginWillBeRemoved, this, &OptionDialog::onePluginWillBeRemoved,Qt::DirectConnection);
+ #endif
+ connect(PluginsManager::pluginsManager, &PluginsManager::pluginListingIsfinish, this, &OptionDialog::loadOption,Qt::QueuedConnection);
+ #ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ connect(PluginsManager::pluginsManager, &PluginsManager::manuallyAdded, this, &OptionDialog::manuallyAdded,Qt::QueuedConnection);
+ #endif
+ connect(OptionEngine::optionEngine, &OptionEngine::newOptionValue, this, &OptionDialog::newOptionValue);
+ std::vector<PluginsAvailable> list=PluginsManager::pluginsManager->getPlugins(true);
+ foreach(PluginsAvailable currentPlugin,list)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+currentPlugin.name+" ("+std::to_string(currentPlugin.category)+")");
+ emit previouslyPluginAdded(currentPlugin);
+ }
+ PluginsManager::pluginsManager->unlockPluginListEdition();
+ defaultImportBackend=PluginsManager::ImportBackend_File;
+ #ifndef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ ui->pluginAdd->hide();
+ ui->pluginRemove->hide();
+ #endif
+ loadLogVariableLabel();
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ ui->labelLoadAtSession->hide();
+ ui->LoadAtSessionStarting->hide();
+ #endif
+ #ifndef ULTRACOPIER_INTERNET_SUPPORT
+ ui->label_checkTheUpdate->hide();
+ ui->checkTheUpdate->hide();
+ #endif
+}
+
+OptionDialog::~OptionDialog()
+{
+ if(oSSpecific!=NULL)
+ delete oSSpecific;
+ delete ui;
+}
+
+//plugin management
+void OptionDialog::onePluginAdded(const PluginsAvailable &plugin)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+plugin.name+" ("+std::to_string(plugin.category)+")");
+ pluginStore newItem;
+ newItem.path=plugin.path;
+ newItem.item=new QTreeWidgetItem(QStringList() << QString::fromStdString(plugin.name) << QString::fromStdString(plugin.version));
+ newItem.isWritable=plugin.isWritable;
+ pluginLink.push_back(newItem);
+ switch(plugin.category)
+ {
+ case PluginType_CopyEngine:
+ ui->pluginList->topLevelItem(0)->addChild(newItem.item);
+ break;
+ case PluginType_Languages:
+ ui->pluginList->topLevelItem(1)->addChild(newItem.item);
+ addLanguage(plugin);
+ break;
+ case PluginType_Listener:
+ ui->pluginList->topLevelItem(2)->addChild(newItem.item);
+ number_of_listener++;
+ ui->labelCatchCopyDefault->setEnabled(number_of_listener>0);
+ ui->CatchCopyAsDefault->setEnabled(number_of_listener>0);
+ break;
+ case PluginType_PluginLoader:
+ ui->pluginList->topLevelItem(3)->addChild(newItem.item);
+ break;
+ case PluginType_SessionLoader:
+ ui->pluginList->topLevelItem(4)->addChild(newItem.item);
+ break;
+ case PluginType_Themes:
+ ui->pluginList->topLevelItem(5)->addChild(newItem.item);
+ addTheme(plugin);
+ break;
+ default:
+ case PluginType_Unknow:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"category not found for: "+plugin.path);
+ }
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+void OptionDialog::onePluginWillBeRemoved(const PluginsAvailable &plugin)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ switch(plugin.category)
+ {
+ case PluginType_CopyEngine:
+ break;
+ case PluginType_Languages:
+ removeLanguage(plugin);
+ break;
+ case PluginType_Listener:
+ number_of_listener--;
+ ui->labelCatchCopyDefault->setEnabled(number_of_listener>0);
+ ui->CatchCopyAsDefault->setEnabled(number_of_listener>0);
+ break;
+ case PluginType_PluginLoader:
+ break;
+ case PluginType_SessionLoader:
+ break;
+ case PluginType_Themes:
+ removeTheme(plugin);
+ break;
+ default:
+ case PluginType_Unknow:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"category not found for: "+plugin.path);
+ }
+ //remove if have options
+ unsigned int index=0;
+ if(plugin.category==PluginType_CopyEngine || plugin.category==PluginType_Listener || plugin.category==PluginType_PluginLoader || plugin.category==PluginType_SessionLoader)
+ {
+ while(index<pluginOptionsWidgetList.size())
+ {
+ if(plugin.category==pluginOptionsWidgetList.at(index).category && plugin.name==pluginOptionsWidgetList.at(index).name)
+ {
+ if(pluginOptionsWidgetList.at(index).item->isSelected())
+ {
+ pluginOptionsWidgetList.at(index).item->setSelected(false);
+ ui->treeWidget->topLevelItem(0)->setSelected(true);
+ }
+ delete pluginOptionsWidgetList.at(index).item;
+ break;
+ }
+ index++;
+ }
+ }
+ //remove from general list
+ index=0;
+ while(index<pluginLink.size())
+ {
+ if(pluginLink.at(index).path==plugin.path)
+ {
+ delete pluginLink.at(index).item;
+ pluginLink.erase(pluginLink.cbegin()+index);
+ return;
+ }
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"not found!");
+}
+#endif
+
+#ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+void OptionDialog::manuallyAdded(const PluginsAvailable &plugin)
+{
+ if(plugin.category==PluginType_Themes)
+ {
+ if(QMessageBox::question(this,tr("Load"),tr("Load the theme?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes)==QMessageBox::Yes)
+ {
+ int index=ui->Ultracopier_current_theme->findData(QString::fromStdString(plugin.name));
+ if(index!=-1)
+ {
+ ui->Ultracopier_current_theme->setCurrentIndex(index);
+ on_Ultracopier_current_theme_currentIndexChanged(ui->Ultracopier_current_theme->currentIndex());
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"theme plugin not found!");
+ }
+ }
+ else if(plugin.category==PluginType_Languages)
+ {
+ if(QMessageBox::question(this,tr("Load"),tr("Load the language?"),QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes)==QMessageBox::Yes)
+ {
+ std::vector<std::pair<std::string,std::string>> listChildAttribute;
+ listChildAttribute.push_back(std::make_pair("mainCode", "true"));
+ int index=ui->Language->findData(QString::fromStdString(PluginsManager::pluginsManager->getDomSpecific(plugin.categorySpecific,"shortName",listChildAttribute)));
+ if(index!=-1)
+ {
+ ui->Language->setCurrentIndex(index);
+ ui->Language_force->setChecked(true);
+ on_Language_currentIndexChanged(index);
+ on_Language_force_toggled(true);
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"language plugin not found!");
+ }
+ }
+}
+#endif
+
+void OptionDialog::addLanguage(const PluginsAvailable &plugin)
+{
+ std::vector<std::pair<std::string,std::string> > listChildAttribute;
+ std::pair<std::string,std::string> temp;
+ temp.first = "mainCode";
+ temp.second = "true";
+ listChildAttribute.push_back(temp);
+ ui->Language->addItem(QIcon(QString::fromStdString(plugin.path)+"flag.png"),
+ QString::fromStdString(PluginsManager::pluginsManager->getDomSpecific(plugin.categorySpecific,"fullName")),
+ QString::fromStdString(PluginsManager::pluginsManager->getDomSpecific(plugin.categorySpecific,"shortName",listChildAttribute)));
+ ui->Language->setEnabled(ui->Language_force->isChecked() && ui->Language->count());
+ ui->Language_force->setEnabled(ui->Language->count());
+}
+
+void OptionDialog::removeLanguage(const PluginsAvailable &plugin)
+{
+ std::vector<std::pair<std::string,std::string> > listChildAttribute;
+ std::pair<std::string,std::string> temp;
+ temp.first = "mainCode";
+ temp.second = "true";
+ listChildAttribute.push_back(temp);
+ int index=ui->Language->findData(QString::fromStdString(PluginsManager::pluginsManager->getDomSpecific(plugin.categorySpecific,"shortName",listChildAttribute)));
+ if(index!=-1)
+ ui->Language->removeItem(index);
+ ui->Language->setEnabled(ui->Language_force->isChecked() && ui->Language->count());
+ ui->Language_force->setEnabled(ui->Language->count());
+}
+
+void OptionDialog::addTheme(const PluginsAvailable &plugin)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"plugin.name: "+plugin.name);
+ ui->Ultracopier_current_theme->addItem(QString::fromStdString(plugin.name),QString::fromStdString(plugin.name));
+}
+
+void OptionDialog::removeTheme(const PluginsAvailable &plugin)
+{
+ int index=ui->Ultracopier_current_theme->findData(QString::fromStdString(plugin.name));
+ if(index!=-1)
+ ui->Ultracopier_current_theme->removeItem(index);
+}
+
+void OptionDialog::changeEvent(QEvent *e)
+{
+ QDialog::changeEvent(e);
+ switch (e->type()) {
+ case QEvent::LanguageChange:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"retranslate the ui");
+ ui->retranslateUi(this);
+ //old code to reload the widget because it dropped by the translation
+ /*
+ index=0;
+ loop_size=pluginOptionsWidgetList.size();
+ while(index<loop_size)
+ {
+ if(pluginOptionsWidgetList.at(index).options!=NULL)
+ ui->treeWidget->topLevelItem(2)->addChild(pluginOptionsWidgetList.at(index).item);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"the copy engine "+std::to_string(index)+" have not the options");
+ index++;
+ }*/
+ ui->treeWidget->topLevelItem(2)->setText(0,tr("Copy engine"));
+ ui->treeWidget->topLevelItem(3)->setText(0,tr("Listener"));
+ ui->treeWidget->topLevelItem(4)->setText(0,tr("Plugin loader"));
+ ui->treeWidget->topLevelItem(5)->setText(0,tr("Session loader"));
+ //ui->labelLoadAtSession->setToolTip(tr("Disabled because you do not have any SessionLoader plugin"));
+ /*#if !defined(ULTRACOPIER_PLUGIN_ALL_IN_ONE) || !defined(ULTRACOPIER_VERSION_PORTABLE)
+ ui->LoadAtSessionStarting->setToolTip(tr("Disabled because you do not have any SessionLoader plugin"));
+ #endif*/
+ ui->ActionOnManualOpen->setItemText(0,tr("Do nothing"));
+ ui->ActionOnManualOpen->setItemText(1,tr("Ask source as folder"));
+ ui->ActionOnManualOpen->setItemText(2,tr("Ask sources as files"));
+ ui->GroupWindowWhen->setItemText(0,tr("Never"));
+ ui->GroupWindowWhen->setItemText(1,tr("When source is same"));
+ ui->GroupWindowWhen->setItemText(2,tr("When destination is same"));
+ ui->GroupWindowWhen->setItemText(3,tr("When source and destination are same"));
+ ui->GroupWindowWhen->setItemText(4,tr("When source or destination are same"));
+ ui->GroupWindowWhen->setItemText(5,tr("Always"));
+ loadLogVariableLabel();
+ break;
+ default:
+ break;
+ }
+}
+
+void OptionDialog::loadLogVariableLabel()
+{
+ QString append=QStringLiteral(" %time%");
+ #ifdef Q_OS_WIN32
+ append+=QStringLiteral(", %computer%, %user%");
+ #endif
+ ui->labelLogTransfer->setText(tr("The variables are %1").arg("%source%, %size%, %destination%"+append));
+ ui->labelLogError->setText(tr("The variables are %1").arg("%path%, %size%, %mtime%, %error%"+append));
+ ui->labelLogFolder->setText(tr("The variables are %1").arg("%path%, %operation%"+append));
+}
+
+void OptionDialog::on_treeWidget_itemSelectionChanged()
+{
+ QList<QTreeWidgetItem *> listSelectedItem=ui->treeWidget->selectedItems();
+ if(listSelectedItem.size()!=1)
+ return;
+ QTreeWidgetItem * selectedItem=listSelectedItem.first();
+ //general
+ if(selectedItem==ui->treeWidget->topLevelItem(0))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetGeneral);
+ //plugins
+ else if(selectedItem==ui->treeWidget->topLevelItem(1))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetPlugins);
+ //Copy engine
+ else if(selectedItem==ui->treeWidget->topLevelItem(2))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetCopyEngine);
+ //Listener
+ else if(selectedItem==ui->treeWidget->topLevelItem(3))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetListener);
+ //PluginLoader
+ //do nothing
+ //SessionLoader
+ //do nothing
+ //Themes
+ else if(selectedItem==ui->treeWidget->topLevelItem(6))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetThemes);
+ //log
+ else if(selectedItem==ui->treeWidget->topLevelItem(7))
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetLog);
+ else
+ {
+ int index;
+ if(selectedItem->parent()==ui->treeWidget->topLevelItem(2))
+ {
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetCopyEngineOptions);
+ index=selectedItem->parent()->indexOfChild(selectedItem);
+ if(index!=-1)
+ ui->stackedOptionsCopyEngine->setCurrentIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"selection into of sub item wrong???");
+ }
+ else if(selectedItem->parent()==ui->treeWidget->topLevelItem(3))
+ {
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetListenerOptions);
+ index=selectedItem->parent()->indexOfChild(selectedItem);
+ if(index!=-1)
+ ui->stackedOptionsListener->setCurrentIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"selection into of sub item wrong???");
+ }
+ else if(selectedItem->parent()==ui->treeWidget->topLevelItem(4))
+ {
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetPluginLoaderOptions);
+ index=selectedItem->parent()->indexOfChild(selectedItem);
+ if(index!=-1)
+ ui->stackedOptionsPluginLoader->setCurrentIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"selection into of sub item wrong???");
+ }
+ else if(selectedItem->parent()==ui->treeWidget->topLevelItem(5))
+ {
+ ui->stackedWidget->setCurrentWidget(ui->stackedWidgetSessionLoaderOptions);
+ index=selectedItem->parent()->indexOfChild(selectedItem);
+ if(index!=-1)
+ ui->stackedOptionsSessionLoader->setCurrentIndex(index);
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"selection into of sub item wrong???");
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"selection into option list cat not found");
+ }
+}
+
+void OptionDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ if(ui->buttonBox->buttonRole(button)==QDialogButtonBox::ResetRole)
+ OptionEngine::optionEngine->queryResetOptions();
+ else
+ this->close();
+}
+
+void OptionDialog::loadOption()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ newOptionValue("Themes", "Ultracopier_current_theme", OptionEngine::optionEngine->getOptionValue("Themes","Ultracopier_current_theme"));
+ newOptionValue("Ultracopier", "ActionOnManualOpen", OptionEngine::optionEngine->getOptionValue("Ultracopier","ActionOnManualOpen"));
+ newOptionValue("Ultracopier", "GroupWindowWhen", OptionEngine::optionEngine->getOptionValue("Ultracopier","GroupWindowWhen"));
+ newOptionValue("Ultracopier", "confirmToGroupWindows", OptionEngine::optionEngine->getOptionValue("Ultracopier","confirmToGroupWindows"));
+ newOptionValue("Ultracopier", "displayOSSpecific", OptionEngine::optionEngine->getOptionValue("Ultracopier","displayOSSpecific"));
+ newOptionValue("Ultracopier", "checkTheUpdate", OptionEngine::optionEngine->getOptionValue("Ultracopier","checkTheUpdate"));
+ newOptionValue("Ultracopier", "remainingTimeAlgorithm", OptionEngine::optionEngine->getOptionValue("Ultracopier","remainingTimeAlgorithm"));
+ newOptionValue("Language", "Language", OptionEngine::optionEngine->getOptionValue("Language","Language"));
+ newOptionValue("Language", "Language_force", OptionEngine::optionEngine->getOptionValue("Language","Language_force"));
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ newOptionValue("SessionLoader", "LoadAtSessionStarting", OptionEngine::optionEngine->getOptionValue("SessionLoader","LoadAtSessionStarting"));
+ #endif
+ newOptionValue("CopyListener", "CatchCopyAsDefault", OptionEngine::optionEngine->getOptionValue("CopyListener","CatchCopyAsDefault"));
+ newOptionValue("CopyEngine", "List", OptionEngine::optionEngine->getOptionValue("CopyEngine","List"));
+ if(ResourcesManager::resourcesManager->getWritablePath().empty())
+ ui->checkBox_Log->setEnabled(false);
+ else
+ {
+ newOptionValue("Write_log", "enabled", OptionEngine::optionEngine->getOptionValue("Write_log","enabled"));
+ newOptionValue("Write_log", "file", OptionEngine::optionEngine->getOptionValue("Write_log","file"));
+ newOptionValue("Write_log", "transfer", OptionEngine::optionEngine->getOptionValue("Write_log","transfer"));
+ newOptionValue("Write_log", "error", OptionEngine::optionEngine->getOptionValue("Write_log","error"));
+ newOptionValue("Write_log", "folder", OptionEngine::optionEngine->getOptionValue("Write_log","folder"));
+ newOptionValue("Write_log", "transfer_format", OptionEngine::optionEngine->getOptionValue("Write_log","transfer_format"));
+ newOptionValue("Write_log", "error_format", OptionEngine::optionEngine->getOptionValue("Write_log","error_format"));
+ newOptionValue("Write_log", "folder_format", OptionEngine::optionEngine->getOptionValue("Write_log","folder_format"));
+ newOptionValue("Write_log", "sync", OptionEngine::optionEngine->getOptionValue("Write_log","sync"));
+ }
+ on_checkBox_Log_clicked();
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ if(PluginsManager::pluginsManager->getPluginsByCategory(PluginType_SessionLoader).size()>0)
+ {
+ ui->labelLoadAtSession->setToolTip(QStringLiteral(""));
+ ui->LoadAtSessionStarting->setToolTip(QStringLiteral(""));
+ ui->labelLoadAtSession->setEnabled(true);
+ ui->LoadAtSessionStarting->setEnabled(true);
+ }
+ else
+ {
+ //ui->labelLoadAtSession->setToolTip(tr("Disabled because you do not have any SessionLoader plugin"));
+ //ui->LoadAtSessionStarting->setToolTip(tr("Disabled because you do not have any SessionLoader plugin"));
+ ui->labelLoadAtSession->setEnabled(false);
+ ui->LoadAtSessionStarting->setEnabled(false);
+ }
+ #endif
+ allPluginsIsLoaded=true;
+ on_Ultracopier_current_theme_currentIndexChanged(ui->Ultracopier_current_theme->currentIndex());
+
+ if(stringtobool(OptionEngine::optionEngine->getOptionValue("Ultracopier","displayOSSpecific")))
+ {
+ if(!quit)
+ {
+ oSSpecific=new OSSpecific();
+ oSSpecific->show();
+ connect(oSSpecific,&OSSpecific::finished,this,&OptionDialog::oSSpecificClosed,Qt::QueuedConnection);
+ }
+ }
+}
+
+void OptionDialog::oSSpecificClosed()
+{
+ if(oSSpecific==NULL)
+ return;
+ if(oSSpecific->dontShowAgain())
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","displayOSSpecific","false");
+ delete oSSpecific;
+ oSSpecific=NULL;
+}
+
+void OptionDialog::newOptionValue(const std::string &group,const std::string &name,const std::string &value)
+{
+ if(group=="Themes")
+ {
+ if(name=="Ultracopier_current_theme")
+ {
+ int index=ui->Ultracopier_current_theme->findData(QString::fromStdString(value));
+ if(index!=-1)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Themes located: "+value);
+ ui->Ultracopier_current_theme->setCurrentIndex(index);
+ }
+ else
+ {
+ if(ui->Ultracopier_current_theme->count()>0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Default to the current value: "+ui->Ultracopier_current_theme->itemData(ui->Ultracopier_current_theme->currentIndex()).toString().toStdString());
+ OptionEngine::optionEngine->setOptionValue("Themes","Ultracopier_current_theme",ui->Ultracopier_current_theme->itemData(ui->Ultracopier_current_theme->currentIndex()).toString().toStdString());
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"No themes: "+value);
+ }
+ }
+ }
+ else if(group=="Language")
+ {
+ if(name=="Language")
+ {
+ int index=ui->Language->findData(QString::fromStdString(value));
+ if(index!=-1)
+ ui->Language->setCurrentIndex(index);
+ else if(ui->Language->count()>0)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Language in settings: "+value);
+ OptionEngine::optionEngine->setOptionValue("Language","Language",ui->Language->itemData(ui->Language->currentIndex()).toString().toStdString());
+ }
+ }
+ else if(name=="Language_force")
+ {
+ ui->Language_force->setChecked(stringtobool(value));
+ ui->Language->setEnabled(ui->Language_force->isChecked() && ui->Language->count());
+ if(!ui->Language_force->isChecked())
+ {
+ const std::string &lang=LanguagesManager::languagesManager->autodetectedLanguage();
+ if(!lang.empty())
+ {
+ int index=ui->Language->findData(QString::fromStdString(lang));
+ if(index!=-1)
+ ui->Language->setCurrentIndex(index);
+ }
+ }
+ }
+ }
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ else if(group=="SessionLoader")
+ {
+ if(name=="LoadAtSessionStarting")
+ {
+ ui->LoadAtSessionStarting->setChecked(stringtobool(value));
+ }
+ }
+ #endif
+ else if(group=="CopyListener")
+ {
+ if(name=="CatchCopyAsDefault")
+ {
+ ui->CatchCopyAsDefault->setChecked(stringtobool(value));
+ }
+ }
+ else if(group=="CopyEngine")
+ {
+ if(name=="List")
+ {
+ if(!ignoreCopyEngineListEdition)
+ {
+ QStringList copyEngine=QString::fromStdString(value).split(';');
+ copyEngine.removeDuplicates();
+ int index=0;
+ const int &loop_size=ui->CopyEngineList->count();
+ while(index<loop_size)
+ {
+ copyEngine.removeOne(ui->CopyEngineList->item(index)->text());
+ index++;
+ }
+ ui->CopyEngineList->addItems(copyEngine);
+ }
+ }
+ }
+ else if(group=="Write_log")
+ {
+ if(name=="enabled")
+ ui->checkBox_Log->setChecked(stringtobool(value));
+ else if(name=="file")
+ ui->lineEditLog_File->setText(QString::fromStdString(value));
+ else if(name=="transfer")
+ ui->checkBoxLog_transfer->setChecked(stringtobool(value));
+ else if(name=="sync")
+ ui->checkBoxLog_sync->setChecked(stringtobool(value));
+ else if(name=="error")
+ ui->checkBoxLog_error->setChecked(stringtobool(value));
+ else if(name=="folder")
+ ui->checkBoxLog_folder->setChecked(stringtobool(value));
+ else if(name=="transfer_format")
+ ui->lineEditLog_transfer_format->setText(QString::fromStdString(value));
+ else if(name=="error_format")
+ ui->lineEditLog_error_format->setText(QString::fromStdString(value));
+ else if(name=="folder_format")
+ ui->lineEditLog_folder_format->setText(QString::fromStdString(value));
+ }
+ else if(group=="Ultracopier")
+ {
+ if(name=="ActionOnManualOpen")
+ ui->ActionOnManualOpen->setCurrentIndex(stringtoint32(value));
+ else if(name=="GroupWindowWhen")
+ ui->GroupWindowWhen->setCurrentIndex(stringtoint32(value));
+ else if(name=="confirmToGroupWindows")
+ ui->confirmToGroupWindows->setChecked(stringtobool(value));
+ else if(name=="displayOSSpecific")
+ ui->DisplayOSWarning->setChecked(stringtobool(value));
+ else if(name=="checkTheUpdate")
+ ui->checkTheUpdate->setChecked(stringtobool(value));
+ else if(name=="remainingTimeAlgorithm")
+ {
+ bool ok;
+ const uint32_t &valueInt=stringtouint32(value,&ok);
+ if(ok)
+ ui->remainingTimeAlgorithm->setCurrentIndex(static_cast<int>(valueInt));
+ }
+ }
+}
+
+void OptionDialog::on_Ultracopier_current_theme_currentIndexChanged(const int &index)
+{
+ if(index!=-1 && allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"data value: "+ui->Ultracopier_current_theme->itemData(index).toString().toStdString()+
+ ", string value: "+ui->Ultracopier_current_theme->itemText(index).toStdString()+
+ ", index: "+std::to_string(index));
+ OptionEngine::optionEngine->setOptionValue("Themes","Ultracopier_current_theme",ui->Ultracopier_current_theme->itemData(index).toString().toStdString());
+ unsigned int index_loop=0;
+ while(index_loop<pluginOptionsWidgetList.size())
+ {
+ if(pluginOptionsWidgetList.at(index_loop).name==ui->Ultracopier_current_theme->itemData(index).toString().toStdString())
+ {
+ if(pluginOptionsWidgetList.at(index_loop).options==NULL)
+ ui->stackedWidgetThemesOptions->setCurrentWidget(ui->pageThemeNoOptions);
+ else
+ ui->stackedWidgetThemesOptions->setCurrentWidget(pluginOptionsWidgetList.at(index_loop).options);
+ return;
+ }
+ index_loop++;
+ }
+ ui->stackedWidgetThemesOptions->setCurrentWidget(ui->pageUnableToLoadThemePlugin);
+ }
+}
+
+void OptionDialog::on_Language_currentIndexChanged(const int &index)
+{
+ if(index!=-1 && allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"data value: "+ui->Language->itemData(index).toString().toStdString()+
+ ", string value: "+ui->Language->itemText(index).toStdString()+", index: "+std::to_string(index));
+ OptionEngine::optionEngine->setOptionValue("Language","Language",ui->Language->itemData(index).toString().toStdString());
+ }
+}
+
+void OptionDialog::on_Language_force_toggled(const bool &checked)
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Language","Language_force",booltostring(checked));
+ ui->Language->setEnabled(ui->Language_force->isChecked() && ui->Language->count());
+ }
+}
+
+void OptionDialog::on_CatchCopyAsDefault_toggled(const bool &checked)
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("CopyListener","CatchCopyAsDefault",booltostring(checked));
+ }
+}
+
+#ifndef ULTRACOPIER_VERSION_PORTABLE
+void OptionDialog::on_LoadAtSessionStarting_toggled(const bool &checked)
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("SessionLoader","LoadAtSessionStarting",booltostring(checked));
+ }
+}
+#endif
+
+void OptionDialog::on_CopyEngineList_itemSelectionChanged()
+{
+ if(ui->CopyEngineList->selectedItems().size()!=0 && ui->CopyEngineList->count()>1)
+ {
+ ui->toolButtonUp->setEnabled(true);
+ ui->toolButtonDown->setEnabled(true);
+ }
+ else
+ {
+ ui->toolButtonUp->setEnabled(false);
+ ui->toolButtonDown->setEnabled(false);
+ }
+}
+
+void OptionDialog::on_toolButtonDown_clicked()
+{
+ QListWidgetItem *item=ui->CopyEngineList->selectedItems().first();
+ int position=ui->CopyEngineList->row(item);
+ if((position+1)<ui->CopyEngineList->count())
+ {
+ QString text=item->text();
+ item->setSelected(false);
+ delete item;
+ ui->CopyEngineList->insertItem(position+1,text);
+ ui->CopyEngineList->item(position+1)->setSelected(true);
+ ignoreCopyEngineListEdition=true;
+ OptionEngine::optionEngine->setOptionValue("CopyEngine","List",stringimplode(copyEngineStringList(),";"));
+ ignoreCopyEngineListEdition=false;
+ }
+}
+
+void OptionDialog::on_toolButtonUp_clicked()
+{
+ QListWidgetItem *item=ui->CopyEngineList->selectedItems().first();
+ int position=ui->CopyEngineList->row(item);
+ if(position>0)
+ {
+ QString text=item->text();
+ item->setSelected(false);
+ delete item;
+ ui->CopyEngineList->insertItem(position-1,text);
+ ui->CopyEngineList->item(position-1)->setSelected(true);
+ ignoreCopyEngineListEdition=true;
+ OptionEngine::optionEngine->setOptionValue("CopyEngine","List",stringimplode(copyEngineStringList(),";"));
+ ignoreCopyEngineListEdition=false;
+ }
+}
+
+std::vector<std::string> OptionDialog::copyEngineStringList() const
+{
+ std::vector<std::string> newList;
+ int index=0;
+ while(index<ui->CopyEngineList->count())
+ {
+ newList.push_back(ui->CopyEngineList->item(index)->text().toStdString());
+ index++;
+ }
+ return newList;
+}
+
+void OptionDialog::newThemeOptions(const std::string &name,QWidget* theNewOptionsWidget,bool isLoaded,bool havePlugin)
+{
+ Q_UNUSED(isLoaded);
+ Q_UNUSED(havePlugin);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: isLoaded: "+booltostring(isLoaded)+", havePlugin: "+
+ booltostring(havePlugin)+", name: "+name);
+ pluginOptionsWidget tempItem;
+ tempItem.name=name;
+ tempItem.item=NULL;
+ tempItem.options=theNewOptionsWidget;
+ tempItem.category=PluginType_Themes;
+ pluginOptionsWidgetList.push_back(tempItem);
+ if(theNewOptionsWidget!=NULL)
+ {
+ ui->stackedWidgetThemesOptions->addWidget(theNewOptionsWidget);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"set the last page");
+ }
+ on_Ultracopier_current_theme_currentIndexChanged(ui->Ultracopier_current_theme->currentIndex());
+}
+
+void OptionDialog::addPluginOptionWidget(const PluginType &category,const std::string &name,QWidget * options)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start: "+name+", category: "+std::to_string(category));
+ //prevent send the empty options
+ if(options!=NULL)
+ {
+ unsigned int index=0;
+ while(index<pluginOptionsWidgetList.size())
+ {
+ if(pluginOptionsWidgetList.at(index).name==name)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"already found: "+name);
+ return;
+ }
+ index++;
+ }
+ //add to real list
+ pluginOptionsWidget temp;
+ temp.name=name;
+ temp.options=options;
+ temp.item=new QTreeWidgetItem(QStringList() << QString::fromStdString(name));
+ temp.category=category;
+ pluginOptionsWidgetList.push_back(temp);
+ //add the specific options
+ switch(category)
+ {
+ case PluginType_CopyEngine:
+ ui->treeWidget->topLevelItem(2)->addChild(pluginOptionsWidgetList.at(index).item);
+ ui->stackedOptionsCopyEngine->addWidget(options);
+ break;
+ case PluginType_Listener:
+ ui->treeWidget->topLevelItem(3)->addChild(pluginOptionsWidgetList.at(index).item);
+ ui->stackedOptionsListener->addWidget(options);
+ break;
+ case PluginType_PluginLoader:
+ ui->treeWidget->topLevelItem(4)->addChild(pluginOptionsWidgetList.at(index).item);
+ ui->stackedOptionsPluginLoader->addWidget(options);
+ break;
+ case PluginType_SessionLoader:
+ ui->treeWidget->topLevelItem(5)->addChild(pluginOptionsWidgetList.at(index).item);
+ ui->stackedOptionsSessionLoader->addWidget(options);
+ break;
+ default:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"Unable to parse this unknow type of plugin: "+name);
+ return;
+ }
+ }
+ //only for copy engine
+ if(category==PluginType_CopyEngine)
+ {
+ //but can loaded by the previous options
+ unsigned int index=0;
+ const unsigned int loop_size=static_cast<unsigned int>(ui->CopyEngineList->count());
+ while(index<loop_size)
+ {
+ if(ui->CopyEngineList->item(static_cast<int>(index))->text().toStdString()==name)
+ break;
+ index++;
+ }
+ if(index==loop_size)
+ ui->CopyEngineList->addItems(QStringList() << QString::fromStdString(name));
+ }
+}
+
+void OptionDialog::on_pluginList_itemSelectionChanged()
+{
+ if(ui->pluginList->selectedItems().size()==0)
+ {
+ ui->pluginRemove->setEnabled(false);
+ ui->pluginInformation->setEnabled(false);
+ }
+ else
+ {
+ treeWidgetItem=ui->pluginList->selectedItems().first();
+ unsigned int index=0;
+ while(index<pluginLink.size())
+ {
+ if(pluginLink.at(index).item==treeWidgetItem)
+ {
+ ui->pluginRemove->setEnabled(pluginLink.at(index).isWritable);
+ ui->pluginInformation->setEnabled(true);
+ return;
+ }
+ index++;
+ }
+ }
+}
+
+void OptionDialog::on_pluginInformation_clicked()
+{
+ treeWidgetItem=ui->pluginList->selectedItems().first();
+ unsigned int index=0;
+ while(index<pluginLink.size())
+ {
+ if(pluginLink.at(index).item==treeWidgetItem)
+ {
+ PluginsManager::pluginsManager->showInformation(pluginLink.at(index).path);
+ return;
+ }
+ index++;
+ }
+}
+
+#ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+void OptionDialog::on_pluginRemove_clicked()
+{
+ treeWidgetItem=ui->pluginList->selectedItems().first();
+ unsigned int index=0;
+ while(index<pluginLink.size())
+ {
+ if(pluginLink.at(index).item==treeWidgetItem)
+ {
+ PluginsManager::pluginsManager->removeThePluginSelected(pluginLink.at(index).path);
+ return;
+ }
+ index++;
+ }
+}
+
+void OptionDialog::on_pluginAdd_clicked()
+{
+ PluginsManager::pluginsManager->addPlugin(defaultImportBackend);
+}
+#endif
+
+void OptionDialog::on_checkBox_Log_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","enabled",booltostring(ui->checkBox_Log->isChecked()));
+ }
+ ui->lineEditLog_transfer_format->setEnabled(ui->checkBoxLog_transfer->isChecked() && ui->checkBox_Log->isChecked());
+ ui->lineEditLog_error_format->setEnabled(ui->checkBoxLog_error->isChecked() && ui->checkBox_Log->isChecked());
+ ui->lineEditLog_folder_format->setEnabled(ui->checkBoxLog_folder->isChecked() && ui->checkBox_Log->isChecked());
+}
+
+void OptionDialog::on_lineEditLog_File_editingFinished()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","file",ui->lineEditLog_File->text().toStdString());
+ }
+}
+
+void OptionDialog::on_lineEditLog_transfer_format_editingFinished()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","transfer_format",ui->lineEditLog_transfer_format->text().toStdString());
+ }
+}
+
+void OptionDialog::on_lineEditLog_error_format_editingFinished()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","error_format",ui->lineEditLog_error_format->text().toStdString());
+ }
+}
+
+void OptionDialog::on_checkBoxLog_transfer_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","transfer",booltostring(ui->checkBoxLog_transfer->isChecked()));
+ }
+}
+
+void OptionDialog::on_checkBoxLog_error_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","error",booltostring(ui->checkBoxLog_error->isChecked()));
+ }
+}
+
+void OptionDialog::on_checkBoxLog_folder_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","folder",booltostring(ui->checkBoxLog_folder->isChecked()));
+ }
+}
+
+void OptionDialog::on_logBrowse_clicked()
+{
+ QString file=QFileDialog::getSaveFileName(this,tr("Save logs as: "),QString::fromStdString(ResourcesManager::resourcesManager->getWritablePath()));
+ if(file!="")
+ {
+ ui->lineEditLog_File->setText(file);
+ on_lineEditLog_File_editingFinished();
+ }
+}
+
+void OptionDialog::on_checkBoxLog_sync_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Write_log","sync",booltostring(ui->checkBoxLog_sync->isChecked()));
+ }
+}
+
+void OptionDialog::on_ActionOnManualOpen_currentIndexChanged(const int &index)
+{
+ if(index!=-1 && allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"data value: "+ui->ActionOnManualOpen->itemData(index).toString().toStdString()+
+ ", string value: "+ui->ActionOnManualOpen->itemText(index).toStdString()+", index: "+std::to_string(index));
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","ActionOnManualOpen",std::to_string(index));
+ }
+}
+
+void OptionDialog::on_GroupWindowWhen_currentIndexChanged(const int &index)
+{
+ if(index!=-1 && allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"data value: "+ui->GroupWindowWhen->itemData(index).toString().toStdString()+
+ ", string value: "+ui->GroupWindowWhen->itemText(index).toStdString()+", index: "+std::to_string(index));
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","GroupWindowWhen",std::to_string(index));
+ }
+}
+
+void OptionDialog::on_DisplayOSWarning_clicked()
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","displayOSSpecific",booltostring(ui->DisplayOSWarning->isChecked()));
+ }
+}
+
+void OptionDialog::newClientList(const std::vector<std::string> &clientsList)
+{
+ ui->clientConnected->clear();
+ unsigned int index=0;
+ while(index<clientsList.size())
+ {
+ ui->clientConnected->addItem(QString::fromStdString(clientsList.at(index)));
+ index++;
+ }
+}
+
+void OptionDialog::on_checkTheUpdate_clicked()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","checkTheUpdate",booltostring(ui->checkTheUpdate->isChecked()));
+}
+
+void OptionDialog::on_confirmToGroupWindows_clicked()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","confirmToGroupWindows",booltostring(ui->confirmToGroupWindows->isChecked()));
+}
+
+void OptionDialog::on_remainingTimeAlgorithm_currentIndexChanged(int index)
+{
+ if(allPluginsIsLoaded)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ OptionEngine::optionEngine->setOptionValue("Ultracopier","remainingTimeAlgorithm",std::to_string(index));
+ }
+}
diff --git a/OptionDialog.h b/OptionDialog.h
new file mode 100644
index 0000000..c8e9db3
--- /dev/null
+++ b/OptionDialog.h
@@ -0,0 +1,122 @@
+/** \file OptionDialog.h
+\brief To have an interface to control the options
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "Environment.h"
+
+#ifndef OPTIONDIALOG_H
+#define OPTIONDIALOG_H
+
+#include <QDialog>
+#include <QAbstractButton>
+#include <QTreeWidgetItem>
+
+#include "Environment.h"
+#include "OSSpecific.h"
+#include "PluginsManager.h"
+
+namespace Ui {
+ class OptionDialog;
+}
+
+/** \brief Dialog for the options
+
+ It's need manage the ultracopier options, plugins selection, plugin prority.
+ It's need manage too the plugin options and plugins informations.
+ */
+class OptionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit OptionDialog();
+ ~OptionDialog();
+ /** \brief add the option widget from copy engine */
+ void addPluginOptionWidget(const PluginType &category,const std::string &name,QWidget * options);
+protected:
+ void changeEvent(QEvent *e);
+ void loadLogVariableLabel();
+private slots:
+ void on_treeWidget_itemSelectionChanged();
+ void on_buttonBox_clicked(QAbstractButton *button);
+ //plugin management
+ void onePluginAdded(const PluginsAvailable &plugin);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ void onePluginWillBeRemoved(const PluginsAvailable &plugin);
+ #endif
+ #ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ void manuallyAdded(const PluginsAvailable &plugin);
+ #endif
+ void loadOption();
+ void newOptionValue(const std::string &group,const std::string &name,const std::string &value);
+ void on_Ultracopier_current_theme_currentIndexChanged(const int &index);
+ void on_Language_currentIndexChanged(const int &index);
+ void on_Language_force_toggled(const bool &checked);
+ void on_CatchCopyAsDefault_toggled(const bool &checked);
+ #ifndef ULTRACOPIER_VERSION_PORTABLE
+ void on_LoadAtSessionStarting_toggled(const bool &checked);
+ #endif
+ void on_CopyEngineList_itemSelectionChanged();
+ void on_toolButtonDown_clicked();
+ void on_toolButtonUp_clicked();
+ void on_pluginList_itemSelectionChanged();
+ #ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ void on_pluginRemove_clicked();
+ void on_pluginAdd_clicked();
+ #endif
+ void on_pluginInformation_clicked();
+ void on_checkBox_Log_clicked();
+ void on_lineEditLog_File_editingFinished();
+ void on_lineEditLog_transfer_format_editingFinished();
+ void on_lineEditLog_error_format_editingFinished();
+ void on_checkBoxLog_transfer_clicked();
+ void on_checkBoxLog_error_clicked();
+ void on_logBrowse_clicked();
+ void on_checkBoxLog_folder_clicked();
+ void on_checkBoxLog_sync_clicked();
+ void on_ActionOnManualOpen_currentIndexChanged(const int &index);
+ void on_GroupWindowWhen_currentIndexChanged(const int &index);
+ void on_DisplayOSWarning_clicked();
+ void on_checkTheUpdate_clicked();
+ void on_confirmToGroupWindows_clicked();
+ void oSSpecificClosed();
+ void on_remainingTimeAlgorithm_currentIndexChanged(int index);
+
+private:
+ bool quit;
+ Ui::OptionDialog *ui;
+ struct pluginStore
+ {
+ QTreeWidgetItem * item;
+ std::string path;
+ bool isWritable;
+ };
+ std::vector<pluginStore> pluginLink;
+ struct pluginOptionsWidget
+ {
+ std::string name;
+ QTreeWidgetItem * item;
+ QWidget *options;
+ PluginType category;
+ };
+ std::vector<pluginOptionsWidget> pluginOptionsWidgetList;
+ int number_of_listener;
+ void addLanguage(const PluginsAvailable &plugin);
+ void removeLanguage(const PluginsAvailable &plugin);
+ void addTheme(const PluginsAvailable &plugin);
+ void removeTheme(const PluginsAvailable &plugin);
+ std::vector<std::string> copyEngineStringList() const;
+ bool ignoreCopyEngineListEdition;
+ PluginsManager::ImportBackend defaultImportBackend;
+ int loadedCopyEnginePlugin;
+ QTreeWidgetItem * treeWidgetItem;
+ OSSpecific *oSSpecific;
+ bool allPluginsIsLoaded;
+public slots:
+ void newThemeOptions(const std::string &name,QWidget* theNewOptionsWidget,bool isLoaded,bool havePlugin);
+ void newClientList(const std::vector<std::string> &clientsList);
+signals:
+ void previouslyPluginAdded(const PluginsAvailable &plugin) const;
+};
+
+#endif // OPTIONDIALOG_H
diff --git a/OptionDialog.ui b/OptionDialog.ui
new file mode 100644
index 0000000..54d9591
--- /dev/null
+++ b/OptionDialog.ui
@@ -0,0 +1,988 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OptionDialog</class>
+ <widget class="QDialog" name="OptionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>779</width>
+ <height>455</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Options</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources/ultracopier-resources.qrc">
+ <normaloff>:/options.png</normaloff>:/options.png</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>1</number>
+ </property>
+ <property name="leftMargin">
+ <number>1</number>
+ </property>
+ <property name="topMargin">
+ <number>1</number>
+ </property>
+ <property name="rightMargin">
+ <number>1</number>
+ </property>
+ <property name="bottomMargin">
+ <number>1</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>200</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Options</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>General</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Plugins</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Copy engine</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Listener</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Plugin loader</string>
+ </property>
+ <property name="flags">
+ <set>ItemIsDragEnabled|ItemIsUserCheckable|ItemIsEnabled</set>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Session loader</string>
+ </property>
+ <property name="flags">
+ <set>ItemIsDragEnabled|ItemIsUserCheckable|ItemIsEnabled</set>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Themes</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Log</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="stackedWidgetGeneral">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="Language_force">
+ <property name="text">
+ <string>Force the language</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="Language"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelCatchCopyDefault">
+ <property name="text">
+ <string>Replace the default copy and move system</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="CatchCopyAsDefault">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelLoadAtSession">
+ <property name="text">
+ <string>Load at the session loading</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="LoadAtSessionStarting">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>When manual open</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QComboBox" name="ActionOnManualOpen">
+ <item>
+ <property name="text">
+ <string notr="true">Do nothing</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">Ask source as folder</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">Ask sources as files</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Group the windows when</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="GroupWindowWhen">
+ <item>
+ <property name="text">
+ <string notr="true">Never</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">When source is same</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">When destination is same</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">When source and destination are same</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">When source or destination are same</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">Always</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Confirm to group the windows</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QCheckBox" name="confirmToGroupWindows"/>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Display the OS warning</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QCheckBox" name="DisplayOSWarning"/>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_checkTheUpdate">
+ <property name="text">
+ <string>Check for updates</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="checkTheUpdate"/>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Remaining time algorithm</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QComboBox" name="remainingTimeAlgorithm">
+ <item>
+ <property name="text">
+ <string>Traditional</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Logarithmic</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>309</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetPlugins">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTreeWidget" name="pluginList">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>Copy engine</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Language</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Listener</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Plugin loader</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Session loader</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Themes</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Plugin</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="pluginAdd">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="popupMode">
+ <enum>QToolButton::MenuButtonPopup</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pluginRemove">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pluginInformation">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Information</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetCopyEngine">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Copy engine by order of preference:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="formLayout">
+ <item>
+ <widget class="QListWidget" name="CopyEngineList">
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="toolButtonUp">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="resources/ultracopier-resources.qrc">
+ <normaloff>:/moveUp.png</normaloff>:/moveUp.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolButtonDown">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="resources/ultracopier-resources.qrc">
+ <normaloff>:/moveDown.png</normaloff>:/moveDown.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetCopyEngineOptions">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QStackedWidget" name="stackedOptionsCopyEngine"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetListener">
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Client connected</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="clientConnected"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetListenerOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item>
+ <widget class="QStackedWidget" name="stackedOptionsListener"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetPluginLoaderOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <widget class="QStackedWidget" name="stackedOptionsPluginLoader"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetSessionLoaderOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_13">
+ <item>
+ <widget class="QStackedWidget" name="stackedOptionsSessionLoader"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetThemes">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelThemes">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>22</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Themes:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="Ultracopier_current_theme"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidgetThemesOptions">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="pageUnableToLoadThemePlugin">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>105</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="pixmap">
+ <pixmap resource="resources/ultracopier-resources.qrc">:/bug-128x128.png</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="font">
+ <font>
+ <pointsize>15</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Unable to load the themes plugin</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>104</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="pageThemeNoOptions">
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>109</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="pixmap">
+ <pixmap resource="resources/ultracopier-resources.qrc">:/none-128x128.png</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>No option for this plugin</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>109</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="stackedWidgetLog">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QCheckBox" name="checkBox_Log">
+ <property name="text">
+ <string>Write the log file into:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLineEdit" name="lineEditLog_File">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="logBrowse">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxLog_sync">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Write directly to the file when it receive a new entry (can produce 50% of lost of performance)</string>
+ </property>
+ <property name="text">
+ <string>Synchronized log</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxLog_transfer">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Write the transfers</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditLog_transfer_format">
+ <property name="toolTip">
+ <string extracomment="%time%, %source%, %size%, %destination% should not be translated">The variables are %time%, %source%, %size%, %destination%</string>
+ </property>
+ <property name="placeholderText">
+ <string notr="true">[%time%] %source% (%size%) %destination%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelLogTransfer">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string notr="true" extracomment="%time%, %source%, %size%, %destination% should not be translated">The variables are %time%, %source%, %size%, %destination%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxLog_error">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Write the errors</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditLog_error_format">
+ <property name="toolTip">
+ <string extracomment="%time%, %path%, %size%, %mtime%, %error% should not be translated">The variables are %time%, %path%, %size%, %mtime%, %error%</string>
+ </property>
+ <property name="placeholderText">
+ <string notr="true">[%time%] %path%, %error%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelLogError">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string notr="true" extracomment="%time%, %path%, %size%, %mtime%, %error% should not be translated">The variables are %time%, %path%, %size%, %mtime%, %error%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxLog_folder">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Write the folder operations</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditLog_folder_format">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string extracomment="%path%, %operation% should not be translated">The variables are %path%, %operation%</string>
+ </property>
+ <property name="placeholderText">
+ <string notr="true">[%time%] %operation% %path%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelLogFolder">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string notr="true" extracomment="%path%, %operation% should not be translated">The variables are %path%, %operation%</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>255</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::RestoreDefaults</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="resources/ultracopier-resources.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineEditLog_File</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>313</x>
+ <y>13</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>533</x>
+ <y>44</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>logBrowse</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>583</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>584</x>
+ <y>40</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>checkBoxLog_transfer</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>345</x>
+ <y>21</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>582</x>
+ <y>105</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>checkBoxLog_error</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>348</x>
+ <y>25</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>557</x>
+ <y>156</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBoxLog_transfer</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineEditLog_transfer_format</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>537</x>
+ <y>105</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>533</x>
+ <y>131</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBoxLog_error</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lineEditLog_error_format</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>501</x>
+ <y>156</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>501</x>
+ <y>182</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>checkBoxLog_folder</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>269</x>
+ <y>15</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>456</x>
+ <y>207</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>checkBox_Log</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>checkBoxLog_sync</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>334</x>
+ <y>12</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>304</x>
+ <y>69</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/OptionEngine.cpp b/OptionEngine.cpp
new file mode 100644
index 0000000..ad2cf7c
--- /dev/null
+++ b/OptionEngine.cpp
@@ -0,0 +1,242 @@
+/** \file OptionEngine.cpp
+\brief Define the class of the event dispatcher
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QFileInfo>
+#include <QDir>
+#include <QLabel>
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QMessageBox>
+
+#include "OptionEngine.h"
+
+/// \todo async the options write
+
+/// \brief Initiate the option, load from backend
+OptionEngine::OptionEngine()
+{
+ //locate the settings
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ QString settingsFilePath=QString::fromStdString(ResourcesManager::resourcesManager->getWritablePath());
+ if(settingsFilePath!="")
+ settings = new QSettings(settingsFilePath+QStringLiteral("Ultracopier.conf"),QSettings::IniFormat);
+ else
+ settings = NULL;
+ #else // ULTRACOPIER_VERSION_PORTABLE
+ settings = new QSettings(QStringLiteral("Ultracopier"),QStringLiteral("Ultracopier"));
+ #endif // ULTRACOPIER_VERSION_PORTABLE
+ if(settings!=NULL)
+ {
+ //do some write test
+ if(settings->status()!=QSettings::NoError)
+ {
+ delete settings;
+ settings=NULL;
+ }
+ else if(!settings->isWritable())
+ {
+ delete settings;
+ settings=NULL;
+ }
+ else
+ {
+ settings->setValue(QStringLiteral("test"),QStringLiteral("test"));
+ if(settings->status()!=QSettings::NoError)
+ {
+ delete settings;
+ settings=NULL;
+ }
+ else
+ {
+ settings->remove(QStringLiteral("test"));
+ if(settings->status()!=QSettings::NoError)
+ {
+ delete settings;
+ settings=NULL;
+ }
+ }
+ }
+ }
+ //set the backend
+ if(settings==NULL)
+ {
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ ResourcesManager::resourcesManager->disableWritablePath();
+ #endif // ULTRACOPIER_VERSION_PORTABLE
+ currentBackend=Memory;
+ }
+ else
+ currentBackend=File;
+}
+
+/// \brief Destroy the option
+OptionEngine::~OptionEngine()
+{
+}
+
+/// \brief To add option group to options
+bool OptionEngine::addOptionGroup(const std::string &groupName,const std::vector<std::pair<std::string, std::string> > &KeysList)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start(\""+groupName+"\",[...])");
+ //search if previous with the same name exists
+ if(GroupKeysList.find(groupName)!=GroupKeysList.cend())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"group already used previously");
+ return false;
+ }
+ //if the backend is file, enter into the group
+ if(currentBackend==File)
+ settings->beginGroup(QString::fromStdString(groupName));
+ //browse all key, and append it to the key
+ unsigned int index=0;
+ //QList<OptionEngineGroupKey> KeyListTemp;
+ while(index<KeysList.size())
+ {
+ OptionEngineGroupKey theCurrentKey;
+ theCurrentKey.defaultValue=KeysList.at(index).second;
+ //if memory backend, load the default value into the current value
+ if(currentBackend==Memory)
+ theCurrentKey.currentValue=theCurrentKey.defaultValue;
+ else
+ {
+ if(settings->contains(QString::fromStdString(KeysList.at(index).first)))//if file backend, load the default value from the file
+ {
+ theCurrentKey.currentValue=settings->value(QString::fromStdString(KeysList.at(index).first)).toString().toStdString();
+ #ifdef ULTRACOPIER_DEBUG
+ if(theCurrentKey.currentValue!=theCurrentKey.defaultValue)
+ {
+ #ifdef ULTRACOPIER_VERSION_ULTIMATE
+ if(groupName=="Ultracopier" && KeysList.at(index).first=="key")
+ {
+ }
+ else
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"The current key: "+groupName+", group: "+KeysList.at(index).first+", have value: "+theCurrentKey.currentValue);
+ }
+ #endif
+ }
+ else //or if not found load the default value and set into the file
+ {
+ theCurrentKey.currentValue=theCurrentKey.defaultValue;
+ //to switch default value if is unchanged
+ //settings->setValue(KeysList.at(index).first,theCurrentKey.defaultValue);
+ }
+ if(settings->status()!=QSettings::NoError)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Have writing error, switch to memory only options");
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ ResourcesManager::resourcesManager->disableWritablePath();
+ #endif // ULTRACOPIER_VERSION_PORTABLE
+ currentBackend=Memory;
+ }
+ }
+ GroupKeysList[groupName][KeysList.at(index).first]=theCurrentKey;
+ index++;
+ }
+ //if the backend is file, leave into the group
+ if(currentBackend==File)
+ settings->endGroup();
+ return true;
+}
+
+/// \brief To remove option group to options, remove the widget need be do into the calling object
+bool OptionEngine::removeOptionGroup(const std::string &groupName)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, groupName: "+groupName);
+ if(GroupKeysList.erase(groupName)!=1)
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"value not found, internal bug, groupName: "+groupName);
+ return false;
+}
+
+/// \brief To get option value
+std::string OptionEngine::getOptionValue(const std::string &groupName,const std::string &variableName) const
+{
+ if(GroupKeysList.find(groupName)!=GroupKeysList.cend())
+ {
+ const std::unordered_map<std::string,OptionEngineGroupKey> &optionEngineGroupKey=GroupKeysList.at(groupName);
+ if(optionEngineGroupKey.find(variableName)!=optionEngineGroupKey.cend())
+ return optionEngineGroupKey.at(variableName).currentValue;
+ QMessageBox::critical(NULL,"Internal error",tr("The variable was not found: %1 %2")
+ .arg(QString::fromStdString(groupName))
+ .arg(QString::fromStdString(variableName))
+ );
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"value not found, internal bug, groupName: "+groupName+", variableName: "+variableName);
+ return std::string();
+ }
+ QMessageBox::critical(NULL,"Internal error",tr("The variable was not found: %1 %2").arg(QString::fromStdString(groupName)).arg(QString::fromStdString(variableName)));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,QString("The variable was not found: %1 %2")
+ .arg(QString::fromStdString(groupName))
+ .arg(QString::fromStdString(variableName))
+ .toStdString()
+ );
+ //return default value
+ return std::string();
+}
+
+/// \brief To set option value
+void OptionEngine::setOptionValue(const std::string &groupName,const std::string &variableName,const std::string &value)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"groupName: \""+groupName+"\", variableName: \""+variableName+"\", value: \""+value+"\"");
+
+ if(GroupKeysList.find(groupName)!=GroupKeysList.cend())
+ {
+ const std::unordered_map<std::string,OptionEngineGroupKey> &group=GroupKeysList.at(groupName);
+ if(group.find(variableName)!=group.cend())
+ {
+ //prevent re-write the same value into the variable
+ if(group.at(variableName).currentValue==value)
+ return;
+ //write ONLY the new value
+ GroupKeysList[groupName][variableName].currentValue=value;
+ if(currentBackend==File)
+ {
+ settings->beginGroup(QString::fromStdString(groupName));
+ settings->setValue(QString::fromStdString(variableName),QString::fromStdString(value));
+ settings->endGroup();
+ if(settings->status()!=QSettings::NoError)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Have writing error, switch to memory only options");
+ #ifdef ULTRACOPIER_VERSION_PORTABLE
+ ResourcesManager::resourcesManager->disableWritablePath();
+ #endif // ULTRACOPIER_VERSION_PORTABLE
+ currentBackend=Memory;
+ }
+ }
+ emit newOptionValue(groupName,variableName,value);
+ return;
+ }
+ QMessageBox::critical(NULL,"Internal error",tr("The variable was not found: %1 %2").arg(QString::fromStdString(groupName)).arg(QString::fromStdString(variableName)));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"value not found, internal bug, groupName: "+groupName+", variableName: "+variableName);
+ return;
+ }
+ QMessageBox::critical(NULL,"Internal error",tr("The variable was not found: %1 %2").arg(QString::fromStdString(groupName)).arg(QString::fromStdString(variableName)));
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"The variable was not found: "+groupName+" "+variableName);
+}
+
+//the reset of right value of widget need be do into the calling object
+void OptionEngine::internal_resetToDefaultValue()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+
+ for(auto& n:GroupKeysList)
+ {
+ const std::string &firstKey=n.first;
+ for(auto& m:n.second)
+ {
+ const std::string &secondKey=m.first;
+ OptionEngineGroupKey &o=m.second;
+ if(o.currentValue!=o.defaultValue)
+ {
+ o.currentValue=o.defaultValue;
+ emit newOptionValue(firstKey,secondKey,o.currentValue);
+ }
+ }
+ }
+}
+
+void OptionEngine::queryResetOptions()
+{
+ emit resetOptions();
+}
diff --git a/OptionEngine.h b/OptionEngine.h
new file mode 100644
index 0000000..027861f
--- /dev/null
+++ b/OptionEngine.h
@@ -0,0 +1,87 @@
+/** \file OptionEngine.h
+\brief Define the class of the option engine
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef OPTION_ENGINE_H
+#define OPTION_ENGINE_H
+
+#include <QDialog>
+#include <QList>
+#include <QSettings>
+#include <QFormLayout>
+#include <QLayout>
+#include <QStringList>
+#include <QFormLayout>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QSpinBox>
+#include <QAbstractButton>
+#include <QTimer>
+#include <QWidget>
+#include <QHash>
+#include <unordered_map>
+
+#include "interface/OptionInterface.h"
+
+#include "Environment.h"
+#include "ResourcesManager.h"
+
+/** \brief To store the options
+
+ That's allow to have mutualised way to store the options. Then the plugins just keep Ultracopier manage it, the portable version will store on the disk near the application, and the normal version will keep at the normal location.
+ That's allow to have cache and buffer to not slow down Ultracopier when it's doing heavy copy/move.
+*/
+class OptionEngine : public QObject
+{
+ Q_OBJECT
+ //class OptionEngine : public OptionInterface, public QDialog, public Singleton<OptionEngine>
+ public:
+ /// \brief Initiate the option, load from backend
+ OptionEngine();
+ /// \brief Destroy the option
+ ~OptionEngine();
+ /// \brief To add option group to options
+ bool addOptionGroup(const std::string &groupName,const std::vector<std::pair<std::string, std::string> > &KeysList);
+ /// \brief To remove option group to options, remove the widget need be do into the calling object
+ bool removeOptionGroup(const std::string &groupName);
+ /// \brief To get option value
+ std::string getOptionValue(const std::string &groupName,const std::string &variableName) const;
+ /// \brief To set option value
+ void setOptionValue(const std::string &groupName,const std::string &variableName,const std::string &value);
+ /// \brief To invalid option value
+ //void setInvalidOptionValue(const QString &groupName,const QString &variableName);
+ /// \brief get query reset options
+ void queryResetOptions();
+ private:
+ /// \brief OptionEngineGroupKey then: Group -> Key
+ struct OptionEngineGroupKey
+ {
+ std::string defaultValue;
+ std::string currentValue;
+ bool emptyList;
+ };
+
+ /// \brief store the option group list
+ std::unordered_map<std::string,std::unordered_map<std::string,OptionEngineGroupKey> > GroupKeysList;
+ std::vector<std::string> unmanagedTabName;
+ /// \brief Enumeration of backend
+ enum Backend
+ {
+ Memory, //Do intensive usage of memory, used only if the file backend is not available
+ File //Store all directly into file
+ };
+ /// \brief The current backend
+ Backend currentBackend;
+ /// \brief To store QSettings for the backend
+ QSettings *settings;
+ //the reset of right value of widget need be do into the calling object
+ void internal_resetToDefaultValue();
+ signals:
+ void newOptionValue(const std::string&,const std::string&,const std::string&) const;
+ void resetOptions() const;
+ public:
+ static OptionEngine *optionEngine;
+};
+
+#endif // OPTION_ENGINE_H
diff --git a/PlatformMacro.h b/PlatformMacro.h
new file mode 100644
index 0000000..d15329d
--- /dev/null
+++ b/PlatformMacro.h
@@ -0,0 +1,59 @@
+/** \file PlatformMacro.h
+\brief Define the macro for the platform
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QObject>
+
+#ifndef PLATFORM_MACRO_H
+#define PLATFORM_MACRO_H
+
+//windows
+#if defined(Q_OS_WIN32)
+ #if defined(_M_X64) //_WIN64
+ //windows 64Bits
+ #define ULTRACOPIER_PLATFORM_NAME tr("Windows 64Bits")
+ #define ULTRACOPIER_PLATFORM_CODE "windows-x86_64"
+ #else
+ //windows 32Bits
+ #define ULTRACOPIER_PLATFORM_NAME tr("Windows 32Bits")
+ #define ULTRACOPIER_PLATFORM_CODE "windows-x86"
+ #endif
+#elif defined(Q_OS_MAC)
+ //Mac OS X
+ #define ULTRACOPIER_PLATFORM_NAME tr("Mac OS X")
+ #define ULTRACOPIER_PLATFORM_CODE "mac-os-x"
+#elif defined(Q_OS_LINUX)
+ #if defined(__i386__)
+ //linux pc i386
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux pc i386")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-i386-pc"
+ #elif defined(__i486__)
+ //linux pc i486
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux pc i486")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-i486-pc"
+ #elif defined(__i586__)
+ //linux pc i586
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux pc i586")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-i586-pc"
+ #elif defined(__i686__)
+ //linux pc i686
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux pc i686")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-i686-pc"
+ #elif defined(__x86_64__)
+ //linux pc 64Bits
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux pc 64Bits")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-x86_64-pc"
+ #else
+ //linux unknow
+ #define ULTRACOPIER_PLATFORM_NAME tr("Linux unknow platform")
+ #define ULTRACOPIER_PLATFORM_CODE "linux-unknow-pc"
+ #endif
+#else
+ //unknow
+ #define ULTRACOPIER_PLATFORM_NAME tr("Unknow platform")
+ #define ULTRACOPIER_PLATFORM_CODE "unknow"
+#endif
+
+#endif // PLATFORM_MACRO_H
+
diff --git a/PluginInformation.cpp b/PluginInformation.cpp
new file mode 100644
index 0000000..8c1551c
--- /dev/null
+++ b/PluginInformation.cpp
@@ -0,0 +1,120 @@
+/** \file PluginInformation.cpp
+\brief Define the plugin information
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "PluginInformation.h"
+#include "ui_PluginInformation.h"
+#include "cpp11addition.h"
+
+PluginInformation::PluginInformation() :
+ ui(new Ui::PluginInformation)
+{
+ ui->setupUi(this);
+ pluginIsLoaded=false;
+}
+
+PluginInformation::~PluginInformation()
+{
+ delete ui;
+}
+
+void PluginInformation::setPlugin(const PluginsAvailable &plugin)
+{
+ this->plugin=plugin;
+ pluginIsLoaded=true;
+ retranslateInformation();
+}
+
+void PluginInformation::setLanguage(const std::string &language)
+{
+ this->language=language;
+}
+
+std::string PluginInformation::categoryToTranslation(const PluginType &category) const
+{
+ switch(category)
+ {
+ case PluginType_CopyEngine:
+ return tr("Copy engine").toStdString();
+ case PluginType_Languages:
+ return tr("Languages").toStdString();
+ case PluginType_Listener:
+ return tr("Listener").toStdString();
+ case PluginType_PluginLoader:
+ return tr("Plugin loader").toStdString();
+ case PluginType_SessionLoader:
+ return tr("Session loader").toStdString();
+ case PluginType_Themes:
+ return tr("Themes").toStdString();
+ default:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"cat translation not found");
+ return tr("Unknown").toStdString();
+ }
+}
+
+void PluginInformation::retranslateInformation()
+{
+ if(!pluginIsLoaded)
+ return;
+ ui->retranslateUi(this);
+ this->setWindowTitle(tr("Information about %1").arg(QString::fromStdString(plugin.name)));
+ ui->name->setText(QString::fromStdString(plugin.name));
+ ui->title->setText(QString::fromStdString(getTranslatedText(plugin,"title",language)));
+ ui->category->setText(QString::fromStdString(categoryToTranslation(plugin.category)));
+ ui->author->setText(QString::fromStdString(getInformationText(plugin,"author")));
+ QString website=QString::fromStdString(getTranslatedText(plugin,"website",language));
+ ui->website->setText(QStringLiteral("<a href=\"")+website+QStringLiteral("\" title=\"")+website+QStringLiteral("\">")+website+QStringLiteral("</a>"));
+ bool ok;
+ int timeStamps=stringtoint32(getInformationText(plugin,"pubDate"),&ok);
+ QDateTime date;
+ date.setTime_t(timeStamps);
+ ui->date->setDateTime(date);
+ if(!ok || timeStamps<=0)
+ ui->date->setEnabled(false);
+ ui->description->setPlainText(QString::fromStdString(getTranslatedText(plugin,"description",language)));
+ ui->version->setText(QString::fromStdString(getInformationText(plugin,"version")));
+}
+
+/// \brief get informations text
+std::string PluginInformation::getInformationText(const PluginsAvailable &plugin,const std::string &informationName)
+{
+ unsigned int index=0;
+ while(index<plugin.informations.size())
+ {
+ const std::vector<std::string> &information=plugin.informations.at(index);
+ if(information.size()==2 && information.front()==informationName)
+ return information.back();
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"information not found: "+informationName+", for: "+plugin.name+", cat: "+categoryToTranslation(plugin.category));
+ return std::string();
+}
+
+/// \brief get translated text
+std::string PluginInformation::getTranslatedText(const PluginsAvailable &plugin,const std::string &informationName,const std::string &mainShortName)
+{
+ unsigned int index=0;
+ std::string TextFound;
+ while(index<plugin.informations.size())
+ {
+ const std::vector<std::string> &information=plugin.informations.at(index);
+ if(information.size()==3)
+ {
+ if(information.front()==informationName)
+ {
+ if(information.at(1)==mainShortName)
+ return information.back();
+ else if(information.at(1)=="en")
+ TextFound=information.back();
+
+ }
+ }
+ index++;
+ }
+ #ifdef ULTRACOPIER_DEBUG
+ if(TextFound.empty() || TextFound.empty())
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"text is not found or empty for: "+informationName+", with the language: "+mainShortName+", for the plugin: "+plugin.path);
+ #endif // ULTRACOPIER_DEBUG
+ return TextFound;
+}
diff --git a/PluginInformation.h b/PluginInformation.h
new file mode 100644
index 0000000..d3c1d5a
--- /dev/null
+++ b/PluginInformation.h
@@ -0,0 +1,42 @@
+/** \file PluginInformation.h
+\brief Define the plugin information
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#ifndef PLUGININFORMATION_H
+#define PLUGININFORMATION_H
+
+#include <QDialog>
+#include <QDateTime>
+
+#include "Environment.h"
+
+namespace Ui {
+ class PluginInformation;
+}
+
+/** \brief to show the plugin information */
+class PluginInformation : public QDialog
+{
+ Q_OBJECT
+ public:
+ explicit PluginInformation();
+ ~PluginInformation();
+ /** \brief get translated categorie */
+ std::string categoryToTranslation(const PluginType &category) const;
+ /** \brief to get the new plugin informations */
+ void setPlugin(const PluginsAvailable &plugin);
+ /** \brief to set the language */
+ void setLanguage(const std::string &language);
+ public slots:
+ void retranslateInformation();
+ private:
+ bool pluginIsLoaded;
+ PluginsAvailable plugin;
+ Ui::PluginInformation *ui;
+ std::string language;
+ std::string getInformationText(const PluginsAvailable &plugin,const std::string &informationName);
+ std::string getTranslatedText(const PluginsAvailable &plugin,const std::string &informationName,const std::string &mainShortName);
+};
+
+#endif // PLUGININFORMATION_H
diff --git a/PluginInformation.ui b/PluginInformation.ui
new file mode 100644
index 0000000..64a0bd1
--- /dev/null
+++ b/PluginInformation.ui
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PluginInformation</class>
+ <widget class="QDialog" name="PluginInformation">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>About this plugin</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout_2">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="name">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Category:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="category">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="author">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Website:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="website">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Date:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QDateTimeEdit" name="date">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QTextEdit" name="description">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QLineEdit" name="version">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Title:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="title">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/PluginLoader.cpp b/PluginLoader.cpp
new file mode 100644
index 0000000..36101a4
--- /dev/null
+++ b/PluginLoader.cpp
@@ -0,0 +1,339 @@
+/** \file PluginLoader.h
+\brief Define the plugin loader
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include "PluginLoader.h"
+#include "LanguagesManager.h"
+
+#ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+#ifdef Q_OS_WIN32
+#include "plugins/PluginLoader/catchcopy-v0002/pluginLoader.h"
+#endif
+#endif
+
+PluginLoader::PluginLoader(OptionDialog *optionDialog)
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ this->optionDialog=optionDialog;
+ //load the overall instance
+ //load the plugin
+ PluginsManager::pluginsManager->lockPluginListEdition();
+ connect(this,&PluginLoader::previouslyPluginAdded, this,&PluginLoader::onePluginAdded,Qt::QueuedConnection);
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginAdded, this,&PluginLoader::onePluginAdded,Qt::QueuedConnection);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ connect(PluginsManager::pluginsManager,&PluginsManager::onePluginWillBeRemoved,this,&PluginLoader::onePluginWillBeRemoved,Qt::DirectConnection);
+ #endif
+ connect(PluginsManager::pluginsManager,&PluginsManager::pluginListingIsfinish, this,&PluginLoader::allPluginIsloaded,Qt::QueuedConnection);
+ std::vector<PluginsAvailable> list=PluginsManager::pluginsManager->getPluginsByCategory(PluginType_PluginLoader);
+ foreach(PluginsAvailable currentPlugin,list)
+ emit previouslyPluginAdded(currentPlugin);
+ PluginsManager::pluginsManager->unlockPluginListEdition();
+ needEnable=false;
+ last_state=Ultracopier::Uncaught;
+ last_have_plugin=false;
+ last_inWaitOfReply=false;
+ stopIt=false;
+}
+
+PluginLoader::~PluginLoader()
+{
+ stopIt=true;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ {
+ /* why it crash here? Only under Window with PluginLoader/catchcopy-v0002
+ int index=0;
+ while(index<pluginList.size())
+ {
+ pluginList.at(index).pluginLoaderInterface->setEnabled(false);
+ if(pluginList.at(index).pluginLoader!=NULL)
+ {
+ if(!pluginList.at(index).pluginLoader->isLoaded() || pluginList.at(index).pluginLoader->unload())
+ {
+ delete pluginList.at(index).options;
+ pluginList.removeAt(index);
+ }
+ else
+ index++;
+ }
+ else
+ index++;
+ }//*/
+ }
+ #endif
+}
+
+void PluginLoader::resendState()
+{
+ if(stopIt)
+ return;
+ sendState(true);
+}
+
+void PluginLoader::onePluginAdded(const PluginsAvailable &plugin)
+{
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ #ifdef Q_OS_WIN32
+ PluginInterface_PluginLoader *factory;
+ #endif
+ #endif
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ if(stopIt)
+ return;
+ if(plugin.category!=PluginType_PluginLoader)
+ return;
+ LocalPlugin newEntry;
+ std::string pluginPath=plugin.path+PluginsManager::getResolvedPluginName("pluginLoader");
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"try load: "+pluginPath);
+ #ifdef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ PluginInterface_PluginLoader *pluginLoaderInstance;
+ QObjectList objectList=QPluginLoader::staticInstances();
+ int index=0;
+ QObject *pluginObject;
+ while(index<objectList.size())
+ {
+ pluginObject=objectList.at(index);
+ pluginLoaderInstance = qobject_cast<PluginInterface_PluginLoader *>(pluginObject);
+ if(pluginLoaderInstance!=NULL)
+ break;
+ index++;
+ }
+ if(index==objectList.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"static listener not found");
+ return;
+ }
+ newEntry.pluginLoader=NULL;
+ #else
+ QPluginLoader *pluginLoader= new QPluginLoader(QString::fromStdString(pluginPath));
+ QObject *pluginInstance = pluginLoader->instance();
+ if(!pluginInstance)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to load the plugin: "+pluginLoader->errorString().toStdString());
+ return;
+ }
+ PluginInterface_PluginLoader *pluginLoaderInstance = qobject_cast<PluginInterface_PluginLoader *>(pluginInstance);
+ if(!pluginLoaderInstance)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"unable to cast the plugin: "+pluginLoader->errorString().toStdString());
+ return;
+ }
+ newEntry.pluginLoader = pluginLoader;
+ //check if found
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(pluginList.at(index).pluginLoaderInterface==pluginLoaderInstance)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Plugin already found");
+ pluginLoader->unload();
+ return;
+ }
+ index++;
+ }
+ #endif
+ #ifdef ULTRACOPIER_DEBUG
+ connect(pluginLoaderInstance,&PluginInterface_PluginLoader::debugInformation,this,&PluginLoader::debugInformation,Qt::DirectConnection);
+ #endif // ULTRACOPIER_DEBUG
+
+ newEntry.options=new LocalPluginOptions("PluginLoader-"+plugin.name);
+ newEntry.pluginLoaderInterface = pluginLoaderInstance;
+ newEntry.path = plugin.path;
+ newEntry.state = Ultracopier::Uncaught;
+ newEntry.inWaitOfReply = false;
+ pluginList.push_back(newEntry);
+ pluginLoaderInstance->setResources(newEntry.options,plugin.writablePath,plugin.path,ULTRACOPIER_VERSION_PORTABLE_BOOL);
+ optionDialog->addPluginOptionWidget(PluginType_PluginLoader,plugin.name,newEntry.pluginLoaderInterface->options());
+ connect(pluginList.back().pluginLoaderInterface,&PluginInterface_PluginLoader::newState,this,&PluginLoader::newState,Qt::DirectConnection);
+ connect(LanguagesManager::languagesManager,&LanguagesManager::newLanguageLoaded,newEntry.pluginLoaderInterface,&PluginInterface_PluginLoader::newLanguageLoaded,Qt::DirectConnection);
+ if(needEnable)
+ {
+ pluginList.back().inWaitOfReply=true;
+ newEntry.pluginLoaderInterface->setEnabled(needEnable);
+ }
+ #else
+ #ifdef Q_OS_WIN32
+ factory=new WindowsExplorerLoader();
+ LocalPlugin newEntry;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ newEntry.pluginLoader=NULL;
+ #endif
+
+ newEntry.options=new LocalPluginOptions("PluginLoader-"+plugin.name);
+ newEntry.pluginLoaderInterface = new WindowsExplorerLoader();
+ newEntry.path = plugin.path;
+ newEntry.state = Ultracopier::Uncaught;
+ newEntry.inWaitOfReply = false;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ #ifdef ULTRACOPIER_DEBUG
+ connect(newEntry.pluginLoaderInterface,&PluginInterface_PluginLoader::debugInformation,this,&PluginLoader::debugInformation,Qt::DirectConnection);
+ #endif // ULTRACOPIER_DEBUG
+ #endif
+ pluginList.push_back(newEntry);
+ newEntry.pluginLoaderInterface->setResources(newEntry.options,plugin.writablePath,plugin.path,ULTRACOPIER_VERSION_PORTABLE_BOOL);
+ optionDialog->addPluginOptionWidget(PluginType_PluginLoader,plugin.name,newEntry.pluginLoaderInterface->options());
+ connect(pluginList.back().pluginLoaderInterface,&PluginInterface_PluginLoader::newState,this,&PluginLoader::newState,Qt::DirectConnection);
+ connect(LanguagesManager::languagesManager,&LanguagesManager::newLanguageLoaded,newEntry.pluginLoaderInterface,&PluginInterface_PluginLoader::newLanguageLoaded,Qt::DirectConnection);
+ if(needEnable)
+ {
+ pluginList.back().inWaitOfReply=true;
+ newEntry.pluginLoaderInterface->setEnabled(needEnable);
+ }
+ #endif
+ Q_UNUSED(plugin);
+ #endif
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+void PluginLoader::onePluginWillBeRemoved(const PluginsAvailable &plugin)
+{
+ if(stopIt)
+ return;
+ if(plugin.category!=PluginType_PluginLoader)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(plugin.path==pluginList.at(index).path)
+ {
+ pluginList.at(index).pluginLoaderInterface->setEnabled(false);
+ if(pluginList.at(index).pluginLoader!=NULL)
+ {
+ if(!pluginList.at(index).pluginLoader->isLoaded() || pluginList.at(index).pluginLoader->unload())
+ {
+ delete pluginList.at(index).options;
+ pluginList.erase(pluginList.cbegin()+index);
+ }
+ }
+ sendState();
+ return;
+ }
+ index++;
+ }
+}
+#endif
+
+void PluginLoader::load()
+{
+ if(stopIt)
+ return;
+ needEnable=true;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ pluginList[index].inWaitOfReply=true;
+ pluginList.at(index).pluginLoaderInterface->setEnabled(true);
+ index++;
+ }
+ sendState(true);
+}
+
+void PluginLoader::unload()
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ needEnable=false;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ pluginList[index].inWaitOfReply=true;
+ pluginList.at(index).pluginLoaderInterface->setEnabled(false);
+ index++;
+ }
+ sendState(true);
+}
+
+#ifdef ULTRACOPIER_DEBUG
+void PluginLoader::debugInformation(const Ultracopier::DebugLevel &level,const std::string& fonction,const std::string& text,const std::string& file,const unsigned int& ligne)
+{
+ DebugEngine::addDebugInformationStatic(level,fonction,text,file,ligne,"Plugin loader plugin");
+}
+#endif // ULTRACOPIER_DEBUG
+
+void PluginLoader::allPluginIsloaded()
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"with value: "+std::to_string(pluginList.size()>0));
+ sendState(true);
+}
+
+void PluginLoader::sendState(bool force)
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, pluginList.size(): "+std::to_string(pluginList.size())+", force: "+std::to_string(force));
+ Ultracopier::CatchState current_state=Ultracopier::Uncaught;
+ bool found_not_listen=false,found_listen=false,found_inWaitOfReply=false;
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(current_state==Ultracopier::Uncaught)
+ {
+ if(pluginList.at(index).state==Ultracopier::Semiuncaught)
+ current_state=Ultracopier::Semiuncaught;
+ else if(pluginList.at(index).state==Ultracopier::Uncaught)
+ found_not_listen=true;
+ else if(pluginList.at(index).state==Ultracopier::Caught)
+ found_listen=true;
+ }
+ if(pluginList.at(index).inWaitOfReply)
+ found_inWaitOfReply=true;
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"current_state: "+std::to_string(current_state));
+ if(current_state==Ultracopier::Uncaught)
+ {
+ if(!found_not_listen && !found_listen)
+ {
+ if(needEnable)
+ current_state=Ultracopier::Caught;
+ }
+ else if(found_not_listen && !found_listen)
+ current_state=Ultracopier::Uncaught;
+ else if(!found_not_listen && found_listen)
+ current_state=Ultracopier::Caught;
+ else
+ current_state=Ultracopier::Semiuncaught;
+ }
+ bool have_plugin=pluginList.size()>0;
+ if(force || current_state!=last_state || have_plugin!=last_have_plugin || found_inWaitOfReply!=last_inWaitOfReply)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"send pluginLoaderReady("+std::to_string(current_state)+","+std::to_string(have_plugin)+","+std::to_string(found_inWaitOfReply)+")");
+ emit pluginLoaderReady(current_state,have_plugin,found_inWaitOfReply);
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"Skip the signal sending");
+ last_state=current_state;
+ last_have_plugin=have_plugin;
+ last_inWaitOfReply=found_inWaitOfReply;
+}
+
+void PluginLoader::newState(const Ultracopier::CatchState &state)
+{
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start, state: "+std::to_string(state));
+ PluginInterface_PluginLoader *temp=qobject_cast<PluginInterface_PluginLoader *>(QObject::sender());
+ if(temp==NULL)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"listener not located!");
+ return;
+ }
+ unsigned int index=0;
+ while(index<pluginList.size())
+ {
+ if(temp==pluginList.at(index).pluginLoaderInterface)
+ {
+ pluginList[index].state=state;
+ pluginList[index].inWaitOfReply=false;
+ sendState(true);
+ return;
+ }
+ index++;
+ }
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"listener not found!");
+}
diff --git a/PluginLoader.h b/PluginLoader.h
new file mode 100644
index 0000000..83dcc11
--- /dev/null
+++ b/PluginLoader.h
@@ -0,0 +1,82 @@
+/** \file PluginLoader.h
+\brief Define the class to load the plugin and lunch it
+\author alpha_one_x86
+\licence GPL3, see the file COPYING
+
+This class load ALL plugin compatible to listen and catch the copy/move
+*/
+
+#ifndef PluginLoader_H
+#define PluginLoader_H
+
+#include <QObject>
+#include <QList>
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+#include <QPluginLoader>
+#endif
+#include <QString>
+#include <QStringList>
+
+#include "interface/PluginInterface_PluginLoader.h"
+#include "PluginsManager.h"
+#include "OptionDialog.h"
+#include "LocalPluginOptions.h"
+
+namespace Ui {
+ class PluginLoaderOptions;
+}
+
+/** \brief Load the plugin
+
+ It use ResourcesManager(), but it provide more higher abstraction. It parse the plugins information, check it, check the dependancies.
+
+ \see ResourcesManager::ResourcesManager()
+ */
+class PluginLoader : public QObject
+{
+ Q_OBJECT
+public:
+ explicit PluginLoader(OptionDialog *optionDialog);
+ ~PluginLoader();
+ /** \brief to rended the state */
+ void resendState();
+ /** \brief should load plugin into file manager if needed */
+ void load();
+ /** \brief should unload plugin into file manager */
+ void unload();
+private slots:
+ void onePluginAdded(const PluginsAvailable &plugin);
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ void onePluginWillBeRemoved(const PluginsAvailable &plugin);
+ #endif
+ #ifdef ULTRACOPIER_DEBUG
+ void debugInformation(const Ultracopier::DebugLevel &level, const std::string& fonction, const std::string& text, const std::string& file, const unsigned int &ligne);
+ #endif // ULTRACOPIER_DEBUG
+ void allPluginIsloaded();
+ void newState(const Ultracopier::CatchState &state);
+private:
+ //variable
+ struct LocalPlugin
+ {
+ PluginInterface_PluginLoader * pluginLoaderInterface;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE_DIRECT
+ QPluginLoader * pluginLoader;
+ #endif
+ Ultracopier::CatchState state;
+ std::string path;
+ bool inWaitOfReply;
+ LocalPluginOptions *options;
+ };
+ std::vector<LocalPlugin> pluginList;
+ bool needEnable;
+ Ultracopier::CatchState last_state;
+ bool last_have_plugin,last_inWaitOfReply;
+ void sendState(bool force=false);
+ OptionDialog *optionDialog;
+ bool stopIt;
+signals:
+ void pluginLoaderReady(const Ultracopier::CatchState &state,bool havePlugin,bool someAreInWaitOfReply) const;
+ void previouslyPluginAdded(const PluginsAvailable &plugin) const;
+};
+
+#endif // PluginLoader_H
diff --git a/PluginsManager.cpp b/PluginsManager.cpp
new file mode 100644
index 0000000..269e837
--- /dev/null
+++ b/PluginsManager.cpp
@@ -0,0 +1,932 @@
+/** \file PluginsManager.cpp
+\brief Define the class to manage and load the plugins
+\author alpha_one_x86
+\licence GPL3, see the file COPYING */
+
+#include <QDir>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QFile>
+#include <QFileInfo>
+
+#include <iterator>
+
+#include "PluginsManager.h"
+#include "cpp11addition.h"
+#include "FacilityEngine.h"
+
+/// \brief Create the manager and load the defaults variables
+PluginsManager::PluginsManager()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ //load the overall instance
+ pluginLoaded = false;
+ language = "en";
+ stopIt = false;
+ pluginInformation = NULL;
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ importingPlugin = false;
+ #endif
+ editionSemList.release();
+ englishPluginType.push_back("CopyEngine");englishPluginType.push_back("Languages");englishPluginType.push_back("Listener");englishPluginType.push_back("PluginLoader");englishPluginType.push_back("SessionLoader");englishPluginType.push_back("Themes");
+ //catPlugin << tr("CopyEngine") << tr("Languages") << tr("Listener") << tr("PluginLoader") << tr("SessionLoader") << tr("Themes");
+ #ifdef ULTRACOPIER_PLUGIN_IMPORT_SUPPORT
+ connect(&decodeThread, &QXzDecodeThread::decodedIsFinish, this, &PluginsManager::decodingFinished,Qt::QueuedConnection);
+ #endif
+ connect(this, &PluginsManager::finished, this, &PluginsManager::post_operation,Qt::QueuedConnection);
+// connect(this, &PluginsManager::pluginListingIsfinish, options,&OptionEngine::setInterfaceValue);
+ //load the plugins list
+
+ /// \bug bug when I put here: moveToThread(this);, due to the direction connection to remove the plugin
+ start();
+}
+
+/// \brief Destroy the manager
+PluginsManager::~PluginsManager()
+{
+ stopIt=true;
+ if(pluginInformation!=NULL)
+ delete pluginInformation;
+ if(this->isRunning())
+ this->wait(0);
+}
+
+/// \brief set current language
+void PluginsManager::setLanguage(const std::string &language)
+{
+ this->language=language;
+}
+
+void PluginsManager::post_operation()
+{
+ pluginLoaded=true;
+ emit pluginListingIsfinish();
+}
+
+bool PluginsManager::allPluginHaveBeenLoaded() const
+{
+ return pluginLoaded;
+}
+
+void PluginsManager::lockPluginListEdition()
+{
+ editionSemList.acquire();
+}
+
+void PluginsManager::unlockPluginListEdition()
+{
+ editionSemList.release();
+}
+
+void PluginsManager::run()
+{
+ regexp_to_clean_1=std::regex("[\n\r]+");
+ regexp_to_clean_2=std::regex("[ \t]+");
+ regexp_to_clean_3=std::regex("(&&)+");
+ regexp_to_clean_4=std::regex("^&&");
+ regexp_to_clean_5=std::regex("&&$");
+ regexp_to_dep_1=std::regex("(&&|\\|\\||\\(|\\))");
+ regexp_to_dep_2=std::regex("^(<=|<|=|>|>=)[a-zA-Z0-9\\-]+-([0-9]+\\.)*[0-9]+$");
+ regexp_to_dep_3=std::regex("(<=|<|=|>|>=)");
+ regexp_to_dep_4=std::regex("-([0-9]+\\.)*[0-9]+");
+ regexp_to_dep_5=std::regex("[a-zA-Z0-9\\-]+-");
+ regexp_to_dep_6=std::regex("[a-zA-Z0-9\\-]+-([0-9]+\\.)*[0-9]+");
+
+ //load the path and plugins into the path
+ const std::string &separator=FacilityEngine::separator();
+ std::vector<std::string> readPath;
+ readPath=ResourcesManager::resourcesManager->getReadPath();
+ pluginsList.clear();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"pluginsList.size(): "+std::to_string(pluginsList.size()));
+ foreach(std::string basePath,readPath)
+ {
+ foreach(std::string dirSub,englishPluginType)
+ {
+ std::string pluginComposed=basePath+dirSub+separator;
+ QDir dir(QString::fromStdString(pluginComposed));
+ if(stopIt)
+ return;
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"search plugin into: "+pluginComposed);
+ if(dir.exists())
+ {
+ foreach(QString dirName, dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot))
+ {
+ if(stopIt)
+ return;
+ loadPluginInformation(pluginComposed+dirName.toStdString()+separator);
+ }
+ }
+ }
+ }
+ #ifdef ULTRACOPIER_DEBUG
+ unsigned int index_debug=0;
+ while(index_debug<pluginsList.size())
+ {
+ std::string category=categoryToString(pluginsList.at(index_debug).category);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,"Plugin "+std::to_string(index_debug)+" loaded ("+category+"): "+pluginsList.at(index_debug).path);
+ index_debug++;
+ }
+ #endif
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ while(checkDependencies()!=0){};
+ #endif
+ //QList<PluginsAvailable> list;
+ unsigned int index=0;
+ while(index<pluginsList.size())
+ {
+ if(pluginsList.at(index).errorString.empty())
+ emit onePluginAdded(pluginsList.at(index));
+ index++;
+ }
+}
+
+std::string PluginsManager::categoryToString(const PluginType &category) const
+{
+ switch(category)
+ {
+ case PluginType_CopyEngine:
+ return "CopyEngine";
+ break;
+ case PluginType_Languages:
+ return "Languages";
+ break;
+ case PluginType_Listener:
+ return "Listener";
+ break;
+ case PluginType_PluginLoader:
+ return "PluginLoader";
+ break;
+ case PluginType_SessionLoader:
+ return "SessionLoader";
+ break;
+ case PluginType_Themes:
+ return "Themes";
+ break;
+ default:
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"cat text not found: "+std::to_string(category));
+ return "Unknown";
+ break;
+ }
+}
+
+std::string PluginsManager::categoryToTranslation(const PluginType &category)
+{
+ if(pluginInformation==NULL)
+ {
+ pluginInformation=new PluginInformation();
+ connect(this, &PluginsManager::newLanguageLoaded, pluginInformation, &PluginInformation::retranslateInformation,Qt::QueuedConnection);
+ }
+ return pluginInformation->categoryToTranslation(category);
+}
+
+bool PluginsManager::isSamePlugin(const PluginsAvailable &pluginA,const PluginsAvailable &pluginB)
+{
+ /*if(pluginA.category!=pluginB.category)
+ return false;*/
+ //only this test should be suffisent
+ if(pluginA.path!=pluginB.path)
+ return false;
+ /*if(pluginA.name!=pluginB.name)
+ return false;
+ if(pluginA.writablePath!=pluginB.writablePath)
+ return false;
+ if(pluginA.categorySpecific!=pluginB.categorySpecific)
+ return false;
+ if(pluginA.version!=pluginB.version)
+ return false;
+ if(pluginA.informations!=pluginB.informations)
+ return false;*/
+ return true;
+}
+
+bool PluginsManager::loadPluginInformation(const std::string &path)
+{
+ PluginsAvailable tempPlugin;
+ tempPlugin.isAuth = false;
+ tempPlugin.path = path;
+ tempPlugin.category = PluginType_Unknow;
+ QDir pluginPath(QString::fromStdString(path));
+ if(pluginPath.cdUp() && pluginPath.cdUp() &&
+ !ResourcesManager::resourcesManager->getWritablePath().empty() &&
+ pluginPath==QDir(QString::fromStdString(ResourcesManager::resourcesManager->getWritablePath())))
+ tempPlugin.isWritable=true;
+ else
+ tempPlugin.isWritable=false;
+ QFile xmlMetaData(QString::fromStdString(path)+"informations.xml");
+ if(xmlMetaData.exists())
+ {
+ if(xmlMetaData.open(QIODevice::ReadOnly))
+ {
+ loadPluginXml(&tempPlugin,xmlMetaData.readAll());
+ xmlMetaData.close();
+ }
+ else
+ {
+ tempPlugin.errorString=tr("informations.xml is not accessible").toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"informations.xml is not accessible into the plugin: "+path);
+ }
+ }
+ else
+ {
+ tempPlugin.errorString=tr("informations.xml not found for the plugin").toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"informations.xml not found for the plugin: "+path);
+ }
+ editionSemList.acquire();
+ pluginsList.push_back(tempPlugin);
+ if(tempPlugin.errorString.empty())
+ pluginsListIndexed[tempPlugin.category].push_back(tempPlugin);
+ editionSemList.release();
+ if(tempPlugin.errorString.empty())
+ return true;
+ else
+ {
+ emit onePluginInErrorAdded(tempPlugin);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Error detected, the not loaded: "+tempPlugin.errorString+", for path: "+tempPlugin.path);
+ return false;
+ }
+}
+
+void PluginsManager::loadPluginXml(PluginsAvailable * thePlugin,const QByteArray &xml)
+{
+ QString errorStr;
+ int errorLine;
+ int errorColumn;
+ QDomDocument domDocument;
+ if (!domDocument.setContent(xml, false, &errorStr,&errorLine,&errorColumn))
+ {
+ thePlugin->errorString=tr("%1, parse error at line %2, column %3: %4").arg("informations.xml").arg(errorLine).arg(errorColumn).arg(errorStr).toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"informations.xml, Parse error at line "+std::to_string(errorLine)+", column "+std::to_string(errorColumn)+": "+errorStr.toStdString());
+ }
+ else
+ {
+ QDomElement root = domDocument.documentElement();
+ if (root.tagName() != QStringLiteral("package"))
+ {
+ thePlugin->errorString=tr("\"package\" root tag not found for the xml file").toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"\"package\" root balise not found for the xml file");
+ }
+ //load the variable
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"title",&(thePlugin->informations),&(thePlugin->errorString),true,true,true);
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"website",&(thePlugin->informations),&(thePlugin->errorString),false,true);
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"description",&(thePlugin->informations),&(thePlugin->errorString),true,true,true);
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"author",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"pubDate",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ {
+ loadBalise(root,"version",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ thePlugin->version=thePlugin->informations.back().back();
+ }
+ if(thePlugin->errorString.empty())
+ {
+ loadBalise(root,"category",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ {
+ std::string tempCat=thePlugin->informations.back().back();
+ if(tempCat=="Languages")
+ thePlugin->category=PluginType_Languages;
+ else if(tempCat=="CopyEngine")
+ thePlugin->category=PluginType_CopyEngine;
+ else if(tempCat=="Listener")
+ thePlugin->category=PluginType_Listener;
+ else if(tempCat=="PluginLoader")
+ thePlugin->category=PluginType_PluginLoader;
+ else if(tempCat=="SessionLoader")
+ thePlugin->category=PluginType_SessionLoader;
+ else if(tempCat=="Themes")
+ thePlugin->category=PluginType_Themes;
+ else
+ thePlugin->errorString="Unknow category: "+std::to_string((int)thePlugin->category);
+ if(thePlugin->errorString.empty())
+ {
+ if(thePlugin->category!=PluginType_Languages)
+ {
+ #ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+ loadBalise(root,"architecture",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ {
+ if(thePlugin->informations.back().back()!=ULTRACOPIER_PLATFORM_CODE)
+ thePlugin->errorString="Wrong platform code: "+thePlugin->informations.back().back();
+ }
+ #endif
+ }
+ }
+ }
+ }
+ if(thePlugin->errorString.empty())
+ {
+ loadBalise(root,"name",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ {
+ thePlugin->name=thePlugin->informations.back().back();
+ size_t index=0;
+ while(index<pluginsList.size())
+ {
+ size_t sub_index=0;
+ while(sub_index<pluginsList.at(index).informations.size())
+ {
+ if(pluginsList.at(index).informations.at(sub_index).front()=="name" &&
+ pluginsList.at(index).name==thePlugin->name &&
+ pluginsList.at(index).category==thePlugin->category)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Plugin duplicate found ("+std::to_string((int)thePlugin->category)+"/"+pluginsList.at(index).informations.at(sub_index).back()+"), already loaded, actual version skipped: "+thePlugin->version);
+ thePlugin->errorString=tr("Duplicated plugin found, already loaded!").toStdString();
+ break;
+ break;
+ }
+ sub_index++;
+ }
+ index++;
+ }
+ }
+ }
+ if(thePlugin->errorString.empty())
+ loadBalise(root,"dependencies",&(thePlugin->informations),&(thePlugin->errorString),true,false);
+ if(thePlugin->errorString.empty())
+ {
+ QDomElement child = root.firstChildElement("categorySpecific");
+ if(!child.isNull() && child.isElement())
+ thePlugin->categorySpecific=child;
+ }
+ }
+}
+
+/// \brief to load the multi-language balise
+void PluginsManager::loadBalise(const QDomElement &root,const std::string &name,std::vector<std::vector<std::string> > *informations,std::string *errorString,bool needHaveOneEntryMinimum,bool multiLanguage,bool englishNeedBeFound)
+{
+ int foundElement=0;
+ bool englishTextIsFoundForThisChild=false;
+ QDomElement child = root.firstChildElement(QString::fromStdString(name));
+ while(!child.isNull())
+ {
+ if(child.isElement())
+ {
+ std::vector<std::string> newInformations;
+ if(multiLanguage)
+ {
+ if(child.hasAttribute(QStringLiteral("xml:lang")))
+ {
+ if(child.attribute(QStringLiteral("xml:lang"))==QStringLiteral("en"))
+ englishTextIsFoundForThisChild=true;
+ foundElement++;
+ newInformations.push_back(child.tagName().toStdString());
+ newInformations.push_back(child.attribute(QStringLiteral("xml:lang")).toStdString());
+ newInformations.push_back(child.text().toStdString());
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Have not the attribute xml:lang: child.tagName(): "+child.tagName().toStdString()+", child.text(): "+child.text().toStdString());
+ }
+ else
+ {
+ foundElement++;
+ newInformations.push_back(child.tagName().toStdString());
+ newInformations.push_back(child.text().toStdString());
+ }
+ informations->push_back(newInformations);
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Is not Element: child.tagName(): "+child.tagName().toStdString());
+ child = child.nextSiblingElement(QString::fromStdString(name));
+ }
+ if(multiLanguage && englishTextIsFoundForThisChild==false && englishNeedBeFound)
+ {
+ informations->clear();
+ *errorString=tr("English text missing in the informations.xml for the tag: %1").arg(QString::fromStdString(name)).toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"English text missing into the informations.xml for the tag: "+name);
+ return;
+ }
+ if(needHaveOneEntryMinimum && foundElement==0)
+ {
+ informations->clear();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Tag not found: "+name);
+ *errorString=tr("Tag not found: %1").arg(QString::fromStdString(name)).toStdString();
+ }
+}
+
+/// \brief to load the get dom specific
+std::string PluginsManager::getDomSpecific(const QDomElement &root,const std::string &name,const std::vector<std::pair<std::string,std::string> > &listChildAttribute) const
+{
+ QDomElement child = root.firstChildElement(QString::fromStdString(name));
+ bool allIsFound;
+ while(!child.isNull())
+ {
+ if(child.isElement())
+ {
+ allIsFound=true;
+ size_t index=0;
+ while(index<listChildAttribute.size())
+ {
+ const std::pair<std::string,std::string> &entry=listChildAttribute.at(index);
+ if(child.attribute(QString::fromStdString(entry.first))!=QString::fromStdString(entry.second))
+ {
+ allIsFound=false;
+ break;
+ }
+ index++;
+ }
+ if(allIsFound)
+ return child.text().toStdString();
+ }
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Is not Element: child.tagName(): "+child.tagName().toStdString());
+ child = child.nextSiblingElement(QString::fromStdString(name));
+ }
+ return std::string();
+}
+
+/// \brief to load the get dom specific
+std::string PluginsManager::getDomSpecific(const QDomElement &root,const std::string &name) const
+{
+ QDomElement child = root.firstChildElement(QString::fromStdString(name));
+ while(!child.isNull())
+ {
+ if(child.isElement())
+ return child.text().toStdString();
+ else
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Is not Element: child.tagName(): "+child.tagName().toStdString());
+ child = child.nextSiblingElement(QString::fromStdString(name));
+ }
+ return std::string();
+}
+
+#ifndef ULTRACOPIER_PLUGIN_ALL_IN_ONE
+/// \brief check the dependencies
+uint32_t PluginsManager::checkDependencies()
+{
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ uint32_t errors=0;
+ unsigned int index=0;
+ bool depCheck;
+ while(index<pluginsList.size())
+ {
+ unsigned int sub_index=0;
+ while(sub_index<pluginsList.at(index).informations.size())
+ {
+ if(pluginsList.at(index).informations.at(sub_index).size()==2 && pluginsList.at(index).informations.at(sub_index).at(0)=="dependencies")
+ {
+ std::string dependencies = pluginsList.at(index).informations.at(sub_index).at(1);
+ dependencies=std::regex_replace(dependencies, regexp_to_clean_1,"&&");
+ dependencies=std::regex_replace(dependencies, regexp_to_clean_2,"");
+ dependencies=std::regex_replace(dependencies, regexp_to_clean_3,"&&");
+ dependencies=std::regex_replace(dependencies, regexp_to_clean_4,"");
+ dependencies=std::regex_replace(dependencies, regexp_to_clean_5,"");
+ std::sregex_token_iterator iter(dependencies.begin(), dependencies.end(), regexp_to_dep_1, -1), end;
+ for ( ; iter != end; ++iter)
+ {
+ std::string dependenciesToParse=trim(*iter);
+ if(dependenciesToParse.empty()) {
+ continue;
+ }
+ if(!std::regex_match(dependenciesToParse, regexp_to_dep_2))
+ {
+ pluginsList[index].informations.clear();
+ pluginsList[index].errorString=tr("Dependencies part is wrong").toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Dependencies part is wrong: "+dependenciesToParse);
+ emit onePluginInErrorAdded(pluginsList.at(index));
+ errors++;
+ break;
+ }
+ std::string partName=dependenciesToParse;
+ partName=std::regex_replace(partName, regexp_to_dep_3, "");
+ partName=std::regex_replace(partName, regexp_to_dep_4, "");
+ std::string partVersion=dependenciesToParse;
+ partVersion=std::regex_replace(partVersion, regexp_to_dep_3, "");
+ partVersion=std::regex_replace(partVersion, regexp_to_dep_5, "");
+ std::string partComp=dependenciesToParse;
+ partComp=std::regex_replace(partComp, regexp_to_dep_6, "");
+ //current version soft
+ std::string pluginVersion=getPluginVersion(partName);
+ depCheck=compareVersion(pluginVersion,partComp,partVersion);
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"dependencies to resolv, partName: "+partName+", partVersion: "+partVersion+", partComp: "+partComp+", pluginVersion: "+pluginVersion+", depCheck: "+std::to_string(depCheck));
+ if(!depCheck)
+ {
+ pluginsList[index].informations.clear();
+ pluginsList[index].errorString=tr("Dependencies %1 are not satisfied, for plugin: %2").arg(QString::fromStdString(dependenciesToParse)).arg(QString::fromStdString(pluginsList[index].path)).toStdString();
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"Dependencies "+dependenciesToParse+" are not satisfied, for plugin: "+pluginsList[index].path);
+ pluginsListIndexed.erase(pluginsListIndexed.find(pluginsList.at(index).category));
+ emit onePluginInErrorAdded(pluginsList.at(index));
+ errors++;
+ break;
+ }
+ }
+ }
+ sub_index++;
+ }
+ index++;
+ }
+ return errors;
+}
+#endif
+
+/// \brief get the version
+std::string PluginsManager::getPluginVersion(const std::string &pluginName) const
+{
+ #ifdef ULTRACOPIER_MODE_SUPERCOPIER
+ if(pluginName=="supercopier")
+ return ULTRACOPIER_VERSION;
+ #else
+ if(pluginName=="ultracopier")
+ return ULTRACOPIER_VERSION;
+ #endif
+ ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start");
+ unsigned int index=0;
+ while(index<pluginsList.size())
+ {
+ std::string version,internalName;
+ unsigned int sub_index=0;
+ while(sub_index<pluginsList.at(index).informations.size())
+ {
+ if(pluginsList.at(index).informations.at(sub_index).size()==2 && pluginsList.at(index).informations.at(sub_index).at(0)=="version")
+ version=pluginsList.at(index).informations.at(sub_index).at(1);
+ if(pluginsList.at(index).informations.at(sub_index).size()==2 && pluginsList.at(index).informations.at(sub_index).at(0)=="internalName")
+ internalName=pluginsList.at(index).informations.at(sub_index).at(1);
+ sub_index++;
+ }
+ if(internalName==pluginName)
+ return version;
+ index++;
+ }
+ return "";
+}
+
+/// \brief To compare version, \return true is case of error
+bool PluginsManager::compareVersion(const std::string &versionA,const std::string &sign,const std::string &versionB)
+{
+ std::vector<std::string> versionANumber=stringsplit(versionA,'.');
+ std::vector<std::string> versionBNumber=stringsplit(versionB,'.');
+ unsigned int index=0;
+ unsigned int defaultReturnValue=true;
+ if(sign=="<")
+ defaultReturnValue=false;
+ if(sign==">")
+ defaultReturnValue=false;
+ bool ok;
+ while(index<versionANumber.size() && index<versionBNumber.size())
+ {
+ unsigned int reaNumberA=stringtouint8(versionANumber.at(index),&ok);
+ if(!ok)
+ return true;
+ unsigned int reaNumberB=stringtouint8(versionBNumber.at(index),&ok);
+ if(!ok)
+ return true;
+ if(sign=="=" && reaNumberA!=reaNumberB)
+ return false;
+ if(sign=="<")
+ {
+ if(reaNumberA>reaNumberB)
+ return false;
+ if(reaNumberA<reaNumberB)
+ return true;
+ }
+ if(sign==">")
+ {
+ if(reaNumberA<reaNumberB)
+ return false;
+ if(reaNumberA>reaNumberB)
+ return true;
+ }
+ if(sign=="<=")
+ {
+ if(reaNumberA>reaNumberB)
+ return false;
+ if(reaNumberA<reaNumberB)
+ return true;
+ }
+ if(sign==">=")
+ {
+ if(reaNumberA<reaNumberB)
+ return false;
+ if(reaNumberA>reaNumberB)
+ return true;