┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dolphincontextmenu.cpp5
-rw-r--r--src/dolphinmainwindow.cpp23
-rw-r--r--src/dolphinmainwindow.h1
-rw-r--r--src/dolphinnewfilemenu.cpp3
-rw-r--r--src/dolphinnewfilemenu.h2
-rw-r--r--src/dolphinpart.cpp6
-rw-r--r--src/settings/viewmodes/generalviewsettingspage.cpp1
-rw-r--r--src/tests/dolphinmainwindowtest.cpp74
-rw-r--r--src/views/dolphinviewactionhandler.cpp10
-rw-r--r--src/views/dolphinviewactionhandler.h7
10 files changed, 123 insertions, 9 deletions
diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp
index e2f7e326b..354111a01 100644
--- a/src/dolphincontextmenu.cpp
+++ b/src/dolphincontextmenu.cpp
@@ -32,6 +32,7 @@
#include <QApplication>
#include <QClipboard>
#include <QKeyEvent>
+#include <QAction>
DolphinContextMenu::DolphinContextMenu(DolphinMainWindow *parent,
const KFileItem &fileInfo,
@@ -198,7 +199,9 @@ void DolphinContextMenu::addDirectoryItemContextMenu()
addOpenWithActions();
// set up 'Create New' menu
- DolphinNewFileMenu *newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection()->action(QStringLiteral("create_dir")), m_mainWindow);
+ QAction *newDirAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_dir"));
+ QAction *newFileAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_file"));
+ DolphinNewFileMenu *newFileMenu = new DolphinNewFileMenu(newDirAction, newFileAction, m_mainWindow);
newFileMenu->checkUpToDate();
newFileMenu->setWorkingDirectory(m_fileInfo.url());
newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp
index d9438ea09..a5dd3f9d3 100644
--- a/src/dolphinmainwindow.cpp
+++ b/src/dolphinmainwindow.cpp
@@ -176,10 +176,16 @@ DolphinMainWindow::DolphinMainWindow()
m_actionHandler = new DolphinViewActionHandler(actionCollection(), m_actionTextHelper, this);
connect(m_actionHandler, &DolphinViewActionHandler::actionBeingHandled, this, &DolphinMainWindow::clearStatusBar);
connect(m_actionHandler, &DolphinViewActionHandler::createDirectoryTriggered, this, &DolphinMainWindow::createDirectory);
+ connect(m_actionHandler, &DolphinViewActionHandler::createFileTriggered, this, &DolphinMainWindow::createFile);
connect(m_actionHandler, &DolphinViewActionHandler::selectionModeChangeTriggered, this, &DolphinMainWindow::slotSetSelectionMode);
- Q_CHECK_PTR(actionCollection()->action(QStringLiteral("create_dir")));
- m_newFileMenu->setNewFolderShortcutAction(actionCollection()->action(QStringLiteral("create_dir")));
+ QAction *newDirAction = actionCollection()->action(QStringLiteral("create_dir"));
+ Q_CHECK_PTR(newDirAction);
+ m_newFileMenu->setNewFolderShortcutAction(newDirAction);
+
+ QAction *newFileAction = actionCollection()->action(QStringLiteral("create_file"));
+ Q_CHECK_PTR(newFileAction);
+ m_newFileMenu->setNewFileShortcutAction(newFileAction);
m_remoteEncoding = new DolphinRemoteEncoding(this, m_actionHandler);
connect(this, &DolphinMainWindow::urlChanged, m_remoteEncoding, &DolphinRemoteEncoding::slotAboutToOpenUrl);
@@ -816,6 +822,15 @@ void DolphinMainWindow::createDirectory()
}
}
+void DolphinMainWindow::createFile()
+{
+ // Use the same logic as in createDirectory()
+ if (!m_newFileMenu->isCreateFileRunning()) {
+ m_newFileMenu->setWorkingDirectory(activeViewContainer()->url());
+ m_newFileMenu->createFile();
+ }
+}
+
void DolphinMainWindow::quit()
{
close();
@@ -1446,6 +1461,8 @@ void DolphinMainWindow::slotWriteStateChanged(bool isFolderWritable)
newFileMenu()->setEnabled(isFolderWritable && m_activeViewContainer->url().scheme() != QLatin1String("trash"));
// When the menu is disabled, actions in it are disabled later in the event loop, and we need to set the disabled reason after that.
QTimer::singleShot(0, this, [this]() {
+ m_disabledActionNotifier->setDisabledReason(actionCollection()->action(QStringLiteral("create_file")),
+ i18nc("@info", "Cannot create new file: You do not have permission to create items in this folder."));
m_disabledActionNotifier->setDisabledReason(actionCollection()->action(QStringLiteral("create_dir")),
i18nc("@info", "Cannot create new folder: You do not have permission to create items in this folder."));
});
@@ -1700,7 +1717,7 @@ void DolphinMainWindow::setupActions()
auto hamburgerMenuAction = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection());
// setup 'File' menu
- m_newFileMenu = new DolphinNewFileMenu(nullptr, this);
+ m_newFileMenu = new DolphinNewFileMenu(nullptr, nullptr, this);
actionCollection()->addAction(QStringLiteral("new_menu"), m_newFileMenu);
QMenu *menu = m_newFileMenu->menu();
menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h
index ceda3cb73..ecc84b971 100644
--- a/src/dolphinmainwindow.h
+++ b/src/dolphinmainwindow.h
@@ -296,6 +296,7 @@ private Q_SLOTS:
void updateNewMenu();
void createDirectory();
+ void createFile();
/** Shows the error message in the status bar of the active view. */
void showErrorMessage(const QString &message);
diff --git a/src/dolphinnewfilemenu.cpp b/src/dolphinnewfilemenu.cpp
index e3aff9762..2ccd7dd69 100644
--- a/src/dolphinnewfilemenu.cpp
+++ b/src/dolphinnewfilemenu.cpp
@@ -12,10 +12,11 @@
#include <QAction>
-DolphinNewFileMenu::DolphinNewFileMenu(QAction *createDirAction, QObject *parent)
+DolphinNewFileMenu::DolphinNewFileMenu(QAction *createDirAction, QAction *createFileAction, QObject *parent)
: KNewFileMenu(parent)
{
setNewFolderShortcutAction(createDirAction);
+ setNewFileShortcutAction(createFileAction);
DolphinNewFileMenuObserver::instance().attach(this);
}
diff --git a/src/dolphinnewfilemenu.h b/src/dolphinnewfilemenu.h
index 5538c9265..d5235db9b 100644
--- a/src/dolphinnewfilemenu.h
+++ b/src/dolphinnewfilemenu.h
@@ -25,7 +25,7 @@ class DOLPHIN_EXPORT DolphinNewFileMenu : public KNewFileMenu
Q_OBJECT
public:
- DolphinNewFileMenu(QAction *createDirAction, QObject *parent);
+ DolphinNewFileMenu(QAction *createDirAction, QAction *createFileAction, QObject *parent);
~DolphinNewFileMenu() override;
Q_SIGNALS:
diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp
index a79b650c5..a7f0d85cd 100644
--- a/src/dolphinpart.cpp
+++ b/src/dolphinpart.cpp
@@ -45,6 +45,7 @@
#include <QTextDocument>
#include <KPluginFactory>
+#include <QAction>
K_PLUGIN_CLASS_WITH_JSON(DolphinPart, "dolphinpart.json")
@@ -139,8 +140,9 @@ DolphinPart::~DolphinPart()
void DolphinPart::createActions()
{
// Edit menu
-
- m_newFileMenu = new DolphinNewFileMenu(actionCollection()->action(QStringLiteral("create_dir")), this);
+ QAction *newDirAction = actionCollection()->action(QStringLiteral("create_dir"));
+ QAction *newFileAction = actionCollection()->action(QStringLiteral("create_file"));
+ m_newFileMenu = new DolphinNewFileMenu(newDirAction, newFileAction, this);
m_newFileMenu->setParentWidget(widget());
connect(m_newFileMenu->menu(), &QMenu::aboutToShow, this, &DolphinPart::updateNewMenu);
diff --git a/src/settings/viewmodes/generalviewsettingspage.cpp b/src/settings/viewmodes/generalviewsettingspage.cpp
index 00bbae296..7caffe0f9 100644
--- a/src/settings/viewmodes/generalviewsettingspage.cpp
+++ b/src/settings/viewmodes/generalviewsettingspage.cpp
@@ -112,6 +112,7 @@ GeneralViewSettingsPage::GeneralViewSettingsPage(const QUrl &url, QWidget *paren
"edit_select_all",
"toggle_selection_mode",
"create_dir",
+ "create_file",
"show_preview",
"show_hidden_files",
"show_in_groups",
diff --git a/src/tests/dolphinmainwindowtest.cpp b/src/tests/dolphinmainwindowtest.cpp
index b22afa142..d7cb763fd 100644
--- a/src/tests/dolphinmainwindowtest.cpp
+++ b/src/tests/dolphinmainwindowtest.cpp
@@ -30,6 +30,10 @@
#include <QStandardPaths>
#include <QTest>
+#include <kfileitem.h>
+#include <qapplication.h>
+#include <qkeysequence.h>
+#include <qnamespace.h>
#include <set>
#include <unordered_set>
@@ -49,6 +53,8 @@ private Q_SLOTS:
void testOpenInNewTabTitle();
void testNewFileMenuEnabled_data();
void testNewFileMenuEnabled();
+ void testCreateFileAction();
+ void testCreateFileActionRequiresWritePermission();
void testWindowTitle_data();
void testWindowTitle();
void testFocusLocationBar();
@@ -372,6 +378,74 @@ void DolphinMainWindowTest::testNewFileMenuEnabled()
QTRY_COMPARE(newFileMenu->isEnabled(), expectedEnabled);
}
+void DolphinMainWindowTest::testCreateFileAction()
+{
+ QScopedPointer<TestDir> testDir{new TestDir()};
+ QString testDirUrl(QDir::cleanPath(testDir->url().toString()));
+ m_mainWindow->openDirectories({testDirUrl}, false);
+ m_mainWindow->show();
+ QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+ QVERIFY(m_mainWindow->isVisible());
+
+ QCOMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+ auto createFileAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_file"));
+ QTRY_COMPARE(createFileAction->isEnabled(), true);
+
+ createFileAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_N));
+
+ QSignalSpy createFileActionSpy(createFileAction, &QAction::triggered);
+
+ QTest::keyClick(QApplication::activeWindow(), Qt::Key_N, Qt::ControlModifier | Qt::AltModifier);
+
+ QTRY_COMPARE(createFileActionSpy.count(), 1);
+
+ QTRY_VERIFY(QApplication::activeModalWidget() != nullptr);
+
+ auto newFileDialog = QApplication::activeModalWidget()->focusWidget();
+ QTest::keyClick(newFileDialog, Qt::Key_X);
+ QTest::keyClick(newFileDialog, Qt::Key_Y);
+ QTest::keyClick(newFileDialog, Qt::Key_Z);
+ QTest::keyClick(newFileDialog, Qt::Key_Enter);
+
+ QTRY_COMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 1);
+
+ QFile file(testDir->url().toLocalFile() + "/xyz.txt");
+ QVERIFY(file.exists());
+ QCOMPARE(file.size(), 0);
+}
+
+ void DolphinMainWindowTest::testCreateFileActionRequiresWritePermission()
+{
+ QScopedPointer<TestDir> testDir{new TestDir()};
+ QString testDirUrl(QDir::cleanPath(testDir->url().toString()));
+ auto testDirAsFile = QFile(testDir->url().toLocalFile());
+
+ // make test dir read only
+ QVERIFY(testDirAsFile.setPermissions(QFileDevice::ReadOwner));
+
+ m_mainWindow->openDirectories({testDirUrl}, false);
+ m_mainWindow->show();
+ QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data()));
+ QVERIFY(m_mainWindow->isVisible());
+
+ QCOMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+ auto createFileAction = m_mainWindow->actionCollection()->action(QStringLiteral("create_file"));
+ QTRY_COMPARE(createFileAction->isEnabled(), false);
+
+ createFileAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_N));
+ QTest::keyClick(QApplication::activeWindow(), Qt::Key_N, Qt::ControlModifier | Qt::AltModifier);
+
+ QTRY_COMPARE(QApplication::activeModalWidget(), nullptr);
+
+ QTRY_COMPARE(m_mainWindow->m_activeViewContainer->view()->items().count(), 0);
+
+ QTRY_COMPARE(createFileAction->isEnabled(), false);
+
+ QVERIFY(m_mainWindow->isVisible());
+}
+
void DolphinMainWindowTest::testWindowTitle_data()
{
QTest::addColumn<QUrl>("activeViewUrl");
diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp
index 88d5c015b..4d5dba070 100644
--- a/src/views/dolphinviewactionhandler.cpp
+++ b/src/views/dolphinviewactionhandler.cpp
@@ -84,6 +84,12 @@ void DolphinViewActionHandler::createActions(SelectionMode::ActionTextHelper *ac
newDirAction->setEnabled(false); // Will be enabled in slotWriteStateChanged(bool) if the current URL is writable
connect(newDirAction, &QAction::triggered, this, &DolphinViewActionHandler::createDirectoryTriggered);
+ QAction *newFileAction = m_actionCollection->addAction(QStringLiteral("create_file"));
+ newFileAction->setText(i18nc("@action", "Create File…"));
+ newFileAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
+ newFileAction->setEnabled(false); // Will be enabled in slotWriteStateChanged(bool) if the current URL is writable
+ connect(newFileAction, &QAction::triggered, this, &DolphinViewActionHandler::createFileTriggered);
+
// File menu
auto renameAction = KStandardAction::renameFile(this, &DolphinViewActionHandler::slotRename, m_actionCollection);
@@ -639,7 +645,9 @@ void DolphinViewActionHandler::slotHiddenFilesShownChanged(bool shown)
void DolphinViewActionHandler::slotWriteStateChanged(bool isFolderWritable)
{
- m_actionCollection->action(QStringLiteral("create_dir"))->setEnabled(isFolderWritable && KProtocolManager::supportsMakeDir(currentView()->url()));
+ const bool supportsMakeDir = KProtocolManager::supportsMakeDir(currentView()->url());
+ m_actionCollection->action(QStringLiteral("create_dir"))->setEnabled(isFolderWritable && supportsMakeDir);
+ m_actionCollection->action(QStringLiteral("create_file"))->setEnabled(isFolderWritable);
}
KToggleAction *DolphinViewActionHandler::iconsModeAction()
diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h
index f36b3d1d0..20d62cf64 100644
--- a/src/views/dolphinviewactionhandler.h
+++ b/src/views/dolphinviewactionhandler.h
@@ -87,6 +87,13 @@ Q_SIGNALS:
*/
void createDirectoryTriggered();
+ /**
+ * Emitted if the user requested creating a new file.
+ * The receiver of the signal (DolphinMainWindow or DolphinPart) invokes
+ * the method createFile of their KNewFileMenu instance.
+ */
+ void createFileTriggered();
+
/** Used to request either entering or leaving of selection mode */
void selectionModeChangeTriggered(bool enabled, SelectionMode::BottomBar::Contents bottomBarContents = SelectionMode::BottomBar::Contents::GeneralContents);