diff --git a/ui/metalinkcreator/metalinkcreator.cpp b/ui/metalinkcreator/metalinkcreator.cpp index 62701385..c2baff66 100644 --- a/ui/metalinkcreator/metalinkcreator.cpp +++ b/ui/metalinkcreator/metalinkcreator.cpp @@ -1,395 +1,408 @@ /*************************************************************************** * 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 "metalinkcreator.h" #include "filedlg.h" #include "dragdlg.h" #include "localemodels.h" #include "generalwidget.h" #include #include #include #include #include #include #include #include #include #include //TODO for 4.4 look at the changes of the newest Draft --> what elements have to be added/removed FileWidget::FileWidget(QWidget *parent) : QWidget(parent) { setAcceptDrops(true); } void FileWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); } } void FileWidget::dropEvent(QDropEvent *event) { QList urls = event->mimeData()->urls(); event->acceptProposedAction(); if (!urls.isEmpty()) { emit urlsDropped(urls); } } MetalinkCreator::MetalinkCreator(QWidget *parent) : KAssistantDialog(parent), m_needUrlCount(0), m_countrySort(nullptr), m_languageModel(nullptr), m_languageSort(nullptr), m_introduction(nullptr), m_generalPage(nullptr), m_filesModel(nullptr) { create(); connect(finishButton(), &QPushButton::clicked, this, &MetalinkCreator::slotSave); connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slotUpdateAssistantButtons(KPageWidgetItem*,KPageWidgetItem*))); qRegisterMetaType("KGetMetalink::File"); connect(&m_thread, SIGNAL(fileResult(KGetMetalink::File)), this, SLOT(slotAddFile(KGetMetalink::File))); connect(&m_thread, SIGNAL(finished()), this, SLOT(slotThreadFinished())); setWindowTitle(i18n("Create a Metalink")); } MetalinkCreator::~MetalinkCreator() { } void MetalinkCreator::slotUpdateAssistantButtons(KPageWidgetItem *to, KPageWidgetItem *from) { //once we leave the introduction page the data is being loaded if (m_introduction && m_generalPage && (from == m_introduction) && (to == m_generalPage)) { load(); } //it is impossible to return to the introduction page backButton()->setEnabled(to != m_generalPage); if (!m_filesModel->rowCount()) { uiFiles.infoWidget->setText(i18n("Add at least one file.")); } else if (m_needUrlCount) { uiFiles.infoWidget->setText(i18n("You need to set mirrors for the entries with an icon.")); } uiFiles.infoWidget->setVisible(!m_filesModel->rowCount() || m_needUrlCount); //only enable finish when the metalink is valid (i.e. no required data missing) //and the thread is not running finishButton()->setEnabled(metalink.isValid() && !m_thread.isRunning()); } void MetalinkCreator::create() { createIntroduction(); m_general = new GeneralWidget(this); m_generalPage = addPage(m_general, i18n("General optional information for the metalink.")); - QTimer::singleShot(0, this, SLOT(slotDelayedCreation())); + QTimer::singleShot(0, this, &MetalinkCreator::slotDelayedCreation); } void MetalinkCreator::slotDelayedCreation() { + QStringList allCountries; + for (int c = 1; c <= QLocale::LastCountry; c++) { + const auto country = static_cast(c); + QLocale locale(QLocale::AnyLanguage, country); + if (locale.country() == country) { + const QString localeName = locale.name(); + const auto idx = localeName.indexOf(QLatin1Char('_')); + if (idx != -1) { + const QString countryCode = localeName.mid(idx + 1); + allCountries.append(countryCode); + } + } + } CountryModel *countryModel = new CountryModel(this); - countryModel->setupModelData(KLocale::global()->allCountriesList()); + countryModel->setupModelData(allCountries); m_countrySort = new QSortFilterProxyModel(this); m_countrySort->setSourceModel(countryModel); m_countrySort->sort(0); m_languageModel = new LanguageModel(this); m_languageModel->setupModelData(KLocale::global()->allLanguagesList()); m_languageSort = new QSortFilterProxyModel(this); m_languageSort->setSourceModel(m_languageModel); m_languageSort->sort(0); createFiles(); slotUpdateIntroductionNextButton(); } void MetalinkCreator::load() { QUrl url = uiIntroduction.load->url(); if (uiIntroduction.loadButton->isChecked() && url.isValid()) { if (!KGetMetalink::HandleMetalink::load(url, &metalink)) { KMessageBox::error(this, i18n("Unable to load: %1", url.toString()), i18n("Error")); } } m_general->load(metalink); loadFiles(); } void MetalinkCreator::slotSave() { m_general->save(&metalink); QUrl url = uiIntroduction.save->url(); if (url.isValid()) { if(!KGetMetalink::HandleMetalink::save(url, &metalink)) { KMessageBox::error(this, i18n("Unable to save to: %1", url.toString()), i18n("Error")); } } } void MetalinkCreator::createIntroduction() { QWidget *widget = new QWidget(this); uiIntroduction.setupUi(widget); uiIntroduction.save->setFilter("*.meta4|" + i18n("Metalink Version 4.0 file (*.meta4)") + "\n*.metalink|" + i18n("Metalink Version 3.0 file (*.metalink)")); uiIntroduction.save->setAcceptMode(QFileDialog::AcceptSave); connect(uiIntroduction.save, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateIntroductionNextButton())); connect(uiIntroduction.load, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateIntroductionNextButton())); connect(uiIntroduction.loadButton, SIGNAL(toggled(bool)), this, SLOT(slotUpdateIntroductionNextButton())); m_introduction = addPage(widget, i18n("Define the saving location.")); setValid(m_introduction, false); } void MetalinkCreator::slotUpdateIntroductionNextButton() { bool enableNext = false; //check if a save location and if selected if also a load location has been specified and if the m_countrySort has been created enableNext = uiIntroduction.save->url().isValid() && m_countrySort; if (enableNext && uiIntroduction.loadButton->isChecked()) { enableNext = uiIntroduction.load->url().isValid(); } setValid(m_introduction, enableNext); } void MetalinkCreator::createFiles() { m_handler = new DirectoryHandler(this); connect(m_handler, SIGNAL(finished()), this, SLOT(slotOpenDragDlg())); FileWidget *widget = new FileWidget(this); uiFiles.setupUi(widget); m_filesModel = new QStandardItemModel(0, 1, this); uiFiles.files->setModel(m_filesModel); uiFiles.infoWidget->setCloseButtonVisible(false); uiFiles.infoWidget->setMessageType(KMessageWidget::Information); uiFiles.add_local_file->setIcon(QIcon::fromTheme("list-add")); KGuiItem::assign(uiFiles.add_file, KStandardGuiItem::add()); KGuiItem::assign(uiFiles.properties_file, KStandardGuiItem::properties()); uiFiles.properties_file->setEnabled(false); KGuiItem::assign(uiFiles.remove_file, KStandardGuiItem::remove()); uiFiles.remove_file->setEnabled(false); uiFiles.dragDrop->hide(); connect(uiFiles.add_local_file, SIGNAL(clicked(bool)), this, SLOT(slotAddLocalFilesClicked())); connect(uiFiles.add_file, SIGNAL(clicked(bool)), this, SLOT(slotAddClicked())); connect(uiFiles.remove_file, SIGNAL(clicked(bool)), this, SLOT(slotRemoveFile())); connect(uiFiles.properties_file, SIGNAL(clicked(bool)), this, SLOT(slotFileProperties())); connect(uiFiles.files->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(slotUpdateFilesButtons())); connect(widget, SIGNAL(urlsDropped(QList)), m_handler, SLOT(slotFiles(QList))); addPage(widget, i18nc("file as in file on hard drive", "Files")); } void MetalinkCreator::loadFiles() { foreach (const KGetMetalink::File &file, metalink.files.files) { QStandardItem *item = new QStandardItem(file.name); if (!file.resources.isValid()) { ++m_needUrlCount; item->setIcon(QIcon::fromTheme("edit-delete")); } m_filesModel->insertRow(m_filesModel->rowCount(), item); } } void MetalinkCreator::slotUpdateFilesButtons() { const QModelIndexList indexes = uiFiles.files->selectionModel()->selectedRows(); uiFiles.remove_file->setEnabled(indexes.count()); bool propertiesEnabled = (indexes.count() == 1); uiFiles.properties_file->setEnabled(propertiesEnabled); } void MetalinkCreator::slotAddLocalFilesClicked() { QPointer dialog = new QFileDialog(this); dialog->setFileMode(QFileDialog::ExistingFiles); if (dialog->exec() == QDialog::Accepted) { m_handler->slotFiles(dialog->selectedUrls()); } delete dialog; } void MetalinkCreator::slotAddFile() { QStandardItem *item = new QStandardItem(m_tempFile.name); m_filesModel->insertRow(m_filesModel->rowCount(), item); metalink.files.files.append(m_tempFile); m_tempFile.clear(); slotUpdateAssistantButtons(nullptr, m_files); } void MetalinkCreator::slotAddFile(const KGetMetalink::File &file) { QStandardItem *item = new QStandardItem(file.name); if (!file.resources.isValid()) { ++m_needUrlCount; item->setIcon(QIcon::fromTheme("edit-delete")); } m_filesModel->insertRow(m_filesModel->rowCount(), item); metalink.files.files.append(file); slotUpdateAssistantButtons(nullptr, m_files); } void MetalinkCreator::slotFileEdited(const QString &oldFileName, const QString &newFileName) { Q_UNUSED(oldFileName) const QModelIndex index = uiFiles.files->selectionModel()->selectedRows().first(); QStandardItem *item = m_filesModel->itemFromIndex(index); item->setText(newFileName); //had no url but has it now if (!item->icon().isNull()) { --m_needUrlCount; item->setIcon(QIcon()); } slotUpdateAssistantButtons(nullptr, m_files); } void MetalinkCreator::slotRemoveFile() { while (uiFiles.files->selectionModel()->hasSelection()) { const QModelIndex index = uiFiles.files->selectionModel()->selectedRows().first(); const QString filePath = index.data().toString(); for (int i = 0; i < metalink.files.files.size(); ++i) { if (metalink.files.files.at(i).name == filePath) { //the entry had not url, so do not count it anymore if (!index.data(Qt::DecorationRole).isNull()) { --m_needUrlCount; } metalink.files.files.removeAt(i); break; } } m_filesModel->removeRow(index.row()); } slotUpdateFilesButtons(); slotUpdateAssistantButtons(nullptr, m_files); } void MetalinkCreator::slotAddClicked() { //no old stored data should be used m_tempFile.clear(); fileDlg(&m_tempFile); } void MetalinkCreator::fileDlg(KGetMetalink::File *file, bool edit) { QStringList currentNames; for (int i = 0; i < m_filesModel->rowCount(); ++i) { currentNames.append(m_filesModel->index(i, 0).data().toString()); } FileDlg *fileDlg = new FileDlg(file, currentNames, m_countrySort, m_languageSort, this, edit); fileDlg->setAttribute(Qt::WA_DeleteOnClose); fileDlg->setWindowModality(Qt::ApplicationModal); fileDlg->show(); connect(fileDlg, SIGNAL(addFile()), this, SLOT(slotAddFile())); connect(fileDlg, SIGNAL(fileEdited(QString,QString)), this, SLOT(slotFileEdited(QString,QString))); } void MetalinkCreator::slotFileProperties() { const QModelIndex index = uiFiles.files->selectionModel()->selectedRows().first(); const QString fileName = index.data().toString(); //search the selected file in metalink for (int i = 0; i < metalink.files.files.count(); ++i) { if (metalink.files.files.at(i).name == fileName) { fileDlg(&metalink.files.files[i], true); break; } } } void MetalinkCreator::slotOpenDragDlg() { m_tempResources.clear(); m_tempCommonData.clear(); DragDlg *dragDlg = new DragDlg(&m_tempResources, &m_tempCommonData, m_countrySort, m_languageSort, this); dragDlg->setAttribute(Qt::WA_DeleteOnClose); dragDlg->show(); connect(dragDlg, SIGNAL(usedTypes(QStringList,bool)), this, SLOT(slotHandleDropped(QStringList,bool))); } void MetalinkCreator::slotHandleDropped(const QStringList &types, bool createPartial) { uiFiles.progressBar->setMaximum(0); uiFiles.dragDrop->show(); m_thread.setData(m_handler->takeFiles(), types, createPartial, m_tempResources, m_tempCommonData); } void MetalinkCreator::slotThreadFinished() { uiFiles.progressBar->setMaximum(10); uiFiles.dragDrop->hide(); slotUpdateAssistantButtons(nullptr, m_files); } diff --git a/ui/mirror/mirrormodel.cpp b/ui/mirror/mirrormodel.cpp index 18c87c79..c3bf7b52 100644 --- a/ui/mirror/mirrormodel.cpp +++ b/ui/mirror/mirrormodel.cpp @@ -1,517 +1,517 @@ /*************************************************************************** * 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 "mirrormodel.h" #include #include #include #include #include MirrorDelegate::MirrorDelegate(QObject *parent) : QStyledItemDelegate(parent), m_countrySort(nullptr) { } MirrorDelegate::MirrorDelegate(QSortFilterProxyModel *countrySort, QObject *parent) : QStyledItemDelegate(parent), m_countrySort(countrySort) { } QWidget *MirrorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option) if (index.isValid()) { if (index.column() == MirrorItem::Url) { KLineEdit *line = new KLineEdit(parent); return line; } else if (index.column() == MirrorItem::Connections) { QSpinBox *numConnections = new QSpinBox(parent); numConnections->setRange(0, 20); return numConnections; } else if (index.column() == MirrorItem::Priority) { QSpinBox *priority = new QSpinBox(parent); priority->setRange(0, 999999); return priority; } else if (index.column() == MirrorItem::Country) { if (m_countrySort) { QComboBox *countrySort = new QComboBox(parent); countrySort->setModel(m_countrySort); return countrySort; } } } return nullptr; } void MirrorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if (index.isValid() && editor) { if (index.column() == MirrorItem::Url) { KLineEdit *line = static_cast(editor); const QUrl url = index.data(Qt::EditRole).toUrl(); line->setUrl(url); } else if (index.column() == MirrorItem::Connections) { QSpinBox *numConnections = static_cast(editor); const int num = index.data(Qt::EditRole).toInt(); numConnections->setValue(num); } else if (index.column() == MirrorItem::Priority) { QSpinBox *priority = static_cast(editor); const int num = index.data(Qt::EditRole).toInt(); priority->setValue(num); } else if (index.column() == MirrorItem::Country) { QComboBox *countrySort = static_cast(editor); const QString countryCode = index.data(Qt::EditRole).toString(); const int indexCountrySort = countrySort->findData(countryCode); countrySort->setCurrentIndex(indexCountrySort); } } } void MirrorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (index.isValid() && editor && model) { if (index.column() == MirrorItem::Url) { KLineEdit *line = static_cast(editor); if (!line->text().isEmpty()) { model->setData(index, line->text()); } } else if (index.column() == MirrorItem::Connections) { QSpinBox *numConnections = static_cast(editor); model->setData(index, numConnections->value()); } else if (index.column() == MirrorItem::Priority) { QSpinBox *priority = static_cast(editor); model->setData(index, priority->value()); } else if (index.column() == MirrorItem::Country) { QComboBox *countrySort = static_cast(editor); const QString countryCode = countrySort->itemData(countrySort->currentIndex()).toString(); model->setData(index, countryCode); } } } void MirrorDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) editor->setGeometry(option.rect); } QSize MirrorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { //make the sizeHint a little bit nicer to have more beautiful editors QSize hint; hint.setWidth(QStyledItemDelegate::sizeHint(option, index).width()); hint.setHeight(option.fontMetrics.height() + 7); return hint; } MirrorProxyModel::MirrorProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { } bool MirrorProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { if (left.column() == MirrorItem::Used) { const int leftData = sourceModel()->data(left, Qt::CheckStateRole).toInt(); const int rightData = sourceModel()->data(right, Qt::CheckStateRole).toInt(); return leftData < rightData; } else if (left.column() == MirrorItem::Priority) { const int leftData = sourceModel()->data(left, Qt::UserRole).toInt(); const int rightData = sourceModel()->data(right, Qt::UserRole).toInt(); return (!leftData ? true : (leftData > rightData) && rightData);//0 is always smallest, otherwise larger is smaller } return QSortFilterProxyModel::lessThan(left, right); } MirrorItem::MirrorItem() : m_checked(Qt::Unchecked), m_numConnections(0), m_priority(0) { } QVariant MirrorItem::data(int column, int role) const { if (column == MirrorItem::Used) { if (role == Qt::CheckStateRole) { return m_checked; } } else if (column == MirrorItem::Url) { if (role == Qt::DisplayRole) { return m_url.toString(); } else if ((role == Qt::UserRole) || (role == Qt::EditRole)) { return QVariant(m_url); } } else if (column == MirrorItem::Connections) { if (role == Qt::DisplayRole) { if (m_numConnections) { return m_numConnections; } else { return i18n("not specified"); } } else if ((role == Qt::EditRole) || (role == Qt::UserRole)) { return m_numConnections; } } else if (column == MirrorItem::Priority) { if (role == Qt::DisplayRole) { if (m_priority) { return m_priority; } else { return i18n("not specified"); } } else if ((role == Qt::EditRole) || (role == Qt::UserRole)) { return m_priority; } } else if (column == MirrorItem::Country) { if (role == Qt::DisplayRole) { return m_countryName; } else if (role == Qt::DecorationRole) { return m_countryFlag; } else if ((role == Qt::UserRole) || (role == Qt::EditRole)) { return m_countryCode; } } return QVariant(); } Qt::ItemFlags MirrorItem::flags(int column) const { Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if (column == MirrorItem::Used) { flags |= Qt::ItemIsUserCheckable; } else if (column == MirrorItem::Url) { flags |= Qt::ItemIsEditable; } else if (column == MirrorItem::Connections) { flags |= Qt::ItemIsEditable; } else if (column == MirrorItem::Priority) { flags |= Qt::ItemIsEditable; } else if (column == MirrorItem::Country) { flags |= Qt::ItemIsEditable; } return flags; } bool MirrorItem::setData(int column, const QVariant &value, int role) { if ((column == MirrorItem::Used) && (role == Qt::CheckStateRole)) { m_checked = static_cast(value.toInt()); return true; } else if ((column == MirrorItem::Url) && (role == Qt::EditRole)) { QUrl url; if (value.type() == QVariant::Url) { url = QUrl(value.toUrl()); } else if (value.type() == QVariant::String) { url = QUrl(value.toString()); } if (!url.isEmpty()) { m_url = url; return true; } } else if ((column == MirrorItem::Connections) && (role == Qt::EditRole)) { m_numConnections = value.toInt(); return true; } else if ((column == MirrorItem::Priority) && (role == Qt::EditRole)) { m_priority = value.toInt(); return true; } else if ((column == MirrorItem::Country) && (role == Qt::EditRole)) { m_countryCode = value.toString(); -// m_countryName = KLocale::global()->countryCodeToName(m_countryCode); -/* + m_countryName = KLocale::global()->countryCodeToName(m_countryCode); + if (!m_countryName.isEmpty()) { QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("locale/") + QString::fromLatin1("l10n/%1/flag.png").arg(m_countryCode)); if (path.isEmpty()) { m_countryFlag = QIcon(); } else { m_countryFlag = QIcon::fromTheme(path); } } else { m_countryFlag = QIcon(); } - return true;*/ + return true; } return false; } MirrorModel::MirrorModel(QObject *parent) : QAbstractTableModel(parent) { } MirrorModel::~MirrorModel() { qDeleteAll(m_data); } int MirrorModel::rowCount(const QModelIndex &index) const { if (!index.isValid()) { return m_data.count(); } else { return 0; } } int MirrorModel::columnCount(const QModelIndex &index) const { if (index.isValid()) { return 0; } return 5; } QVariant MirrorModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Vertical) { return QVariant(); } if ((section == MirrorItem::Url) && (role == Qt::DisplayRole)) { return i18nc("Mirror as in server, in url", "Mirror"); } else if (section == MirrorItem::Priority) { if (role == Qt::DisplayRole) { return i18nc("The priority of the mirror", "Priority"); } else if (role == Qt::DecorationRole) { return QIcon::fromTheme("games-highscores"); } } else if ((section == MirrorItem::Connections) && (role == Qt::DisplayRole)) { return i18nc("Number of paralell connections to the mirror", "Connections"); } else if ((section == MirrorItem::Country) && (role == Qt::DisplayRole)) { return i18nc("Location = country", "Location"); } return QVariant(); } QVariant MirrorModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } return m_data.at(index.row())->data(index.column(), role); } Qt::ItemFlags MirrorModel::flags(const QModelIndex &index) const { if (!index.isValid()) { return 0; } return m_data.at(index.row())->flags(index.column()); } bool MirrorModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) { return false; } const bool changed = m_data.at(index.row())->setData(index.column(), value, role); if (changed) { emit dataChanged(index, index); } return changed; } bool MirrorModel::removeRows(int row, int count, const QModelIndex &parent) { if (parent.isValid() || (row < 0) || (count < 1) || (row + count > rowCount())) { return false; } beginRemoveRows(parent, row, row + count - 1); while (count) { MirrorItem *item = m_data[row]; m_data.removeAt(row); delete item; --count; } endRemoveRows(); return true; } void MirrorModel::addMirror(const QUrl &url, int numConnections, int priority, const QString &countryCode) { if (!url.isValid()) { return; } for (int i = 0; i < rowCount(); ++i) { //exists already, so remove the row if (QUrl(m_data.at(i)->data(MirrorItem::Url).toString()) == url) { removeRow(i); break; } } int index = rowCount(); emit beginInsertRows(QModelIndex(), index, index); MirrorItem *item = new MirrorItem; m_data.append(item); item->setData(MirrorItem::Used, Qt::Checked, Qt::CheckStateRole);//every newly added mirror is set to checked automatically item->setData(MirrorItem::Url, QVariant(url)); item->setData(MirrorItem::Connections, numConnections); item->setData(MirrorItem::Priority, priority); item->setData(MirrorItem::Country, countryCode); emit endInsertRows(); } void MirrorModel::setMirrors(const QHash > &mirrors) { removeRows(0, rowCount()); QHash >::const_iterator it; QHash >::const_iterator itEnd = mirrors.constEnd(); for (it = mirrors.constBegin(); it != itEnd; ++it) { MirrorItem *item = new MirrorItem; item->setData(MirrorItem::Url, QVariant(it.key())); Qt::CheckState state = (*it).first ? Qt::Checked : Qt::Unchecked; item->setData(MirrorItem::Used, state, Qt::CheckStateRole); item->setData(MirrorItem::Connections, (*it).second); m_data.append(item); } emit reset(); } QHash > MirrorModel::availableMirrors() const { QHash > mirrors; foreach (MirrorItem *item, m_data) { bool used = (item->data(MirrorItem::Used, Qt::CheckStateRole).toInt() == Qt::Checked) ? true : false; const QUrl url = QUrl(item->data(MirrorItem::Url).toString()); mirrors[url] = QPair(used, item->data(MirrorItem::Connections, Qt::UserRole).toInt()); } return mirrors; }