From 3406eab29c0c8f912619cd934072caa123b0917e Mon Sep 17 00:00:00 2001 From: Le Tan Date: Sat, 25 Mar 2017 23:29:10 +0800 Subject: [PATCH] Captain mode --- src/src.pro | 6 +- src/utils/vutils.cpp | 2 + src/utils/vutils.h | 2 + src/vavatar.cpp | 10 ++ src/vavatar.h | 2 + src/vcaptain.cpp | 278 +++++++++++++++++++++++++++++++++++++++++++ src/vcaptain.h | 53 +++++++++ src/vedit.cpp | 1 + src/veditarea.cpp | 59 +++++++-- src/veditarea.h | 7 ++ src/vedittab.cpp | 4 + src/veditwindow.cpp | 95 ++++++++++----- src/veditwindow.h | 5 + src/vfilelist.cpp | 12 +- src/vfilelist.h | 2 + src/vmainwindow.cpp | 60 +++++++++- src/vmainwindow.h | 11 ++ src/vnote.cpp | 24 +++- 18 files changed, 583 insertions(+), 50 deletions(-) create mode 100644 src/vcaptain.cpp create mode 100644 src/vcaptain.h diff --git a/src/src.pro b/src/src.pro index 062aa9b7..97b8e60d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -55,7 +55,8 @@ SOURCES += main.cpp\ dialog/vfindreplacedialog.cpp \ dialog/vsettingsdialog.cpp \ dialog/vdeletenotebookdialog.cpp \ - dialog/vselectdialog.cpp + dialog/vselectdialog.cpp \ + vcaptain.cpp HEADERS += vmainwindow.h \ vdirectorytree.h \ @@ -96,7 +97,8 @@ HEADERS += vmainwindow.h \ dialog/vfindreplacedialog.h \ dialog/vsettingsdialog.h \ dialog/vdeletenotebookdialog.h \ - dialog/vselectdialog.h + dialog/vselectdialog.h \ + vcaptain.h RESOURCES += \ vnote.qrc \ diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index 509c5d3d..81d0b09b 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -11,6 +11,7 @@ #include #include #include +#include const QVector> VUtils::c_availableLanguages = {QPair("en_US", "Englisth(US)"), QPair("zh_CN", "Chinese")}; @@ -340,3 +341,4 @@ bool VUtils::isImageURLText(const QString &p_url) QFileInfo info(p_url); return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()); } + diff --git a/src/utils/vutils.h b/src/utils/vutils.h index 2e288213..c6b8681a 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -10,6 +10,8 @@ #include "vconfigmanager.h" #include "vconstants.h" +class QKeyEvent; + class VUtils { public: diff --git a/src/vavatar.cpp b/src/vavatar.cpp index 66444bbb..8d89389d 100644 --- a/src/vavatar.cpp +++ b/src/vavatar.cpp @@ -105,3 +105,13 @@ void VAvatar::setColor(const QString &p_baseColor, const QString &p_fgColor, con m_bgColor.setNamedColor(p_bgColor); } +void VAvatar::updateBaseColor(const QString &p_baseColor) +{ + m_baseColor.setNamedColor(p_baseColor); + update(); +} + +QString VAvatar::getBaseColor() const +{ + return m_baseColor.name(); +} diff --git a/src/vavatar.h b/src/vavatar.h index a84d421c..deeb83c6 100644 --- a/src/vavatar.h +++ b/src/vavatar.h @@ -17,7 +17,9 @@ public: void setAvatarPixmap(const QString &p_avatarPixmap); void setAvatarText(const QString &p_avatarText); void setColor(const QString &p_baseColor, const QString &p_fgColor, const QString &p_bgColor); + void updateBaseColor(const QString &p_baseColor); QSize sizeHint() const Q_DECL_OVERRIDE; + QString getBaseColor() const; protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/src/vcaptain.cpp b/src/vcaptain.cpp new file mode 100644 index 00000000..901c49e2 --- /dev/null +++ b/src/vcaptain.cpp @@ -0,0 +1,278 @@ +#include +#include +#include +#include +#include +#include "vcaptain.h" +#include "vmainwindow.h" +#include "veditarea.h" +#include "vedittab.h" +#include "vfilelist.h" + +// 3s pending time after the leader keys. +const int c_pendingTime = 3 * 1000; + +VCaptain::VCaptain(VMainWindow *p_parent) + : QWidget(p_parent), m_mainWindow(p_parent), m_mode(VCaptain::Normal), + m_widgetBeforeCaptain(NULL) +{ + m_pendingTimer = new QTimer(this); + m_pendingTimer->setSingleShot(true); + m_pendingTimer->setInterval(c_pendingTime); + connect(m_pendingTimer, &QTimer::timeout, + this, &VCaptain::pendingTimerTimeout); + + connect(qApp, &QApplication::focusChanged, + this, &VCaptain::handleFocusChanged); + + QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+E"), this, + Q_NULLPTR, Q_NULLPTR); + connect(shortcut, &QShortcut::activated, + this, &VCaptain::trigger); + + qApp->installEventFilter(this); + + setWindowFlags(Qt::FramelessWindowHint); + // Make it as small as possible. This widget will stay at the top-left corner + // of VMainWindow. + resize(1, 1); +} + +// In pending mode, if user click other widgets, we need to exit Captain mode. +void VCaptain::handleFocusChanged(QWidget *p_old, QWidget * /* p_now */) +{ + if (p_old == this) { + exitCaptainMode(); + } +} + +void VCaptain::pendingTimerTimeout() +{ + qDebug() << "Captain mode timeout"; + exitCaptainMode(); + restoreFocus(); +} + +void VCaptain::trigger() +{ + if (m_mode == VCaptain::Pending) { + return; + } + qDebug() << "trigger Captain mode"; + // Focus to listen pending key press. + m_widgetBeforeCaptain = QApplication::focusWidget(); + setFocus(); + m_mode = VCaptain::Pending; + m_pendingTimer->stop(); + m_pendingTimer->start(); + + emit captainModeChanged(true); +} + +void VCaptain::keyPressEvent(QKeyEvent *p_event) +{ + int key = p_event->key(); + Qt::KeyboardModifiers modifiers = p_event->modifiers(); + qDebug() << "VCaptain key pressed" << key << modifiers; + + if (m_mode == VCaptain::Normal) { + // Should not in focus while in Normal mode. + QWidget::keyPressEvent(p_event); + m_mainWindow->focusNextChild(); + return; + } + + if (key == Qt::Key_Control || key == Qt::Key_Shift) { + qDebug() << "VCaptain ignore key event"; + QWidget::keyPressEvent(p_event); + return; + } + + if (handleKeyPress(key, modifiers)) { + p_event->accept(); + } else { + QWidget::keyPressEvent(p_event); + } +} + +bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) +{ + qDebug() << "handleKeyPress" << p_key << p_modifiers; + bool ret = true; + + if (p_key == Qt::Key_Escape + || (p_key == Qt::Key_BracketLeft + && p_modifiers == Qt::ControlModifier)) { + goto exit; + } + + // In Captain mode, Ctrl key won't make a difference. + switch (p_key) { + case Qt::Key_D: + // Locate current tab. + m_mainWindow->locateCurrentFile(); + break; + + case Qt::Key_E: + // Toggle expand view. + m_mainWindow->expandViewAct->trigger(); + break; + + case Qt::Key_F: + { + // Show current window's opened file list. + VEditWindow *win = m_mainWindow->editArea->getCurrentWindow(); + if (win) { + if (win->showOpenedFileList()) { + // showOpenedFileList() already focus the right widget. + m_widgetBeforeCaptain = NULL; + } + } + break; + } + + case Qt::Key_H: + { + if (p_modifiers & Qt::ShiftModifier) { + // Move current tab one split left. + m_mainWindow->editArea->moveCurrentTabOneSplit(false); + } else { + // Focus previous window split. + int idx = m_mainWindow->editArea->focusNextWindow(-1); + if (idx > -1) { + m_widgetBeforeCaptain = NULL; + } + } + break; + } + + case Qt::Key_J: + { + // Focus next tab. + VEditWindow *win = m_mainWindow->editArea->getCurrentWindow(); + if (win) { + win->focusNextTab(true); + // focusNextTab() will focus the right widget. + m_widgetBeforeCaptain = NULL; + } + break; + } + + case Qt::Key_K: + { + // Focus previous tab. + VEditWindow *win = m_mainWindow->editArea->getCurrentWindow(); + if (win) { + win->focusNextTab(false); + // focusNextTab() will focus the right widget. + m_widgetBeforeCaptain = NULL; + } + break; + } + + case Qt::Key_L: + { + if (p_modifiers & Qt::ShiftModifier) { + // Move current tab one split right. + m_mainWindow->editArea->moveCurrentTabOneSplit(true); + } else { + // Focus next window split. + int idx = m_mainWindow->editArea->focusNextWindow(1); + if (idx > -1) { + m_widgetBeforeCaptain = NULL; + } + } + break; + } + + case Qt::Key_P: + // Toggle one/two panel view. + m_mainWindow->toggleOnePanelView(); + break; + + case Qt::Key_Q: + // Discard changes and exit edit mode. + m_mainWindow->discardExitAct->trigger(); + break; + + case Qt::Key_R: + { + // Remove current window split. + m_mainWindow->editArea->removeCurrentWindow(); + + QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); + m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; + break; + } + + case Qt::Key_T: + // Toggle the Tools dock. + m_mainWindow->toolDock->setVisible(!m_mainWindow->toolDock->isVisible()); + break; + + case Qt::Key_V: + // Vertical split current window. + m_mainWindow->editArea->splitCurrentWindow(); + // Do not restore focus. + m_widgetBeforeCaptain = NULL; + + break; + + case Qt::Key_X: + { + // Close current tab. + m_mainWindow->closeCurrentFile(); + + // m_widgetBeforeCaptain may be the closed tab which will cause crash. + QWidget *nextFocus = m_mainWindow->editArea->currentEditTab(); + m_widgetBeforeCaptain = nextFocus ? nextFocus : m_mainWindow->fileList; + break; + } + + default: + // Not implemented yet. Just exit Captain mode. + break; + } + +exit: + exitCaptainMode(); + restoreFocus(); + return ret; +} + +bool VCaptain::eventFilter(QObject *p_obj, QEvent *p_event) +{ + if (m_mode == VCaptain::Pending && p_event->type() == QEvent::Shortcut) { + qDebug() << "filter" << p_event; + QShortcutEvent *keyEve = dynamic_cast(p_event); + Q_ASSERT(keyEve); + const QKeySequence &keys = keyEve->key(); + if (keys.count() == 1) { + int key = keys[0]; + Qt::KeyboardModifiers modifiers = Qt::KeyboardModifiers(key & (~0x01FFFFFFU)); + key &= 0x01FFFFFFUL; + if (handleKeyPress(key, modifiers)) { + return true; + } + } + exitCaptainMode(); + restoreFocus(); + } + return QWidget::eventFilter(p_obj, p_event); +} + +void VCaptain::restoreFocus() +{ + if (m_widgetBeforeCaptain) { + m_widgetBeforeCaptain->setFocus(); + } +} + +void VCaptain::exitCaptainMode() +{ + m_mode = VCaptain::Normal; + m_pendingTimer->stop(); + + emit captainModeChanged(false); +} + diff --git a/src/vcaptain.h b/src/vcaptain.h new file mode 100644 index 00000000..2493d7d8 --- /dev/null +++ b/src/vcaptain.h @@ -0,0 +1,53 @@ +#ifndef VCAPTAIN_H +#define VCAPTAIN_H + +#include + +class QTimer; +class QKeyEvent; +class VMainWindow; +class QEvent; + +class VCaptain : public QWidget +{ + Q_OBJECT +public: + explicit VCaptain(VMainWindow *p_parent); + + // Trigger Captain mode. + void trigger(); + +signals: + void captainModeChanged(bool p_enabled); + +protected: + void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; + bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; + +public slots: + +private slots: + void pendingTimerTimeout(); + void handleFocusChanged(QWidget *p_old, QWidget *p_new); + +private: + // Restore the focus to m_widgetBeforeCaptain. + void restoreFocus(); + void exitCaptainMode(); + // Return true if finish handling the event; otherwise, let the base widget + // to handle it. + bool handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers); + + enum VCaptainMode { + Normal = 0, + Pending + }; + + VMainWindow *m_mainWindow; + QTimer *m_pendingTimer; + int m_mode; + // The widget which has the focus before entering Captain mode. + QWidget* m_widgetBeforeCaptain; +}; + +#endif // VCAPTAIN_H diff --git a/src/vedit.cpp b/src/vedit.cpp index 84e50b3a..90a11496 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -500,3 +500,4 @@ void VEdit::clearSearchedWordHighlight() selects.clear(); highlightExtraSelections(); } + diff --git a/src/veditarea.cpp b/src/veditarea.cpp index 4ca59d68..c61f71d2 100644 --- a/src/veditarea.cpp +++ b/src/veditarea.cpp @@ -167,20 +167,16 @@ void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus) void VEditArea::setCurrentWindow(int windowIndex, bool setFocus) { int nrWin = splitter->count(); - if (curWindowIndex == windowIndex) { - goto out; - } curWindowIndex = windowIndex; - if (curWindowIndex > -1 && setFocus) { - getWindow(curWindowIndex)->focusWindow(); - } -out: for (int i = 0; i < nrWin; ++i) { getWindow(i)->setCurrentWindow(false); } if (curWindowIndex > -1) { getWindow(curWindowIndex)->setCurrentWindow(true); + if (setFocus) { + getWindow(curWindowIndex)->focusWindow(); + } } // Update status updateWindowStatus(); @@ -323,6 +319,13 @@ void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow) setCurrentWindow(idx, true); } +void VEditArea::splitCurrentWindow() +{ + if (curWindowIndex > -1) { + handleSplitWindowRequest(getWindow(curWindowIndex)); + } +} + void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow) { if (!curWindow || splitter->count() <= 1) { @@ -339,6 +342,13 @@ void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow) setCurrentWindow(idx, true); } +void VEditArea::removeCurrentWindow() +{ + if (curWindowIndex > -1) { + handleRemoveSplitRequest(getWindow(curWindowIndex)); + } +} + void VEditArea::mousePressEvent(QMouseEvent *event) { QPoint pos = event->pos(); @@ -525,3 +535,38 @@ QString VEditArea::getSelectedText() return QString(); } } + +int VEditArea::focusNextWindow(int p_biaIdx) +{ + if (p_biaIdx == 0) { + return curWindowIndex; + } + int newIdx = curWindowIndex + p_biaIdx; + if (newIdx < 0) { + newIdx = 0; + } else if (newIdx >= splitter->count()) { + newIdx = splitter->count() - 1; + } + if (newIdx >= 0 && newIdx < splitter->count()) { + setCurrentWindow(newIdx, true); + } else { + newIdx = -1; + } + return newIdx; +} + +void VEditArea::moveCurrentTabOneSplit(bool p_right) +{ + if (splitter->count() < 2) { + return; + } + getWindow(curWindowIndex)->moveCurrentTabOneSplit(p_right); +} + +VEditWindow *VEditArea::getCurrentWindow() const +{ + if (curWindowIndex < 0) { + return NULL; + } + return getWindow(curWindowIndex); +} diff --git a/src/veditarea.h b/src/veditarea.h index 535224ed..1663aeb7 100644 --- a/src/veditarea.h +++ b/src/veditarea.h @@ -42,6 +42,13 @@ public: inline VFindReplaceDialog *getFindReplaceDialog() const; // Return selected text of current edit tab. QString getSelectedText(); + void splitCurrentWindow(); + void removeCurrentWindow(); + // Focus next window (curWindowIndex + p_biaIdx). + // Return the new current window index, otherwise, return -1. + int focusNextWindow(int p_biaIdx); + void moveCurrentTabOneSplit(bool p_right); + VEditWindow *getCurrentWindow() const; signals: void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode); diff --git a/src/vedittab.cpp b/src/vedittab.cpp index ce091358..97ccc2fa 100644 --- a/src/vedittab.cpp +++ b/src/vedittab.cpp @@ -333,6 +333,10 @@ void VEditTab::focusTab() void VEditTab::handleFocusChanged(QWidget * /* old */, QWidget *now) { if (isChild(now)) { + if (now == this) { + // When VEditTab get focus, it should focus to current widget. + currentWidget()->setFocus(); + } emit getFocused(); } } diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index 471c1f44..c7e1d593 100644 --- a/src/veditwindow.cpp +++ b/src/veditwindow.cpp @@ -28,7 +28,6 @@ VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent) connect(bar, &QTabBar::customContextMenuRequested, this, &VEditWindow::tabbarContextMenuRequested); - connect(this, &VEditWindow::tabCloseRequested, this, &VEditWindow::handleTabCloseRequest); connect(this, &VEditWindow::tabBarClicked, @@ -416,17 +415,13 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos) menu.addAction(m_locateAct); int totalWin = m_editArea->windowCount(); - int idx = m_editArea->windowIndex(this); if (totalWin > 1) { menu.addSeparator(); - if (idx > 0) { - m_moveLeftAct->setData(tab); - menu.addAction(m_moveLeftAct); - } - if (idx < totalWin - 1) { - m_moveRightAct->setData(tab); - menu.addAction(m_moveRightAct); - } + m_moveLeftAct->setData(tab); + menu.addAction(m_moveLeftAct); + + m_moveRightAct->setData(tab); + menu.addAction(m_moveRightAct); } menu.exec(bar->mapToGlobal(p_pos)); @@ -615,18 +610,41 @@ void VEditWindow::handleLocateAct() void VEditWindow::handleMoveLeftAct() { - int tab = m_locateAct->data().toInt(); + int tab = m_moveLeftAct->data().toInt(); Q_ASSERT(tab != -1); - VEditTab *editor = getTab(tab); + moveTabOneSplit(tab, false); +} + +void VEditWindow::handleMoveRightAct() +{ + int tab = m_moveRightAct->data().toInt(); + Q_ASSERT(tab != -1); + moveTabOneSplit(tab, true); +} + +void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right) +{ + Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count()); + int totalWin = m_editArea->windowCount(); + if (totalWin < 2) { + return; + } + int idx = m_editArea->windowIndex(this); + int newIdx = p_right ? idx + 1 : idx - 1; + if (newIdx >= totalWin) { + newIdx = 0; + } else if (newIdx < 0) { + newIdx = totalWin - 1; + } + VEditTab *editor = getTab(p_tabIdx); // Remove it from current window. This won't close the split even if it is // the only tab. - removeTab(tab); + removeTab(p_tabIdx); // Disconnect all the signals. disconnect(editor, 0, this, 0); - int idx = m_editArea->windowIndex(this); - m_editArea->moveTab(editor, idx, idx - 1); + m_editArea->moveTab(editor, idx, newIdx); // If there is no tab, remove current split. if (count() == 0) { @@ -634,25 +652,13 @@ void VEditWindow::handleMoveLeftAct() } } -void VEditWindow::handleMoveRightAct() +void VEditWindow::moveCurrentTabOneSplit(bool p_right) { - int tab = m_locateAct->data().toInt(); - Q_ASSERT(tab != -1); - VEditTab *editor = getTab(tab); - // Remove it from current window. This won't close the split even if it is - // the only tab. - removeTab(tab); - - // Disconnect all the signals. - disconnect(editor, 0, this, 0); - - int idx = m_editArea->windowIndex(this); - m_editArea->moveTab(editor, idx, idx + 1); - - // If there is no tab, remove current split. - if (count() == 0) { - emit requestRemoveSplit(this); + int idx = currentIndex(); + if (idx == -1) { + return; } + moveTabOneSplit(idx, p_right); } bool VEditWindow::addEditTab(QWidget *p_widget) @@ -697,3 +703,28 @@ void VEditWindow::clearSearchedWordHighlight() getTab(i)->clearSearchedWordHighlight(); } } + +void VEditWindow::focusNextTab(bool p_right) +{ + focusWindow(); + if (count() < 2) { + return; + } + int idx = currentIndex(); + idx = p_right ? idx + 1 : idx - 1; + if (idx < 0) { + idx = count() - 1; + } else if (idx >= count()) { + idx = 0; + } + setCurrentIndex(idx); +} + +bool VEditWindow::showOpenedFileList() +{ + if (count() == 0) { + return false; + } + leftBtn->showMenu(); + return true; +} diff --git a/src/veditwindow.h b/src/veditwindow.h index 5a1cb100..c7654cd6 100644 --- a/src/veditwindow.h +++ b/src/veditwindow.h @@ -46,6 +46,10 @@ public: // Set whether it is the current window. void setCurrentWindow(bool p_current); void clearSearchedWordHighlight(); + void moveCurrentTabOneSplit(bool p_right); + void focusNextTab(bool p_right); + // Return true if the file list is shown. + bool showOpenedFileList(); protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; @@ -90,6 +94,7 @@ private: inline QString generateTooltip(const VFile *p_file) const; inline QString generateTabText(const QString &p_name, bool p_modified) const; bool canRemoveSplit(); + void moveTabOneSplit(int p_tabIdx, bool p_right); VNote *vnote; VEditArea *m_editArea; diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp index 4579dc4e..4a66dc29 100644 --- a/src/vfilelist.cpp +++ b/src/vfilelist.cpp @@ -246,9 +246,10 @@ void VFileList::deleteFile(VFile *p_file) VDirectory *dir = p_file->getDirectory(); QString fileName = p_file->getName(); int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), - tr("Are you sure to delete note %1?").arg(fileName), - tr("This may be unrecoverable!"), - QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok, this); + tr("Are you sure to delete note %1?").arg(fileName), + tr("This may be unrecoverable!"), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Ok, this); if (ret == QMessageBox::Ok) { editArea->closeFile(p_file, true); @@ -469,6 +470,11 @@ void VFileList::keyPressEvent(QKeyEvent *event) QWidget::keyPressEvent(event); } +void VFileList::focusInEvent(QFocusEvent * /* p_event */) +{ + fileList->setFocus(); +} + bool VFileList::locateFile(const VFile *p_file) { if (p_file) { diff --git a/src/vfilelist.h b/src/vfilelist.h index add35837..82eb217f 100644 --- a/src/vfilelist.h +++ b/src/vfilelist.h @@ -17,6 +17,7 @@ class VNote; class QListWidget; class QPushButton; class VEditArea; +class QFocusEvent; class VFileList : public QWidget { @@ -52,6 +53,7 @@ public slots: protected: void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; private: void setupUI(); diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 5b287518..558b148f 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -12,6 +12,7 @@ #include "vavatar.h" #include "dialog/vfindreplacedialog.h" #include "dialog/vsettingsdialog.h" +#include "vcaptain.h" extern VConfigManager vconfig; @@ -37,6 +38,17 @@ VMainWindow::VMainWindow(QWidget *parent) setContextMenuPolicy(Qt::NoContextMenu); notebookSelector->update(); + + initCaptain(); +} + +void VMainWindow::initCaptain() +{ + // VCaptain should be visible to accpet key focus. But VCaptain + // may hide other widgets. + m_captain = new VCaptain(this); + connect(m_captain, &VCaptain::captainModeChanged, + this, &VMainWindow::handleCaptainModeChanged); } void VMainWindow::setupUI() @@ -156,10 +168,10 @@ void VMainWindow::initViewToolBar() panelMenu->addAction(twoPanelViewAct); expandViewAct = new QAction(QIcon(":/resources/icons/expand.svg"), - tr("Expand"), this); + tr("Expand"), this); expandViewAct->setStatusTip(tr("Expand the edit area")); expandViewAct->setCheckable(true); - expandViewAct->setShortcut(QKeySequence("Ctrl+E")); + expandViewAct->setShortcut(QKeySequence("Ctrl+T")); expandViewAct->setMenu(panelMenu); connect(expandViewAct, &QAction::triggered, this, &VMainWindow::expandPanelView); @@ -826,6 +838,15 @@ void VMainWindow::twoPanelView() m_onePanel = false; } +void VMainWindow::toggleOnePanelView() +{ + if (m_onePanel) { + twoPanelView(); + } else { + onePanelView(); + } +} + void VMainWindow::expandPanelView(bool p_checked) { int nrSplits = 0; @@ -948,9 +969,11 @@ void VMainWindow::resizeEvent(QResizeEvent *event) void VMainWindow::keyPressEvent(QKeyEvent *event) { - if (event->key() == Qt::Key_Escape - || (event->key() == Qt::Key_BracketLeft - && event->modifiers() == Qt::ControlModifier)) { + int key = event->key(); + Qt::KeyboardModifiers modifiers = event->modifiers(); + if (key == Qt::Key_Escape + || (key == Qt::Key_BracketLeft + && modifiers == Qt::ControlModifier)) { m_findReplaceDialog->closeDialog(); event->accept(); return; @@ -1002,6 +1025,13 @@ void VMainWindow::locateFile(VFile *p_file) twoPanelView(); } +void VMainWindow::locateCurrentFile() +{ + if (m_curFile) { + locateFile(m_curFile); + } +} + void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */) { bool enabled = true; @@ -1025,3 +1055,23 @@ void VMainWindow::viewSettings() VSettingsDialog settingsDialog(this); settingsDialog.exec(); } + +void VMainWindow::handleCaptainModeChanged(bool p_enabled) +{ + static QString normalBaseColor = m_avatar->getBaseColor(); + static QString captainModeColor = vnote->getColorFromPalette("Purple5"); + + if (p_enabled) { + m_avatar->updateBaseColor(captainModeColor); + } else { + m_avatar->updateBaseColor(normalBaseColor); + } +} + +void VMainWindow::closeCurrentFile() +{ + if (m_curFile) { + editArea->closeFile(m_curFile, false); + } +} + diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 8a12f013..b8bc3428 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -28,15 +28,19 @@ class VOutline; class VNotebookSelector; class VAvatar; class VFindReplaceDialog; +class VCaptain; class VMainWindow : public QMainWindow { Q_OBJECT public: + friend class VCaptain; + VMainWindow(QWidget *parent = 0); const QVector > &getPalette() const; void locateFile(VFile *p_file); + void locateCurrentFile(); private slots: void importNoteFromFile(); @@ -63,6 +67,7 @@ private slots: void openFindDialog(); void enableMermaid(bool p_checked); void enableMathjax(bool p_checked); + void handleCaptainModeChanged(bool p_enabled); protected: void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; @@ -97,10 +102,16 @@ private: void restoreStateAndGeometry(); void repositionAvatar(); + void initCaptain(); + void toggleOnePanelView(); + void closeCurrentFile(); + VNote *vnote; QPointer m_curFile; QPointer m_curTab; + VCaptain *m_captain; + QLabel *notebookLabel; QLabel *directoryLabel; VNotebookSelector *notebookSelector; diff --git a/src/vnote.cpp b/src/vnote.cpp index e56a5652..73c298db 100644 --- a/src/vnote.cpp +++ b/src/vnote.cpp @@ -41,7 +41,7 @@ void VNote::initPalette(QPalette palette) palette.background().color().name())); m_palette.append(QPair("hover-color", "#42A5F5")); m_palette.append(QPair("base-color", "#BDBDBD")); - m_palette.append(QPair("focus-color", "#15AE67")); + m_palette.append(QPair("focus-color", "#75C5B5")); m_palette.append(QPair("logo-base", "#D6EACE")); m_palette.append(QPair("logo-max", "#15AE67")); m_palette.append(QPair("logo-min", "#75C5B5")); @@ -79,6 +79,28 @@ void VNote::initPalette(QPalette palette) m_palette.append(QPair("Green7", "#388E3C")); m_palette.append(QPair("Green8", "#2E7D32")); m_palette.append(QPair("Green9", "#1B5E20")); + + m_palette.append(QPair("DeepPurple0", "#EDE7F6")); + m_palette.append(QPair("DeepPurple1", "#D1C4E9")); + m_palette.append(QPair("DeepPurple2", "#B39DDB")); + m_palette.append(QPair("DeepPurple3", "#9575CD")); + m_palette.append(QPair("DeepPurple4", "#7E57C2")); + m_palette.append(QPair("DeepPurple5", "#673AB7")); + m_palette.append(QPair("DeepPurple6", "#5E35B1")); + m_palette.append(QPair("DeepPurple7", "#512DA8")); + m_palette.append(QPair("DeepPurple8", "#4527A0")); + m_palette.append(QPair("DeepPurple9", "#311B92")); + + m_palette.append(QPair("Purple0", "#F3E5F5")); + m_palette.append(QPair("Purple1", "#E1BEE7")); + m_palette.append(QPair("Purple2", "#CE93D8")); + m_palette.append(QPair("Purple3", "#BA68C8")); + m_palette.append(QPair("Purple4", "#AB47BC")); + m_palette.append(QPair("Purple5", "#9C27B0")); + m_palette.append(QPair("Purple6", "#8E24AA")); + m_palette.append(QPair("Purple7", "#7B1FA2")); + m_palette.append(QPair("Purple8", "#6A1B9A")); + m_palette.append(QPair("Purple9", "#4A148C")); } QString VNote::getColorFromPalette(const QString &p_name) const