refactor VCaptain to enable Captain mode with Input Method

This commit is contained in:
Le Tan 2017-11-21 20:15:58 +08:00
parent 8d568e6e23
commit 6c83f9bd04
9 changed files with 289 additions and 127 deletions

View File

@ -1066,3 +1066,11 @@ void VUtils::touchFile(const QString &p_file)
file.close(); file.close();
} }
bool VUtils::isMetaKey(int p_key)
{
return p_key == Qt::Key_Control
|| p_key == Qt::Key_Shift
|| p_key == Qt::Key_Meta
|| p_key == Qt::Key_Alt;
}

View File

@ -258,6 +258,9 @@ public:
// If @p_file does not exists, create an empty file. // If @p_file does not exists, create an empty file.
static void touchFile(const QString &p_file); static void touchFile(const QString &p_file);
// Ctrl, Meta, Shift, Alt.
static bool isMetaKey(int p_key);
// Regular expression for image link. // Regular expression for image link.
// ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" ) // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
// Captured texts (need to be trimmed): // Captured texts (need to be trimmed):

View File

@ -14,13 +14,10 @@ extern VConfigManager *g_config;
VCaptain::VCaptain(QWidget *p_parent) VCaptain::VCaptain(QWidget *p_parent)
: QWidget(p_parent), : QWidget(p_parent),
m_mode(CaptainMode::Normal), m_mode(CaptainMode::Normal),
m_widgetBeforeNavigation(NULL), m_widgetBeforeCaptain(NULL),
m_nextMajorKey('a'), m_nextMajorKey('a'),
m_ignoreFocusChange(false), m_ignoreFocusChange(false)
m_leaderKey(g_config->getShortcutKeySequence("CaptainMode"))
{ {
Q_ASSERT(!m_leaderKey.isEmpty());
connect(qApp, &QApplication::focusChanged, connect(qApp, &QApplication::focusChanged,
this, &VCaptain::handleFocusChanged); this, &VCaptain::handleFocusChanged);
@ -30,6 +27,14 @@ VCaptain::VCaptain(QWidget *p_parent)
// of VMainWindow. // of VMainWindow.
resize(1, 1); resize(1, 1);
// Register Captain mode leader key.
// This can fix the Input Method blocking issue.
QShortcut *shortcut = new QShortcut(QKeySequence(g_config->getShortcutKeySequence("CaptainMode")),
this);
shortcut->setContext(Qt::ApplicationShortcut);
connect(shortcut, &QShortcut::activated,
this, &VCaptain::trigger);
// Register Navigation mode as Captain mode target. // Register Navigation mode as Captain mode target.
registerCaptainTarget(tr("NavigationMode"), registerCaptainTarget(tr("NavigationMode"),
g_config->getCaptainShortcutKeySequence("NavigationMode"), g_config->getCaptainShortcutKeySequence("NavigationMode"),
@ -61,19 +66,31 @@ void VCaptain::handleFocusChanged(QWidget *p_old, QWidget * p_now)
{ {
Q_UNUSED(p_now); Q_UNUSED(p_now);
if (!m_ignoreFocusChange if (p_old == this
&& !checkMode(CaptainMode::Normal) && !m_ignoreFocusChange
&& p_old == this) { && !checkMode(CaptainMode::Normal)) {
exitNavigationMode(); exitCaptainMode();
} }
} }
void VCaptain::trigger()
{
if (!checkMode(CaptainMode::Normal)) {
exitCaptainMode();
return;
}
triggerCaptainMode();
}
void VCaptain::keyPressEvent(QKeyEvent *p_event) void VCaptain::keyPressEvent(QKeyEvent *p_event)
{ {
int key = p_event->key(); int key = p_event->key();
Qt::KeyboardModifiers modifiers = p_event->modifiers(); Qt::KeyboardModifiers modifiers = p_event->modifiers();
if (key == Qt::Key_Control || key == Qt::Key_Shift) { Q_ASSERT(!checkMode(CaptainMode::Normal));
if (VUtils::isMetaKey(key)) {
QWidget::keyPressEvent(p_event); QWidget::keyPressEvent(p_event);
return; return;
} }
@ -87,18 +104,19 @@ void VCaptain::keyPressEvent(QKeyEvent *p_event)
bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers) bool VCaptain::handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers)
{ {
if (!checkMode(CaptainMode::Navigation)) { bool ret = true;
return false;
m_ignoreFocusChange = true;
if (checkMode(CaptainMode::Navigation)) {
ret = handleKeyPressNavigationMode(p_key, p_modifiers);
m_ignoreFocusChange = false;
return ret;
} }
if (p_key == Qt::Key_Escape ret = handleKeyPressCaptainMode(p_key, p_modifiers);
|| (p_key == Qt::Key_BracketLeft m_ignoreFocusChange = false;
&& p_modifiers == Qt::ControlModifier)) { return ret;
exitNavigationMode();
return true;
}
return handleKeyPressNavigationMode(p_key, p_modifiers);
} }
bool VCaptain::handleKeyPressNavigationMode(int p_key, bool VCaptain::handleKeyPressNavigationMode(int p_key,
@ -107,7 +125,6 @@ bool VCaptain::handleKeyPressNavigationMode(int p_key,
Q_ASSERT(m_mode == CaptainMode::Navigation); Q_ASSERT(m_mode == CaptainMode::Navigation);
bool hasConsumed = false; bool hasConsumed = false;
bool pending = false; bool pending = false;
m_ignoreFocusChange = true;
for (auto &target : m_naviTargets) { for (auto &target : m_naviTargets) {
if (hasConsumed) { if (hasConsumed) {
target.m_available = false; target.m_available = false;
@ -122,7 +139,7 @@ bool VCaptain::handleKeyPressNavigationMode(int p_key,
hasConsumed = true; hasConsumed = true;
if (succeed) { if (succeed) {
// Exit. // Exit.
m_widgetBeforeNavigation = NULL; m_widgetBeforeCaptain = NULL;
} else { } else {
// Consumed but not succeed. Need more keys. // Consumed but not succeed. Need more keys.
pending = true; pending = true;
@ -135,21 +152,18 @@ bool VCaptain::handleKeyPressNavigationMode(int p_key,
} }
} }
m_ignoreFocusChange = false;
if (pending) { if (pending) {
return true; return true;
} }
exitNavigationMode(); exitCaptainMode();
return true; return true;
} }
void VCaptain::triggerNavigationMode() void VCaptain::triggerNavigationMode()
{ {
setMode(CaptainMode::Navigation); setMode(CaptainMode::Navigation);
m_widgetBeforeNavigation = QApplication::focusWidget();
// Focus to listen pending key press.
setFocus();
for (auto &target : m_naviTargets) { for (auto &target : m_naviTargets) {
target.m_available = true; target.m_available = true;
target.m_target->showNavigation(); target.m_target->showNavigation();
@ -164,17 +178,30 @@ void VCaptain::exitNavigationMode()
target.m_available = true; target.m_available = true;
target.m_target->hideNavigation(); target.m_target->hideNavigation();
} }
restoreFocus();
} }
void VCaptain::restoreFocus() void VCaptain::restoreFocus()
{ {
if (m_widgetBeforeNavigation) { if (m_widgetBeforeCaptain) {
m_widgetBeforeNavigation->setFocus(); m_widgetBeforeCaptain->setFocus();
m_widgetBeforeCaptain = NULL;
} }
} }
void VCaptain::exitCaptainMode()
{
if (checkMode(CaptainMode::Navigation)) {
exitNavigationMode();
}
setMode(CaptainMode::Normal);
m_ignoreFocusChange = false;
restoreFocus();
qDebug() << "exit Captain mode";
}
bool VCaptain::registerCaptainTarget(const QString &p_name, bool VCaptain::registerCaptainTarget(const QString &p_name,
const QString &p_key, const QString &p_key,
void *p_target, void *p_target,
@ -184,48 +211,72 @@ bool VCaptain::registerCaptainTarget(const QString &p_name,
return false; return false;
} }
QString lowerKey = p_key.toLower(); QString normKey = QKeySequence(p_key).toString();
if (m_captainTargets.contains(lowerKey)) { if (m_captainTargets.contains(normKey)) {
return false; return false;
} }
// Register shortcuts.
QString sequence = QString("%1,%2").arg(m_leaderKey).arg(p_key);
QShortcut *shortcut = new QShortcut(QKeySequence(sequence),
this);
shortcut->setContext(Qt::ApplicationShortcut);
connect(shortcut, &QShortcut::activated,
this, std::bind(&VCaptain::triggerCaptainTarget, this, p_key));
CaptainModeTarget target(p_name, CaptainModeTarget target(p_name,
p_key, normKey,
p_target, p_target,
p_func, p_func);
shortcut); m_captainTargets.insert(normKey, target);
m_captainTargets.insert(lowerKey, target);
qDebug() << "registered:" << target.toString() << sequence; qDebug() << "registered:" << target.toString() << normKey;
return true; return true;
} }
void VCaptain::triggerCaptainTarget(const QString &p_key) void VCaptain::triggerCaptainTarget(const QString &p_key)
{ {
auto it = m_captainTargets.find(p_key.toLower()); auto it = m_captainTargets.find(p_key);
Q_ASSERT(it != m_captainTargets.end()); if (it == m_captainTargets.end()) {
return;
}
const CaptainModeTarget &target = it.value(); const CaptainModeTarget &target = it.value();
qDebug() << "triggered:" << target.toString(); qDebug() << "triggered:" << target.toString();
target.m_function(target.m_target, nullptr); CaptainData data(m_widgetBeforeCaptain);
if (!target.m_function(target.m_target, (void *)&data)) {
m_widgetBeforeCaptain = NULL;
}
} }
void VCaptain::navigationModeByCaptain(void *p_target, void *p_data) bool VCaptain::navigationModeByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VCaptain *obj = static_cast<VCaptain *>(p_target); VCaptain *obj = static_cast<VCaptain *>(p_target);
obj->triggerNavigationMode(); obj->triggerNavigationMode();
return true;
}
void VCaptain::triggerCaptainMode()
{
qDebug() << "trigger Captain mode";
m_widgetBeforeCaptain = QApplication::focusWidget();
m_ignoreFocusChange = false;
setMode(CaptainMode::Pending);
// Focus to listen pending key press.
setFocus();
}
bool VCaptain::handleKeyPressCaptainMode(int p_key,
Qt::KeyboardModifiers p_modifiers)
{
Q_ASSERT(checkMode(CaptainMode::Pending));
QString normKey = QKeySequence(p_key | p_modifiers).toString();
triggerCaptainTarget(normKey);
if (!checkMode(CaptainMode::Navigation)) {
exitCaptainMode();
}
return true;
} }

View File

@ -11,8 +11,22 @@ class QKeyEvent;
class VNavigationMode; class VNavigationMode;
class QShortcut; class QShortcut;
// void func(void *p_target, void *p_data); // bool func(void *p_target, void *p_data);
typedef std::function<void(void *, void *)> CaptainFunc; // Return true if the target needs to restore focus by the Captain.
typedef std::function<bool(void *, void *)> CaptainFunc;
// Will be passed to CaptainFunc as the data.
struct CaptainData
{
CaptainData(QWidget *p_focusWidgetBeforeCaptain)
: m_focusWidgetBeforeCaptain(p_focusWidgetBeforeCaptain)
{
}
QWidget *m_focusWidgetBeforeCaptain;
};
class VCaptain : public QWidget class VCaptain : public QWidget
{ {
@ -62,20 +76,18 @@ private:
struct CaptainModeTarget { struct CaptainModeTarget {
CaptainModeTarget() CaptainModeTarget()
: m_target(nullptr), m_function(nullptr), m_shortcut(nullptr) : m_target(nullptr), m_function(nullptr)
{ {
} }
CaptainModeTarget(const QString &p_name, CaptainModeTarget(const QString &p_name,
const QString &p_key, const QString &p_key,
void *p_target, void *p_target,
CaptainFunc p_func, CaptainFunc p_func)
QShortcut *p_shortcut)
: m_name(p_name), : m_name(p_name),
m_key(p_key), m_key(p_key),
m_target(p_target), m_target(p_target),
m_function(p_func), m_function(p_func)
m_shortcut(p_shortcut)
{ {
} }
@ -96,12 +108,9 @@ private:
// Function to call when this target is trigger. // Function to call when this target is trigger.
CaptainFunc m_function; CaptainFunc m_function;
// Shortcut for this target.
QShortcut *m_shortcut;
}; };
// Restore the focus to m_widgetBeforeNavigation. // Restore the focus to m_widgetBeforeCaptain.
void restoreFocus(); void restoreFocus();
// Return true if finish handling the event; otherwise, let the base widget // Return true if finish handling the event; otherwise, let the base widget
@ -112,6 +121,10 @@ private:
bool handleKeyPressNavigationMode(int p_key, bool handleKeyPressNavigationMode(int p_key,
Qt::KeyboardModifiers p_modifiers); Qt::KeyboardModifiers p_modifiers);
// Handle key press event in Captain mode.
bool handleKeyPressCaptainMode(int p_key,
Qt::KeyboardModifiers p_modifiers);
// Get next major key to use for Navigation mode. // Get next major key to use for Navigation mode.
QChar getNextMajorKey(); QChar getNextMajorKey();
@ -121,6 +134,8 @@ private:
// Exit navigation mode to ask all targets hide themselves. // Exit navigation mode to ask all targets hide themselves.
void exitNavigationMode(); void exitNavigationMode();
void exitCaptainMode();
// Called to trigger the action of a Captain target which has // Called to trigger the action of a Captain target which has
// registered @p_key. // registered @p_key.
void triggerCaptainTarget(const QString &p_key); void triggerCaptainTarget(const QString &p_key);
@ -129,13 +144,17 @@ private:
bool checkMode(CaptainMode p_mode) const; bool checkMode(CaptainMode p_mode) const;
static void navigationModeByCaptain(void *p_target, void *p_data); void trigger();
// Used to indicate whether we are in Navigation mode. void triggerCaptainMode();
static bool navigationModeByCaptain(void *p_target, void *p_data);
// Used to indicate current mode.
CaptainMode m_mode; CaptainMode m_mode;
// The widget which has the focus before entering Navigation mode. // The widget which has the focus before entering Captain mode.
QWidget* m_widgetBeforeNavigation; QWidget *m_widgetBeforeCaptain;
// Targets for Navigation mode. // Targets for Navigation mode.
QVector<NaviModeTarget> m_naviTargets; QVector<NaviModeTarget> m_naviTargets;
@ -146,11 +165,8 @@ private:
// Key(lower) -> CaptainModeTarget. // Key(lower) -> CaptainModeTarget.
QHash<QString, CaptainModeTarget> m_captainTargets; QHash<QString, CaptainModeTarget> m_captainTargets;
// Ignore focus change during handling Navigation target actions. // Ignore focus change during handling Captain and Navigation target actions.
bool m_ignoreFocusChange; bool m_ignoreFocusChange;
// Leader key sequence for Captain mode.
QString m_leaderKey;
}; };
inline void VCaptain::setMode(CaptainMode p_mode) inline void VCaptain::setMode(CaptainMode p_mode)

View File

@ -10,6 +10,7 @@
#include "vfilesessioninfo.h" #include "vfilesessioninfo.h"
#include "vmainwindow.h" #include "vmainwindow.h"
#include "vcaptain.h" #include "vcaptain.h"
#include "vfilelist.h"
extern VConfigManager *g_config; extern VConfigManager *g_config;
@ -899,65 +900,87 @@ void VEditArea::registerCaptainTargets()
applySnippetByCaptain); applySnippetByCaptain);
} }
void VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx) bool VEditArea::activateTabByCaptain(void *p_target, void *p_data, int p_idx)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
VEditWindow *win = obj->getCurrentWindow(); VEditWindow *win = obj->getCurrentWindow();
if (win) { if (win) {
win->activateTab(p_idx); if (win->activateTab(p_idx)) {
return false;
} }
} }
void VEditArea::alternateTabByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::alternateTabByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
VEditWindow *win = obj->getCurrentWindow(); VEditWindow *win = obj->getCurrentWindow();
if (win) { if (win) {
win->alternateTab(); if (win->alternateTab()) {
return false;
} }
} }
void VEditArea::showOpenedFileListByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::showOpenedFileListByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
VEditWindow *win = obj->getCurrentWindow(); VEditWindow *win = obj->getCurrentWindow();
if (win) { if (win) {
win->showOpenedFileList(); if (win->showOpenedFileList()) {
return false;
} }
} }
void VEditArea::activateSplitLeftByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::activateSplitLeftByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->focusNextWindow(-1); if (obj->focusNextWindow(-1) > -1) {
return false;
} }
void VEditArea::activateSplitRightByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::activateSplitRightByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->focusNextWindow(1); if (obj->focusNextWindow(1) > -1) {
return false;
} }
void VEditArea::moveTabSplitLeftByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::moveTabSplitLeftByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->moveCurrentTabOneSplit(false); obj->moveCurrentTabOneSplit(false);
return true;
} }
void VEditArea::moveTabSplitRightByCaptain(void *p_target, void *p_data) bool VEditArea::moveTabSplitRightByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->moveCurrentTabOneSplit(true); obj->moveCurrentTabOneSplit(true);
return true;
} }
void VEditArea::activateNextTabByCaptain(void *p_target, void *p_data) bool VEditArea::activateNextTabByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
@ -965,50 +988,75 @@ void VEditArea::activateNextTabByCaptain(void *p_target, void *p_data)
if (win) { if (win) {
win->focusNextTab(true); win->focusNextTab(true);
} }
return true;
} }
void VEditArea::activatePreviousTabByCaptain(void *p_target, void *p_data) bool VEditArea::activatePreviousTabByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
VEditWindow *win = obj->getCurrentWindow(); VEditWindow *win = obj->getCurrentWindow();
if (win) { if (win) {
win->focusNextTab(false); win->focusNextTab(false);
} return false;
} }
void VEditArea::verticalSplitByCaptain(void *p_target, void *p_data) return true;
}
bool VEditArea::verticalSplitByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->splitCurrentWindow(); obj->splitCurrentWindow();
return false;
} }
void VEditArea::removeSplitByCaptain(void *p_target, void *p_data) bool VEditArea::removeSplitByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
obj->removeCurrentWindow(); obj->removeCurrentWindow();
QWidget *nextFocus = obj->getCurrentTab();
if (nextFocus) {
nextFocus->setFocus();
} else {
g_mainWin->getFileList()->setFocus();
} }
void VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data) return false;
}
bool VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
CaptainData *data = static_cast<CaptainData *>(p_data);
VEditTab *tab = obj->getCurrentTab(); VEditTab *tab = obj->getCurrentTab();
if (tab && tab->tabHasFocus()) { if (tab
&& (data->m_focusWidgetBeforeCaptain == tab
|| tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) {
tab->evaluateMagicWords(); tab->evaluateMagicWords();
} }
return true;
} }
void VEditArea::applySnippetByCaptain(void *p_target, void *p_data) bool VEditArea::applySnippetByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data);
VEditArea *obj = static_cast<VEditArea *>(p_target); VEditArea *obj = static_cast<VEditArea *>(p_target);
CaptainData *data = static_cast<CaptainData *>(p_data);
VEditTab *tab = obj->getCurrentTab(); VEditTab *tab = obj->getCurrentTab();
if (tab && tab->tabHasFocus()) { if (tab
&& (data->m_focusWidgetBeforeCaptain == tab
|| tab->isAncestorOf(data->m_focusWidgetBeforeCaptain))) {
tab->applySnippet(); tab->applySnippet();
} }
return true;
} }
void VEditArea::recordClosedFile(const VFileSessionInfo &p_file) void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)

