mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
vim-mode: add an indicator for Vim status in status bar
This commit is contained in:
parent
ffce4b9611
commit
d909091f46
@ -2,7 +2,8 @@
|
|||||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
<path d="M184.7,413.1l2.1-1.8l156.5-136c5.3-4.6,8.6-11.5,8.6-19.2c0-7.7-3.4-14.6-8.6-19.2L187.1,101l-2.6-2.3
|
<g>
|
||||||
C182,97,179,96,175.8,96c-8.7,0-15.8,7.4-15.8,16.6h0v286.8h0c0,9.2,7.1,16.6,15.8,16.6C179.1,416,182.2,414.9,184.7,413.1z"/>
|
<polygon points="128,320 256,192 384,320 "/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 725 B After Width: | Height: | Size: 542 B |
@ -17,6 +17,22 @@ QPushButton[CornerBtn="true"]::focus {
|
|||||||
background-color: @focus-color;
|
background-color: @focus-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPushButton[StatusBtn="true"] {
|
||||||
|
font: bold;
|
||||||
|
padding: 0px 2px 0px 2px;
|
||||||
|
margin: 0px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton[StatusBtn="true"]::hover {
|
||||||
|
background-color: @hover-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton[StatusBtn="true"]::focus {
|
||||||
|
background-color: @focus-color;
|
||||||
|
}
|
||||||
|
|
||||||
QPushButton[FlatBtn="true"] {
|
QPushButton[FlatBtn="true"] {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
@ -66,7 +66,9 @@ SOURCES += main.cpp\
|
|||||||
vmdtab.cpp \
|
vmdtab.cpp \
|
||||||
vhtmltab.cpp \
|
vhtmltab.cpp \
|
||||||
utils/vvim.cpp \
|
utils/vvim.cpp \
|
||||||
utils/veditutils.cpp
|
utils/veditutils.cpp \
|
||||||
|
vvimindicator.cpp \
|
||||||
|
vbuttonwithwidget.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -119,7 +121,9 @@ HEADERS += vmainwindow.h \
|
|||||||
vmdtab.h \
|
vmdtab.h \
|
||||||
vhtmltab.h \
|
vhtmltab.h \
|
||||||
utils/vvim.h \
|
utils/vvim.h \
|
||||||
utils/veditutils.h
|
utils/veditutils.h \
|
||||||
|
vvimindicator.h \
|
||||||
|
vbuttonwithwidget.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc \
|
vnote.qrc \
|
||||||
|
@ -290,12 +290,16 @@ bool VVim::handleKeyPressEvent(QKeyEvent *p_event)
|
|||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pendingKeys.append(keyInfo);
|
||||||
|
|
||||||
if (expectingRegisterName()) {
|
if (expectingRegisterName()) {
|
||||||
// Expecting a register name.
|
// Expecting a register name.
|
||||||
QChar reg = keyToRegisterName(keyInfo);
|
QChar reg = keyToRegisterName(keyInfo);
|
||||||
if (!reg.isNull()) {
|
if (!reg.isNull()) {
|
||||||
resetState();
|
// We should keep m_pendingKeys.
|
||||||
m_regName = reg;
|
m_keys.clear();
|
||||||
|
m_tokens.clear();
|
||||||
|
setRegister(reg);
|
||||||
if (m_registers[reg].isNamedRegister()) {
|
if (m_registers[reg].isNamedRegister()) {
|
||||||
m_registers[reg].m_append = (modifiers == Qt::ShiftModifier);
|
m_registers[reg].m_append = (modifiers == Qt::ShiftModifier);
|
||||||
} else {
|
} else {
|
||||||
@ -1281,6 +1285,7 @@ accept:
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
m_resetPositionInBlock = resetPositionInBlock;
|
m_resetPositionInBlock = resetPositionInBlock;
|
||||||
|
emit vimStatusUpdated(this);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,7 +1293,8 @@ void VVim::resetState()
|
|||||||
{
|
{
|
||||||
m_keys.clear();
|
m_keys.clear();
|
||||||
m_tokens.clear();
|
m_tokens.clear();
|
||||||
m_regName = c_unnamedRegister;
|
m_pendingKeys.clear();
|
||||||
|
setRegister(c_unnamedRegister);
|
||||||
m_resetPositionInBlock = true;
|
m_resetPositionInBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1305,6 +1311,7 @@ void VVim::setMode(VimMode p_mode)
|
|||||||
resetState();
|
resetState();
|
||||||
|
|
||||||
emit modeChanged(m_mode);
|
emit modeChanged(m_mode);
|
||||||
|
emit vimStatusUpdated(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3380,3 +3387,28 @@ void VVim::message(const QString &p_msg)
|
|||||||
qDebug() << "vim msg:" << p_msg;
|
qDebug() << "vim msg:" << p_msg;
|
||||||
emit vimMessage(p_msg);
|
emit vimMessage(p_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QMap<QChar, VVim::Register> &VVim::getRegisters() const
|
||||||
|
{
|
||||||
|
return m_registers;
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar VVim::getCurrentRegisterName() const
|
||||||
|
{
|
||||||
|
return m_regName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VVim::getPendingKeys() const
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
for (auto const & key : m_pendingKeys) {
|
||||||
|
str.append(keyToChar(key.m_key, key.m_modifiers));
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVim::setRegister(QChar p_reg)
|
||||||
|
{
|
||||||
|
m_regName = p_reg;
|
||||||
|
}
|
||||||
|
148
src/utils/vvim.h
148
src/utils/vvim.h
@ -4,7 +4,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTextCursor>
|
#include <QTextCursor>
|
||||||
#include <QHash>
|
#include <QMap>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "vutils.h"
|
#include "vutils.h"
|
||||||
|
|
||||||
@ -28,6 +28,69 @@ class VVim : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit VVim(VEdit *p_editor);
|
explicit VVim(VEdit *p_editor);
|
||||||
|
|
||||||
|
struct Register
|
||||||
|
{
|
||||||
|
Register(QChar p_name, const QString &p_value)
|
||||||
|
: m_name(p_name), m_value(p_value), m_append(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Register(QChar p_name)
|
||||||
|
: m_name(p_name), m_append(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Register()
|
||||||
|
: m_append(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register a-z.
|
||||||
|
bool isNamedRegister() const
|
||||||
|
{
|
||||||
|
char ch = m_name.toLatin1();
|
||||||
|
return ch >= 'a' && ch <= 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUnnamedRegister() const
|
||||||
|
{
|
||||||
|
return m_name == c_unnamedRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBlackHoleRegister() const
|
||||||
|
{
|
||||||
|
return m_name == c_blackHoleRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSelectionRegister() const
|
||||||
|
{
|
||||||
|
return m_name == c_selectionRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBlock() const
|
||||||
|
{
|
||||||
|
return m_value.endsWith('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// @p_value is the content to update.
|
||||||
|
// If @p_value ends with \n, then it is a block.
|
||||||
|
// When @p_value is a block, we need to add \n at the end if necessary.
|
||||||
|
// If @m_append is true and @p_value is a block, we need to add \n between
|
||||||
|
// them if necessary.
|
||||||
|
void update(const QString &p_value);
|
||||||
|
|
||||||
|
// Read the value of this register.
|
||||||
|
const QString &read();
|
||||||
|
|
||||||
|
QChar m_name;
|
||||||
|
QString m_value;
|
||||||
|
|
||||||
|
// This is not info of Register itself, but a hint to the handling logics
|
||||||
|
// whether we need to append the content to this register.
|
||||||
|
// Only valid for a-z registers.
|
||||||
|
bool m_append;
|
||||||
|
};
|
||||||
|
|
||||||
// Handle key press event.
|
// Handle key press event.
|
||||||
// Returns true if the event is consumed and need no more handling.
|
// Returns true if the event is consumed and need no more handling.
|
||||||
bool handleKeyPressEvent(QKeyEvent *p_event);
|
bool handleKeyPressEvent(QKeyEvent *p_event);
|
||||||
@ -38,6 +101,18 @@ public:
|
|||||||
// Set current mode.
|
// Set current mode.
|
||||||
void setMode(VimMode p_mode);
|
void setMode(VimMode p_mode);
|
||||||
|
|
||||||
|
// Set current register.
|
||||||
|
void setRegister(QChar p_reg);
|
||||||
|
|
||||||
|
// Get m_registers.
|
||||||
|
const QMap<QChar, Register> &getRegisters() const;
|
||||||
|
|
||||||
|
QChar getCurrentRegisterName() const;
|
||||||
|
|
||||||
|
// Get pending keys.
|
||||||
|
// Turn m_pendingKeys to a string.
|
||||||
|
QString getPendingKeys() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Emit when current mode has been changed.
|
// Emit when current mode has been changed.
|
||||||
void modeChanged(VimMode p_mode);
|
void modeChanged(VimMode p_mode);
|
||||||
@ -45,6 +120,9 @@ signals:
|
|||||||
// Emit when VVim want to display some messages.
|
// Emit when VVim want to display some messages.
|
||||||
void vimMessage(const QString &p_msg);
|
void vimMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Emit when current status updated.
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// When user use mouse to select texts in Normal mode, we should change to
|
// When user use mouse to select texts in Normal mode, we should change to
|
||||||
// Visual mode.
|
// Visual mode.
|
||||||
@ -265,69 +343,6 @@ private:
|
|||||||
Key m_key;
|
Key m_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Register
|
|
||||||
{
|
|
||||||
Register(QChar p_name, const QString &p_value)
|
|
||||||
: m_name(p_name), m_value(p_value), m_append(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Register(QChar p_name)
|
|
||||||
: m_name(p_name), m_append(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Register()
|
|
||||||
: m_append(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register a-z.
|
|
||||||
bool isNamedRegister() const
|
|
||||||
{
|
|
||||||
char ch = m_name.toLatin1();
|
|
||||||
return ch >= 'a' && ch <= 'z';
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUnnamedRegister() const
|
|
||||||
{
|
|
||||||
return m_name == c_unnamedRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBlackHoleRegister() const
|
|
||||||
{
|
|
||||||
return m_name == c_blackHoleRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSelectionRegister() const
|
|
||||||
{
|
|
||||||
return m_name == c_selectionRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBlock() const
|
|
||||||
{
|
|
||||||
return m_value.endsWith('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
// @p_value is the content to update.
|
|
||||||
// If @p_value ends with \n, then it is a block.
|
|
||||||
// When @p_value is a block, we need to add \n at the end if necessary.
|
|
||||||
// If @m_append is true and @p_value is a block, we need to add \n between
|
|
||||||
// them if necessary.
|
|
||||||
void update(const QString &p_value);
|
|
||||||
|
|
||||||
// Read the value of this register.
|
|
||||||
const QString &read();
|
|
||||||
|
|
||||||
QChar m_name;
|
|
||||||
QString m_value;
|
|
||||||
|
|
||||||
// This is not info of Register itself, but a hint to the handling logics
|
|
||||||
// whether we need to append the content to this register.
|
|
||||||
// Only valid for a-z registers.
|
|
||||||
bool m_append;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Reset all key state info.
|
// Reset all key state info.
|
||||||
void resetState();
|
void resetState();
|
||||||
|
|
||||||
@ -468,10 +483,13 @@ private:
|
|||||||
QList<Key> m_keys;
|
QList<Key> m_keys;
|
||||||
QList<Token> m_tokens;
|
QList<Token> m_tokens;
|
||||||
|
|
||||||
|
// Keys for status indication.
|
||||||
|
QList<Key> m_pendingKeys;
|
||||||
|
|
||||||
// Whether reset the position in block when moving cursor.
|
// Whether reset the position in block when moving cursor.
|
||||||
bool m_resetPositionInBlock;
|
bool m_resetPositionInBlock;
|
||||||
|
|
||||||
QHash<QChar, Register> m_registers;
|
QMap<QChar, Register> m_registers;
|
||||||
|
|
||||||
// Currently used register.
|
// Currently used register.
|
||||||
QChar m_regName;
|
QChar m_regName;
|
||||||
|
98
src/vbuttonwithwidget.cpp
Normal file
98
src/vbuttonwithwidget.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "vbuttonwithwidget.h"
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QRect>
|
||||||
|
|
||||||
|
VButtonWithWidget::VButtonWithWidget(QWidget *p_parent)
|
||||||
|
: QPushButton(p_parent), m_popupWidget(NULL)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
VButtonWithWidget::VButtonWithWidget(const QString &p_text, QWidget *p_parent)
|
||||||
|
: QPushButton(p_text, p_parent), m_popupWidget(NULL)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
VButtonWithWidget::VButtonWithWidget(const QIcon &p_icon,
|
||||||
|
const QString &p_text,
|
||||||
|
QWidget *p_parent)
|
||||||
|
: QPushButton(p_icon, p_text, p_parent), m_popupWidget(NULL)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
VButtonWithWidget::~VButtonWithWidget()
|
||||||
|
{
|
||||||
|
if (m_popupWidget) {
|
||||||
|
delete m_popupWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VButtonWithWidget::init()
|
||||||
|
{
|
||||||
|
connect(this, &QPushButton::clicked,
|
||||||
|
this, &VButtonWithWidget::showPopupWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VButtonWithWidget::setPopupWidget(QWidget *p_widget)
|
||||||
|
{
|
||||||
|
if (m_popupWidget) {
|
||||||
|
delete m_popupWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_popupWidget = p_widget;
|
||||||
|
if (m_popupWidget) {
|
||||||
|
m_popupWidget->hide();
|
||||||
|
m_popupWidget->setParent(NULL);
|
||||||
|
|
||||||
|
Qt::WindowFlags flags = Qt::Popup;
|
||||||
|
m_popupWidget->setWindowFlags(flags);
|
||||||
|
m_popupWidget->setWindowModality(Qt::NonModal);
|
||||||
|
|
||||||
|
// Let popup widget to hide itself if focus lost.
|
||||||
|
m_popupWidget->installEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *VButtonWithWidget::getPopupWidget() const
|
||||||
|
{
|
||||||
|
return m_popupWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VButtonWithWidget::showPopupWidget()
|
||||||
|
{
|
||||||
|
if (m_popupWidget->isVisible()) {
|
||||||
|
m_popupWidget->hide();
|
||||||
|
} else {
|
||||||
|
emit popupWidgetAboutToShow(m_popupWidget);
|
||||||
|
|
||||||
|
// Calculate the position of the popup widget.
|
||||||
|
QPoint btnPos = mapToGlobal(QPoint(0, 0));
|
||||||
|
int btnWidth = width();
|
||||||
|
|
||||||
|
int popupWidth = btnWidth * 10;
|
||||||
|
int popupHeight = height() * 10;
|
||||||
|
int popupX = btnPos.x() + btnWidth - popupWidth;
|
||||||
|
int popupY = btnPos.y() - popupHeight - 10;
|
||||||
|
|
||||||
|
m_popupWidget->setGeometry(popupX, popupY, popupWidth, popupHeight);
|
||||||
|
m_popupWidget->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VButtonWithWidget::eventFilter(QObject *p_obj, QEvent *p_event)
|
||||||
|
{
|
||||||
|
if (p_event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
QMouseEvent *eve = dynamic_cast<QMouseEvent *>(p_event);
|
||||||
|
QPoint clickPos = eve->pos();
|
||||||
|
const QRect &rect = m_popupWidget->rect();
|
||||||
|
if (!rect.contains(clickPos)) {
|
||||||
|
m_popupWidget->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QPushButton::eventFilter(p_obj, p_event);
|
||||||
|
}
|
42
src/vbuttonwithwidget.h
Normal file
42
src/vbuttonwithwidget.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef VBUTTONWITHWIDGET_H
|
||||||
|
#define VBUTTONWITHWIDGET_H
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QString>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
// A QPushButton with popup widget.
|
||||||
|
class VButtonWithWidget : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VButtonWithWidget(QWidget *p_parent = Q_NULLPTR);
|
||||||
|
VButtonWithWidget(const QString &p_text, QWidget *p_parent = Q_NULLPTR);
|
||||||
|
VButtonWithWidget(const QIcon &p_icon,
|
||||||
|
const QString &p_text,
|
||||||
|
QWidget *p_parent = Q_NULLPTR);
|
||||||
|
~VButtonWithWidget();
|
||||||
|
|
||||||
|
// Set the widget which will transfer the ownership to VButtonWithWidget.
|
||||||
|
void setPopupWidget(QWidget *p_widget);
|
||||||
|
|
||||||
|
QWidget *getPopupWidget() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// Emit when popup widget is about to show.
|
||||||
|
void popupWidgetAboutToShow(QWidget *p_widget);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// Show the popup widget.
|
||||||
|
void showPopupWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
QWidget *m_popupWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VBUTTONWITHWIDGET_H
|
@ -781,3 +781,12 @@ void VEdit::mouseMoveEvent(QMouseEvent *p_event)
|
|||||||
|
|
||||||
QTextEdit::mouseMoveEvent(p_event);
|
QTextEdit::mouseMoveEvent(p_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEdit::requestUpdateVimStatus()
|
||||||
|
{
|
||||||
|
if (m_editOps) {
|
||||||
|
m_editOps->requestUpdateVimStatus();
|
||||||
|
} else {
|
||||||
|
emit vimStatusUpdated(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
class VEditOperations;
|
class VEditOperations;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
class VVim;
|
||||||
|
|
||||||
enum class SelectionId {
|
enum class SelectionId {
|
||||||
CurrentLine = 0,
|
CurrentLine = 0,
|
||||||
@ -81,6 +82,9 @@ public:
|
|||||||
|
|
||||||
VEditConfig &getConfig();
|
VEditConfig &getConfig();
|
||||||
|
|
||||||
|
// Request to update Vim status.
|
||||||
|
void requestUpdateVimStatus();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void saveAndRead();
|
void saveAndRead();
|
||||||
void discardAndRead();
|
void discardAndRead();
|
||||||
@ -92,6 +96,9 @@ signals:
|
|||||||
// Emit when want to show message in status bar.
|
// Emit when want to show message in status bar.
|
||||||
void statusMessage(const QString &p_msg);
|
void statusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Emit when Vim status updated.
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void highlightCurrentLine();
|
virtual void highlightCurrentLine();
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ void VEditArea::insertSplitWindow(int idx)
|
|||||||
this, &VEditArea::handleCurHeaderChanged);
|
this, &VEditArea::handleCurHeaderChanged);
|
||||||
connect(win, &VEditWindow::statusMessage,
|
connect(win, &VEditWindow::statusMessage,
|
||||||
this, &VEditArea::handleWindowStatusMessage);
|
this, &VEditArea::handleWindowStatusMessage);
|
||||||
|
connect(win, &VEditWindow::vimStatusUpdated,
|
||||||
|
this, &VEditArea::handleWindowVimStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditArea::handleEditWindowStatusChanged(const VFile *p_file,
|
void VEditArea::handleEditWindowStatusChanged(const VFile *p_file,
|
||||||
@ -99,6 +101,13 @@ void VEditArea::handleWindowStatusMessage(const QString &p_msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditArea::handleWindowVimStatusUpdated(const VVim *p_vim)
|
||||||
|
{
|
||||||
|
if (splitter->widget(curWindowIndex) == sender()) {
|
||||||
|
emit vimStatusUpdated(p_vim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VEditArea::removeSplitWindow(VEditWindow *win)
|
void VEditArea::removeSplitWindow(VEditWindow *win)
|
||||||
{
|
{
|
||||||
if (!win) {
|
if (!win) {
|
||||||
|
@ -20,6 +20,7 @@ class VFile;
|
|||||||
class VDirectory;
|
class VDirectory;
|
||||||
class VFindReplaceDialog;
|
class VFindReplaceDialog;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
class VVim;
|
||||||
|
|
||||||
class VEditArea : public QWidget, public VNavigationMode
|
class VEditArea : public QWidget, public VNavigationMode
|
||||||
{
|
{
|
||||||
@ -66,6 +67,9 @@ signals:
|
|||||||
// Emit when want to show message in status bar.
|
// Emit when want to show message in status bar.
|
||||||
void statusMessage(const QString &p_msg);
|
void statusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Emit when Vim status updated.
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -101,6 +105,9 @@ private slots:
|
|||||||
// Handle the statusMessage signal of VEditWindow.
|
// Handle the statusMessage signal of VEditWindow.
|
||||||
void handleWindowStatusMessage(const QString &p_msg);
|
void handleWindowStatusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Handle the vimStatusUpdated signal of VEditWindow.
|
||||||
|
void handleWindowVimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
|
QVector<QPair<int, int> > findTabsByFile(const VFile *p_file);
|
||||||
|
@ -20,6 +20,8 @@ VEditOperations::VEditOperations(VEdit *p_editor, VFile *p_file)
|
|||||||
this, &VEditOperations::handleVimModeChanged);
|
this, &VEditOperations::handleVimModeChanged);
|
||||||
connect(m_vim, &VVim::vimMessage,
|
connect(m_vim, &VVim::vimMessage,
|
||||||
this, &VEditOperations::statusMessage);
|
this, &VEditOperations::statusMessage);
|
||||||
|
connect(m_vim, &VVim::vimStatusUpdated,
|
||||||
|
this, &VEditOperations::vimStatusUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditOperations::insertTextAtCurPos(const QString &p_text)
|
void VEditOperations::insertTextAtCurPos(const QString &p_text)
|
||||||
@ -80,3 +82,12 @@ void VEditOperations::handleVimModeChanged(VimMode p_mode)
|
|||||||
|
|
||||||
updateCursorLineBg();
|
updateCursorLineBg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditOperations::requestUpdateVimStatus()
|
||||||
|
{
|
||||||
|
if (m_editConfig->m_enableVimMode) {
|
||||||
|
emit vimStatusUpdated(m_vim);
|
||||||
|
} else {
|
||||||
|
emit vimStatusUpdated(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,10 +27,16 @@ public:
|
|||||||
// processed.
|
// processed.
|
||||||
virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0;
|
virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0;
|
||||||
|
|
||||||
|
// Request to propogate Vim status.
|
||||||
|
void requestUpdateVimStatus();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Want to display a template message in status bar.
|
// Want to display a template message in status bar.
|
||||||
void statusMessage(const QString &p_msg);
|
void statusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Propogate Vim status.
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
// Handle the update of VEditConfig of the editor.
|
// Handle the update of VEditConfig of the editor.
|
||||||
virtual void handleEditConfigUpdated();
|
virtual void handleEditConfigUpdated();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include "vtoc.h"
|
#include "vtoc.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
|
#include "utils/vvim.h"
|
||||||
|
|
||||||
class VEditArea;
|
class VEditArea;
|
||||||
|
|
||||||
@ -63,6 +64,9 @@ public:
|
|||||||
|
|
||||||
virtual void clearSearchedWordHighlight() = 0;
|
virtual void clearSearchedWordHighlight() = 0;
|
||||||
|
|
||||||
|
// Request current tab to propogate its status about Vim.
|
||||||
|
virtual void requestUpdateVimStatus() = 0;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode
|
// Enter edit mode
|
||||||
virtual void editFile() = 0;
|
virtual void editFile() = 0;
|
||||||
@ -96,6 +100,8 @@ signals:
|
|||||||
// Emit when want to show message in status bar.
|
// Emit when want to show message in status bar.
|
||||||
void statusMessage(const QString &p_msg);
|
void statusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Called when app focus changed.
|
// Called when app focus changed.
|
||||||
void handleFocusChanged(QWidget *p_old, QWidget *p_now);
|
void handleFocusChanged(QWidget *p_old, QWidget *p_now);
|
||||||
|
@ -270,6 +270,8 @@ int VEditWindow::openFileInTab(VFile *p_file, OpenFileMode p_mode)
|
|||||||
this, &VEditWindow::handleTabStatusChanged);
|
this, &VEditWindow::handleTabStatusChanged);
|
||||||
connect(editor, &VEditTab::statusMessage,
|
connect(editor, &VEditTab::statusMessage,
|
||||||
this, &VEditWindow::handleTabStatusMessage);
|
this, &VEditWindow::handleTabStatusMessage);
|
||||||
|
connect(editor, &VEditTab::vimStatusUpdated,
|
||||||
|
this, &VEditWindow::handleTabVimStatusUpdated);
|
||||||
|
|
||||||
int idx = appendEditTab(p_file, editor);
|
int idx = appendEditTab(p_file, editor);
|
||||||
return idx;
|
return idx;
|
||||||
@ -586,6 +588,14 @@ void VEditWindow::handleTabStatusMessage(const QString &p_msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditWindow::handleTabVimStatusUpdated(const VVim *p_vim)
|
||||||
|
{
|
||||||
|
int idx = indexOf(dynamic_cast<QWidget *>(sender()));
|
||||||
|
if (idx == currentIndex()) {
|
||||||
|
emit vimStatusUpdated(p_vim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VEditWindow::updateFileInfo(const VFile *p_file)
|
void VEditWindow::updateFileInfo(const VFile *p_file)
|
||||||
{
|
{
|
||||||
if (!p_file) {
|
if (!p_file) {
|
||||||
|
@ -71,6 +71,9 @@ signals:
|
|||||||
// Emit when want to show message in status bar.
|
// Emit when want to show message in status bar.
|
||||||
void statusMessage(const QString &p_msg);
|
void statusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Emit when Vim mode status changed.
|
||||||
|
void vimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
bool handleTabCloseRequest(int index);
|
bool handleTabCloseRequest(int index);
|
||||||
void splitWindow();
|
void splitWindow();
|
||||||
@ -91,6 +94,9 @@ private slots:
|
|||||||
// Handle the statusMessage signal of VEditTab.
|
// Handle the statusMessage signal of VEditTab.
|
||||||
void handleTabStatusMessage(const QString &p_msg);
|
void handleTabStatusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Handle the vimStatusUpdated() signal of VEditTab.
|
||||||
|
void handleTabVimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initTabActions();
|
void initTabActions();
|
||||||
void setupCornerWidget();
|
void setupCornerWidget();
|
||||||
|
@ -41,6 +41,9 @@ void VHtmlTab::setupUI()
|
|||||||
this, &VHtmlTab::editFile);
|
this, &VHtmlTab::editFile);
|
||||||
connect(m_editor, &VEdit::statusMessage,
|
connect(m_editor, &VEdit::statusMessage,
|
||||||
this, &VEditTab::statusMessage);
|
this, &VEditTab::statusMessage);
|
||||||
|
connect(m_editor, &VEdit::vimStatusUpdated,
|
||||||
|
this, &VEditTab::vimStatusUpdated);
|
||||||
|
|
||||||
m_editor->reloadFile();
|
m_editor->reloadFile();
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
@ -250,3 +253,8 @@ void VHtmlTab::focusChild()
|
|||||||
{
|
{
|
||||||
m_editor->setFocus();
|
m_editor->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VHtmlTab::requestUpdateVimStatus()
|
||||||
|
{
|
||||||
|
m_editor->requestUpdateVimStatus();
|
||||||
|
}
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
|
|
||||||
void clearSearchedWordHighlight() Q_DECL_OVERRIDE;
|
void clearSearchedWordHighlight() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "vwebview.h"
|
#include "vwebview.h"
|
||||||
#include "vexporter.h"
|
#include "vexporter.h"
|
||||||
#include "vmdtab.h"
|
#include "vmdtab.h"
|
||||||
|
#include "vvimindicator.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
@ -111,12 +112,17 @@ void VMainWindow::setupUI()
|
|||||||
this, &VMainWindow::handleCurTabStatusChanged);
|
this, &VMainWindow::handleCurTabStatusChanged);
|
||||||
connect(editArea, &VEditArea::statusMessage,
|
connect(editArea, &VEditArea::statusMessage,
|
||||||
this, &VMainWindow::showStatusMessage);
|
this, &VMainWindow::showStatusMessage);
|
||||||
|
connect(editArea, &VEditArea::vimStatusUpdated,
|
||||||
|
this, &VMainWindow::handleVimStatusUpdated);
|
||||||
connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged,
|
connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged,
|
||||||
this, &VMainWindow::handleFindDialogTextChanged);
|
this, &VMainWindow::handleFindDialogTextChanged);
|
||||||
|
|
||||||
setCentralWidget(mainSplitter);
|
setCentralWidget(mainSplitter);
|
||||||
|
|
||||||
// Create and show the status bar
|
// Create and show the status bar
|
||||||
statusBar();
|
m_vimIndicator = new VVimIndicator(this);
|
||||||
|
m_vimIndicator->hide();
|
||||||
|
statusBar()->addPermanentWidget(m_vimIndicator);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *VMainWindow::setupDirectoryPanel()
|
QWidget *VMainWindow::setupDirectoryPanel()
|
||||||
@ -1121,9 +1127,12 @@ void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab
|
|||||||
title.append('#');
|
title.append('#');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateWindowTitle(title);
|
updateWindowTitle(title);
|
||||||
m_curFile = const_cast<VFile *>(p_file);
|
m_curFile = const_cast<VFile *>(p_file);
|
||||||
m_curTab = const_cast<VEditTab *>(p_editTab);
|
m_curTab = const_cast<VEditTab *>(p_editTab);
|
||||||
|
|
||||||
|
updateStatusInfo(p_editMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::onePanelView()
|
void VMainWindow::onePanelView()
|
||||||
@ -1496,3 +1505,22 @@ void VMainWindow::showStatusMessage(const QString &p_msg)
|
|||||||
const int timeout = 3000;
|
const int timeout = 3000;
|
||||||
statusBar()->showMessage(p_msg, timeout);
|
statusBar()->showMessage(p_msg, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMainWindow::updateStatusInfo(bool p_editMode)
|
||||||
|
{
|
||||||
|
if (!p_editMode || !m_curTab) {
|
||||||
|
m_vimIndicator->hide();
|
||||||
|
} else {
|
||||||
|
m_curTab->requestUpdateVimStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMainWindow::handleVimStatusUpdated(const VVim *p_vim)
|
||||||
|
{
|
||||||
|
if (!p_vim || !m_curTab) {
|
||||||
|
m_vimIndicator->hide();
|
||||||
|
} else {
|
||||||
|
m_vimIndicator->update(p_vim);
|
||||||
|
m_vimIndicator->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -29,6 +29,7 @@ class VNotebookSelector;
|
|||||||
class VAvatar;
|
class VAvatar;
|
||||||
class VFindReplaceDialog;
|
class VFindReplaceDialog;
|
||||||
class VCaptain;
|
class VCaptain;
|
||||||
|
class VVimIndicator;
|
||||||
|
|
||||||
class VMainWindow : public QMainWindow
|
class VMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
@ -88,6 +89,9 @@ private slots:
|
|||||||
// Show a temporary message in status bar.
|
// Show a temporary message in status bar.
|
||||||
void showStatusMessage(const QString &p_msg);
|
void showStatusMessage(const QString &p_msg);
|
||||||
|
|
||||||
|
// Handle Vim status updated.
|
||||||
|
void handleVimStatusUpdated(const VVim *p_vim);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
||||||
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
||||||
@ -127,6 +131,9 @@ private:
|
|||||||
void toggleOnePanelView();
|
void toggleOnePanelView();
|
||||||
void closeCurrentFile();
|
void closeCurrentFile();
|
||||||
|
|
||||||
|
// Update status bar information according to m_curTab and m_curFile.
|
||||||
|
void updateStatusInfo(bool p_editMode);
|
||||||
|
|
||||||
// Wrapper to create a QAction.
|
// Wrapper to create a QAction.
|
||||||
QAction *newAction(const QIcon &p_icon,
|
QAction *newAction(const QIcon &p_icon,
|
||||||
const QString &p_text,
|
const QString &p_text,
|
||||||
@ -150,6 +157,7 @@ private:
|
|||||||
VOutline *outline;
|
VOutline *outline;
|
||||||
VAvatar *m_avatar;
|
VAvatar *m_avatar;
|
||||||
VFindReplaceDialog *m_findReplaceDialog;
|
VFindReplaceDialog *m_findReplaceDialog;
|
||||||
|
VVimIndicator *m_vimIndicator;
|
||||||
|
|
||||||
// Whether it is one panel or two panles.
|
// Whether it is one panel or two panles.
|
||||||
bool m_onePanel;
|
bool m_onePanel;
|
||||||
|
@ -53,6 +53,8 @@ VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type,
|
|||||||
|
|
||||||
connect(m_editOps, &VEditOperations::statusMessage,
|
connect(m_editOps, &VEditOperations::statusMessage,
|
||||||
this, &VEdit::statusMessage);
|
this, &VEdit::statusMessage);
|
||||||
|
connect(m_editOps, &VEditOperations::vimStatusUpdated,
|
||||||
|
this, &VEdit::vimStatusUpdated);
|
||||||
|
|
||||||
connect(this, &VMdEdit::cursorPositionChanged,
|
connect(this, &VMdEdit::cursorPositionChanged,
|
||||||
this, &VMdEdit::updateCurHeader);
|
this, &VMdEdit::updateCurHeader);
|
||||||
|
@ -60,6 +60,8 @@ void VMdTab::setupUI()
|
|||||||
this, &VMdTab::discardAndRead);
|
this, &VMdTab::discardAndRead);
|
||||||
connect(m_editor, &VEdit::statusMessage,
|
connect(m_editor, &VEdit::statusMessage,
|
||||||
this, &VEditTab::statusMessage);
|
this, &VEditTab::statusMessage);
|
||||||
|
connect(m_editor, &VEdit::vimStatusUpdated,
|
||||||
|
this, &VEditTab::vimStatusUpdated);
|
||||||
|
|
||||||
m_editor->reloadFile();
|
m_editor->reloadFile();
|
||||||
m_stacks->addWidget(m_editor);
|
m_stacks->addWidget(m_editor);
|
||||||
@ -643,3 +645,12 @@ void VMdTab::focusChild()
|
|||||||
{
|
{
|
||||||
m_stacks->currentWidget()->setFocus();
|
m_stacks->currentWidget()->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMdTab::requestUpdateVimStatus()
|
||||||
|
{
|
||||||
|
if (m_editor) {
|
||||||
|
m_editor->requestUpdateVimStatus();
|
||||||
|
} else {
|
||||||
|
emit vimStatusUpdated(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
|
|
||||||
MarkdownConverterType getMarkdownConverterType() const;
|
MarkdownConverterType getMarkdownConverterType() const;
|
||||||
|
|
||||||
|
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -66,7 +66,6 @@
|
|||||||
<file>resources/icons/dir_item.svg</file>
|
<file>resources/icons/dir_item.svg</file>
|
||||||
<file>resources/icons/notebook_item.svg</file>
|
<file>resources/icons/notebook_item.svg</file>
|
||||||
<file>resources/icons/arrow_dropdown.svg</file>
|
<file>resources/icons/arrow_dropdown.svg</file>
|
||||||
<file>resources/icons/current_tab.svg</file>
|
|
||||||
<file>resources/icons/vnote.png</file>
|
<file>resources/icons/vnote.png</file>
|
||||||
<file>resources/icons/insert_image.svg</file>
|
<file>resources/icons/insert_image.svg</file>
|
||||||
<file>resources/icons/import_note.svg</file>
|
<file>resources/icons/import_note.svg</file>
|
||||||
@ -108,5 +107,6 @@
|
|||||||
<file>utils/markdown-it/markdown-it-sub.min.js</file>
|
<file>utils/markdown-it/markdown-it-sub.min.js</file>
|
||||||
<file>utils/markdown-it/markdown-it-sup.min.js</file>
|
<file>utils/markdown-it/markdown-it-sup.min.js</file>
|
||||||
<file>utils/markdown-it/markdown-it-footnote.min.js</file>
|
<file>utils/markdown-it/markdown-it-footnote.min.js</file>
|
||||||
|
<file>resources/icons/arrow_dropup.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
174
src/vvimindicator.cpp
Normal file
174
src/vvimindicator.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#include "vvimindicator.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
#include "vbuttonwithwidget.h"
|
||||||
|
|
||||||
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
|
VVimIndicator::VVimIndicator(QWidget *parent)
|
||||||
|
: QWidget(parent), m_vim(NULL)
|
||||||
|
{
|
||||||
|
setupUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVimIndicator::setupUI()
|
||||||
|
{
|
||||||
|
m_modeLabel = new QLabel(this);
|
||||||
|
|
||||||
|
m_regBtn = new VButtonWithWidget(QIcon(":/resources/icons/arrow_dropup.svg"),
|
||||||
|
"\"",
|
||||||
|
this);
|
||||||
|
m_regBtn->setProperty("StatusBtn", true);
|
||||||
|
m_regBtn->setFocusPolicy(Qt::NoFocus);
|
||||||
|
QTreeWidget *regTree = new QTreeWidget(this);
|
||||||
|
regTree->setColumnCount(2);
|
||||||
|
regTree->header()->setStretchLastSection(true);
|
||||||
|
regTree->header()->setProperty("RegisterTree", true);
|
||||||
|
QStringList headers;
|
||||||
|
headers << tr("Register") << tr("Value");
|
||||||
|
regTree->setHeaderLabels(headers);
|
||||||
|
m_regBtn->setPopupWidget(regTree);
|
||||||
|
connect(m_regBtn, &VButtonWithWidget::popupWidgetAboutToShow,
|
||||||
|
this, &VVimIndicator::updateRegistersTree);
|
||||||
|
|
||||||
|
m_keyLabel = new QLabel(this);
|
||||||
|
QFontMetrics metric(font());
|
||||||
|
m_keyLabel->setMinimumWidth(metric.width('A') * 5);
|
||||||
|
|
||||||
|
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||||
|
mainLayout->addWidget(m_modeLabel);
|
||||||
|
mainLayout->addWidget(m_regBtn);
|
||||||
|
mainLayout->addWidget(m_keyLabel);
|
||||||
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VVimIndicator::modeToString(VimMode p_mode) const
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
|
||||||
|
switch (p_mode) {
|
||||||
|
case VimMode::Normal:
|
||||||
|
str = tr("Normal");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Insert:
|
||||||
|
str = tr("Insert");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Visual:
|
||||||
|
str = tr("Visual");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::VisualLine:
|
||||||
|
str = tr("VisualLine");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Replace:
|
||||||
|
str = tr("Replace");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
str = tr("Unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString modeBackgroundColor(VimMode p_mode)
|
||||||
|
{
|
||||||
|
QString color;
|
||||||
|
|
||||||
|
switch (p_mode) {
|
||||||
|
case VimMode::Normal:
|
||||||
|
color = vconfig.getEditorVimNormalBg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Insert:
|
||||||
|
color = vconfig.getEditorVimInsertBg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Visual:
|
||||||
|
color = vconfig.getEditorVimVisualBg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::VisualLine:
|
||||||
|
color = vconfig.getEditorVimVisualBg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VimMode::Replace:
|
||||||
|
color = vconfig.getEditorVimReplaceBg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
color = "red";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fillTreeItemsWithRegisters(QTreeWidget *p_tree,
|
||||||
|
const QMap<QChar, VVim::Register> &p_regs)
|
||||||
|
{
|
||||||
|
p_tree->clear();
|
||||||
|
for (auto const ® : p_regs) {
|
||||||
|
if (reg.m_value.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList itemStr;
|
||||||
|
itemStr << reg.m_name << reg.m_value;
|
||||||
|
QTreeWidgetItem *item = new QTreeWidgetItem(p_tree, itemStr);
|
||||||
|
item->setFlags(item->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_tree->resizeColumnToContents(0);
|
||||||
|
p_tree->resizeColumnToContents(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVimIndicator::update(const VVim *p_vim)
|
||||||
|
{
|
||||||
|
if (!p_vim) {
|
||||||
|
m_vim = p_vim;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vim = p_vim;
|
||||||
|
|
||||||
|
VimMode mode = p_vim->getMode();
|
||||||
|
QChar curRegName = p_vim->getCurrentRegisterName();
|
||||||
|
|
||||||
|
QString style = QString("QLabel { padding: 0px 2px 0px 2px; font: bold; background-color: %1; }")
|
||||||
|
.arg(modeBackgroundColor(mode));
|
||||||
|
m_modeLabel->setStyleSheet(style);
|
||||||
|
m_modeLabel->setText(modeToString(mode));
|
||||||
|
|
||||||
|
m_regBtn->setText(curRegName);
|
||||||
|
|
||||||
|
QString keyText = QString("<span style=\"font-weight:bold;\">%1</span>")
|
||||||
|
.arg(p_vim->getPendingKeys());
|
||||||
|
m_keyLabel->setText(keyText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VVimIndicator::updateRegistersTree(QWidget *p_widget)
|
||||||
|
{
|
||||||
|
QTreeWidget *regTree = dynamic_cast<QTreeWidget *>(p_widget);
|
||||||
|
if (!m_vim) {
|
||||||
|
regTree->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QMap<QChar, VVim::Register> ®s = m_vim->getRegisters();
|
||||||
|
fillTreeItemsWithRegisters(regTree, regs);
|
||||||
|
}
|
40
src/vvimindicator.h
Normal file
40
src/vvimindicator.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef VVIMINDICATOR_H
|
||||||
|
#define VVIMINDICATOR_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "utils/vvim.h"
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class VButtonWithWidget;
|
||||||
|
|
||||||
|
class VVimIndicator : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VVimIndicator(QWidget *parent = 0);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void update(const VVim *p_vim);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateRegistersTree(QWidget *p_widget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupUI();
|
||||||
|
|
||||||
|
QString modeToString(VimMode p_mode) const;
|
||||||
|
|
||||||
|
// Indicate the mode.
|
||||||
|
QLabel *m_modeLabel;
|
||||||
|
|
||||||
|
// Indicate the registers.
|
||||||
|
VButtonWithWidget *m_regBtn;
|
||||||
|
|
||||||
|
// Indicate the pending keys.
|
||||||
|
QLabel *m_keyLabel;
|
||||||
|
|
||||||
|
const VVim *m_vim;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VVIMINDICATOR_H
|
Loading…
x
Reference in New Issue
Block a user