Enhancements for macro editor's search and replace: replace single wasn't working properly and now there is find next and previous

This commit is contained in:
Matthias Koefferlein 2023-08-03 21:35:37 +02:00
parent f583d5e3db
commit 7d749140f7
12 changed files with 555 additions and 25 deletions

View File

@ -284,5 +284,9 @@
<file alias="bookmark_16px@2x.png">images/bookmark_16px@2x.png</file>
<file alias="bookmark_24px.png">images/bookmark_24px.png</file>
<file alias="bookmark_24px@2x.png">images/bookmark_24px@2x.png</file>
<file alias="find_next_16px.png">images/find_next_16px.png</file>
<file alias="find_next_16px@2x.png">images/find_next_16px@2x.png</file>
<file alias="find_prev_16px.png">images/find_prev_16px.png</file>
<file alias="find_prev_16px@2x.png">images/find_prev_16px@2x.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 4.2333332 4.2333335"
version="1.1"
id="svg1011"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="find_next_16px.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1013"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
units="px"
inkscape:snap-nodes="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-others="false"
inkscape:zoom="12.224789"
inkscape:cx="1.9223236"
inkscape:cy="9.7752198"
inkscape:window-width="1465"
inkscape:window-height="666"
inkscape:window-x="1099"
inkscape:window-y="250"
inkscape:window-maximized="0"
inkscape:current-layer="layer1"
width="16px"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1074"
spacingx="0.13229167"
spacingy="0.13229167"
empspacing="2" />
</sodipodi:namedview>
<defs
id="defs1008">
<linearGradient
id="linearGradient3600">
<stop
style="stop-color:#ff9f3f;stop-opacity:1;"
offset="0"
id="stop3602" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3604" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5268"
id="radialGradient5274"
cx="1240.1577"
cy="1031.1023"
fx="1240.1577"
fy="1031.1023"
r="17.716494"
gradientTransform="matrix(0.07467134,-2.1333204e-7,1.7097273e-7,0.05973699,-91.281506,-60.271751)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient5268">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5270" />
<stop
style="stop-color:#adadad;stop-opacity:1;"
offset="1"
id="stop5272" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5280"
id="radialGradient5286"
cx="1240.1576"
cy="1031.1023"
fx="1240.1576"
fy="1031.1023"
r="17.716494"
gradientTransform="matrix(0.07467134,-5.3367783e-7,4.263589e-7,0.05973696,-91.281753,-60.27133)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient5280">
<stop
style="stop-color:#ababab;stop-opacity:1;"
offset="0"
id="stop5282" />
<stop
style="stop-color:#535353;stop-opacity:1;"
offset="1"
id="stop5284" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5298"
id="linearGradient5304"
x1="1257.874"
y1="1059.4489"
x2="1264.9606"
y2="1052.3622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.07467134,0,0,0.07467124,-91.281317,-75.670759)" />
<linearGradient
id="linearGradient5298">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5300" />
<stop
id="stop5306"
offset="0.50000167"
style="stop-color:#8f8f8f;stop-opacity:1;" />
<stop
style="stop-color:#353535;stop-opacity:1;"
offset="1"
id="stop5302" />
</linearGradient>
<linearGradient
id="linearGradient4099">
<stop
id="stop4101"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#ff9e3f;stop-opacity:1;"
offset="0.65753424"
id="stop4485" />
<stop
id="stop4103"
offset="1"
style="stop-color:#808080;stop-opacity:1;" />
</linearGradient>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#865b26;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3596"
width="4.2333326"
height="4.2333331"
x="3.3333333e-07"
y="3.3333333e-07"
inkscape:export-filename="/home/matthias/klayout/master/src/lay/lay/images/back.png"
inkscape:export-xdpi="27.093315"
inkscape:export-ydpi="27.093315" />
<rect
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5220"
width="4.2333336"
height="4.2333336"
x="-8.8817842e-16"
y="-7.7715612e-16"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25.399982"
inkscape:export-ydpi="25.399982" />
<ellipse
style="fill:url(#radialGradient5274);fill-opacity:1;stroke:url(#radialGradient5286);stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5258"
cx="1.5874953"
cy="1.5875114"
rx="1.188506"
ry="1.1885061"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<ellipse
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5278"
cx="0.65258032"
cy="2.108269"
rx="0.21676302"
ry="0.51771969"
transform="matrix(0.84080627,-0.54133615,0.68097313,0.7323084,0,0)"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<ellipse
style="fill:none;fill-opacity:1;stroke:#303030;stroke-width:0.0746713;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5308"
cx="1.5874953"
cy="1.5875114"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25"
rx="1.3229176"
ry="1.3229157" />
<path
style="fill:url(#linearGradient5304);fill-opacity:1;fill-rule:evenodd;stroke:#303030;stroke-width:0.0746713;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3.9687491,3.4395946 3.4395757,3.9687602 2.1166608,2.645847 2.6458268,2.1166818 Z"
id="path5288"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<path
inkscape:export-ydpi="25"
inkscape:export-xdpi="25"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path5342"
d="M 3.042749,1.4552217 H 1.9843342 l -7.36e-5,1.0595032 h -0.521379 l 1.05066,1.0761548 1.058786,-1.0722781 -0.529505,-0.00388 z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.05833334;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98414469" />
<path
style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3.0427083,1.4552084 H 1.984375 l -7.36e-5,1.0595163 H 1.4629626 l 1.050579,1.076168 1.0587045,-1.0722914 -0.5294642,-0.00389 z"
id="path5330"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="16"
height="16"
viewBox="0 0 4.2333332 4.2333335"
version="1.1"
id="svg1011"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="find_prev_16px.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1013"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="true"
units="px"
inkscape:snap-nodes="true"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-others="false"
inkscape:zoom="12.224789"
inkscape:cx="6.666782"
inkscape:cy="14.192475"
inkscape:window-width="1092"
inkscape:window-height="666"
inkscape:window-x="1083"
inkscape:window-y="278"
inkscape:window-maximized="0"
inkscape:current-layer="layer1"
width="16px"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid1074"
spacingx="0.13229167"
spacingy="0.13229167"
empspacing="2" />
</sodipodi:namedview>
<defs
id="defs1008">
<linearGradient
id="linearGradient3600">
<stop
style="stop-color:#ff9f3f;stop-opacity:1;"
offset="0"
id="stop3602" />
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop3604" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5268"
id="radialGradient5274"
cx="1240.1577"
cy="1031.1023"
fx="1240.1577"
fy="1031.1023"
r="17.716494"
gradientTransform="matrix(0.07467134,-2.1333204e-7,1.7097273e-7,0.05973699,-91.281506,-60.271751)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient5268">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5270" />
<stop
style="stop-color:#adadad;stop-opacity:1;"
offset="1"
id="stop5272" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5280"
id="radialGradient5286"
cx="1240.1576"
cy="1031.1023"
fx="1240.1576"
fy="1031.1023"
r="17.716494"
gradientTransform="matrix(0.07467134,-5.3367783e-7,4.263589e-7,0.05973696,-91.281753,-60.27133)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient5280">
<stop
style="stop-color:#ababab;stop-opacity:1;"
offset="0"
id="stop5282" />
<stop
style="stop-color:#535353;stop-opacity:1;"
offset="1"
id="stop5284" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5298"
id="linearGradient5304"
x1="1257.874"
y1="1059.4489"
x2="1264.9606"
y2="1052.3622"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.07467134,0,0,0.07467124,-91.281317,-75.670759)" />
<linearGradient
id="linearGradient5298">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5300" />
<stop
id="stop5306"
offset="0.50000167"
style="stop-color:#8f8f8f;stop-opacity:1;" />
<stop
style="stop-color:#353535;stop-opacity:1;"
offset="1"
id="stop5302" />
</linearGradient>
<linearGradient
id="linearGradient4099">
<stop
id="stop4101"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#ff9e3f;stop-opacity:1;"
offset="0.65753424"
id="stop4485" />
<stop
id="stop4103"
offset="1"
style="stop-color:#808080;stop-opacity:1;" />
</linearGradient>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#865b26;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3596"
width="4.2333326"
height="4.2333331"
x="3.3333333e-07"
y="3.3333333e-07"
inkscape:export-filename="/home/matthias/klayout/master/src/lay/lay/images/back.png"
inkscape:export-xdpi="27.093315"
inkscape:export-ydpi="27.093315" />
<rect
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5220"
width="4.2333336"
height="4.2333336"
x="-8.8817842e-16"
y="-7.7715612e-16"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25.399982"
inkscape:export-ydpi="25.399982" />
<ellipse
style="fill:url(#radialGradient5274);fill-opacity:1;stroke:url(#radialGradient5286);stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5258"
cx="1.5874953"
cy="1.5875114"
rx="1.188506"
ry="1.1885061"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<ellipse
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.268817;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5278"
cx="0.65258032"
cy="2.108269"
rx="0.21676302"
ry="0.51771969"
transform="matrix(0.84080627,-0.54133615,0.68097313,0.7323084,0,0)"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<ellipse
style="fill:none;fill-opacity:1;stroke:#303030;stroke-width:0.0746713;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5308"
cx="1.5874953"
cy="1.5875114"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25"
rx="1.3229176"
ry="1.3229157" />
<path
style="fill:url(#linearGradient5304);fill-opacity:1;fill-rule:evenodd;stroke:#303030;stroke-width:0.0746713;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3.9687491,3.4395946 3.4395757,3.9687602 2.1166608,2.645847 2.6458268,2.1166818 Z"
id="path5288"
inkscape:connector-curvature="0"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/find.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
<path
inkscape:export-ydpi="25"
inkscape:export-xdpi="25"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path5342"
d="M 3.0478337,3.5792109 H 1.9895004 L 1.9839304,2.5174183 H 1.4625915 l 1.0505791,-1.076168 1.0587045,1.0722914 -0.5294642,0.00389 z"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.05833334;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#1a1a1a;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 3.0478337,3.5792109 H 1.9895004 L 1.9839304,2.5174183 H 1.4625915 l 1.0505791,-1.076168 1.0587045,1.0722914 -0.5294642,0.00389 z"
id="path5330"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="/home/matthias/klayout/trunk/src/lay/images/replace.png"
inkscape:export-xdpi="25"
inkscape:export-ydpi="25" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -463,10 +463,6 @@
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../icons/icons.qrc">
<normaloff>:/breakpoint_16px.png</normaloff>:/breakpoint_16px.png</iconset>
</property>
<property name="shortcut">
<string>F9</string>
</property>
@ -636,7 +632,7 @@
</property>
<property name="icon">
<iconset resource="../../icons/icons.qrc">
<normaloff>:/find_16px.png</normaloff>:/find_16px.png</iconset>
<normaloff>:/find_next_16px.png</normaloff>:/find_next_16px.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+F</string>
@ -646,6 +642,23 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="findPrevButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../icons/icons.qrc">
<normaloff>:/find_prev_16px.png</normaloff>:/find_prev_16px.png</iconset>
</property>
<property name="shortcut">
<string>Ctrl+Shift+F</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replaceModeButton">
<property name="sizePolicy">

