mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
implement Find/Replace logics
Supports Find/Replace in both edit and preview modes. Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
768c1632b0
commit
3005d9bf5c
@ -2,7 +2,7 @@
|
|||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
|
|
||||||
VFindReplaceDialog::VFindReplaceDialog(QWidget *p_parent)
|
VFindReplaceDialog::VFindReplaceDialog(QWidget *p_parent)
|
||||||
: QWidget(p_parent)
|
: QWidget(p_parent), m_options(0), m_replaceAvailable(true)
|
||||||
{
|
{
|
||||||
setupUI();
|
setupUI();
|
||||||
}
|
}
|
||||||
@ -24,25 +24,42 @@ void VFindReplaceDialog::setupUI()
|
|||||||
// Find
|
// Find
|
||||||
QLabel *findLabel = new QLabel(tr("&Find:"));
|
QLabel *findLabel = new QLabel(tr("&Find:"));
|
||||||
m_findEdit = new QLineEdit();
|
m_findEdit = new QLineEdit();
|
||||||
|
m_findEdit->setPlaceholderText(tr("Enter text to search"));
|
||||||
findLabel->setBuddy(m_findEdit);
|
findLabel->setBuddy(m_findEdit);
|
||||||
m_findNextBtn = new QPushButton(tr("Find Next"));
|
m_findNextBtn = new QPushButton(tr("Find &Next"));
|
||||||
m_findNextBtn->setProperty("FlatBtn", true);
|
m_findNextBtn->setProperty("FlatBtn", true);
|
||||||
m_findNextBtn->setDefault(true);
|
m_findNextBtn->setDefault(true);
|
||||||
m_findPrevBtn = new QPushButton(tr("Find Previous"));
|
m_findPrevBtn = new QPushButton(tr("Find &Previous"));
|
||||||
m_findPrevBtn->setProperty("FlatBtn", true);
|
m_findPrevBtn->setProperty("FlatBtn", true);
|
||||||
|
|
||||||
// Replace
|
// Replace
|
||||||
QLabel *replaceLabel = new QLabel(tr("&Replace with:"));
|
QLabel *replaceLabel = new QLabel(tr("&Replace with:"));
|
||||||
m_replaceEdit = new QLineEdit();
|
m_replaceEdit = new QLineEdit();
|
||||||
|
m_replaceEdit->setPlaceholderText(tr("Enter text to replace with"));
|
||||||
replaceLabel->setBuddy(m_replaceEdit);
|
replaceLabel->setBuddy(m_replaceEdit);
|
||||||
m_replaceBtn = new QPushButton(tr("Replace"));
|
m_replaceBtn = new QPushButton(tr("R&eplace"));
|
||||||
m_replaceBtn->setProperty("FlatBtn", true);
|
m_replaceBtn->setProperty("FlatBtn", true);
|
||||||
m_replaceFindBtn = new QPushButton(tr("Replace && Find"));
|
m_replaceFindBtn = new QPushButton(tr("Replace && Fin&d"));
|
||||||
m_replaceFindBtn->setProperty("FlatBtn", true);
|
m_replaceFindBtn->setProperty("FlatBtn", true);
|
||||||
m_replaceAllBtn = new QPushButton(tr("Replace All"));
|
m_replaceAllBtn = new QPushButton(tr("Replace A&ll"));
|
||||||
m_replaceAllBtn->setProperty("FlatBtn", true);
|
m_replaceAllBtn->setProperty("FlatBtn", true);
|
||||||
m_advancedBtn = new QPushButton(tr("Advanced"));
|
m_advancedBtn = new QPushButton(tr("&Advanced >>"));
|
||||||
m_advancedBtn->setProperty("FlatBtn", true);
|
m_advancedBtn->setProperty("FlatBtn", true);
|
||||||
|
m_advancedBtn->setCheckable(true);
|
||||||
|
|
||||||
|
// Options
|
||||||
|
m_caseSensitiveCheck = new QCheckBox(tr("&Case sensitive"), this);
|
||||||
|
connect(m_caseSensitiveCheck, &QCheckBox::stateChanged,
|
||||||
|
this, &VFindReplaceDialog::optionBoxToggled);
|
||||||
|
m_wholeWordOnlyCheck = new QCheckBox(tr("&Whole word only"), this);
|
||||||
|
connect(m_wholeWordOnlyCheck, &QCheckBox::stateChanged,
|
||||||
|
this, &VFindReplaceDialog::optionBoxToggled);
|
||||||
|
m_regularExpressionCheck = new QCheckBox(tr("Re&gular expression"), this);
|
||||||
|
connect(m_regularExpressionCheck, &QCheckBox::stateChanged,
|
||||||
|
this, &VFindReplaceDialog::optionBoxToggled);
|
||||||
|
m_incrementalSearchCheck = new QCheckBox(tr("&Incremental search"), this);
|
||||||
|
connect(m_incrementalSearchCheck, &QCheckBox::stateChanged,
|
||||||
|
this, &VFindReplaceDialog::optionBoxToggled);
|
||||||
|
|
||||||
QGridLayout *gridLayout = new QGridLayout();
|
QGridLayout *gridLayout = new QGridLayout();
|
||||||
gridLayout->addWidget(findLabel, 0, 0);
|
gridLayout->addWidget(findLabel, 0, 0);
|
||||||
@ -55,6 +72,10 @@ void VFindReplaceDialog::setupUI()
|
|||||||
gridLayout->addWidget(m_replaceFindBtn, 1, 3);
|
gridLayout->addWidget(m_replaceFindBtn, 1, 3);
|
||||||
gridLayout->addWidget(m_replaceAllBtn, 1, 4);
|
gridLayout->addWidget(m_replaceAllBtn, 1, 4);
|
||||||
gridLayout->addWidget(m_advancedBtn, 1, 5);
|
gridLayout->addWidget(m_advancedBtn, 1, 5);
|
||||||
|
gridLayout->addWidget(m_caseSensitiveCheck, 2, 1);
|
||||||
|
gridLayout->addWidget(m_wholeWordOnlyCheck, 2, 2);
|
||||||
|
gridLayout->addWidget(m_regularExpressionCheck, 3, 1);
|
||||||
|
gridLayout->addWidget(m_incrementalSearchCheck, 3, 2);
|
||||||
gridLayout->setColumnStretch(0, 0);
|
gridLayout->setColumnStretch(0, 0);
|
||||||
gridLayout->setColumnStretch(1, 4);
|
gridLayout->setColumnStretch(1, 4);
|
||||||
gridLayout->setColumnStretch(2, 1);
|
gridLayout->setColumnStretch(2, 1);
|
||||||
@ -62,6 +83,7 @@ void VFindReplaceDialog::setupUI()
|
|||||||
gridLayout->setColumnStretch(4, 1);
|
gridLayout->setColumnStretch(4, 1);
|
||||||
gridLayout->setColumnStretch(5, 1);
|
gridLayout->setColumnStretch(5, 1);
|
||||||
gridLayout->setColumnStretch(6, 3);
|
gridLayout->setColumnStretch(6, 3);
|
||||||
|
|
||||||
QMargins margin = gridLayout->contentsMargins();
|
QMargins margin = gridLayout->contentsMargins();
|
||||||
margin.setLeft(3);
|
margin.setLeft(3);
|
||||||
gridLayout->setContentsMargins(margin);
|
gridLayout->setContentsMargins(margin);
|
||||||
@ -73,31 +95,195 @@ void VFindReplaceDialog::setupUI()
|
|||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
m_caseSensitiveCheck->hide();
|
||||||
|
m_wholeWordOnlyCheck->hide();
|
||||||
|
m_regularExpressionCheck->hide();
|
||||||
|
m_incrementalSearchCheck->hide();
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
connect(m_closeBtn, &QPushButton::clicked,
|
connect(m_closeBtn, &QPushButton::clicked,
|
||||||
this, &VFindReplaceDialog::closeDialog);
|
this, &VFindReplaceDialog::closeDialog);
|
||||||
|
connect(m_findEdit, &QLineEdit::textChanged,
|
||||||
|
this, &VFindReplaceDialog::handleFindTextChanged);
|
||||||
|
connect(m_advancedBtn, &QPushButton::toggled,
|
||||||
|
this, &VFindReplaceDialog::advancedBtnToggled);
|
||||||
|
connect(m_findNextBtn, SIGNAL(clicked(bool)),
|
||||||
|
this, SLOT(findNext()));
|
||||||
|
connect(m_findPrevBtn, SIGNAL(clicked(bool)),
|
||||||
|
this, SLOT(findPrevious()));
|
||||||
|
connect(m_replaceBtn, SIGNAL(clicked(bool)),
|
||||||
|
this, SLOT(replace()));
|
||||||
|
connect(m_replaceFindBtn, SIGNAL(clicked(bool)),
|
||||||
|
this, SLOT(replaceFind()));
|
||||||
|
connect(m_replaceAllBtn, SIGNAL(clicked(bool)),
|
||||||
|
this, SLOT(replaceAll()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VFindReplaceDialog::closeDialog()
|
void VFindReplaceDialog::closeDialog()
|
||||||
{
|
{
|
||||||
if (this->isVisible()) {
|
if (this->isVisible()) {
|
||||||
this->hide();
|
hide();
|
||||||
emit dialogClosed();
|
emit dialogClosed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VFindReplaceDialog::showEvent(QShowEvent *event)
|
|
||||||
{
|
|
||||||
m_findEdit->selectAll();
|
|
||||||
QWidget::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VFindReplaceDialog::keyPressEvent(QKeyEvent *event)
|
void VFindReplaceDialog::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if (event->key() == Qt::Key_Escape) {
|
switch (event->key()) {
|
||||||
|
case Qt::Key_Escape:
|
||||||
event->accept();
|
event->accept();
|
||||||
closeDialog();
|
closeDialog();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Qt::Key_Return:
|
||||||
|
{
|
||||||
|
int modifiers = event->modifiers();
|
||||||
|
bool shift = false;
|
||||||
|
if (modifiers == Qt::ShiftModifier) {
|
||||||
|
shift = true;
|
||||||
|
} else if (modifiers != Qt::NoModifier) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!m_findEdit->hasFocus() && !m_replaceEdit->hasFocus()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
event->accept();
|
||||||
|
if (shift) {
|
||||||
|
findPrevious();
|
||||||
|
} else {
|
||||||
|
findNext();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
QWidget::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::openDialog(QString p_text)
|
||||||
|
{
|
||||||
|
show();
|
||||||
|
if (!p_text.isEmpty()) {
|
||||||
|
m_findEdit->setText(p_text);
|
||||||
|
}
|
||||||
|
m_findEdit->setFocus();
|
||||||
|
m_findEdit->selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::handleFindTextChanged(const QString &p_text)
|
||||||
|
{
|
||||||
|
emit findTextChanged(p_text, m_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::advancedBtnToggled(bool p_checked)
|
||||||
|
{
|
||||||
|
if (p_checked) {
|
||||||
|
m_advancedBtn->setText("B&asic <<");
|
||||||
|
} else {
|
||||||
|
m_advancedBtn->setText("&Advanced <<");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_caseSensitiveCheck->setVisible(p_checked);
|
||||||
|
m_wholeWordOnlyCheck->setVisible(p_checked);
|
||||||
|
m_regularExpressionCheck->setVisible(p_checked);
|
||||||
|
m_incrementalSearchCheck->setVisible(p_checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::optionBoxToggled(int p_state)
|
||||||
|
{
|
||||||
|
QObject *obj = sender();
|
||||||
|
FindOption opt = FindOption::CaseSensitive;
|
||||||
|
if (obj == m_caseSensitiveCheck) {
|
||||||
|
opt = FindOption::CaseSensitive;
|
||||||
|
} else if (obj == m_wholeWordOnlyCheck) {
|
||||||
|
opt = FindOption::WholeWordOnly;
|
||||||
|
} else if (obj == m_regularExpressionCheck) {
|
||||||
|
opt = FindOption::RegularExpression;
|
||||||
|
} else {
|
||||||
|
opt = FindOption::IncrementalSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_state) {
|
||||||
|
m_options |= opt;
|
||||||
|
} else {
|
||||||
|
m_options &= ~opt;
|
||||||
|
}
|
||||||
|
emit findOptionChanged(m_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::setOption(FindOption p_opt, bool p_enabled)
|
||||||
|
{
|
||||||
|
if (p_opt == FindOption::CaseSensitive) {
|
||||||
|
m_caseSensitiveCheck->setChecked(p_enabled);
|
||||||
|
} else if (p_opt == FindOption::WholeWordOnly) {
|
||||||
|
m_wholeWordOnlyCheck->setChecked(p_enabled);
|
||||||
|
} else if (p_opt == FindOption::RegularExpression) {
|
||||||
|
m_regularExpressionCheck->setChecked(p_enabled);
|
||||||
|
} else if (p_opt == FindOption::IncrementalSearch) {
|
||||||
|
m_incrementalSearchCheck->setChecked(p_enabled);
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::findNext()
|
||||||
|
{
|
||||||
|
QString text = m_findEdit->text();
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit findNext(text, m_options, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::findPrevious()
|
||||||
|
{
|
||||||
|
QString text = m_findEdit->text();
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit findNext(text, m_options, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::replace()
|
||||||
|
{
|
||||||
|
QString text = m_findEdit->text();
|
||||||
|
if (text.isEmpty() || !m_replaceAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString replaceText = m_replaceEdit->text();
|
||||||
|
emit replace(text, m_options, replaceText, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::replaceFind()
|
||||||
|
{
|
||||||
|
QString text = m_findEdit->text();
|
||||||
|
if (text.isEmpty() || !m_replaceAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString replaceText = m_replaceEdit->text();
|
||||||
|
emit replace(text, m_options, replaceText, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::replaceAll()
|
||||||
|
{
|
||||||
|
QString text = m_findEdit->text();
|
||||||
|
if (text.isEmpty() || !m_replaceAvailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString replaceText = m_replaceEdit->text();
|
||||||
|
emit replaceAll(text, m_options, replaceText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFindReplaceDialog::updateState(DocType p_docType, bool p_editMode)
|
||||||
|
{
|
||||||
|
if (p_editMode || p_docType == DocType::Html) {
|
||||||
|
m_wholeWordOnlyCheck->setEnabled(true);
|
||||||
|
m_regularExpressionCheck->setEnabled(true);
|
||||||
|
} else {
|
||||||
|
m_wholeWordOnlyCheck->setEnabled(false);
|
||||||
|
m_regularExpressionCheck->setEnabled(false);
|
||||||
|
}
|
||||||
|
m_replaceAvailable = p_editMode;
|
||||||
|
}
|
||||||
|
@ -2,28 +2,64 @@
|
|||||||
#define VFINDREPLACEDIALOG_H
|
#define VFINDREPLACEDIALOG_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QString>
|
||||||
|
#include "vconstants.h"
|
||||||
|
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
class QCheckBox;
|
||||||
|
|
||||||
|
enum FindOption
|
||||||
|
{
|
||||||
|
CaseSensitive = 0x1U,
|
||||||
|
WholeWordOnly = 0x2U,
|
||||||
|
RegularExpression = 0x4U,
|
||||||
|
IncrementalSearch = 0x8U
|
||||||
|
};
|
||||||
|
|
||||||
class VFindReplaceDialog : public QWidget
|
class VFindReplaceDialog : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VFindReplaceDialog(QWidget *p_parent = 0);
|
explicit VFindReplaceDialog(QWidget *p_parent = 0);
|
||||||
|
void setOption(FindOption p_opt, bool p_enabled);
|
||||||
|
// Update the options enabled/disabled state according to current
|
||||||
|
// edit tab.
|
||||||
|
void updateState(DocType p_docType, bool p_editMode);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dialogClosed();
|
void dialogClosed();
|
||||||
|
void findTextChanged(const QString &p_text, uint p_options);
|
||||||
|
void findOptionChanged(uint p_options);
|
||||||
|
void findNext(const QString &p_text, uint p_options, bool p_forward);
|
||||||
|
void replace(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext);
|
||||||
|
void replaceAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
|
|
||||||
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void closeDialog();
|
void closeDialog();
|
||||||
|
void openDialog(QString p_text = "");
|
||||||
|
void findNext();
|
||||||
|
void findPrevious();
|
||||||
|
void replace();
|
||||||
|
void replaceFind();
|
||||||
|
void replaceAll();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleFindTextChanged(const QString &p_text);
|
||||||
|
void advancedBtnToggled(bool p_checked);
|
||||||
|
void optionBoxToggled(int p_state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
// Bit OR of FindOption
|
||||||
|
uint m_options;
|
||||||
|
bool m_replaceAvailable;
|
||||||
|
|
||||||
QLineEdit *m_findEdit;
|
QLineEdit *m_findEdit;
|
||||||
QLineEdit *m_replaceEdit;
|
QLineEdit *m_replaceEdit;
|
||||||
QPushButton *m_findNextBtn;
|
QPushButton *m_findNextBtn;
|
||||||
@ -33,6 +69,10 @@ private:
|
|||||||
QPushButton *m_replaceAllBtn;
|
QPushButton *m_replaceAllBtn;
|
||||||
QPushButton *m_advancedBtn;
|
QPushButton *m_advancedBtn;
|
||||||
QPushButton *m_closeBtn;
|
QPushButton *m_closeBtn;
|
||||||
|
QCheckBox *m_caseSensitiveCheck;
|
||||||
|
QCheckBox *m_wholeWordOnlyCheck;
|
||||||
|
QCheckBox *m_regularExpressionCheck;
|
||||||
|
QCheckBox *m_incrementalSearchCheck;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VFINDREPLACEDIALOG_H
|
#endif // VFINDREPLACEDIALOG_H
|
||||||
|
10
src/resources/icons/find_replace.svg
Normal file
10
src/resources/icons/find_replace.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- 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">
|
||||||
|
<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">
|
||||||
|
<path d="M445,386.7l-84.8-85.9c13.8-24.1,21-50.9,21-77.9c0-87.6-71.2-158.9-158.6-158.9C135.2,64,64,135.3,64,222.9
|
||||||
|
c0,87.6,71.2,158.9,158.6,158.9c27.9,0,55.5-7.7,80.1-22.4l84.4,85.6c1.9,1.9,4.6,3.1,7.3,3.1c2.7,0,5.4-1.1,7.3-3.1l43.3-43.8
|
||||||
|
C449,397.1,449,390.7,445,386.7z M222.6,125.9c53.4,0,96.8,43.5,96.8,97c0,53.5-43.4,97-96.8,97c-53.4,0-96.8-43.5-96.8-97
|
||||||
|
C125.8,169.4,169.2,125.9,222.6,125.9z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 894 B |
@ -68,6 +68,15 @@ void VConfigManager::initialize()
|
|||||||
m_mainSplitterState = getConfigFromSettings("session", "main_splitter_state").toByteArray();
|
m_mainSplitterState = getConfigFromSettings("session", "main_splitter_state").toByteArray();
|
||||||
|
|
||||||
updateMarkdownEditStyle();
|
updateMarkdownEditStyle();
|
||||||
|
|
||||||
|
m_findCaseSensitive = getConfigFromSettings("global",
|
||||||
|
"find_case_sensitive").toBool();
|
||||||
|
m_findWholeWordOnly = getConfigFromSettings("global",
|
||||||
|
"find_whole_word_only").toBool();
|
||||||
|
m_findRegularExpression = getConfigFromSettings("global",
|
||||||
|
"find_regular_expression").toBool();
|
||||||
|
m_findIncrementalSearch = getConfigFromSettings("global",
|
||||||
|
"find_incremental_search").toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VConfigManager::readPredefinedColorsFromSettings()
|
void VConfigManager::readPredefinedColorsFromSettings()
|
||||||
|
@ -99,6 +99,18 @@ public:
|
|||||||
inline const QByteArray &getMainSplitterState() const;
|
inline const QByteArray &getMainSplitterState() const;
|
||||||
inline void setMainSplitterState(const QByteArray &p_state);
|
inline void setMainSplitterState(const QByteArray &p_state);
|
||||||
|
|
||||||
|
inline bool getFindCaseSensitive() const;
|
||||||
|
inline void setFindCaseSensitive(bool p_enabled);
|
||||||
|
|
||||||
|
inline bool getFindWholeWordOnly() const;
|
||||||
|
inline void setFindWholeWordOnly(bool p_enabled);
|
||||||
|
|
||||||
|
inline bool getFindRegularExpression() const;
|
||||||
|
inline void setFindRegularExpression(bool p_enabled);
|
||||||
|
|
||||||
|
inline bool getFindIncrementalSearch() const;
|
||||||
|
inline void setFindIncrementalSearch(bool p_enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateMarkdownEditStyle();
|
void updateMarkdownEditStyle();
|
||||||
QVariant getConfigFromSettings(const QString §ion, const QString &key);
|
QVariant getConfigFromSettings(const QString §ion, const QString &key);
|
||||||
@ -144,6 +156,12 @@ private:
|
|||||||
QByteArray m_mainWindowState;
|
QByteArray m_mainWindowState;
|
||||||
QByteArray m_mainSplitterState;
|
QByteArray m_mainSplitterState;
|
||||||
|
|
||||||
|
// Find/Replace dialog options
|
||||||
|
bool m_findCaseSensitive;
|
||||||
|
bool m_findWholeWordOnly;
|
||||||
|
bool m_findRegularExpression;
|
||||||
|
bool m_findIncrementalSearch;
|
||||||
|
|
||||||
// The name of the config file in each directory
|
// The name of the config file in each directory
|
||||||
static const QString dirConfigFileName;
|
static const QString dirConfigFileName;
|
||||||
// The name of the default configuration file
|
// The name of the default configuration file
|
||||||
@ -373,4 +391,62 @@ inline void VConfigManager::setMainSplitterState(const QByteArray &p_state)
|
|||||||
setConfigToSettings("session", "main_splitter_state", m_mainSplitterState);
|
setConfigToSettings("session", "main_splitter_state", m_mainSplitterState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getFindCaseSensitive() const
|
||||||
|
{
|
||||||
|
return m_findCaseSensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setFindCaseSensitive(bool p_enabled)
|
||||||
|
{
|
||||||
|
if (m_findCaseSensitive == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_findCaseSensitive = p_enabled;
|
||||||
|
setConfigToSettings("global", "find_case_sensitive", m_findCaseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getFindWholeWordOnly() const
|
||||||
|
{
|
||||||
|
return m_findWholeWordOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setFindWholeWordOnly(bool p_enabled)
|
||||||
|
{
|
||||||
|
if (m_findWholeWordOnly == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_findWholeWordOnly = p_enabled;
|
||||||
|
setConfigToSettings("global", "find_whole_word_only", m_findWholeWordOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getFindRegularExpression() const
|
||||||
|
{
|
||||||
|
return m_findRegularExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setFindRegularExpression(bool p_enabled)
|
||||||
|
{
|
||||||
|
if (m_findRegularExpression == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_findRegularExpression = p_enabled;
|
||||||
|
setConfigToSettings("global", "find_regular_expression",
|
||||||
|
m_findRegularExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getFindIncrementalSearch() const
|
||||||
|
{
|
||||||
|
return m_findIncrementalSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setFindIncrementalSearch(bool p_enabled)
|
||||||
|
{
|
||||||
|
if (m_findIncrementalSearch == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_findIncrementalSearch = p_enabled;
|
||||||
|
setConfigToSettings("global", "find_incremental_search",
|
||||||
|
m_findIncrementalSearch);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
164
src/vedit.cpp
164
src/vedit.cpp
@ -1,11 +1,13 @@
|
|||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QDebug>
|
||||||
#include "vedit.h"
|
#include "vedit.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "vtoc.h"
|
#include "vtoc.h"
|
||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "veditoperations.h"
|
#include "veditoperations.h"
|
||||||
|
#include "dialog/vfindreplacedialog.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
@ -82,3 +84,165 @@ void VEdit::insertImage()
|
|||||||
m_editOps->insertImage();
|
m_editOps->insertImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VEdit::findText(const QString &p_text, uint p_options, bool p_peek,
|
||||||
|
bool p_forward)
|
||||||
|
{
|
||||||
|
static int startPos = textCursor().selectionStart();
|
||||||
|
static int lastPos = startPos;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (p_text.isEmpty() && p_peek) {
|
||||||
|
// Clear previous selection
|
||||||
|
QTextCursor cursor = textCursor();
|
||||||
|
cursor.clearSelection();
|
||||||
|
cursor.setPosition(startPos);
|
||||||
|
setTextCursor(cursor);
|
||||||
|
} else {
|
||||||
|
QTextCursor cursor = textCursor();
|
||||||
|
if (p_peek) {
|
||||||
|
int curPos = cursor.selectionStart();
|
||||||
|
if (curPos != lastPos) {
|
||||||
|
// Cursor has been moved. Just start at current position.
|
||||||
|
startPos = curPos;
|
||||||
|
lastPos = curPos;
|
||||||
|
} else {
|
||||||
|
// Move cursor to startPos to search.
|
||||||
|
cursor.setPosition(startPos);
|
||||||
|
setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options
|
||||||
|
QTextDocument::FindFlags flags;
|
||||||
|
if (p_options & FindOption::CaseSensitive) {
|
||||||
|
flags |= QTextDocument::FindCaseSensitively;
|
||||||
|
}
|
||||||
|
if (p_options & FindOption::WholeWordOnly) {
|
||||||
|
flags |= QTextDocument::FindWholeWords;
|
||||||
|
}
|
||||||
|
if (!p_forward) {
|
||||||
|
flags |= QTextDocument::FindBackward;
|
||||||
|
}
|
||||||
|
// Use regular expression
|
||||||
|
if (p_options & FindOption::RegularExpression) {
|
||||||
|
QRegExp exp(p_text,
|
||||||
|
p_options & FindOption::CaseSensitive ?
|
||||||
|
Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
found = find(exp, flags);
|
||||||
|
} else {
|
||||||
|
found = find(p_text, flags);
|
||||||
|
}
|
||||||
|
cursor = textCursor();
|
||||||
|
if (!p_peek) {
|
||||||
|
startPos = cursor.selectionStart();
|
||||||
|
}
|
||||||
|
lastPos = cursor.selectionStart();
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::replaceText(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext)
|
||||||
|
{
|
||||||
|
// Options
|
||||||
|
QTextDocument::FindFlags flags;
|
||||||
|
if (p_options & FindOption::CaseSensitive) {
|
||||||
|
flags |= QTextDocument::FindCaseSensitively;
|
||||||
|
}
|
||||||
|
if (p_options & FindOption::WholeWordOnly) {
|
||||||
|
flags |= QTextDocument::FindWholeWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useRegExp = false;
|
||||||
|
QRegExp exp;
|
||||||
|
if (p_options & FindOption::RegularExpression) {
|
||||||
|
useRegExp = true;
|
||||||
|
exp = QRegExp(p_text,
|
||||||
|
p_options & FindOption::CaseSensitive ?
|
||||||
|
Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = textCursor();
|
||||||
|
if (cursor.hasSelection()) {
|
||||||
|
// Replace occurs only if the selected text matches @p_text with @p_options.
|
||||||
|
QTextCursor matchCursor;
|
||||||
|
if (useRegExp) {
|
||||||
|
matchCursor = document()->find(exp, cursor.selectionStart(),
|
||||||
|
flags);
|
||||||
|
} else {
|
||||||
|
matchCursor = document()->find(p_text, cursor.selectionStart(),
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
bool matched = (cursor.selectionStart() == matchCursor.selectionStart())
|
||||||
|
&& (cursor.selectionEnd() == matchCursor.selectionEnd());
|
||||||
|
if (matched) {
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
cursor.removeSelectedText();
|
||||||
|
cursor.insertText(p_replaceText);
|
||||||
|
cursor.endEditBlock();
|
||||||
|
setTextCursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p_findNext) {
|
||||||
|
findText(p_text, p_options, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEdit::replaceTextAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText)
|
||||||
|
{
|
||||||
|
// Options
|
||||||
|
QTextDocument::FindFlags flags;
|
||||||
|
if (p_options & FindOption::CaseSensitive) {
|
||||||
|
flags |= QTextDocument::FindCaseSensitively;
|
||||||
|
}
|
||||||
|
if (p_options & FindOption::WholeWordOnly) {
|
||||||
|
flags |= QTextDocument::FindWholeWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useRegExp = false;
|
||||||
|
QRegExp exp;
|
||||||
|
if (p_options & FindOption::RegularExpression) {
|
||||||
|
useRegExp = true;
|
||||||
|
exp = QRegExp(p_text,
|
||||||
|
p_options & FindOption::CaseSensitive ?
|
||||||
|
Qt::CaseSensitive : Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = textCursor();
|
||||||
|
int pos = cursor.position();
|
||||||
|
int nrReplaces = 0;
|
||||||
|
int startPos = 0;
|
||||||
|
int lastMatch = -1;
|
||||||
|
while (true) {
|
||||||
|
QTextCursor matchCursor;
|
||||||
|
if (useRegExp) {
|
||||||
|
matchCursor = document()->find(exp, startPos, flags);
|
||||||
|
} else {
|
||||||
|
matchCursor = document()->find(p_text, startPos, flags);
|
||||||
|
}
|
||||||
|
if (matchCursor.isNull()) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (matchCursor.selectionStart() <= lastMatch) {
|
||||||
|
// Wrap back.
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lastMatch = matchCursor.selectionStart();
|
||||||
|
}
|
||||||
|
nrReplaces++;
|
||||||
|
matchCursor.beginEditBlock();
|
||||||
|
matchCursor.removeSelectedText();
|
||||||
|
matchCursor.insertText(p_replaceText);
|
||||||
|
matchCursor.endEditBlock();
|
||||||
|
setTextCursor(matchCursor);
|
||||||
|
startPos = matchCursor.position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Restore cursor position.
|
||||||
|
cursor.setPosition(pos);
|
||||||
|
setTextCursor(cursor);
|
||||||
|
qDebug() << "replace all" << nrReplaces << "occurencs";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,12 @@ public:
|
|||||||
virtual void scrollToLine(int p_lineNumber);
|
virtual void scrollToLine(int p_lineNumber);
|
||||||
// User requests to insert an image.
|
// User requests to insert an image.
|
||||||
virtual void insertImage();
|
virtual void insertImage();
|
||||||
|
virtual bool findText(const QString &p_text, uint p_options, bool p_peek,
|
||||||
|
bool p_forward);
|
||||||
|
virtual void replaceText(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext);
|
||||||
|
virtual void replaceTextAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPointer<VFile> m_file;
|
QPointer<VFile> m_file;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
#include "dialog/vfindreplacedialog.h"
|
#include "dialog/vfindreplacedialog.h"
|
||||||
|
|
||||||
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
VEditArea::VEditArea(VNote *vnote, QWidget *parent)
|
VEditArea::VEditArea(VNote *vnote, QWidget *parent)
|
||||||
: QWidget(parent), vnote(vnote), curWindowIndex(-1)
|
: QWidget(parent), vnote(vnote), curWindowIndex(-1)
|
||||||
{
|
{
|
||||||
@ -20,6 +22,14 @@ void VEditArea::setupUI()
|
|||||||
{
|
{
|
||||||
splitter = new QSplitter(this);
|
splitter = new QSplitter(this);
|
||||||
m_findReplace = new VFindReplaceDialog(this);
|
m_findReplace = new VFindReplaceDialog(this);
|
||||||
|
m_findReplace->setOption(FindOption::CaseSensitive,
|
||||||
|
vconfig.getFindCaseSensitive());
|
||||||
|
m_findReplace->setOption(FindOption::WholeWordOnly,
|
||||||
|
vconfig.getFindWholeWordOnly());
|
||||||
|
m_findReplace->setOption(FindOption::RegularExpression,
|
||||||
|
vconfig.getFindRegularExpression());
|
||||||
|
m_findReplace->setOption(FindOption::IncrementalSearch,
|
||||||
|
vconfig.getFindIncrementalSearch());
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
mainLayout->addWidget(splitter);
|
mainLayout->addWidget(splitter);
|
||||||
@ -31,6 +41,22 @@ void VEditArea::setupUI()
|
|||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
connect(m_findReplace, &VFindReplaceDialog::findTextChanged,
|
||||||
|
this, &VEditArea::handleFindTextChanged);
|
||||||
|
connect(m_findReplace, &VFindReplaceDialog::findOptionChanged,
|
||||||
|
this, &VEditArea::handleFindOptionChanged);
|
||||||
|
connect(m_findReplace, SIGNAL(findNext(const QString &, uint, bool)),
|
||||||
|
this, SLOT(handleFindNext(const QString &, uint, bool)));
|
||||||
|
connect(m_findReplace,
|
||||||
|
SIGNAL(replace(const QString &, uint, const QString &, bool)),
|
||||||
|
this,
|
||||||
|
SLOT(handleReplace(const QString &, uint, const QString &, bool)));
|
||||||
|
connect(m_findReplace,
|
||||||
|
SIGNAL(replaceAll(const QString &, uint, const QString &)),
|
||||||
|
this,
|
||||||
|
SLOT(handleReplaceAll(const QString &, uint, const QString &)));
|
||||||
|
connect(m_findReplace, &VFindReplaceDialog::dialogClosed,
|
||||||
|
this, &VEditArea::handleFindDialogClosed);
|
||||||
m_findReplace->hide();
|
m_findReplace->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,3 +448,80 @@ void VEditArea::moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx)
|
|||||||
delete p_widget;
|
delete p_widget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only propogate the search in the IncrementalSearch case.
|
||||||
|
void VEditArea::handleFindTextChanged(const QString &p_text, uint p_options)
|
||||||
|
{
|
||||||
|
VEditTab *tab = currentEditTab();
|
||||||
|
if (tab) {
|
||||||
|
if (p_options & FindOption::IncrementalSearch) {
|
||||||
|
tab->findText(p_text, p_options, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditArea::handleFindOptionChanged(uint p_options)
|
||||||
|
{
|
||||||
|
qDebug() << "find option changed" << p_options;
|
||||||
|
vconfig.setFindCaseSensitive(p_options & FindOption::CaseSensitive);
|
||||||
|
vconfig.setFindWholeWordOnly(p_options & FindOption::WholeWordOnly);
|
||||||
|
vconfig.setFindRegularExpression(p_options & FindOption::RegularExpression);
|
||||||
|
vconfig.setFindIncrementalSearch(p_options & FindOption::IncrementalSearch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditArea::handleFindNext(const QString &p_text, uint p_options,
|
||||||
|
bool p_forward)
|
||||||
|
{
|
||||||
|
qDebug() << "find next" << p_text << p_options << p_forward;
|
||||||
|
VEditTab *tab = currentEditTab();
|
||||||
|
if (tab) {
|
||||||
|
tab->findText(p_text, p_options, false, p_forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditArea::handleReplace(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext)
|
||||||
|
{
|
||||||
|
qDebug() << "replace" << p_text << p_options << "with" << p_replaceText
|
||||||
|
<< p_findNext;
|
||||||
|
VEditTab *tab = currentEditTab();
|
||||||
|
if (tab) {
|
||||||
|
tab->replaceText(p_text, p_options, p_replaceText, p_findNext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditArea::handleReplaceAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText)
|
||||||
|
{
|
||||||
|
qDebug() << "replace all" << p_text << p_options << "with" << p_replaceText;
|
||||||
|
VEditTab *tab = currentEditTab();
|
||||||
|
if (tab) {
|
||||||
|
tab->replaceTextAll(p_text, p_options, p_replaceText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let VEditArea get focus after VFindReplaceDialog is closed.
|
||||||
|
void VEditArea::handleFindDialogClosed()
|
||||||
|
{
|
||||||
|
if (curWindowIndex == -1) {
|
||||||
|
setFocus();
|
||||||
|
} else {
|
||||||
|
getWindow(curWindowIndex)->focusWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all the selection in Web view.
|
||||||
|
int nrWin = splitter->count();
|
||||||
|
for (int i = 0; i < nrWin; ++i) {
|
||||||
|
getWindow(i)->clearFindSelectionInWebView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VEditArea::getSelectedText()
|
||||||
|
{
|
||||||
|
VEditTab *tab = currentEditTab();
|
||||||
|
if (tab) {
|
||||||
|
return tab->getSelectedText();
|
||||||
|
} else {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -40,6 +40,8 @@ public:
|
|||||||
// If fail, just delete the p_widget.
|
// If fail, just delete the p_widget.
|
||||||
void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx);
|
void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx);
|
||||||
inline VFindReplaceDialog *getFindReplaceDialog() const;
|
inline VFindReplaceDialog *getFindReplaceDialog() const;
|
||||||
|
// Return selected text of current edit tab.
|
||||||
|
QString getSelectedText();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
||||||
@ -66,6 +68,14 @@ private slots:
|
|||||||
void handleWindowFocused();
|
void handleWindowFocused();
|
||||||
void handleOutlineChanged(const VToc &toc);
|
void handleOutlineChanged(const VToc &toc);
|
||||||
void handleCurHeaderChanged(const VAnchor &anchor);
|
void handleCurHeaderChanged(const VAnchor &anchor);
|
||||||
|
void handleFindTextChanged(const QString &p_text, uint p_options);
|
||||||
|
void handleFindOptionChanged(uint p_options);
|
||||||
|
void handleFindNext(const QString &p_text, uint p_options, bool p_forward);
|
||||||
|
void handleReplace(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext);
|
||||||
|
void handleReplaceAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText);
|
||||||
|
void handleFindDialogClosed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
#include "vtoc.h"
|
#include "vtoc.h"
|
||||||
#include "vmdedit.h"
|
#include "vmdedit.h"
|
||||||
|
#include "dialog/vfindreplacedialog.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
@ -107,6 +108,7 @@ void VEditTab::showFileReadMode()
|
|||||||
previewByConverter();
|
previewByConverter();
|
||||||
}
|
}
|
||||||
setCurrentWidget(webPreviewer);
|
setCurrentWidget(webPreviewer);
|
||||||
|
clearFindSelectionInWebView();
|
||||||
scrollPreviewToHeader(outlineIndex);
|
scrollPreviewToHeader(outlineIndex);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -276,6 +278,7 @@ void VEditTab::setupMarkdownPreview()
|
|||||||
void VEditTab::focusTab()
|
void VEditTab::focusTab()
|
||||||
{
|
{
|
||||||
currentWidget()->setFocus();
|
currentWidget()->setFocus();
|
||||||
|
emit getFocused();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditTab::handleFocusChanged(QWidget * /* old */, QWidget *now)
|
void VEditTab::handleFocusChanged(QWidget * /* old */, QWidget *now)
|
||||||
@ -455,3 +458,60 @@ void VEditTab::insertImage()
|
|||||||
}
|
}
|
||||||
m_textEditor->insertImage();
|
m_textEditor->insertImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditTab::findText(const QString &p_text, uint p_options, bool p_peek,
|
||||||
|
bool p_forward)
|
||||||
|
{
|
||||||
|
if (isEditMode || !webPreviewer) {
|
||||||
|
m_textEditor->findText(p_text, p_options, p_peek, p_forward);
|
||||||
|
} else {
|
||||||
|
findTextInWebView(p_text, p_options, p_peek, p_forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditTab::replaceText(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext)
|
||||||
|
{
|
||||||
|
if (isEditMode) {
|
||||||
|
m_textEditor->replaceText(p_text, p_options, p_replaceText, p_findNext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditTab::replaceTextAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText)
|
||||||
|
{
|
||||||
|
if (isEditMode) {
|
||||||
|
m_textEditor->replaceTextAll(p_text, p_options, p_replaceText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditTab::findTextInWebView(const QString &p_text, uint p_options,
|
||||||
|
bool p_peek, bool p_forward)
|
||||||
|
{
|
||||||
|
Q_ASSERT(webPreviewer);
|
||||||
|
QWebEnginePage::FindFlags flags;
|
||||||
|
if (p_options & FindOption::CaseSensitive) {
|
||||||
|
flags |= QWebEnginePage::FindCaseSensitively;
|
||||||
|
}
|
||||||
|
if (!p_forward) {
|
||||||
|
flags |= QWebEnginePage::FindBackward;
|
||||||
|
}
|
||||||
|
webPreviewer->findText(p_text, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VEditTab::getSelectedText() const
|
||||||
|
{
|
||||||
|
if (isEditMode || !webPreviewer) {
|
||||||
|
QTextCursor cursor = m_textEditor->textCursor();
|
||||||
|
return cursor.selectedText();
|
||||||
|
} else {
|
||||||
|
return webPreviewer->selectedText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VEditTab::clearFindSelectionInWebView()
|
||||||
|
{
|
||||||
|
if (webPreviewer) {
|
||||||
|
webPreviewer->findText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -38,6 +38,16 @@ public:
|
|||||||
void scrollToAnchor(const VAnchor& anchor);
|
void scrollToAnchor(const VAnchor& anchor);
|
||||||
inline VFile *getFile();
|
inline VFile *getFile();
|
||||||
void insertImage();
|
void insertImage();
|
||||||
|
// Search @p_text in current note.
|
||||||
|
void findText(const QString &p_text, uint p_options, bool p_peek,
|
||||||
|
bool p_forward = true);
|
||||||
|
// Replace @p_text with @p_replaceText in current note.
|
||||||
|
void replaceText(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText, bool p_findNext);
|
||||||
|
void replaceTextAll(const QString &p_text, uint p_options,
|
||||||
|
const QString &p_replaceText);
|
||||||
|
QString getSelectedText() const;
|
||||||
|
void clearFindSelectionInWebView();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void getFocused();
|
void getFocused();
|
||||||
@ -65,6 +75,8 @@ private:
|
|||||||
void parseTocUl(QXmlStreamReader &xml, QVector<VHeader> &headers, int level);
|
void parseTocUl(QXmlStreamReader &xml, QVector<VHeader> &headers, int level);
|
||||||
void parseTocLi(QXmlStreamReader &xml, QVector<VHeader> &headers, int level);
|
void parseTocLi(QXmlStreamReader &xml, QVector<VHeader> &headers, int level);
|
||||||
void scrollPreviewToHeader(int p_outlineIndex);
|
void scrollPreviewToHeader(int p_outlineIndex);
|
||||||
|
void findTextInWebView(const QString &p_text, uint p_options, bool p_peek,
|
||||||
|
bool p_forward);
|
||||||
|
|
||||||
QPointer<VFile> m_file;
|
QPointer<VFile> m_file;
|
||||||
bool isEditMode;
|
bool isEditMode;
|
||||||
|
@ -362,6 +362,7 @@ void VEditWindow::focusWindow()
|
|||||||
int idx = currentIndex();
|
int idx = currentIndex();
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
setFocus();
|
setFocus();
|
||||||
|
emit getFocused();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getTab(idx)->focusTab();
|
getTab(idx)->focusTab();
|
||||||
@ -375,7 +376,7 @@ void VEditWindow::handleTabbarClicked(int /* index */)
|
|||||||
|
|
||||||
void VEditWindow::mousePressEvent(QMouseEvent *event)
|
void VEditWindow::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
emit getFocused();
|
focusWindow();
|
||||||
QTabWidget::mousePressEvent(event);
|
QTabWidget::mousePressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,3 +706,11 @@ void VEditWindow::setCurrentWindow(bool p_current)
|
|||||||
leftBtn->setIcon(QIcon(":/resources/icons/corner_tablist.svg"));
|
leftBtn->setIcon(QIcon(":/resources/icons/corner_tablist.svg"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditWindow::clearFindSelectionInWebView()
|
||||||
|
{
|
||||||
|
int nrTab = count();
|
||||||
|
for (int i = 0; i < nrTab; ++i) {
|
||||||
|
getTab(i)->clearFindSelectionInWebView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,6 +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();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
@ -48,6 +48,7 @@ void VMainWindow::setupUI()
|
|||||||
|
|
||||||
editArea = new VEditArea(vnote);
|
editArea = new VEditArea(vnote);
|
||||||
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
m_findReplaceDialog = editArea->getFindReplaceDialog();
|
||||||
fileList->setEditArea(editArea);
|
fileList->setEditArea(editArea);
|
||||||
directoryTree->setEditArea(editArea);
|
directoryTree->setEditArea(editArea);
|
||||||
notebookSelector->setEditArea(editArea);
|
notebookSelector->setEditArea(editArea);
|
||||||
@ -79,10 +80,12 @@ void VMainWindow::setupUI()
|
|||||||
editArea, &VEditArea::handleFileUpdated);
|
editArea, &VEditArea::handleFileUpdated);
|
||||||
connect(editArea, &VEditArea::curTabStatusChanged,
|
connect(editArea, &VEditArea::curTabStatusChanged,
|
||||||
this, &VMainWindow::handleCurTabStatusChanged);
|
this, &VMainWindow::handleCurTabStatusChanged);
|
||||||
|
connect(m_findReplaceDialog, &VFindReplaceDialog::findTextChanged,
|
||||||
|
this, &VMainWindow::handleFindDialogTextChanged);
|
||||||
|
|
||||||
setCentralWidget(mainSplitter);
|
setCentralWidget(mainSplitter);
|
||||||
// TODO: Create and show the status bar
|
// Create and show the status bar
|
||||||
// statusBar();
|
statusBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *VMainWindow::setupDirectoryPanel()
|
QWidget *VMainWindow::setupDirectoryPanel()
|
||||||
@ -179,7 +182,7 @@ void VMainWindow::initFileToolBar()
|
|||||||
newNoteAct = new QAction(QIcon(":/resources/icons/create_note_tb.svg"),
|
newNoteAct = new QAction(QIcon(":/resources/icons/create_note_tb.svg"),
|
||||||
tr("New &Note"), this);
|
tr("New &Note"), this);
|
||||||
newNoteAct->setStatusTip(tr("Create a note in current directory"));
|
newNoteAct->setStatusTip(tr("Create a note in current directory"));
|
||||||
newNoteAct->setShortcut(QKeySequence("Ctrl+N"));
|
newNoteAct->setShortcut(QKeySequence::New);
|
||||||
connect(newNoteAct, &QAction::triggered,
|
connect(newNoteAct, &QAction::triggered,
|
||||||
fileList, &VFileList::newFile);
|
fileList, &VFileList::newFile);
|
||||||
|
|
||||||
@ -325,13 +328,49 @@ void VMainWindow::initEditMenu()
|
|||||||
{
|
{
|
||||||
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
||||||
|
|
||||||
// Inser image.
|
// Insert image.
|
||||||
QAction *insertImageAct = new QAction(QIcon(":/resources/icons/insert_image.svg"),
|
m_insertImageAct = new QAction(QIcon(":/resources/icons/insert_image.svg"),
|
||||||
tr("Insert &Image"), this);
|
tr("Insert &Image"), this);
|
||||||
insertImageAct->setStatusTip(tr("Insert an image from file in current note"));
|
m_insertImageAct->setStatusTip(tr("Insert an image from file in current note"));
|
||||||
connect(insertImageAct, &QAction::triggered,
|
connect(m_insertImageAct, &QAction::triggered,
|
||||||
this, &VMainWindow::insertImage);
|
this, &VMainWindow::insertImage);
|
||||||
|
|
||||||
|
// Find/Replace.
|
||||||
|
m_findReplaceAct = new QAction(QIcon(":/resources/icons/find_replace.svg"),
|
||||||
|
tr("Find/Replace"), this);
|
||||||
|
m_findReplaceAct->setStatusTip(tr("Open Find/Replace dialog to search in current note"));
|
||||||
|
m_findReplaceAct->setShortcut(QKeySequence::Find);
|
||||||
|
connect(m_findReplaceAct, &QAction::triggered,
|
||||||
|
this, &VMainWindow::openFindDialog);
|
||||||
|
|
||||||
|
m_findNextAct = new QAction(tr("Find Next"), this);
|
||||||
|
m_findNextAct->setStatusTip(tr("Find next occurence"));
|
||||||
|
m_findNextAct->setShortcut(QKeySequence::FindNext);
|
||||||
|
connect(m_findNextAct, SIGNAL(triggered(bool)),
|
||||||
|
m_findReplaceDialog, SLOT(findNext()));
|
||||||
|
|
||||||
|
m_findPreviousAct = new QAction(tr("Find Previous"), this);
|
||||||
|
m_findPreviousAct->setStatusTip(tr("Find previous occurence"));
|
||||||
|
m_findPreviousAct->setShortcut(QKeySequence::FindPrevious);
|
||||||
|
connect(m_findPreviousAct, SIGNAL(triggered(bool)),
|
||||||
|
m_findReplaceDialog, SLOT(findPrevious()));
|
||||||
|
|
||||||
|
m_replaceAct = new QAction(tr("Replace"), this);
|
||||||
|
m_replaceAct->setStatusTip(tr("Replace current occurence"));
|
||||||
|
m_replaceAct->setShortcut(QKeySequence::Replace);
|
||||||
|
connect(m_replaceAct, SIGNAL(triggered(bool)),
|
||||||
|
m_findReplaceDialog, SLOT(replace()));
|
||||||
|
|
||||||
|
m_replaceFindAct = new QAction(tr("Replace && Find"), this);
|
||||||
|
m_replaceFindAct->setStatusTip(tr("Replace current occurence and find the next one"));
|
||||||
|
connect(m_replaceFindAct, SIGNAL(triggered(bool)),
|
||||||
|
m_findReplaceDialog, SLOT(replaceFind()));
|
||||||
|
|
||||||
|
m_replaceAllAct = new QAction(tr("Replace All"), this);
|
||||||
|
m_replaceAllAct->setStatusTip(tr("Replace all occurences in current note"));
|
||||||
|
connect(m_replaceAllAct, SIGNAL(triggered(bool)),
|
||||||
|
m_findReplaceDialog, SLOT(replaceAll()));
|
||||||
|
|
||||||
// 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"));
|
||||||
@ -364,8 +403,25 @@ void VMainWindow::initEditMenu()
|
|||||||
this, &VMainWindow::changeHighlightCursorLine);
|
this, &VMainWindow::changeHighlightCursorLine);
|
||||||
|
|
||||||
|
|
||||||
editMenu->addAction(insertImageAct);
|
editMenu->addAction(m_insertImageAct);
|
||||||
editMenu->addSeparator();
|
editMenu->addSeparator();
|
||||||
|
m_insertImageAct->setEnabled(false);
|
||||||
|
|
||||||
|
QMenu *findReplaceMenu = editMenu->addMenu(tr("Find/Replace"));
|
||||||
|
findReplaceMenu->addAction(m_findReplaceAct);
|
||||||
|
findReplaceMenu->addAction(m_findNextAct);
|
||||||
|
findReplaceMenu->addAction(m_findPreviousAct);
|
||||||
|
findReplaceMenu->addAction(m_replaceAct);
|
||||||
|
findReplaceMenu->addAction(m_replaceFindAct);
|
||||||
|
findReplaceMenu->addAction(m_replaceAllAct);
|
||||||
|
editMenu->addSeparator();
|
||||||
|
m_findReplaceAct->setEnabled(false);
|
||||||
|
m_findNextAct->setEnabled(false);
|
||||||
|
m_findPreviousAct->setEnabled(false);
|
||||||
|
m_replaceAct->setEnabled(false);
|
||||||
|
m_replaceFindAct->setEnabled(false);
|
||||||
|
m_replaceAllAct->setEnabled(false);
|
||||||
|
|
||||||
editMenu->addAction(expandTabAct);
|
editMenu->addAction(expandTabAct);
|
||||||
if (vconfig.getIsExpandTab()) {
|
if (vconfig.getIsExpandTab()) {
|
||||||
expandTabAct->setChecked(true);
|
expandTabAct->setChecked(true);
|
||||||
@ -588,36 +644,56 @@ void VMainWindow::setRenderBackgroundColor(QAction *action)
|
|||||||
vnote->updateTemplate();
|
vnote->updateTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::updateToolbarFromTabChage(const VFile *p_file, bool p_editMode)
|
void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
|
||||||
|
bool p_editMode)
|
||||||
{
|
{
|
||||||
qDebug() << "update toolbar";
|
if (p_file) {
|
||||||
if (!p_file) {
|
if (p_editMode) {
|
||||||
|
editNoteAct->setVisible(false);
|
||||||
|
saveExitAct->setVisible(true);
|
||||||
|
saveNoteAct->setVisible(true);
|
||||||
|
deleteNoteAct->setEnabled(true);
|
||||||
|
|
||||||
|
m_insertImageAct->setEnabled(true);
|
||||||
|
} else {
|
||||||
|
editNoteAct->setVisible(true);
|
||||||
|
saveExitAct->setVisible(false);
|
||||||
|
saveNoteAct->setVisible(false);
|
||||||
|
deleteNoteAct->setEnabled(true);
|
||||||
|
|
||||||
|
m_insertImageAct->setEnabled(false);
|
||||||
|
m_replaceAct->setEnabled(false);
|
||||||
|
m_replaceFindAct->setEnabled(false);
|
||||||
|
m_replaceAllAct->setEnabled(false);
|
||||||
|
}
|
||||||
|
noteInfoAct->setEnabled(true);
|
||||||
|
|
||||||
|
m_findReplaceAct->setEnabled(true);
|
||||||
|
} else {
|
||||||
editNoteAct->setVisible(false);
|
editNoteAct->setVisible(false);
|
||||||
saveExitAct->setVisible(false);
|
saveExitAct->setVisible(false);
|
||||||
saveNoteAct->setVisible(false);
|
saveNoteAct->setVisible(false);
|
||||||
deleteNoteAct->setEnabled(false);
|
deleteNoteAct->setEnabled(false);
|
||||||
} else if (p_editMode) {
|
|
||||||
editNoteAct->setVisible(false);
|
|
||||||
saveExitAct->setVisible(true);
|
|
||||||
saveNoteAct->setVisible(true);
|
|
||||||
deleteNoteAct->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
editNoteAct->setVisible(true);
|
|
||||||
saveExitAct->setVisible(false);
|
|
||||||
saveNoteAct->setVisible(false);
|
|
||||||
deleteNoteAct->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_file) {
|
|
||||||
noteInfoAct->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
noteInfoAct->setEnabled(false);
|
noteInfoAct->setEnabled(false);
|
||||||
|
|
||||||
|
m_insertImageAct->setEnabled(false);
|
||||||
|
// Find/Replace
|
||||||
|
m_findReplaceAct->setEnabled(false);
|
||||||
|
m_findNextAct->setEnabled(false);
|
||||||
|
m_findPreviousAct->setEnabled(false);
|
||||||
|
m_replaceAct->setEnabled(false);
|
||||||
|
m_replaceFindAct->setEnabled(false);
|
||||||
|
m_replaceAllAct->setEnabled(false);
|
||||||
|
m_findReplaceDialog->closeDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode)
|
void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode)
|
||||||
{
|
{
|
||||||
updateToolbarFromTabChage(p_file, p_editMode);
|
updateActionStateFromTabStatusChange(p_file, p_editMode);
|
||||||
|
if (p_file) {
|
||||||
|
m_findReplaceDialog->updateState(p_file->getDocType(), p_editMode);
|
||||||
|
}
|
||||||
|
|
||||||
QString title;
|
QString title;
|
||||||
if (p_file) {
|
if (p_file) {
|
||||||
@ -761,7 +837,7 @@ void VMainWindow::resizeEvent(QResizeEvent *event)
|
|||||||
void VMainWindow::keyPressEvent(QKeyEvent *event)
|
void VMainWindow::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
if (event->key() == Qt::Key_Escape) {
|
if (event->key() == Qt::Key_Escape) {
|
||||||
editArea->getFindReplaceDialog()->closeDialog();
|
m_findReplaceDialog->closeDialog();
|
||||||
event->accept();
|
event->accept();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -809,3 +885,21 @@ void VMainWindow::locateFile(VFile *p_file) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMainWindow::handleFindDialogTextChanged(const QString &p_text, uint /* p_options */)
|
||||||
|
{
|
||||||
|
bool enabled = true;
|
||||||
|
if (p_text.isEmpty()) {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
m_findNextAct->setEnabled(enabled);
|
||||||
|
m_findPreviousAct->setEnabled(enabled);
|
||||||
|
m_replaceAct->setEnabled(enabled);
|
||||||
|
m_replaceFindAct->setEnabled(enabled);
|
||||||
|
m_replaceAllAct->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMainWindow::openFindDialog()
|
||||||
|
{
|
||||||
|
m_findReplaceDialog->openDialog(editArea->getSelectedText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ class QToolBox;
|
|||||||
class VOutline;
|
class VOutline;
|
||||||
class VNotebookSelector;
|
class VNotebookSelector;
|
||||||
class VAvatar;
|
class VAvatar;
|
||||||
|
class VFindReplaceDialog;
|
||||||
|
|
||||||
class VMainWindow : public QMainWindow
|
class VMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
@ -55,6 +56,8 @@ private slots:
|
|||||||
void handleCurrentDirectoryChanged(const VDirectory *p_dir);
|
void handleCurrentDirectoryChanged(const VDirectory *p_dir);
|
||||||
void handleCurrentNotebookChanged(const VNotebook *p_notebook);
|
void handleCurrentNotebookChanged(const VNotebook *p_notebook);
|
||||||
void insertImage();
|
void insertImage();
|
||||||
|
void handleFindDialogTextChanged(const QString &p_text, uint p_options);
|
||||||
|
void openFindDialog();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
|
||||||
@ -83,7 +86,8 @@ private:
|
|||||||
void initEditorBackgroundMenu(QMenu *menu);
|
void initEditorBackgroundMenu(QMenu *menu);
|
||||||
void changeSplitterView(int nrPanel);
|
void changeSplitterView(int nrPanel);
|
||||||
void updateWindowTitle(const QString &str);
|
void updateWindowTitle(const QString &str);
|
||||||
void updateToolbarFromTabChage(const VFile *p_file, bool p_editMode);
|
void updateActionStateFromTabStatusChange(const VFile *p_file,
|
||||||
|
bool p_editMode);
|
||||||
void saveStateAndGeometry();
|
void saveStateAndGeometry();
|
||||||
void restoreStateAndGeometry();
|
void restoreStateAndGeometry();
|
||||||
void repositionAvatar();
|
void repositionAvatar();
|
||||||
@ -103,6 +107,7 @@ private:
|
|||||||
QToolBox *toolBox;
|
QToolBox *toolBox;
|
||||||
VOutline *outline;
|
VOutline *outline;
|
||||||
VAvatar *m_avatar;
|
VAvatar *m_avatar;
|
||||||
|
VFindReplaceDialog *m_findReplaceDialog;
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
QAction *newRootDirAct;
|
QAction *newRootDirAct;
|
||||||
@ -115,6 +120,14 @@ private:
|
|||||||
QAction *discardExitAct;
|
QAction *discardExitAct;
|
||||||
QAction *expandViewAct;
|
QAction *expandViewAct;
|
||||||
|
|
||||||
|
QAction *m_insertImageAct;
|
||||||
|
QAction *m_findReplaceAct;
|
||||||
|
QAction *m_findNextAct;
|
||||||
|
QAction *m_findPreviousAct;
|
||||||
|
QAction *m_replaceAct;
|
||||||
|
QAction *m_replaceFindAct;
|
||||||
|
QAction *m_replaceAllAct;
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
QMenu *viewMenu;
|
QMenu *viewMenu;
|
||||||
|
|
||||||
|
@ -287,6 +287,7 @@ bool VMdEditOperations::handleKeyBracketLeft(QKeyEvent *p_event)
|
|||||||
// 1. If it is not in Normal state, just go back to Normal state;
|
// 1. If it is not in Normal state, just go back to Normal state;
|
||||||
// 2. If it is already Normal state, try to clear selection;
|
// 2. If it is already Normal state, try to clear selection;
|
||||||
// 3. Anyway, we accept this event.
|
// 3. Anyway, we accept this event.
|
||||||
|
bool accept = false;
|
||||||
if (p_event->modifiers() == Qt::ControlModifier) {
|
if (p_event->modifiers() == Qt::ControlModifier) {
|
||||||
if (m_keyState != KeyState::Normal) {
|
if (m_keyState != KeyState::Normal) {
|
||||||
m_pendingTimer->stop();
|
m_pendingTimer->stop();
|
||||||
@ -299,9 +300,12 @@ bool VMdEditOperations::handleKeyBracketLeft(QKeyEvent *p_event)
|
|||||||
m_editor->setTextCursor(cursor);
|
m_editor->setTextCursor(cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
accept = true;
|
||||||
}
|
}
|
||||||
p_event->accept();
|
if (accept) {
|
||||||
return true;
|
p_event->accept();
|
||||||
|
}
|
||||||
|
return accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event)
|
bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event)
|
||||||
|
@ -82,5 +82,6 @@
|
|||||||
<file>resources/icons/corner_menu_cur.svg</file>
|
<file>resources/icons/corner_menu_cur.svg</file>
|
||||||
<file>resources/icons/corner_tablist_cur.svg</file>
|
<file>resources/icons/corner_tablist_cur.svg</file>
|
||||||
<file>resources/icons/close.svg</file>
|
<file>resources/icons/close.svg</file>
|
||||||
|
<file>resources/icons/find_replace.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user