mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
add toolbar for text editing
Bold, italic, underline, strikethrough, inline code. Underline and strikethrough are not implemented yet.
This commit is contained in:
parent
b73f30222d
commit
f9f7a365f8
7
src/resources/icons/bold.svg
Normal file
7
src/resources/icons/bold.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="bold" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">B</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 471 B |
7
src/resources/icons/inline_code.svg
Normal file
7
src/resources/icons/inline_code.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text style="cursor: move;" fill="#000000" stroke-width="0" x="-146.756839" y="248.490375" id="svg_4" font-size="24" font-family="serif" text-anchor="middle" xml:space="preserve" font-weight="normal" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " stroke="#000000" font-style="normal">O</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 515 B |
7
src/resources/icons/italic.svg
Normal file
7
src/resources/icons/italic.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text font-style="italic" stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="normal" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">I</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 493 B |
8
src/resources/icons/strikethrough.svg
Normal file
8
src/resources/icons/strikethrough.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text fill="#000000" stroke-width="0" x="-146.756839" y="248.490375" id="svg_4" font-size="24" font-family="serif" text-anchor="middle" xml:space="preserve" font-weight="normal" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " stroke="#000000" font-style="normal">S</text>
|
||||||
|
<rect stroke="#000000" fill="#000000" stroke-width="5" x="94.999999" y="282" width="318.999997" height="21" id="svg_2" stroke-opacity="0"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 635 B |
8
src/resources/icons/underline.svg
Normal file
8
src/resources/icons/underline.svg
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text style="cursor: move;" font-style="normal" stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="normal" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">U</text>
|
||||||
|
<rect stroke="#000000" stroke-opacity="0" id="svg_2" height="21" width="322.000016" y="422" x="91.999999" stroke-width="5" fill="#000000"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 657 B |
@ -4241,8 +4241,8 @@ int VVim::blockCountOfPageStep() const
|
|||||||
void VVim::selectionToVisualMode(bool p_hasText)
|
void VVim::selectionToVisualMode(bool p_hasText)
|
||||||
{
|
{
|
||||||
if (p_hasText && m_mode == VimMode::Normal) {
|
if (p_hasText && m_mode == VimMode::Normal) {
|
||||||
// Enter visual mode.
|
// Enter visual mode without clearing the selection.
|
||||||
setMode(VimMode::Visual);
|
setMode(VimMode::Visual, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,4 +34,11 @@ namespace DirConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const QString c_emptyHeaderName = "[EMPTY]";
|
static const QString c_emptyHeaderName = "[EMPTY]";
|
||||||
|
|
||||||
|
enum class TextDecoration { None,
|
||||||
|
Bold,
|
||||||
|
Italic,
|
||||||
|
Underline,
|
||||||
|
Strikethrough,
|
||||||
|
InlineCode };
|
||||||
#endif
|
#endif
|
||||||
|
@ -826,3 +826,10 @@ void VEdit::setInputMethodEnabled(bool p_enabled)
|
|||||||
im->update(Qt::ImEnabled);
|
im->update(Qt::ImEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEdit::decorateText(TextDecoration p_decoration)
|
||||||
|
{
|
||||||
|
if (m_editOps) {
|
||||||
|
m_editOps->decorateText(p_decoration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -92,6 +92,9 @@ public:
|
|||||||
|
|
||||||
void setInputMethodEnabled(bool p_enabled);
|
void setInputMethodEnabled(bool p_enabled);
|
||||||
|
|
||||||
|
// Insert decoration markers or decorate selected text.
|
||||||
|
void decorateText(TextDecoration p_decoration);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Request VEditTab to save and exit edit mode.
|
// Request VEditTab to save and exit edit mode.
|
||||||
void saveAndRead();
|
void saveAndRead();
|
||||||
|
@ -30,6 +30,9 @@ public:
|
|||||||
// Request to propogate Vim status.
|
// Request to propogate Vim status.
|
||||||
void requestUpdateVimStatus();
|
void requestUpdateVimStatus();
|
||||||
|
|
||||||
|
// Insert decoration markers or decorate selected text.
|
||||||
|
virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
|
||||||
|
|
||||||
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);
|
||||||
|
@ -68,6 +68,9 @@ public:
|
|||||||
// Request current tab to propogate its status about Vim.
|
// Request current tab to propogate its status about Vim.
|
||||||
virtual void requestUpdateVimStatus() = 0;
|
virtual void requestUpdateVimStatus() = 0;
|
||||||
|
|
||||||
|
// Insert decoration markers or decorate selected text.
|
||||||
|
virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode
|
// Enter edit mode
|
||||||
virtual void editFile() = 0;
|
virtual void editFile() = 0;
|
||||||
|
@ -175,6 +175,7 @@ void VMainWindow::initToolBar()
|
|||||||
{
|
{
|
||||||
initFileToolBar();
|
initFileToolBar();
|
||||||
initViewToolBar();
|
initViewToolBar();
|
||||||
|
initEditToolBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::initViewToolBar()
|
void VMainWindow::initViewToolBar()
|
||||||
@ -210,6 +211,90 @@ void VMainWindow::initViewToolBar()
|
|||||||
viewToolBar->addAction(expandViewAct);
|
viewToolBar->addAction(expandViewAct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setActionsVisible(QWidget *p_widget, bool p_visible)
|
||||||
|
{
|
||||||
|
Q_ASSERT(p_widget);
|
||||||
|
QList<QAction *> actions = p_widget->actions();
|
||||||
|
for (auto const & act : actions) {
|
||||||
|
act->setVisible(p_visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMainWindow::initEditToolBar()
|
||||||
|
{
|
||||||
|
m_editToolBar = addToolBar(tr("Edit Toolbar"));
|
||||||
|
m_editToolBar->setObjectName("EditToolBar");
|
||||||
|
m_editToolBar->setMovable(false);
|
||||||
|
|
||||||
|
m_editToolBar->addSeparator();
|
||||||
|
|
||||||
|
QAction *boldAct = new QAction(QIcon(":/resources/icons/bold.svg"),
|
||||||
|
tr("Bold"), this);
|
||||||
|
boldAct->setStatusTip(tr("Insert bold text or change selected text to bold"));
|
||||||
|
connect(boldAct, &QAction::triggered,
|
||||||
|
this, [this](){
|
||||||
|
if (m_curTab) {
|
||||||
|
m_curTab->decorateText(TextDecoration::Bold);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_editToolBar->addAction(boldAct);
|
||||||
|
|
||||||
|
QAction *italicAct = new QAction(QIcon(":/resources/icons/italic.svg"),
|
||||||
|
tr("Italic"), this);
|
||||||
|
italicAct->setStatusTip(tr("Insert italic text or change selected text to italic"));
|
||||||
|
connect(italicAct, &QAction::triggered,
|
||||||
|
this, [this](){
|
||||||
|
if (m_curTab) {
|
||||||
|
m_curTab->decorateText(TextDecoration::Italic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_editToolBar->addAction(italicAct);
|
||||||
|
|
||||||
|
QAction *underlineAct = new QAction(QIcon(":/resources/icons/underline.svg"),
|
||||||
|
tr("Underline"), this);
|
||||||
|
underlineAct->setStatusTip(tr("Insert underlined text or change selected text to underlined"));
|
||||||
|
connect(underlineAct, &QAction::triggered,
|
||||||
|
this, [this](){
|
||||||
|
if (m_curTab) {
|
||||||
|
m_curTab->decorateText(TextDecoration::Underline);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_editToolBar->addAction(underlineAct);
|
||||||
|
|
||||||
|
QAction *strikethroughAct = new QAction(QIcon(":/resources/icons/strikethrough.svg"),
|
||||||
|
tr("Strikethrough"), this);
|
||||||
|
strikethroughAct->setStatusTip(tr("Insert strikethrough text or change selected text to strikethroughed"));
|
||||||
|
connect(strikethroughAct, &QAction::triggered,
|
||||||
|
this, [this](){
|
||||||
|
if (m_curTab) {
|
||||||
|
m_curTab->decorateText(TextDecoration::Strikethrough);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_editToolBar->addAction(strikethroughAct);
|
||||||
|
|
||||||
|
QAction *inlineCodeAct = new QAction(QIcon(":/resources/icons/inline_code.svg"),
|
||||||
|
tr("Inline Code"), this);
|
||||||
|
inlineCodeAct->setStatusTip(tr("Insert inline-code text or change selected text to inline-coded"));
|
||||||
|
connect(inlineCodeAct, &QAction::triggered,
|
||||||
|
this, [this](){
|
||||||
|
if (m_curTab) {
|
||||||
|
m_curTab->decorateText(TextDecoration::InlineCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_editToolBar->addAction(inlineCodeAct);
|
||||||
|
|
||||||
|
QAction *toggleAct = m_editToolBar->toggleViewAction();
|
||||||
|
toggleAct->setToolTip(tr("Toggle the edit toolbar"));
|
||||||
|
viewMenu->addAction(toggleAct);
|
||||||
|
|
||||||
|
setActionsVisible(m_editToolBar, false);
|
||||||
|
}
|
||||||
|
|
||||||
void VMainWindow::initFileToolBar()
|
void VMainWindow::initFileToolBar()
|
||||||
{
|
{
|
||||||
QToolBar *fileToolBar = addToolBar(tr("Note"));
|
QToolBar *fileToolBar = addToolBar(tr("Note"));
|
||||||
@ -507,6 +592,7 @@ void VMainWindow::initMarkdownMenu()
|
|||||||
void VMainWindow::initViewMenu()
|
void VMainWindow::initViewMenu()
|
||||||
{
|
{
|
||||||
viewMenu = menuBar()->addMenu(tr("&View"));
|
viewMenu = menuBar()->addMenu(tr("&View"));
|
||||||
|
viewMenu->setToolTipsVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::initFileMenu()
|
void VMainWindow::initFileMenu()
|
||||||
@ -795,7 +881,10 @@ void VMainWindow::initDockWindows()
|
|||||||
toolBox->addItem(outline, QIcon(":/resources/icons/outline.svg"), tr("Outline"));
|
toolBox->addItem(outline, QIcon(":/resources/icons/outline.svg"), tr("Outline"));
|
||||||
toolDock->setWidget(toolBox);
|
toolDock->setWidget(toolBox);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, toolDock);
|
addDockWidget(Qt::RightDockWidgetArea, toolDock);
|
||||||
viewMenu->addAction(toolDock->toggleViewAction());
|
|
||||||
|
QAction *toggleAct = toolDock->toggleViewAction();
|
||||||
|
toggleAct->setToolTip(tr("Toggle the tools dock widget"));
|
||||||
|
viewMenu->addAction(toggleAct);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::initAvatar()
|
void VMainWindow::initAvatar()
|
||||||
@ -1154,6 +1243,9 @@ void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
|
|||||||
noteInfoAct->setEnabled(p_file && p_file->getType() == FileType::Normal);
|
noteInfoAct->setEnabled(p_file && p_file->getType() == FileType::Normal);
|
||||||
|
|
||||||
m_insertImageAct->setEnabled(p_file && p_editMode);
|
m_insertImageAct->setEnabled(p_file && p_editMode);
|
||||||
|
|
||||||
|
setActionsVisible(m_editToolBar, p_file && p_editMode);
|
||||||
|
|
||||||
// Find/Replace
|
// Find/Replace
|
||||||
m_findReplaceAct->setEnabled(p_file);
|
m_findReplaceAct->setEnabled(p_file);
|
||||||
m_findNextAct->setEnabled(p_file);
|
m_findNextAct->setEnabled(p_file);
|
||||||
|
@ -108,6 +108,9 @@ private:
|
|||||||
void initFileToolBar();
|
void initFileToolBar();
|
||||||
void initViewToolBar();
|
void initViewToolBar();
|
||||||
|
|
||||||
|
// Init the Edit toolbar.
|
||||||
|
void initEditToolBar();
|
||||||
|
|
||||||
void initMenuBar();
|
void initMenuBar();
|
||||||
void initFileMenu();
|
void initFileMenu();
|
||||||
void initEditMenu();
|
void initEditMenu();
|
||||||
@ -196,6 +199,9 @@ private:
|
|||||||
// Menus
|
// Menus
|
||||||
QMenu *viewMenu;
|
QMenu *viewMenu;
|
||||||
|
|
||||||
|
// Edit Toolbar.
|
||||||
|
QToolBar *m_editToolBar;
|
||||||
|
|
||||||
QVector<QPixmap> predefinedColorPixmaps;
|
QVector<QPixmap> predefinedColorPixmaps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -241,10 +241,12 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
|||||||
|
|
||||||
case Qt::Key_B:
|
case Qt::Key_B:
|
||||||
{
|
{
|
||||||
if (handleKeyB(p_event)) {
|
if (modifiers == Qt::ControlModifier) {
|
||||||
|
decorateBold();
|
||||||
|
p_event->accept();
|
||||||
ret = true;
|
ret = true;
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,19 +261,23 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
|||||||
|
|
||||||
case Qt::Key_I:
|
case Qt::Key_I:
|
||||||
{
|
{
|
||||||
if (handleKeyI(p_event)) {
|
if (modifiers == Qt::ControlModifier) {
|
||||||
|
decorateItalic();
|
||||||
|
p_event->accept();
|
||||||
ret = true;
|
ret = true;
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::Key_O:
|
case Qt::Key_O:
|
||||||
{
|
{
|
||||||
if (handleKeyO(p_event)) {
|
if (modifiers == Qt::ControlModifier) {
|
||||||
|
decorateInlineCode();
|
||||||
|
p_event->accept();
|
||||||
ret = true;
|
ret = true;
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,51 +441,6 @@ bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyB(QKeyEvent *p_event)
|
|
||||||
{
|
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
|
||||||
// Ctrl+B, Bold.
|
|
||||||
QTextCursor cursor = m_editor->textCursor();
|
|
||||||
if (cursor.hasSelection()) {
|
|
||||||
// Insert ** around the selected text.
|
|
||||||
int start = cursor.selectionStart();
|
|
||||||
int end = cursor.selectionEnd();
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
cursor.clearSelection();
|
|
||||||
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("**");
|
|
||||||
cursor.setPosition(end + 2, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("**");
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
} else {
|
|
||||||
// Insert **** and place cursor in the middle.
|
|
||||||
// Or if there are two * after current cursor, just skip them.
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
int pos = cursor.positionInBlock();
|
|
||||||
bool hasStars = false;
|
|
||||||
QString text = cursor.block().text();
|
|
||||||
if (pos <= text.size() - 2) {
|
|
||||||
if (text[pos] == '*' && text[pos + 1] == '*') {
|
|
||||||
hasStars = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasStars) {
|
|
||||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
|
||||||
} else {
|
|
||||||
cursor.insertText("****");
|
|
||||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
|
|
||||||
}
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
p_event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
|
bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
|
||||||
{
|
{
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
if (p_event->modifiers() == Qt::ControlModifier) {
|
||||||
@ -493,95 +454,6 @@ bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyI(QKeyEvent *p_event)
|
|
||||||
{
|
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
|
||||||
// Ctrl+I, Italic.
|
|
||||||
QTextCursor cursor = m_editor->textCursor();
|
|
||||||
if (cursor.hasSelection()) {
|
|
||||||
// Insert * around the selected text.
|
|
||||||
int start = cursor.selectionStart();
|
|
||||||
int end = cursor.selectionEnd();
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
cursor.clearSelection();
|
|
||||||
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("*");
|
|
||||||
cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("*");
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
} else {
|
|
||||||
// Insert ** and place cursor in the middle.
|
|
||||||
// Or if there are one * after current cursor, just skip it.
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
int pos = cursor.positionInBlock();
|
|
||||||
bool hasStar = false;
|
|
||||||
QString text = cursor.block().text();
|
|
||||||
if (pos <= text.size() - 1) {
|
|
||||||
if (text[pos] == '*') {
|
|
||||||
hasStar = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasStar) {
|
|
||||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
|
||||||
} else {
|
|
||||||
cursor.insertText("**");
|
|
||||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
|
||||||
}
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
p_event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyO(QKeyEvent *p_event)
|
|
||||||
{
|
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
|
||||||
// Ctrl+O, inline codeblock.
|
|
||||||
QTextCursor cursor = m_editor->textCursor();
|
|
||||||
if (cursor.hasSelection()) {
|
|
||||||
// Insert ` around the selected text.
|
|
||||||
int start = cursor.selectionStart();
|
|
||||||
int end = cursor.selectionEnd();
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
cursor.clearSelection();
|
|
||||||
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("`");
|
|
||||||
cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
|
|
||||||
cursor.insertText("`");
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
} else {
|
|
||||||
// Insert `` and place cursor in the middle.
|
|
||||||
// Or if there are one ` after current cursor, just skip it.
|
|
||||||
cursor.beginEditBlock();
|
|
||||||
int pos = cursor.positionInBlock();
|
|
||||||
bool hasBackquote = false;
|
|
||||||
QString text = cursor.block().text();
|
|
||||||
if (pos <= text.size() - 1) {
|
|
||||||
if (text[pos] == '`') {
|
|
||||||
hasBackquote = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasBackquote) {
|
|
||||||
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
|
||||||
} else {
|
|
||||||
cursor.insertText("``");
|
|
||||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
|
||||||
}
|
|
||||||
cursor.endEditBlock();
|
|
||||||
m_editor->setTextCursor(cursor);
|
|
||||||
}
|
|
||||||
p_event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyU(QKeyEvent *p_event)
|
bool VMdEditOperations::handleKeyU(QKeyEvent *p_event)
|
||||||
{
|
{
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
if (p_event->modifiers() == Qt::ControlModifier) {
|
||||||
@ -775,3 +647,140 @@ bool VMdEditOperations::insertTitle(int p_level)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::decorateText(TextDecoration p_decoration)
|
||||||
|
{
|
||||||
|
if (p_decoration == TextDecoration::None) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vim->setMode(VimMode::Insert, false);
|
||||||
|
|
||||||
|
switch (p_decoration) {
|
||||||
|
case TextDecoration::Bold:
|
||||||
|
decorateBold();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextDecoration::Italic:
|
||||||
|
decorateItalic();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextDecoration::InlineCode:
|
||||||
|
decorateInlineCode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qDebug() << "decoration" << (int)p_decoration << "is not implemented yet";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::decorateBold()
|
||||||
|
{
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
// Insert ** around the selected text.
|
||||||
|
int start = cursor.selectionStart();
|
||||||
|
int end = cursor.selectionEnd();
|
||||||
|
cursor.clearSelection();
|
||||||
|
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("**");
|
||||||
|
cursor.setPosition(end + 2, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("**");
|
||||||
|
} else {
|
||||||
|
// Insert **** and place cursor in the middle.
|
||||||
|
// Or if there are two * after current cursor, just skip them.
|
||||||
|
int pos = cursor.positionInBlock();
|
||||||
|
bool hasStars = false;
|
||||||
|
QString text = cursor.block().text();
|
||||||
|
if (pos <= text.size() - 2) {
|
||||||
|
if (text[pos] == '*' && text[pos + 1] == '*') {
|
||||||
|
hasStars = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasStars) {
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
|
||||||
|
} else {
|
||||||
|
cursor.insertText("****");
|
||||||
|
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.endEditBlock();
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::decorateItalic()
|
||||||
|
{
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
// Insert * around the selected text.
|
||||||
|
int start = cursor.selectionStart();
|
||||||
|
int end = cursor.selectionEnd();
|
||||||
|
cursor.clearSelection();
|
||||||
|
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("*");
|
||||||
|
cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("*");
|
||||||
|
} else {
|
||||||
|
// Insert ** and place cursor in the middle.
|
||||||
|
// Or if there are one * after current cursor, just skip it.
|
||||||
|
int pos = cursor.positionInBlock();
|
||||||
|
bool hasStar = false;
|
||||||
|
QString text = cursor.block().text();
|
||||||
|
if (pos <= text.size() - 1) {
|
||||||
|
if (text[pos] == '*') {
|
||||||
|
hasStar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasStar) {
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||||
|
} else {
|
||||||
|
cursor.insertText("**");
|
||||||
|
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.endEditBlock();
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditOperations::decorateInlineCode()
|
||||||
|
{
|
||||||
|
QTextCursor cursor = m_editor->textCursor();
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
// Insert ` around the selected text.
|
||||||
|
int start = cursor.selectionStart();
|
||||||
|
int end = cursor.selectionEnd();
|
||||||
|
cursor.clearSelection();
|
||||||
|
cursor.setPosition(start, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("`");
|
||||||
|
cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
|
||||||
|
cursor.insertText("`");
|
||||||
|
} else {
|
||||||
|
// Insert `` and place cursor in the middle.
|
||||||
|
// Or if there are one ` after current cursor, just skip it.
|
||||||
|
int pos = cursor.positionInBlock();
|
||||||
|
bool hasBackquote = false;
|
||||||
|
QString text = cursor.block().text();
|
||||||
|
if (pos <= text.size() - 1) {
|
||||||
|
if (text[pos] == '`') {
|
||||||
|
hasBackquote = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasBackquote) {
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
|
||||||
|
} else {
|
||||||
|
cursor.insertText("``");
|
||||||
|
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.endEditBlock();
|
||||||
|
m_editor->setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
@ -21,6 +21,10 @@ public:
|
|||||||
bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE;
|
bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
// Insert decoration markers or decorate selected text.
|
||||||
|
// If it is Vim Normal mode, change to Insert mode first.
|
||||||
|
void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath);
|
void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath);
|
||||||
|
|
||||||
@ -32,10 +36,7 @@ private:
|
|||||||
// Key press handlers.
|
// Key press handlers.
|
||||||
bool handleKeyTab(QKeyEvent *p_event);
|
bool handleKeyTab(QKeyEvent *p_event);
|
||||||
bool handleKeyBackTab(QKeyEvent *p_event);
|
bool handleKeyBackTab(QKeyEvent *p_event);
|
||||||
bool handleKeyB(QKeyEvent *p_event);
|
|
||||||
bool handleKeyH(QKeyEvent *p_event);
|
bool handleKeyH(QKeyEvent *p_event);
|
||||||
bool handleKeyI(QKeyEvent *p_event);
|
|
||||||
bool handleKeyO(QKeyEvent *p_event);
|
|
||||||
bool handleKeyU(QKeyEvent *p_event);
|
bool handleKeyU(QKeyEvent *p_event);
|
||||||
bool handleKeyW(QKeyEvent *p_event);
|
bool handleKeyW(QKeyEvent *p_event);
|
||||||
bool handleKeyEsc(QKeyEvent *p_event);
|
bool handleKeyEsc(QKeyEvent *p_event);
|
||||||
@ -46,6 +47,15 @@ private:
|
|||||||
// Change the sequence number of a list block.
|
// Change the sequence number of a list block.
|
||||||
void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
|
void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
|
||||||
|
|
||||||
|
// Insert bold marker or set selected text bold.
|
||||||
|
void decorateBold();
|
||||||
|
|
||||||
|
// Insert italic marker or set selected text italic.
|
||||||
|
void decorateItalic();
|
||||||
|
|
||||||
|
// Insert inline-code marker or set selected text inline-coded.
|
||||||
|
void decorateInlineCode();
|
||||||
|
|
||||||
// The cursor position after auto indent or auto list.
|
// The cursor position after auto indent or auto list.
|
||||||
// It will be -1 if last key press do not trigger the auto indent or auto list.
|
// It will be -1 if last key press do not trigger the auto indent or auto list.
|
||||||
int m_autoIndentPos;
|
int m_autoIndentPos;
|
||||||
|
@ -665,3 +665,10 @@ VEditTabInfo VMdTab::createEditTabInfo()
|
|||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMdTab::decorateText(TextDecoration p_decoration)
|
||||||
|
{
|
||||||
|
if (m_editor) {
|
||||||
|
m_editor->decorateText(p_decoration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -57,6 +57,9 @@ public:
|
|||||||
|
|
||||||
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
void requestUpdateVimStatus() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
// Insert decoration markers or decorate selected text.
|
||||||
|
void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -111,5 +111,10 @@
|
|||||||
<file>resources/icons/vnote_update.svg</file>
|
<file>resources/icons/vnote_update.svg</file>
|
||||||
<file>utils/flowchart.js/flowchart.min.js</file>
|
<file>utils/flowchart.js/flowchart.min.js</file>
|
||||||
<file>utils/flowchart.js/raphael.min.js</file>
|
<file>utils/flowchart.js/raphael.min.js</file>
|
||||||
|
<file>resources/icons/bold.svg</file>
|
||||||
|
<file>resources/icons/italic.svg</file>
|
||||||
|
<file>resources/icons/underline.svg</file>
|
||||||
|
<file>resources/icons/strikethrough.svg</file>
|
||||||
|
<file>resources/icons/inline_code.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user