View File

@ -493,6 +493,7 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection
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 ()));
connect (findPrevButton, SIGNAL (clicked ()), this, SLOT (find_prev_button_clicked ()));
connect (replaceAllButton, SIGNAL (clicked ()), this, SLOT (replace_all_button_clicked ()));
connect (allVariables, SIGNAL (clicked (bool)), variableList, SLOT (set_show_all (bool)));
@ -2021,7 +2022,7 @@ MacroEditorDialog::replace_all_button_clicked ()
}
void
MacroEditorDialog::search_requested (const QString &s)
MacroEditorDialog::search_requested (const QString &s, bool prev)
{
if (! s.isNull ()) {
searchEditBox->setText (s);
@ -2029,7 +2030,21 @@ MacroEditorDialog::search_requested (const QString &s)
searchEditBox->selectAll ();
}
searchEditBox->setFocus ();
search_editing ();
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
if (! page) {
return;
}
apply_search ();
page->find_reset (); // search from the initial position
if (! page->has_multi_block_selection ()) {
if (! prev) {
page->find_next ();
} else {
page->find_prev ();
}
}
}
void
@ -3511,7 +3526,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 (search_requested (const QString &, bool)), this, SLOT (search_requested (const QString &, bool)));
connect (editor.get (), SIGNAL (edit_trace (bool)), this, SLOT (add_edit_trace (bool)));
return editor.release ();
}

