Enhancements to search and replace in macro editor.

This commit is contained in:
Matthias Koefferlein 2021-02-13 19:13:22 +01:00
parent 0f8dc9ac13
commit 92d36868bb
5 changed files with 412 additions and 332 deletions

View File

@ -1383,63 +1383,6 @@ p, li { white-space: pre-wrap; }
</widget>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Close</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
<action name="actionNewFolder">
<property name="icon">
@ -1596,22 +1539,5 @@ p, li { white-space: pre-wrap; }
<resources>
<include location="layResources.qrc"/>
</resources>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>MacroEditorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>905</x>
<y>694</y>
</hint>
<hint type="destinationlabel">
<x>929</x>
<y>696</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -355,8 +355,8 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
QMenu *m = new QMenu (searchEditBox);
m->addAction (actionUseRegularExpressions);
m->addAction (actionCaseSensitive);
connect (actionUseRegularExpressions, SIGNAL (triggered ()), this, SLOT (apply_search ()));
connect (actionCaseSensitive, SIGNAL (triggered ()), this, SLOT (apply_search ()));
connect (actionUseRegularExpressions, SIGNAL (triggered ()), this, SLOT (search_editing ()));
connect (actionCaseSensitive, SIGNAL (triggered ()), this, SLOT (search_editing ()));
addAction (actionSearchReplace);
connect (actionSearchReplace, SIGNAL (triggered ()), this, SLOT (search_replace ()));
@ -364,7 +364,11 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
searchEditBox->set_clear_button_enabled (true);
searchEditBox->set_options_button_enabled (true);
searchEditBox->set_options_menu (m);
searchEditBox->set_escape_signal_enabled (true);
searchEditBox->set_tab_signal_enabled (true);
replaceText->set_clear_button_enabled (true);
replaceText->set_escape_signal_enabled (true);
replaceText->set_tab_signal_enabled (true);
#if QT_VERSION >= 0x40700
searchEditBox->setPlaceholderText (tr ("Find text ..."));
replaceText->setPlaceholderText (tr ("Replace text ..."));
@ -382,8 +386,6 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
tabWidget->setMovable (true);
tabWidget->setTabsClosable (true);
connect (tabWidget, SIGNAL (tabCloseRequested (int)), this, SLOT (tab_close_requested (int)));
closeButton->hide ();
closeButtonSeparator->hide ();
#endif
dbgOn->setEnabled (true);
@ -411,7 +413,6 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
connect (helpButton, SIGNAL (clicked ()), this, SLOT (help_button_clicked ()));
connect (addButton, SIGNAL (clicked ()), this, SLOT (add_button_clicked ()));
connect (actionAddMacro, SIGNAL (triggered ()), this, SLOT (add_button_clicked ()));
connect (closeButton, SIGNAL (clicked ()), this, SLOT (close_button_clicked ()));
connect (deleteButton, SIGNAL (clicked ()), this, SLOT (delete_button_clicked ()));
connect (actionDelete, SIGNAL (triggered ()), this, SLOT (delete_button_clicked ()));
connect (renameButton, SIGNAL (clicked ()), this, SLOT (rename_button_clicked ()));
@ -438,9 +439,16 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
connect (callStack, SIGNAL (itemDoubleClicked (QListWidgetItem *)), this, SLOT (stack_element_double_clicked (QListWidgetItem *)));
connect (singleStepButton, SIGNAL (clicked ()), this, SLOT (single_step_button_clicked ()));
connect (nextStepButton, SIGNAL (clicked ()), this, SLOT (next_step_button_clicked ()));
connect (searchEditBox, SIGNAL (textEdited (const QString &)), this, SLOT (search_editing ()));
connect (searchEditBox, SIGNAL (returnPressed ()), this, SLOT (search_edited ()));
connect (searchEditBox, SIGNAL (editingFinished ()), this, SLOT (search_edited ()));
connect (searchEditBox, SIGNAL (textEdited (QString)), this, SLOT (apply_search ()));
connect (searchEditBox, SIGNAL (esc_pressed ()), this, SLOT (search_finished ()));
connect (searchEditBox, SIGNAL (tab_pressed ()), this, SLOT (find_next_button_clicked ()));
connect (searchEditBox, SIGNAL (backtab_pressed ()), this, SLOT (find_prev_button_clicked ()));
connect (replaceText, SIGNAL (esc_pressed ()), this, SLOT (search_finished ()));
connect (replaceText, SIGNAL (tab_pressed ()), this, SLOT (find_next_button_clicked ()));
connect (replaceText, SIGNAL (backtab_pressed ()), this, SLOT (find_prev_button_clicked ()));
connect (replaceText, SIGNAL (returnPressed ()), this, SLOT (replace_next_button_clicked ()));
connect (replaceModeButton, SIGNAL (clicked ()), this, SLOT (replace_mode_button_clicked ()));
connect (replaceNextButton, SIGNAL (clicked ()), this, SLOT (replace_next_button_clicked ()));
connect (findNextButton, SIGNAL (clicked ()), this, SLOT (find_next_button_clicked ()));
@ -946,15 +954,13 @@ MacroEditorDialog::showEvent (QShowEvent *)
void
MacroEditorDialog::reject ()
{
closeEvent (0);
QDialog::reject ();
// .. ignore Esc ..
}
void
MacroEditorDialog::accept ()
{
closeEvent (0);
QDialog::accept ();
// .. ignore Enter ..
}
void
@ -1105,12 +1111,6 @@ MacroEditorDialog::can_exit ()
return true;
}
void
MacroEditorDialog::search_replace ()
{
searchEditBox->setFocus (Qt::TabFocusReason);
}
void
MacroEditorDialog::add_edit_trace (bool compress)
{
@ -1882,6 +1882,18 @@ BEGIN_PROTECTED
END_PROTECTED
}
void
MacroEditorDialog::set_editor_focus ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
if (! page) {
return;
}
QSignalBlocker signal_blocker (searchEditBox);
page->set_editor_focus ();
}
void
MacroEditorDialog::replace_mode_button_clicked ()
{
@ -1905,10 +1917,27 @@ MacroEditorDialog::find_next_button_clicked ()
apply_search (true);
page->find_next ();
page->set_editor_focus ();
if (sender () != searchEditBox && sender () != replaceText) {
set_editor_focus ();
}
}
void
void
MacroEditorDialog::find_prev_button_clicked ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
if (! page) {
return;
}
apply_search (true);
page->find_prev ();
if (sender () != searchEditBox && sender () != replaceText) {
set_editor_focus ();
}
}
void
MacroEditorDialog::replace_next_button_clicked ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
@ -1918,10 +1947,12 @@ MacroEditorDialog::replace_next_button_clicked ()
apply_search (true);
page->replace_and_find_next (replaceText->text ());
page->set_editor_focus ();
if (sender () != replaceText) {
set_editor_focus ();
}
}
void
void
MacroEditorDialog::replace_all_button_clicked ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
@ -1931,7 +1962,34 @@ MacroEditorDialog::replace_all_button_clicked ()
apply_search (true);
page->replace_all (replaceText->text ());
page->set_editor_focus ();
set_editor_focus ();
}
void
MacroEditorDialog::search_requested (const QString &s)
{
searchEditBox->setText (s);
searchEditBox->setFocus ();
search_editing ();
}
void
MacroEditorDialog::search_replace ()
{
searchEditBox->setFocus (Qt::TabFocusReason);
}
void
MacroEditorDialog::search_editing ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
if (! page) {
return;
}
apply_search ();
page->find_reset (); // search from the initial position
page->find_next ();
}
void
@ -1942,6 +2000,18 @@ MacroEditorDialog::search_edited ()
md_search_edited ();
}
void
MacroEditorDialog::search_finished ()
{
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
if (! page) {
return;
}
page->find_reset (); // search from the initial position
set_editor_focus ();
}
void
MacroEditorDialog::do_search_edited ()
{
@ -1951,8 +2021,9 @@ MacroEditorDialog::do_search_edited ()
}
apply_search ();
page->find_reset (); // search from the initial position
page->find_next ();
page->set_editor_focus ();
set_editor_focus ();
}
void
@ -1963,7 +2034,7 @@ MacroEditorDialog::apply_search (bool if_needed)
return;
}
if (searchEditBox->text ().size () > 0) {
if (! searchEditBox->text ().isEmpty ()) {
QRegExp re (searchEditBox->text (),
actionCaseSensitive->isChecked () ? Qt::CaseSensitive : Qt::CaseInsensitive,
actionUseRegularExpressions->isChecked () ? QRegExp::RegExp : QRegExp::FixedString);
@ -2080,7 +2151,7 @@ BEGIN_PROTECTED
END_PROTECTED
}
void
void
MacroEditorDialog::help_requested(const QString &s)
{
lay::MainWindow::instance ()->show_assistant_topic (tl::to_string (s));
@ -3172,7 +3243,6 @@ MacroEditorDialog::do_update_ui_to_run_mode ()
addButton->setEnabled (! m_in_exec);
actionAddMacro->setEnabled (! m_in_exec);
closeButton->setEnabled (! m_in_exec);
deleteButton->setEnabled (! m_in_exec);
actionDelete->setEnabled (! m_in_exec);
renameButton->setEnabled (! m_in_exec);
@ -3270,6 +3340,7 @@ MacroEditorDialog::create_page (lym::Macro *macro)
editor->exec_model ()->set_run_mode (m_in_exec);
editor->connect_macro (macro);
connect (editor.get (), SIGNAL (help_requested (const QString &)), this, SLOT (help_requested (const QString &)));
connect (editor.get (), SIGNAL (search_requested (const QString &)), this, SLOT (search_requested (const QString &)));
connect (editor.get (), SIGNAL (edit_trace (bool)), this, SLOT (add_edit_trace (bool)));
return editor.release ();
}

View File

@ -209,12 +209,16 @@ private slots:
void commit ();
void stack_element_double_clicked (QListWidgetItem *item);
void search_edited ();
void search_editing ();
void search_finished ();
void tab_close_requested (int);
void replace_mode_button_clicked ();
void replace_next_button_clicked ();
void replace_all_button_clicked ();
void find_next_button_clicked ();
void find_prev_button_clicked ();
void help_requested (const QString &s);
void search_requested (const QString &s);
void macro_changed (lym::Macro *macro);
void macro_deleted (lym::Macro *macro);
void macro_collection_deleted (lym::MacroCollection *collection);
@ -288,6 +292,7 @@ private:
void update_watches ();
lym::Macro *new_macro ();
void do_search_edited ();
void set_editor_focus ();
void select_trace (size_t index);
bool configure (const std::string &name, const std::string &value);
void config_finalize ();

View File

@ -475,7 +475,7 @@ void MacroEditorSidePanel::paintEvent (QPaintEvent *)
// MacroEditorPage implementation
MacroEditorPage::MacroEditorPage (QWidget * /*parent*/, MacroEditorHighlighters *highlighters)
: mp_macro (0), mp_highlighters (highlighters), mp_highlighter (0), m_error_line (-1), m_ntab (8), m_nindent (2)
: mp_macro (0), mp_highlighters (highlighters), mp_highlighter (0), m_error_line (-1), m_ntab (8), m_nindent (2), m_ignore_cursor_changed_event (false)
{
QVBoxLayout *layout = new QVBoxLayout (this);
@ -600,7 +600,12 @@ static bool valid_element (const SyntaxHighlighterElement &e)
void MacroEditorPage::cursor_position_changed ()
{
if (m_ignore_cursor_changed_event) {
return;
}
QTextCursor cursor = mp_text->textCursor ();
m_edit_cursor = cursor;
// prepare a format for the bracket highlights
QTextCharFormat fmt;
@ -861,11 +866,23 @@ void MacroEditorPage::connect_macro (lym::Macro *macro)
}
}
void
MacroEditorPage::find_reset ()
{
m_ignore_cursor_changed_event = true;
mp_text->setTextCursor (m_edit_cursor);
m_ignore_cursor_changed_event = false;
}
bool
MacroEditorPage::find_prev ()
{
update_extra_selections ();
if (m_current_search == QRegExp ()) {
return false;
}
QTextCursor c = mp_text->textCursor ();
bool first = true;
@ -891,7 +908,9 @@ MacroEditorPage::find_prev ()
QTextCursor newc (b);
newc.setPosition (i + b.position () + l);
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
m_ignore_cursor_changed_event = true;
mp_text->setTextCursor (newc);
m_ignore_cursor_changed_event = false;
return true;
}
@ -913,6 +932,10 @@ MacroEditorPage::find_next ()
{
update_extra_selections ();
if (m_current_search == QRegExp ()) {
return false;
}
QTextCursor c = mp_text->textCursor ();
bool first = true;
@ -926,7 +949,9 @@ MacroEditorPage::find_next ()
QTextCursor newc (b);
newc.setPosition (i + b.position () + m_current_search.matchedLength ());
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
m_ignore_cursor_changed_event = true;
mp_text->setTextCursor (newc);
m_ignore_cursor_changed_event = false;
emit edit_trace (false);
return true;
}
@ -1152,225 +1177,289 @@ MacroEditorPage::current_pos () const
return mp_text->textCursor ().position () - mp_text->textCursor ().block ().position ();
}
bool
MacroEditorPage::tab_key_pressed ()
{
if (mp_text->isReadOnly ()) {
return false;
}
QTextBlock bs, be;
bool adjust_end = false;
bool indent = false;
if (mp_text->textCursor ().hasSelection ()) {
bs = mp_text->document ()->findBlock (mp_text->textCursor ().selectionStart ());
be = mp_text->document ()->findBlock (mp_text->textCursor ().selectionEnd ());
if (be != bs) {
indent = true;
QTextCursor se (mp_text->document ());
se.setPosition (mp_text->textCursor ().selectionEnd ());
if (se.atBlockStart ()) {
be = be.previous ();
adjust_end = true;
}
}
}
if (indent) {
// tab out
QTextCursor c (mp_text->document ());
c.setPosition (bs.position ());
c.beginEditBlock ();
for (QTextBlock b = bs; ; b = b.next()) {
c.setPosition (b.position ());
QString text = b.text ();
bool has_tabs = false;
int p = 0;
int i = 0;
for (; i < text.length (); ++i) {
if (text [i] == QChar::fromLatin1 (' ')) {
++p;
} else if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
has_tabs = true;
} else {
break;
}
}
if (has_tabs) {
for ( ; i > 0; --i) {
c.deleteChar ();
}
c.insertText (QString (m_nindent + p, QChar::fromLatin1 (' ')));
} else {
c.insertText (QString (m_nindent, QChar::fromLatin1 (' ')));
}
if (b == be) {
break;
}
}
c.endEditBlock ();
c.setPosition (bs.position ());
if (adjust_end) {
c.setPosition (be.next ().position (), QTextCursor::KeepAnchor);
} else {
c.setPosition (be.position () + be.text ().length (), QTextCursor::KeepAnchor);
}
mp_text->setTextCursor (c);
} else {
QTextCursor c = mp_text->textCursor ();
QString text = c.block ().text ();
int col = c.position () - c.block ().position ();
int p = 0;
for (int i = 0; i < text.length () && i < col; ++i) {
if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
} else {
++p;
}
}
c.insertText (QString (m_nindent - p % m_nindent, QChar::fromLatin1 (' ')));
mp_text->setTextCursor (c);
}
return true;
}
bool
MacroEditorPage::back_tab_key_pressed ()
{
if (!mp_text->textCursor ().hasSelection () || mp_text->isReadOnly ()) {
return false;
}
// tab in
QTextBlock bs = mp_text->document ()->findBlock (mp_text->textCursor ().selectionStart ());
QTextBlock be = mp_text->document ()->findBlock (mp_text->textCursor ().selectionEnd ());
bool adjust_end = false;
if (be != bs) {
QTextCursor se (mp_text->document ());
se.setPosition (mp_text->textCursor ().selectionEnd ());
if (se.atBlockStart ()) {
be = be.previous ();
adjust_end = true;
}
}
QTextCursor c (mp_text->document ());
c.setPosition (bs.position ());
c.beginEditBlock ();
for (QTextBlock b = bs; ; b = b.next()) {
c.setPosition (b.position ());
QString text = b.text ();
int n = m_nindent;
int p = 0;
for (int i = 0; i < text.length () && n > 0; ++i) {
if (text [i] == QChar::fromLatin1 (' ')) {
++p;
--n;
c.deleteChar ();
} else if (text [i] == QChar::fromLatin1 ('\t')) {
c.deleteChar ();
int pp = p;
p = (p - p % m_ntab) + m_ntab;
if (p - pp >= n) {
if (p - pp > n) {
c.insertText (QString (p - pp - n, QChar::fromLatin1 (' ')));
}
n = 0;
} else {
n -= p - pp;
}
} else {
break;
}
}
if (b == be) {
break;
}
}
c.endEditBlock ();
c.setPosition (bs.position ());
if (adjust_end) {
c.setPosition (be.next ().position (), QTextCursor::KeepAnchor);
} else {
c.setPosition (be.position () + be.text ().length (), QTextCursor::KeepAnchor);
}
mp_text->setTextCursor (c);
return true;
}
bool
MacroEditorPage::backspace_pressed ()
{
if (mp_text->textCursor ().hasSelection () || mp_text->isReadOnly()) {
return false;
}
QTextCursor c = mp_text->textCursor ();
QString text = c.block ().text ();
int col = c.position () - c.block ().position ();
if (col > 0) {
int p = 0;
bool only_space_before = true;
for (int i = 0; i < text.length () && i < col; ++i) {
if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
} else if (text [i] == QChar::fromLatin1 (' ')) {
++p;
} else {
only_space_before = false;
}
}
if (only_space_before) {
for (int i = 0; i < col; ++i) {
c.deletePreviousChar ();
}
c.insertText (QString (std::max (0, ((p - 1) / m_nindent) * m_nindent), QChar::fromLatin1 (' ')));
mp_text->setTextCursor (c);
return true;
}
}
return false;
}
bool
MacroEditorPage::return_pressed ()
{
if (mp_text->isReadOnly ()) {
return false;
}
// Implement auto-indent on return
QTextCursor c = mp_text->textCursor ();
QTextBlock b = c.block ();
c.insertBlock ();
QString l;
if (b.isValid ()) {
QString text = b.text ();
for (int i = 0; i < text.length (); ++i) {
if (text [i] == QChar::fromLatin1 ('\t') || text [i] == QChar::fromLatin1 (' ')) {
l += text [i];
} else {
break;
}
}
}
c.insertText (l);
mp_text->setTextCursor (c);
return true;
}
bool
MacroEditorPage::eventFilter (QObject *watched, QEvent *event)
{
if (watched == mp_text) {
if (event->type () == QEvent::KeyPress) {
if (event->type () == QEvent::ShortcutOverride) {
// override shortcuts
event->accept ();
return true;
} else if (event->type () == QEvent::KeyPress) {
m_error_line = -1;
mp_text->setExtraSelections (QList<QTextEdit::ExtraSelection> ());
QKeyEvent *ke = dynamic_cast<QKeyEvent *> (event);
if (ke && ke->key () == Qt::Key_Tab && (ke->modifiers () & Qt::ShiftModifier) == 0) {
if (! ke) {
return false; // should not happen
}
if (!mp_text->isReadOnly ()) {
if (ke->key () == Qt::Key_Tab && (ke->modifiers () & Qt::ShiftModifier) == 0) {
QTextBlock bs, be;
bool adjust_end = false;
return tab_key_pressed ();
bool indent = false;
if (mp_text->textCursor ().hasSelection ()) {
bs = mp_text->document ()->findBlock (mp_text->textCursor ().selectionStart ());
be = mp_text->document ()->findBlock (mp_text->textCursor ().selectionEnd ());
if (be != bs) {
indent = true;
QTextCursor se (mp_text->document ());
se.setPosition (mp_text->textCursor ().selectionEnd ());
if (se.atBlockStart ()) {
be = be.previous ();
adjust_end = true;
}
}
}
} else if ((ke->key () == Qt::Key_Backtab || (ke->key () == Qt::Key_Tab && (ke->modifiers () & Qt::ShiftModifier) != 0))) {
if (indent) {
return back_tab_key_pressed ();
// tab out
QTextCursor c (mp_text->document ());
c.setPosition (bs.position ());
c.beginEditBlock ();
} else if (ke->key () == Qt::Key_Backspace) {
for (QTextBlock b = bs; ; b = b.next()) {
return backspace_pressed ();
c.setPosition (b.position ());
QString text = b.text ();
} else if (ke->key () == Qt::Key_Escape) {
bool has_tabs = false;
int p = 0;
int i = 0;
for (; i < text.length (); ++i) {
if (text [i] == QChar::fromLatin1 (' ')) {
++p;
} else if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
has_tabs = true;
} else {
break;
}
}
// Handle Esc to return to the before-find position and clear the selection
if (has_tabs) {
for ( ; i > 0; --i) {
c.deleteChar ();
}
c.insertText (QString (m_nindent + p, QChar::fromLatin1 (' ')));
} else {
c.insertText (QString (m_nindent, QChar::fromLatin1 (' ')));
}
if (b == be) {
break;
}
}
c.endEditBlock ();
c.setPosition (bs.position ());
if (adjust_end) {
c.setPosition (be.next ().position (), QTextCursor::KeepAnchor);
} else {
c.setPosition (be.position () + be.text ().length (), QTextCursor::KeepAnchor);
}
mp_text->setTextCursor (c);
} else {
QTextCursor c = mp_text->textCursor ();
QString text = c.block ().text ();
int col = c.position () - c.block ().position ();
int p = 0;
for (int i = 0; i < text.length () && i < col; ++i) {
if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
} else {
++p;
}
}
c.insertText (QString (m_nindent - p % m_nindent, QChar::fromLatin1 (' ')));
mp_text->setTextCursor (c);
}
}
return true;
} else if (ke && (ke->key () == Qt::Key_Backtab || (ke->key () == Qt::Key_Tab && (ke->modifiers () & Qt::ShiftModifier) != 0))) {
if (mp_text->textCursor ().hasSelection () && !mp_text->isReadOnly ()) {
// tab in
QTextBlock bs = mp_text->document ()->findBlock (mp_text->textCursor ().selectionStart ());
QTextBlock be = mp_text->document ()->findBlock (mp_text->textCursor ().selectionEnd ());
bool adjust_end = false;
if (be != bs) {
QTextCursor se (mp_text->document ());
se.setPosition (mp_text->textCursor ().selectionEnd ());
if (se.atBlockStart ()) {
be = be.previous ();
adjust_end = true;
}
}
QTextCursor c (mp_text->document ());
c.setPosition (bs.position ());
c.beginEditBlock ();
for (QTextBlock b = bs; ; b = b.next()) {
c.setPosition (b.position ());
QString text = b.text ();
int n = m_nindent;
int p = 0;
for (int i = 0; i < text.length () && n > 0; ++i) {
if (text [i] == QChar::fromLatin1 (' ')) {
++p;
--n;
c.deleteChar ();
} else if (text [i] == QChar::fromLatin1 ('\t')) {
c.deleteChar ();
int pp = p;
p = (p - p % m_ntab) + m_ntab;
if (p - pp >= n) {
if (p - pp > n) {
c.insertText (QString (p - pp - n, QChar::fromLatin1 (' ')));
}
n = 0;
} else {
n -= p - pp;
}
} else {
break;
}
}
if (b == be) {
break;
}
}
c.endEditBlock ();
c.setPosition (bs.position ());
if (adjust_end) {
c.setPosition (be.next ().position (), QTextCursor::KeepAnchor);
} else {
c.setPosition (be.position () + be.text ().length (), QTextCursor::KeepAnchor);
}
mp_text->setTextCursor (c);
}
return true;
} else if (ke && ke->key () == Qt::Key_Backspace) {
if (!mp_text->textCursor ().hasSelection () && !mp_text->isReadOnly()) {
QTextCursor c = mp_text->textCursor ();
QString text = c.block ().text ();
int col = c.position () - c.block ().position ();
if (col > 0) {
int p = 0;
bool only_space_before = true;
for (int i = 0; i < text.length () && i < col; ++i) {
if (text [i] == QChar::fromLatin1 ('\t')) {
p = (p - p % m_ntab) + m_ntab;
} else if (text [i] == QChar::fromLatin1 (' ')) {
++p;
} else {
only_space_before = false;
}
}
if (only_space_before) {
for (int i = 0; i < col; ++i) {
c.deletePreviousChar ();
}
c.insertText (QString (std::max (0, ((p - 1) / m_nindent) * m_nindent), QChar::fromLatin1 (' ')));
mp_text->setTextCursor (c);
return true;
}
}
}
} else if (ke && ke->key () == Qt::Key_Escape) {
// Handle Esc to clear the selection
find_reset ();
QTextCursor c = mp_text->textCursor ();
c.clearSelection ();
@ -1378,37 +1467,11 @@ MacroEditorPage::eventFilter (QObject *watched, QEvent *event)
return true;
} else if (ke && ke->key () == Qt::Key_Return) {
} else if (ke->key () == Qt::Key_Return) {
if (!mp_text->isReadOnly ()) {
return return_pressed ();
// Implement auto-indent on return
QTextCursor c = mp_text->textCursor ();
QTextBlock b = c.block ();
c.insertBlock ();
QString l;
if (b.isValid ()) {
QString text = b.text ();
for (int i = 0; i < text.length (); ++i) {
if (text [i] == QChar::fromLatin1 ('\t') || text [i] == QChar::fromLatin1 (' ')) {
l += text [i];
} else {
break;
}
}
}
c.insertText (l);
mp_text->setTextCursor (c);
return true;
}
} else if (ke && ke->key () == Qt::Key_F1) {
} else if (ke->key () == Qt::Key_F1) {
QTextCursor c = mp_text->textCursor ();
if (c.selectionStart () == c.selectionEnd ()) {
@ -1418,7 +1481,14 @@ MacroEditorPage::eventFilter (QObject *watched, QEvent *event)
return true;
} else if (ke && ke->key () == Qt::Key_F3) {
} else if (ke->key () == Qt::Key_F && (ke->modifiers () & Qt::ControlModifier) != 0) {
QTextCursor c = mp_text->textCursor ();
emit search_requested (c.selectedText ());
return true;
} else if (ke->key () == Qt::Key_F3) {
// Jump to the next occurence of the search string

View File

@ -254,8 +254,8 @@ public:
return m_current_search;
}
void find_reset ();
bool find_next ();
bool find_prev ();
void replace_and_find_next (const QString &replace);
@ -268,6 +268,7 @@ public:
signals:
void help_requested (const QString &s);
void search_requested (const QString &s);
void edit_trace (bool);
public slots:
@ -294,8 +295,15 @@ private:
int m_ntab, m_nindent;
std::set<QTextBlock> m_breakpoints;
QRegExp m_current_search;
QTextCursor m_edit_cursor;
bool m_ignore_cursor_changed_event;
void update_extra_selections ();
bool return_pressed ();
bool backspace_pressed ();
bool back_tab_key_pressed ();
bool tab_key_pressed ();
bool eventFilter (QObject *watched, QEvent *event);
};