# # # patch "src/model/InventoryModel.cpp" # from [5a2e4dd08f8c4356601d24ead5fe434f27e38164] # to [eff4e055808cb691fe5be4b3b30f3aae7c27adba] # # patch "src/model/InventoryModel.h" # from [b97a6e7d1d8eb4cdc052765d5808e0905d24d397] # to [35bf3a8954e46ffa15de39942e2bace8623723b7] # # patch "src/view/mainwindows/WorkspaceWindow.cpp" # from [0db6f77e3e81641722c35458c873cba38e68f2e6] # to [9971a3d11bd369c22873bff455f6228fb3a1d45c] # # patch "src/view/widgets/InventoryView.cpp" # from [e5e62dbf86bd44a4cf7b48a1cc26546cc82f2408] # to [4f3d0251a3dec816b3c0b510ba75991e3d0f65e2] # # patch "src/view/widgets/InventoryView.h" # from [9e4eb7d1b4540f44a9f2bf3e9f09c87c4dc5479a] # to [ac58d3b7ec668ea50d13c8b2260d82b8b7e514fb] # ============================================================ --- src/model/InventoryModel.cpp 5a2e4dd08f8c4356601d24ead5fe434f27e38164 +++ src/model/InventoryModel.cpp eff4e055808cb691fe5be4b3b30f3aae7c27adba @@ -442,6 +442,30 @@ void InventoryModel::renamePath(const QS runWorkspaceCommand(args); } +void InventoryModel::newFile(const QString & path) +{ + QFile file(workspacePath + "/" + path); + if (!file.open(QIODevice::ReadWrite)) + { + emit workspaceCommandError(tr("Could not create file %1").arg(path)); + return; + } + file.close(); + + addPaths(QStringList() << path); +} + +void InventoryModel::newDirectory(const QString & path) +{ + QDir workspace(workspacePath); + if (!workspace.mkpath(path)) + { + emit workspaceCommandError(tr("Could not create directory %1").arg(path)); + return; + } + addPaths(QStringList() << path); +} + void InventoryModel::ignorePaths(const QStringList & paths) { QString path(workspacePath); ============================================================ --- src/model/InventoryModel.h b97a6e7d1d8eb4cdc052765d5808e0905d24d397 +++ src/model/InventoryModel.h 35bf3a8954e46ffa15de39942e2bace8623723b7 @@ -61,6 +61,8 @@ public slots: void renamePath(const QString &, const QString &); void ignorePaths(const QStringList &); void unignorePaths(const QStringList &); + void newFile(const QString &); + void newDirectory(const QString &); private: QModelIndex indexFromItem(ModelItem *, int) const; ============================================================ --- src/view/mainwindows/WorkspaceWindow.cpp 0db6f77e3e81641722c35458c873cba38e68f2e6 +++ src/view/mainwindows/WorkspaceWindow.cpp 9971a3d11bd369c22873bff455f6228fb3a1d45c @@ -353,6 +353,16 @@ void WorkspaceWindow::setup() invModel, SLOT(unignorePaths(const QStringList &)) ); + connect( + listView, SIGNAL(newFile(const QString &)), + invModel, SLOT(newFile(const QString &)) + ); + + connect( + listView, SIGNAL(newDirectory(const QString &)), + invModel, SLOT(newDirectory(const QString &)) + ); + attrView->setModel(attrModel); iconHelp = new IconHelp(this); ============================================================ --- src/view/widgets/InventoryView.cpp e5e62dbf86bd44a4cf7b48a1cc26546cc82f2408 +++ src/view/widgets/InventoryView.cpp 4f3d0251a3dec816b3c0b510ba75991e3d0f65e2 @@ -159,6 +159,14 @@ void InventoryView::createAndConnectCont actRefresh->setStatusTip(tr("Re-reads the item and refeshes the view")); connect(actRefresh, SIGNAL(triggered()), this, SLOT(slotRefresh())); + actNewFile = new QAction(tr("New file"), this); + actNewFile->setStatusTip(tr("Creates a new versioned file")); + connect(actNewFile, SIGNAL(triggered()), this, SLOT(slotNewFile())); + + actNewDirectory = new QAction(tr("New directory"), this); + actNewDirectory->setStatusTip(tr("Creates a new versioned directory")); + connect(actNewDirectory, SIGNAL(triggered()), this, SLOT(slotNewDirectory())); + actAddMultiple = new QAction(tr("Add %1 items"), this); actAddMultiple->setStatusTip(tr("Add multiple items")); connect(actAddMultiple, SIGNAL(triggered()), this, SLOT(slotAdd())); @@ -199,6 +207,8 @@ InventoryView::~InventoryView() delete actRevisionDiff; delete actRename; delete actRefresh; + delete actNewFile; + delete actNewDirectory; delete actAddMultiple; delete actRemoveMultiple; delete actCommitMultiple; @@ -226,17 +236,17 @@ void InventoryView::setModel(QSortFilter disconnect( oldModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(setBackgroundImage()) + this, SLOT(rowsInserted(QModelIndex &, int, int)) ); disconnect( oldModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(setBackgroundImage()) + this, SLOT(rowsRemoved(const QModelIndex &, int, int)) ); disconnect( oldModel, SIGNAL(modelReset()), - this, SLOT(setBackgroundImage()) + this, SLOT(modelReset()) ); } @@ -249,17 +259,17 @@ void InventoryView::setModel(QSortFilter connect( newModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(setBackgroundImage()) + this, SLOT(rowsInserted(const QModelIndex &, int, int)) ); connect( newModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(setBackgroundImage()) + this, SLOT(rowsRemoved(const QModelIndex &, int, int)) ); connect( newModel, SIGNAL(modelReset()), - this, SLOT(setBackgroundImage()) + this, SLOT(modelReset()) ); } @@ -299,10 +309,19 @@ void InventoryView::slotContextMenuReque if (indexList.size() == 0) { QMenu menu(this); + menu.addAction(actRefresh); QFont activeFont; activeFont.setBold(true); actRefresh->setFont(activeFont); + + if (type == FileList) + { + menu.addSeparator(); + menu.addAction(actNewFile); + menu.addAction(actNewDirectory); + } + menu.exec(pos); return; } @@ -368,8 +387,11 @@ void InventoryView::slotContextMenuReque invitem->hasNotStatus(InventoryItem::Unknown) && !invitem->getPath().isEmpty()) { - menu.addAction(actRemove); - menu.addAction(actRename); + if (invitem->isNewNode()) + { + menu.addAction(actRemove); + menu.addAction(actRename); + } // as long as it is not unchanged, it can be converted if (invitem->hasChanged()) @@ -384,6 +406,7 @@ void InventoryView::slotContextMenuReque } if (invitem->getFSType() == InventoryItem::File && + invitem->isNewNode() && invitem->hasNotStatus(InventoryItem::Added)) { menu.addAction(actFileHistory); @@ -825,7 +848,16 @@ void InventoryView::slotRename() void InventoryView::slotRename() { - C("Not implemented."); + QItemSelectionModel * selectionModel = this->selectionModel(); + QList list; + foreach (QModelIndex index, selectionModel->selectedIndexes()) + { + if (index.column() != 0) continue; + list.append(index); + } + + if (list.size() != 1) return; + edit(list.at(0)); } // @@ -961,6 +993,60 @@ void InventoryView::slotRevisionDiff() emit diffRevision(invitem->getPath(), QString(), QString()); } +QString InventoryView::getNewPath(const QModelIndex & parent, const QString & prefix) +{ + I(!prefix.isEmpty()); + I(parent.isValid()); + + const ModelItem * modelParent = modelItem(sourceIndex(parent, true)); + const InventoryItem * invParent = qobject_cast(modelParent); + if (!invParent) return QString(); + + QString newFilename; + int c = 0; + while (true) + { + newFilename = ++c == 1 ? prefix : prefix + " " + QString::number(c); + + bool exists = false; + foreach (ModelItem * child, invParent->getChildren()) + { + InventoryItem * invChild = qobject_cast(child); + if (!invChild) continue; + if (invChild->getFilename() == newFilename) + { + exists = true; + break; + } + } + + if (!exists) + break; + } + + QString baseDirectory = invParent->getPath(); + if (baseDirectory.isEmpty()) + return newFilename; + + return baseDirectory + "/" + newFilename; +} + +void InventoryView::slotNewFile() +{ + if (type != FileList) return; + newPath = getNewPath(rootIndex(), tr("New file")); + if (!newPath.isEmpty()) + emit newFile(newPath); +} + +void InventoryView::slotNewDirectory() +{ + if (type != FileList) return; + newPath = getNewPath(rootIndex(), tr("New directory")); + if (!newPath.isEmpty()) + emit newDirectory(newPath); +} + QSet InventoryView::getSelectedItems() const { QItemSelectionModel * selectionModel = this->selectionModel(); @@ -1081,3 +1167,47 @@ void InventoryView::setBackgroundImage() } } +void InventoryView::rowsInserted(const QModelIndex & parent, int start, int end) +{ + Q_UNUSED(start); + Q_UNUSED(end); + + if (!newPath.isEmpty()) + { + for (int i=start; i<=end; i++) + { + QModelIndex proxyIndex = parent.model()->index(i, 0, parent); + const ModelItem * item = modelItem(sourceIndex(proxyIndex, true)); + const InventoryItem * invItem = qobject_cast(item); + + if (!invItem || invItem->getPath() != newPath) + continue; + + selectionModel()->setCurrentIndex( + proxyIndex, + QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows + ); + + edit(proxyIndex); + + newPath = QString(); + } + } + + setBackgroundImage(); +} + +void InventoryView::rowsRemoved(const QModelIndex & parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + + setBackgroundImage(); +} + +void InventoryView::modelReset() +{ + setBackgroundImage(); +} + ============================================================ --- src/view/widgets/InventoryView.h 9e4eb7d1b4540f44a9f2bf3e9f09c87c4dc5479a +++ src/view/widgets/InventoryView.h ac58d3b7ec668ea50d13c8b2260d82b8b7e514fb @@ -54,6 +54,8 @@ signals: void revertPaths(const QStringList &); void ignorePaths(const QStringList &); void unignorePaths(const QStringList &); + void newFile(const QString &); + void newDirectory(const QString &); private: enum DefaultAction { None, Chdir, Open, FileDiff, Commit }; @@ -63,10 +65,12 @@ private: DefaultAction getDefaultAction(const QModelIndex &) const; void createAndConnectContextActions(); void closeEvent(); + void setBackgroundImage(); inline QModelIndex sourceIndex(const QModelIndex &, bool useIndexModel = false) const; inline QModelIndex proxyIndex(const QModelIndex &) const; static inline const ModelItem * modelItem(const QModelIndex &); + QString getNewPath(const QModelIndex &, const QString &); QAction * actChdir; QAction * actOpen; @@ -81,6 +85,8 @@ private: QAction * actFileHistory; QAction * actRevisionDiff; QAction * actRefresh; + QAction * actNewFile; + QAction * actNewDirectory; QAction * actAddMultiple; QAction * actRemoveMultiple; @@ -92,6 +98,7 @@ private: Type type; InventoryViewDelegate invViewDelegate; + QString newPath; private slots: void expandRootNode(const QModelIndex &, const QModelIndex &); @@ -99,7 +106,9 @@ private slots: void slotContextMenuRequested(const QModelIndexList &, const QPoint &); void itemClicked(const QModelIndex & index); void itemDoubleClicked(const QModelIndex & index); - void setBackgroundImage(); + void rowsInserted(const QModelIndex &, int, int); + void rowsRemoved(const QModelIndex &, int, int); + void modelReset(); void slotChdir(); void slotOpen(); @@ -114,6 +123,8 @@ private slots: void slotFileHistory(); void slotRevisionDiff(); void slotRefresh(); + void slotNewFile(); + void slotNewDirectory(); }; #endif