Compare commits

..

12 Commits
2.9 ... 2.10.1

12 changed files with 276 additions and 355 deletions

View File

@ -22,6 +22,7 @@ Un clic gauche sur un fichier l'ajoute à la file des téléchargements, sur un
Un clic droit sur un dossier ouvre un menu contextuel permettant de télécharger le dossier entier.
Une notification s'affiche lors du début, de la fin, et lorsque l'on stoppe un téléchargement.
Le gadget de fermeture ferme la fenêtre mais ne quitte pas l'application, pour afficher à nouveau la fenêtre, cliquez sur l'icône dans la boite à miniatures.
Un identifiant et un mot de passe lorsqu'un service est protégé par mot de passe, celui-ci est enregistré dans le portefeuille système(gome-keyring ou kwallet)
## File de téléchargement
@ -30,7 +31,7 @@ Cliquez sur un fichier pour le supprimer de la file et une fenêtre de confirmat
## Barre d'outils
1er icône: Changer le dossier de destination
Permet de changer le dossier de téléchargement par défaut pour chaque service de chaque serveur.
- Permet de changer le dossier de téléchargement par défaut pour chaque service de chaque serveur.
2ème icône: Paramètres de l'application
- Limite de bande passante
@ -41,7 +42,7 @@ Cliquez sur un fichier pour le supprimer de la file et une fenêtre de confirmat
- Enregistrement automatique
Enregistre automatiquement la liste des téléchargements en cours.(activé par défaut)
3ème icône: À propos
Affiche les propriétés de l'application.
- Affiche les propriétés de l'application.
4ème icône: À propos de QT
5 ème icône: Quitter
5ème icône: Quitter
Permet de quitter le programme.

View File

@ -6,11 +6,14 @@ QT += KConfigCore KConfigGui
QT += KCoreAddons
QT += KDBusAddons
#LIBS += -lKF5WindowSystem
LIBS += -lqt5keychain
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
DEFINES += QTKEYCHAIN_NO_EXPORT
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
@ -31,14 +34,14 @@ HEADERS += \
FORMS += \
about.ui \
configuration.ui \
login.ui \
mainwindow.ui
TRANSLATIONS += \
RsyncUI_fr_FR.ts
INCLUDEPATH += \
/usr/include/KF5
/usr/include/KF5 \
/usr/include/qt5keychain/
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
@ -64,3 +67,4 @@ desktopfile.path = /usr/share/applications
desktopfile.files = RsyncUI.desktop
icon.path = /usr/share/icons/
icon.files = RsyncUI.png
-lqt5keychain

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.14.2, 2023-03-05T10:17:18. -->
<!-- Written by QtCreator 4.14.2, 2023-03-09T22:37:54. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

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

View File

@ -125,26 +125,3 @@ void MainWindow::readRsyncOutput()
}
}
}
/*void MainWindow::downloadProcessError(QProcess::ProcessError error)
{
QMessageBox::warning(
this,
"RsyncUI",
downloadProcessErrorString[error].toStdString().c_str()
);
}*/
// process raise error
void MainWindow::downloadProcessStderr()
{
QByteArray errorLine;
errorLine = this->downloading.process->readAllStandardError();
QMessageBox::warning(
this,
"RsyncUI",
errorLine
);
}

144
login.ui
View File

@ -1,144 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LoginDialog</class>
<widget class="QDialog" name="LoginDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>194</height>
</rect>
</property>
<property name="windowTitle">
<string>RsyncUI request</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<widget class="QDialogButtonBox" name="loginBox">
<property name="geometry">
<rect>
<x>50</x>
<y>150</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>381</width>
<height>121</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Login name</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="loginEdit">
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>32767</number>
</property>
<property name="placeholderText">
<string>Enter login</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="passwordEdit">
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="placeholderText">
<string>Enter password</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>loginBox</sender>
<signal>accepted()</signal>
<receiver>LoginDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>loginBox</sender>
<signal>rejected()</signal>
<receiver>LoginDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -21,6 +21,9 @@ int main(int argc, char *argv[])
a.installTranslator(&myappTranslator);
}
static const QString appName = "RsyncUI";
//Password passwdJob;
MainWindow w;
w.show();
w.init();

