Compare commits

..

11 Commits
1.9.2 ... 2.2

Author SHA1 Message Date
d681d65d9c version 2.2 2023-02-12 19:11:26 +01:00
65896b087f -corrected bug in localization 2023-02-12 19:11:06 +01:00
3e0bd57029 version 2.1.3 2023-02-12 17:56:12 +01:00
65c0318449 version 2.1.2 2023-02-12 17:50:13 +01:00
a2d9f93ace added icon in system tray 2023-02-12 00:37:50 +01:00
4ead825bad version 2.1.1 2023-02-11 13:42:46 +01:00
f73174216a -corrected bug
- added  warning when selecting a file which is already in download
  queue
2023-02-11 13:40:46 +01:00
0b60543ff3 version 2.1 2023-02-11 01:15:41 +01:00
d52a0663e5 - added verification of already downloaded files 2023-02-11 01:14:14 +01:00
a3933ee1c9 version 2.0 2023-02-10 23:28:52 +01:00
9671a5cea8 completely migrate to QT and some bugs corrected 2023-02-10 23:27:44 +01:00
11 changed files with 416 additions and 146 deletions

View File

@ -6,7 +6,7 @@ Comment=Client for rsync servers
Comment[fr]=Client pour serveur rsync Comment[fr]=Client pour serveur rsync
Version=1.0 Version=1.0
Exec=RsyncUI Exec=RsyncUI
Icon= Icon=/usr/share/icons/RsyncUI.png
Type=Application Type=Application
Terminal=false Terminal=false
StartupNotify=true StartupNotify=true

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.14.2, 2023-02-10T14:36:52. --> <!-- Written by QtCreator 4.14.2, 2023-02-12T17:55:57. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -141,7 +141,7 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">true</value> <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
@ -183,7 +183,7 @@
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value> <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value> <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">true</value> <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/> <valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap> </valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1"> <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">

View File

@ -2,7 +2,7 @@
Name: rsyncui Name: rsyncui
Summary: Client for rsync server Summary: Client for rsync server
Version: 1.9.2 Version: 2.2
Release: %mkrel 1 Release: %mkrel 1
License: GPLv3 License: GPLv3
Group: Networking/Remote access Group: Networking/Remote access

View File

