Captain mode

This commit is contained in:
Le Tan 2017-03-25 23:29:10 +08:00
parent 2a1cba1fed
commit 3406eab29c
18 changed files with 583 additions and 50 deletions

View File

@ -55,7 +55,8 @@ SOURCES += main.cpp\
dialog/vfindreplacedialog.cpp \ dialog/vfindreplacedialog.cpp \
dialog/vsettingsdialog.cpp \ dialog/vsettingsdialog.cpp \
dialog/vdeletenotebookdialog.cpp \ dialog/vdeletenotebookdialog.cpp \
dialog/vselectdialog.cpp dialog/vselectdialog.cpp \
vcaptain.cpp
HEADERS += vmainwindow.h \ HEADERS += vmainwindow.h \
vdirectorytree.h \ vdirectorytree.h \
@ -96,7 +97,8 @@ HEADERS += vmainwindow.h \
dialog/vfindreplacedialog.h \ dialog/vfindreplacedialog.h \
dialog/vsettingsdialog.h \ dialog/vsettingsdialog.h \
dialog/vdeletenotebookdialog.h \ dialog/vdeletenotebookdialog.h \
dialog/vselectdialog.h dialog/vselectdialog.h \
vcaptain.h
RESOURCES += \ RESOURCES += \
vnote.qrc \ vnote.qrc \

View File

@ -11,6 +11,7 @@
#include <QDateTime> #include <QDateTime>
#include <QFileInfo> #include <QFileInfo>
#include <QImageReader> #include <QImageReader>
#include <QKeyEvent>
const QVector<QPair<QString, QString>> VUtils::c_availableLanguages = {QPair<QString, QString>("en_US", "Englisth(US)"), const QVector<QPair<QString, QString>> VUtils::c_availableLanguages = {QPair<QString, QString>("en_US", "Englisth(US)"),
QPair<QString, QString>("zh_CN", "Chinese")}; QPair<QString, QString>("zh_CN", "Chinese")};
@ -340,3 +341,4 @@ bool VUtils::isImageURLText(const QString &p_url)
QFileInfo info(p_url); QFileInfo info(p_url);
return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1()); return QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1());
} }

View File

@ -10,6 +10,8 @@
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "vconstants.h" #include "vconstants.h"
class QKeyEvent;
class VUtils class VUtils
{ {
public: public:

View File

@ -105,3 +105,13 @@ void VAvatar::setColor(const QString &p_baseColor, const QString &p_fgColor, con
m_bgColor.setNamedColor(p_bgColor); 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();
}

View File

@ -17,7 +17,9 @@ public:
void setAvatarPixmap(const QString &p_avatarPixmap); void setAvatarPixmap(const QString &p_avatarPixmap);
void setAvatarText(const QString &p_avatarText); void setAvatarText(const QString &p_avatarText);
void setColor(const QString &p_baseColor, const QString &p_fgColor, const QString &p_bgColor); 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; QSize sizeHint() const Q_DECL_OVERRIDE;
QString getBaseColor() const;
protected: protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;

278
src/vcaptain.cpp Normal file
View File

@ -0,0 +1,278 @@
#include <QtWidgets>
#include <QString>
#include <QTimer>
#include <QDebug>
#include <QShortcut>
#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<QShortcutEvent *>(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);
}

53
src/vcaptain.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef VCAPTAIN_H
#define VCAPTAIN_H
#include <QWidget>
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

View File

@ -500,3 +500,4 @@ void VEdit::clearSearchedWordHighlight()
selects.clear(); selects.clear();
highlightExtraSelections(); highlightExtraSelections();
} }

View File

