mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
utilize ExtraSelection for special highlighting
1. Highlight current line; 2. Highlight selected word; 3. Highlight searched word; Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
62f2d39fbc
commit
901c477705
@ -8,6 +8,8 @@ current_notebook=0
|
|||||||
tab_stop_width=4
|
tab_stop_width=4
|
||||||
is_expand_tab=1
|
is_expand_tab=1
|
||||||
highlight_cursor_line=1
|
highlight_cursor_line=1
|
||||||
|
highlight_selected_word=1
|
||||||
|
highlight_searched_word=1
|
||||||
current_background_color=System
|
current_background_color=System
|
||||||
current_render_background_color=System
|
current_render_background_color=System
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ void VConfigManager::initialize()
|
|||||||
tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt();
|
tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt();
|
||||||
isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool();
|
isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool();
|
||||||
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
|
m_highlightCursorLine = getConfigFromSettings("global", "highlight_cursor_line").toBool();
|
||||||
|
m_highlightSelectedWord = getConfigFromSettings("global", "highlight_selected_word").toBool();
|
||||||
|
m_highlightSearchedWord = getConfigFromSettings("global", "highlight_searched_word").toBool();
|
||||||
|
|
||||||
readPredefinedColorsFromSettings();
|
readPredefinedColorsFromSettings();
|
||||||
curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString();
|
curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString();
|
||||||
@ -228,23 +230,21 @@ void VConfigManager::updateMarkdownEditStyle()
|
|||||||
|
|
||||||
void VConfigManager::updatePaletteColor()
|
void VConfigManager::updatePaletteColor()
|
||||||
{
|
{
|
||||||
QString rgb;
|
static const QColor defaultColor = baseEditPalette.color(QPalette::Base);
|
||||||
if (curBackgroundColor == "System") {
|
QColor newColor = defaultColor;
|
||||||
return;
|
if (curBackgroundColor != "System") {
|
||||||
} else {
|
|
||||||
for (int i = 0; i < predefinedColors.size(); ++i) {
|
for (int i = 0; i < predefinedColors.size(); ++i) {
|
||||||
if (predefinedColors[i].name == curBackgroundColor) {
|
if (predefinedColors[i].name == curBackgroundColor) {
|
||||||
rgb = predefinedColors[i].rgb;
|
QString rgb = predefinedColors[i].rgb;
|
||||||
|
if (!rgb.isEmpty()) {
|
||||||
|
newColor = QColor(VUtils::QRgbFromString(rgb));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rgb.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
baseEditPalette.setColor(QPalette::Base,
|
baseEditPalette.setColor(QPalette::Base, newColor);
|
||||||
QColor(VUtils::QRgbFromString(rgb)));
|
|
||||||
|
|
||||||
// Update markdown editor palette
|
// Update markdown editor palette
|
||||||
updateMarkdownEditStyle();
|
updateMarkdownEditStyle();
|
||||||
|
@ -79,6 +79,12 @@ public:
|
|||||||
inline bool getHighlightCursorLine() const;
|
inline bool getHighlightCursorLine() const;
|
||||||
inline void setHighlightCursorLine(bool p_cursorLine);
|
inline void setHighlightCursorLine(bool p_cursorLine);
|
||||||
|
|
||||||
|
inline bool getHighlightSelectedWord() const;
|
||||||
|
inline void setHighlightSelectedWord(bool p_selectedWord);
|
||||||
|
|
||||||
|
inline bool getHighlightSearchedWord() const;
|
||||||
|
inline void setHighlightSearchedWord(bool p_searchedWord);
|
||||||
|
|
||||||
inline const QVector<VColor> &getPredefinedColors() const;
|
inline const QVector<VColor> &getPredefinedColors() const;
|
||||||
|
|
||||||
inline const QString &getCurBackgroundColor() const;
|
inline const QString &getCurBackgroundColor() const;
|
||||||
@ -145,6 +151,12 @@ private:
|
|||||||
// Highlight current cursor line.
|
// Highlight current cursor line.
|
||||||
bool m_highlightCursorLine;
|
bool m_highlightCursorLine;
|
||||||
|
|
||||||
|
// Highlight selected word.
|
||||||
|
bool m_highlightSelectedWord;
|
||||||
|
|
||||||
|
// Highlight searched word.
|
||||||
|
bool m_highlightSearchedWord;
|
||||||
|
|
||||||
// App defined color
|
// App defined color
|
||||||
QVector<VColor> predefinedColors;
|
QVector<VColor> predefinedColors;
|
||||||
QString curBackgroundColor;
|
QString curBackgroundColor;
|
||||||
@ -308,6 +320,36 @@ inline void VConfigManager::setHighlightCursorLine(bool p_cursorLine)
|
|||||||
setConfigToSettings("global", "highlight_cursor_line", m_highlightCursorLine);
|
setConfigToSettings("global", "highlight_cursor_line", m_highlightCursorLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getHighlightSelectedWord() const
|
||||||
|
{
|
||||||
|
return m_highlightSelectedWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setHighlightSelectedWord(bool p_selectedWord)
|
||||||
|
{
|
||||||
|
if (p_selectedWord == m_highlightSelectedWord) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_highlightSelectedWord = p_selectedWord;
|
||||||
|
setConfigToSettings("global", "highlight_selected_word",
|
||||||
|
m_highlightSelectedWord);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getHighlightSearchedWord() const
|
||||||
|
{
|
||||||
|
return m_highlightSearchedWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setHighlightSearchedWord(bool p_searchedWord)
|
||||||
|
{
|
||||||
|
if (p_searchedWord == m_highlightSearchedWord) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_highlightSearchedWord = p_searchedWord;
|
||||||
|
setConfigToSettings("global", "highlight_searched_word",
|
||||||
|
m_highlightSearchedWord);
|
||||||
|
}
|
||||||
|
|
||||||
inline const QVector<VColor>& VConfigManager::getPredefinedColors() const
|
inline const QVector<VColor>& VConfigManager::getPredefinedColors() const
|
||||||
{
|
{
|
||||||
return predefinedColors;
|
return predefinedColors;
|
||||||
|
212
src/vedit.cpp
212
src/vedit.cpp
@ -10,13 +10,19 @@
|
|||||||
#include "dialog/vfindreplacedialog.h"
|
#include "dialog/vfindreplacedialog.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
extern VNote *g_vnote;
|
||||||
|
|
||||||
VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
||||||
: QTextEdit(p_parent), m_file(p_file), m_editOps(NULL)
|
: QTextEdit(p_parent), m_file(p_file), m_editOps(NULL)
|
||||||
{
|
{
|
||||||
const int labelTimerInterval = 500;
|
const int labelTimerInterval = 500;
|
||||||
|
const int selectedWordTimerInterval = 500;
|
||||||
const int labelSize = 64;
|
const int labelSize = 64;
|
||||||
|
|
||||||
|
m_cursorLineColor = QColor(g_vnote->getColorFromPalette("Indigo1"));
|
||||||
|
m_selectedWordColor = QColor("Yellow");
|
||||||
|
m_searchedWordColor = QColor(g_vnote->getColorFromPalette("Green4"));
|
||||||
|
|
||||||
QPixmap wrapPixmap(":/resources/icons/search_wrap.svg");
|
QPixmap wrapPixmap(":/resources/icons/search_wrap.svg");
|
||||||
m_wrapLabel = new QLabel(this);
|
m_wrapLabel = new QLabel(this);
|
||||||
m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize));
|
m_wrapLabel->setPixmap(wrapPixmap.scaled(labelSize, labelSize));
|
||||||
@ -26,8 +32,23 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent)
|
|||||||
m_labelTimer->setInterval(labelTimerInterval);
|
m_labelTimer->setInterval(labelTimerInterval);
|
||||||
connect(m_labelTimer, &QTimer::timeout,
|
connect(m_labelTimer, &QTimer::timeout,
|
||||||
this, &VEdit::labelTimerTimeout);
|
this, &VEdit::labelTimerTimeout);
|
||||||
|
|
||||||
|
m_selectedWordTimer = new QTimer(this);
|
||||||
|
m_selectedWordTimer->setSingleShot(true);
|
||||||
|
m_selectedWordTimer->setInterval(selectedWordTimerInterval);
|
||||||
|
connect(m_selectedWordTimer, &QTimer::timeout,
|
||||||
|
this, &VEdit::highlightSelectedWord);
|
||||||
|
|
||||||
connect(document(), &QTextDocument::modificationChanged,
|
connect(document(), &QTextDocument::modificationChanged,
|
||||||
(VFile *)m_file, &VFile::setModified);
|
(VFile *)m_file, &VFile::setModified);
|
||||||
|
|
||||||
|
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
||||||
|
updateFontAndPalette();
|
||||||
|
|
||||||
|
connect(this, &VEdit::cursorPositionChanged,
|
||||||
|
this, &VEdit::highlightCurrentLine);
|
||||||
|
connect(this, &VEdit::selectionChanged,
|
||||||
|
this, &VEdit::triggerHighlightSelectedWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
VEdit::~VEdit()
|
VEdit::~VEdit()
|
||||||
@ -40,6 +61,8 @@ VEdit::~VEdit()
|
|||||||
|
|
||||||
void VEdit::beginEdit()
|
void VEdit::beginEdit()
|
||||||
{
|
{
|
||||||
|
updateFontAndPalette();
|
||||||
|
|
||||||
setReadOnly(false);
|
setReadOnly(false);
|
||||||
setModified(false);
|
setModified(false);
|
||||||
}
|
}
|
||||||
@ -130,6 +153,8 @@ bool VEdit::peekText(const QString &p_text, uint p_options)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use QTextEdit::find() instead of QTextDocument::find() because the later has
|
||||||
|
// bugs in searching backward.
|
||||||
bool VEdit::findTextHelper(const QString &p_text, uint p_options,
|
bool VEdit::findTextHelper(const QString &p_text, uint p_options,
|
||||||
bool p_forward, bool &p_wrapped)
|
bool p_forward, bool &p_wrapped)
|
||||||
{
|
{
|
||||||
@ -186,6 +211,49 @@ bool VEdit::findTextHelper(const QString &p_text, uint p_options,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QTextCursor> VEdit::findTextAll(const QString &p_text, uint p_options)
|
||||||
|
{
|
||||||
|
QList<QTextCursor> results;
|
||||||
|
if (p_text.isEmpty()) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
// Options
|
||||||
|
QTextDocument::FindFlags findFlags;
|
||||||
|
bool caseSensitive = false;
|
||||||
|
if (p_options & FindOption::CaseSensitive) {
|
||||||
|
findFlags |= QTextDocument::FindCaseSensitively;
|
||||||
|
caseSensitive = true;
|
||||||
|
}
|
||||||
|
if (p_options & FindOption::WholeWordOnly) {
|
||||||
|
findFlags |= QTextDocument::FindWholeWords;
|
||||||
|
}
|
||||||
|
// Use regular expression
|
||||||
|
bool useRegExp = false;
|
||||||
|
QRegExp exp;
|
||||||
|
if (p_options & FindOption::RegularExpression) {
|
||||||
|
useRegExp = true;
|
||||||
|
exp = QRegExp(p_text,
|
||||||
|
caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
int startPos = 0;
|
||||||
|
QTextCursor cursor;
|
||||||
|
QTextDocument *doc = document();
|
||||||
|
while (true) {
|
||||||
|
if (useRegExp) {
|
||||||
|
cursor = doc->find(exp, startPos, findFlags);
|
||||||
|
} else {
|
||||||
|
cursor = doc->find(p_text, startPos, findFlags);
|
||||||
|
}
|
||||||
|
if (cursor.isNull()) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
results.append(cursor);
|
||||||
|
startPos = cursor.selectionEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
bool VEdit::findText(const QString &p_text, uint p_options, bool p_forward)
|
bool VEdit::findText(const QString &p_text, uint p_options, bool p_forward)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -196,8 +264,14 @@ bool VEdit::findText(const QString &p_text, uint p_options, bool p_forward)
|
|||||||
} else {
|
} else {
|
||||||
bool wrapped = false;
|
bool wrapped = false;
|
||||||
found = findTextHelper(p_text, p_options, p_forward, wrapped);
|
found = findTextHelper(p_text, p_options, p_forward, wrapped);
|
||||||
if (found && wrapped) {
|
if (found) {
|
||||||
showWrapLabel();
|
if (wrapped) {
|
||||||
|
showWrapLabel();
|
||||||
|
}
|
||||||
|
highlightSearchedWord(p_text, p_options);
|
||||||
|
} else {
|
||||||
|
// Simply clear previous highlight.
|
||||||
|
highlightSearchedWord("", p_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug() << "findText" << p_text << p_options << p_forward
|
qDebug() << "findText" << p_text << p_options << p_forward
|
||||||
@ -294,3 +368,137 @@ void VEdit::labelTimerTimeout()
|
|||||||
{
|
{
|
||||||
m_wrapLabel->hide();
|
m_wrapLabel->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEdit::updateFontAndPalette()
|
||||||
|
{
|
||||||
|
setFont(vconfig.getBaseEditFont());
|
||||||
|
setPalette(vconfig.getBaseEditPalette());
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::highlightExtraSelections()
|
||||||
|
{
|
||||||
|
int nrExtra = m_extraSelections.size();
|
||||||
|
Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection);
|
||||||
|
QList<QTextEdit::ExtraSelection> extraSelects;
|
||||||
|
for (int i = 0; i < nrExtra; ++i) {
|
||||||
|
extraSelects.append(m_extraSelections[i]);
|
||||||
|
}
|
||||||
|
setExtraSelections(extraSelects);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::highlightCurrentLine()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
|
||||||
|
if (vconfig.getHighlightCursorLine() && !isReadOnly()) {
|
||||||
|
// Need to highlight current line.
|
||||||
|
selects.clear();
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection select;
|
||||||
|
select.format.setBackground(m_cursorLineColor);
|
||||||
|
select.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
|
select.cursor = textCursor();
|
||||||
|
select.cursor.clearSelection();
|
||||||
|
selects.append(select);
|
||||||
|
} else {
|
||||||
|
// Need to clear current line highlight.
|
||||||
|
if (selects.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightExtraSelections();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::setReadOnly(bool p_ro)
|
||||||
|
{
|
||||||
|
QTextEdit::setReadOnly(p_ro);
|
||||||
|
highlightCurrentLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::highlightSelectedWord()
|
||||||
|
{
|
||||||
|
QString text;
|
||||||
|
if (vconfig.getHighlightSelectedWord()) {
|
||||||
|
text = textCursor().selectedText().trimmed();
|
||||||
|
if (wordInSearchedSelection(text)) {
|
||||||
|
qDebug() << "select searched word, just skip";
|
||||||
|
text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setBackground(m_selectedWordColor);
|
||||||
|
highlightTextAll(text, FindOption::CaseSensitive, SelectionId::SelectedWord,
|
||||||
|
format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VEdit::wordInSearchedSelection(const QString &p_text)
|
||||||
|
{
|
||||||
|
QString text = p_text.trimmed();
|
||||||
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::SearchedKeyword];
|
||||||
|
for (int i = 0; i < selects.size(); ++i) {
|
||||||
|
QString searchedWord = selects[i].cursor.selectedText();
|
||||||
|
if (text == searchedWord.trimmed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::triggerHighlightSelectedWord()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::SelectedWord];
|
||||||
|
if (!vconfig.getHighlightSelectedWord() && selects.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_selectedWordTimer->stop();
|
||||||
|
QString text = textCursor().selectedText().trimmed();
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
// Clear previous selection right now.
|
||||||
|
highlightSelectedWord();
|
||||||
|
} else {
|
||||||
|
m_selectedWordTimer->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::highlightTextAll(const QString &p_text, uint p_options,
|
||||||
|
SelectionId p_id, QTextCharFormat p_format)
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)p_id];
|
||||||
|
if (!p_text.isEmpty()) {
|
||||||
|
selects.clear();
|
||||||
|
|
||||||
|
QList<QTextCursor> occurs = findTextAll(p_text, p_options);
|
||||||
|
for (int i = 0; i < occurs.size(); ++i) {
|
||||||
|
QTextEdit::ExtraSelection select;
|
||||||
|
select.format = p_format;
|
||||||
|
select.cursor = occurs[i];
|
||||||
|
selects.append(select);
|
||||||
|
}
|
||||||
|
qDebug() << "highlight" << selects.size() << "occurences of" << p_text;
|
||||||
|
} else {
|
||||||
|
if (selects.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selects.clear();
|
||||||
|
}
|
||||||
|
highlightExtraSelections();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::highlightSearchedWord(const QString &p_text, uint p_options)
|
||||||
|
{
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setBackground(m_searchedWordColor);
|
||||||
|
QString text;
|
||||||
|
if (vconfig.getHighlightSearchedWord()) {
|
||||||
|
text = p_text;
|
||||||
|
}
|
||||||
|
highlightTextAll(text, p_options, SelectionId::SearchedKeyword, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::clearSearchedWordHighlight()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::SearchedKeyword];
|
||||||
|
selects.clear();
|
||||||
|
highlightExtraSelections();
|
||||||
|
}
|
||||||
|
33
src/vedit.h
33
src/vedit.h
@ -4,6 +4,9 @@
|
|||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QList>
|
||||||
|
#include <QColor>
|
||||||
#include "vconstants.h"
|
#include "vconstants.h"
|
||||||
#include "vtoc.h"
|
#include "vtoc.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
@ -12,6 +15,13 @@ class VEditOperations;
|
|||||||
class QLabel;
|
class QLabel;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
|
||||||
|
enum class SelectionId {
|
||||||
|
CurrentLine = 0,
|
||||||
|
SelectedWord,
|
||||||
|
SearchedKeyword,
|
||||||
|
MaxSelection
|
||||||
|
};
|
||||||
|
|
||||||
class VEdit : public QTextEdit
|
class VEdit : public QTextEdit
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -36,19 +46,42 @@ public:
|
|||||||
const QString &p_replaceText, bool p_findNext);
|
const QString &p_replaceText, bool p_findNext);
|
||||||
void replaceTextAll(const QString &p_text, uint p_options,
|
void replaceTextAll(const QString &p_text, uint p_options,
|
||||||
const QString &p_replaceText);
|
const QString &p_replaceText);
|
||||||
|
void setReadOnly(bool p_ro);
|
||||||
|
void clearSearchedWordHighlight();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void labelTimerTimeout();
|
void labelTimerTimeout();
|
||||||
|
void triggerHighlightSelectedWord();
|
||||||
|
void highlightSelectedWord();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
virtual void highlightCurrentLine();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPointer<VFile> m_file;
|
QPointer<VFile> m_file;
|
||||||
VEditOperations *m_editOps;
|
VEditOperations *m_editOps;
|
||||||
|
QColor m_cursorLineColor;
|
||||||
|
|
||||||
|
virtual void updateFontAndPalette();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel *m_wrapLabel;
|
QLabel *m_wrapLabel;
|
||||||
QTimer *m_labelTimer;
|
QTimer *m_labelTimer;
|
||||||
|
// highlightExtraSelections() will highlight these selections.
|
||||||
|
// Selections are indexed by SelectionId.
|
||||||
|
QVector<QList<QTextEdit::ExtraSelection> > m_extraSelections;
|
||||||
|
QTimer *m_selectedWordTimer;
|
||||||
|
QColor m_selectedWordColor;
|
||||||
|
QColor m_searchedWordColor;
|
||||||
|
|
||||||
void showWrapLabel();
|
void showWrapLabel();
|
||||||
|
void highlightExtraSelections();
|
||||||
|
// Find all the occurences of @p_text.
|
||||||
|
QList<QTextCursor> findTextAll(const QString &p_text, uint p_options);
|
||||||
|
void highlightTextAll(const QString &p_text, uint p_options,
|
||||||
|
SelectionId p_id, QTextCharFormat p_format);
|
||||||
|
void highlightSearchedWord(const QString &p_text, uint p_options);
|
||||||
|
bool wordInSearchedSelection(const QString &p_text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -509,10 +509,10 @@ void VEditArea::handleFindDialogClosed()
|
|||||||
getWindow(curWindowIndex)->focusWindow();
|
getWindow(curWindowIndex)->focusWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all the selection in Web view.
|
// Clear all the search highlight.
|
||||||
int nrWin = splitter->count();
|
int nrWin = splitter->count();
|
||||||
for (int i = 0; i < nrWin; ++i) {
|
for (int i = 0; i < nrWin; ++i) {
|
||||||
getWindow(i)->clearFindSelectionInWebView();
|
getWindow(i)->clearSearchedWordHighlight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ void VEditTab::showFileReadMode()
|
|||||||
previewByConverter();
|
previewByConverter();
|
||||||
}
|
}
|
||||||
setCurrentWidget(webPreviewer);
|
setCurrentWidget(webPreviewer);
|
||||||
clearFindSelectionInWebView();
|
clearSearchedWordHighlight();
|
||||||
scrollPreviewToHeader(outlineIndex);
|
scrollPreviewToHeader(outlineIndex);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -520,11 +520,12 @@ QString VEditTab::getSelectedText() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditTab::clearFindSelectionInWebView()
|
void VEditTab::clearSearchedWordHighlight()
|
||||||
{
|
{
|
||||||
if (webPreviewer) {
|
if (webPreviewer) {
|
||||||
webPreviewer->findText("");
|
webPreviewer->findText("");
|
||||||
}
|
}
|
||||||
|
m_textEditor->clearSearchedWordHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VEditTab::checkToc()
|
bool VEditTab::checkToc()
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
void replaceTextAll(const QString &p_text, uint p_options,
|
void replaceTextAll(const QString &p_text, uint p_options,
|
||||||
const QString &p_replaceText);
|
const QString &p_replaceText);
|
||||||
QString getSelectedText() const;
|
QString getSelectedText() const;
|
||||||
void clearFindSelectionInWebView();
|
void clearSearchedWordHighlight();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void getFocused();
|
void getFocused();
|
||||||
|
@ -718,10 +718,10 @@ void VEditWindow::setCurrentWindow(bool p_current)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditWindow::clearFindSelectionInWebView()
|
void VEditWindow::clearSearchedWordHighlight()
|
||||||
{
|
{
|
||||||
int nrTab = count();
|
int nrTab = count();
|
||||||
for (int i = 0; i < nrTab; ++i) {
|
for (int i = 0; i < nrTab; ++i) {
|
||||||
getTab(i)->clearFindSelectionInWebView();
|
getTab(i)->clearSearchedWordHighlight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
bool addEditTab(QWidget *p_widget);
|
bool addEditTab(QWidget *p_widget);
|
||||||
// Set whether it is the current window.
|
// Set whether it is the current window.
|
||||||
void setCurrentWindow(bool p_current);
|
void setCurrentWindow(bool p_current);
|
||||||
void clearFindSelectionInWebView();
|
void clearSearchedWordHighlight();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
@ -371,6 +371,12 @@ void VMainWindow::initEditMenu()
|
|||||||
connect(m_replaceAllAct, SIGNAL(triggered(bool)),
|
connect(m_replaceAllAct, SIGNAL(triggered(bool)),
|
||||||
m_findReplaceDialog, SLOT(replaceAll()));
|
m_findReplaceDialog, SLOT(replaceAll()));
|
||||||
|
|
||||||
|
QAction *searchedWordAct = new QAction(tr("Highlight Searched Pattern"), this);
|
||||||
|
searchedWordAct->setStatusTip(tr("Highlight all occurences of searched pattern"));
|
||||||
|
searchedWordAct->setCheckable(true);
|
||||||
|
connect(searchedWordAct, &QAction::triggered,
|
||||||
|
this, &VMainWindow::changeHighlightSearchedWord);
|
||||||
|
|
||||||
// Expand Tab into spaces.
|
// Expand Tab into spaces.
|
||||||
QAction *expandTabAct = new QAction(tr("&Expand Tab"), this);
|
QAction *expandTabAct = new QAction(tr("&Expand Tab"), this);
|
||||||
expandTabAct->setStatusTip(tr("Expand entered tab to spaces"));
|
expandTabAct->setStatusTip(tr("Expand entered tab to spaces"));
|
||||||
@ -402,6 +408,12 @@ void VMainWindow::initEditMenu()
|
|||||||
connect(cursorLineAct, &QAction::triggered,
|
connect(cursorLineAct, &QAction::triggered,
|
||||||
this, &VMainWindow::changeHighlightCursorLine);
|
this, &VMainWindow::changeHighlightCursorLine);
|
||||||
|
|
||||||
|
// Highlight selected word.
|
||||||
|
QAction *selectedWordAct = new QAction(tr("Highlight Selected Word"), this);
|
||||||
|
selectedWordAct->setStatusTip(tr("Highlight all occurences of selected word"));
|
||||||
|
selectedWordAct->setCheckable(true);
|
||||||
|
connect(selectedWordAct, &QAction::triggered,
|
||||||
|
this, &VMainWindow::changeHighlightSelectedWord);
|
||||||
|
|
||||||
editMenu->addAction(m_insertImageAct);
|
editMenu->addAction(m_insertImageAct);
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
@ -414,6 +426,14 @@ void VMainWindow::initEditMenu()
|
|||||||
findReplaceMenu->addAction(m_replaceAct);
|
findReplaceMenu->addAction(m_replaceAct);
|
||||||
findReplaceMenu->addAction(m_replaceFindAct);
|
findReplaceMenu->addAction(m_replaceFindAct);
|
||||||
findReplaceMenu->addAction(m_replaceAllAct);
|
findReplaceMenu->addAction(m_replaceAllAct);
|
||||||
|
findReplaceMenu->addSeparator();
|
||||||
|
findReplaceMenu->addAction(searchedWordAct);
|
||||||
|
if (vconfig.getHighlightSearchedWord()) {
|
||||||
|
searchedWordAct->setChecked(true);
|
||||||
|
} else {
|
||||||
|
searchedWordAct->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
m_findReplaceAct->setEnabled(false);
|
m_findReplaceAct->setEnabled(false);
|
||||||
m_findNextAct->setEnabled(false);
|
m_findNextAct->setEnabled(false);
|
||||||
@ -447,12 +467,20 @@ void VMainWindow::initEditMenu()
|
|||||||
qWarning() << "unsupported tab stop width" << tabStopWidth << "in config";
|
qWarning() << "unsupported tab stop width" << tabStopWidth << "in config";
|
||||||
}
|
}
|
||||||
initEditorBackgroundMenu(editMenu);
|
initEditorBackgroundMenu(editMenu);
|
||||||
|
editMenu->addSeparator();
|
||||||
editMenu->addAction(cursorLineAct);
|
editMenu->addAction(cursorLineAct);
|
||||||
if (vconfig.getHighlightCursorLine()) {
|
if (vconfig.getHighlightCursorLine()) {
|
||||||
cursorLineAct->setChecked(true);
|
cursorLineAct->setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
cursorLineAct->setChecked(false);
|
cursorLineAct->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editMenu->addAction(selectedWordAct);
|
||||||
|
if (vconfig.getHighlightSelectedWord()) {
|
||||||
|
selectedWordAct->setChecked(true);
|
||||||
|
} else {
|
||||||
|
selectedWordAct->setChecked(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::initDockWindows()
|
void VMainWindow::initDockWindows()
|
||||||
@ -479,7 +507,7 @@ void VMainWindow::initAvatar()
|
|||||||
m_avatar = new VAvatar(this);
|
m_avatar = new VAvatar(this);
|
||||||
m_avatar->setAvatarPixmap(":/resources/icons/vnote.svg");
|
m_avatar->setAvatarPixmap(":/resources/icons/vnote.svg");
|
||||||
m_avatar->setColor(vnote->getColorFromPalette("base-color"), vnote->getColorFromPalette("Indigo4"),
|
m_avatar->setColor(vnote->getColorFromPalette("base-color"), vnote->getColorFromPalette("Indigo4"),
|
||||||
vnote->getColorFromPalette("teal4"));
|
vnote->getColorFromPalette("Teal4"));
|
||||||
m_avatar->hide();
|
m_avatar->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,6 +567,16 @@ void VMainWindow::changeHighlightCursorLine(bool p_checked)
|
|||||||
vconfig.setHighlightCursorLine(p_checked);
|
vconfig.setHighlightCursorLine(p_checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMainWindow::changeHighlightSelectedWord(bool p_checked)
|
||||||
|
{
|
||||||
|
vconfig.setHighlightSelectedWord(p_checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMainWindow::changeHighlightSearchedWord(bool p_checked)
|
||||||
|
{
|
||||||
|
vconfig.setHighlightSearchedWord(p_checked);
|
||||||
|
}
|
||||||
|
|
||||||
void VMainWindow::setTabStopWidth(QAction *action)
|
void VMainWindow::setTabStopWidth(QAction *action)
|
||||||
{
|
{
|
||||||
if (!action) {
|
if (!action) {
|
||||||
|
@ -47,6 +47,8 @@ private slots:
|
|||||||
void setEditorBackgroundColor(QAction *action);
|
void setEditorBackgroundColor(QAction *action);
|
||||||
void setRenderBackgroundColor(QAction *action);
|
void setRenderBackgroundColor(QAction *action);
|
||||||
void changeHighlightCursorLine(bool p_checked);
|
void changeHighlightCursorLine(bool p_checked);
|
||||||
|
void changeHighlightSelectedWord(bool p_checked);
|
||||||
|
void changeHighlightSearchedWord(bool p_checked);
|
||||||
void handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
void handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
||||||
void onePanelView();
|
void onePanelView();
|
||||||
void twoPanelView();
|
void twoPanelView();
|
||||||
|
@ -35,10 +35,6 @@ VMdEdit::VMdEdit(VFile *p_file, QWidget *p_parent)
|
|||||||
|
|
||||||
connect(this, &VMdEdit::cursorPositionChanged,
|
connect(this, &VMdEdit::cursorPositionChanged,
|
||||||
this, &VMdEdit::updateCurHeader);
|
this, &VMdEdit::updateCurHeader);
|
||||||
if (vconfig.getHighlightCursorLine()) {
|
|
||||||
connect(this, &VMdEdit::cursorPositionChanged,
|
|
||||||
this, &VMdEdit::highlightCurrentLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(this, &VMdEdit::selectionChanged,
|
connect(this, &VMdEdit::selectionChanged,
|
||||||
this, &VMdEdit::handleSelectionChanged);
|
this, &VMdEdit::handleSelectionChanged);
|
||||||
@ -60,8 +56,6 @@ void VMdEdit::beginEdit()
|
|||||||
m_editOps->updateTabSettings();
|
m_editOps->updateTabSettings();
|
||||||
updateFontAndPalette();
|
updateFontAndPalette();
|
||||||
|
|
||||||
setFont(vconfig.getMdEditFont());
|
|
||||||
|
|
||||||
Q_ASSERT(m_file->getContent() == toPlainTextWithoutImg());
|
Q_ASSERT(m_file->getContent() == toPlainTextWithoutImg());
|
||||||
|
|
||||||
initInitImages();
|
initInitImages();
|
||||||
@ -491,22 +485,6 @@ int VMdEdit::removeObjectReplacementLine(QString &p_text, int p_index) const
|
|||||||
return prevLineIdx - 1;
|
return prevLineIdx - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMdEdit::highlightCurrentLine()
|
|
||||||
{
|
|
||||||
QList<QTextEdit::ExtraSelection> extraSelects;
|
|
||||||
|
|
||||||
if (!isReadOnly()) {
|
|
||||||
QTextEdit::ExtraSelection select;
|
|
||||||
|
|
||||||
select.format.setBackground(m_cursorLineColor);
|
|
||||||
select.format.setProperty(QTextFormat::FullWidthSelection, true);
|
|
||||||
select.cursor = textCursor();
|
|
||||||
select.cursor.clearSelection();
|
|
||||||
extraSelects.append(select);
|
|
||||||
}
|
|
||||||
setExtraSelections(extraSelects);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VMdEdit::handleEditStateChanged(KeyState p_state)
|
void VMdEdit::handleEditStateChanged(KeyState p_state)
|
||||||
{
|
{
|
||||||
qDebug() << "edit state" << (int)p_state;
|
qDebug() << "edit state" << (int)p_state;
|
||||||
|
@ -39,7 +39,6 @@ private slots:
|
|||||||
void updateCurHeader();
|
void updateCurHeader();
|
||||||
// Update block list containing image links.
|
// Update block list containing image links.
|
||||||
void updateImageBlocks(QSet<int> p_imageBlocks);
|
void updateImageBlocks(QSet<int> p_imageBlocks);
|
||||||
void highlightCurrentLine();
|
|
||||||
void handleEditStateChanged(KeyState p_state);
|
void handleEditStateChanged(KeyState p_state);
|
||||||
void handleSelectionChanged();
|
void handleSelectionChanged();
|
||||||
void handleClipboardChanged(QClipboard::Mode p_mode);
|
void handleClipboardChanged(QClipboard::Mode p_mode);
|
||||||
@ -48,9 +47,9 @@ protected:
|
|||||||
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||||
bool canInsertFromMimeData(const QMimeData *source) const Q_DECL_OVERRIDE;
|
bool canInsertFromMimeData(const QMimeData *source) const Q_DECL_OVERRIDE;
|
||||||
void insertFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE;
|
void insertFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE;
|
||||||
|
void updateFontAndPalette() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateFontAndPalette();
|
|
||||||
void initInitImages();
|
void initInitImages();
|
||||||
void clearUnusedImages();
|
void clearUnusedImages();
|
||||||
// p_text[p_index] is QChar::ObjectReplacementCharacter. Remove the line containing it.
|
// p_text[p_index] is QChar::ObjectReplacementCharacter. Remove the line containing it.
|
||||||
@ -80,7 +79,6 @@ private:
|
|||||||
QVector<QString> m_insertedImages;
|
QVector<QString> m_insertedImages;
|
||||||
QVector<QString> m_initImages;
|
QVector<QString> m_initImages;
|
||||||
QVector<VHeader> m_headers;
|
QVector<VHeader> m_headers;
|
||||||
QColor m_cursorLineColor;
|
|
||||||
bool m_previewImage;
|
bool m_previewImage;
|
||||||
|
|
||||||
static const QString c_cursorLineColor;
|
static const QString c_cursorLineColor;
|
||||||
|
@ -34,11 +34,11 @@ void VNote::initPalette(QPalette palette)
|
|||||||
m_palette.append(QPair<QString, QString>("base-color", "#BDBDBD"));
|
m_palette.append(QPair<QString, QString>("base-color", "#BDBDBD"));
|
||||||
|
|
||||||
// Material Design Colors
|
// Material Design Colors
|
||||||
m_palette.append(QPair<QString, QString>("teal0", "#E0F2F1"));
|
m_palette.append(QPair<QString, QString>("Teal0", "#E0F2F1"));
|
||||||
m_palette.append(QPair<QString, QString>("teal1", "#B2DFDB"));
|
m_palette.append(QPair<QString, QString>("Teal1", "#B2DFDB"));
|
||||||
m_palette.append(QPair<QString, QString>("teal2", "#80CBC4"));
|
m_palette.append(QPair<QString, QString>("Teal2", "#80CBC4"));
|
||||||
m_palette.append(QPair<QString, QString>("teal3", "#4DB6AC"));
|
m_palette.append(QPair<QString, QString>("Teal3", "#4DB6AC"));
|
||||||
m_palette.append(QPair<QString, QString>("teal4", "#26A69A"));
|
m_palette.append(QPair<QString, QString>("Teal4", "#26A69A"));
|
||||||
|
|
||||||
m_palette.append(QPair<QString, QString>("Indigo0", "#E8EAF6"));
|
m_palette.append(QPair<QString, QString>("Indigo0", "#E8EAF6"));
|
||||||
m_palette.append(QPair<QString, QString>("Indigo1", "#C5CAE9"));
|
m_palette.append(QPair<QString, QString>("Indigo1", "#C5CAE9"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user