View File

@ -4,9 +4,9 @@
using namespace std;
bool display = false;
//extern QDialog Configuration;
extern Ui::Configuration config;
extern bool testRsyncReturn(QProcess *);
extern QApplication a;
QMap<int, QString> rsyncErrorStrings {
{0, QTranslator::tr("Success. The rsync command completed successfully without any errors.")},
@ -38,19 +38,16 @@ MainWindow::MainWindow(QWidget *parent)
QCoreApplication::setOrganizationName("RsyncUI");
QCoreApplication::setApplicationName("RsyncUI");
this->setWindowTitle(a.applicationName());
// context menu for treewidget (list of files)
ui->treeWidget->addAction(ui->actionDownload);
// init configuration window
config.setupUi(&Configuration);
// init about window
AboutW.setupUi(&aboutDialog);
//init login dialog
loginD.setupUi(&loginDialog);
loginD.loginEdit->setFocus();
// text of About
QString aboutText = tr("<h2>Client for rsync server</h2>") +
"<b>" + tr("Version") + ": " + this->about.version + "</b><br>" +
@ -68,7 +65,6 @@ MainWindow::MainWindow(QWidget *parent)
connect(this, &MainWindow::stopDownloading, this, &MainWindow::cancelled);
connect(config.buttonBox, SIGNAL(accepted()), this, SLOT(on_buttonBox_accepted()));
connect(config.comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::on_comboBox_currentIndexChanged);
connect(loginD.loginBox, SIGNAL(accepted()), this, SLOT(on_loginBox_accepted()));
loadSettings();
@ -119,7 +115,7 @@ void MainWindow::init()
if (this->settings.value("Downloads/rows").toInt() != 0)
{
// asking if we load the list and continue downloading
msgBox.setWindowTitle("RsyncUI");
msgBox.setWindowTitle(a.applicationName());
msgBox.setInformativeText(tr("A list of interrupted downloads exists, do you want to continue downloading ? if not the list will be cleared" ));
QPushButton *yes = msgBox.addButton(QMessageBox::Yes);
@ -136,7 +132,7 @@ void MainWindow::init()
}
}
// load list of services
populateList();
populateList(ui->khistorycombobox->currentIndex());
}
void MainWindow::initSystemTrayIcon()
@ -211,7 +207,7 @@ void MainWindow::quitApp()
reply = QMessageBox::question(
this,
"RsyncUI",
a.applicationName(),
tr("Exiting will stop downloading, and will clear the download queue.\nDo you want to exit ?") + displayText,
param,
QMessageBox::No);
@ -249,7 +245,7 @@ void MainWindow::closeEvent (QCloseEvent *event)
return;
if (trayIcon->isVisible() and this->settings.value("CloseCheckbox").toBool() == false)
{
msgBox.setWindowTitle("RsyncUI");
msgBox.setWindowTitle(a.applicationName());
msgBox.setInformativeText(tr("The program will keep running in the "
"system tray. To terminate the program, "
"choose <b>Quit</b> in the context menu "
@ -292,7 +288,10 @@ void MainWindow::populateTree()
{
// server is validated, scanning directory
path = this->connexion.service + "/";
scanDir(this->connexion.server, this->connexion.port, nullptr, path);
while (this->rescan)
{
scanDir(this->connexion.server, this->connexion.port, nullptr, path);
}
}
// Restoring cursor
QGuiApplication::restoreOverrideCursor();
@ -300,14 +299,15 @@ void MainWindow::populateTree()
}
// Populate Listview with list of services
void MainWindow::populateList()
void MainWindow::populateList(int item)
{
QString server;
QString service;
QStringList hidden;
int port;
int i;
server = ui->khistorycombobox->currentText();
server = ui->khistorycombobox->itemText(item);
port = ui->portEdit->text().toUInt();
if ((server != this->connexion.server) or (port != this->connexion.port))
{
@ -353,18 +353,73 @@ void MainWindow::populateList()
}
}
this->settings.endGroup();
this->settings.beginGroup("Hidden/");
this->settings.beginGroup("Hidden/" + server);
hidden = this->settings.allKeys();
for (i = 0; i < hidden.size(); i++)
if (hidden.count() > 0)
{
//TODO detect if service is already present
ui->listWidget->addItem(this->settings.value(hidden.at(i)).toString() + "\n\t");
for (i = 0; i < hidden.size(); i++)
{
service = hidden[i];
//TODO detect if service is already present
if (testServicePresence(service, false))
{
ui->listWidget->addItem(service + "\n\t");
}
}
}
QGuiApplication::restoreOverrideCursor(); //setting cursor to default
this->settings.endGroup();
QGuiApplication::restoreOverrideCursor(); //setting cursor to default
}
}
// Test if service is already present on the server
bool MainWindow::testServicePresence(QString service, bool askPassword)
{
QString cmd;
QStringList param;
QString line;
QString errorRsync;
QStringList v;
QProcess *myProcess;
bool returnValue = false;
QEventLoop loop;
cmd = "/usr/bin/rsync";
param << "--contimeout=10" << "-nq" << "--port=" + QString::number(this->connexion.port) << this->connexion.server + "::" + service;
myProcess = new QProcess(this);
myProcess->setProcessChannelMode(QProcess::MergedChannels);
myProcess->start(cmd, param);
myProcess->waitForStarted();
myProcess->write("\n");
//myProcess->waitForFinished(12000);
while(myProcess->waitForReadyRead(10000))
{
while(1)
{
// line empty then buffer is empty so returning to wait new datas
line = QString::fromUtf8(myProcess->readLine());
if (line.isEmpty())
{
break;
}
if (line.contains("auth failed"))
{
if (askPassword)
{
getUserPassword(&this->connexion);
}
returnValue = true;
}
}
}
if (myProcess->exitCode() == 0)
{
returnValue = true;
}
myProcess->close();
return returnValue;
}
//list services of the rsync server
void MainWindow::listServices()
{
@ -425,13 +480,15 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
QString fileType;
QString date;
QProcess * myProcess;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
bool isDir = false;
bool flag = false;
bool readOk = false;
bool passwdOk = false;
int nChild = 0;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
myProcess = new QProcess(this);
myProcess->setProcessChannelMode(QProcess::MergedChannels);
if (parent != nullptr)
{
@ -470,12 +527,19 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
flag = true;
break;
}
if (line.contains("auth failed"))
{
myProcess->readAllStandardOutput();
getUserPassword(&this->connexion);
this->rescan = true;
return 0;
}
// extracting name, size and if is dir/file
line = line.simplified();
filename = line.section(" ", 4);
if (filename != '.')
{
size = line.section(" ", 1, 1);
fullsize = size;
fullsize.remove(",");
@ -484,7 +548,8 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
{
size = sizeA.at(0) + " " + UnitText[0] + " ";
}else
{
{ myProcess->setProcessEnvironment(env);
size = sizeA.at(0) + "," + sizeA.at(1).left(2) + " " + UnitText[sizeA.count()-1] + " ";
}
@ -498,6 +563,13 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
date = line.section(' ', 2, 2);
fileType = getFileType(filename);
addTreeItem(filename, size, fullsize, fileType, date, isDir, parent);
if (passwdOk == false and !this->connexion.password.isEmpty())
{
this->settings.setValue("Passwords/" + this->connexion.server + "/" + this->connexion.service + "/" + this->connexion.user, true);
setPassword(this->connexion.user, this->connexion.password);
this->settings.sync();
}
this->rescan = false;
}
}
flag = false;
@ -509,7 +581,7 @@ bool MainWindow::scanDir(QString server, int portN, QTreeWidgetItem *parent, QSt
{
QMessageBox::warning(
this,
"RsyncUI",
a.applicationName(),
tr("The processus does'nt respond: ") + myProcess->errorString());
}
}
@ -595,7 +667,7 @@ bool MainWindow::validateServer(QString server)
// server-s address not valid
QMessageBox::warning(
this,
"RsyncUI",
a.applicationName(),
tr("server does not exists" )
);
}
@ -604,16 +676,16 @@ bool MainWindow::validateServer(QString server)
}
// slot activated when combobox is changed
void MainWindow::on_khistorycombobox_currentIndexChanged(int i)
void MainWindow::on_khistorycombobox_currentIndexChanged(int item)
{
this->connexion.comboboxChanged = true;
populateList();
populateList(item);
}
// slot activated when button connection is clicked
void MainWindow::on_connectButton_clicked()
{
populateList();
populateList(ui->khistorycombobox->currentIndex());
}
// add parent in treeview
@ -655,6 +727,7 @@ void MainWindow::addTreeItem(QString name, QString fileSize, QString fullsize, Q
void MainWindow::on_listWidget_clicked()
{
this->connexion.service = ui->listWidget->currentItem()->text().section("\n", 0 ,0);
ui->treeWidget->clear();
preparePopulateTree();
}
@ -673,45 +746,74 @@ void MainWindow::preparePopulateTree()
// setting savePath from settings
this->downloading.savePath = this->settings.value(str).toString();
}
this->settings.beginGroup("Passwords/" + this->connexion.server + "/" + this->connexion.service);
logins = this->settings.allKeys();
//TODO choose login
if (logins.count() != 0)
{
this->connexion.user = logins[0];
this->connexion.password = this->settings.value(logins[0]).toString();
}
this->settings.endGroup();
//getUserPassword(&this->connexion);
populateTree();
}
// get password and user login
// if object = false ==> searching from connexion object
// else searching from downloading object
bool MainWindow::getUserPassword(bool object = false)
bool MainWindow::getUserPassword(Connexion * object)
{
QStringList logins;
bool returnValue;
QString login;
QString password;
QString server;
QString service;
int c;
if (object == false)
{
this->settings.beginGroup("Passwords/" + this->connexion.server + "/" + this->connexion.service);
}else
{
this->settings.beginGroup("Passwords/" + this->downloading.server + "/" + this->downloading.service);
}
bool returnValue = false;
bool ok = false;
server = object->server;
service = object->service;
object->user = "";
object->password = "";
this->settings.beginGroup("Passwords/" + server + "/" + service);
logins = this->settings.allKeys();
//TODO choose login in case of multiples logins
if (logins.count() != 0)
c = logins.count();
if ( c != 1)
{
this->downloading.user = logins[0];
this->downloading.password = this->settings.value(logins[0]).toString();
returnValue = true;
//choose login in case of multiples logins
login = QInputDialog::getItem(this,
"RsincUI",
tr("Select the user you want to connect with or enter a new one"),
logins,
0,
true,
&ok,
Qt::Popup,
Qt::ImhNoPredictiveText
);
if (ok and !login.isEmpty())
{
if (!logins.contains(login))
{
password = QInputDialog::getText(this,
a.applicationName() + tr(" Request"),
tr("Enter password"), QLineEdit::Password,
"", &ok, Qt::Popup,
Qt::ImhNoPredictiveText);
if (!ok or password.isEmpty())
{
password = "";
}
}else
{
password = getPassword(login);
}
object->user = login;
object->password = password;
}
}else
{
this->downloading.user = nullptr;
this->downloading.password = nullptr;
returnValue = false;
object->user = logins.at(0);
object->password = getPassword(object->user);
returnValue = true;
}
this->settings.endGroup();
return returnValue;
@ -720,7 +822,6 @@ bool MainWindow::getUserPassword(bool object = false)
//Slot activated when a file is clicked in the treeview
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadDir)
{
QFuture<void> future;
QFileDialog dialog;
QTreeWidgetItem * itemR;
QString path;
@ -769,7 +870,7 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
{
reply = QMessageBox::question(
this,
"RsyncUI",
a.applicationName(),
tr("File is partially downloaded. Do you want to resume download ? if no, the file will be deleted from destination directory"),
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
QMessageBox::Cancel);
@ -786,7 +887,7 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
{
reply = QMessageBox::question(
this,
"RsyncUI",
a.applicationName(),
tr("File is already downloaded. Do you want to reload it ? The old file will be deleted"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
@ -823,16 +924,20 @@ void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, bool downloadD
{
QMessageBox::warning(
this,
"RsyncUI",
a.applicationName(),
tr("File is already downloading" )
);
}
}else
{
//Item is a Directory
scanDir(this->connexion.server, this->connexion.port, item, this->connexion.service + "/" + path +"/");
item->setExpanded(true);
while (this->rescan)
{
scanDir(this->connexion.server, this->connexion.port, item, this->connexion.service + "/" + path +"/");
item->setExpanded(true);
}
}
if (config.autosaveCheckbox->checkState() == Qt::Checked)
{
saveDownloadList();
@ -845,11 +950,11 @@ void MainWindow::startDownloading()
ui->progressBar->setValue(0);
ui->progressBar->show();
getUserPassword(false);
//getUserPassword();
//QtConcurrent::run(&this->downloadO, &downloadFile::download, this);
this->download();
this->trayIcon->showMessage("RsyncUI", tr("Starting downloading\n") + this->downloading.path, QSystemTrayIcon::Information);
this->trayIcon->showMessage(a.applicationName(), tr("Starting downloading\n") + this->downloading.path, QSystemTrayIcon::Information);
}
// Slot stopping download
@ -873,25 +978,25 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
QMessageBox::warning(
NULL,
"RsyncUI",
a.applicationName(),
tr("Rsync process crashed"));
}
//test result code of command (if 20 then command stopped by user)
if (exitCode != 0)
if (exitCode != 0 and this->stopDlAsked != true)
{
if (exitCode == 20)
{
aborted = tr("stopped by user");
}else if (exitCode == 5) // password asked
{
loginDialog.show();
getUserPassword(&this->downloading);
retry = true;
}
// displaying warning with exit code
reply = QMessageBox::warning(
this,
"RsyncUI",
a.applicationName(),
rsyncErrorStrings[exitCode] + tr("\nDo you want to retry?"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::Yes);
@ -900,13 +1005,13 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
retry = true;
}
}
this->trayIcon->showMessage("RsyncUI", tr("Download ") + aborted + "\n" + this->downloading.path, QSystemTrayIcon::Information);
this->stopDlAsked = false;
this->trayIcon->showMessage(a.applicationName(), tr("Download ") + aborted + "\n" + this->downloading.path, QSystemTrayIcon::Information);
// disconnecting signals to slots
disconnect(this->downloading.process, 0, 0, 0);
// reset variables and window
// reset variables and window, close process
this->downloading.process->close();
ui->progressBar->hide();
@ -928,7 +1033,9 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
this->downloading.server = path.midRef(pos+4).toString();
path.resize(pos);
this->downloading.path = path;
getUserPassword(true);
//getUserPassword(true);
testServicePresence(this->downloading.service, true);
// savepath exists in settings ?
str = "Folder/" + this->downloading.server + "/" + this->downloading.service;
@ -936,14 +1043,14 @@ void MainWindow::downloadFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
// setting savepath from saved settings
this->downloading.savePath = this->settings.value(str).toString();
sleep(2);
startDownloading();
}else
{
// no save path
if(!on_DefaultSaveFolder_triggered())
{
cout << "Error no save path so deleting download";
//downloadFinished();
cout << "Error no save path so removing download";
return;
}
}
@ -965,13 +1072,14 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
// first line clicked on download list
reply = QMessageBox::question(
this,
"RsyncUI",
a.applicationName(),
tr("Do you want to stop downloading and delete this file from download queue ?"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
if (reply == QMessageBox::Yes)
{
// stopping download
this->stopDlAsked = true;
emit (stopDownloading(this->downloading.process));
}
}else
@ -979,7 +1087,7 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
// not first line on download list
reply = QMessageBox::question(
this,
"RsyncUI",
a.applicationName(),
tr("Do you want to delete this file from download queue ?"),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No);
@ -988,7 +1096,6 @@ void MainWindow::on_listDownload_itemClicked(QListWidgetItem *item)
// removing line from download list
ui->listDownload->removeItemWidget(item);
delete item;
}
}
if (config.autosaveCheckbox->checkState() == Qt::Checked)
@ -1069,7 +1176,7 @@ bool MainWindow::on_DefaultSaveFolder_triggered()
{
QMessageBox::warning(
NULL,
"RsyncUI",
a.applicationName(),
tr("Since the save path is linked to service, you need to select a service before you can select a folder"));
return false;
}
@ -1181,7 +1288,7 @@ void MainWindow::loadDownloadList()
}
// clear object downloading
void Downloading::clear()
void Connexion::clear()
{
this->path.clear();
this->server.clear();
@ -1207,7 +1314,7 @@ void MainWindow::on_actionDownload_triggered()
{
QMessageBox::warning(
this,
"RsyncUI",
a.applicationName(),
errorString,
QMessageBox::Ok,
QMessageBox::Ok);
@ -1225,25 +1332,6 @@ void MainWindow::on_actionExit_triggered()
quitApp();
}
void MainWindow::on_loginBox_accepted()
{
if (!loginD.loginEdit->text().isEmpty())
{
this->connexion.user = loginD.loginEdit->text();
if (!loginD.passwordEdit->text().isEmpty())
{
this->connexion.password = loginD.passwordEdit->text();
this->settings.setValue("Passwords/" + this->connexion.server + "/" + this->connexion.service + "/" + this->connexion.user, this->connexion.password);
this->settings.sync();
if (this->rescan == true)
{
this->rescan = false;
populateTree();
}
}
}
}
void MainWindow::setDlSpeed(QString speed)
{
speed.squeeze();
@ -1254,13 +1342,14 @@ void MainWindow::on_actionHiddenService_triggered()
QInputDialog hiddenFolderDialog;
bool ok;
QString text = QInputDialog::getText(this, tr("RsyncUI Request"),
QString text = QInputDialog::getText(this, a.applicationName() + tr(" Request"),
tr("Hidden service name"), QLineEdit::Normal,
"test", &ok);
if (ok && !text.isEmpty())
{
this->connexion.service = text;
this->settings.setValue("Hidden/" + this->connexion.server, text);
this->settings.setValue("Hidden/" + this->connexion.server + '/' + text, true);
ui->listWidget->addItem(text + "\n\t");
preparePopulateTree();
}
}

View File

@ -5,9 +5,9 @@
#include "ui_mainwindow.h"
#include "ui_configuration.h"
#include "ui_about.h"
#include "ui_login.h"
#include "downloadfile.h"
#include "tools.h"
#include "password.h"
#include <QMainWindow>
#include <string>
#include <QTreeWidgetItem>
@ -25,8 +25,6 @@
#include <cstdio>
#include <QMessageBox>
#include <boost/algorithm/string/replace.hpp>
#include <QFuture>
#include <qtconcurrentrun.h>
#include <QFileDialog>
#include <QThread>
#include <QProgressDialog>
@ -61,10 +59,15 @@ class Connexion
int contimeout = 20;
QString server;
QString service;
QString path;
QString savePath;
QString user;
QString password;
QProcess * process = nullptr;
int port = 873;
bool comboboxChanged;
bool quit = false;
void clear();
};
class Downloading
@ -85,8 +88,7 @@ class Downloading
class About
{
public:
QString title = "RsyncUI";
QString version = "2.9";
QString version = "2.10.1";
QString author = "Daniel TARTAVEL-JEANNOT";
QString licence = "GPL_V3";
QString description;
@ -102,21 +104,21 @@ class MainWindow : public QMainWindow
Ui::MainWindow *ui;
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// passwdManager;
QProgressDialog *progress;
Connexion connexion;
Downloading downloading;
Connexion downloading;
QSettings settings;
About about;
QDialog Configuration;
Ui::Configuration config;
QDialog aboutDialog;
Ui::windowAbout AboutW;
QDialog loginDialog;
Ui::LoginDialog loginD;
std::vector <QString> serversList;
QSystemTrayIcon * trayIcon;
QString icon = "/usr/share/icons/RsyncUI.png";
bool rescan = false;
bool stopDlAsked;
QList<QString> UnitText {
tr("B"),
@ -146,13 +148,11 @@ class MainWindow : public QMainWindow
void displayTree();
void populateTree();
void populateList();
void populateList(int);
void listServices();
bool validateServer(QString server);
bool isIpAddress(QString server);
void addTreeItem(QString name, QString fileSize, QString fullsize, QString type, QString date, bool isDir, QTreeWidgetItem *parent);
//QTreeWidgetItem * addTreeRoot(QString name, QString size, QString fullsize, bool isDir);
//QTreeWidgetItem * addTreeChild(QTreeWidgetItem *parent, QString name, QString size, QString fullsize, bool isDir);
bool scanDir(QString server, int portN, QTreeWidgetItem *parent = NULL, QString path = "" );
void startDownloading();
void loadSettings();
@ -165,8 +165,11 @@ class MainWindow : public QMainWindow
void hideWindow();
void showWindow();
void init();
bool getUserPassword(bool);
bool getUserPassword(Connexion *);
void preparePopulateTree();
bool testServicePresence(QString, bool=false);
void passwordStore (QString account, QString password);
QString passwordGet (QString account);
private slots:
@ -176,10 +179,6 @@ class MainWindow : public QMainWindow
void downloadFinished(int exitCode, QProcess::ExitStatus exitStatus);
// void downloadProcessError(QProcess::ProcessError error);
void downloadProcessStderr();
void readRsyncOutput();
void stoppingDownload();
@ -216,17 +215,15 @@ class MainWindow : public QMainWindow
void setDlSpeed(QString speed);
void on_loginBox_accepted();
void on_actionHiddenService_triggered();
signals:
signals:
void stopDownloading(QProcess *);
void progressSignal(int);
void speed(QString);
void finishedSignal(bool = true);
void fileName(QString);
//void errorSignal(QString);
void passwordReady();
};
#endif // MAINWINDOW_H

View File

@ -2,58 +2,54 @@
#include "password.h"
#include <qt5keychain/keychain.h>
#include <qt5keychain/qkeychain_export.h>
#include <QSettings>
using namespace std;
extern QApplication a;
/*Password::Password()
QString appName = "RsyncUI";
static QSettings sett{appName, appName};
void setPassword(QString account, QString pass)
{
this->passwdJob->setObjectName(this->appName);
this->passwdJob->setAutoDelete(false);
this->passwdJob->connect(this->passwdJob, SIGNAL(finished(QKeychain::Job*)), this, SLOT(finished(QKeychain::Job*)));
//this->readPass->connect(this->readPass, SIGNAL(finished()))
QKeychain::WritePasswordJob write(appName);
write.setSettings(&sett);
// write.setAutoDelete(false);
write.setKey(account);
write.setTextData(pass);
QEventLoop loop;
write.connect(&write, &QKeychain::WritePasswordJob::finished, &loop, &QEventLoop::quit);
write.start();
loop.exec();
if(write.error())
cout << "Error writing key1. Error: " << write.errorString().toStdString();
}
void Password::store (QString account, QString password)
QString getPassword(const QString& name)
{
this->passwdJob->setKey(account);
this->passwdJob->setTextData(password);
this->passwdJob->start();
}
QKeychain::ReadPasswordJob readPass(appName);
readPass.setSettings(&sett);
// readPass.setAutoDelete(false);
readPass.setKey(name);
QString Password::read(QString account)
{
this->readPass->setObjectName("");
this->readPass->setKey(account);
this->readPass->start();
}
QEventLoop loop;
readPass.connect(&readPass, &QKeychain::ReadPasswordJob::finished, &loop, &QEventLoop::quit);
bool Password::remove(QString)
{
readPass.start();
loop.exec();
}
void Password::finished(QKeychain::Job * passwdJob)
{
if(passwdJob->error()) {
QMessageBox::warning(
NULL,
"RsyncUI",
QString(this->mw->tr("Error: Unable to save password!")) + QString(passwdJob->error()));
if(readPass.error())
{
cout << "KeyHandler~Error reading decrypt Pass. Error: " + readPass.errorString() . toStdString() << endl;
return "";
}
else
{
QString data = readPass.textData();
return data;
}
}
void Password::readReturn()
{
if(this->readPass->error())
{
QMessageBox::warning(
NULL,
"RsyncUI",
QString(this->mw->tr("Error: Unable to read password!")) + QString(readPass->error()));
}else
{
this->password = readPass->textData();
}
}
*/

View File

@ -5,7 +5,12 @@
#include <qt5keychain/keychain.h>
#include <qt5keychain/qkeychain_export.h>
class Password : QObject
extern QApplication a;
void setPassword(QString account, QString pass);
QString getPassword(const QString& name);
/*class Password : QObject
{
public:
QString appName;
@ -13,6 +18,7 @@ class Password : QObject
QKeychain::ReadPasswordJob * readPass;
MainWindow * mw;
QString password;
QSettings passwdSettings{a.applicationName(),a.applicationName()};
Password();
~Password();
@ -22,8 +28,8 @@ class Password : QObject
bool remove(QString);
private slots:
void finished(QKeychain::Job*);
void readReturn();
};
void storeFinished();
void readFinished();
};*/
#endif // PASSWORD_H

View File

@ -6,6 +6,7 @@ using namespace std;
#define WRITE 1
extern QMap<int, QString> rsyncErrorStrings;
extern QApplication a;
//Take a string and explode it in array
// s => string to explode
@ -44,30 +45,20 @@ const vector<string> explode(const string& s, const char& c, int n = 0)
}
// test return code of rsync
// return true in case of error
bool testRsyncReturn(MainWindow * w, QProcess * myProcess)
{
if (myProcess->exitStatus() != 0)
if (myProcess->exitStatus() != 0 and w->stopDlAsked != true)
{
QMessageBox::warning(
NULL,
"RsyncUI",
w,
a.applicationName(),
myProcess->errorString(),
QMessageBox::Ok,
QMessageBox::Ok);
return true;
}else if (myProcess->exitCode() == 5)
{
w->loginDialog.show();
}else if (myProcess->exitCode() != 0)
{
QMessageBox::warning(
NULL,
"RsyncUI",
rsyncErrorStrings[myProcess->exitCode()],
QMessageBox::Ok,
QMessageBox::Ok);
return true;
}
w->stopDlAsked = false;
return false;
}
@ -78,3 +69,4 @@ QString getFileType(QString filename)
QString returnValue = mime.name().section('/',0 ,0);
return returnValue;
}