@ -167,20 +167,16 @@ void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus)
void VEditArea::setCurrentWindow(int windowIndex, bool setFocus) void VEditArea::setCurrentWindow(int windowIndex, bool setFocus)
{ {
int nrWin = splitter->count(); int nrWin = splitter->count();
if (curWindowIndex == windowIndex) {
goto out;
}
curWindowIndex = windowIndex; curWindowIndex = windowIndex;
if (curWindowIndex > -1 && setFocus) {
getWindow(curWindowIndex)->focusWindow();
}
out:
for (int i = 0; i < nrWin; ++i) { for (int i = 0; i < nrWin; ++i) {
getWindow(i)->setCurrentWindow(false); getWindow(i)->setCurrentWindow(false);
} }
if (curWindowIndex > -1) { if (curWindowIndex > -1) {
getWindow(curWindowIndex)->setCurrentWindow(true); getWindow(curWindowIndex)->setCurrentWindow(true);
if (setFocus) {
getWindow(curWindowIndex)->focusWindow();
}
} }
// Update status // Update status
updateWindowStatus(); updateWindowStatus();
@ -323,6 +319,13 @@ void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow)
setCurrentWindow(idx, true); setCurrentWindow(idx, true);
} }
void VEditArea::splitCurrentWindow()
{
if (curWindowIndex > -1) {
handleSplitWindowRequest(getWindow(curWindowIndex));
}
}
void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow) void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow)
{ {
if (!curWindow || splitter->count() <= 1) { if (!curWindow || splitter->count() <= 1) {
@ -339,6 +342,13 @@ void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow)
setCurrentWindow(idx, true); setCurrentWindow(idx, true);
} }
void VEditArea::removeCurrentWindow()
{
if (curWindowIndex > -1) {
handleRemoveSplitRequest(getWindow(curWindowIndex));
}
}
void VEditArea::mousePressEvent(QMouseEvent *event) void VEditArea::mousePressEvent(QMouseEvent *event)
{ {
QPoint pos = event->pos(); QPoint pos = event->pos();
@ -525,3 +535,38 @@ QString VEditArea::getSelectedText()
return QString(); 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);
}

View File

@ -42,6 +42,13 @@ public:
inline VFindReplaceDialog *getFindReplaceDialog() const; inline VFindReplaceDialog *getFindReplaceDialog() const;
// Return selected text of current edit tab. // Return selected text of current edit tab.
QString getSelectedText(); 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: signals:
void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode); void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);

View File

@ -333,6 +333,10 @@ void VEditTab::focusTab()
void VEditTab::handleFocusChanged(QWidget * /* old */, QWidget *now) void VEditTab::handleFocusChanged(QWidget * /* old */, QWidget *now)
{ {
if (isChild(now)) { if (isChild(now)) {
if (now == this) {
// When VEditTab get focus, it should focus to current widget.
currentWidget()->setFocus();
}
emit getFocused(); emit getFocused();
} }
} }

View File

@ -28,7 +28,6 @@ VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
connect(bar, &QTabBar::customContextMenuRequested, connect(bar, &QTabBar::customContextMenuRequested,
this, &VEditWindow::tabbarContextMenuRequested); this, &VEditWindow::tabbarContextMenuRequested);
connect(this, &VEditWindow::tabCloseRequested, connect(this, &VEditWindow::tabCloseRequested,
this, &VEditWindow::handleTabCloseRequest); this, &VEditWindow::handleTabCloseRequest);
connect(this, &VEditWindow::tabBarClicked, connect(this, &VEditWindow::tabBarClicked,
@ -416,18 +415,14 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
menu.addAction(m_locateAct); menu.addAction(m_locateAct);
int totalWin = m_editArea->windowCount(); int totalWin = m_editArea->windowCount();
int idx = m_editArea->windowIndex(this);
if (totalWin > 1) { if (totalWin > 1) {
menu.addSeparator(); menu.addSeparator();
if (idx > 0) {
m_moveLeftAct->setData(tab); m_moveLeftAct->setData(tab);
menu.addAction(m_moveLeftAct); menu.addAction(m_moveLeftAct);
}
if (idx < totalWin - 1) {
m_moveRightAct->setData(tab); m_moveRightAct->setData(tab);
menu.addAction(m_moveRightAct); menu.addAction(m_moveRightAct);
} }
}
menu.exec(bar->mapToGlobal(p_pos)); menu.exec(bar->mapToGlobal(p_pos));
} }
@ -615,18 +610,41 @@ void VEditWindow::handleLocateAct()
void VEditWindow::handleMoveLeftAct() void VEditWindow::handleMoveLeftAct()
{ {
int tab = m_locateAct->data().toInt(); int tab = m_moveLeftAct->data().toInt();
Q_ASSERT(tab != -1); 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 // Remove it from current window. This won't close the split even if it is
// the only tab. // the only tab.
removeTab(tab); removeTab(p_tabIdx);
// Disconnect all the signals. // Disconnect all the signals.
disconnect(editor, 0, this, 0); disconnect(editor, 0, this, 0);
int idx = m_editArea->windowIndex(this); m_editArea->moveTab(editor, idx, newIdx);
m_editArea->moveTab(editor, idx, idx - 1);
// If there is no tab, remove current split. // If there is no tab, remove current split.
if (count() == 0) { 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(); int idx = currentIndex();
Q_ASSERT(tab != -1); if (idx == -1) {
VEditTab *editor = getTab(tab); return;
// 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);
} }
moveTabOneSplit(idx, p_right);
} }
bool VEditWindow::addEditTab(QWidget *p_widget) bool VEditWindow::addEditTab(QWidget *p_widget)
@ -697,3 +703,28 @@ void VEditWindow::clearSearchedWordHighlight()
getTab(i)->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;
}

