mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59: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)
|
||||
{
|
||||
if (p_hasText && m_mode == VimMode::Normal) {
|
||||
// Enter visual mode.
|
||||
setMode(VimMode::Visual);
|
||||
// Enter visual mode without clearing the selection.
|
||||
setMode(VimMode::Visual, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,4 +34,11 @@ namespace DirConfig
|
||||
}
|
||||
|
||||
static const QString c_emptyHeaderName = "[EMPTY]";
|
||||
|
||||
enum class TextDecoration { None,
|
||||
Bold,
|
||||
Italic,
|
||||
Underline,
|
||||
Strikethrough,
|
||||
InlineCode };
|
||||
#endif
|
||||
|
@ -826,3 +826,10 @@ void VEdit::setInputMethodEnabled(bool p_enabled)
|
||||
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);
|
||||
|
||||
// Insert decoration markers or decorate selected text.
|
||||
void decorateText(TextDecoration p_decoration);
|
||||
|
||||
signals:
|
||||
// Request VEditTab to save and exit edit mode.
|
||||
void saveAndRead();
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
// Request to propogate Vim status.
|
||||
void requestUpdateVimStatus();
|
||||
|
||||
// Insert decoration markers or decorate selected text.
|
||||
virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
|
||||
|
||||
signals:
|
||||
// Want to display a template message in status bar.
|
||||
void statusMessage(const QString &p_msg);
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
// Request current tab to propogate its status about Vim.
|
||||
virtual void requestUpdateVimStatus() = 0;
|
||||
|
||||
// Insert decoration markers or decorate selected text.
|
||||
virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
|
||||
|
||||
public slots:
|
||||
// Enter edit mode
|
||||
virtual void editFile() = 0;
|
||||
|
@ -175,6 +175,7 @@ void VMainWindow::initToolBar()
|
||||
{
|
||||
initFileToolBar();
|
||||
initViewToolBar();
|
||||
initEditToolBar();
|
||||
}
|
||||
|
||||
void VMainWindow::initViewToolBar()
|
||||
@ -210,6 +211,90 @@ void VMainWindow::initViewToolBar()
|
||||
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()
|
||||
{
|
||||
QToolBar *fileToolBar = addToolBar(tr("Note"));
|
||||
@ -507,6 +592,7 @@ void VMainWindow::initMarkdownMenu()
|
||||
void VMainWindow::initViewMenu()
|
||||
{
|
||||
viewMenu = menuBar()->addMenu(tr("&View"));
|
||||
viewMenu->setToolTipsVisible(true);
|
||||
}
|
||||
|
||||
void VMainWindow::initFileMenu()
|
||||
@ -795,7 +881,10 @@ void VMainWindow::initDockWindows()
|
||||
toolBox->addItem(outline, QIcon(":/resources/icons/outline.svg"), tr("Outline"));
|
||||
toolDock->setWidget(toolBox);
|
||||
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()
|
||||
@ -1154,6 +1243,9 @@ void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
|
||||
noteInfoAct->setEnabled(p_file && p_file->getType() == FileType::Normal);
|
||||
|
||||
m_insertImageAct->setEnabled(p_file && p_editMode);
|
||||
|
||||
setActionsVisible(m_editToolBar, p_file && p_editMode);
|
||||
|
||||
// Find/Replace
|
||||
m_findReplaceAct->setEnabled(p_file);
|
||||
m_findNextAct->setEnabled(p_file);
|
||||
|
@ -108,6 +108,9 @@ private:
|
||||
void initFileToolBar();
|
||||
void initViewToolBar();
|
||||
|
||||
// Init the Edit toolbar.
|
||||
void initEditToolBar();
|
||||
|
||||
void initMenuBar();
|
||||
void initFileMenu();
|
||||
void initEditMenu();
|
||||
@ -196,6 +199,9 @@ private:
|
||||
// Menus
|
||||
QMenu *viewMenu;
|
||||
|
||||
// Edit Toolbar.
|
||||
QToolBar *m_editToolBar;
|
||||
|
||||
QVector<QPixmap> predefinedColorPixmaps;
|
||||
};
|
||||
|
||||
|
@ -241,10 +241,12 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
|
||||
case Qt::Key_B:
|
||||
{
|
||||
if (handleKeyB(p_event)) {
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
decorateBold();
|
||||
p_event->accept();
|
||||
ret = true;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -259,19 +261,23 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
|
||||
|
||||
case Qt::Key_I:
|
||||
{
|
||||
if (handleKeyI(p_event)) {
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
decorateItalic();
|
||||
p_event->accept();
|
||||
ret = true;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_O:
|
||||
{
|
||||
if (handleKeyO(p_event)) {
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
decorateInlineCode();
|
||||
p_event->accept();
|
||||
ret = true;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -435,51 +441,6 @@ bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event)
|
||||
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)
|
||||
{
|
||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
||||
@ -493,95 +454,6 @@ bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
|
||||
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)
|
||||
{
|
||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
||||
@ -775,3 +647,140 @@ bool VMdEditOperations::insertTitle(int p_level)
|
||||
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 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:
|
||||
void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath);
|
||||
|
||||
@ -32,10 +36,7 @@ private:
|
||||
// Key press handlers.
|
||||
bool handleKeyTab(QKeyEvent *p_event);
|
||||
bool handleKeyBackTab(QKeyEvent *p_event);
|
||||
bool handleKeyB(QKeyEvent *p_event);
|
||||
bool handleKeyH(QKeyEvent *p_event);
|
||||
bool handleKeyI(QKeyEvent *p_event);
|
||||
bool handleKeyO(QKeyEvent *p_event);
|
||||
bool handleKeyU(QKeyEvent *p_event);
|
||||
bool handleKeyW(QKeyEvent *p_event);
|
||||
bool handleKeyEsc(QKeyEvent *p_event);
|
||||
@ -46,6 +47,15 @@ private:
|
||||
// Change the sequence number of a list block.
|
||||
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.
|
||||
// It will be -1 if last key press do not trigger the auto indent or auto list.
|
||||
int m_autoIndentPos;
|
||||
|
@ -665,3 +665,10 @@ VEditTabInfo VMdTab::createEditTabInfo()
|
||||
|
||||
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;
|
||||
|
||||
// Insert decoration markers or decorate selected text.
|
||||
void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
// Enter edit mode.
|
||||
void editFile() Q_DECL_OVERRIDE;
|
||||
|
@ -111,5 +111,10 @@
|
||||
<file>resources/icons/vnote_update.svg</file>
|
||||
<file>utils/flowchart.js/flowchart.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>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user