1 /***************************************************************************
2 *   Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net>                     *
3 *                                                                         *
4 *   This program is free software; you can redistribute it and/or modify  *
5 *   it under the terms of the GNU General Public License as published by  *
6 *   the Free Software Foundation; either version 2 of the License, or     *
7 *   (at your option) any later version.                                   *
8 *                                                                         *
9 *   This program is distributed in the hope that it will be useful,       *
10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12 *   GNU General Public License for more details.                          *
13 *                                                                         *
14 *   You should have received a copy of the GNU General Public License     *
15 *   along with this program; if not, write to the                         *
16 *   Free Software Foundation, Inc.,                                       *
17 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
18 ***************************************************************************/
19 
20 #include "filedlg.h"
21 #include "metalinker.h"
22 #include "urlwidget.h"
23 #include "../verificationdialog.h"
24 
25 #include "../../core/verifier.h"
26 #include "../../core/verificationmodel.h"
27 #include "../../core/verificationdelegate.h"
28 
29 #include <QSortFilterProxyModel>
30 #include <KStandardGuiItem>
31 
32 #include <KLocalizedString>
33 
FileDlg(KGetMetalink::File * file,const QStringList & currentFileNames,QSortFilterProxyModel * countrySort,QSortFilterProxyModel * languageSort,QWidget * parent,bool edit)34 FileDlg::FileDlg(KGetMetalink::File *file, const QStringList &currentFileNames, QSortFilterProxyModel *countrySort, QSortFilterProxyModel *languageSort, QWidget *parent, bool edit)
35   : KGetSaveSizeDialog("FileDlg", parent),
36     m_file(file),
37     m_initialFileName(m_file->name),
38     m_currentFileNames(currentFileNames),
39     m_edit(edit)
40 {
41     //remove the initial name, to see later if the chosen name is still free
42     m_currentFileNames.removeAll(m_initialFileName);
43 
44     ui.setupUi(this);
45 
46     QValidator *validator = new QIntValidator();
47     ui.size->setValidator(validator);
48 
49     m_urlWidget = new UrlWidget(this);
50     m_urlWidget->init(&m_file->resources, countrySort);
51     ui.urlLayout->addWidget(m_urlWidget->widget());
52     connect(m_urlWidget, &UrlWidget::urlsChanged, this, &FileDlg::slotUpdateOkButton);
53 
54     auto *data = new QWidget(this);
55     uiData.setupUi(data);
56     ui.dataLayout->addWidget(data);
57 
58     ui.infoWidget->setCloseButtonVisible(false);
59     ui.infoWidget->setMessageType(KMessageWidget::Information);
60 
61     //set the file data
62     ui.name->setText(m_file->name);
63     uiData.identity->setText(m_file->data.identity);
64     uiData.version->setText(m_file->data.version);
65     uiData.description->setText(m_file->data.description);
66     uiData.logo->setUrl(m_file->data.logo);
67     if (m_file->data.oses.count()) {
68         uiData.os->setText(m_file->data.oses.join(i18nc("comma, to separate members of a list", ",")));
69     }
70     uiData.copyright->setText(m_file->data.copyright);
71     uiData.pub_name->setText(m_file->data.publisher.name);
72     uiData.pub_url->setUrl(m_file->data.publisher.url);
73 
74     if (m_file->size) {
75         ui.size->setText(QString::number(m_file->size));
76     }
77 
78 
79     //create the language selection
80     uiData.language->setModel(languageSort);
81     if (m_file->data.languages.count()) {//TODO 4.5 support multiple languages
82         const int index = uiData.language->findData(m_file->data.languages.first());
83         uiData.language->setCurrentIndex(index);
84     } else {
85         //Do not select a language of a file if none was defined.
86         uiData.language->setCurrentIndex(-1);
87     }
88 
89 
90     //create the verification stuff
91     m_verificationModel = new VerificationModel(this);
92     QHash<QString, QString>::const_iterator it;
93     QHash<QString, QString>::const_iterator itEnd = m_file->verification.hashes.constEnd();
94     for (it = m_file->verification.hashes.constBegin(); it != itEnd; ++it) {
95         m_verificationModel->addChecksum(it.key(), it.value());
96     }
97     KGuiItem::assign(ui.add_hash, KStandardGuiItem::add());
98     KGuiItem::assign(ui.remove_hash, KStandardGuiItem::remove());
99     m_verificationProxy = new QSortFilterProxyModel(this);
100     m_verificationProxy->setSourceModel(m_verificationModel);
101     ui.used_hashes->setSortingEnabled(true);
102     ui.used_hashes->hideColumn(VerificationModel::Verified);
103     ui.used_hashes->setModel(m_verificationProxy);
104     ui.used_hashes->setItemDelegate(new VerificationDelegate(this));
105     slotUpdateVerificationButtons();
106 
107     connect(m_verificationModel, &VerificationModel::dataChanged, this, &FileDlg::slotUpdateVerificationButtons);
108     connect(m_verificationModel, &VerificationModel::rowsRemoved, this, &FileDlg::slotUpdateVerificationButtons);
109     connect(ui.used_hashes, &QTreeView::clicked, this, &FileDlg::slotUpdateVerificationButtons);
110     connect(ui.add_hash, &QPushButton::clicked, this, &FileDlg::slotAddHash);
111     connect(ui.remove_hash, &QPushButton::clicked, this, &FileDlg::slotRemoveHash);
112     connect(ui.name, &KLineEdit::textEdited, this, &FileDlg::slotUpdateOkButton);
113     connect(this, &QDialog::accepted, this, &FileDlg::slotOkClicked);
114     connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
115     connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
116 
117     slotUpdateOkButton();
118 
119     setWindowTitle(i18n("File Properties"));
120 }
121 
slotUpdateOkButton()122 void FileDlg::slotUpdateOkButton()
123 {
124     bool hasName = !ui.name->text().isEmpty();
125     bool hasUrls =  m_urlWidget->hasUrls();
126     bool isDuplicate = (m_currentFileNames.indexOf(ui.name->text()) > -1);
127 
128     QStringList information;
129 
130     if (!hasName) {
131         information << i18n("Enter a filename.");
132     }
133     if (isDuplicate) {
134         information << i18n("The filename exists already, choose a different one.");
135     }
136     if (!hasUrls) {
137         information << i18n("Enter at least one URL.");
138     }
139 
140     ui.infoWidget->setText(information.join(" "));
141     ui.infoWidget->setVisible(!information.isEmpty());
142 
143     ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(hasName && hasUrls && !isDuplicate);
144 }
145 
slotUpdateVerificationButtons()146 void FileDlg::slotUpdateVerificationButtons()
147 {
148     ui.remove_hash->setEnabled(ui.used_hashes->selectionModel()->hasSelection());
149 }
150 
slotRemoveHash()151 void FileDlg::slotRemoveHash()
152 {
153     while (ui.used_hashes->selectionModel()->hasSelection()) {
154         const QModelIndex index = ui.used_hashes->selectionModel()->selectedRows().first();
155         m_verificationModel->removeRow(m_verificationProxy->mapToSource(index).row());
156     }
157 }
158 
slotAddHash()159 void FileDlg::slotAddHash()
160 {
161     auto *dialog = new VerificationAddDlg(m_verificationModel, this);
162     dialog->show();
163 }
164 
slotOkClicked()165 void FileDlg::slotOkClicked()
166 {
167     QList<KGetMetalink::Metaurl> metaurls = m_file->resources.metaurls;//TODO remove once metaurls are also shown
168     QList<KGetMetalink::Pieces> pieces = m_file->verification.pieces;//TODO remove once the partial hashes are also shown
169     m_file->clear();
170 
171     m_file->name = ui.name->text();
172     m_file->size = ui.size->text().toLongLong();
173     m_file->data.identity = uiData.identity->text();
174     m_file->data.version = uiData.version->text();
175     m_file->data.description = uiData.description->text();
176     m_file->data.logo = QUrl(uiData.logo->text());
177     if (!uiData.os->text().isEmpty()) {
178         m_file->data.oses = uiData.os->text().split(i18nc("comma, to separate members of a list", ","));
179     }
180     m_file->data.copyright = uiData.copyright->text();
181     m_file->data.publisher.name = uiData.pub_name->text();
182     m_file->data.publisher.url = QUrl(uiData.pub_url->text());
183     m_file->data.languages << uiData.language->itemData(uiData.language->currentIndex()).toString();
184 
185     m_urlWidget->save();
186     m_file->resources.metaurls = metaurls;
187 
188 
189     //store the verification data
190     for (int i = 0; i < m_verificationModel->rowCount(); ++i) {
191         const QString type = m_verificationModel->index(i, VerificationModel::Type).data().toString();
192         const QString hash = m_verificationModel->index(i, VerificationModel::Checksum).data().toString();
193         m_file->verification.hashes[type] = hash;
194     }
195     m_file->verification.pieces = pieces;
196 
197     if (m_edit) {
198         //the file has been edited
199         Q_EMIT fileEdited(m_initialFileName, m_file->name);
200     } else {
201         //a new file should be added, not edited
202         Q_EMIT addFile();
203     }
204 }
205 
206 
207