View File

@ -46,6 +46,10 @@ public:
// Set whether it is the current window. // Set whether it is the current window.
void setCurrentWindow(bool p_current); void setCurrentWindow(bool p_current);
void clearSearchedWordHighlight(); void clearSearchedWordHighlight();
void moveCurrentTabOneSplit(bool p_right);
void focusNextTab(bool p_right);
// Return true if the file list is shown.
bool showOpenedFileList();
protected: protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
@ -90,6 +94,7 @@ private:
inline QString generateTooltip(const VFile *p_file) const; inline QString generateTooltip(const VFile *p_file) const;
inline QString generateTabText(const QString &p_name, bool p_modified) const; inline QString generateTabText(const QString &p_name, bool p_modified) const;
bool canRemoveSplit(); bool canRemoveSplit();
void moveTabOneSplit(int p_tabIdx, bool p_right);
VNote *vnote; VNote *vnote;
VEditArea *m_editArea; VEditArea *m_editArea;

View File

@ -248,7 +248,8 @@ void VFileList::deleteFile(VFile *p_file)
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"), int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
tr("Are you sure to delete note %1?").arg(fileName), tr("Are you sure to delete note %1?").arg(fileName),
tr("This may be unrecoverable!"), tr("This may be unrecoverable!"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok, this); QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Ok, this);
if (ret == QMessageBox::Ok) { if (ret == QMessageBox::Ok) {
editArea->closeFile(p_file, true); editArea->closeFile(p_file, true);
@ -469,6 +470,11 @@ void VFileList::keyPressEvent(QKeyEvent *event)
QWidget::keyPressEvent(event); QWidget::keyPressEvent(event);
} }
void VFileList::focusInEvent(QFocusEvent * /* p_event */)
{
fileList->setFocus();
}
bool VFileList::locateFile(const VFile *p_file) bool VFileList::locateFile(const VFile *p_file)
{ {
if (p_file) { if (p_file) {

View File

@ -17,6 +17,7 @@ class VNote;
class QListWidget; class QListWidget;
class QPushButton; class QPushButton;
class VEditArea; class VEditArea;
class QFocusEvent;
class VFileList : public QWidget class VFileList : public QWidget
{ {
@ -52,6 +53,7 @@ public slots:
protected: protected:
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE;
private: private:
void setupUI(); void setupUI();

View File

@ -12,6 +12,7 @@
#include "vavatar.h" #include "vavatar.h"
#include "dialog/vfindreplacedialog.h" #include "dialog/vfindreplacedialog.h"
#include "dialog/vsettingsdialog.h" #include "dialog/vsettingsdialog.h"
#include "vcaptain.h"
extern VConfigManager vconfig; extern VConfigManager vconfig;
@ -37,6 +38,17 @@ VMainWindow::VMainWindow(QWidget *parent)
setContextMenuPolicy(Qt::NoContextMenu); setContextMenuPolicy(Qt::NoContextMenu);
notebookSelector->update(); 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() void VMainWindow::setupUI()
@ -159,7 +171,7 @@ void VMainWindow::initViewToolBar()
tr("Expand"), this); tr("Expand"), this);
expandViewAct->setStatusTip(tr("Expand the edit area")); expandViewAct->setStatusTip(tr("Expand the edit area"));
expandViewAct->setCheckable(true); expandViewAct->setCheckable(true);
expandViewAct->setShortcut(QKeySequence("Ctrl+E")); expandViewAct->setShortcut(QKeySequence("Ctrl+T"));
expandViewAct->setMenu(panelMenu); expandViewAct->setMenu(panelMenu);
connect(expandViewAct, &QAction::triggered, connect(expandViewAct, &QAction::triggered,
this, &VMainWindow::expandPanelView); this, &VMainWindow::expandPanelView);
@ -826,6 +838,15 @@ void VMainWindow::twoPanelView()
m_onePanel = false; m_onePanel = false;
} }
void VMainWindow::toggleOnePanelView()
{
if (m_onePanel) {
twoPanelView();
} else {
onePanelView();
}
}
void VMainWindow::expandPanelView(bool p_checked) void VMainWindow::expandPanelView(bool p_checked)
{ {
int nrSplits = 0; int nrSplits = 0;
@ -948,9 +969,11 @@ void VMainWindow::resizeEvent(QResizeEvent *event)
void VMainWindow::keyPressEvent(QKeyEvent *event) void VMainWindow::keyPressEvent(QKeyEvent *event)
{ {
if (event->key() == Qt::Key_Escape int key = event->key();
|| (event->key() == Qt::Key_BracketLeft Qt::KeyboardModifiers modifiers = event->modifiers();
&& event->modifiers() == Qt::ControlModifier)) { if (key == Qt::Key_Escape
|| (key == Qt::Key_BracketLeft
&& modifiers == Qt::ControlModifier)) {
m_findReplaceDialog->closeDialog(); m_findReplaceDialog->closeDialog();
event->accept(); event->accept();
return; return;
@ -1002,6 +1025,13 @@ void VMainWindow::locateFile(VFile *p_file)
twoPanelView(); twoPanelView();
} }
void VMainWindow::locateCurrentFile()
{
if (m_curFile) {
locateFile(m_curFile);
}
}
void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */) void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */)
{ {
bool enabled = true; bool enabled = true;
@ -1025,3 +1055,23 @@ void VMainWindow::viewSettings()
VSettingsDialog settingsDialog(this); VSettingsDialog settingsDialog(this);
settingsDialog.exec(); 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);
}
}

View File

@ -28,15 +28,19 @@ class VOutline;
class VNotebookSelector; class VNotebookSelector;
class VAvatar; class VAvatar;
class VFindReplaceDialog; class VFindReplaceDialog;
class VCaptain;
class VMainWindow : public QMainWindow class VMainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
friend class VCaptain;
VMainWindow(QWidget *parent = 0); VMainWindow(QWidget *parent = 0);
const QVector<QPair<QString, QString> > &getPalette() const; const QVector<QPair<QString, QString> > &getPalette() const;
void locateFile(VFile *p_file); void locateFile(VFile *p_file);
void locateCurrentFile();
private slots: private slots:
void importNoteFromFile(); void importNoteFromFile();
@ -63,6 +67,7 @@ private slots:
void openFindDialog(); void openFindDialog();
void enableMermaid(bool p_checked); void enableMermaid(bool p_checked);
void enableMathjax(bool p_checked); void enableMathjax(bool p_checked);
void handleCaptainModeChanged(bool p_enabled);
protected: protected:
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
@ -97,10 +102,16 @@ private:
void restoreStateAndGeometry(); void restoreStateAndGeometry();
void repositionAvatar(); void repositionAvatar();
void initCaptain();
void toggleOnePanelView();
void closeCurrentFile();
VNote *vnote; VNote *vnote;
QPointer<VFile> m_curFile; QPointer<VFile> m_curFile;
QPointer<VEditTab> m_curTab; QPointer<VEditTab> m_curTab;
VCaptain *m_captain;
QLabel *notebookLabel; QLabel *notebookLabel;
QLabel *directoryLabel; QLabel *directoryLabel;
VNotebookSelector *notebookSelector; VNotebookSelector *notebookSelector;

View File

@ -41,7 +41,7 @@ void VNote::initPalette(QPalette palette)
palette.background().color().name())); palette.background().color().name()));
m_palette.append(QPair<QString, QString>("hover-color", "#42A5F5")); m_palette.append(QPair<QString, QString>("hover-color", "#42A5F5"));
m_palette.append(QPair<QString, QString>("base-color", "#BDBDBD")); m_palette.append(QPair<QString, QString>("base-color", "#BDBDBD"));
m_palette.append(QPair<QString, QString>("focus-color", "#15AE67")); m_palette.append(QPair<QString, QString>("focus-color", "#75C5B5"));
m_palette.append(QPair<QString, QString>("logo-base", "#D6EACE")); m_palette.append(QPair<QString, QString>("logo-base", "#D6EACE"));
m_palette.append(QPair<QString, QString>("logo-max", "#15AE67")); m_palette.append(QPair<QString, QString>("logo-max", "#15AE67"));
m_palette.append(QPair<QString, QString>("logo-min", "#75C5B5")); m_palette.append(QPair<QString, QString>("logo-min", "#75C5B5"));
@ -79,6 +79,28 @@ void VNote::initPalette(QPalette palette)
m_palette.append(QPair<QString, QString>("Green7", "#388E3C")); m_palette.append(QPair<QString, QString>("Green7", "#388E3C"));
m_palette.append(QPair<QString, QString>("Green8", "#2E7D32")); m_palette.append(QPair<QString, QString>("Green8", "#2E7D32"));
m_palette.append(QPair<QString, QString>("Green9", "#1B5E20")); m_palette.append(QPair<QString, QString>("Green9", "#1B5E20"));
m_palette.append(QPair<QString, QString>("DeepPurple0", "#EDE7F6"));
m_palette.append(QPair<QString, QString>("DeepPurple1", "#D1C4E9"));
m_palette.append(QPair<QString, QString>("DeepPurple2", "#B39DDB"));
m_palette.append(QPair<QString, QString>("DeepPurple3", "#9575CD"));
m_palette.append(QPair<QString, QString>("DeepPurple4", "#7E57C2"));
m_palette.append(QPair<QString, QString>("DeepPurple5", "#673AB7"));
m_palette.append(QPair<QString, QString>("DeepPurple6", "#5E35B1"));
m_palette.append(QPair<QString, QString>("DeepPurple7", "#512DA8"));
m_palette.append(QPair<QString, QString>("DeepPurple8", "#4527A0"));
m_palette.append(QPair<QString, QString>("DeepPurple9", "#311B92"));
m_palette.append(QPair<QString, QString>("Purple0", "#F3E5F5"));
m_palette.append(QPair<QString, QString>("Purple1", "#E1BEE7"));
m_palette.append(QPair<QString, QString>("Purple2", "#CE93D8"));
m_palette.append(QPair<QString, QString>("Purple3", "#BA68C8"));
m_palette.append(QPair<QString, QString>("Purple4", "#AB47BC"));
m_palette.append(QPair<QString, QString>("Purple5", "#9C27B0"));
m_palette.append(QPair<QString, QString>("Purple6", "#8E24AA"));
m_palette.append(QPair<QString, QString>("Purple7", "#7B1FA2"));
m_palette.append(QPair<QString, QString>("Purple8", "#6A1B9A"));
m_palette.append(QPair<QString, QString>("Purple9", "#4A148C"));
} }
QString VNote::getColorFromPalette(const QString &p_name) const QString VNote::getColorFromPalette(const QString &p_name) const