@ -74,121 +74,136 @@
<translation>Fenêtre principale</translation> <translation>Fenêtre principale</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="83"/> <location filename="mainwindow.ui" line="86"/>
<source>Server</source> <source>Server</source>
<oldsource>Serveur</oldsource> <oldsource>Serveur</oldsource>
<translation>Serveur</translation> <translation>Serveur</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="105"/> <location filename="mainwindow.ui" line="108"/>
<source>Enter server&apos;s URL</source> <source>Enter server&apos;s URL</source>
<translation>Entrez l&apos;adresse du serveur</translation> <translation>Entrez l&apos;adresse du serveur</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="121"/> <location filename="mainwindow.ui" line="124"/>
<source>Port</source> <source>Port</source>
<translation>Port</translation> <translation>Port</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="149"/> <location filename="mainwindow.ui" line="152"/>
<source>Enter rsync port on server</source> <source>Enter rsync port on server</source>
<translation>Entrez le port du serveur rsync</translation> <translation>Entrez le port du serveur rsync</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="186"/> <location filename="mainwindow.ui" line="189"/>
<source>Press button to connect to rsync server</source> <source>Press button to connect to rsync server</source>
<extracomment>Connect to server</extracomment> <extracomment>Connect to server</extracomment>
<translation>Cliquez pour se connecter au serveur rsync</translation> <translation>Cliquez pour se connecter au serveur rsync</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="192"/> <location filename="mainwindow.ui" line="195"/>
<source>Connection</source> <source>Connection</source>
<translation>Connexion</translation> <translation>Connexion</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="195"/> <location filename="mainwindow.ui" line="198"/>
<source>Return</source> <source>Return</source>
<translation>Retour</translation> <translation>Retour</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="221"/> <location filename="mainwindow.ui" line="224"/>
<source>Click to view the list of files of this folder</source> <source>Click to view the list of files of this folder</source>
<translation>Cliquez pour afficher la liste des documents</translation> <translation>Cliquez pour afficher la liste des documents</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="256"/> <location filename="mainwindow.ui" line="259"/>
<source>Click to add to download queue</source> <source>Click to add to download queue</source>
<translation>Cliquez pour ajouter à la file de téléchargement</translation> <translation>Cliquez pour ajouter à la file de téléchargement</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="334"/> <location filename="mainwindow.ui" line="337"/>
<source>Click on file to stop downloading</source> <source>Click on file to stop downloading</source>
<translation>Cliquez sur le document pour arrêter le téléchargement et l&apos;enlever de la file</translation> <translation>Cliquez sur le document pour arrêter le téléchargement et l&apos;enlever de la file</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="357"/> <location filename="mainwindow.ui" line="360"/>
<source>%p%</source> <source>%p%</source>
<extracomment>Downloading</extracomment> <extracomment>Downloading</extracomment>
<translation>Téléchargement</translation> <translation>Téléchargement</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="368"/> <location filename="mainwindow.ui" line="371"/>
<source>toolBar</source> <source>toolBar</source>
<translation>Barre d&apos;outils</translation> <translation>Barre d&apos;outils</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="440"/> <location filename="mainwindow.ui" line="444"/>
<source>Download</source> <source>Download</source>
<translation>Télécharger</translation> <translation>Télécharger</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="443"/> <location filename="mainwindow.ui" line="447"/>
<source>Click on menu button to download the entire folder</source> <source>Click on menu button to download the entire folder</source>
<translation>Cliquer sur le bouton droit de la souris pour télécharger le dossier entier</translation> <translation>Cliquer sur le bouton droit de la souris pour télécharger le dossier entier</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="405"/> <location filename="mainwindow.ui" line="455"/>
<location filename="mainwindow.ui" line="408"/> <source>Exit</source>
<translation>Quitter</translation>
</message>
<message>
<location filename="mainwindow.ui" line="458"/>
<source>Terminate the program</source>
<translation>Terminer le programme</translation>
</message>
<message>
<location filename="mainwindow.ui" line="461"/>
<source>Ctrl+Q</source>
<translation>Ctrl+Q</translation>
</message>
<message>
<location filename="mainwindow.ui" line="409"/>
<location filename="mainwindow.ui" line="412"/>
<source>Change save folder</source> <source>Change save folder</source>
<translation>Changer le dossier de destination</translation> <translation>Changer le dossier de destination</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="417"/> <location filename="mainwindow.ui" line="421"/>
<source>About</source> <source>About</source>
<translation>À propos</translation> <translation>À propos</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="426"/> <location filename="mainwindow.ui" line="430"/>
<source>About Qt</source> <source>About Qt</source>
<translation>À propos de Qt</translation> <translation>À propos de Qt</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.ui" line="435"/> <location filename="mainwindow.ui" line="439"/>
<source>Settings</source> <source>Settings</source>
<translation>Paramètres</translation> <translation>Paramètres</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="86"/> <location filename="mainwindow.cpp" line="90"/>
<source>KB</source> <source>KB</source>
<translation>Ko</translation> <translation>Ko</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="86"/> <location filename="mainwindow.cpp" line="90"/>
<source>MB</source> <source>MB</source>
<translation>Mo</translation> <translation>Mo</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="86"/> <location filename="mainwindow.cpp" line="90"/>
<source>GB</source> <source>GB</source>
<translation>Go</translation> <translation>Go</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="86"/> <location filename="mainwindow.cpp" line="90"/>
<source>TB</source> <source>TB</source>
<translation>To</translation> <translation>To</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="86"/> <location filename="mainwindow.cpp" line="90"/>
<source>PB</source> <source>PB</source>
<translation>Po</translation> <translation>Po</translation>
</message> </message>
@ -217,125 +232,160 @@ Cliquez sur un fichier pour l&apos;ajouter dans la file de téléchargement</tra
<translation>Type</translation> <translation>Type</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="92"/> <location filename="mainwindow.cpp" line="97"/>
<source>A list of interrupted downloads exists, do you want to continue downloading ? if not the list will be cleared</source> <source>A list of interrupted downloads exists, do you want to continue downloading ? if not the list will be cleared</source>
<translation>Une liste de téléchargement existe, voulez-vous utiliser cette liste ? si non, elle sera effacée</translation> <translation>Une liste de téléchargement existe, voulez-vous utiliser cette liste ? si non, elle sera effacée</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="393"/> <location filename="mainwindow.cpp" line="125"/>
<source>&amp;Quit</source>
<translation>&amp;Quitter</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="182"/>
<source>Clicking Save button, You can save the list of downloads
</source>
<translation>Vous pouvez enregistrer la liste des téléchargements en cliquant sur &quot;enregister&quot;
</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="187"/>
<source>Exiting will stop downloading, and will clear the download queue.
Do you want to exit ?</source>
<translation>Si vous sortez, les téléchargements seront arrêter.
Voulez-vous vraiment sortir ?</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="215"/>
<source>The program will keep running in the system tray. To terminate the program, choose &lt;b&gt;Quit&lt;/b&gt; in the context menu of the system tray entry.</source>
<translation>Le programme continue dans la boîte à miniatures. Pour quitter le programme cliquez sur l&apos;icône &lt;b&gt;Quitter&lt;/b&gt; ou dans les menu contextuel.</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="500"/>
<source>server does not exists</source> <source>server does not exists</source>
<translation>Le serveur n&apos;existe pas</translation> <translation>Le serveur n&apos;existe pas</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="421"/> <location filename="mainwindow.cpp" line="527"/>
<location filename="mainwindow.cpp" line="441"/> <location filename="mainwindow.cpp" line="547"/>
<source>Dir</source> <source>Dir</source>
<translation>dossier</translation> <translation>dossier</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="424"/> <location filename="mainwindow.cpp" line="531"/>
<location filename="mainwindow.cpp" line="487"/> <location filename="mainwindow.cpp" line="615"/>
<source>File</source> <source>File</source>
<translation>Doc</translation> <translation>Doc</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="561"/> <location filename="mainwindow.cpp" line="624"/>
<source>File is already downloaded. Do you want to reload it ? The old file will be deleted</source>
<translation>Le document est déjà téléchargé. Voulez-vous le télécharger à nouveau ? L&apos;ancien fichier sera effacé</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="659"/>
<source>File is already downloading</source>
<translation>Le document est déjà en téléchargement</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="682"/>
<source>Starting downloading
</source>
<translation>Démarrage du téléchargement
</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="697"/>
<source>finished</source>
<translation>Terminé</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="705"/>
<source>Rsync process crashed</source> <source>Rsync process crashed</source>
<translation>Le processus rsync à planté</translation> <translation>Le processus rsync à planté</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="699"/> <location filename="mainwindow.cpp" line="717"/>
<source>stopped by user</source>
<translation>stoppé par l&apos;utilisateur</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="721"/>
<source>Download </source>
<translation>Téléchargement </translation>
</message>
<message>
<location filename="mainwindow.cpp" line="867"/>
<source>Version</source> <source>Version</source>
<translation>Version</translation> <translation>Version</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="700"/> <location filename="mainwindow.cpp" line="868"/>
<source>Licence</source> <source>Licence</source>
<translation>License</translation> <translation>License</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="701"/> <location filename="mainwindow.cpp" line="869"/>
<source>Author</source> <source>Author</source>
<translation>Auteur</translation> <translation>Auteur</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="702"/> <location filename="mainwindow.cpp" line="870"/>
<source>EMail</source> <source>EMail</source>
<translation>Courriel</translation> <translation>Courriel</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="703"/> <location filename="mainwindow.cpp" line="871"/>
<source>Source code</source> <source>Source code</source>
<translation>Code source</translation> <translation>Code source</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="725"/> <location filename="mainwindow.cpp" line="894"/>
<source>Since the save path is linked to service, you need to select a service before you can select a folder</source> <source>Since the save path is linked to service, you need to select a service before you can select a folder</source>
<translation>Vous devez sélectionnez un service pour pouvoir sélectionnez un dossier par défaut</translation> <translation>Vous devez sélectionnez un service pour pouvoir sélectionnez un dossier par défaut</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.cpp" line="728"/> <location filename="mainwindow.cpp" line="899"/>
<source>Choose folder where to save file</source> <source>Choose folder where to save file</source>
<translation>Choisissez un dossier enregistrer le document</translation> <translation>Choisissez un dossier enregistrer le document</translation>
</message> </message>
<message> <message>
<source>Choose directory to save file</source> <location filename="mainwindow.cpp" line="785"/>
<translation type="vanished">Choisissez le dossier enregistrer</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="620"/>
<source>Do you want to stop downloading and delete this file from download queue ?</source> <source>Do you want to stop downloading and delete this file from download queue ?</source>
<translation>Voulez-vous arrêter le téléchargement et enlever ce fichier de la file de téléchargement ?</translation> <translation>Voulez-vous arrêter le téléchargement et enlever ce fichier de la file de téléchargement ?</translation>
</message> </message>
<message> <message>
<source>A list of interrupted downloads exists, do you want to continue downloading ? or you can delete the list</source> <location filename="mainwindow.cpp" line="799"/>
<translation type="vanished">Voulez-vous reprendre les téléchargements interrompus la fois précédente? ou vous pouvez supprimer la liste</translation>
</message>
<message>
<source>Remove</source>
<translation type="vanished">Supprimer</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="135"/>
<source>Exiting will stop downloading, and will clear the download queue.
You can save the list of downloads
Do you want to exit ?</source>
<translatorcomment>i</translatorcomment>
<translation>Si vous sortez, les téléchargements seront arrêter, mais vous pouvez enregistrer la liste pour la prochaine fois.
Voulez-vous vraiment sortir ?</translation>
</message>
<message>
<location filename="mainwindow.cpp" line="632"/>
<source>Do you want to delete this file from download queue ?</source> <source>Do you want to delete this file from download queue ?</source>
<translation>Voulez-vous enlever ce fichier de la file de téléchargement ?</translation> <translation>Voulez-vous enlever ce fichier de la file de téléchargement ?</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="118"/> <location filename="mainwindow.h" line="122"/>
<source>The process failed to start. Either the invoked program is missing, or you may have insufficient permissions or resources to invoke the program.</source> <source>The process failed to start. Either the invoked program is missing, or you may have insufficient permissions or resources to invoke the program.</source>
<translation>Le processus échoué, soit le programme est manquant, soit vous n&apos;avez pas l&apos;autorisation de l&apos;exécuter.</translation> <translation>Le processus échoué, soit le programme est manquant, soit vous n&apos;avez pas l&apos;autorisation de l&apos;exécuter.</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="119"/> <location filename="mainwindow.h" line="123"/>
<source>The process crashed some time after starting successfully.</source> <source>The process crashed some time after starting successfully.</source>
<translation>Le processus à planté après avoir démarré avec succès.</translation> <translation>Le processus à planté après avoir démarré avec succès.</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="120"/> <location filename="mainwindow.h" line="124"/>
<source>The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.</source> <source>The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.</source>
<translation>La fonction waitFor...() a dépassé la limite de temps, you pouvez essayer de la relancer.</translation> <translation>La fonction waitFor...() a dépassé la limite de temps, you pouvez essayer de la relancer.</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="121"/> <location filename="mainwindow.h" line="125"/>
<source>An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.</source> <source>An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.</source>
<translation>Une erreur est survenue lors de l&apos;envoi des données vers le processus. Le processus est peut être arrté ou il a fermé son canal d&apos;entrée.</translation> <translation>Une erreur est survenue lors de l&apos;envoi des données vers le processus. Le processus est peut être arrté ou il a fermé son canal d&apos;entrée.</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="122"/> <location filename="mainwindow.h" line="126"/>
<source>An error occurred when attempting to read from the process. For example, the process may not be running.</source> <source>An error occurred when attempting to read from the process. For example, the process may not be running.</source>
<translation>Une erreur est survenue lors de la lecturee de données, le processus est probablement arrêté.</translation> <translation>Une erreur est survenue lors de la lecturee de données, le processus est probablement arrêté.</translation>
</message> </message>
<message> <message>
<location filename="mainwindow.h" line="123"/> <location filename="mainwindow.h" line="127"/>
<source>An unknown error occurred. This is the default return value of error().</source> <source>An unknown error occurred. This is the default return value of error().</source>
<translation>Une erreur inconnue est survenue. C&apos;est la valeur de retour par défaut de error().</translation> <translation>Une erreur inconnue est survenue. C&apos;est la valeur de retour par défaut de error().</translation>
</message> </message>