View File

@ -176,33 +176,33 @@ private:
// Captain mode functions. // Captain mode functions.
// Activate tab @p_idx. // Activate tab @p_idx.
static void activateTabByCaptain(void *p_target, void *p_data, int p_idx); static bool activateTabByCaptain(void *p_target, void *p_data, int p_idx);
static void alternateTabByCaptain(void *p_target, void *p_data); static bool alternateTabByCaptain(void *p_target, void *p_data);
static void showOpenedFileListByCaptain(void *p_target, void *p_data); static bool showOpenedFileListByCaptain(void *p_target, void *p_data);
static void activateSplitLeftByCaptain(void *p_target, void *p_data); static bool activateSplitLeftByCaptain(void *p_target, void *p_data);
static void activateSplitRightByCaptain(void *p_target, void *p_data); static bool activateSplitRightByCaptain(void *p_target, void *p_data);
static void moveTabSplitLeftByCaptain(void *p_target, void *p_data); static bool moveTabSplitLeftByCaptain(void *p_target, void *p_data);
static void moveTabSplitRightByCaptain(void *p_target, void *p_data); static bool moveTabSplitRightByCaptain(void *p_target, void *p_data);
static void activateNextTabByCaptain(void *p_target, void *p_data); static bool activateNextTabByCaptain(void *p_target, void *p_data);
static void activatePreviousTabByCaptain(void *p_target, void *p_data); static bool activatePreviousTabByCaptain(void *p_target, void *p_data);
static void verticalSplitByCaptain(void *p_target, void *p_data); static bool verticalSplitByCaptain(void *p_target, void *p_data);
static void removeSplitByCaptain(void *p_target, void *p_data); static bool removeSplitByCaptain(void *p_target, void *p_data);
// Evaluate selected text or the word on cursor as magic words. // Evaluate selected text or the word on cursor as magic words.
static void evaluateMagicWordsByCaptain(void *p_target, void *p_data); static bool evaluateMagicWordsByCaptain(void *p_target, void *p_data);
// Prompt for user to apply a snippet. // Prompt for user to apply a snippet.
static void applySnippetByCaptain(void *p_target, void *p_data); static bool applySnippetByCaptain(void *p_target, void *p_data);
// End Captain mode functions. // End Captain mode functions.

