diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-08-15 21:57:08 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-11-03 11:39:07 -0500 |
| commit | 14d15070c8b24e73297a6f37132b8ad5c6e966ef (patch) | |
| tree | f16ef1e224d73cb8f27c9fb208486f017f994fe4 /src | |
| parent | 003ef66d2ff8e83e864d362f152a6f87ae05cbc4 (diff) | |
added checkboxes for deleting instances
disabled instance conversion buttons again, not implemented
Diffstat (limited to 'src')
| -rw-r--r-- | src/instancemanagerdialog.cpp | 178 | ||||
| -rw-r--r-- | src/instancemanagerdialog.ui | 22 |
2 files changed, 104 insertions, 96 deletions
diff --git a/src/instancemanagerdialog.cpp b/src/instancemanagerdialog.cpp index a91e3d92..5810a255 100644 --- a/src/instancemanagerdialog.cpp +++ b/src/instancemanagerdialog.cpp @@ -29,6 +29,29 @@ QString iniFile(const QDir& dir) class InstanceInfo { public: + struct Object + { + QString path; + bool mandatoryDelete; + + Object(QString p, bool d=false) + : path(std::move(p)), mandatoryDelete(d) + { + } + + bool operator<(const Object& o) const + { + if (mandatoryDelete && !o.mandatoryDelete) { + return true; + } else if (!mandatoryDelete && o.mandatoryDelete) { + return false; + } + + return false; + } + }; + + InstanceInfo(QDir dir, bool isPortable) : m_dir(std::move(dir)), m_portable(isPortable), m_settings(iniFile(dir)) { @@ -98,7 +121,7 @@ public: // returns a list of files and folders that must be deleted when deleting // this instance // - QStringList filesForDeletion() const + std::vector<Object> objectsForDeletion() const { // native separators and ending slash auto prettyDir = [](auto s) { @@ -151,47 +174,48 @@ public: // directories that might contain the individual files and directories // set in the path settings - QStringList roots; + std::vector<Object> roots; // a portable instance has its location in the installation directory, // don't delete that if (!isPortable()) { - roots.append(loc); + roots.push_back({loc, true}); } // the base directory is the location directory by default, don't add it // if it's the same if (canonicalDir(base) != canonicalDir(loc)) { - roots.append(base); + roots.push_back({base, false}); } - // all the directories that are part of an instance - const QStringList dirs = { + // all the directories that are part of an instance; none of them are + // mandatory for deletion + const std::vector<Object> dirs = { m_settings.paths().downloads(), m_settings.paths().mods(), - m_settings.paths().overwrite(), - m_settings.paths().profiles(), m_settings.paths().cache(), + m_settings.paths().profiles(), + m_settings.paths().overwrite(), m_dir.filePath(QString::fromStdWString(AppConfig::dumpsDir())), m_dir.filePath(QString::fromStdWString(AppConfig::logPath())), }; // all the files that are part of an instance - const QStringList files = { - iniFile(m_dir), + const std::vector<Object> files = { + {iniFile(m_dir), true}, // the ini file must be deleted }; // this will contain the root directories, plus all the individual // directories that are not inside these roots - QStringList cleanDirs; + std::vector<Object> cleanDirs; for (const auto& f : dirs) { bool inRoots = false; for (const auto& root : roots) { - if (dirInRoot(root, f)) { + if (dirInRoot(root.path, f.path)) { inRoots = true; break; } @@ -199,28 +223,29 @@ public: if (!inRoots) { // not in roots, this is a path that was changed by the user - cleanDirs.append(prettyDir(f)); + cleanDirs.push_back({prettyDir(f.path), f.mandatoryDelete}); } } - // adding the roots - for (const auto& root : roots) { - cleanDirs.append(prettyDir(root)); + // prepending the roots + for (auto itor=roots.rbegin(); itor!=roots.rend(); ++itor) { + cleanDirs.insert( + cleanDirs.begin(), + {prettyDir(itor->path), itor->mandatoryDelete}); } - cleanDirs.sort(Qt::CaseInsensitive); // this will contain the individual files that are not inside the roots; // not that this only contains the INI file for now, so most of this is // useless - QStringList cleanFiles; + std::vector<Object> cleanFiles; for (const auto& f : files) { bool inRoots = false; for (const auto& root : roots) { - if (fileInRoot(root, f)) { + if (fileInRoot(root.path, f.path)) { inRoots = true; break; } @@ -228,17 +253,18 @@ public: if (!inRoots) { // not in roots, this is a path that was changed by the user - cleanFiles.append(prettyFile(f)); + cleanFiles.push_back({prettyFile(f.path), f.mandatoryDelete}); } } - cleanFiles.sort(Qt::CaseInsensitive); - // contains all the directories and files to be deleted - QStringList all; - all.append(cleanDirs); - all.append(cleanFiles); + std::vector<Object> all; + all.insert(all.end(), cleanDirs.begin(), cleanDirs.end()); + all.insert(all.end(), cleanFiles.begin(), cleanFiles.end()); + + // mandatory on top + std::stable_sort(all.begin(), all.end()); return all; } @@ -534,60 +560,65 @@ void InstanceManagerDialog::deleteInstance() const auto Delete = QMessageBox::Yes; const auto Cancel = QMessageBox::Cancel; - const auto files = i->filesForDeletion(); + const auto files = i->objectsForDeletion(); MOBase::TaskDialog dlg(this); dlg - .title(("Deleting instance")) - .main(QObject::tr("These files and folders will be deleted")) + .title(tr("Deleting instance")) + .main(tr("These files and folders will be deleted")) + .content(tr("All checked items will be deleted.")) .icon(QMessageBox::Warning) .button({tr("Move to the recycle bin"), Recycle}) .button({tr("Delete permanently"), Delete}) .button({tr("Cancel"), Cancel}); - auto* list = new QPlainTextEdit(); - list->setReadOnly(true); - list->setWordWrapMode(QTextOption::NoWrap); - list->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + auto* list = new QListWidget(); + list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); list->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - list->setMaximumHeight(150); + list->setMaximumHeight(160); for (const auto& f : files) { - list->appendPlainText(f); - } + auto* item = new QListWidgetItem(f.path); + + if (f.mandatoryDelete) { + item->setFlags(item->flags() & (~Qt::ItemIsEnabled)); + } else { + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + } - list->moveCursor(QTextCursor::MoveOperation::Start); + item->setCheckState(Qt::Checked); + list->addItem(item); + } dlg.addContent(list); + const auto r = dlg.exec(); - switch (r) - { - case Recycle: - { - if (!doDelete(files, true)) { - return; - } + if (r != Recycle && r != Delete) { + return; + } - break; - } - case Delete: - { - if (!doDelete(files, false)) { - return; - } + QStringList selected; - break; + for (int i=0; i<list->count(); ++i) { + if (list->item(i)->checkState() == Qt::Checked) { + selected.append(list->item(i)->text()); } + } - case Cancel: // fall-through - default: - { - return; - } + if (selected.isEmpty()) { + QMessageBox::information( + this, tr("Deleting instance"), tr("Nothing to delete.")); + + return; + } + + if (!doDelete(selected, (r == Recycle))) { + return; } updateInstances(); @@ -613,39 +644,12 @@ bool InstanceManagerDialog::doDelete(const QStringList& files, bool recycle) void InstanceManagerDialog::convertToGlobal() { - const auto* i = singleSelection(); - if (!i) { - return; - } - - if (!i->isPortable()) { - log::error("can't convert to global, this is not a portable instance"); - return; - } - - const auto& m = InstanceManager::instance(); - - const auto name = getInstanceName( - this, - tr("Convert to global instance"), - tr( - "This will move all the instance data currently in Mod Organizer's " - "installation folder into a global instance. If the operation fails or " - "is cancelled, no data should be lost, but the move will need to be " - "completed or cleaned up manually.<br><br>" - "Source: %1<br>" - "Destination: %2") - .arg(i->location()) - .arg(QDir::toNativeSeparators(m.instancesPath())), - tr("Name of the new instance")); - - if (name.isEmpty()) { - return; - } + // not implemented } void InstanceManagerDialog::convertToPortable() { + // not implemented } void InstanceManagerDialog::onSelection() @@ -725,6 +729,10 @@ void InstanceManagerDialog::fillData(const InstanceInfo& ii) ui->convertToPortable->setToolTip(""); } } + + // not implemented, hide the buttons + ui->convertToPortable->setVisible(false); + ui->convertToGlobal->setVisible(false); } void InstanceManagerDialog::clearData() diff --git a/src/instancemanagerdialog.ui b/src/instancemanagerdialog.ui index b2abfa4b..414d4982 100644 --- a/src/instancemanagerdialog.ui +++ b/src/instancemanagerdialog.ui @@ -309,6 +309,17 @@ </widget> </item> <item> + <widget class="QPushButton" name="deleteInstance"> + <property name="text"> + <string>Delete instance</string> + </property> + <property name="icon"> + <iconset resource="resources.qrc"> + <normaloff>:/MO/gui/remove</normaloff>:/MO/gui/remove</iconset> + </property> + </widget> + </item> + <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -321,17 +332,6 @@ </property> </spacer> </item> - <item> - <widget class="QPushButton" name="deleteInstance"> - <property name="text"> - <string>Delete instance</string> - </property> - <property name="icon"> - <iconset resource="resources.qrc"> - <normaloff>:/MO/gui/remove</normaloff>:/MO/gui/remove</iconset> - </property> - </widget> - </item> </layout> </widget> </item> |
