# # # patch "src/model/InventoryModel.cpp" # from [b306a75c202e78afa1726f3706ed7363bb17debf] # to [e82024895abd0fba88629090ded9a710dd2e4278] # # patch "src/model/InventoryModel.h" # from [1915c6ef78d7902a9fe55d206e8c6ea6de564ce5] # to [01990ea3beecefff8b773a31a92bd29c60276a69] # # patch "src/view/mainwindows/WorkspaceWindow.cpp" # from [718be72da88aedfa117a74d4e28de20c36b21ae8] # to [0db6f77e3e81641722c35458c873cba38e68f2e6] # # patch "src/view/mainwindows/WorkspaceWindow.h" # from [b611ad3e5d0a89657582a0bc2c718d93c7e528ab] # to [1ca261b3d08d4593f25670bbbfbf389c0ad16bc5] # # patch "src/view/widgets/InventoryView.cpp" # from [acf136cdfe5e8e591de5d50ec4fad199e4caf644] # to [e5e62dbf86bd44a4cf7b48a1cc26546cc82f2408] # # patch "src/view/widgets/InventoryView.h" # from [f05ba7b23f419f5540c42036dbdeb26cafeb799a] # to [9e4eb7d1b4540f44a9f2bf3e9f09c87c4dc5479a] # ============================================================ --- src/model/InventoryModel.cpp b306a75c202e78afa1726f3706ed7363bb17debf +++ src/model/InventoryModel.cpp e82024895abd0fba88629090ded9a710dd2e4278 @@ -17,6 +17,7 @@ ***************************************************************************/ #include "InventoryModel.h" +#include "MonotoneProcess.h" InventoryModel::InventoryModel(QObject * parent) : QAbstractItemModel(parent), inventory() @@ -371,3 +372,88 @@ void InventoryModel::triggerDataChanged( emit dataChanged(indexFromItem(item, 0), indexFromItem(item, 2)); } +void InventoryModel::runWorkspaceCommand(const QStringList & args) +{ + MonotoneProcess proc(workspacePath); + proc.start(args); + proc.waitForFinished(); + + if (!proc.successful()) + { + emit workspaceCommandError(proc.getBufferedOutput()); + } +} + +void InventoryModel::addPaths(const QStringList & paths) +{ + QStringList args; + args << "add" << "--recursive"; + args += paths; + + runWorkspaceCommand(args); +} + +void InventoryModel::dropPaths(const QStringList & paths) +{ + QStringList args; + args << "drop" << "--recursive"; + args += paths; + + runWorkspaceCommand(args); +} + +void InventoryModel::revertPaths(const QStringList & paths) +{ + QStringList args; + args << "revert"; + args += paths; + + runWorkspaceCommand(args); +} + +void InventoryModel::ignorePaths(const QStringList & paths) +{ + QString path(workspacePath); + path.append(QDir::separator()).append(".mtn-ignore"); + + QFile file(path); + if (!file.open(QIODevice::WriteOnly)) + { + emit workspaceCommandError( + tr("could not open .mtn-ignore for writing") + ); + return; + } + + foreach (QString path, paths) + { + file.write(QRegExp::escape(path).toUtf8() + "\n"); + } + file.close(); +} + +void InventoryModel::unignorePaths(const QStringList & paths) +{ + QString path(workspacePath); + path.append(QDir::separator()).append(".mtn-ignore"); + + QFile file(path); + if (!file.open(QIODevice::ReadWrite)) + { + emit workspaceCommandError( + tr("could not open .mtn-ignore for reading and writing") + ); + return; + } + + QString data = QString::fromUtf8(file.readAll().data()); + foreach (QString path, paths) + { + data.replace(QRegExp::escape(path).toUtf8() + "\n", ""); + } + + file.resize(0); + file.write(data.toUtf8()); + file.close(); +} + ============================================================ --- src/model/InventoryModel.h 1915c6ef78d7902a9fe55d206e8c6ea6de564ce5 +++ src/model/InventoryModel.h 01990ea3beecefff8b773a31a92bd29c60276a69 @@ -54,8 +54,15 @@ public slots: void setWorkspacePath(const WorkspacePath &); void refresh(const QString & path = QString()); + void addPaths(const QStringList &); + void dropPaths(const QStringList &); + void revertPaths(const QStringList &); + void ignorePaths(const QStringList &); + void unignorePaths(const QStringList &); + private: QModelIndex indexFromItem(ModelItem *, int) const; + void runWorkspaceCommand(const QStringList &); Inventory * inventory; WorkspacePath workspacePath; @@ -77,6 +84,7 @@ signals: void invalidWorkspaceFormat(); void pathsInserted(const QStringList &); void pathsRemoved(const QStringList &); + void workspaceCommandError(const QString &); }; #endif ============================================================ --- src/view/mainwindows/WorkspaceWindow.cpp 718be72da88aedfa117a74d4e28de20c36b21ae8 +++ src/view/mainwindows/WorkspaceWindow.cpp 0db6f77e3e81641722c35458c873cba38e68f2e6 @@ -207,6 +207,12 @@ void WorkspaceWindow::setup() // models invModel = new InventoryModel(this); + + connect( + invModel, SIGNAL(workspaceCommandError(const QString &)), + this, SLOT(workspaceCommandError(const QString &)) + ); + invWatcher = new InventoryWatcher(this); attrModel = new GetAttributes(this); @@ -297,6 +303,56 @@ void WorkspaceWindow::setup() invModel, SLOT(refresh(const QString &)) ); + connect( + treeView, SIGNAL(addPaths(const QStringList &)), + invModel, SLOT(addPaths(const QStringList &)) + ); + + connect( + listView, SIGNAL(addPaths(const QStringList &)), + invModel, SLOT(addPaths(const QStringList &)) + ); + + connect( + treeView, SIGNAL(dropPaths(const QStringList &)), + invModel, SLOT(dropPaths(const QStringList &)) + ); + + connect( + listView, SIGNAL(dropPaths(const QStringList &)), + invModel, SLOT(dropPaths(const QStringList &)) + ); + + connect( + treeView, SIGNAL(revertPaths(const QStringList &)), + invModel, SLOT(revertPaths(const QStringList &)) + ); + + connect( + listView, SIGNAL(revertPaths(const QStringList &)), + invModel, SLOT(revertPaths(const QStringList &)) + ); + + connect( + treeView, SIGNAL(ignorePaths(const QStringList &)), + invModel, SLOT(ignorePaths(const QStringList &)) + ); + + connect( + listView, SIGNAL(ignorePaths(const QStringList &)), + invModel, SLOT(ignorePaths(const QStringList &)) + ); + + connect( + treeView, SIGNAL(unignorePaths(const QStringList &)), + invModel, SLOT(unignorePaths(const QStringList &)) + ); + + connect( + listView, SIGNAL(unignorePaths(const QStringList &)), + invModel, SLOT(unignorePaths(const QStringList &)) + ); + attrView->setModel(attrModel); iconHelp = new IconHelp(this); @@ -420,3 +476,13 @@ void WorkspaceWindow::workspaceUpdated(c invModel->refresh(); } +void WorkspaceWindow::workspaceCommandError(const QString & error) +{ + QMessageBox::critical( + this, + tr("Error"), + tr("Unable to execute workspace action: %1").arg(error), + QMessageBox::Ok, 0, 0 + ); +} + ============================================================ --- src/view/mainwindows/WorkspaceWindow.h b611ad3e5d0a89657582a0bc2c718d93c7e528ab +++ src/view/mainwindows/WorkspaceWindow.h 1ca261b3d08d4593f25670bbbfbf389c0ad16bc5 @@ -72,6 +72,7 @@ private slots: void maybeReadNodeInfo(const QModelIndexList &); void workspaceUpdated(const QString &); void invalidWorkspaceFormat(); + void workspaceCommandError(const QString &); void openFile(const QString &); }; ============================================================ --- src/view/widgets/InventoryView.cpp acf136cdfe5e8e591de5d50ec4fad199e4caf644 +++ src/view/widgets/InventoryView.cpp e5e62dbf86bd44a4cf7b48a1cc26546cc82f2408 @@ -620,6 +620,8 @@ void InventoryView::slotRemove() if (items.size() == 0) return; QStringList paths; + int pathsWithChanges = 0; + foreach (const ModelItem * item, items) { const InventoryItem * invitem = dynamic_cast(item); @@ -653,6 +655,12 @@ void InventoryView::slotRemove() ); return; } + if ((status & InventoryItem::ContentsChanged) == InventoryItem::ContentsChanged || + (status & InventoryItem::AttributesChanged) == InventoryItem::AttributesChanged) + { + pathsWithChanges++; + } + paths.push_back(path); } @@ -667,6 +675,20 @@ void InventoryView::slotRemove() return; } + if (pathsWithChanges > 0) + { + QMessageBox::StandardButton btn = QMessageBox::question( + this, + tr("Items have changes"), + tr("%n out of %1 item(s) have changes which cannot " + "be reverted after the removal. Are you sure you " + "want to continue?", "", pathsWithChanges).arg(paths.size()), + QMessageBox::Yes | QMessageBox::No + ); + + if (btn == QMessageBox::No) return; + } + emit dropPaths(paths); } @@ -758,7 +780,47 @@ void InventoryView::slotRevert() void InventoryView::slotRevert() { - C("Not implemented."); + QSet items = getSelectedItems(); + if (items.size() == 0) return; + + QStringList paths; + + foreach (const ModelItem * item, items) + { + const InventoryItem * invitem = dynamic_cast(item); + + if (!invitem) + continue; + + if (!invitem->hasChangedRecursive()) + continue; + + QString path = invitem->getPath(); + paths.push_back(path); + } + + if (paths.size() == 0) + { + QMessageBox::information( + this, + tr("Items can't be reverted"), + tr("None of the selected items can be reverted."), + QMessageBox::Ok + ); + return; + } + + QMessageBox::StandardButton btn = QMessageBox::question( + this, + tr("Revert items"), + tr("Are you sure you want to revert the selected items? " + "This action cannot be undone."), + QMessageBox::Yes | QMessageBox::No + ); + + if (btn == QMessageBox::No) return; + + emit revertPaths(paths); } void InventoryView::slotRename() @@ -774,12 +836,72 @@ void InventoryView::slotIgnore() // void InventoryView::slotIgnore() { - C("Not implemented."); + QSet items = getSelectedItems(); + if (items.size() == 0) return; + + QStringList paths; + + foreach (const ModelItem * item, items) + { + const InventoryItem * invitem = dynamic_cast(item); + + if (!invitem) + continue; + + if (invitem->hasNotStatus(InventoryItem::Unknown)) + continue; + + QString path = invitem->getPath(); + paths.push_back(path); + } + + if (paths.size() == 0) + { + QMessageBox::information( + this, + tr("Items can't be ignored"), + tr("None of the selected items can be ignored."), + QMessageBox::Ok + ); + return; + } + + emit ignorePaths(paths); } void InventoryView::slotUnignore() { - C("Not implemented."); + QSet items = getSelectedItems(); + if (items.size() == 0) return; + + QStringList paths; + + foreach (const ModelItem * item, items) + { + const InventoryItem * invitem = dynamic_cast(item); + + if (!invitem) + continue; + + if (invitem->hasNotStatus(InventoryItem::Ignored)) + continue; + + QString path = invitem->getPath(); + paths.push_back(path); + } + + if (paths.size() == 0) + { + QMessageBox::information( + this, + tr("Items can't be unignored"), + tr("None of the selected items can be unignored."), + QMessageBox::Ok + ); + return; + } + + emit unignorePaths(paths); } void InventoryView::slotFileDiff() ============================================================ --- src/view/widgets/InventoryView.h f05ba7b23f419f5540c42036dbdeb26cafeb799a +++ src/view/widgets/InventoryView.h 9e4eb7d1b4540f44a9f2bf3e9f09c87c4dc5479a @@ -51,6 +51,9 @@ signals: void refreshPath(const QString &); void addPaths(const QStringList &); void dropPaths(const QStringList &); + void revertPaths(const QStringList &); + void ignorePaths(const QStringList &); + void unignorePaths(const QStringList &); private: enum DefaultAction { None, Chdir, Open, FileDiff, Commit };