View File

@ -2582,32 +2582,39 @@ bool VMainWindow::isHeadingSequenceApplicable() const
} }
// Popup the attachment list if it is enabled. // Popup the attachment list if it is enabled.
void VMainWindow::showAttachmentListByCaptain(void *p_target, void *p_data) bool VMainWindow::showAttachmentListByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
if (obj->m_attachmentBtn->isEnabled()) { if (obj->m_attachmentBtn->isEnabled()) {
obj->m_attachmentBtn->showPopupWidget(); obj->m_attachmentBtn->showPopupWidget();
} }
return true;
} }
void VMainWindow::locateCurrentFileByCaptain(void *p_target, void *p_data) bool VMainWindow::locateCurrentFileByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
if (obj->m_curFile) { if (obj->m_curFile) {
obj->locateFile(obj->m_curFile); if (obj->locateFile(obj->m_curFile)) {
return false;
} }
} }
void VMainWindow::toggleExpandModeByCaptain(void *p_target, void *p_data) return true;
}
bool VMainWindow::toggleExpandModeByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
obj->expandViewAct->trigger(); obj->expandViewAct->trigger();
return true;
} }
void VMainWindow::toggleOnePanelViewByCaptain(void *p_target, void *p_data) bool VMainWindow::toggleOnePanelViewByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
@ -2616,39 +2623,57 @@ void VMainWindow::toggleOnePanelViewByCaptain(void *p_target, void *p_data)
} else { } else {
obj->twoPanelView(); obj->twoPanelView();
} }
return true;
} }
void VMainWindow::discardAndReadByCaptain(void *p_target, void *p_data) bool VMainWindow::discardAndReadByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
if (obj->m_curFile) { if (obj->m_curTab) {
obj->discardExitAct->trigger(); obj->discardExitAct->trigger();
} obj->m_curTab->setFocus();
return false;
} }
void VMainWindow::toggleToolsDockByCaptain(void *p_target, void *p_data) return true;
}
bool VMainWindow::toggleToolsDockByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
obj->toolDock->setVisible(!obj->toolDock->isVisible()); obj->toolDock->setVisible(!obj->toolDock->isVisible());
return true;
} }
void VMainWindow::closeFileByCaptain(void *p_target, void *p_data) bool VMainWindow::closeFileByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
obj->closeCurrentFile(); obj->closeCurrentFile();
QWidget *nextFocus = obj->editArea->getCurrentTab();
if (nextFocus) {
nextFocus->setFocus();
} else {
obj->m_fileList->setFocus();
} }
void VMainWindow::shortcutsHelpByCaptain(void *p_target, void *p_data) return false;
}
bool VMainWindow::shortcutsHelpByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_data); Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target); VMainWindow *obj = static_cast<VMainWindow *>(p_target);
obj->shortcutsHelp(); obj->shortcutsHelp();
return false;
} }
void VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data) bool VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data)
{ {
Q_UNUSED(p_target); Q_UNUSED(p_target);
Q_UNUSED(p_data); Q_UNUSED(p_data);
@ -2657,6 +2682,8 @@ void VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data)
// Flush g_logFile. // Flush g_logFile.
g_logFile.flush(); g_logFile.flush();
#endif #endif
return true;
} }
void VMainWindow::promptNewNotebookIfEmpty() void VMainWindow::promptNewNotebookIfEmpty()

