Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context Menu operations on Folder as Workspace tree #556

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
23 changes: 14 additions & 9 deletions src/NotepadNext/ScintillaNext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,22 +369,27 @@ bool ScintillaNext::rename(const QString &newFilePath)
QFile::remove(oldPath);

// Everything worked fine, so update the buffer's info
setFileInfo(newFilePath);
setSavePoint();

// If this was a temporary file, make sure it is not any more
setTemporary(false);

emit saved();

emit renamed();
renameEditorPath(newFilePath);

return true;
}

return false;
}

void ScintillaNext::renameEditorPath(const QString &newFilePath)
{
setFileInfo(newFilePath);
setSavePoint();

// If this was a temporary file, make sure it is not any more
setTemporary(false);

emit saved();

emit renamed();
}

ScintillaNext::FileStateChange ScintillaNext::checkFileForStateChange()
{
if (bufferType == BufferType::New) {
Expand Down
3 changes: 2 additions & 1 deletion src/NotepadNext/ScintillaNext.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ public slots:
void reload();
QFileDevice::FileError saveAs(const QString &newFilePath);
QFileDevice::FileError saveCopyAs(const QString &filePath);
bool rename(const QString &newFilePath);
bool rename(const QString &newFilePath); // update FS then update representation
void renameEditorPath(const QString &newFilePath); // update representation only
ScintillaNext::FileStateChange checkFileForStateChange();
bool moveToTrash();

Expand Down
19 changes: 17 additions & 2 deletions src/NotepadNext/dialogs/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1332,14 +1332,29 @@ void MainWindow::moveCurrentFileToTrash()
moveFileToTrash(editor);
}

bool MainWindow::askMoveToTrash(const QString &path)
{
auto reply = QMessageBox::question(this, tr("Delete File"), tr("Are you sure you want to move <b>%1</b> to the trash?").arg(path));

return reply == QMessageBox::Yes;
}

void MainWindow::closeByPath(const QString &path)
{
forEachEditorByPath(path, [=](ScintillaNext* editor) {
closeFile(editor);
});
// Since the file no longer exists, specifically remove it from the recent files list
app->getRecentFilesListManager()->removeFile(path);
}

void MainWindow::moveFileToTrash(ScintillaNext *editor)
{
Q_ASSERT(editor->isFile());

const QString filePath = editor->getFilePath();
auto reply = QMessageBox::question(this, tr("Delete File"), tr("Are you sure you want to move <b>%1</b> to the trash?").arg(filePath));

if (reply == QMessageBox::Yes) {
if (askMoveToTrash(filePath)) {
if (editor->moveToTrash()) {
closeCurrentFile();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you closing current file? One could open one file and delete another one.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! Good catch! 😄 This is what I get for trying to modify it on little sleep.


Expand Down
21 changes: 21 additions & 0 deletions src/NotepadNext/dialogs/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class MainWindow : public QMainWindow
QVector<ScintillaNext *> editors() const;
DockedEditor *getDockedEditor() const { return dockedEditor; }

template<typename Func>
void forEachEditorByPath(const QString &path, Func callback);

bool askMoveToTrash(const QString &path);

void closeByPath(const QString &path);

public slots:
void newFile();

Expand Down Expand Up @@ -171,4 +178,18 @@ private slots:
int contextMenuPos = 0;
};

template<typename Func>
void MainWindow::forEachEditorByPath(const QString &path, Func callback)
{
qInfo() << path;
for(auto &&editor : editors())
{
qInfo() << editor->getFilePath();
if (editor->getFilePath() == path)
{
callback(editor);
}
}
}

#endif // MAINWINDOW_H
106 changes: 104 additions & 2 deletions src/NotepadNext/docks/FolderAsWorkspaceDock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,26 @@


#include "FolderAsWorkspaceDock.h"

#include <QFileSystemModel>
#include <QMessageBox>

#include "ApplicationSettings.h"
#include "MainWindow.h"
#include "ui_FolderAsWorkspaceDock.h"

#include <QFileSystemModel>

ApplicationSetting<QString> rootPathSetting{"FolderAsWorkspace/RootPath"};

FolderAsWorkspaceDock::FolderAsWorkspaceDock(QWidget *parent) :
FolderAsWorkspaceDock::FolderAsWorkspaceDock(MainWindow *parent) :
QDockWidget(parent),
ui(new Ui::FolderAsWorkspaceDock),
window(parent),
model(new QFileSystemModel(this))
{
ui->setupUi(this);

model->setReadOnly(false);
ui->treeView->setModel(model);
ui->treeView->header()->hideSection(1);
ui->treeView->header()->hideSection(2);
Expand All @@ -43,6 +49,9 @@ FolderAsWorkspaceDock::FolderAsWorkspaceDock(QWidget *parent) :
}
});

connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &FolderAsWorkspaceDock::onCustomContextMenu);
connect(model, &QFileSystemModel::fileRenamed, this, &FolderAsWorkspaceDock::onFileRenamed);

ApplicationSettings settings;
setRootPath(settings.get(rootPathSetting));
}
Expand All @@ -65,3 +74,96 @@ QString FolderAsWorkspaceDock::rootPath() const
{
return model->rootPath();
}

void FolderAsWorkspaceDock::onCustomContextMenu(const QPoint &point)
{
QModelIndex index = ui->treeView->indexAt(point);

// Nothing was selected
if (!index.isValid()) {
lastSelectedItem = model->index(rootPath());
ui->menuEmpty->exec(ui->treeView->viewport()->mapToGlobal(point));
return;
}

lastSelectedItem = index;

// Decide which menu to show if it is a directory or not
if (model->isDir(index)) {
ui->menuDirectory->exec(ui->treeView->viewport()->mapToGlobal(point));
}
else {
ui->menuFile->exec(ui->treeView->viewport()->mapToGlobal(point));
}
}