View File

@ -96,6 +96,7 @@ void MainWindow::readRsyncOutput()
); );
}*/ }*/
// process raise error
void MainWindow::downloadProcessStderr() void MainWindow::downloadProcessStderr()
{ {
QByteArray errorLine; QByteArray errorLine;

View File

@ -9,10 +9,14 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationName("RsyncUI"); QCoreApplication::setOrganizationName("RsyncUI");
QCoreApplication::setApplicationName("RsyncUI"); QCoreApplication::setApplicationName("RsyncUI");
// Initialization of localization // Initialization of localization
QLocale localeName = QLocale::system(); QLocale localeName = QLocale::system();
QString localeFile = "/usr/share/locale/" + localeName.name() + "/LC_MESSAGES/RsyncUI_" + localeName.name() + ".qm"; QString localeDir = "/usr/share/locale/" + localeName.name() + "/LC_MESSAGES/"; //RsyncUI_" + localeName.name() + ".qm";
if (myappTranslator.load(localeFile)) QString localeFilename = QCoreApplication::applicationName() + "_" + localeName.name();
QLocale locale = QLocale();
if (myappTranslator.load(localeFilename, localeDir))
{ {
a.installTranslator(&myappTranslator); a.installTranslator(&myappTranslator);
} }

View File

@ -40,10 +40,10 @@ MainWindow::MainWindow(QWidget *parent)
QCoreApplication::setOrganizationName("RsyncUI"); QCoreApplication::setOrganizationName("RsyncUI");
QCoreApplication::setApplicationName("RsyncUI"); QCoreApplication::setApplicationName("RsyncUI");
// context menu for treewidget // context menu for treewidget (list of files)
ui->treeWidget->addAction(ui->actionDownload); ui->treeWidget->addAction(ui->actionDownload);
// init shortcut // init configuration window
config.setupUi(&Configuration); config.setupUi(&Configuration);
// init of About // init of About
@ -57,12 +57,14 @@ MainWindow::MainWindow(QWidget *parent)
connect(config.comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::on_comboBox_currentIndexChanged); connect(config.comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::on_comboBox_currentIndexChanged);
// init of widgets // init of widgets
ui->ktreewidgetsearchline->setTreeWidget(ui->treeWidget); ui->ktreewidgetsearchline->setTreeWidget(ui->treeWidget); // attach search widget to treewidget
ui->ktreewidgetsearchline->setCaseSensitivity(Qt::CaseInsensitive); ui->ktreewidgetsearchline->setCaseSensitivity(Qt::CaseInsensitive); // and set it case insensitive
ui->treeWidget->setHeaderLabels({tr("Path"), tr("Type"), tr("Size")} ); ui->treeWidget->setHeaderLabels({tr("Path"), tr("Type"), tr("Size")} ); // set header of columns of tree widget
// if last server exists in settings
if (this->settings.contains("connexion/lastServer")) if (this->settings.contains("connexion/lastServer"))
{ {
// set window to precedent server/port configuration
ui->portEdit->setText(this->settings.value("connexion/port").toString()); ui->portEdit->setText(this->settings.value("connexion/port").toString());
ui->khistorycombobox->setCurrentText(this->settings.value("connexion/lastServer").toString()); ui->khistorycombobox->setCurrentText(this->settings.value("connexion/lastServer").toString());
}else }else
@ -71,7 +73,7 @@ MainWindow::MainWindow(QWidget *parent)
ui->khistorycombobox->clear(); ui->khistorycombobox->clear();
} }
// setting arrowcursor for treeWidget, listWidget and listDownload // setting arrowcursor for treeWidget, listWidget and listDownload to arrow
ui->treeWidget->setCursor(Qt::ArrowCursor); ui->treeWidget->setCursor(Qt::ArrowCursor);
ui->listWidget->setCursor(Qt::ArrowCursor); ui->listWidget->setCursor(Qt::ArrowCursor);
ui->listDownload->setCursor(Qt::ArrowCursor); ui->listDownload->setCursor(Qt::ArrowCursor);
@ -82,41 +84,90 @@ MainWindow::MainWindow(QWidget *parent)
loadSettings(); loadSettings();
//setting configuration window //setting configuration window
config.comboBox->setCurrentIndex(ui->toolBar->toolButtonStyle()); config.comboBox->setCurrentIndex(ui->toolBar->toolButtonStyle()); // setting combobox to saved settings
//setting unit of bandwidth limit
config.UnitCombobox->addItems({tr("KB"), tr("MB"), tr("GB"), tr("TB"), tr("PB")}); config.UnitCombobox->addItems({tr("KB"), tr("MB"), tr("GB"), tr("TB"), tr("PB")});
//if exists list of donwloads in saved settings
if (this->settings.value("Downloads/rows").toInt() != 0) if (this->settings.value("Downloads/rows").toInt() != 0)
{ {
//this->settings.endArray(); // asking if we load the list and continue downloading
msgBox.setWindowTitle("RsyncUI"); msgBox.setWindowTitle("RsyncUI");
msgBox.setInformativeText(tr("A list of interrupted downloads exists, do you want to continue downloading ? if not the list will be cleared" )); msgBox.setInformativeText(tr("A list of interrupted downloads exists, do you want to continue downloading ? if not the list will be cleared" ));
//QPushButton *remove = msgBox.addButton(tr("Remove"), QMessageBox::ActionRole);
QPushButton *yes = msgBox.addButton(QMessageBox::Yes); QPushButton *yes = msgBox.addButton(QMessageBox::Yes);
msgBox.addButton(QMessageBox::No); msgBox.addButton(QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setDefaultButton(QMessageBox::Yes);
msgBox.exec(); msgBox.exec();
reply = msgBox.clickedButton(); reply = msgBox.clickedButton();
// if response is yes then loading list
if(reply == yes) if(reply == yes)
{ {
loadDownloadList(); loadDownloadList();
} }
} }
// load list of services
populateList(); populateList();
initSystemTrayIcon();
}
void MainWindow::initSystemTrayIcon()
{
QMenu *trayIconMenu;
QAction * quitAction;
this->trayIcon = new QSystemTrayIcon;
this->trayIcon->setIcon(this->windowIcon());
quitAction = new QAction(tr("&Quit"), this);
connect(quitAction, &QAction::triggered, this, &MainWindow::quitApp);
trayIconMenu = new QMenu(this);
trayIconMenu->addAction(quitAction);
trayIcon->setContextMenu(trayIconMenu);
connect(this->trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(on_trayIcon_clicked(QSystemTrayIcon::ActivationReason)));
this->trayIcon->show();
}
void MainWindow::on_trayIcon_clicked(QSystemTrayIcon::ActivationReason reason)
{
if (reason == QSystemTrayIcon::Trigger)
{
if (this->isHidden())
{
this->show();
}else
{
this->hide();
}
}
}
void MainWindow::hideWindow()
{
this->hide();
}
void MainWindow::showWindow()
{
this->show();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui; delete ui;
QCoreApplication::quit();
} }
// Closing window has been clicked void MainWindow::quitApp()
void MainWindow::closeEvent (QCloseEvent *event)
{ {
QMessageBox::StandardButton reply; QMessageBox::StandardButton reply;
QMessageBox::StandardButtons param; QMessageBox::StandardButtons param;
QString displayText;
// saving settings // saving settings
saveSettings(); saveSettings();
@ -128,19 +179,16 @@ void MainWindow::closeEvent (QCloseEvent *event)
if (config.autosaveCheckbox->checkState() != Qt::Checked) if (config.autosaveCheckbox->checkState() != Qt::Checked)
{ {
param |= QMessageBox::Save; param |= QMessageBox::Save;
displayText = tr("Clicking Save button, You can save the list of downloads\n");
} }
reply = QMessageBox::question( reply = QMessageBox::question(
this, this,
"RsyncUI", "RsyncUI",
tr("Exiting will stop downloading, and will clear the download queue.\nYou can save the list of downloads\nDo you want to exit ?"), tr("Exiting will stop downloading, and will clear the download queue.\nDo you want to exit ?") + displayText,
param, param,
QMessageBox::No); QMessageBox::No);
if (reply == QMessageBox::No)
{ if(reply == QMessageBox::Yes)
// continuing
event->ignore();
return;
}else if(reply == QMessageBox::Yes)
{ {
// emission of signal to downloading thread and stopping // emission of signal to downloading thread and stopping
emit (stopDownloading(this->downloading.process)); emit (stopDownloading(this->downloading.process));
@ -149,13 +197,49 @@ void MainWindow::closeEvent (QCloseEvent *event)
saveDownloadList(); saveDownloadList();
} }
} }
event->accept(); //delete ui;
QCoreApplication::quit();
}
// Close window has been clicked
void MainWindow::closeEvent (QCloseEvent *event)
{
QMessageBox msgBox;
QCheckBox *cb = new QCheckBox("Don't show this again ?");
if (!event->spontaneous() || !isVisible())
return;
if (trayIcon->isVisible() and this->settings.value("CloseCheckbox").toBool() == false)
{
msgBox.setWindowTitle("RsyncUI");
msgBox.setInformativeText(tr("The program will keep running in the "
"system tray. To terminate the program, "
"choose <b>Quit</b> in the context menu "
"of the system tray entry."));
msgBox.addButton(QMessageBox::Ok);
//msgBox.addButton(QMessageBox::No);
// msgBox.setDefaultButton(QMessageBox::Yes);
msgBox.setCheckBox(cb);
msgBox.exec();
msgBox.clickedButton();
// if response is yes then loading list
if (cb->isChecked())
{
this->settings.setValue("CloseCheckbox", true);
}
hide();
//event->accept();
event->ignore();
}
} }
// Populate treeview with list of files // Populate treeview with list of files
void MainWindow::populateTree(QTreeWidgetItem * parent) void MainWindow::populateTree(QTreeWidgetItem * parent)
{ {
stringstream ss;
QString path; QString path;
// Clear treewidget // Clear treewidget
@ -165,6 +249,7 @@ void MainWindow::populateTree(QTreeWidgetItem * parent)
// setting cursor to "Wait" // setting cursor to "Wait"
QGuiApplication::setOverrideCursor(Qt::WaitCursor); QGuiApplication::setOverrideCursor(Qt::WaitCursor);
// validating server's address
if (validateServer(this->connexion.server)) if (validateServer(this->connexion.server))
{ {
// server is validated // server is validated
@ -179,8 +264,6 @@ void MainWindow::populateTree(QTreeWidgetItem * parent)
// Populate Listview with list of services // Populate Listview with list of services
void MainWindow::populateList() void MainWindow::populateList()
{ {
//stringstream ss;
QString str;
QString server; QString server;
int port; int port;
@ -190,9 +273,11 @@ void MainWindow::populateList()
{ {
// clearing listwidget // clearing listwidget
ui->listWidget->clear(); ui->listWidget->clear();
this->connexion.server = server; this->connexion.server = server;
this->connexion.port = port; this->connexion.port = port;
// setting cursor to "Wait"
QGuiApplication::setOverrideCursor(Qt::WaitCursor); QGuiApplication::setOverrideCursor(Qt::WaitCursor);
// verify if server is in history // verify if server is in history
@ -203,6 +288,8 @@ void MainWindow::populateList()
port = this->settings.value(server).toUInt(); port = this->settings.value(server).toUInt();
ui->portEdit->setText(QString::number(port)); ui->portEdit->setText(QString::number(port));
this->connexion.port = port; this->connexion.port = port;
//display list of services
listServices(); listServices();
}else }else
{ {
@ -211,6 +298,7 @@ void MainWindow::populateList()
if (validateServer(server)) if (validateServer(server))
{ {
cout << server.toStdString() << endl; cout << server.toStdString() << endl;
// storing serverURL and port in settings // storing serverURL and port in settings
this->settings.setValue(server, port); this->settings.setValue(server, port);
this->settings.sync(); this->settings.sync();
@ -219,14 +307,13 @@ void MainWindow::populateList()
// storing in history of combobox // storing in history of combobox
ui->khistorycombobox->addToHistory(server); ui->khistorycombobox->addToHistory(server);
// "waiting" cursor
// load and display rsync services of the rsync server // load and display rsync services of the rsync server
listServices(); listServices();
} }
} }
} }
this->settings.endGroup(); this->settings.endGroup();
QGuiApplication::restoreOverrideCursor(); //setOverrideCursor(Qt::ArrowCursor); QGuiApplication::restoreOverrideCursor(); //setting cursor to default
} }
} }
@ -247,26 +334,32 @@ void MainWindow::listServices()
myProcess = new QProcess(this); myProcess = new QProcess(this);
myProcess->start(cmd, param); myProcess->start(cmd, param);
// waiting for response of the server with a timeout of 10 seconds
while(myProcess->waitForReadyRead(10000)) while(myProcess->waitForReadyRead(10000))
{ {
while(!flag) while(!flag)
{ {
line = QString::fromUtf8(myProcess->readLine()); line = QString::fromUtf8(myProcess->readLine());
// line empty then buffer is empty so returning to wait new datas
if (line.isEmpty()) if (line.isEmpty())
{ {
flag = true; flag = true;
break; break;
} }
// extracting name and comment of the service
v = line.split("\t"); v = line.split("\t");
v[0].replace(" ", ""); v[0].replace(" ", "");
v[1].replace("\n", ""); v[1].replace("\n", "");
service = v[0] + "\n\t" + v[1]; service = v[0] + "\n\t" + v[1];
// adding to list of services
ui->listWidget->addItem(service); ui->listWidget->addItem(service);
} }
// buffer empty go to waiting new datas
flag =false; flag =false;
} }
// verifying error code
testRsyncReturn(myProcess); testRsyncReturn(myProcess);
} }
@ -276,11 +369,8 @@ void MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
QString cmd; QString cmd;
QStringList param; QStringList param;
QString line; QString line;
QString errorRsync;
QString size; QString size;
QString filename; QString filename;
QString dir;
QTreeWidgetItem * item;
QProcess * myProcess; QProcess * myProcess;
bool isDir = false; bool isDir = false;
bool flag = false; bool flag = false;
@ -291,16 +381,19 @@ void MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
myProcess = new QProcess(this); myProcess = new QProcess(this);
myProcess->start(cmd, param); myProcess->start(cmd, param);
// waiting for responsiteme of the server with a timeout of 10 seconds
while(myProcess->waitForReadyRead(100000)) while(myProcess->waitForReadyRead(100000))
{ {
while (!flag) while (!flag)
{ {
line = QString::fromUtf8(myProcess->readLine()); line = QString::fromUtf8(myProcess->readLine());
// line empty then buffer is empty so returning to wait new datas
if (line.isEmpty()) if (line.isEmpty())
{ {
flag = true; flag = true;
break; break;
} }
// extracting name, size and is dir/file
line = line.simplified(); line = line.simplified();
size = line.section(" ", 1, 1); size = line.section(" ", 1, 1);
filename = line.section(" ", 4); filename = line.section(" ", 4);
@ -315,16 +408,19 @@ void MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
} }
if (parent != NULL) if (parent != NULL)
{ {
item = addTreeChild(parent, filename, size, isDir); //adding item to tree
addTreeChild(parent, filename, size, isDir);
}else }else
{ {
item = addTreeRoot(filename, size, isDir); //adding item to tree (as directory)
addTreeRoot(filename, size, isDir);
} }
} }
} }
flag = false;
}
flag = false;
}
// buffer empty go to waiting new datas
testRsyncReturn(myProcess); testRsyncReturn(myProcess);
} }
@ -333,7 +429,6 @@ bool MainWindow::isIpAddress(QString server)
{ {
QStringList r; QStringList r;
int elementN; int elementN;
QString qr;
bool ok; bool ok;
r = server.split('.'); r = server.split('.');
@ -360,9 +455,9 @@ bool MainWindow::validateServer(QString server)
QString cmd; QString cmd;
QStringList param; QStringList param;
QString line; QString line;
QString errorDig;
QProcess * myProcess; QProcess * myProcess;
bool flag = false; bool flag = false;
bool bflag = false;
cmd = "dig"; cmd = "dig";
param << server; param << server;
@ -370,23 +465,35 @@ bool MainWindow::validateServer(QString server)
myProcess = new QProcess(this); myProcess = new QProcess(this);
myProcess->start(cmd, param); myProcess->start(cmd, param);
// maiking a dig on the server's address
while(myProcess->waitForReadyRead()) while(myProcess->waitForReadyRead())
{
while (!bflag)
{ {
line = QString::fromUtf8(myProcess->readAllStandardOutput()); line = QString::fromUtf8(myProcess->readAllStandardOutput());
if (line.indexOf(";; ANSWER SECTION:") != -1) // line empty then buffer is empty so returning to wait new datas
if (line.isEmpty())
{
bflag = true;
break;
}else if (line.indexOf(";; ANSWER SECTION:") != -1)
{ {
flag = true; flag = true;
} }
} }
bflag = false;
}
//testRsyncReturn(myProcess); //testRsyncReturn(myProcess);
if ( flag == false) if ( flag == false)
{ {
//server's address is not valid testing if ip address is valid
flag = isIpAddress(server); flag = isIpAddress(server);
} }
if ( flag == false) if ( flag == false)
{ {
// server-s address not valid
QMessageBox::warning( QMessageBox::warning(
this, this,
"RsyncUI", "RsyncUI",
@ -412,15 +519,15 @@ void MainWindow::on_connectButton_clicked()
// add a dir in treeview // add a dir in treeview
QTreeWidgetItem * MainWindow::addTreeRoot(QString name, QString fileSize, bool isDir) QTreeWidgetItem * MainWindow::addTreeRoot(QString name, QString fileSize, bool isDir)
{ {
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui->treeWidget); QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui->treeWidget);
// QTreeWidgetItem::setText(int column, const QString & text)
if (isDir == true) if (isDir == true)
{ {
// item is a dir
treeItem->setText(1, tr("Dir")); treeItem->setText(1, tr("Dir"));
}else }else
{ {
// item is a file
treeItem->setText(1,tr("File")); treeItem->setText(1,tr("File"));
} }
treeItem->setText(0, name); treeItem->setText(0, name);
@ -432,15 +539,15 @@ QTreeWidgetItem * MainWindow::addTreeRoot(QString name, QString fileSize, bool i
// add a file in treeview // add a file in treeview
QTreeWidgetItem * MainWindow::addTreeChild(QTreeWidgetItem *parent, QString name, QString fileSize, bool isDir) QTreeWidgetItem * MainWindow::addTreeChild(QTreeWidgetItem *parent, QString name, QString fileSize, bool isDir)
{ {
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
QTreeWidgetItem *treeItem = new QTreeWidgetItem(); QTreeWidgetItem *treeItem = new QTreeWidgetItem();
// QTreeWidgetItem::setText(int column, const QString & text)
if (isDir == true) if (isDir == true)
{ {
// item is a dir
treeItem->setText(1, tr("Dir")); treeItem->setText(1, tr("Dir"));
}else }else
{ {
// item is a file
treeItem->setText(1,("File")); treeItem->setText(1,("File"));
} }
treeItem->setText(0, name); treeItem->setText(0, name);
@ -454,13 +561,14 @@ QTreeWidgetItem * MainWindow::addTreeChild(QTreeWidgetItem *parent, QString name
// Slot acivated when a service in the list is clicked // Slot acivated when a service in the list is clicked
void MainWindow::on_listWidget_clicked() void MainWindow::on_listWidget_clicked()
{ {
QString service;
QString str; QString str;
this->connexion.service = ui->listWidget->currentItem()->text().section("\n", 0 ,0); this->connexion.service = ui->listWidget->currentItem()->text().section("\n", 0 ,0);
str = "Folder/" + this->connexion.server + "/" + this->connexion.service; str = "Folder/" + this->connexion.server + "/" + this->connexion.service;
// if service exists in settings for this server
if (this->settings.contains(str)) if (this->settings.contains(str))
{ {
// setting savePath from settings
this->downloading.savePath = this->settings.value(str).toString(); this->downloading.savePath = this->settings.value(str).toString();
} }
populateTree(NULL); populateTree(NULL);
@ -474,24 +582,15 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
QTreeWidgetItem * itemR; QTreeWidgetItem * itemR;
QString path; QString path;
QString str; QString str;
QMessageBox::StandardButton reply;
itemR = item; itemR = item;
// assembling path from treewidget
path = item->text(0); path = item->text(0);
while(itemR->parent() != NULL)
{
itemR = itemR->parent();
path = itemR->text(0) + "/" + path;
};
if (item->text(1) == tr("File") or downloadDir == true)
{
// Item is a file
if(ui->listDownload->findItems(path, Qt::MatchStartsWith).empty())
{
// exists saving path in settings ? // exists saving path in settings ?
str = "Folder/" + this->connexion.server + "/" + this->downloading.service; str = "Folder/" + this->connexion.server + "/" + this->connexion.service;
if(!this->settings.contains(str)) if(!this->settings.contains(str))
{ {
// saving path do not exists, asking for it // saving path do not exists, asking for it
@ -500,8 +599,43 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
cout << "no directory selectioned, ignoring download request"; cout << "no directory selectioned, ignoring download request";
return; return;
} }
}else
{
this->downloading.savePath = this->settings.value(str).toString();
} }
while(itemR->parent() != NULL)
{
itemR = itemR->parent();
// concatening parent to path
path.prepend(itemR->text(0) + "/");
};
if (item->text(1) == tr("File") or downloadDir == true)
{
// Item is a file
// searching if file exists in savepath
if (QFile::exists(this->downloading.savePath + "/" + path))
{
reply = QMessageBox::question(
this,
"RsyncUI",
tr("File is already downloaded. Do you want to reload it ? The old file will be deleted"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
if (reply == QMessageBox::No)
{
return;
}else
{
QFile::remove(this->downloading.savePath + "/" + path);
}
}
if(ui->listDownload->findItems(path, Qt::MatchStartsWith).empty())
{
// is there a downloading process ? // is there a downloading process ?
if (this->downloading.process == nullptr) if (this->downloading.process == nullptr)
{ {
@ -510,13 +644,20 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
this->downloading.server = this->connexion.server; this->downloading.server = this->connexion.server;
this->downloading.service = this->connexion.service; this->downloading.service = this->connexion.service;
startDownloading(); startDownloading();
// wit 1 second to process start // wait 1 second to process start
//sleep(1); //sleep(1);
} }
// Adding download in download list // Adding download in download list
str = path + " => " + this->connexion.server + "/" + this->connexion.service; str = path + " => " + this->connexion.server + "/" + this->connexion.service;
ui->listDownload->addItem(str); ui->listDownload->addItem(str);
}else
{
QMessageBox::warning(
this,
"RsyncUI",
tr("File is already downloading" )
);
} }
}else }else
{ {
@ -538,6 +679,7 @@ void MainWindow::startDownloading()
//QtConcurrent::run(&this->downloadO, &downloadFile::download, this); //QtConcurrent::run(&this->downloadO, &downloadFile::download, this);
download(); download();
this->trayIcon->showMessage("RsyncUI", tr("Starting downloading\n") + this->downloading.path, QSystemTrayIcon::Information);
} }
// Slot stopping download // Slot stopping download
@ -550,9 +692,11 @@ void MainWindow::stoppingDownload()
void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus) void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
{ {
QString path; QString path;
int pos;
QString str; QString str;
int pos;
QString aborted = tr("finished");
// test if process crashed
if (exitStatus == QProcess::CrashExit) if (exitStatus == QProcess::CrashExit)
{ {
QMessageBox::warning( QMessageBox::warning(
@ -560,25 +704,42 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
"RsyncUI", "RsyncUI",
tr("Rsync process crashed")); tr("Rsync process crashed"));
} }
//test result code of command (if 20 then command stopped by user)
if (exitCode != 0 and exitCode != 20) if (exitCode != 0 and exitCode != 20)
{ {
// displaying warning with exit code
QMessageBox::warning( QMessageBox::warning(
NULL, NULL,
"RsyncUI", "RsyncUI",
rsyncErrorStrings[exitCode]); rsyncErrorStrings[exitCode]);
}else if (exitCode == 20)
{
aborted = tr("stopped by user");
} }
this->trayIcon->showMessage("RsyncUI", tr("Download ") + aborted + "\n" + this->downloading.path, QSystemTrayIcon::Information);
// disconnecting signals to slots
disconnect(this->downloading.process, 0, 0, 0); disconnect(this->downloading.process, 0, 0, 0);
this->downloading.process= nullptr;
// reset variables and window
this->downloading.process = nullptr;
ui->progressBar->hide(); ui->progressBar->hide();
delete ui->listDownload->takeItem(0); delete ui->listDownload->takeItem(0);
this->downloading.clear(); this->downloading.clear();
// Some downloads staying in queue
if (ui->listDownload->count() != 0) if (ui->listDownload->count() != 0)
{ {
// autosave is activated
if (config.autosaveCheckbox->checkState() == Qt::Checked) if (config.autosaveCheckbox->checkState() == Qt::Checked)
{ {
// saving download list
saveDownloadList(); saveDownloadList();
} }
// initializing download
path = ui->listDownload->item(0)->text(); path = ui->listDownload->item(0)->text();
pos = path.lastIndexOf("/"); pos = path.lastIndexOf("/");
this->downloading.service = path.midRef(pos+1).toString(); this->downloading.service = path.midRef(pos+1).toString();
@ -587,12 +748,17 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
this->downloading.server = path.midRef(pos+4).toString(); this->downloading.server = path.midRef(pos+4).toString();
path.resize(pos); path.resize(pos);
this->downloading.path = path; this->downloading.path = path;
// savepath exists in settings ?
str = "Folder/" + this->downloading.server + "/" + this->downloading.service; str = "Folder/" + this->downloading.server + "/" + this->downloading.service;
if (this->settings.contains(str)) if (this->settings.contains(str))
{ {
// setting savepath from saved settings
this->downloading.savePath = this->settings.value(str).toString(); this->downloading.savePath = this->settings.value(str).toString();
startDownloading();
}else }else
{ {
// no save path
if(!on_DefaultSaveFolder_triggered()) if(!on_DefaultSaveFolder_triggered())
{ {
cout << "Error no save path so deleting download"; cout << "Error no save path so deleting download";
@ -600,20 +766,19 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
return; return;
} }
} }
startDownloading();
} }
saveDownloadList();
} }
// Slot activated when a line is clicked in queue list // Slot activated when a line is clicked in queue list
void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item) void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
{ {
QFileDialog dialog;
QMessageBox::StandardButton reply; QMessageBox::StandardButton reply;
//cout << item->text().toStdString() << endl;
if (item->listWidget()->row(item) == 0) if (item->listWidget()->row(item) == 0)
{ {
// first line clicked on download list
reply = QMessageBox::question( reply = QMessageBox::question(
this, this,
"RsyncUI", "RsyncUI",
@ -622,10 +787,12 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
QMessageBox::No); QMessageBox::No);
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes)
{ {
// stopping download
emit (stopDownloading(this->downloading.process)); emit (stopDownloading(this->downloading.process));
} }
}else }else
{ {
// not first line on download list
reply = QMessageBox::question( reply = QMessageBox::question(
this, this,
"RsyncUI", "RsyncUI",
@ -634,10 +801,12 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
QMessageBox::No); QMessageBox::No);
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes)
{ {
// removing line from download list
ui->listDownload->removeItemWidget(item); ui->listDownload->removeItemWidget(item);
delete item; delete item;
if (config.autosaveCheckbox->checkState() == Qt::Checked) if (config.autosaveCheckbox->checkState() == Qt::Checked)
{ {
// autosave acivated,so saving download list
saveDownloadList(); saveDownloadList();
} }
} }
@ -694,7 +863,6 @@ void MainWindow::saveSettings()
// About // About
void MainWindow::on_actionAbout_triggered() void MainWindow::on_actionAbout_triggered()
{ {
//TODO => initialisation
QString text = this->about.description + "\n\n" + QString text = this->about.description + "\n\n" +
tr("Version") + ": " + this->about.version + "\n" + tr("Version") + ": " + this->about.version + "\n" +
tr("Licence") + ": " + this->about.licence + "\n" + tr("Licence") + ": " + this->about.licence + "\n" +
@ -717,6 +885,7 @@ bool MainWindow::on_DefaultSaveFolder_triggered()
QString folder; QString folder;
QString path; QString path;
// if service not selected display a message
if (this->connexion.service.isEmpty()) if (this->connexion.service.isEmpty())
{ {
QMessageBox::warning( QMessageBox::warning(
@ -725,12 +894,15 @@ bool MainWindow::on_DefaultSaveFolder_triggered()
tr("Since the save path is linked to service, you need to select a service before you can select a folder")); tr("Since the save path is linked to service, you need to select a service before you can select a folder"));
return false; return false;
} }
// Asking for directory to save files
path = dialog.getExistingDirectory(this, tr("Choose folder where to save file"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); path = dialog.getExistingDirectory(this, tr("Choose folder where to save file"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!path.isEmpty()) if (!path.isEmpty())
{ {
this->downloading.savePath = path; this->downloading.savePath = path;
if (!this->connexion.service.isEmpty() and !this->connexion.server.isEmpty()) if (!this->connexion.service.isEmpty() and !this->connexion.server.isEmpty())
{ {
// saving save path in settings
folder = "Folder/" + this->connexion.server + "/" + this->connexion.service; folder = "Folder/" + this->connexion.server + "/" + this->connexion.service;
this->settings.setValue(folder, this->downloading.savePath); this->settings.setValue(folder, this->downloading.savePath);
this->settings.sync(); this->settings.sync();
@ -759,6 +931,7 @@ void MainWindow::on_buttonBox_accepted()
bw = config.spinBox->text(); bw = config.spinBox->text();
if (bw.toInt() == 0) if (bw.toInt() == 0)
{ {
// bandwidth = 0
this->connexion.bandwidthLimit = 0; this->connexion.bandwidthLimit = 0;
this->connexion.bandwidthLimitUnit = 0; this->connexion.bandwidthLimitUnit = 0;
}else }else
@ -780,9 +953,11 @@ void MainWindow::saveDownloadList()
{ {
int nRows; int nRows;
// remove list of downloads
this->settings.remove("Downloads/"); this->settings.remove("Downloads/");
// Saving list of current downloads
nRows = ui->listDownload->count(); nRows = ui->listDownload->count();
//this->settings.beginWriteArray("Downloads/");
this->settings.beginGroup("Downloads"); this->settings.beginGroup("Downloads");
this->settings.setValue("rows", nRows); this->settings.setValue("rows", nRows);
for (int i = 0; i < nRows; i++) for (int i = 0; i < nRows; i++)
@ -793,12 +968,14 @@ void MainWindow::saveDownloadList()
this->settings.sync(); this->settings.sync();
} }
// Loading download list
void MainWindow::loadDownloadList() void MainWindow::loadDownloadList()
{ {
QString path; QString path;
QString str; QString str;
int pos; int pos;
this->settings.sync();
this->settings.beginGroup("Downloads"); this->settings.beginGroup("Downloads");
int size = this->settings.value("rows").toInt(); int size = this->settings.value("rows").toInt();
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
@ -807,8 +984,6 @@ void MainWindow::loadDownloadList()
} }
this->settings.endGroup(); this->settings.endGroup();
this->settings.sync();
path = ui->listDownload->item(0)->text(); path = ui->listDownload->item(0)->text();
pos = path.lastIndexOf("/"); pos = path.lastIndexOf("/");
this->downloading.service = path.midRef(pos+1).toString(); this->downloading.service = path.midRef(pos+1).toString();
@ -825,6 +1000,7 @@ void MainWindow::loadDownloadList()
startDownloading(); startDownloading();
} }
// clear object downloading
void Downloading::clear() void Downloading::clear()
{ {
this->path.clear(); this->path.clear();
@ -833,6 +1009,7 @@ void Downloading::clear()
this->service.clear(); this->service.clear();
} }
// Context menu of file list clicked
void MainWindow::on_actionDownload_triggered() void MainWindow::on_actionDownload_triggered()
{ {
// action made in qt-designer and added in init function. // action made in qt-designer and added in init function.
@ -852,7 +1029,13 @@ void MainWindow::on_actionDownload_triggered()
} }
*/ */
// Chnage toolbar style
void MainWindow::on_comboBox_currentIndexChanged(int index) void MainWindow::on_comboBox_currentIndexChanged(int index)
{ {
ui->toolBar->setToolButtonStyle((Qt::ToolButtonStyle)index); ui->toolBar->setToolButtonStyle((Qt::ToolButtonStyle)index);
} }
void MainWindow::on_actionExit_triggered()
{
quitApp();
}

View File

@ -39,6 +39,9 @@
#include <QProcess> #include <QProcess>
#include <QToolBar> #include <QToolBar>
#include <QDir> #include <QDir>
#include <QSystemTrayIcon>
#include <QMenu>
#include<QTranslator>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
@ -73,7 +76,7 @@ class About
{ {
public: public:
QString title = "RsyncUI"; QString title = "RsyncUI";
QString version = "1.9.2"; QString version = "2.2";
QString author = "Daniel TARTAVEL-JEANNOT"; QString author = "Daniel TARTAVEL-JEANNOT";
QString licence = "GPL_V3"; QString licence = "GPL_V3";
QString description; QString description;
@ -98,6 +101,7 @@ class MainWindow : public QMainWindow
QDialog Configuration; QDialog Configuration;
Ui::Configuration config; Ui::Configuration config;
std::vector <QString> serversList; std::vector <QString> serversList;
QSystemTrayIcon * trayIcon;
QList<QString> bwUnitText { QList<QString> bwUnitText {
"KB", "KB",
"MB", "MB",
@ -139,6 +143,9 @@ class MainWindow : public QMainWindow
void saveDownloadList(); void saveDownloadList();
void loadDownloadList(); void loadDownloadList();
void download(); void download();
void initSystemTrayIcon();
void hideWindow();
void showWindow();
private slots: private slots:
@ -180,7 +187,13 @@ class MainWindow : public QMainWindow
void cancelled(QProcess *); void cancelled(QProcess *);
signals: void on_trayIcon_clicked(QSystemTrayIcon::ActivationReason reason);
void quitApp();
void on_actionExit_triggered();
signals:
void stopDownloading(QProcess *); void stopDownloading(QProcess *);
void progressSignal(int); void progressSignal(int);
void finishedSignal(bool = true); void finishedSignal(bool = true);

View File

@ -20,6 +20,9 @@
<property name="windowTitle"> <property name="windowTitle">
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<property name="windowIcon">
<iconset theme="/usr/share/icons/RsyncUI.png"/>
</property>
<property name="toolButtonStyle"> <property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum> <enum>Qt::ToolButtonTextUnderIcon</enum>
</property> </property>
@ -395,6 +398,7 @@
<addaction name="action_Settings"/> <addaction name="action_Settings"/>
<addaction name="actionAbout"/> <addaction name="actionAbout"/>
<addaction name="actionAbout_Qt"/> <addaction name="actionAbout_Qt"/>
<addaction name="actionExit"/>
</widget> </widget>
<action name="DefaultSaveFolder"> <action name="DefaultSaveFolder">
<property name="icon"> <property name="icon">
@ -443,6 +447,20 @@
<string>Click on menu button to download the entire folder</string> <string>Click on menu button to download the entire folder</string>
</property> </property>
</action> </action>
<action name="actionExit">
<property name="icon">
<iconset theme="application-exit"/>
</property>
<property name="text">
<string>Exit</string>
</property>
<property name="toolTip">
<string>Terminate the program</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -43,6 +43,7 @@ const vector<string> explode(const string& s, const char& c, int n = 0)
return v; return v;
} }
// test return code of rsync
bool testRsyncReturn(QProcess * myProcess) bool testRsyncReturn(QProcess * myProcess)
{ {
if (myProcess->exitStatus() != 0) if (myProcess->exitStatus() != 0)