View File

@ -264,23 +264,23 @@ private:
// Captain mode functions. // Captain mode functions.
// Popup the attachment list if it is enabled. // Popup the attachment list if it is enabled.
static void showAttachmentListByCaptain(void *p_target, void *p_data); static bool showAttachmentListByCaptain(void *p_target, void *p_data);
static void locateCurrentFileByCaptain(void *p_target, void *p_data); static bool locateCurrentFileByCaptain(void *p_target, void *p_data);
static void toggleExpandModeByCaptain(void *p_target, void *p_data); static bool toggleExpandModeByCaptain(void *p_target, void *p_data);
static void toggleOnePanelViewByCaptain(void *p_target, void *p_data); static bool toggleOnePanelViewByCaptain(void *p_target, void *p_data);
static void discardAndReadByCaptain(void *p_target, void *p_data); static bool discardAndReadByCaptain(void *p_target, void *p_data);
static void toggleToolsDockByCaptain(void *p_target, void *p_data); static bool toggleToolsDockByCaptain(void *p_target, void *p_data);
static void closeFileByCaptain(void *p_target, void *p_data); static bool closeFileByCaptain(void *p_target, void *p_data);
static void shortcutsHelpByCaptain(void *p_target, void *p_data); static bool shortcutsHelpByCaptain(void *p_target, void *p_data);
static void flushLogFileByCaptain(void *p_target, void *p_data); static bool flushLogFileByCaptain(void *p_target, void *p_data);
// End Captain mode functions. // End Captain mode functions.

View File

@ -4,6 +4,7 @@
#include <QLabel> #include <QLabel>
#include <QListWidget> #include <QListWidget>
#include <QTreeWidget> #include <QTreeWidget>
#include <QScrollBar>
#include "vnote.h" #include "vnote.h"
#include "utils/vutils.h" #include "utils/vutils.h"
@ -50,8 +51,16 @@ void VNavigationMode::showNavigation(QListWidget *p_widget)
label->show(); label->show();
QRect rect = p_widget->visualItemRect(items[i]); QRect rect = p_widget->visualItemRect(items[i]);
// Display the label at the end to show the file name. // Display the label at the end to show the file name.
label->move(rect.x() + p_widget->rect().width() - label->width() - 2, // Fix: take the vertical scrollbar into account.
int extraWidth = label->width() + 2;
QScrollBar *vbar = p_widget->verticalScrollBar();
if (vbar && vbar->minimum() != vbar->maximum()) {
extraWidth += vbar->width();
}
label->move(rect.x() + p_widget->rect().width() - extraWidth,
rect.y()); rect.y());
m_naviLabels.append(label); m_naviLabels.append(label);
} }
} }