void FolderAsWorkspaceDock::on_actionSaveHere_triggered()
{
QDir parentDir(model->filePath(lastSelectedItem));
auto editor = window->currentEditor();
QString destinationName(parentDir.absoluteFilePath(editor->getName()));

if (window->saveFileAs(editor, destinationName)) {
auto newItem = model->index(destinationName);
ui->treeView->setCurrentIndex(newItem);
ui->treeView->edit(newItem);
}
else {
qWarning("Unable to save %s", qUtf8Printable(destinationName));
}
}

void FolderAsWorkspaceDock::on_actionNewFolder_triggered()
{
QDir parentDirectory(model->filePath(lastSelectedItem));
QString destinationName;
int i = 1;

// Find the next valid folder name
do {
destinationName = tr("New Folder %1").arg(i);
++i;
} while (parentDirectory.exists(destinationName));

// Try to create it
auto newItem = model->mkdir(lastSelectedItem, destinationName);

if (newItem.isValid()) {
ui->treeView->setCurrentIndex(newItem);
ui->treeView->edit(newItem);
}
else {
qWarning("Unable to create %s", qUtf8Printable(destinationName));
}
}

void FolderAsWorkspaceDock::on_actionRename_triggered()
{
ui->treeView->setCurrentIndex(lastSelectedItem);
ui->treeView->edit(lastSelectedItem);
}

void FolderAsWorkspaceDock::onFileRenamed(const QString &parentPath, const QString &oldName, const QString &newName)
{
QDir parentDir(parentPath);
QString oldPath = parentDir.absoluteFilePath(oldName);
QString newPath = parentDir.absoluteFilePath(newName);

window->forEachEditorByPath(oldPath, [=](ScintillaNext* editor) {
editor->renameEditorPath(newPath);
});
}

void FolderAsWorkspaceDock::on_actionMoveToTrash_triggered()
{
QString path(model->filePath(lastSelectedItem));

if (window->askMoveToTrash(path)) {
if (QFile::moveToTrash(path)) {
window->closeByPath(path);
}
else {
qWarning("Unable to remove %s", path.toUtf8().constData());
}
}
}
16 changes: 15 additions & 1 deletion src/NotepadNext/docks/FolderAsWorkspaceDock.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,21 @@
#define FOLDERASWORKSPACEDOCK_H

#include <QDockWidget>
#include <QModelIndex>

namespace Ui {
class FolderAsWorkspaceDock;
}

class QFileSystemModel;
class MainWindow;

class FolderAsWorkspaceDock : public QDockWidget
{
Q_OBJECT

public:
explicit FolderAsWorkspaceDock(QWidget *parent = nullptr);
explicit FolderAsWorkspaceDock(MainWindow *parent = nullptr);
~FolderAsWorkspaceDock();

void setRootPath(const QString dir);
Expand All @@ -42,10 +44,22 @@ class FolderAsWorkspaceDock : public QDockWidget
signals:
void fileDoubleClicked(const QString &filePath);

private slots:
void on_actionSaveHere_triggered();
void on_actionNewFolder_triggered();
void on_actionRename_triggered();
void on_actionMoveToTrash_triggered();

void onCustomContextMenu(const QPoint &point);
void onFileRenamed(const QString &path, const QString &oldName, const QString &newName);

private:
Ui::FolderAsWorkspaceDock *ui;

MainWindow *window;
QFileSystemModel *model;

QModelIndex lastSelectedItem;
};

#endif // FOLDERASWORKSPACEDOCK_H
64 changes: 63 additions & 1 deletion src/NotepadNext/docks/FolderAsWorkspaceDock.ui
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,81 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QMenu" name="menuFile">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can QtCreator create a QMenu in the ui file? or some other method (e.g. manually)? I'm just interested since I've never seen this done before :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't. I googled for it but at least Qt 5 can't. For me it looks like minor inconvenience everyone accustomed to.

<property name="title">
<string>File Menu</string>
</property>
<addaction name="actionRename"/>
<addaction name="actionMoveToTrash"/>
</widget>
</item>
<item>
<widget class="QMenu" name="menuDirectory">
<property name="title">
<string>Folder Menu</string>
</property>
<addaction name="actionRename"/>
<addaction name="actionMoveToTrash"/>
<addaction name="separator"/>
<addaction name="actionNewFolder"/>
<addaction name="actionSaveHere"/>
</widget>
</item>
<item>
<widget class="QMenu" name="menuEmpty">
<property name="title">
<string>Space Menu</string>
</property>
<addaction name="actionNewFolder"/>
<addaction name="actionSaveHere"/>
</widget>
</item>
<item>
<widget class="QTreeView" name="treeView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed</set>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<action name="actionSaveHere">
<property name="text">
<string>&amp;Save Current File Here</string>
</property>
</action>
<action name="actionNewFolder">
<property name="text">
<string>New &amp;Folder</string>
</property>
</action>
<action name="actionRename">
<property name="text">
<string>&amp;Rename</string>
</property>
</action>
<action name="actionMoveToTrash">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/icons/bin_closed.png</normaloff>:/icons/bin_closed.png</iconset>
</property>
<property name="text">
<string>Move to &amp;Trash</string>
</property>
</action>
</widget>
<resources/>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections/>
</ui>