View File

@ -222,7 +222,7 @@ private slots:
void find_next_button_clicked ();
void find_prev_button_clicked ();
void help_requested (const QString &s);
void search_requested (const QString &s);
void search_requested (const QString &s, bool prev);
void macro_changed (lym::Macro *macro);
void macro_deleted (lym::Macro *macro);
void macro_collection_deleted (lym::MacroCollection *collection);

View File

@ -1077,12 +1077,10 @@ MacroEditorPage::find_prev ()
first = false;
int i = -1;
int l = 0;
int p = 0;
while (true) {
int ii = m_current_search.indexIn (b.text (), p);
if (ii >= 0 && (o < 0 || ii < o)) {
l = m_current_search.matchedLength ();
i = ii;
p = ii + 1;
} else {
@ -1091,8 +1089,7 @@ MacroEditorPage::find_prev ()
}
if (i >= 0) {
QTextCursor newc (b);
newc.setPosition (i + b.position () + l);
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
newc.setPosition (i + b.position ());
m_ignore_cursor_changed_event = true;
mp_text->setTextCursor (newc);
m_ignore_cursor_changed_event = false;
@ -1136,8 +1133,7 @@ MacroEditorPage::find_next ()
int i = m_current_search.indexIn (b.text (), o);
if (i >= 0) {
QTextCursor newc (b);
newc.setPosition (i + b.position () + m_current_search.matchedLength ());
newc.setPosition (i + b.position (), QTextCursor::KeepAnchor);
newc.setPosition (i + b.position ());
m_ignore_cursor_changed_event = true;
mp_text->setTextCursor (newc);
m_ignore_cursor_changed_event = false;
@ -1158,6 +1154,39 @@ MacroEditorPage::find_next ()
return false;
}
bool
MacroEditorPage::select_match_here ()
{
if (m_current_search == QRegExp ()) {
return false;
}
QTextCursor c = mp_text->textCursor ();
if (c.isNull ()) {
return false;
}
if (c.hasSelection ()) {
return true;
}
QTextBlock b = c.block ();
int pos = c.position () - b.position ();
int i = m_current_search.indexIn (b.text (), pos);
if (i == pos) {
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;
} else {
return false;
}
}
void
MacroEditorPage::set_editor_focus ()
{
@ -1196,7 +1225,9 @@ MacroEditorPage::replace_and_find_next (const QString &replace)
return;
}
replace_in_selection (replace, true);
if (select_match_here ()) {
replace_in_selection (replace, true);
}
find_next ();
}
@ -1280,12 +1311,8 @@ MacroEditorPage::replace_in_selection (const QString &replace, bool first)
o = i + r.size ();
if (first) {
// in single-selection mode, put cursor past substitution
c.setPosition (i + b.position ());
has_selection = false;
done = true;
} else if (b == be) {
pe += int (r.size ()) - int (m_current_search.matchedLength ());
}
@ -1734,6 +1761,11 @@ static bool is_find_key (QKeyEvent *ke)
return ke->key () == Qt::Key_F && (ke->modifiers () & Qt::ControlModifier) != 0;
}
static bool is_find_backwards_key (QKeyEvent *ke)
{
return ke->key () == Qt::Key_F && (ke->modifiers () & Qt::ControlModifier) != 0 && (ke->modifiers () & Qt::ShiftModifier) != 0;
}
static bool is_up_key (QKeyEvent *ke)
{
return ke->key () == Qt::Key_Up;
@ -1755,6 +1787,7 @@ static bool is_any_known_key (QKeyEvent *ke)
is_help_key (ke) ||
is_find_next_key (ke) ||
is_find_key (ke) ||
is_find_backwards_key (ke) ||
is_up_key (ke) ||
is_down_key (ke);
}
@ -1848,19 +1881,21 @@ MacroEditorPage::eventFilter (QObject *watched, QEvent *event)
QApplication::sendEvent (mp_completer_list, event);
return true;
} else if (is_find_key (ke)) {
} else if (is_find_key (ke) || is_find_backwards_key (ke)) {
bool prev = is_find_backwards_key (ke);
QTextCursor c = mp_text->textCursor ();
if (c.selectionStart () != c.selectionEnd ()) {
QTextBlock s = mp_text->document ()->findBlock (c.selectionStart ());
QTextBlock e = mp_text->document ()->findBlock (c.selectionEnd ());
if (e == s) {
emit search_requested (c.selectedText ());
emit search_requested (c.selectedText (), prev);
} else {
emit search_requested (QString ());
emit search_requested (QString (), prev);
}
} else {
emit search_requested (QString ());
emit search_requested (QString (), prev);
}
return true;

View File

@ -271,7 +271,7 @@ public:
signals:
void help_requested (const QString &s);
void search_requested (const QString &s);
void search_requested (const QString &s, bool backward);
void edit_trace (bool);
public slots:
@ -314,6 +314,7 @@ private:
void fill_completer_list ();
void complete ();
QTextCursor get_completer_cursor (int &pos0, int &pos);
bool select_match_here ();
void replace_in_selection (const QString &replace, bool first);
bool eventFilter (QObject *watched, QEvent *event);