NotificationDisplay: proper handling of marks at insert position
Basically we create a pair of marks, with left/right gravity and then inject the content between. Unfortunately, when the insert position is the very end of the buffer (which it always is), this trick leads to nesting the marked regions into each other. As a remedy, we first insert the trailing newline, and then attach the insert position one step before
This commit is contained in:
parent
4635d18265
commit
e9527d6304
2 changed files with 132 additions and 30 deletions
|
|
@ -109,7 +109,8 @@ namespace widget {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
/*********************************************************************//**
|
||||
* Widget to display log and error messages.
|
||||
* Based on a multiline text display box with scrollbars.
|
||||
* Warning and error messages are highlighted by special formatting.
|
||||
|
|
@ -168,6 +169,7 @@ namespace widget {
|
|||
textLog_.get_buffer()->set_text (placeholder); // discard existing content
|
||||
}
|
||||
|
||||
|
||||
/** just add normal information message to buffer,
|
||||
* without special markup and without expanding the widget */
|
||||
void
|
||||
|
|
@ -201,7 +203,7 @@ namespace widget {
|
|||
|
||||
/**
|
||||
* clear all mere information messages;
|
||||
* retain just the errors with tags
|
||||
* retain just the previously tagged errors
|
||||
* @remark in fact populates a new buffer
|
||||
*/
|
||||
void
|
||||
|
|
@ -211,12 +213,15 @@ namespace widget {
|
|||
vector<Entry> newMarks;
|
||||
for (Entry& entry : errorMarks_)
|
||||
{
|
||||
newBuff->insert (newBuff->end(), "\n");
|
||||
auto pos = newBuff->end();
|
||||
--pos;
|
||||
newMarks.emplace_back(
|
||||
make_pair (
|
||||
newBuff->create_mark (newBuff->end(), true), // "left gravity": stays to the left of inserted text
|
||||
newBuff->create_mark (newBuff->end(), false))); // "right gravity": sticks right behind the inserted text))
|
||||
newBuff->create_mark (pos, true), // "left gravity" : stays to the left of inserted text
|
||||
newBuff->create_mark (pos, false))); // "right gravity": sticks right behind the inserted text))
|
||||
|
||||
newBuff->insert (newBuff->end()
|
||||
newBuff->insert (pos // copy from old to new buffer, complete with formatting tag
|
||||
,entry.first->get_iter()
|
||||
,entry.second->get_iter()
|
||||
);
|
||||
|
|
@ -250,27 +255,32 @@ namespace widget {
|
|||
private:/* ===== Internals ===== */
|
||||
|
||||
/** add message entry to the (ever growing) text buffer.
|
||||
* @remark According to the [GTKmm tutorial], `TextView::scroll_to(iter)` is not reliable;
|
||||
* rather we need to use a text mark and set that text mark to the insert position.
|
||||
* Actually, there is always one predefined text mark [called "insert"][insert-mark],
|
||||
* which corresponds to the text cursor. Thus it suffices to navigate to text end,
|
||||
* insert and scroll into view.
|
||||
* @return pair of anonymous marks bracketing the content added
|
||||
* @remark an entry is content sans the following line break, which is appended automatically.
|
||||
* We inject the content _between_ two marks, which will adjust when content is altered.
|
||||
* @remark According to the [API doc], `TextView::scroll_to(iter)` is not reliable; preferably
|
||||
* we should use a text mark and set that text mark to the [insert position][insert-mark].
|
||||
* The handling of marks and tags is described in the [GTKmm tutorial].
|
||||
* @warning Each entry creates a new pair of marks. Not sure about the impact on performance...
|
||||
*
|
||||
* [GTKmm tutorial]: https://developer.gnome.org/gtkmm-tutorial/stable/sec-textview-buffer.html.en#textview-marks
|
||||
* [insert-mark]: https://developer.gnome.org/gtkmm/3.22/classGtk_1_1TextMark.html#details
|
||||
* [API doc]: https://developer.gnome.org/gtkmm/3.22/classGtk_1_1TextView.html#a8412941c4da9a71a381052d6049164e4
|
||||
*/
|
||||
Entry
|
||||
addEntry (string const& text, Literal markupTagName =nullptr)
|
||||
{
|
||||
auto buff = textLog_.get_buffer();
|
||||
auto begin = buff->create_mark (buff->end(), true); // "left gravity": stays to the left of inserted text
|
||||
auto after = buff->create_mark (buff->end(), false);// "right gravity": sticks right behind the inserted text
|
||||
if (markupTagName)
|
||||
buff->insert_with_tag(buff->end(), text, cuString{markupTagName});
|
||||
else
|
||||
buff->insert (buff->end(), text);
|
||||
buff->insert (buff->end(), "\n");
|
||||
textLog_.scroll_to (after);
|
||||
auto pos = buff->end();
|
||||
--pos;
|
||||
auto begin = buff->create_mark (pos, true); // "left gravity" : stays to the left of inserted text
|
||||
auto after = buff->create_mark (pos, false);// "right gravity": sticks right behind the inserted text
|
||||
if (markupTagName)
|
||||
buff->insert_with_tag(pos, text, cuString{markupTagName});
|
||||
else
|
||||
buff->insert (pos, text);
|
||||
textLog_.scroll_to (begin);
|
||||
return make_pair (move(begin), move(after));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1773,7 +1773,8 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1534850841673" ID="ID_375492094" MODIFIED="1538263469667" TEXT="ParentView-Interface">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1504203667130" ID="ID_1745777873" MODIFIED="1538263469667" TEXT="vorläufig Empfänger für Fehler-Log">
|
||||
<node CREATED="1504203667130" HGAP="50" ID="ID_1745777873" MODIFIED="1538584290312" TEXT="vorläufig Empfänger für Fehler-Log" VSHIFT="2">
|
||||
<arrowlink COLOR="#98a2c5" DESTINATION="ID_217810080" ENDARROW="Default" ENDINCLINATION="1891;-1228;" ID="Arrow_ID_1688804340" STARTARROW="None" STARTINCLINATION="-1261;74;"/>
|
||||
<linktarget COLOR="#7893b2" DESTINATION="ID_1745777873" ENDARROW="Default" ENDINCLINATION="-499;-464;" ID="Arrow_ID_1590510093" SOURCE="ID_812129962" STARTARROW="None" STARTINCLINATION="808;0;"/>
|
||||
<linktarget COLOR="#628195" DESTINATION="ID_1745777873" ENDARROW="Default" ENDINCLINATION="245;349;" ID="Arrow_ID_1743659141" SOURCE="ID_1981930639" STARTARROW="None" STARTINCLINATION="397;197;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
|
|
@ -2116,8 +2117,8 @@
|
|||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1534725501467" ID="ID_1420459325" MODIFIED="1538263469669" TEXT="Bookmark speichern">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1534725501467" ID="ID_1420459325" MODIFIED="1538586532645" TEXT="Bookmark speichern">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1537535919147" ID="ID_1338221225" MODIFIED="1538263469669" TEXT="Technologie">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1537535925874" ID="ID_196796680" MODIFIED="1538263469669" TEXT="Tag / TagTable">
|
||||
|
|
@ -2146,7 +2147,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1538581570783" ID="ID_1599117331" MODIFIED="1538581665660" TEXT="Problem: Ende wandert mit...">
|
||||
<node COLOR="#338800" CREATED="1538581570783" ID="ID_1599117331" MODIFIED="1538586033692" TEXT="Problem: Ende wandert mit...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -2161,10 +2162,27 @@
|
|||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1538585387424" ID="ID_151756918" MODIFIED="1538585442447" TEXT="Trick: erst abschließenden Zeilenumbruch">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1537571882918" ID="ID_620353485" MODIFIED="1538263469669" TEXT="reorganisieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1538585409653" ID="ID_584738161" MODIFIED="1538585447421">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...dann Einfügestelle <i>davor</i> platzieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1537571882918" ID="ID_620353485" MODIFIED="1538586057629" TEXT="reorganisieren">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1538586059134" ID="ID_5616537" MODIFIED="1538586065889" TEXT="besser wegwerfen und neu bauen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -2210,8 +2228,8 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1534725142756" ID="ID_343395831" MODIFIED="1538263469669" TEXT="clearInfoMsg">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1534725142756" ID="ID_343395831" MODIFIED="1538586610313" TEXT="clearInfoMsg">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1538581145248" ID="ID_643768128" MODIFIED="1538581206025" TEXT="neuen TextBuffer anlegen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -2756,8 +2774,8 @@
|
|||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1534120150463" ID="ID_183847307" MODIFIED="1538263469672" TEXT="doClearMsg()">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1534120150463" ID="ID_183847307" MODIFIED="1538586631566" TEXT="doClearMsg()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1534120150463" ID="ID_1378278687" MODIFIED="1538263469672" TEXT=""remove all mere information messages"">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
|
|
@ -5014,9 +5032,20 @@
|
|||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1538583873795" ID="ID_1515056203" MODIFIED="1538583876382" TEXT="spezifisch">
|
||||
<node CREATED="1537659880597" ID="ID_1214109906" MODIFIED="1537659889631" TEXT="Timecode"/>
|
||||
<node CREATED="1537659890292" ID="ID_1230379898" MODIFIED="1537659892520" TEXT="Placement"/>
|
||||
</node>
|
||||
<node CREATED="1538583877106" ID="ID_1825646582" MODIFIED="1538583879910" TEXT="generisch">
|
||||
<node CREATED="1538583886065" ID="ID_217810080" MODIFIED="1538584290312" TEXT="ErrorLogView">
|
||||
<linktarget COLOR="#98a2c5" DESTINATION="ID_217810080" ENDARROW="Default" ENDINCLINATION="1891;-1228;" ID="Arrow_ID_1688804340" SOURCE="ID_1745777873" STARTARROW="None" STARTINCLINATION="-1261;74;"/>
|
||||
<node CREATED="1538583894072" ID="ID_1836686899" MODIFIED="1538584118864" TEXT="Gtk::TextView + Mark-Index">
|
||||
<arrowlink COLOR="#3251a9" DESTINATION="ID_243616989" ENDARROW="Default" ENDINCLINATION="-2060;-1360;" ID="Arrow_ID_794678010" STARTARROW="None" STARTINCLINATION="-3506;-148;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1537961656982" ID="ID_1251358269" MODIFIED="1537961731447" TEXT="frameworks">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -5028,7 +5057,7 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1537961734956" ID="ID_345535043" MODIFIED="1537961770028" TEXT="Notebook-Widget">
|
||||
<node CREATED="1537961734956" FOLDED="true" ID="ID_345535043" MODIFIED="1538583863918" TEXT="Notebook-Widget">
|
||||
<node CREATED="1537961776184" ID="ID_167848646" MODIFIED="1537961791126" TEXT="Problematik">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1537961797061" ID="ID_104206298" MODIFIED="1537961806159" TEXT="extrem viele Komponenten-Widgets"/>
|
||||
|
|
@ -37869,8 +37898,9 @@
|
|||
<node CREATED="1534635322938" ID="ID_1532459469" MODIFIED="1534635328573" TEXT="show_all zeigt rekursiv an"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1534634259498" ID="ID_1900017952" MODIFIED="1534635809110" TEXT=""Schließen"">
|
||||
<node CREATED="1534634259498" FOLDED="true" ID="ID_1900017952" MODIFIED="1538583305997" TEXT=""Schließen"">
|
||||
<linktarget COLOR="#6f7ab9" DESTINATION="ID_1900017952" ENDARROW="Default" ENDINCLINATION="-2264;0;" ID="Arrow_ID_1220603071" SOURCE="ID_146943890" STARTARROW="None" STARTINCLINATION="-6278;0;"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1534634292477" ID="ID_1867321008" MODIFIED="1534634310281">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
|
@ -38812,6 +38842,68 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1538583396203" ID="ID_243616989" MODIFIED="1538584118865" TEXT="TextView">
|
||||
<linktarget COLOR="#3251a9" DESTINATION="ID_243616989" ENDARROW="Default" ENDINCLINATION="-2060;-1360;" ID="Arrow_ID_794678010" SOURCE="ID_1836686899" STARTARROW="None" STARTINCLINATION="-3506;-148;"/>
|
||||
<node CREATED="1538583408897" ID="ID_1222725022" MODIFIED="1538583418805" TEXT="das Editor-Widget">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1538583420272" ID="ID_438604441" MODIFIED="1538583449944" TEXT="Model == Buffer">
|
||||
<node CREATED="1538583478040" ID="ID_511541932" MODIFIED="1538583483915" TEXT="kann getauscht werden"/>
|
||||
<node CREATED="1538583484647" ID="ID_457973011" MODIFIED="1538583504768" TEXT="Buffer gemeinsam verwenden"/>
|
||||
</node>
|
||||
<node CREATED="1538583507988" HGAP="72" ID="ID_1806257929" MODIFIED="1538583518616" TEXT="TextBuffer" VSHIFT="18">
|
||||
<node CREATED="1538583533033" ID="ID_964637986" MODIFIED="1538583734951" TEXT="Konzepte">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1538583627852" ID="ID_1431409524" MODIFIED="1538583630676" TEXT="Position">
|
||||
<node CREATED="1538583632075" ID="ID_1308223917" MODIFIED="1538583654421">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
stets <i>zwischen </i>den Zeichen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1538583655744" ID="ID_415292974" MODIFIED="1538583682595">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<b>Danke</b>! endlich bekommt das mal jemand korrekt hin
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1538583535896" ID="ID_81892828" MODIFIED="1538583539908" TEXT="TextIterator">
|
||||
<node CREATED="1538583541231" ID="ID_1777219378" MODIFIED="1538583544571" TEXT="flüchtig"/>
|
||||
<node CREATED="1538583546679" ID="ID_1182183621" MODIFIED="1538583555801" TEXT="kann intelligent navigieren">
|
||||
<node CREATED="1538583567436" ID="ID_750990432" MODIFIED="1538583573647" TEXT="Zeichen"/>
|
||||
<node CREATED="1538583573995" ID="ID_881520087" MODIFIED="1538583579166" TEXT="nächstes Wort"/>
|
||||
<node CREATED="1538583579754" ID="ID_198678641" MODIFIED="1538583582742" TEXT="nächste Zeile"/>
|
||||
</node>
|
||||
<node CREATED="1538583556374" ID="ID_661377638" MODIFIED="1538583562128" TEXT="weiß viel über seine Position"/>
|
||||
</node>
|
||||
<node CREATED="1538583588689" ID="ID_1850195952" MODIFIED="1538583593741" TEXT="TextMark">
|
||||
<node CREATED="1538583596768" ID="ID_281650917" MODIFIED="1538583612602" TEXT="dauerhafte Positionsmarke"/>
|
||||
<node CREATED="1538583613326" ID="ID_1642730307" MODIFIED="1538583618193" TEXT="wandert mit"/>
|
||||
<node CREATED="1538583618989" ID="ID_870667973" MODIFIED="1538583624848" TEXT="left/right gravity"/>
|
||||
</node>
|
||||
<node CREATED="1538583722679" ID="ID_80198934" MODIFIED="1538583725898" TEXT="TextTag">
|
||||
<node CREATED="1538583726990" ID="ID_679389681" MODIFIED="1538583730874" TEXT="Formatierung / Markup"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477526858307" ID="ID_676269117" MODIFIED="1518487921100" TEXT="custom widget">
|
||||
<node COLOR="#ca1b00" CREATED="1477526864162" ID="ID_1385929770" LINK="https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-widgets.html.en" MODIFIED="1518487921100" TEXT="Beispiel">
|
||||
|
|
|
|||
Loading…
Reference in a new issue