@@ -101,6 +101,11 @@ void QtSLiMTextEdit::selfInit(void)
101101 connect (this , &QPlainTextEdit::selectionChanged, this , &QtSLiMTextEdit::updateStatusFieldFromSelection);
102102 connect (this , &QPlainTextEdit::cursorPositionChanged, this , &QtSLiMTextEdit::updateStatusFieldFromSelection);
103103
104+ // BCH 28 August 2025: get rid of the annoying insertion point remnant shown briefly when the selection changes
105+ // this is a dangerous change since it could, if there is a bug somewhere, make the insertion point disappear!
106+ connect (this , &QPlainTextEdit::selectionChanged, this , [this ]() { if (textCursor ().hasSelection ()) setCursorWidth (0 ); else setCursorWidth (1 ); });
107+ connect (this , &QPlainTextEdit::cursorPositionChanged, this , [this ]() { if (textCursor ().hasSelection ()) setCursorWidth (0 ); else setCursorWidth (1 ); });
108+
104109 // Wire up to change the font when the display font pref changes
105110 QtSLiMPreferencesNotifier &prefsNotifier = QtSLiMPreferencesNotifier::instance ();
106111
@@ -2525,7 +2530,9 @@ class LineNumberArea : public QWidget
25252530protected:
25262531 virtual bool event (QEvent *p_event) override ;
25272532 virtual void paintEvent (QPaintEvent *p_paintEvent) override { codeEditor->lineNumberAreaPaintEvent (p_paintEvent); }
2528- virtual void mousePressEvent (QMouseEvent *p_mouseEvent) override { codeEditor->lineNumberAreaMouseEvent (p_mouseEvent); }
2533+ virtual void mousePressEvent (QMouseEvent *p_mouseEvent) override { codeEditor->lineNumberAreaMousePressEvent (p_mouseEvent); }
2534+ virtual void mouseMoveEvent (QMouseEvent *p_mouseEvent) override { codeEditor->lineNumberAreaMouseMoveEvent (p_mouseEvent); }
2535+ virtual void mouseReleaseEvent (QMouseEvent *p_mouseEvent) override { codeEditor->lineNumberAreaMouseReleaseEvent (p_mouseEvent); }
25292536 virtual void contextMenuEvent (QContextMenuEvent *p_event) override { codeEditor->lineNumberAreaContextMenuEvent (p_event); }
25302537 virtual void wheelEvent (QWheelEvent *p_wheelEvent) override { codeEditor->lineNumberAreaWheelEvent (p_wheelEvent); }
25312538
@@ -2583,8 +2590,10 @@ void QtSLiMScriptTextEdit::initializeLineNumbers(void)
25832590 connect (this ->document (), SIGNAL (blockCountChanged (int )), this , SLOT (updateLineNumberAreaWidth (int )));
25842591 connect (this ->verticalScrollBar (), SIGNAL (valueChanged (int )), this , SLOT (updateLineNumberArea (int )));
25852592 connect (this , SIGNAL (textChanged ()), this , SLOT (updateLineNumberArea ()));
2593+ connect (this , SIGNAL (selectionChanged ()), this , SLOT (updateLineNumberArea ()));
25862594 connect (this , SIGNAL (cursorPositionChanged ()), this , SLOT (updateLineNumberArea ()));
25872595
2596+ connect (this , &QtSLiMScriptTextEdit::selectionChanged, this , &QtSLiMScriptTextEdit::highlightCurrentLine);
25882597 connect (this , &QtSLiMScriptTextEdit::cursorPositionChanged, this , &QtSLiMScriptTextEdit::highlightCurrentLine);
25892598 connect (qtSLiMAppDelegate, &QtSLiMAppDelegate::applicationPaletteChanged, this , &QtSLiMScriptTextEdit::highlightCurrentLine);
25902599
@@ -2938,6 +2947,43 @@ void QtSLiMScriptTextEdit::toggleDebuggingForLine(int lineNumber)
29382947 updateDebugPoints ();
29392948}
29402949
2950+ void QtSLiMScriptTextEdit::trackLineSelection (int lineNumber, int anchorLineNumber)
2951+ {
2952+ QTextDocument *doc = document ();
2953+ QTextBlock block = doc->findBlockByNumber (lineNumber);
2954+ QTextCursor block_tc (block);
2955+ QTextBlock anchor_block = doc->findBlockByNumber (anchorLineNumber);
2956+ QTextCursor anchor_tc (anchor_block);
2957+
2958+ block_tc.movePosition (QTextCursor::EndOfBlock, QTextCursor::KeepAnchor, 1 );
2959+ block_tc.movePosition (QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1 );
2960+
2961+ int block_start = block_tc.selectionStart ();
2962+ int block_end = block_tc.selectionEnd ();
2963+
2964+ anchor_tc.movePosition (QTextCursor::EndOfBlock, QTextCursor::KeepAnchor, 1 );
2965+ anchor_tc.movePosition (QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 1 );
2966+
2967+ int anchor_start = anchor_tc.selectionStart ();
2968+ int anchor_end = anchor_tc.selectionEnd ();
2969+
2970+ QTextCursor selection_tc (anchor_tc);
2971+
2972+ if (anchor_start <= block_start)
2973+ {
2974+ // the anchor is above the final line, so select from the anchor start to the final end
2975+ selection_tc.setPosition (block_end, QTextCursor::KeepAnchor);
2976+ }
2977+ else
2978+ {
2979+ // the anchor is below the final line, so select from the anchor end to the final start
2980+ selection_tc.setPosition (anchor_end, QTextCursor::MoveAnchor);
2981+ selection_tc.setPosition (block_start, QTextCursor::KeepAnchor);
2982+ }
2983+
2984+ setTextCursor (selection_tc);
2985+ }
2986+
29412987void QtSLiMScriptTextEdit::updateDebugPoints (void )
29422988{
29432989 // prevent re-entrancy
@@ -3066,7 +3112,22 @@ void QtSLiMScriptTextEdit::highlightCurrentLine()
30663112 selection.format .setBackground (inDarkMode ? lineHighlightColor_DARK : lineHighlightColor);
30673113 selection.format .setProperty (QTextFormat::FullWidthSelection, true );
30683114 selection.cursor = textCursor ();
3069- selection.cursor .clearSelection ();
3115+
3116+ if (selection.cursor .hasSelection ())
3117+ {
3118+ // with a selection, we want to try to highlight the appropriate range
3119+ // if the selection ends at a newline, we don't want to highlight the
3120+ // next line; want want to highlight the lines that contain visible text
3121+ int start = selection.cursor .selectionStart ();
3122+
3123+ selection.cursor .setPosition (start, QTextCursor::MoveAnchor);
3124+
3125+ // still have a movement bug when the selection changes, the highlight doesn't update correctly in some cases
3126+ // check when/how the message is sent
3127+ }
3128+
3129+ qDebug () << " highlightCurrentLine() with position" << selection.cursor .selectionStart ();
3130+
30703131 extra_selections.append (selection);
30713132 }
30723133
@@ -3272,29 +3333,12 @@ void QtSLiMScriptTextEdit::lineNumberAreaPaintEvent(QPaintEvent *p_paintEvent)
32723333 painter.restore ();
32733334}
32743335
3275- void QtSLiMScriptTextEdit::lineNumberAreaMouseEvent (QMouseEvent *p_mouseEvent )
3336+ int QtSLiMScriptTextEdit::_blockNumberForLocalY (QPointF localPos )
32763337{
3277- if (lineNumberAreaBugWidth == 0 )
3278- return ;
3279-
3280- // For some reason, Qt calls mousePressEvent() first for control-clicks and right-clicks,
3281- // and *then* calls contextMenuEvent(), so we need to detect the context menu situation
3282- // and return without doing anything. Note that Qt::RightButton is set for control-clicks!
3283- if (p_mouseEvent->button () == Qt::RightButton)
3284- return ;
3285-
3286- #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
3287- QPointF localPos = p_mouseEvent->localPos ();
3288- #else
3289- QPointF localPos = p_mouseEvent->position ();
3290- #endif
32913338 qreal localY = localPos.y ();
32923339
32933340 // qDebug() << "localY ==" << localY;
32943341
3295- if ((localPos.x () < 0 ) || (localPos.x () >= lineNumberAreaBugWidth + 2 )) // +2 for a little slop
3296- return ;
3297-
32983342 // Find the position of the click in the document. We loop through the blocks manually.
32993343 QTextBlock block = firstVisibleBlock ();
33003344 int blockNumber = block.blockNumber ();
@@ -3307,12 +3351,11 @@ void QtSLiMScriptTextEdit::lineNumberAreaMouseEvent(QMouseEvent *p_mouseEvent)
33073351 {
33083352 if ((localY >= top) && (localY <= bottom))
33093353 {
3310- toggleDebuggingForLine (blockNumber);
3311- break ;
3354+ return blockNumber;
33123355 }
33133356 else if (localY < top)
33143357 {
3315- break ;
3358+ return - 1 ;
33163359 }
33173360 }
33183361
@@ -3321,6 +3364,89 @@ void QtSLiMScriptTextEdit::lineNumberAreaMouseEvent(QMouseEvent *p_mouseEvent)
33213364 bottom = top + qRound (blockBoundingRect (block).height ());
33223365 ++blockNumber;
33233366 }
3367+
3368+ return -1 ;
3369+ }
3370+
3371+ void QtSLiMScriptTextEdit::lineNumberAreaMousePressEvent (QMouseEvent *p_mouseEvent)
3372+ {
3373+ if (lineNumberAreaBugWidth == 0 )
3374+ return ;
3375+
3376+ // For some reason, Qt calls mousePressEvent() first for control-clicks and right-clicks,
3377+ // and *then* calls contextMenuEvent(), so we need to detect the context menu situation
3378+ // and return without doing anything. Note that Qt::RightButton is set for control-clicks!
3379+ if (p_mouseEvent->button () == Qt::RightButton)
3380+ return ;
3381+
3382+ #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
3383+ QPointF localPos = p_mouseEvent->localPos ();
3384+ #else
3385+ QPointF localPos = p_mouseEvent->position ();
3386+ #endif
3387+
3388+ if (localPos.x () < 0 )
3389+ return ;
3390+
3391+ int blockNumber = _blockNumberForLocalY (localPos);
3392+
3393+ if (blockNumber != -1 )
3394+ {
3395+ if (localPos.x () >= lineNumberAreaBugWidth)
3396+ {
3397+ // This is a click in the line number area, so select the line
3398+ trackingLineSelection = true ;
3399+ trackingLineAnchor = blockNumber;
3400+
3401+ trackLineSelection (blockNumber, trackingLineAnchor);
3402+ }
3403+ else
3404+ {
3405+ // This is a click in the debug point column, so toggle debugging
3406+ toggleDebuggingForLine (blockNumber);
3407+ }
3408+ }
3409+ }
3410+
3411+ void QtSLiMScriptTextEdit::lineNumberAreaMouseMoveEvent (QMouseEvent *p_mouseEvent)
3412+ {
3413+ if (!trackingLineSelection)
3414+ return ;
3415+
3416+ #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
3417+ QPointF localPos = p_mouseEvent->localPos ();
3418+ #else
3419+ QPointF localPos = p_mouseEvent->position ();
3420+ #endif
3421+
3422+ int blockNumber = _blockNumberForLocalY (localPos);
3423+
3424+ if (blockNumber != -1 )
3425+ {
3426+ trackLineSelection (blockNumber, trackingLineAnchor);
3427+ }
3428+ }
3429+
3430+ void QtSLiMScriptTextEdit::lineNumberAreaMouseReleaseEvent (QMouseEvent *p_mouseEvent)
3431+ {
3432+ if (!trackingLineSelection)
3433+ return ;
3434+
3435+ #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
3436+ QPointF localPos = p_mouseEvent->localPos ();
3437+ #else
3438+ QPointF localPos = p_mouseEvent->position ();
3439+ #endif
3440+
3441+ int blockNumber = _blockNumberForLocalY (localPos);
3442+
3443+ if (blockNumber != -1 )
3444+ {
3445+ trackLineSelection (blockNumber, trackingLineAnchor);
3446+ }
3447+
3448+ trackingLineSelection = false ;
3449+ trackingLineAnchor = -1 ;
33243450}
33253451
33263452void QtSLiMScriptTextEdit::lineNumberAreaContextMenuEvent (QContextMenuEvent *p_event)
0 commit comments