diff --git a/conf/verificationpreferences.cpp b/conf/verificationpreferences.cpp index 2c6f447e..4a0b043c 100644 --- a/conf/verificationpreferences.cpp +++ b/conf/verificationpreferences.cpp @@ -1,75 +1,74 @@ /*************************************************************************** * Copyright (C) 2009 Matthias Fuchs * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "verificationpreferences.h" #include "settings.h" #include -#include #include #include #include VerificationPreferences::VerificationPreferences(KConfigDialog *parent, Qt::WindowFlags f) : QWidget(parent, f) { ui.setupUi(this); m_tempKeyServers = Settings::signatureKeyServers(); ui.keyservers->upButton()->setText(i18n("&Increase Priority")); ui.keyservers->downButton()->setText(i18n("&Decrease Priority")); ui.keyservers->setItems(m_tempKeyServers); #ifndef HAVE_QGPGME ui.signatureGroup->hide(); #endif connect(ui.keyservers, &KEditListWidget::changed, this, &VerificationPreferences::changed); connect(parent, SIGNAL(accepted()), SLOT(slotAccpeted())); connect(parent, SIGNAL(rejected()), SLOT(slotRejected())); connect(parent, SIGNAL(resetDefaults()), SLOT(slotDefaultClicked())); } void VerificationPreferences::slotAccpeted() { ui.keyservers->lineEdit()->clear(); m_tempKeyServers = ui.keyservers->items(); Settings::self()->setSignatureKeyServers(m_tempKeyServers); Settings::self()->save(); } void VerificationPreferences::slotRejected() { //PreferencesDialog is not recreated, so we have to manually stop the //settings from changing ui.keyservers->setItems(m_tempKeyServers); ui.keyservers->lineEdit()->clear(); } void VerificationPreferences::slotDefaultClicked() { ui.keyservers->lineEdit()->clear(); KConfigSkeletonItem *item = Settings::self()->findItem("SignatureKeyServers"); if (item) { item->readDefault(Settings::self()->config()); ui.keyservers->setItems(Settings::signatureKeyServers()); } } diff --git a/transfer-plugins/bittorrent/advanceddetails/btadvanceddetailswidget.cpp b/transfer-plugins/bittorrent/advanceddetails/btadvanceddetailswidget.cpp index d5a4eca4..f2948a80 100644 --- a/transfer-plugins/bittorrent/advanceddetails/btadvanceddetailswidget.cpp +++ b/transfer-plugins/bittorrent/advanceddetails/btadvanceddetailswidget.cpp @@ -1,119 +1,120 @@ /* This file is part of the KDE project Copyright (C) 2007 Lukas Appelhans Copyright (C) 2007 Joris Guisson 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 2 of the License, or (at your option) any later version. */ #include "btadvanceddetailswidget.h" #include #include #include "bttransferhandler.h" #include "bittorrentsettings.h" #include "fileview.h" #include "chunkdownloadview.h" #include "peerview.h" #include "monitor.h" #include "trackerview.h" #include "webseedstab.h" #include "kget_debug.h" -#include +#include #include #include #include #include #include +#include using namespace kt; BTAdvancedDetailsWidget::BTAdvancedDetailsWidget(BTTransferHandler * transfer) : m_transfer(transfer) { tc = m_transfer->torrentControl(); init(); //This updates the widget with the right values slotTransferChanged(transfer, 0xFFFFFFFF); connect(m_transfer, SIGNAL(transferChangedEvent(TransferHandler*,TransferHandler::ChangesFlags)), this, SLOT(slotTransferChanged(TransferHandler*,TransferHandler::ChangesFlags))); } void BTAdvancedDetailsWidget::init() { setWindowTitle(i18n("Advanced Details for %1", m_transfer->source().fileName())); resize(500, 400); QGridLayout *layout = new QGridLayout(); KTitleWidget *titleWidget = new KTitleWidget(this); titleWidget->setText(i18n("Advanced Details for %1", m_transfer->source().fileName())); titleWidget->setPixmap(QIcon::fromTheme("dialog-information")); layout->addWidget(titleWidget); tabWidget = new QTabWidget(this); layout->addWidget(tabWidget); setLayout(layout); file_view = new FileView(this); file_view->changeTC(tc, KSharedConfig::openConfig()); tabWidget->insertTab(0, file_view, QIcon::fromTheme("inode-directory"), i18n("Files")); //peer_view = new PeerView(this); //tabWidget->insertTab(1, peer_view, QIcon::fromTheme("system-users"), i18n("Peers")); //cd_view = new ChunkDownloadView(this); //cd_view->changeTC(tc); //tabWidget->insertTab(2, cd_view, QIcon::fromTheme("preferences-plugin"), i18n("Chunks")); tracker_view = new TrackerView(this); tracker_view->changeTC(tc); tabWidget->insertTab(1, tracker_view, QIcon::fromTheme("network-server"), i18n("Trackers")); webseeds_tab = new WebSeedsTab(this); webseeds_tab->changeTC(tc); tabWidget->insertTab(2, webseeds_tab, QIcon::fromTheme("network-server"), i18n("Webseeds")); monitor = new Monitor(tc, nullptr, nullptr, file_view); } void BTAdvancedDetailsWidget::hideEvent(QHideEvent * event) { Q_UNUSED(event) if (tc) tc->setMonitor(0); emit aboutToClose(); deleteLater(); } kt::Monitor* BTAdvancedDetailsWidget::torrentMonitor() const { return monitor; } void BTAdvancedDetailsWidget::slotTransferChanged(TransferHandler * transfer, TransferHandler::ChangesFlags flags) { qCDebug(KGET_DEBUG) << "BTAdvancedDetailsWidget::slotTransferChanged" ; Q_UNUSED(transfer) if (flags & BTTransfer::Tc_ChunksTotal || flags & BTTransfer::Tc_ChunksDownloaded || flags & BTTransfer::Tc_ChunksExcluded || flags & BTTransfer::Tc_ChunksLeft || flags & Transfer::Tc_DownloadSpeed || flags & Transfer::Tc_UploadSpeed) { //if (tabWidget->currentIndex() == 1) // peer_view->update(); //else if (tabWidget->currentIndex() == 2) // cd_view->update(); /*else */if (tabWidget->currentIndex() == 1) tracker_view->update(); } /*else if (m_transfer->status() == Job::Stopped) { peer_view->removeAll(); //cd_view->removeAll(); }*/ } diff --git a/transfer-plugins/bittorrent/scandlg.cpp b/transfer-plugins/bittorrent/scandlg.cpp index 5cd55978..31ff959d 100644 --- a/transfer-plugins/bittorrent/scandlg.cpp +++ b/transfer-plugins/bittorrent/scandlg.cpp @@ -1,118 +1,122 @@ /*************************************************************************** * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "scandlg.h" #include #include #include #include #include #include #include +#include +#include +#include +#include using namespace bt; namespace kt { ScanDlg::ScanDlg(KJob *job, QWidget* parent) - : KDialog(parent), m_job(static_cast(job)) + : QDialog(parent), m_job(static_cast(job)) { - setButtons(KDialog::None); Ui::ScanDlgBase ui; QWidget *widget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; ui.setupUi(widget); - setMainWidget(widget); + mainLayout->addWidget(widget); m_torrent_label = ui.torrent_label; m_chunks_found = ui.chunks_found; m_chunks_failed = ui.chunks_failed; m_chunks_downloaded = ui.chunks_downloaded; m_chunks_not_downloaded = ui.chunks_not_downloaded; m_progress = ui.progress; m_cancel = ui.cancel; KGuiItem::assign(m_cancel, KStandardGuiItem::cancel()); connect(m_cancel,SIGNAL(clicked()),this,SLOT(reject())); m_progress->setMaximum(100); m_progress->setValue(0); connect(m_job, SIGNAL(description(KJob*,QString,QPair,QPair)), SLOT(description(KJob*,QString,QPair,QPair))); connect(m_job, SIGNAL(result(KJob*)), SLOT(result(KJob*))); connect(m_job, SIGNAL(percent(KJob*,ulong)), SLOT(percent(KJob*,ulong))); } ScanDlg::~ScanDlg() { } void ScanDlg::closeEvent(QCloseEvent* ) { if (m_job) { m_job->kill(false); m_job = nullptr; } else accept(); } void ScanDlg::reject() { if (m_job) { m_job->kill(false); m_job = nullptr; } - KDialog::reject(); + QDialog::reject(); deleteLater(); } void ScanDlg::accept() { - KDialog::accept(); + QDialog::accept(); deleteLater(); } void ScanDlg::description(KJob *job, const QString &title, const QPair &field1, const QPair< QString, QString > &field2) { m_chunks_found->setText(field1.first); m_chunks_failed->setText(field1.second); m_chunks_downloaded->setText(field1.first); m_chunks_not_downloaded->setText(field2.second); } void ScanDlg::result(KJob *job) { if (job->error() && job->error() != KIO::ERR_USER_CANCELED) { KMessageBox::error(nullptr,i18n("Error scanning data: %1",job->errorString())); } m_job = nullptr; m_progress->setValue(100); disconnect(m_cancel,SIGNAL(clicked()),this,SLOT(reject())); connect(m_cancel,SIGNAL(clicked()),this,SLOT(accept())); } void ScanDlg::percent(KJob *job, unsigned long percent) { m_progress->setValue(percent); } } diff --git a/transfer-plugins/bittorrent/scandlg.h b/transfer-plugins/bittorrent/scandlg.h index 97dab99b..1b099c69 100644 --- a/transfer-plugins/bittorrent/scandlg.h +++ b/transfer-plugins/bittorrent/scandlg.h @@ -1,73 +1,73 @@ /*************************************************************************** * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * * joris.guisson@gmail.com * * ivasic@gmail.com * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KT_SCANDLG_HH #define KT_SCANDLG_HH +#include #include #include -#include #include #include #include "ui_scandlg.h" namespace bt { class TorrentInterface; } namespace kt { class TorrentInterface; - class ScanDlg : public KDialog + class ScanDlg : public QDialog { Q_OBJECT public: ScanDlg(KJob *job, QWidget* parent); virtual ~ScanDlg(); protected: /// Handle the close event virtual void closeEvent(QCloseEvent* e); protected slots: virtual void reject(); virtual void accept(); private slots: void description(KJob *job, const QString &title, const QPair &field1, const QPair< QString, QString > &field2); void result(KJob *job); void percent(KJob *job, unsigned long percent); private: bt::Job * m_job; QProgressBar *m_progress; QPushButton *m_cancel; QLabel *m_torrent_label; QLabel *m_chunks_failed; QLabel *m_chunks_found; QLabel *m_chunks_not_downloaded; QLabel *m_chunks_downloaded; }; } #endif diff --git a/transfer-plugins/checksumsearch/dlgchecksumsearch.h b/transfer-plugins/checksumsearch/dlgchecksumsearch.h index 45b06912..92be0e76 100644 --- a/transfer-plugins/checksumsearch/dlgchecksumsearch.h +++ b/transfer-plugins/checksumsearch/dlgchecksumsearch.h @@ -1,136 +1,136 @@ /*************************************************************************** * Copyright (C) 2009 Matthias Fuchs * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #ifndef DLGCHECKSUMSEARCH_H #define DLGCHECKSUMSEARCH_H #include "ui_checksumsearch.h" #include "ui_checksumsearchadddlg.h" #include "checksumsearchtransferdatasource.h" #include #include -#include +#include class QSortFilterProxyModel; class QStandardItemModel; class QStringListModel; class ChecksumSearchAddDlg : public QDialog { Q_OBJECT public: ChecksumSearchAddDlg(QStringListModel *modesModel, QStringListModel *typesModel, QWidget *parent = nullptr, Qt::WFlags flags = 0); signals: /** * Emitted when the dialog gets accepted * @param change the string that should change the source url by mode * @param mode the change mode * @param type the checksum type, can be an empty string */ void addItem(const QString &change, int mode, const QString &type); private slots: /** * Enables or disables buttons depending on if the user entered text or not, also changes * the label etc. */ void slotUpdate(); void slotAccpeted(); private: Ui::ChecksumSearchAddDlg ui; QStringListModel *m_modesModel; QStringListModel *m_typesModel; static const QUrl URL; }; class ChecksumDelegate : public QStyledItemDelegate { Q_OBJECT public: ChecksumDelegate(QObject *parent = nullptr); ChecksumDelegate(QStringListModel *modesModel, QStringListModel *typesModel, QObject *parent = nullptr); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; private: QStringListModel *m_modesModel; QStringListModel *m_typesModel; }; class DlgChecksumSettingsWidget : public KCModule { Q_OBJECT public: explicit DlgChecksumSettingsWidget(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); ~DlgChecksumSettingsWidget(); public slots: void save(); void load(); private slots: /** * Oppens the AddDlg */ void slotAdd(); /** * Remove the selected indexes */ void slotRemove(); /** * Enables or disables buttons depending on if the user entered text or not, also changes * the label etc. */ void slotUpdate(); /** * Adds a new item defining how to proceed a search for checksums to the model * @param change the string that should change the source url by mode * @param mode the change mode, defined in verifier.h, using int instead of enum as convenience * @param type the checksum type, like e.g. "md5", empty if you do not know that * e.g. if change is "CHECKSUMS" you cannot know which checksums are present */ void slotAddItem(const QString &change, int mode, const QString &type = QString()); private: Ui::ChecksumSearch ui; QStandardItemModel *m_model; QSortFilterProxyModel *m_proxy; QStringList m_modes; QStringListModel *m_modesModel; QStringListModel *m_typesModel; }; #endif // DLGCHECKSUMSEARCH_H diff --git a/transfer-plugins/contentfetch/dlgcontentfetchsettingwidget.cpp b/transfer-plugins/contentfetch/dlgcontentfetchsettingwidget.cpp index 77889aa3..8ca5c890 100644 --- a/transfer-plugins/contentfetch/dlgcontentfetchsettingwidget.cpp +++ b/transfer-plugins/contentfetch/dlgcontentfetchsettingwidget.cpp @@ -1,261 +1,263 @@ /* This file is part of the KDE project Copyright (C) 2008 Ningyu Shi 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 2 of the License, or (at your option) any later version. */ #include "dlgcontentfetchsettingwidget.h" #include "dlgscriptediting.h" #include "contentfetchsetting.h" #include "scriptconfigadaptor.h" #include "kget_export.h" #include -#include +#include #include +#include KGET_EXPORT_PLUGIN_CONFIG(DlgContentFetchSettingWidget) DlgContentFetchSettingWidget::DlgContentFetchSettingWidget(QWidget * parent = nullptr, const QVariantList &args = QVariantList()) : KCModule(KGetFactory::componentData(), parent, args), m_p_action(nullptr) { ui.setupUi(this); ui.newScriptButton->setIcon(QIcon::fromTheme("list-add")); ui.removeScriptButton->setIcon(QIcon::fromTheme("list-remove")); loadContentFetchSetting(); connect(ui.newScriptButton, SIGNAL(clicked()), this, SLOT(slotNewScript())); connect(ui.editScriptButton, SIGNAL(clicked()), this, SLOT(slotEditScript())); connect(ui.configureScriptButton, SIGNAL(clicked()), this, SLOT(slotConfigureScript())); connect(ui.removeScriptButton, SIGNAL(clicked()), this, SLOT(slotRemoveScript())); connect(ui.scriptTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotCheckConfigurable(QTreeWidgetItem*,int))); connect(ui.scriptTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotEnableChanged(QTreeWidgetItem*,int))); } DlgContentFetchSettingWidget::~DlgContentFetchSettingWidget() { } void DlgContentFetchSettingWidget::slotNewScript() { QPointer dialog = new DlgScriptEditing(this); if (dialog->exec()) { addScriptItem(true, dialog->scriptPath(), dialog->scriptUrlRegexp(), dialog->scriptDescription()); } changed(); } void DlgContentFetchSettingWidget::slotEditScript() { QList selectedItems = ui.scriptTreeWidget->selectedItems(); // only edit one item at one time if (selectedItems.size()!=1) { return; } QTreeWidgetItem &item = *(selectedItems[0]); QPointer dialog = new DlgScriptEditing(this, (QStringList() << item.toolTip(0) << item.text(1) << item.text(2))); if (dialog->exec()) { if (item.toolTip(0) != dialog->scriptPath()) { item.setText(0, QFileInfo(dialog->scriptPath()).fileName()); item.setToolTip(0, dialog->scriptPath()); changed(); } if (item.text(1) != dialog->scriptUrlRegexp()) { item.setText(1, dialog->scriptUrlRegexp()); changed(); } if (item.text(2) != dialog->scriptDescription()) { item.setText(2, dialog->scriptDescription()); changed(); } } } void DlgContentFetchSettingWidget::slotConfigureScript() { QList selectedItems = ui.scriptTreeWidget->selectedItems(); // only configure one item at one time if (selectedItems.size()!=1) { return; } QString filename = selectedItems[0]->toolTip(0); if (m_p_action) { delete m_p_action; } m_p_action = new Kross::Action(this, QString("%1_ContentFetchConfig").arg(filename)); // TODO add check file m_p_action->setFile(filename); m_p_action->addObject(this, "kgetscriptconfig", Kross::ChildrenInterface::AutoConnectSignals); m_p_action->trigger(); - KDialog *dialog = new KDialog(this); + QDialog *dialog = new QDialog(this); dialog->setObjectName("configure_script"); - dialog->setCaption(i18nc("Configure script", "Configure script")); - dialog->enableButtonOk(false); + dialog->setWindowTitle(i18nc("Configure script", "Configure script")); + dialog->okButton->setEnabled(false); dialog->setModal(true); SettingWidgetAdaptor *widget = new SettingWidgetAdaptor(dialog); ScriptConfigAdaptor config; emit configureScript(widget,&config); if (widget->findChild()) { - dialog->enableButtonOk(true); + dialog->okButton->setEnabled(true); } - dialog->setMainWidget(widget); - dialog->showButtonSeparator(true); + QVBoxLayout *mainLayout = new QVBoxLayout; + dialog->setLayout(mainLayout); + mainLayout->addWidget(widget); // dirty hack, add the ok/canel button size manually dialog->resize(widget->size()+QSize(0,30)); dialog->show(); if (dialog->exec() == QDialog::Accepted) { emit configurationAccepted(widget, &config); } dialog->deleteLater(); } void DlgContentFetchSettingWidget::slotRemoveScript() { QList selectedItems = ui.scriptTreeWidget->selectedItems(); foreach(QTreeWidgetItem * selectedItem, selectedItems) delete(selectedItem); changed(); } void DlgContentFetchSettingWidget::addScriptItem(bool enabled, const QString &path, const QString ®exp, const QString &description) { QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << QFileInfo(path).fileName() << regexp << description); item->setToolTip(0, path); item->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked); ui.scriptTreeWidget->addTopLevelItem(item); } void DlgContentFetchSettingWidget::loadContentFetchSetting() { ui.scriptTreeWidget->clear();//Cleanup things first QStringList paths = ContentFetchSetting::self()->pathList(); QStringList regexps = ContentFetchSetting::self()->urlRegexpList(); QStringList descriptions = ContentFetchSetting::self()->descriptionList(); QList enables = ContentFetchSetting::self()->enableList(); // TODO: add some safety check to avoid crashing when user rc got corrputed. for (int i = 0; i < paths.size(); ++i) { addScriptItem(bool(enables[i]), paths[i], regexps[i], descriptions[i]); } } void DlgContentFetchSettingWidget::saveContentFetchSetting() { qCDebug(KGET_DEBUG); QStringList paths; QStringList regexps; QStringList descriptions; QList enables; for (int i = 0; i < ui.scriptTreeWidget->topLevelItemCount(); ++i) { paths.append(ui.scriptTreeWidget->topLevelItem(i)->toolTip(0)); regexps.append(ui.scriptTreeWidget->topLevelItem(i)->text(1)); descriptions.append(ui.scriptTreeWidget->topLevelItem(i)->text(2)); if (ui.scriptTreeWidget->topLevelItem(i)->checkState(0) == Qt::Unchecked) { enables.append(0); } else { enables.append(1); } } ContentFetchSetting::self()->setPathList(paths); ContentFetchSetting::self()->setUrlRegexpList(regexps); ContentFetchSetting::self()->setDescriptionList(descriptions); ContentFetchSetting::self()->setEnableList(enables); ContentFetchSetting::self()->save(); } void DlgContentFetchSettingWidget::save() { saveContentFetchSetting(); // NOTICE: clean the last config script, might change in the furture if (m_p_action) { delete m_p_action; m_p_action = nullptr; } } void DlgContentFetchSettingWidget::load() { // clean the last config script if (m_p_action) { delete m_p_action; m_p_action = nullptr; } // this class is never destroyed, so reload the rc file into ui to sync loadContentFetchSetting(); } void DlgContentFetchSettingWidget::slotCheckConfigurable(QTreeWidgetItem *p_item, int column ) { if (column == -1) { return; } QString filename = p_item->toolTip(0); Kross::Action action(this, QString("%1_CheckConfig").arg(filename)); // TODO add check file action.setFile(filename); action.trigger(); if (action.functionNames().contains("configureScript")) { ui.configureScriptButton->setEnabled(true); } else { ui.configureScriptButton->setEnabled(false); } } void DlgContentFetchSettingWidget::slotEnableChanged(QTreeWidgetItem* p_item, int column) { Q_UNUSED(p_item) if (column != 0) { return; } changed(); } diff --git a/transfer-plugins/contentfetch/dlgscriptediting.cpp b/transfer-plugins/contentfetch/dlgscriptediting.cpp index 41ad60bf..d4a5feda 100644 --- a/transfer-plugins/contentfetch/dlgscriptediting.cpp +++ b/transfer-plugins/contentfetch/dlgscriptediting.cpp @@ -1,91 +1,108 @@ /* This file is part of the KDE project Copyright (C) 2008 Ningyu Shi 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 2 of the License, or (at your option) any later version. */ #include "dlgscriptediting.h" #include "contentfetchsetting.h" #include #include #include +#include +#include +#include +#include DlgScriptEditing::DlgScriptEditing(QWidget *p_parent) - : KDialog(p_parent) + : QDialog(p_parent) { QWidget *mainWidget = new QWidget(this); ui.setupUi(mainWidget); - setMainWidget(mainWidget); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); setWindowTitle(i18n("Add New Script")); init(); } DlgScriptEditing::DlgScriptEditing(QWidget *p_parent, const QStringList &script) - : KDialog(p_parent) + : QDialog(p_parent) { QWidget *mainWidget = new QWidget(this); ui.setupUi(mainWidget); - setMainWidget(mainWidget); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); setWindowTitle(i18n("Edit Script")); ui.scriptPathRequester->setUrl(QUrl::fromLocalFile(script[0])); ui.scriptUrlRegexpEdit->setText(script[1]); ui.scriptDescriptionEdit->setText(script[2]); init(); } void DlgScriptEditing::init() { ui.scriptPathRequester->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly); - ui.scriptPathRequester->fileDialog()->setCaption(i18n("Set Script File")); + ui.scriptPathRequester->fileDialog()->setWindowTitle(i18n("Set Script File")); QStringList filter; foreach(Kross::InterpreterInfo* info, Kross::Manager::self().interpreterInfos()) filter << info->mimeTypes().join(" "); ui.scriptPathRequester->setFilter(filter.join(" ")); setModal(true); - setButtons(KDialog::Ok | KDialog::Cancel); - showButtonSeparator(true); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); + QWidget *mainWidget = new QWidget(this); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); + okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgScriptEditing::accept); + connect(buttonBox, &QSIGNAL(rejected()), this, &DlgScriptEditing::reject); + mainLayout->addWidget(buttonBox); connect(ui.scriptPathRequester,SIGNAL(textChanged(QString)), this, SLOT(slotChangeText())); connect(ui.scriptUrlRegexpEdit,SIGNAL(textChanged(QString)), this, SLOT(slotChangeText())); connect(ui.scriptDescriptionEdit,SIGNAL(textChanged(QString)), this, SLOT(slotChangeText())); } DlgScriptEditing::~DlgScriptEditing() { } void DlgScriptEditing::slotChangeText() { - enableButton(KDialog::Ok, !(ui.scriptPathRequester->url().isEmpty() || + okButton->setEnabled(!(ui.scriptPathRequester->url().isEmpty() || ui.scriptUrlRegexpEdit->text().isEmpty())); } QString DlgScriptEditing::scriptPath() const { return ui.scriptPathRequester->url().toLocalFile(); } QString DlgScriptEditing::scriptUrlRegexp() const { return ui.scriptUrlRegexpEdit->text(); } QString DlgScriptEditing::scriptDescription() const { return ui.scriptDescriptionEdit->text(); } diff --git a/transfer-plugins/contentfetch/dlgscriptediting.h b/transfer-plugins/contentfetch/dlgscriptediting.h index d5c8d460..c2cb4fac 100644 --- a/transfer-plugins/contentfetch/dlgscriptediting.h +++ b/transfer-plugins/contentfetch/dlgscriptediting.h @@ -1,36 +1,37 @@ /* This file is part of the KDE project Copyright (C) 2008 Ningyu Shi 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 2 of the License, or (at your option) any later version. */ #ifndef DLG_SCRIPT_EDITING_H #define DLG_SCRIPT_EDITING_H #include "ui_dlgscriptediting.h" #include -class DlgScriptEditing : public KDialog +class DlgScriptEditing : public QDialog { Q_OBJECT public: DlgScriptEditing(QWidget *p_parent); DlgScriptEditing(QWidget *p_parent, const QStringList &script); ~DlgScriptEditing(); void init(); QString scriptPath() const; QString scriptUrlRegexp() const; QString scriptDescription() const; private slots: void slotChangeText(); private: Ui::DlgScriptEditing ui; + QPushButton *okButton; }; #endif // DLG_SCRIPT_EDITING_H diff --git a/transfer-plugins/metalink/abstractmetalink.cpp b/transfer-plugins/metalink/abstractmetalink.cpp index 922fd38a..459d5e01 100644 --- a/transfer-plugins/metalink/abstractmetalink.cpp +++ b/transfer-plugins/metalink/abstractmetalink.cpp @@ -1,552 +1,551 @@ /* This file is part of the KDE project Copyright (C) 2004 Dario Massarin Copyright (C) 2007 Manolo Valdes Copyright (C) 2009 Matthias Fuchs Copyright (C) 2012 Aish Raj Dahal 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 2 of the License, or (at your option) any later version. */ #include "abstractmetalink.h" #include "core/kget.h" #include "core/transfergroup.h" #include "core/download.h" #include "core/transferdatasource.h" #include "core/filemodel.h" #include "core/urlchecker.h" #include "core/verifier.h" #include "core/signature.h" #include "kget_debug.h" #include #include #include #include #include #include -#include - +#include #include #include AbstractMetalink::AbstractMetalink(TransferGroup * parent, TransferFactory * factory, Scheduler * scheduler, const QUrl & source, const QUrl & dest, const QDomElement * e) : Transfer(parent, factory, scheduler, source, dest, e), m_fileModel(nullptr), m_currentFiles(), m_ready(false), m_speedCount(0), m_tempAverageSpeed(0), m_averageSpeed(0) { } AbstractMetalink::~AbstractMetalink() { } void AbstractMetalink::slotDataSourceFactoryChange(Transfer::ChangesFlags change) { if ((change & Tc_Status) | (change & Tc_TotalSize)) { DataSourceFactory *factory = qobject_cast(sender()); if (change & Tc_Status) { bool changeStatus; updateStatus(factory, &changeStatus); if (!changeStatus) { change &= ~Tc_Status; } } if (change & Tc_TotalSize) { recalculateTotalSize(factory); } } if (change & Tc_DownloadedSize) { recalculateProcessedSize(); change |= Tc_Percent; } if (change & Tc_DownloadSpeed) { recalculateSpeed(); } setTransferChange(change, true); } void AbstractMetalink::recalculateTotalSize(DataSourceFactory *sender) { m_totalSize = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_totalSize += factory->size(); } } if (m_fileModel) { if (sender) { QModelIndex sizeIndex = m_fileModel->index(sender->dest(), FileItem::Size); m_fileModel->setData(sizeIndex, static_cast(sender->size())); } } } void AbstractMetalink::recalculateProcessedSize() { m_downloadedSize = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_downloadedSize += factory->downloadedSize(); } } if (m_totalSize) { m_percent = (m_downloadedSize * 100) / m_totalSize; } else { m_percent = 0; } } void AbstractMetalink::recalculateSpeed() { m_downloadSpeed = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_downloadSpeed += factory->currentSpeed(); } } //calculate the average of the last three speeds m_tempAverageSpeed += m_downloadSpeed; ++m_speedCount; if (m_speedCount == 3) { m_averageSpeed = m_tempAverageSpeed / 3; m_speedCount = 0; m_tempAverageSpeed = 0; } } int AbstractMetalink::remainingTime() const { if (!m_averageSpeed) { m_averageSpeed = m_downloadSpeed; } return KIO::calculateRemainingSeconds(m_totalSize, m_downloadedSize, m_averageSpeed); } void AbstractMetalink::updateStatus(DataSourceFactory *sender, bool *changeStatus) { Job::Status status = (sender ? sender->status() : Job::Stopped); *changeStatus = true; switch (status) { case Job::Aborted: case Job::Stopped: { m_currentFiles = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { //one factory is still running, do not change the status if (factory->doDownload() && (factory->status() == Job::Running)) { *changeStatus = false; ++m_currentFiles; } } if (*changeStatus) { setStatus(status); } break; } case Job::Finished: //one file that has been downloaded now is finished//FIXME ignore downloads that were finished in the previous download!!!! if (m_currentFiles) { --m_currentFiles; startMetalink(); } foreach (DataSourceFactory *factory, m_dataSourceFactory) { //one factory is not finished, do not change the status if (factory->doDownload() && (factory->status() != Job::Finished)) { *changeStatus = false; break; } } if (*changeStatus) { setStatus(Job::Finished); } break; default: setStatus(status); break; } if (m_fileModel) { if (sender) { QModelIndex statusIndex = m_fileModel->index(sender->dest(), FileItem::Status); m_fileModel->setData(statusIndex, status); } } } void AbstractMetalink::slotVerified(bool isVerified) { Q_UNUSED(isVerified) if (status() == Job::Finished) { //see if some files are NotVerified QStringList brokenFiles; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (m_fileModel) { QModelIndex checksumVerified = m_fileModel->index(factory->dest(), FileItem::ChecksumVerified); m_fileModel->setData(checksumVerified, factory->verifier()->status()); } if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { brokenFiles.append(factory->dest().toString()); } } if (brokenFiles.count()) { if (KMessageBox::warningYesNoCancelList(nullptr, i18n("The download could not be verified, do you want to repair (if repairing does not work the download would be restarted) it?"), brokenFiles) == KMessageBox::Yes) { if (repair()) { return; } } } } } void AbstractMetalink::slotSignatureVerified() { if (status() == Job::Finished) { //see if some files are NotVerified QStringList brokenFiles; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (m_fileModel) { QModelIndex signatureVerified = m_fileModel->index(factory->dest(), FileItem::SignatureVerified); m_fileModel->setData(signatureVerified, factory->signature()->status()); } if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { brokenFiles.append(factory->dest().toString()); } } /* if (brokenFiles.count())//TODO { if (KMessageBox::warningYesNoCancelList(0, i18n("The download could not be verified, try to repair it?"), brokenFiles) == KMessageBox::Yes) { if (repair()) { return; } } }*/ } } bool AbstractMetalink::repair(const QUrl &file) { if (file.isValid()) { if (m_dataSourceFactory.contains(file)) { DataSourceFactory *broken = m_dataSourceFactory[file]; if (broken->verifier()->status() == Verifier::NotVerified) { broken->repair(); return true; } } } else { QList broken; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { broken.append(factory); } } if (broken.count()) { foreach (DataSourceFactory *factory, broken) { factory->repair(); } return true; } } return false; } Verifier *AbstractMetalink::verifier(const QUrl &file) { if (!m_dataSourceFactory.contains(file)) { return 0; } return m_dataSourceFactory[file]->verifier(); } Signature *AbstractMetalink::signature(const QUrl &file) { if (!m_dataSourceFactory.contains(file)) { return 0; } return m_dataSourceFactory[file]->signature(); } QList AbstractMetalink::files() const { return m_dataSourceFactory.keys(); } FileModel *AbstractMetalink::fileModel() { if (!m_fileModel) { m_fileModel = new FileModel(files(), directory(), this); connect(m_fileModel, SIGNAL(rename(QUrl,QUrl)), this, SLOT(slotRename(QUrl,QUrl))); connect(m_fileModel, SIGNAL(checkStateChanged()), this, SLOT(filesSelected())); foreach (DataSourceFactory *factory, m_dataSourceFactory) { const QUrl dest = factory->dest(); QModelIndex size = m_fileModel->index(dest, FileItem::Size); m_fileModel->setData(size, static_cast(factory->size())); QModelIndex status = m_fileModel->index(dest, FileItem::Status); m_fileModel->setData(status, factory->status()); QModelIndex checksumVerified = m_fileModel->index(dest, FileItem::ChecksumVerified); m_fileModel->setData(checksumVerified, factory->verifier()->status()); QModelIndex signatureVerified = m_fileModel->index(dest, FileItem::SignatureVerified); m_fileModel->setData(signatureVerified, factory->signature()->status()); if (!factory->doDownload()) { QModelIndex index = m_fileModel->index(factory->dest(), FileItem::File); m_fileModel->setData(index, Qt::Unchecked, Qt::CheckStateRole); } } } return m_fileModel; } void AbstractMetalink::slotRename(const QUrl &oldUrl, const QUrl &newUrl) { if (!m_dataSourceFactory.contains(oldUrl)) { return; } m_dataSourceFactory[newUrl] = m_dataSourceFactory[oldUrl]; m_dataSourceFactory.remove(oldUrl); m_dataSourceFactory[newUrl]->setNewDestination(newUrl); setTransferChange(Tc_FileName); } bool AbstractMetalink::setDirectory(const QUrl &new_directory) { if (new_directory == directory()) { return false; } if (m_fileModel) { m_fileModel->setDirectory(new_directory); } const QString oldDirectory = directory().toString(); const QString newDirectory = new_directory.toString(); const QString fileName = m_dest.fileName(); m_dest = new_directory; m_dest.setPath(m_dest.adjusted(QUrl::RemoveFilename).toString() + fileName); QHash newStorage; foreach (DataSourceFactory *factory, m_dataSourceFactory) { const QUrl oldUrl = factory->dest(); const QUrl newUrl = QUrl(oldUrl.toString().replace(oldDirectory, newDirectory)); factory->setNewDestination(newUrl); newStorage[newUrl] = factory; } m_dataSourceFactory = newStorage; setTransferChange(Tc_FileName); return true; } QHash > AbstractMetalink::availableMirrors(const QUrl &file) const { QHash > urls; if (m_dataSourceFactory.contains(file)) { urls = m_dataSourceFactory[file]->mirrors(); } return urls; } void AbstractMetalink::setAvailableMirrors(const QUrl &file, const QHash > &mirrors) { if (!m_dataSourceFactory.contains(file)) { return; } m_dataSourceFactory[file]->setMirrors(mirrors); } void AbstractMetalink::slotUpdateCapabilities() { Capabilities oldCap = capabilities(); Capabilities newCap = 0; foreach (DataSourceFactory *file, m_dataSourceFactory) { if (file->doDownload()) {//FIXME when a download did not start yet it should be moveable!!//FIXME why not working, when only two connections? if (newCap) { newCap &= file->capabilities(); } else { newCap = file->capabilities(); } } } if (newCap != oldCap) { setCapabilities(newCap); } } void AbstractMetalink::untickAllFiles() { for (int row = 0; row < fileModel()->rowCount(); ++row) { QModelIndex index = fileModel()->index(row, FileItem::File); if (index.isValid()) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); } } } void AbstractMetalink::fileDlgFinished(int result) { //the dialog was not accepted untick every file, this ensures that the user does not //press start by accident without first selecting the desired files if (result != QDialog::Accepted) { untickAllFiles(); } filesSelected(); //no files selected to download or dialog rejected, stop the download if (!m_numFilesSelected || (result != QDialog::Accepted)) { setStatus(Job::Stopped); setTransferChange(Tc_Status, true); return; } startMetalink(); } void AbstractMetalink::filesSelected() { bool overwriteAll = false; bool autoSkip = false; bool cancel = false; QModelIndexList files = fileModel()->fileIndexes(FileItem::File); m_numFilesSelected = 0; //sets the CheckState of the fileModel to the according DataSourceFactories //and asks the user if there are existing files already foreach (const QModelIndex &index, files) { const QUrl dest = fileModel()->getUrl(index); bool doDownload = index.data(Qt::CheckStateRole).toBool(); if (m_dataSourceFactory.contains(dest)) { DataSourceFactory *factory = m_dataSourceFactory[dest]; //ignore finished transfers if ((factory->status() == Job::Finished) || (factory->status() == Job::FinishedKeepAlive)) { continue; } //check if the file at dest exists already and ask the user what to do in this case, ignore already running transfers if (doDownload && (factory->status() != Job::Running) && QFile::exists(dest.toLocalFile())) { //user has chosen to skip all files that exist already before if (autoSkip) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; //ask the user, unless he has chosen overwriteAll before } else if (!overwriteAll) { KIO::RenameDialog dlg(0, i18n("File already exists"), index.data().toString(), dest, KIO::RenameDialog_Options(KIO::RenameDialog_MultipleItems | KIO::RenameDialog_Overwrite | KIO::RenameDialog_Skip)); const int result = dlg.exec(); if (result == KIO::R_RENAME) { //no reason to use FileModel::rename() since the file does not exist yet, so simply skip it //avoids having to deal with signals const QUrl newDest = dlg.newDestUrl(); factory->setDoDownload(doDownload); factory->setNewDestination(newDest); fileModel()->setData(index, newDest.fileName(), FileItem::File); ++m_numFilesSelected; m_dataSourceFactory.remove(dest); m_dataSourceFactory[newDest] = factory; continue; } else if (result == KIO::R_SKIP) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; } else if (result == KIO::R_CANCEL) { cancel = true; break; } else if (result == KIO::R_AUTO_SKIP) { autoSkip = true; fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; } else if (result == KIO::R_OVERWRITE_ALL) { overwriteAll = true; } } } factory->setDoDownload(doDownload); if (doDownload && (factory->status() != Finished) && (factory->status() != FinishedKeepAlive)) { ++m_numFilesSelected; } } } //the user decided to cancel, so untick all files if (cancel) { m_numFilesSelected = 0; untickAllFiles(); foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->setDoDownload(false); } } Transfer::ChangesFlags change = (Tc_TotalSize | Tc_DownloadSpeed); //some files have been selected that are not finished yet, set them to stop if the transfer is not running (checked in slotStatus) if (m_numFilesSelected) { change |= Tc_Status; } slotDataSourceFactoryChange(change); } void AbstractMetalink::stop() { qCDebug(KGET_DEBUG) << "metalink::Stop"; if (m_ready && ((status() != Stopped) || (status() != Finished))) { m_currentFiles = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->stop(); } } } diff --git a/transfer-plugins/metalink/fileselectiondlg.cpp b/transfer-plugins/metalink/fileselectiondlg.cpp index 12f715ba..9f747177 100644 --- a/transfer-plugins/metalink/fileselectiondlg.cpp +++ b/transfer-plugins/metalink/fileselectiondlg.cpp @@ -1,44 +1,56 @@ /*************************************************************************** * Copyright (C) 2010 Matthias Fuchs * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "fileselectiondlg.h" #include "../../core/filemodel.h" #include #include +#include +#include +#include +#include FileSelectionDlg::FileSelectionDlg(FileModel *model, QWidget *parent) - : KDialog(parent) + : QDialog(parent) { - setCaption(i18n("File Selection")); + setWindowTitle(i18n("File Selection")); QWidget *widget = new QWidget(this); ui.setupUi(widget); - setMainWidget(widget); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(widget); QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); proxy->setSourceModel(model); ui.treeView->setModel(proxy); ui.treeView->sortByColumn(0, Qt::AscendingOrder); ui.treeView->hideColumn(FileItem::Status); ui.treeView->hideColumn(FileItem::ChecksumVerified); ui.treeView->hideColumn(FileItem::SignatureVerified); - setButtons(KDialog::Ok | KDialog::Cancel); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); + QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &FileSelectionDlg::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &FileSelectionDlg::reject); + mainLayout->addWidget(buttonBox); } diff --git a/transfer-plugins/metalink/fileselectiondlg.h b/transfer-plugins/metalink/fileselectiondlg.h index e21246f6..98fab6fc 100644 --- a/transfer-plugins/metalink/fileselectiondlg.h +++ b/transfer-plugins/metalink/fileselectiondlg.h @@ -1,40 +1,40 @@ /*************************************************************************** * Copyright (C) 2010 Matthias Fuchs * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #ifndef FILESELECTIONDLG_H #define FILESELECTIONDLG_H -#include +#include #include "ui_fileselection.h" class FileModel; -class FileSelectionDlg : public KDialog +class FileSelectionDlg : public QDialog { Q_OBJECT public: FileSelectionDlg(FileModel *model, QWidget *parent = nullptr); private: Ui::FileSelection ui; }; #endif diff --git a/transfer-plugins/metalink/metalink.cpp b/transfer-plugins/metalink/metalink.cpp index 68cc5476..981124b3 100644 --- a/transfer-plugins/metalink/metalink.cpp +++ b/transfer-plugins/metalink/metalink.cpp @@ -1,853 +1,854 @@ /* This file is part of the KDE project Copyright (C) 2004 Dario Massarin Copyright (C) 2007 Manolo Valdes Copyright (C) 2009 Matthias Fuchs 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 2 of the License, or (at your option) any later version. */ #include "metalink.h" #include "fileselectiondlg.h" #include "metalinksettings.h" #include "core/kget.h" #include "core/transfergroup.h" #include "core/download.h" #include "core/transferdatasource.h" #include "core/filemodel.h" #include "core/urlchecker.h" #include "core/verifier.h" #include "core/signature.h" #include #include #include #include #include #include #include -#include +#include #include #include #include +#include Metalink::Metalink(TransferGroup * parent, TransferFactory * factory, Scheduler * scheduler, const QUrl & source, const QUrl & dest, const QDomElement * e) : Transfer(parent, factory, scheduler, source, dest, e), m_fileModel(nullptr), m_currentFiles(0), m_metalinkJustDownloaded(false), m_ready(false), m_speedCount(0), m_tempAverageSpeed(0), m_averageSpeed(0) { } Metalink::~Metalink() { } void Metalink::start() { qCDebug(KGET_DEBUG) << "metalink::start"; if (!m_ready) { if (m_localMetalinkLocation.isValid() && metalinkInit()) { startMetalink(); } else { downloadMetalink(); } } else { startMetalink(); } } void Metalink::downloadMetalink() { m_metalinkJustDownloaded = true; setStatus(Job::Stopped, i18n("Downloading Metalink File...."), SmallIcon("document-save")); setTransferChange(Tc_Status, true); Download *download = new Download(m_source, QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/metalinks/") + m_source.fileName()); connect(download, SIGNAL(finishedSuccessfully(QUrl,QByteArray)), SLOT(metalinkInit(QUrl,QByteArray))); } bool Metalink::metalinkInit(const QUrl &src, const QByteArray &data) { qCDebug(KGET_DEBUG); if (!src.isEmpty()) { m_localMetalinkLocation = src; } //use the downloaded metalink-file data directly if possible if (!data.isEmpty()) { KGetMetalink::HandleMetalink::load(data, &m_metalink); } //try to parse the locally stored metalink-file if (!m_metalink.isValid() && m_localMetalinkLocation.isValid()) { KGetMetalink::HandleMetalink::load(m_localMetalinkLocation.toLocalFile(), &m_metalink); } if (!m_metalink.isValid()) { qCCritical(KGET_DEBUG) << "Unknown error when trying to load the .metalink-file. Metalink is not valid."; setStatus(Job::Aborted); setTransferChange(Tc_Status, true); return false; } //offers a dialog to download the newest version of a dynamic metalink if ((m_source.isLocalFile() || !m_metalinkJustDownloaded) && m_metalink.dynamic && (UrlChecker::checkSource(m_metalink.origin) == UrlChecker::NoError)) { if (KMessageBox::questionYesNo(nullptr, i18n("A newer version of this Metalink might exist, do you want to download it?"), i18n("Redownload Metalink")) == KMessageBox::Yes) { m_localMetalinkLocation.clear(); m_source = m_metalink.origin; downloadMetalink(); return false; } } QList::const_iterator it; QList::const_iterator itEnd = m_metalink.files.files.constEnd(); m_totalSize = 0; KIO::fileoffset_t segSize = 500 * 1024;//TODO use config here! const QUrl tempDest = QUrl(m_dest.directory()); QUrl dest; for (it = m_metalink.files.files.constBegin(); it != itEnd ; ++it) { dest = tempDest; dest.addPath((*it).name); QList urlList = (*it).resources.urls; //sort the urls according to their priority (highest first) qSort(urlList.begin(), urlList.end(), qGreater()); KIO::filesize_t fileSize = (*it).size; m_totalSize += fileSize; //create a DataSourceFactory for each separate file DataSourceFactory *dataFactory = new DataSourceFactory(this, dest, fileSize, segSize); dataFactory->setMaxMirrorsUsed(MetalinkSettings::mirrorsPerFile()); //TODO compare available file size () with the sizes of the server while downloading? connect(dataFactory, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(dataFactory, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); connect(dataFactory->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(dataFactory->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(dataFactory, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); //add the DataSources for (int i = 0; i < urlList.size(); ++i) { const QUrl url = urlList[i].url; if (url.isValid()) { dataFactory->addMirror(url, MetalinkSettings::connectionsPerUrl()); } } //no datasource has been created, so remove the datasource factory if (dataFactory->mirrors().isEmpty()) { delete dataFactory; } else { dataFactory->verifier()->addChecksums((*it).verification.hashes); foreach (const KGetMetalink::Pieces &pieces, (*it).verification.pieces) { dataFactory->verifier()->addPartialChecksums(pieces.type, pieces.length, pieces.hashes); } const QHash signatures = (*it).verification.signatures; QHash::const_iterator it; QHash::const_iterator itEnd = signatures.constEnd(); for (it = signatures.constBegin(); it != itEnd; ++it) { if (it.key().toLower() == "pgp") { dataFactory->signature()->setAsciiDetatchedSignature(*it); } } m_dataSourceFactory[dataFactory->dest()] = dataFactory; } } if ((m_metalink.files.files.size() == 1) && m_dataSourceFactory.size()) { m_dest = dest; } if (!m_dataSourceFactory.size()) { //TODO make this via log in the future + do not display the KMessageBox qCWarning(KGET_DEBUG) << "Download of" << m_source << "failed, no working URLs were found."; KMessageBox::error(nullptr, i18n("Download failed, no working URLs were found."), i18n("Error")); setStatus(Job::Aborted); setTransferChange(Tc_Status, true); return false; } m_ready = !m_dataSourceFactory.isEmpty(); slotUpdateCapabilities(); //the metalink-file has just been downloaded, so ask the user to choose the files that // should be downloaded if (m_metalinkJustDownloaded) { - KDialog *dialog = new FileSelectionDlg(fileModel()); + QDialog *dialog = new FileSelectionDlg(fileModel()); dialog->setAttribute(Qt::WA_DeleteOnClose); connect(dialog, SIGNAL(finished(int)), this, SLOT(fileDlgFinished(int))); dialog->show(); } return true; } void Metalink::untickAllFiles() { for (int row = 0; row < fileModel()->rowCount(); ++row) { QModelIndex index = fileModel()->index(row, FileItem::File); if (index.isValid()) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); } } } void Metalink::fileDlgFinished(int result) { //the dialog was not accepted untick every file, this ensures that the user does not //press start by accident without first selecting the desired files if (result != QDialog::Accepted) { untickAllFiles(); } filesSelected(); //no files selected to download or dialog rejected, stop the download if (!m_numFilesSelected || (result != QDialog::Accepted)) { setStatus(Job::Stopped); setTransferChange(Tc_Status, true); return; } startMetalink(); } void Metalink::startMetalink() { if (m_ready) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { //specified number of files is downloaded simultanously if (m_currentFiles < MetalinkSettings::simultanousFiles()) { const int status = factory->status(); //only start factories that should be downloaded if (factory->doDownload() && (status != Job::Finished) && (status != Job::FinishedKeepAlive) && (status != Job::Running)) { ++m_currentFiles; factory->start(); } } else { break; } } } } void Metalink::deinit(Transfer::DeleteOptions options) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (options & Transfer::DeleteFiles) { factory->deinit(); } }//TODO: Ask the user if he/she wants to delete the *.part-file? To discuss (boom1992) //FIXME does that mean, that the metalink file is always removed, even if //downloaded by the user? if ((options & Transfer::DeleteTemporaryFiles) && m_localMetalinkLocation.isLocalFile()) { KIO::Job *del = KIO::del(m_localMetalinkLocation, KIO::HideProgressInfo); KIO::NetAccess::synchronousRun(del, nullptr); } } void Metalink::stop() { qCDebug(KGET_DEBUG) << "metalink::Stop"; if (m_ready && status() != Stopped) { m_currentFiles = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->stop(); } } } void Metalink::slotDataSourceFactoryChange(Transfer::ChangesFlags change) { if ((change & Tc_Status) | (change & Tc_TotalSize)) { DataSourceFactory *factory = qobject_cast(sender()); if (change & Tc_Status) { bool changeStatus; updateStatus(factory, &changeStatus); if (!changeStatus) { change &= ~Tc_Status; } } if (change & Tc_TotalSize) { recalculateTotalSize(factory); } } if (change & Tc_DownloadedSize) { recalculateProcessedSize(); change |= Tc_Percent; } if (change & Tc_DownloadSpeed) { recalculateSpeed(); } setTransferChange(change, true); } void Metalink::recalculateTotalSize(DataSourceFactory *sender) { m_totalSize = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_totalSize += factory->size(); } } if (m_fileModel) { if (sender) { QModelIndex sizeIndex = m_fileModel->index(sender->dest(), FileItem::Size); m_fileModel->setData(sizeIndex, static_cast(sender->size())); } } } void Metalink::recalculateProcessedSize() { m_downloadedSize = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_downloadedSize += factory->downloadedSize(); } } if (m_totalSize) { m_percent = (m_downloadedSize * 100) / m_totalSize; } else { m_percent = 0; } } void Metalink::recalculateSpeed() { m_downloadSpeed = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload()) { m_downloadSpeed += factory->currentSpeed(); } } //calculate the average of the last three speeds m_tempAverageSpeed += m_downloadSpeed; ++m_speedCount; if (m_speedCount == 3) { m_averageSpeed = m_tempAverageSpeed / 3; m_speedCount = 0; m_tempAverageSpeed = 0; } } int Metalink::remainingTime() const { if (!m_averageSpeed) { m_averageSpeed = m_downloadSpeed; } return KIO::calculateRemainingSeconds(m_totalSize, m_downloadedSize, m_averageSpeed); } void Metalink::updateStatus(DataSourceFactory *sender, bool *changeStatus) { Job::Status status = (sender ? sender->status() : Job::Stopped); *changeStatus = true; switch (status) { case Job::Aborted: case Job::Stopped: { m_currentFiles = 0; foreach (DataSourceFactory *factory, m_dataSourceFactory) { //one factory is still running, do not change the status if (factory->doDownload() && (factory->status() == Job::Running)) { *changeStatus = false; ++m_currentFiles; } } if (*changeStatus) { setStatus(status); } break; } case Job::Finished: //one file that has been downloaded now is finished//FIXME ignore downloads that were finished in the previous download!!!! if (m_currentFiles) { --m_currentFiles; startMetalink(); } foreach (DataSourceFactory *factory, m_dataSourceFactory) { //one factory is not finished, do not change the status if (factory->doDownload() && (factory->status() != Job::Finished)) { *changeStatus = false; break; } } if (*changeStatus) { setStatus(Job::Finished); } break; default: setStatus(status); break; } if (m_fileModel) { if (sender) { QModelIndex statusIndex = m_fileModel->index(sender->dest(), FileItem::Status); m_fileModel->setData(statusIndex, status); } } } void Metalink::slotVerified(bool isVerified) { Q_UNUSED(isVerified) if (status() == Job::Finished) { //see if some files are NotVerified QStringList brokenFiles; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (m_fileModel) { QModelIndex checksumVerified = m_fileModel->index(factory->dest(), FileItem::ChecksumVerified); m_fileModel->setData(checksumVerified, factory->verifier()->status()); } if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { brokenFiles.append(factory->dest().pathOrUrl()); } } if (brokenFiles.count()) { if (KMessageBox::warningYesNoCancelList(nullptr, i18n("The download could not be verified, do you want to repair (if repairing does not work the download would be restarted) it?"), brokenFiles) == KMessageBox::Yes) { if (repair()) { return; } } } } } void Metalink::slotSignatureVerified() { if (status() == Job::Finished) { //see if some files are NotVerified QStringList brokenFiles; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (m_fileModel) { QModelIndex signatureVerified = m_fileModel->index(factory->dest(), FileItem::SignatureVerified); m_fileModel->setData(signatureVerified, factory->signature()->status()); } if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { brokenFiles.append(factory->dest().pathOrUrl()); } } /* if (brokenFiles.count())//TODO { if (KMessageBox::warningYesNoCancelList(nullptr, i18n("The download could not be verified, try to repair it?"), brokenFiles) == KMessageBox::Yes) { if (repair()) { return; } } }*/ } } bool Metalink::repair(const QUrl &file) { if (file.isValid()) { if (m_dataSourceFactory.contains(file)) { DataSourceFactory *broken = m_dataSourceFactory[file]; if (broken->verifier()->status() == Verifier::NotVerified) { broken->repair(); return true; } } } else { QList broken; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { broken.append(factory); } } if (broken.count()) { foreach (DataSourceFactory *factory, broken) { factory->repair(); } return true; } } return false; } void Metalink::load(const QDomElement *element) { Transfer::load(element); if (!element) { return; } const QDomElement e = *element; m_localMetalinkLocation = QUrl(e.attribute("LocalMetalinkLocation")); QDomNodeList factories = e.firstChildElement("factories").elementsByTagName("factory"); //no stored information found, stop right here if (!factories.count()) { return; } while (factories.count()) { QDomDocument doc; QDomElement factory = doc.createElement("factories"); factory.appendChild(factories.item(0).toElement()); doc.appendChild(factory); DataSourceFactory *file = new DataSourceFactory(this); file->load(&factory); connect(file, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(file, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); m_dataSourceFactory[file->dest()] = file; connect(file->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(file->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(file, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); //start the DataSourceFactories that were Started when KGet was closed if (file->status() == Job::Running) { if (m_currentFiles < MetalinkSettings::simultanousFiles()) { ++m_currentFiles; file->start(); } else { //enough simultanous files already, so increase the number and set file to stop --> that will decrease the number again file->stop(); } } } m_ready = !m_dataSourceFactory.isEmpty(); slotUpdateCapabilities(); } void Metalink::save(const QDomElement &element) { Transfer::save(element); QDomElement e = element; e.setAttribute("LocalMetalinkLocation", m_localMetalinkLocation.url()); foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->save(e); } } Verifier *Metalink::verifier(const QUrl &file) { if (!m_dataSourceFactory.contains(file)) { return nullptr; } return m_dataSourceFactory[file]->verifier(); } Signature *Metalink::signature(const QUrl &file) { if (!m_dataSourceFactory.contains(file)) { return nullptr; } return m_dataSourceFactory[file]->signature(); } QList Metalink::files() const { return m_dataSourceFactory.keys(); } FileModel *Metalink::fileModel() { if (!m_fileModel) { m_fileModel = new FileModel(files(), directory(), this); connect(m_fileModel, SIGNAL(rename(QUrl,QUrl)), this, SLOT(slotRename(QUrl,QUrl))); connect(m_fileModel, SIGNAL(checkStateChanged()), this, SLOT(filesSelected())); foreach (DataSourceFactory *factory, m_dataSourceFactory) { const QUrl dest = factory->dest(); QModelIndex size = m_fileModel->index(dest, FileItem::Size); m_fileModel->setData(size, static_cast(factory->size())); QModelIndex status = m_fileModel->index(dest, FileItem::Status); m_fileModel->setData(status, factory->status()); QModelIndex checksumVerified = m_fileModel->index(dest, FileItem::ChecksumVerified); m_fileModel->setData(checksumVerified, factory->verifier()->status()); QModelIndex signatureVerified = m_fileModel->index(dest, FileItem::SignatureVerified); m_fileModel->setData(signatureVerified, factory->signature()->status()); if (!factory->doDownload()) { QModelIndex index = m_fileModel->index(factory->dest(), FileItem::File); m_fileModel->setData(index, Qt::Unchecked, Qt::CheckStateRole); } } } return m_fileModel; } void Metalink::filesSelected() { bool overwriteAll = false; bool autoSkip = false; bool cancel = false; QModelIndexList files = fileModel()->fileIndexes(FileItem::File); m_numFilesSelected = 0; //sets the CheckState of the fileModel to the according DataSourceFactories //and asks the user if there are existing files already foreach (const QModelIndex &index, files) { const QUrl dest = fileModel()->getUrl(index); bool doDownload = index.data(Qt::CheckStateRole).toBool(); if (m_dataSourceFactory.contains(dest)) { DataSourceFactory *factory = m_dataSourceFactory[dest]; //ignore finished transfers if ((factory->status() == Job::Finished) || (factory->status() == Job::FinishedKeepAlive)) { continue; } //check if the file at dest exists already and ask the user what to do in this case, ignore already running transfers if (doDownload && (factory->status() != Job::Running) && QFile::exists(dest.toLocalFile())) { //user has chosen to skip all files that exist already before if (autoSkip) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; //ask the user, unless he has chosen overwriteAll before } else if (!overwriteAll) { KIO::RenameDialog dlg(nullptr, i18n("File already exists"), index.data().toString(), dest, KIO::RenameDialog_Options(KIO::RenameDialog_MultipleItems | KIO::RenameDialog_Overwrite | KIO::RenameDialog_Skip)); const int result = dlg.exec(); if (result == KIO::R_RENAME) { //no reason to use FileModel::rename() since the file does not exist yet, so simply skip it //avoids having to deal with signals const QUrl newDest = dlg.newDestUrl(); factory->setDoDownload(doDownload); factory->setNewDestination(newDest); fileModel()->setData(index, newDest.fileName(), FileItem::File); ++m_numFilesSelected; m_dataSourceFactory.remove(dest); m_dataSourceFactory[newDest] = factory; continue; } else if (result == KIO::R_SKIP) { fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; } else if (result == KIO::R_CANCEL) { cancel = true; break; } else if (result == KIO::R_AUTO_SKIP) { autoSkip = true; fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole); doDownload = false; } else if (result == KIO::R_OVERWRITE_ALL) { overwriteAll = true; } } } factory->setDoDownload(doDownload); if (doDownload && (factory->status() != Finished) && (factory->status() != FinishedKeepAlive)) { ++m_numFilesSelected; } } } //the user decided to cancel, so untick all files if (cancel) { m_numFilesSelected = 0; untickAllFiles(); foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->setDoDownload(false); } } Transfer::ChangesFlags change = (Tc_TotalSize | Tc_DownloadSpeed); //some files have been selected that are not finished yet, set them to stop if the transfer is not running (checked in slotStatus) if (m_numFilesSelected) { change |= Tc_Status; } slotDataSourceFactoryChange(change); } void Metalink::slotRename(const QUrl &oldUrl, const QUrl &newUrl) { if (!m_dataSourceFactory.contains(oldUrl)) { return; } m_dataSourceFactory[newUrl] = m_dataSourceFactory[oldUrl]; m_dataSourceFactory.remove(oldUrl); m_dataSourceFactory[newUrl]->setNewDestination(newUrl); setTransferChange(Tc_FileName); } bool Metalink::setDirectory(const QUrl &new_directory) { if (new_directory == directory()) { return false; } if (m_fileModel) { m_fileModel->setDirectory(new_directory); } const QString oldDirectory = directory().pathOrUrl(QUrl::AddTrailingSlash); const QString newDirectory = new_directory.pathOrUrl(QUrl::AddTrailingSlash); const QString fileName = m_dest.fileName(); m_dest = new_directory; m_dest.addPath(fileName); QHash newStorage; foreach (DataSourceFactory *factory, m_dataSourceFactory) { const QUrl oldUrl = factory->dest(); const QUrl newUrl = QUrl(oldUrl.pathOrUrl().replace(oldDirectory, newDirectory)); factory->setNewDestination(newUrl); newStorage[newUrl] = factory; } m_dataSourceFactory = newStorage; setTransferChange(Tc_FileName); return true; } QHash > Metalink::availableMirrors(const QUrl &file) const { QHash > urls; if (m_dataSourceFactory.contains(file)) { urls = m_dataSourceFactory[file]->mirrors(); } return urls; } void Metalink::setAvailableMirrors(const QUrl &file, const QHash > &mirrors) { if (!m_dataSourceFactory.contains(file)) { return; } m_dataSourceFactory[file]->setMirrors(mirrors); } void Metalink::slotUpdateCapabilities() { Capabilities oldCap = capabilities(); Capabilities newCap = 0; foreach (DataSourceFactory *file, m_dataSourceFactory) { if (file->doDownload()) {//FIXME when a download did not start yet it should be moveable!!//FIXME why not working, when only two connections? if (newCap) { newCap &= file->capabilities(); } else { newCap = file->capabilities(); } } } if (newCap != oldCap) { setCapabilities(newCap); } } diff --git a/transfer-plugins/metalink/metalinkhttp.cpp b/transfer-plugins/metalink/metalinkhttp.cpp index 89394d97..77e7b7cc 100644 --- a/transfer-plugins/metalink/metalinkhttp.cpp +++ b/transfer-plugins/metalink/metalinkhttp.cpp @@ -1,307 +1,308 @@ /* This file is part of the KDE project Copyright (C) 2004 Dario Massarin Copyright (C) 2007 Manolo Valdes Copyright (C) 2009 Matthias Fuchs Copyright (C) 2012 Aish Raj Dahal 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 2 of the License, or (at your option) any later version. */ #include "metalinkhttp.h" #include "metalinksettings.h" #include "metalinkxml.h" #include "core/kget.h" #include "core/transfergroup.h" #include "core/download.h" #include "core/transferdatasource.h" #include "core/filemodel.h" #include "core/urlchecker.h" #include "core/verifier.h" #include "core/signature.h" #include "kget_debug.h" #include #include #include #include #include #include -#include +#include #include #include #include +#include /** * @return Hex value from a base64 value * @note needed for hex based signature verification */ QString base64ToHex(const QString& b64) { return QString(QByteArray::fromBase64(b64.toAscii()).toHex()); } MetalinkHttp::MetalinkHttp(TransferGroup * parent, TransferFactory * factory, Scheduler * scheduler, const QUrl & source, const QUrl & dest, KGetMetalink::MetalinkHttpParser *httpParser, const QDomElement * e) : AbstractMetalink(parent,factory,scheduler,source, dest, e) , m_signatureUrl(QUrl()), m_httpparser(httpParser) { m_httpparser->setParent(this); } MetalinkHttp::~MetalinkHttp() { } void MetalinkHttp::load(const QDomElement *element) { qCDebug(KGET_DEBUG); Transfer::load(element); DataSourceFactory * fac = new DataSourceFactory(this, m_dest); m_dataSourceFactory.insert(m_dest, fac); connect(fac, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(fac, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); connect(fac->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(fac->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(fac, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); fac->load(element); if (fac->mirrors().isEmpty()) { return; } m_ready = true; } void MetalinkHttp::save(const QDomElement &element) { qCDebug(KGET_DEBUG); Transfer::save(element); m_dataSourceFactory.begin().value()->save(element); } void MetalinkHttp::startMetalink() { if (m_ready) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { //specified number of files is downloaded simultanously if (m_currentFiles < MetalinkSettings::simultanousFiles()) { const Job::Status status = factory->status(); //only start factories that should be downloaded if (factory->doDownload() && (status != Job::Finished) && (status != Job::FinishedKeepAlive) && (status != Job::Running)) { ++m_currentFiles; factory->start(); } } else { break; } } } } void MetalinkHttp::start() { qDebug() << "metalinkhttp::start"; if (!m_ready) { setLinks(); setDigests(); if (metalinkHttpInit()) { startMetalink(); } } else { startMetalink(); } } void MetalinkHttp::setSignature(QUrl & dest, QByteArray & data, DataSourceFactory* dataFactory) { Q_UNUSED(dest); dataFactory->signature()->setSignature(data,Signature::AsciiDetached); } void MetalinkHttp::slotSignatureVerified() { if (status() == Job::Finished) { //see if some files are NotVerified QStringList brokenFiles; foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (m_fileModel) { QModelIndex signatureVerified = m_fileModel->index(factory->dest(), FileItem::SignatureVerified); m_fileModel->setData(signatureVerified, factory->signature()->status()); } if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified)) { brokenFiles.append(factory->dest().toString()); } } if (brokenFiles.count()) { if (KMessageBox::warningYesNoCancelList(nullptr, i18n("The download could not be verified, try to repair it?"), brokenFiles) == KMessageBox::Yes) { if (repair()) { KGet::addTransfer(m_metalinkxmlUrl); //TODO Use a Notification instead. Check kget.h for how to use it. } } } } } bool MetalinkHttp::metalinkHttpInit() { qDebug() << "m_dest = " << m_dest; const QUrl tempDest = QUrl(m_dest.adjusted(QUrl::RemoveFilename)); QUrl dest = tempDest.toString() + m_dest.fileName(); qDebug() << "dest = " << dest; //sort the urls according to their priority (highest first) qStableSort(m_linkheaderList); DataSourceFactory *dataFactory = new DataSourceFactory(this,dest); dataFactory->setMaxMirrorsUsed(MetalinkSettings::mirrorsPerFile()); connect(dataFactory, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(dataFactory, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); connect(dataFactory->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(dataFactory->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(dataFactory, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); //add the Mirrors Sources for(int i = 0; i < m_linkheaderList.size(); ++i) { const QUrl url = m_linkheaderList[i].url; if (url.isValid()) { if (m_linkheaderList[i].pref) { qDebug() << "found etag in a mirror" ; KGetMetalink::MetalinkHttpParser* eTagCher = new KGetMetalink::MetalinkHttpParser(url) ; if (eTagCher->getEtag() != m_httpparser->getEtag()) { //There is an ETag mismatch continue ; } } dataFactory->addMirror(url, MetalinkSettings::connectionsPerUrl()); } } //no datasource has been created, so remove the datasource factory if (dataFactory->mirrors().isEmpty()) { qDebug() << "data source factory being deleted" ; delete dataFactory; } else { QHashIterator itr(m_DigestList); while(itr.hasNext()) { itr.next(); qDebug() << itr.key() << ":" << itr.value() ; } dataFactory->verifier()->addChecksums(m_DigestList); //Add OpenPGP signatures if (m_signatureUrl != QUrl()) { Download *signat_download = new Download(m_signatureUrl, QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/metalinks/") + m_source.fileName()); connect(signat_download, SIGNAL(finishedSuccessfully(QUrl,QByteArray)), SLOT(setSignature(QUrl,QByteArray))); } m_dataSourceFactory[dataFactory->dest()] = dataFactory; } if (m_dataSourceFactory.size()) { m_dest = dest; } if (!m_dataSourceFactory.size()) { //TODO make this via log in the future + do not display the KMessageBox qCWarning(KGET_DEBUG) << "Download of" << m_source << "failed, no working URLs were found."; KMessageBox::error(nullptr, i18n("Download failed, no working URLs were found."), i18n("Error")); setStatus(Job::Aborted); setTransferChange(Tc_Status, true); return false; } m_ready = !m_dataSourceFactory.isEmpty(); slotUpdateCapabilities(); return true; } void MetalinkHttp::setLinks() { const QMultiMap* headerInf = m_httpparser->getHeaderInfo(); const QList linkVals = headerInf->values("link"); foreach (const QString link, linkVals) { const KGetMetalink::HttpLinkHeader linkheader(link); if (linkheader.reltype == "duplicate") { m_linkheaderList.append(linkheader); } else if (linkheader.reltype == "application/pgp-signature") { m_signatureUrl = linkheader.url; //There will only be one signature } else if (linkheader.reltype == "application/metalink4+xml") { m_metalinkxmlUrl = linkheader.url ; // There will only be one metalink xml (metainfo URL) } } } void MetalinkHttp::deinit(Transfer::DeleteOptions options) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (options & Transfer::DeleteFiles) { factory->deinit(); } } } void MetalinkHttp::setDigests() { const QMultiMap* digestInfo = m_httpparser->getHeaderInfo(); const QList digestList = digestInfo->values("digest"); foreach(const QString digest, digestList) { const int eqDelimiter = digest.indexOf('='); const QString digestType = MetalinkHttp::adaptDigestType(digest.left(eqDelimiter).trimmed()); const QString hexDigestValue = base64ToHex(digest.mid(eqDelimiter + 1).trimmed()); m_DigestList.insertMulti(digestType,hexDigestValue); } } QString MetalinkHttp::adaptDigestType(const QString & hashType) { if (hashType == QString("SHA")) { return QString("sha"); } else if (hashType == QString("MD5")) { return QString("md5"); } else if (hashType == QString("SHA-256")) { return QString("sha256"); } else { return hashType; } } diff --git a/transfer-plugins/metalink/metalinkxml.cpp b/transfer-plugins/metalink/metalinkxml.cpp index c097f5c5..3a638cf8 100644 --- a/transfer-plugins/metalink/metalinkxml.cpp +++ b/transfer-plugins/metalink/metalinkxml.cpp @@ -1,324 +1,325 @@ /* This file is part of the KDE project Copyright (C) 2004 Dario Massarin Copyright (C) 2007 Manolo Valdes Copyright (C) 2009 Matthias Fuchs Copyright (C) 2012 Aish Raj Dahal 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 2 of the License, or (at your option) any later version. */ #include "metalinkxml.h" #include "fileselectiondlg.h" #include "metalinksettings.h" #include "core/kget.h" #include "core/transfergroup.h" #include "core/download.h" #include "core/transferdatasource.h" #include "core/filemodel.h" #include "core/urlchecker.h" #include "core/verifier.h" #include "core/signature.h" #include "kget_debug.h" #include #include #include #include #include #include -#include +#include #include #include #include +#include MetalinkXml::MetalinkXml(TransferGroup * parent, TransferFactory * factory, Scheduler * scheduler, const QUrl & source, const QUrl & dest, const QDomElement * e) : AbstractMetalink(parent, factory, scheduler, source, dest, e) { } MetalinkXml::~MetalinkXml() { } void MetalinkXml::start() { qCDebug(KGET_DEBUG) << "metalinkxml::start"; if (!m_ready) { if (m_localMetalinkLocation.isValid() && metalinkInit()) { startMetalink(); } else { downloadMetalink(); } } else { startMetalink(); } } void MetalinkXml::downloadMetalink() { m_metalinkJustDownloaded = true; setStatus(Job::Running, i18n("Downloading Metalink File...."), SmallIcon("document-save")); setTransferChange(Tc_Status, true); Download *download = new Download(m_source, QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/metalinks/") + m_source.fileName()); connect(download, SIGNAL(finishedSuccessfully(QUrl,QByteArray)), SLOT(metalinkInit(QUrl,QByteArray))); } bool MetalinkXml::metalinkInit(const QUrl &src, const QByteArray &data) { qCDebug(KGET_DEBUG) << "MetalinkXml::metalinkInit"; if (!src.isEmpty()) { m_localMetalinkLocation = src; } //use the downloaded metalink-file data directly if possible if (!data.isEmpty()) { KGetMetalink::HandleMetalink::load(data, &m_metalink); } //try to parse the locally stored metalink-file if (!m_metalink.isValid() && m_localMetalinkLocation.isValid()) { KGetMetalink::HandleMetalink::load(m_localMetalinkLocation.toLocalFile(), &m_metalink); } if (!m_metalink.isValid()) { qCCritical(KGET_DEBUG) << "Unknown error when trying to load the .metalink-file. Metalink is not valid."; setStatus(Job::Aborted); setTransferChange(Tc_Status, true); return false; } //offers a dialog to download the newest version of a dynamic metalink if ((m_source.isLocalFile() || !m_metalinkJustDownloaded) && m_metalink.dynamic && (UrlChecker::checkSource(m_metalink.origin) == UrlChecker::NoError)) { if (KMessageBox::questionYesNo(nullptr, i18n("A newer version of this Metalink might exist, do you want to download it?"), i18n("Redownload Metalink")) == KMessageBox::Yes) { m_localMetalinkLocation.clear(); m_source = m_metalink.origin; downloadMetalink(); return false; } } QList::const_iterator it; QList::const_iterator itEnd = m_metalink.files.files.constEnd(); m_totalSize = 0; KIO::fileoffset_t segSize = 500 * 1024;//TODO use config here! const QUrl tempDest = QUrl(m_dest.adjusted(QUrl::RemoveFilename)); QUrl dest; for (it = m_metalink.files.files.constBegin(); it != itEnd ; ++it) { dest = tempDest; dest.setPath(tempDest.path() + (*it).name); QList urlList = (*it).resources.urls; //sort the urls according to their priority (highest first) qSort(urlList.begin(), urlList.end(), qGreater()); KIO::filesize_t fileSize = (*it).size; m_totalSize += fileSize; //create a DataSourceFactory for each separate file DataSourceFactory *dataFactory = new DataSourceFactory(this, dest, fileSize, segSize); dataFactory->setMaxMirrorsUsed(MetalinkSettings::mirrorsPerFile()); //TODO compare available file size () with the sizes of the server while downloading? connect(dataFactory, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(dataFactory, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); connect(dataFactory->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(dataFactory->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(dataFactory, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); //add the DataSources for (int i = 0; i < urlList.size(); ++i) { const QUrl url = urlList[i].url; if (url.isValid()) { dataFactory->addMirror(url, MetalinkSettings::connectionsPerUrl()); } } //no datasource has been created, so remove the datasource factory if (dataFactory->mirrors().isEmpty()) { delete dataFactory; } else { dataFactory->verifier()->addChecksums((*it).verification.hashes); foreach (const KGetMetalink::Pieces &pieces, (*it).verification.pieces) { dataFactory->verifier()->addPartialChecksums(pieces.type, pieces.length, pieces.hashes); } const QHash signatures = (*it).verification.signatures; QHash::const_iterator it; QHash::const_iterator itEnd = signatures.constEnd(); for (it = signatures.constBegin(); it != itEnd; ++it) { if (it.key().toLower() == "pgp") { dataFactory->signature()->setAsciiDetatchedSignature(*it); } } m_dataSourceFactory[dataFactory->dest()] = dataFactory; } } if ((m_metalink.files.files.size() == 1) && m_dataSourceFactory.size()) { m_dest = dest; } if (!m_dataSourceFactory.size()) { //TODO make this via log in the future + do not display the KMessageBox qCWarning(KGET_DEBUG) << "Download of" << m_source << "failed, no working URLs were found."; KMessageBox::error(nullptr, i18n("Download failed, no working URLs were found."), i18n("Error")); setStatus(Job::Aborted); setTransferChange(Tc_Status, true); return false; } m_ready = !m_dataSourceFactory.isEmpty(); slotUpdateCapabilities(); //the metalink-file has just been downloaded, so ask the user to choose the files that // should be downloaded /* TODO this portion seems not to be working. Need to ask boom1992 */ if (m_metalinkJustDownloaded) { QDialog *dialog = new FileSelectionDlg(fileModel()); dialog->setAttribute(Qt::WA_DeleteOnClose); connect(dialog, SIGNAL(finished(int)), this, SLOT(fileDlgFinished(int))); dialog->show(); } return true; } void MetalinkXml::startMetalink() { if (m_ready) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { //specified number of files is downloaded simultanously if (m_currentFiles < MetalinkSettings::simultanousFiles()) { const int status = factory->status(); //only start factories that should be downloaded if (factory->doDownload() && (status != Job::Finished) && (status != Job::FinishedKeepAlive) && (status != Job::Running)) { ++m_currentFiles; factory->start(); } } else { break; } } } } void MetalinkXml::deinit(Transfer::DeleteOptions options) { foreach (DataSourceFactory *factory, m_dataSourceFactory) { if (options & Transfer::DeleteFiles) { factory->deinit(); } }//TODO: Ask the user if he/she wants to delete the *.part-file? To discuss (boom1992) //FIXME does that mean, that the metalink file is always removed, even if //downloaded by the user? if ((options & Transfer::DeleteTemporaryFiles) && m_localMetalinkLocation.isLocalFile()) { KIO::Job *del = KIO::del(m_localMetalinkLocation, KIO::HideProgressInfo); KIO::NetAccess::synchronousRun(del, nullptr); } } void MetalinkXml::load(const QDomElement *element) { Transfer::load(element); if (!element) { return; } const QDomElement e = *element; m_localMetalinkLocation = QUrl(e.attribute("LocalMetalinkLocation")); QDomNodeList factories = e.firstChildElement("factories").elementsByTagName("factory"); //no stored information found, stop right here if (!factories.count()) { return; } while (factories.count()) { QDomDocument doc; QDomElement factory = doc.createElement("factories"); factory.appendChild(factories.item(0).toElement()); doc.appendChild(factory); DataSourceFactory *file = new DataSourceFactory(this); file->load(&factory); connect(file, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities())); connect(file, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags))); m_dataSourceFactory[file->dest()] = file; connect(file->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool))); connect(file->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified())); connect(file, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel))); //start the DataSourceFactories that were Started when KGet was closed if (file->status() == Job::Running) { if (m_currentFiles < MetalinkSettings::simultanousFiles()) { ++m_currentFiles; file->start(); } else { //enough simultanous files already, so increase the number and set file to stop --> that will decrease the number again file->stop(); } } } m_ready = !m_dataSourceFactory.isEmpty(); slotUpdateCapabilities(); } void MetalinkXml::save(const QDomElement &element) { Transfer::save(element); QDomElement e = element; e.setAttribute("LocalMetalinkLocation", m_localMetalinkLocation.url()); foreach (DataSourceFactory *factory, m_dataSourceFactory) { factory->save(e); } } diff --git a/transfer-plugins/mirrorsearch/dlgmirrorsearch.cpp b/transfer-plugins/mirrorsearch/dlgmirrorsearch.cpp index ea6192bb..e15b6e3e 100644 --- a/transfer-plugins/mirrorsearch/dlgmirrorsearch.cpp +++ b/transfer-plugins/mirrorsearch/dlgmirrorsearch.cpp @@ -1,143 +1,154 @@ /* This file is part of the KDE project Copyright (C) 2008 Manolo Valdes 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 2 of the License, or (at your option) any later version. */ #include "dlgmirrorsearch.h" #include "kget_macro.h" #include "mirrorsearchsettings.h" #include "kget_debug.h" #include #include +#include +#include +#include +#include DlgEngineEditing::DlgEngineEditing(QWidget *parent) - : KDialog(parent) + : QDialog(parent) { QWidget *mainWidget = new QWidget(this); ui.setupUi(mainWidget); - setMainWidget(mainWidget); + QVBoxLayout *mainLayout = new QVBoxLayout; + setLayout(mainLayout); + mainLayout->addWidget(mainWidget); setWindowTitle(i18n("Insert Engine")); setModal(true); - setButtons(KDialog::Ok | KDialog::Cancel); - showButtonSeparator(true); + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); + okButton = buttonBox->button(QDialogButtonBox::Ok); + okButton->setDefault(true); + okButton->setShortcut(Qt::CTRL | Qt::Key_Return); + connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgEngineEditing::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgEngineEditing::reject); + mainLayout->addWidget(buttonBox); ui.engineNameLabel->setText(i18n("Engine name:")); ui.urlLabel->setText(i18n("URL:")); connect(ui.urlEdit,SIGNAL(textChanged(QString)), SLOT(slotChangeText())); connect(ui.engineNameEdit,SIGNAL(textChanged(QString)),SLOT(slotChangeText())); slotChangeText(); } DlgEngineEditing::~DlgEngineEditing() { } void DlgEngineEditing::slotChangeText() { - enableButton(KDialog::Ok, !ui.urlEdit->text().isEmpty()); + okButton->setEnabled(!ui.urlEdit->text().isEmpty()); } QString DlgEngineEditing::engineName() const { return ui.engineNameEdit->text(); } QString DlgEngineEditing::engineUrl() const { return ui.urlEdit->text(); } KGET_EXPORT_PLUGIN_CONFIG(DlgSettingsWidget) DlgSettingsWidget::DlgSettingsWidget(QWidget *parent, const QVariantList &args) : KCModule(/*KGetFactory::componentData(),*/ parent, args) { ui.setupUi(this); ui.newEngineBt->setIcon(QIcon::fromTheme("list-add")); ui.removeEngineBt->setIcon(QIcon::fromTheme("list-remove")); connect(ui.newEngineBt, SIGNAL(clicked()), SLOT(slotNewEngine())); connect(ui.removeEngineBt, SIGNAL(clicked()), SLOT(slotRemoveEngine())); } DlgSettingsWidget::~DlgSettingsWidget() { } void DlgSettingsWidget::slotNewEngine() { DlgEngineEditing dialog; if(dialog.exec()) { addSearchEngineItem(dialog.engineName(), dialog.engineUrl()); changed(); } } void DlgSettingsWidget::slotRemoveEngine() { QList selectedItems = ui.enginesTreeWidget->selectedItems(); foreach(QTreeWidgetItem * selectedItem, selectedItems) delete(selectedItem); changed(); } void DlgSettingsWidget::load() { loadSearchEnginesSettings(); } void DlgSettingsWidget::addSearchEngineItem(const QString &name, const QString &url) { ui.enginesTreeWidget->addTopLevelItem(new QTreeWidgetItem(QStringList() << name << url)); changed(); } void DlgSettingsWidget::loadSearchEnginesSettings() { ui.enginesTreeWidget->clear();//Cleanup things first QStringList enginesNames = MirrorSearchSettings::self()->searchEnginesNameList(); QStringList enginesUrls = MirrorSearchSettings::self()->searchEnginesUrlList(); for(int i = 0; i < enginesNames.size(); i++) { addSearchEngineItem(enginesNames[i], enginesUrls[i]); } } void DlgSettingsWidget::saveSearchEnginesSettings() { QStringList enginesNames; QStringList enginesUrls; for(int i = 0; i < ui.enginesTreeWidget->topLevelItemCount(); i++) { enginesNames.append(ui.enginesTreeWidget->topLevelItem(i)->text(0)); enginesUrls.append(ui.enginesTreeWidget->topLevelItem(i)->text(1)); } MirrorSearchSettings::self()->setSearchEnginesNameList(enginesNames); MirrorSearchSettings::self()->setSearchEnginesUrlList(enginesUrls); MirrorSearchSettings::self()->save(); } void DlgSettingsWidget::save() { qCDebug(KGET_DEBUG); saveSearchEnginesSettings(); MirrorSearchSettings::self()->save(); } #include "dlgmirrorsearch.moc" diff --git a/transfer-plugins/mirrorsearch/dlgmirrorsearch.h b/transfer-plugins/mirrorsearch/dlgmirrorsearch.h index 9021ad99..dd947043 100644 --- a/transfer-plugins/mirrorsearch/dlgmirrorsearch.h +++ b/transfer-plugins/mirrorsearch/dlgmirrorsearch.h @@ -1,63 +1,64 @@ /* This file is part of the KDE project Copyright (C) 2008 Manolo Valdes 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 2 of the License, or (at your option) any later version. */ #ifndef DLGMIRRORSEARCH_H #define DLGMIRRORSEARCH_H #include "ui_dlgengineediting.h" #include "ui_dlgmirrorsearch.h" #include -#include +#include -class DlgEngineEditing : public KDialog +class DlgEngineEditing : public QDialog { Q_OBJECT public: DlgEngineEditing(QWidget *parent = nullptr); ~DlgEngineEditing(); QString engineName() const; QString engineUrl() const; private slots: void slotChangeText(); private: Ui::DlgEngineEditing ui; + QPushButton *okButton; }; class DlgSettingsWidget : public KCModule { Q_OBJECT public: explicit DlgSettingsWidget(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); ~DlgSettingsWidget(); public slots: void save(); void load(); private slots: void slotNewEngine(); void slotRemoveEngine(); private: void addSearchEngineItem(const QString &name, const QString &url); void loadSearchEnginesSettings(); void saveSearchEnginesSettings(); Ui::DlgMirrorSearch ui; QDialog *m_parent; }; #endif // DLGMULTISEGKIO_H diff --git a/ui/groupsettingsdialog.cpp b/ui/groupsettingsdialog.cpp index 83254243..6d0e87e9 100644 --- a/ui/groupsettingsdialog.cpp +++ b/ui/groupsettingsdialog.cpp @@ -1,70 +1,69 @@ /* This file is part of the KDE project Copyright (C) 2008 Lukas Appelhans Copyright (C) 2009 Matthias Fuchs 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 2 of the License, or (at your option) any later version. */ #include "groupsettingsdialog.h" #include "core/transfergrouphandler.h" GroupSettingsDialog::GroupSettingsDialog(QWidget *parent, TransferGroupHandler *group) : KGetSaveSizeDialog("GroupSettingsDialog", parent), m_group(group) { setWindowTitle(i18n("Group Settings for %1", group->name())); - //showButtonSeparator(true); ui.setupUi(this); ui.downloadBox->setValue(group->downloadLimit(Transfer::VisibleSpeedLimit)); ui.uploadBox->setValue(group->uploadLimit(Transfer::VisibleSpeedLimit)); ui.defaultFolderRequester->setMode(KFile::Directory); QString path = group->defaultFolder(); ui.defaultFolderRequester->setUrl(path); ui.defaultFolderRequester->setStartDir(QUrl(KGet::generalDestDir(true))); ui.regExpEdit->setText(group->regExp().pattern()); ui.nepomukWidget->hide(); connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(this, &GroupSettingsDialog::accepted, this, &GroupSettingsDialog::save); } GroupSettingsDialog::~GroupSettingsDialog() { } QSize GroupSettingsDialog::sizeHint() const { QSize sh = QDialog::sizeHint(); sh.setWidth(sh.width() * 1.4); return sh; } void GroupSettingsDialog::save() { //check needed, otherwise "/" would be added as folder if the line was empty! if (ui.defaultFolderRequester->text().isEmpty()) { m_group->setDefaultFolder(QString()); } else { m_group->setDefaultFolder(ui.defaultFolderRequester->url().toLocalFile()); } m_group->setDownloadLimit(ui.downloadBox->value(), Transfer::VisibleSpeedLimit); m_group->setUploadLimit(ui.uploadBox->value(), Transfer::VisibleSpeedLimit); QRegExp regExp; regExp.setPattern(ui.regExpEdit->text()); m_group->setRegExp(regExp); } diff --git a/ui/renamefile.cpp b/ui/renamefile.cpp index c520a2e7..4ae7e422 100644 --- a/ui/renamefile.cpp +++ b/ui/renamefile.cpp @@ -1,69 +1,68 @@ /*************************************************************************** * Copyright (C) 2009 Matthias Fuchs * * * * 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 2 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, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "renamefile.h" #include "core/filemodel.h" #include #include #include RenameFile::RenameFile(FileModel *model, const QModelIndex &index, QWidget *parent, Qt::WFlags flags) : QDialog(parent, flags), m_model(model), m_index(index) { setWindowTitle(i18n("Rename File")); - //showButtonSeparator(true); ui.setupUi(this); const QString originalName = m_model->data(m_index, Qt::DisplayRole).toString(); m_dest = m_model->getUrl(m_index).adjusted(QUrl::RemoveFilename); ui.label->setText(i18n("Rename %1 to:", originalName)); ui.name->setText(originalName); ui.buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("&Rename")); ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); //ui.buttonBox->button(QDialogButtonBox::Ok)->setShortcut(Qt::CTRL | Qt::Key_Return); connect(ui.name, &KLineEdit::textEdited, this, &RenameFile::updateButton); connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &RenameFile::accept); connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(this, &QDialog::accepted, this, &RenameFile::rename); } void RenameFile::updateButton() { const QString newName = ui.name->text(); QUrl dest = m_dest; dest.setPath(m_dest.path() + newName); const bool enabled = !newName.isEmpty() && !QFile::exists(dest.toString()); ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); } void RenameFile::rename() { const QString newName = ui.name->text(); m_model->rename(m_index, newName); } diff --git a/ui/transfersettingsdialog.cpp b/ui/transfersettingsdialog.cpp index 11a202e7..407739e2 100644 --- a/ui/transfersettingsdialog.cpp +++ b/ui/transfersettingsdialog.cpp @@ -1,184 +1,183 @@ /* This file is part of the KDE project Copyright (C) 2008 Lukas Appelhans Copyright (C) 2009 Matthias Fuchs 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 2 of the License, or (at your option) any later version. */ #include "transfersettingsdialog.h" #include "mirror/mirrorsettings.h" #include "renamefile.h" #include "signaturedlg.h" #include "verificationdialog.h" #include "settings.h" #include "core/transferhandler.h" #include "core/filemodel.h" #include "core/verifier.h" #include #include #include #include TransferSettingsDialog::TransferSettingsDialog(QWidget *parent, TransferHandler *transfer) : KGetSaveSizeDialog("TransferSettingsDialog", parent), m_transfer(transfer), m_model(m_transfer->fileModel()), m_proxy(nullptr) { setWindowTitle(i18n("Transfer Settings for %1", m_transfer->source().fileName())); - //showButtonSeparator(true); ui.setupUi(this); ui.ktitlewidget->setPixmap(QIcon::fromTheme("preferences-other").pixmap(16)); ui.downloadSpin->setValue(m_transfer->downloadLimit(Transfer::VisibleSpeedLimit)); ui.uploadSpin->setValue(m_transfer->uploadLimit(Transfer::VisibleSpeedLimit)); ui.ratioSpin->setValue(m_transfer->maximumShareRatio()); ui.destination->setUrl(m_transfer->directory().toString()); ui.destination->lineEdit()->setReadOnly(true); ui.rename->setIcon(QIcon::fromTheme("edit-rename")); ui.mirrors->setIcon(QIcon::fromTheme("download")); ui.signature->setIcon(QIcon::fromTheme("application-pgp-signature")); ui.verification->setIcon(QIcon::fromTheme("document-decrypt")); if (m_model) { m_model->watchCheckState(); m_proxy = new QSortFilterProxyModel(this); m_proxy->setSourceModel(m_model); ui.treeView->setModel(m_proxy); ui.treeView->sortByColumn(0, Qt::AscendingOrder); QByteArray loadedState = QByteArray::fromBase64(Settings::transferSettingsHeaderState().toAscii()); if (!loadedState.isEmpty()) { ui.treeView->header()->restoreState(loadedState); } else { ui.treeView->header()->resizeSection(0, ui.treeView->header()->defaultSectionSize() * 3); } } updateCapabilities(); connect(m_transfer, &TransferHandler::capabilitiesChanged, this, &TransferSettingsDialog::updateCapabilities); connect(this, &TransferSettingsDialog::accepted, this, &TransferSettingsDialog::save); connect(this, &TransferSettingsDialog::finished, this, &TransferSettingsDialog::slotFinished); connect(ui.treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(slotSelectionChanged())); connect(ui.rename, &QPushButton::clicked, this, &TransferSettingsDialog::slotRename); connect(ui.mirrors, &QPushButton::clicked, this, &TransferSettingsDialog::slotMirrors); connect(ui.verification, &QPushButton::clicked, this, &TransferSettingsDialog::slotVerification); connect(ui.signature, &QPushButton::clicked, this, &TransferSettingsDialog::slotSignature); connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } TransferSettingsDialog::~TransferSettingsDialog() { if (m_model) { Settings::setTransferSettingsHeaderState(ui.treeView->header()->saveState().toBase64()); } } QSize TransferSettingsDialog::sizeHint() const { QSize sh = QDialog::sizeHint(); sh.setWidth(sh.width() * 1.7); return sh; } void TransferSettingsDialog::updateCapabilities() { const int capabilities = m_transfer->capabilities(); const bool supportsSpeedLimit = capabilities & Transfer::Cap_SpeedLimit; ui.labelDownload->setVisible(supportsSpeedLimit); ui.downloadSpin->setVisible(supportsSpeedLimit); ui.labelUpload->setVisible(supportsSpeedLimit); ui.uploadSpin->setVisible(supportsSpeedLimit); ui.labelShareRatio->setVisible(supportsSpeedLimit); ui.ratioSpin->setVisible(supportsSpeedLimit); ui.destination->setEnabled(capabilities & Transfer::Cap_Moving); ui.mirrors->setVisible(capabilities & Transfer::Cap_MultipleMirrors); ui.rename->setVisible(capabilities & Transfer::Cap_Renaming); } void TransferSettingsDialog::slotMirrors() { const QModelIndex index = m_proxy->mapToSource(ui.treeView->selectionModel()->selectedIndexes().first()); QDialog *mirrors = new MirrorSettings(this, m_transfer, m_model->getUrl(index)); mirrors->setAttribute(Qt::WA_DeleteOnClose); mirrors->show(); } void TransferSettingsDialog::slotRename() { const QModelIndex index = m_proxy->mapToSource(ui.treeView->selectionModel()->selectedIndexes().first()); RenameFile *renameDlg = new RenameFile(m_model, index, this); renameDlg->setAttribute(Qt::WA_DeleteOnClose); renameDlg->show(); } void TransferSettingsDialog::slotVerification() { const QModelIndex index = m_proxy->mapToSource(ui.treeView->selectionModel()->selectedIndexes().first()); QDialog *verification = new VerificationDialog(this, m_transfer, m_model->getUrl(index)); verification->setAttribute(Qt::WA_DeleteOnClose); verification->show(); } void TransferSettingsDialog::slotSignature() { const QModelIndex index = m_proxy->mapToSource(ui.treeView->selectionModel()->selectedIndexes().first()); SignatureDlg *signature = new SignatureDlg(m_transfer, m_model->getUrl(index), this); signature->setAttribute(Qt::WA_DeleteOnClose); signature->show(); } void TransferSettingsDialog::slotSelectionChanged() { bool enabled = false; //only enable rename when one item is selected and when this item is a file if (ui.treeView->selectionModel()->selectedRows().count() == 1) { const QModelIndex index = m_proxy->mapToSource(ui.treeView->selectionModel()->selectedIndexes().first()); if (index.isValid() && !(static_cast(index.internalPointer()))->childCount()) { enabled = true; } } ui.mirrors->setEnabled(enabled); ui.rename->setEnabled(enabled); ui.verification->setEnabled(enabled); ui.signature->setEnabled(enabled); } void TransferSettingsDialog::save() {//TODO: Set to -1 when no limit QUrl oldDirectory = m_transfer->directory(); QUrl newDirectory = ui.destination->url(); if ((oldDirectory != newDirectory) && !m_transfer->setDirectory(newDirectory)) { KMessageBox::error(this, i18n("Changing the destination did not work, the destination stays unmodified."), i18n("Destination unmodified")); } m_transfer->setDownloadLimit(ui.downloadSpin->value(), Transfer::VisibleSpeedLimit); m_transfer->setUploadLimit(ui.uploadSpin->value(), Transfer::VisibleSpeedLimit); m_transfer->setMaximumShareRatio(ui.ratioSpin->value()); } void TransferSettingsDialog::slotFinished() { if (m_model) { m_model->stopWatchCheckState(); } }