/* 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 #include #include #include #include #include #include #include #include #include #include #include "archiveview.h" #include "smglobals.h" ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent), mConstructing(true) { QSettings s; mArchiveModel = static_cast(SmGlobals::instance()->model("ArchiveModel")); connect(mArchiveModel, SIGNAL(needRefresh()), this, SLOT(refreshArchive())); connect(mArchiveModel, SIGNAL(databaseError(QString)), this, SLOT(showDatabaseError(QString))); mProxy = new ArchiveProxy; mProxy->setSourceModel(mArchiveModel); mTree = new ArchiveTree; mTree->setModel(mProxy); mTree->setColumnHidden(ArchiveModel::GenericId, true); mTree->setColumnHidden(ArchiveModel::SeriesPartId, true); mTree->setColumnHidden(ArchiveModel::SeriesPart, true); mTree->setColumnHidden(ArchiveModel::Type, true); mTree->setColumnHidden(ArchiveModel::Favorite, true); mTree->setColumnHidden(ArchiveModel::Subtitle, true); mTree->setColumnHidden(ArchiveModel::Count, true); mTree->resizeColumnToContents(ArchiveModel::Name); mTree->setSortingEnabled(true); mTree->setEditTriggers(QAbstractItemView::NoEditTriggers); connect(mTree, SIGNAL(expanded(QModelIndex)), this, SLOT(expandItem(QModelIndex))); connect(mTree, SIGNAL(collapsed(QModelIndex)), this, SLOT(collapseItem(QModelIndex))); QString sortOrderName = s.value("archivemodel/sortorder", "Series Name").toString(); mSortOrder = new QComboBox; mSortOrder->addItems(mArchiveModel->availableOrders()); mSortOrder->setCurrentText(sortOrderName); // this is _not_ redundant! when sortOrderName is the first // item in the list, nothing will happen otherwise! mArchiveModel->setOrder(sortOrderName); connect(mSortOrder, SIGNAL(currentIndexChanged(QString)), mArchiveModel, SLOT(setOrder(QString))); connect(mArchiveModel, SIGNAL(collectorDone()), this, SLOT(expandedItems())); QLabel *l1 = new QLabel(tr("Filter")); mFilter = new QLineEdit; QString savedFilter = s.value("archivemodel/filter", QString()).toString(); connect(mFilter, SIGNAL(returnPressed()), this, SLOT(setFilter())); QPushButton *filter = new QPushButton(tr("Filter")); connect(filter, SIGNAL(clicked()), this, SLOT(setFilter())); QPushButton *clear = new QPushButton(tr("Clear")); mFilter->setText(savedFilter); connect(clear, SIGNAL(clicked()), this, SLOT(clearFilter())); mProxy->setFilter(savedFilter, currentSortOrder()); QHBoxLayout *filterLayout = new QHBoxLayout; filterLayout->addWidget(l1); filterLayout->addWidget(mFilter); filterLayout->addWidget(filter); filterLayout->addWidget(clear); QVBoxLayout *treeLayout = new QVBoxLayout; treeLayout->addWidget(mSortOrder); treeLayout->addLayout(filterLayout); treeLayout->addWidget(mTree); QWidget *treeWidget = new QWidget; treeWidget->setLayout(treeLayout); mFiles = new ArchiveFiles; QSplitter *treeSplitter = new QSplitter(Qt::Horizontal); treeSplitter->addWidget(treeWidget); treeSplitter->addWidget(mFiles); treeSplitter->setStretchFactor(0, 1); treeSplitter->setStretchFactor(1, 4); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addWidget(treeSplitter); setLayout(mainLayout); } int ArchiveView::currentSortOrder() const { return mArchiveModel->availableOrdersHash().value(mSortOrder->currentText()); } void ArchiveView::readSettings(){ QSettings s; QVariantList list; list = s.value("archivemodel/expandedgenres").toList(); mExpandedItems[ArchiveModel::Genre] = list; list = s.value("archivemodel/expandedactors").toList(); mExpandedItems[ArchiveModel::Actor] = list; list = s.value("archivemodel/expandedseries").toList(); mExpandedItems[ArchiveModel::SeriesName] = list; expandedItems(); } void ArchiveView::writeSettings() { QSettings s; s.setValue("archivemodel/sortorder", mSortOrder->currentText()); s.setValue("archivemodel/filter", mFilter->text()); s.setValue("archivemodel/expandedgenres", mExpandedItems.value(ArchiveModel::Genre)); s.setValue("archivemodel/expandedactors", mExpandedItems.value(ArchiveModel::Actor)); s.setValue("archivemodel/expandedseries", mExpandedItems.value(ArchiveModel::SeriesName)); } void ArchiveView::refreshArchive(){ writeSettings(); mArchiveModel->refresh(); expandedItems(); } void ArchiveView::expandedItems(){ QVariantList list = mExpandedItems.value(currentSortOrder()); foreach(QVariant p, list){ QStringList path = p.toStringList(); QModelIndexList expand = mArchiveModel->pathToIndex(path); foreach(QModelIndex idx, expand){ mTree->setExpanded(mProxy->mapFromSource(idx), true); } } } void ArchiveView::setFilter(){ QString filter = mFilter->text(); mProxy->setFilter(filter, currentSortOrder()); mTree->expandAll(); } void ArchiveView::clearFilter(){ mFilter->clear(); mProxy->setFilter(QString(), currentSortOrder()); mTree->collapseAll(); } void ArchiveView::showDatabaseError(const QString &errorMsg){ QMessageBox::critical(this, tr("Database Error"), errorMsg); } void ArchiveView::expandItem(const QModelIndex &idx){ QModelIndex realIdx = mProxy->mapToSource(idx); if(realIdx.isValid()){ QStringList path = mArchiveModel->indexToPath(realIdx); QVariantList list = mExpandedItems.value(currentSortOrder()); if(!list.contains(path)){ list << mArchiveModel->indexToPath(realIdx); } mExpandedItems[currentSortOrder()] = list; } } void ArchiveView::collapseItem(const QModelIndex &idx){ QModelIndex realIdx = mProxy->mapToSource(idx); if(realIdx.isValid()){ QVariantList list = mExpandedItems.value(currentSortOrder()); list.removeAll(mArchiveModel->indexToPath(realIdx)); mExpandedItems[currentSortOrder()] = list; } } ArchiveTree::ArchiveTree(QWidget *parent) : SmTreeView(parent) {} void ArchiveTree::setModel(ArchiveProxy *model){ mProxy = model; mModel = qobject_cast(mProxy->sourceModel()); QTreeView::setModel(model); } void ArchiveTree::rename(){ QModelIndex idx = currentIndex(); int nodeType = idx.data(ArchiveModel::TypeRole).toInt(); if(nodeType == ArchiveModel::SeriesPartNode){ impossible(); return; } QString currentName = idx.data(ArchiveModel::NameRole).toString(); QString question = QString(tr("Rename %1 to:")).arg(currentName); QString newName = QInputDialog::getText(this, tr("Rename"), question, QLineEdit::Normal, currentName); if(!newName.isEmpty()){ QModelIndex realIdx = mProxy->mapToSource(idx); mModel->setData(realIdx, newName, Qt::EditRole); } } void ArchiveTree::remove(){ QModelIndex idx = currentIndex(); QModelIndex realIdx = mProxy->mapToSource(idx); QString warningMsg = QString("Really remove %1?").arg(idx.data().toString()); int retval = QMessageBox::warning(this, tr("Question"), warningMsg, QMessageBox::Yes | QMessageBox::No); if(retval == QMessageBox::Yes){ if(!mModel->removeNode(realIdx)){ impossible(); } } } void ArchiveTree::impossible(const QString msg){ QMessageBox::critical(this, tr("Error"), msg); } ArchiveFiles::ArchiveFiles(QWidget *parent) : SmTreeView(parent){ } ArchiveProxy::ArchiveProxy(QObject *parent) : QSortFilterProxyModel(parent) {} void ArchiveProxy::setFilter(const QString &filter, int sortOrder){ mFilter = QRegExp(filter); mSortOrder = sortOrder; invalidateFilter(); } bool ArchiveProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { if(mFilter.isEmpty()){ return true; } QModelIndex nameIdx = sourceModel()->index(sourceRow, ArchiveModel::Name, sourceParent); ArchiveModel *model = qobject_cast(sourceModel()); return model->matchRecursive(nameIdx, mFilter); }