diff --git a/src/vcaptain.cpp b/src/vcaptain.cpp index 620ef851..4b238f6b 100644 --- a/src/vcaptain.cpp +++ b/src/vcaptain.cpp @@ -173,7 +173,10 @@ bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) case Qt::Key_D: // Locate current tab. - m_mainWindow->locateCurrentFile(); + if (m_mainWindow->locateCurrentFile()) { + m_widgetBeforeCaptain = NULL; + } + break; case Qt::Key_E: diff --git a/src/vdirectorytree.cpp b/src/vdirectorytree.cpp index b4aaf5b6..fb59feb8 100644 --- a/src/vdirectorytree.cpp +++ b/src/vdirectorytree.cpp @@ -12,6 +12,11 @@ extern VConfigManager *g_config; extern VNote *g_vnote; +const QString VDirectoryTree::c_infoShortcutSequence = "F2"; +const QString VDirectoryTree::c_copyShortcutSequence = "Ctrl+C"; +const QString VDirectoryTree::c_cutShortcutSequence = "Ctrl+X"; +const QString VDirectoryTree::c_pasteShortcutSequence = "Ctrl+V"; + VDirectoryTree::VDirectoryTree(VNote *vnote, QWidget *parent) : QTreeWidget(parent), VNavigationMode(), vnote(vnote), m_editArea(NULL) @@ -19,6 +24,7 @@ VDirectoryTree::VDirectoryTree(VNote *vnote, QWidget *parent) setColumnCount(1); setHeaderHidden(true); setContextMenuPolicy(Qt::CustomContextMenu); + initShortcuts(); initActions(); connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)), @@ -31,6 +37,37 @@ VDirectoryTree::VDirectoryTree(VNote *vnote, QWidget *parent) this, &VDirectoryTree::currentDirectoryItemChanged); } +void VDirectoryTree::initShortcuts() +{ + QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); + infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(infoShortcut, &QShortcut::activated, + this, [this](){ + editDirectoryInfo(); + }); + + QShortcut *copyShortcut = new QShortcut(QKeySequence(c_copyShortcutSequence), this); + copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(copyShortcut, &QShortcut::activated, + this, [this](){ + copySelectedDirectories(); + }); + + QShortcut *cutShortcut = new QShortcut(QKeySequence(c_cutShortcutSequence), this); + cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(cutShortcut, &QShortcut::activated, + this, [this](){ + cutSelectedDirectories(); + }); + + QShortcut *pasteShortcut = new QShortcut(QKeySequence(c_pasteShortcutSequence), this); + pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(pasteShortcut, &QShortcut::activated, + this, [this](){ + pasteDirectoriesInCurDir(); + }); +} + void VDirectoryTree::initActions() { newRootDirAct = new QAction(QIcon(":/resources/icons/create_rootdir.svg"), @@ -51,25 +88,25 @@ void VDirectoryTree::initActions() this, &VDirectoryTree::deleteDirectory); dirInfoAct = new QAction(QIcon(":/resources/icons/dir_info.svg"), - tr("&Info"), this); + tr("&Info\t%1").arg(QKeySequence(c_infoShortcutSequence).toString()), this); dirInfoAct->setToolTip(tr("View and edit current folder's information")); connect(dirInfoAct, &QAction::triggered, this, &VDirectoryTree::editDirectoryInfo); copyAct = new QAction(QIcon(":/resources/icons/copy.svg"), - tr("&Copy"), this); + tr("&Copy\t%1").arg(QKeySequence(c_copyShortcutSequence).toString()), this); copyAct->setToolTip(tr("Copy selected folders")); connect(copyAct, &QAction::triggered, this, &VDirectoryTree::copySelectedDirectories); cutAct = new QAction(QIcon(":/resources/icons/cut.svg"), - tr("C&ut"), this); + tr("C&ut\t%1").arg(QKeySequence(c_cutShortcutSequence).toString()), this); cutAct->setToolTip(tr("Cut selected folders")); connect(cutAct, &QAction::triggered, this, &VDirectoryTree::cutSelectedDirectories); pasteAct = new QAction(QIcon(":/resources/icons/paste.svg"), - tr("&Paste"), this); + tr("&Paste\t%1").arg(QKeySequence(c_pasteShortcutSequence).toString()), this); pasteAct->setToolTip(tr("Paste folders in this folder")); connect(pasteAct, &QAction::triggered, this, &VDirectoryTree::pasteDirectoriesInCurDir); @@ -534,11 +571,16 @@ void VDirectoryTree::cutSelectedDirectories() void VDirectoryTree::pasteDirectoriesInCurDir() { + if (m_copiedDirs.isEmpty()) { + return; + } + QTreeWidgetItem *item = currentItem(); VDirectory *destDir = m_notebook->getRootDir(); if (item) { destDir = getVDirectory(item); } + pasteDirectories(destDir); } @@ -553,9 +595,10 @@ void VDirectoryTree::pasteDirectories(VDirectory *p_destDir) int nrPasted = 0; for (int i = 0; i < m_copiedDirs.size(); ++i) { QPointer srcDir = m_copiedDirs[i]; - if (!srcDir) { + if (!srcDir || srcDir == p_destDir) { continue; } + QString dirName = srcDir->getName(); VDirectory *srcParentDir = srcDir->getParentDirectory(); if (srcParentDir == p_destDir && !isCut) { diff --git a/src/vdirectorytree.h b/src/vdirectorytree.h index 3cea5ccb..7db9a572 100644 --- a/src/vdirectorytree.h +++ b/src/vdirectorytree.h @@ -76,7 +76,10 @@ private: void fillTreeItem(QTreeWidgetItem &p_item, const QString &p_name, VDirectory *p_directory, const QIcon &p_icon); + void initShortcuts(); + void initActions(); + // Update @p_item's direct children only: deleted, added, renamed. void updateItemChildren(QTreeWidgetItem *p_item); // Find the corresponding item of @p_dir; @@ -124,6 +127,11 @@ private: // Map second key to QTreeWidgetItem. QMap m_keyMap; QVector m_naviLabels; + + static const QString c_infoShortcutSequence; + static const QString c_copyShortcutSequence; + static const QString c_cutShortcutSequence; + static const QString c_pasteShortcutSequence; }; inline QPointer VDirectoryTree::getVDirectory(QTreeWidgetItem *p_item) const diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp index 9be7b205..57ed32f3 100644 --- a/src/vfilelist.cpp +++ b/src/vfilelist.cpp @@ -14,10 +14,16 @@ extern VConfigManager *g_config; extern VNote *g_vnote; +const QString VFileList::c_infoShortcutSequence = "F2"; +const QString VFileList::c_copyShortcutSequence = "Ctrl+C"; +const QString VFileList::c_cutShortcutSequence = "Ctrl+X"; +const QString VFileList::c_pasteShortcutSequence = "Ctrl+V"; + VFileList::VFileList(QWidget *parent) : QWidget(parent), VNavigationMode() { setupUI(); + initShortcuts(); initActions(); } @@ -43,10 +49,46 @@ void VFileList::setupUI() setLayout(mainLayout); } +void VFileList::initShortcuts() +{ + QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); + infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(infoShortcut, &QShortcut::activated, + this, [this](){ + fileInfo(); + }); + + QShortcut *copyShortcut = new QShortcut(QKeySequence(c_copyShortcutSequence), this); + copyShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(copyShortcut, &QShortcut::activated, + this, [this](){ + copySelectedFiles(); + }); + + QShortcut *cutShortcut = new QShortcut(QKeySequence(c_cutShortcutSequence), this); + cutShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(cutShortcut, &QShortcut::activated, + this, [this](){ + cutSelectedFiles(); + }); + + QShortcut *pasteShortcut = new QShortcut(QKeySequence(c_pasteShortcutSequence), this); + pasteShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(pasteShortcut, &QShortcut::activated, + this, [this](){ + pasteFilesInCurDir(); + }); +} + void VFileList::initActions() { newFileAct = new QAction(QIcon(":/resources/icons/create_note.svg"), tr("&New Note"), this); + QString shortcutStr = QKeySequence(g_config->getShortcutKeySequence("NewNote")).toString(); + if (!shortcutStr.isEmpty()) { + newFileAct->setText(tr("&New Note\t%1").arg(shortcutStr)); + } + newFileAct->setToolTip(tr("Create a note in current folder")); connect(newFileAct, SIGNAL(triggered(bool)), this, SLOT(newFile())); @@ -58,25 +100,25 @@ void VFileList::initActions() this, SLOT(deleteFile())); fileInfoAct = new QAction(QIcon(":/resources/icons/note_info.svg"), - tr("&Info"), this); + tr("&Info\t%1").arg(QKeySequence(c_infoShortcutSequence).toString()), this); fileInfoAct->setToolTip(tr("View and edit current note's information")); connect(fileInfoAct, SIGNAL(triggered(bool)), this, SLOT(fileInfo())); copyAct = new QAction(QIcon(":/resources/icons/copy.svg"), - tr("&Copy"), this); + tr("&Copy\t%1").arg(QKeySequence(c_copyShortcutSequence).toString()), this); copyAct->setToolTip(tr("Copy selected notes")); connect(copyAct, &QAction::triggered, this, &VFileList::copySelectedFiles); cutAct = new QAction(QIcon(":/resources/icons/cut.svg"), - tr("C&ut"), this); + tr("C&ut\t%1").arg(QKeySequence(c_cutShortcutSequence).toString()), this); cutAct->setToolTip(tr("Cut selected notes")); connect(cutAct, &QAction::triggered, this, &VFileList::cutSelectedFiles); pasteAct = new QAction(QIcon(":/resources/icons/paste.svg"), - tr("&Paste"), this); + tr("&Paste\t%1").arg(QKeySequence(c_pasteShortcutSequence).toString()), this); pasteAct->setToolTip(tr("Paste notes in current folder")); connect(pasteAct, &QAction::triggered, this, &VFileList::pasteFilesInCurDir); @@ -117,9 +159,10 @@ void VFileList::updateFileList() void VFileList::fileInfo() { - QListWidgetItem *curItem = fileList->currentItem(); - V_ASSERT(curItem); - fileInfo(getVFile(curItem)); + QList items = fileList->selectedItems(); + if (items.size() == 1) { + fileInfo(getVFile(items[0])); + } } void VFileList::openFileLocation() const @@ -383,10 +426,16 @@ QListWidgetItem* VFileList::findItem(const VFile *p_file) void VFileList::handleItemClicked(QListWidgetItem *currentItem) { + Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); + if (modifiers != Qt::NoModifier) { + return; + } + if (!currentItem) { emit fileClicked(NULL); return; } + // Qt seems not to update the QListWidget correctly. Manually force it to repaint. fileList->update(); emit fileClicked(getVFile(currentItem), OpenFileMode::Read); @@ -456,6 +505,10 @@ void VFileList::copyFileInfoToClipboard(const QJsonArray &p_files, bool p_isCut) void VFileList::pasteFilesInCurDir() { + if (m_copiedFiles.isEmpty()) { + return; + } + pasteFiles(m_directory); } @@ -554,6 +607,7 @@ void VFileList::keyPressEvent(QKeyEvent *event) if (item) { handleItemClicked(item); } + break; } @@ -599,11 +653,14 @@ bool VFileList::locateFile(const VFile *p_file) if (p_file->getDirectory() != m_directory) { return false; } + QListWidgetItem *item = findItem(p_file); if (item) { fileList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); + return true; } } + return false; } diff --git a/src/vfilelist.h b/src/vfilelist.h index 93ebfd7f..04727821 100644 --- a/src/vfilelist.h +++ b/src/vfilelist.h @@ -67,9 +67,15 @@ protected: private: void setupUI(); + + // Init shortcuts. + void initShortcuts(); + void updateFileList(); QListWidgetItem *insertFileListItem(VFile *file, bool atFront = false); void removeFileListItem(QListWidgetItem *item); + + // Init actions. void initActions(); // Return the corresponding QListWidgetItem of @p_file. @@ -113,6 +119,11 @@ private: // Map second key to QListWidgetItem. QMap m_keyMap; QVector m_naviLabels; + + static const QString c_infoShortcutSequence; + static const QString c_copyShortcutSequence; + static const QString c_cutShortcutSequence; + static const QString c_pasteShortcutSequence; }; inline void VFileList::setEditArea(VEditArea *editArea) diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index c9c010d8..288a1a35 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -1704,35 +1704,45 @@ void VMainWindow::insertImage() m_curTab->insertImage(); } -void VMainWindow::locateFile(VFile *p_file) +bool VMainWindow::locateFile(VFile *p_file) { + bool ret = false; if (!p_file || p_file->getType() != FileType::Normal) { - return; + return ret; } - qDebug() << "locate file" << p_file->retrivePath(); + VNotebook *notebook = p_file->getNotebook(); if (notebookSelector->locateNotebook(notebook)) { while (directoryTree->currentNotebook() != notebook) { QCoreApplication::sendPostedEvents(); } + VDirectory *dir = p_file->getDirectory(); if (directoryTree->locateDirectory(dir)) { while (fileList->currentDirectory() != dir) { QCoreApplication::sendPostedEvents(); } - fileList->locateFile(p_file); + + if (fileList->locateFile(p_file)) { + ret = true; + fileList->setFocus(); + } } } // Open the directory and file panels after location. twoPanelView(); + + return ret; } -void VMainWindow::locateCurrentFile() +bool VMainWindow::locateCurrentFile() { if (m_curFile) { - locateFile(m_curFile); + return locateFile(m_curFile); } + + return false; } void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */) diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 4523e264..017d55b4 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -44,8 +44,12 @@ public: VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent = 0); const QVector > &getPalette() const; - void locateFile(VFile *p_file); - void locateCurrentFile(); + + // Returns true if the location succeeds. + bool locateFile(VFile *p_file); + + // Returns true if the location succeeds. + bool locateCurrentFile(); VFileList *getFileList() const;