/* 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 #include "seriestreewidget.h" #include "smtreemodel.h" #include "smmodelsingleton.h" #include "seriestreemodel.h" SeriesTreeWidget::SeriesTreeWidget(QWidget *parent) : QWidget(parent){ //filter bar QLabel *l1 = new QLabel(tr("&Filter:")); mFilterEdit = new QLineEdit; l1->setBuddy(mFilterEdit); mFilter = new QPushButton(tr("Filter")); QHBoxLayout *filterLayout = new QHBoxLayout; connect(mFilter, SIGNAL(clicked()), this, SLOT(filter())); connect(mFilterEdit, SIGNAL(returnPressed()), this, SLOT(filter())); filterLayout->addWidget(l1); filterLayout->addWidget(mFilterEdit); filterLayout->addWidget(mFilter); //the view mView = new SeriesTreeView; mProxy = new SeriesTreeSortModel(this); mModel = static_cast(SmModelSingleton::instance()->model("SeriesModel")); mProxy->setSourceModel(mModel); mView->setModel(mProxy); mView->setSortingEnabled(true); for(int i = 1; i < 5 ;++i){ mView->setColumnHidden(i, true); } mView->resizeColumnToContents(0); mView->setSelectionMode(QAbstractItemView::ExtendedSelection); connect(mModel, SIGNAL(needResort()), this, SLOT(resort())); connect(mView, SIGNAL(expanded(QModelIndex)), this, SLOT(itemExpanded(QModelIndex))); connect(mView, SIGNAL(collapsed(QModelIndex)), this, SLOT(itemCollaped(QModelIndex))); //layout QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(filterLayout); mainLayout->addWidget(mView); setLayout(mainLayout); } QModelIndexList SeriesTreeWidget::mapToSource(const QModelIndexList &indexes) const{ QModelIndexList retval; foreach(QModelIndex i, indexes){ retval << mProxy->mapToSource(i); } return retval; } void SeriesTreeWidget::newSeries(){ QList data; data << tr("") << QVariant() << QVariant() << QVariant() << SeriesTreeModel::NewSeries; if(mModel->addRow(data, QModelIndex())){ QModelIndex newRow = mModel->index(mModel->rowCount(QModelIndex()) - 1, 0, QModelIndex()); if(newRow.isValid()){ QModelIndex proxyIndex = mProxy->mapFromSource(newRow); mView->selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect); mView->edit(proxyIndex); } } } void SeriesTreeWidget::deleteFromSeries(){ QModelIndexList selected = mView->selectionModel()->selectedRows(); if(selected.isEmpty()){ return; } QList series; QList parts; foreach(QModelIndex s, selected){ QModelIndex real = mProxy->mapToSource(s); if(real.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::Series || real.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::NewSeries){ series << QPersistentModelIndex(real); } if(real.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::Part){ parts << QPersistentModelIndex(real); } } QList removeParts; foreach(QPersistentModelIndex s, parts){ if(series.contains(s.parent())){ removeParts << s; } } foreach(QPersistentModelIndex s, removeParts){ parts.removeAll(s); } QFileInfoList files; foreach(QPersistentModelIndex s, series){ files.append(mModel->findFiles(s)); } QString message; if(!files.isEmpty()){ message = QString(tr("

This operation will delete %1 file(s) permanently:

")).arg(files.count()); message.append(tr("
    ")); int ctr = 0; foreach(QFileInfo f, files){ ++ctr; QString li = QString(tr("
  • %1
  • ")).arg(f.absoluteFilePath()); message.append(li); if(ctr == 20){ QString elide = QString(tr("
  • (%1 more files)
  • ")).arg(files.count() - ctr); message.append(elide); break; } } message.append(tr("
")); message.append(tr("

Continue?

")); }else{ message = QString(tr("

This operation will delete no files. Continue?

")); } int retval = QMessageBox::critical(this, tr("Delete Series"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if(retval == QMessageBox::Yes){ foreach(QPersistentModelIndex s, series){ mModel->deleteFromSeries(s); } foreach(QPersistentModelIndex s, parts){ mModel->deleteFromSeries(s); } } } void SeriesTreeWidget::readSettings(){ QSettings s; QStringList expanded = s.value("archive/expanded").toStringList(); foreach(QString s, expanded){ QModelIndex idx = mProxy->mapFromSource(mModel->findValue(s)); mView->expand(idx); mExpandedItems << s; } int sortOrder = s.value("archive/sortorder", Qt::DescendingOrder).toInt(); mView->sortByColumn(0, static_cast(sortOrder)); } void SeriesTreeWidget::writeSettings(){ QSettings s; s.setValue("archive/expanded", mExpandedItems); s.setValue("archive/sortorder", mProxy->sortOrder()); } void SeriesTreeWidget::expandCurrent(){ QModelIndexList selected = mView->selectionModel()->selectedRows(); if(selected.isEmpty()){ return; } QModelIndex idx = selected.at(0); mView->expand(idx); } void SeriesTreeWidget::filter(){ mProxy->setFilterRegExp(mFilterEdit->text()); } void SeriesTreeWidget::resort(){ mView->sortByColumn(0, mProxy->sortOrder()); mView->scrollTo(mView->selectionModel()->currentIndex(), QAbstractItemView::PositionAtCenter); } void SeriesTreeWidget::itemExpanded(const QModelIndex &what){ mExpandedItems << what.data(SeriesTreeModel::NameRole).toString(); } void SeriesTreeWidget::itemCollaped(const QModelIndex &what){ QString itemName = what.data(SeriesTreeModel::NameRole).toString(); if(mExpandedItems.contains(itemName)){ mExpandedItems.removeAll(itemName); } } SeriesTreeView::SeriesTreeView(QWidget *parent) : QTreeView(parent) {} void SeriesTreeView::contextMenuEvent(QContextMenuEvent *e){ QMenu contextMenu(this); foreach(QAction *a, actions()){ contextMenu.addAction(a); } contextMenu.exec(e->globalPos()); } SeriesTreeSortModel::SeriesTreeSortModel(QObject *parent) : QSortFilterProxyModel(parent) {} bool SeriesTreeSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const{ if(left.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::Part && right.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::Part){ return left.data(SeriesTreeModel::SeriesPartRole).toInt() < right.data(SeriesTreeModel::SeriesPartRole).toInt(); } return QSortFilterProxyModel::lessThan(left, right); }