From 346930a0a267cf2afbed3aa432cb647ea20b2680 Mon Sep 17 00:00:00 2001
From: Sebastião Guerra <sebastiao.luiz.guerra@gmail.com>
Date: Tue, 20 Oct 2026 06:48:09 -0300
Subject: Add clearCurrentItem() method to TQCombobox and TQListBox.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add a nonvirtual API to clear the current item while preserving the
historical behavior of setCurrentItem(-1). Keep an explicitly empty
selection stable as the popup opens and during keyboard navigation, while
allowing normal navigation and activation to choose an item.

Co-authored-by: Opencode/Big Pickle
Signed-off-by: Sebastião Guerra <sebastiao.luiz.guerra@gmail.com>
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
---
 doc/html/functions.html          |  3 +-
 doc/html/index                   |  2 ++
 doc/html/qt.dcf                  |  2 ++
 doc/html/tqcombobox-members.html |  1 +
 doc/html/tqcombobox.html         |  3 ++
 doc/html/tqlistbox-members.html  |  1 +
 doc/html/tqlistbox.html          |  4 +++
 src/widgets/tqcombobox.cpp       | 71 +++++++++++++++++++++++++++++++------
 src/widgets/tqcombobox.h         |  1 +
 src/widgets/tqlistbox.cpp        | 75 ++++++++++++++++++++++++++++++++++++----
 src/widgets/tqlistbox.h          |  1 +
 11 files changed, 145 insertions(+), 19 deletions(-)

diff --git a/doc/html/functions.html b/doc/html/functions.html
index 8b6765935..4a0b09d9b 100644
--- a/doc/html/functions.html
+++ b/doc/html/functions.html
@@ -385,7 +385,8 @@ c:
  <a href="tqprocess.html#clearArguments">TQProcess</a><li>clearBit:
  <a href="tqbitarray.html#clearBit">TQBitArray</a><li>clearCell:
  <a href="tqtable.html#clearCell">TQTable</a><li>clearCellWidget:
- <a href="tqtable.html#clearCellWidget">TQTable</a><li>clearEdit:
+ <a href="tqtable.html#clearCellWidget">TQTable</a><li>clearCurrentItem:
+ <a href="tqcombobox.html#clearCurrentItem">TQComboBox</a> <a href="tqlistbox.html#clearCurrentItem">TQListBox</a><li>clearEdit:
  <a href="tqcombobox.html#clearEdit">TQComboBox</a><li>clearEntries:
  <a href="tqurloperator.html#clearEntries">TQUrlOperator</a><li>clearFocus:
  <a href="tqwidget.html#clearFocus">TQWidget</a><li>clearGenerated:
diff --git a/doc/html/index b/doc/html/index
index 8cad14b19..a85b9c4d1 100644
--- a/doc/html/index
+++ b/doc/html/index
@@ -959,6 +959,7 @@
 "TQComboBox::autoMask" tqcombobox.html#autoMask-prop
 "TQComboBox::changeItem" tqcombobox.html#changeItem
 "TQComboBox::clear" tqcombobox.html#clear
+"TQComboBox::clearCurrentItem" tqcombobox.html#clearCurrentItem
 "TQComboBox::clearEdit" tqcombobox.html#clearEdit
 "TQComboBox::clearValidator" tqcombobox.html#clearValidator
 "TQComboBox::completionIndex" tqcombobox.html#completionIndex
@@ -3418,6 +3419,7 @@
 "TQListBox::SelectionMode" tqlistbox.html#SelectionMode
 "TQListBox::changeItem" tqlistbox.html#changeItem
 "TQListBox::clear" tqlistbox.html#clear
+"TQListBox::clearCurrentItem" tqlistbox.html#clearCurrentItem
 "TQListBox::clearSelection" tqlistbox.html#clearSelection
 "TQListBox::clicked" tqlistbox.html#clicked
 "TQListBox::columnAt" tqlistbox.html#columnAt
diff --git a/doc/html/qt.dcf b/doc/html/qt.dcf
index 81716a7c7..f545b2b17 100644
--- a/doc/html/qt.dcf
+++ b/doc/html/qt.dcf
@@ -1061,6 +1061,7 @@
     <keyword ref="tqcombobox.html#autoMask-prop">autoMask</keyword>
     <keyword ref="tqcombobox.html#changeItem">changeItem</keyword>
     <keyword ref="tqcombobox.html#clear">clear</keyword>
+    <keyword ref="tqcombobox.html#clearCurrentItem">clearCurrentItem</keyword>
     <keyword ref="tqcombobox.html#clearEdit">clearEdit</keyword>
     <keyword ref="tqcombobox.html#clearValidator">clearValidator</keyword>
     <keyword ref="tqcombobox.html#completionIndex">completionIndex</keyword>
@@ -3986,6 +3987,7 @@
     <keyword ref="tqlistbox.html#SelectionMode">SelectionMode</keyword>
     <keyword ref="tqlistbox.html#changeItem">changeItem</keyword>
     <keyword ref="tqlistbox.html#clear">clear</keyword>
+    <keyword ref="tqlistbox.html#clearCurrentItem">clearCurrentItem</keyword>
     <keyword ref="tqlistbox.html#clearSelection">clearSelection</keyword>
     <keyword ref="tqlistbox.html#clicked">clicked</keyword>
     <keyword ref="tqlistbox.html#columnAt">columnAt</keyword>
diff --git a/doc/html/tqcombobox-members.html b/doc/html/tqcombobox-members.html
index 77106bf00..bba78b562 100644
--- a/doc/html/tqcombobox-members.html
+++ b/doc/html/tqcombobox-members.html
@@ -60,6 +60,7 @@ body { background: #ffffff; color: black; }
 <li><a href="tqwidget.html#childrenRegion">childrenRegion</a>()
 <li><a href="tqobject.html#className">className</a>()
 <li><a href="tqcombobox.html#clear">clear</a>()
+<li><a href="tqcombobox.html#clearCurrentItem">clearCurrentItem</a>()
 <li><a href="tqcombobox.html#clearEdit">clearEdit</a>()
 <li><a href="tqwidget.html#clearFocus">clearFocus</a>()
 <li><a href="tqwidget.html#clearMask">clearMask</a>()
diff --git a/doc/html/tqcombobox.html b/doc/html/tqcombobox.html
index 8a7aaeb68..3e01fbb59 100644
--- a/doc/html/tqcombobox.html
+++ b/doc/html/tqcombobox.html
@@ -51,6 +51,7 @@ body { background: #ffffff; color: black; }
 <li class=fn>void <a href="#removeItem"><b>removeItem</b></a> ( int&nbsp;index )</li>
 <li class=fn>int <a href="#currentItem"><b>currentItem</b></a> () const</li>
 <li class=fn>virtual void <a href="#setCurrentItem"><b>setCurrentItem</b></a> ( int&nbsp;index )</li>
+<li class=fn>void <a href="#clearCurrentItem"><b>clearCurrentItem</b></a> ()</li>
 <li class=fn>TQString <a href="#currentText"><b>currentText</b></a> () const</li>
 <li class=fn>virtual void <a href="#setCurrentText"><b>setCurrentText</b></a> ( const TQString &amp; )</li>
 <li class=fn>TQString <a href="#text"><b>text</b></a> ( int&nbsp;index ) const</li>
@@ -429,6 +430,8 @@ See the <a href="tqcombobox.html#autoResize-prop">"autoResize"</a> property for
 <h3 class=fn>void <a name="setCurrentItem"></a>TQComboBox::setCurrentItem ( int&nbsp;index )<tt> [virtual]</tt>
 </h3><p>Sets the index of the current item in the combobox to <em>index</em>.
 See the <a href="tqcombobox.html#currentItem-prop">"currentItem"</a> property for details.
+<h3 class=fn>void <a name="clearCurrentItem"></a>TQComboBox::clearCurrentItem ()
+</h3><p>Clears the current item selection without removing any item. The current item index becomes -1 and the line edit text is left unchanged; use <a href="#clearEdit">clearEdit</a>() to clear that text.
 <h3 class=fn>void <a name="setCurrentText"></a>TQComboBox::setCurrentText ( const&nbsp;<a href="tqstring.html">TQString</a>&nbsp;&amp; )<tt> [virtual]</tt>
 </h3><p>Sets the text of the combobox's current item.
 See the <a href="tqcombobox.html#currentText-prop">"currentText"</a> property for details.
diff --git a/doc/html/tqlistbox-members.html b/doc/html/tqlistbox-members.html
index 857b6a53c..7ac72c919 100644
--- a/doc/html/tqlistbox-members.html
+++ b/doc/html/tqlistbox-members.html
@@ -69,6 +69,7 @@ body { background: #ffffff; color: black; }
 <li><a href="tqwidget.html#childrenRegion">childrenRegion</a>()
 <li><a href="tqobject.html#className">className</a>()
 <li><a href="tqlistbox.html#clear">clear</a>()
+<li><a href="tqlistbox.html#clearCurrentItem">clearCurrentItem</a>()
 <li><a href="tqwidget.html#clearFocus">clearFocus</a>()
 <li><a href="tqwidget.html#clearMask">clearMask</a>()
 <li><a href="tqlistbox.html#clearSelection">clearSelection</a>()
diff --git a/doc/html/tqlistbox.html b/doc/html/tqlistbox.html
index 329a14dc0..46f133c42 100644
--- a/doc/html/tqlistbox.html
+++ b/doc/html/tqlistbox.html
@@ -62,6 +62,7 @@ body { background: #ffffff; color: black; }
 <li class=fn>TQString <a href="#currentText"><b>currentText</b></a> () const</li>
 <li class=fn>virtual void <a href="#setCurrentItem"><b>setCurrentItem</b></a> ( int&nbsp;index )</li>
 <li class=fn>virtual void <a href="#setCurrentItem-2"><b>setCurrentItem</b></a> ( TQListBoxItem&nbsp;*&nbsp;i )</li>
+<li class=fn>void <a href="#clearCurrentItem"><b>clearCurrentItem</b></a> ()</li>
 <li class=fn>void centerCurrentItem () &nbsp;<em>(obsolete)</em></li>
 <li class=fn>int <a href="#topItem"><b>topItem</b></a> () const</li>
 <li class=fn>virtual void <a href="#setTopItem"><b>setTopItem</b></a> ( int&nbsp;index )</li>
@@ -945,6 +946,9 @@ See the <a href="tqlistbox.html#currentItem-prop">"currentItem"</a> property for
 This is an overloaded member function, provided for convenience. It behaves essentially like the above function.
 <p> Sets the current item to the <a href="tqlistboxitem.html">TQListBoxItem</a> <em>i</em>.
 
+<h3 class=fn>void <a name="clearCurrentItem"></a>TQListBox::clearCurrentItem ()
+</h3><p>Clears the current item, if any. After this call currentItem() is -1: the list box has no current item at all, and any selection on the former current item is cleared. The items themselves are left in place. The next keyboard navigation action establishes a new current item; for example, pressing Down from this state selects the first item.
+
 <h3 class=fn>void <a name="setMultiSelection"></a>TQListBox::setMultiSelection ( bool&nbsp;multi )
 </h3><p>Sets whether or not the list box is in Multi selection mode to <em>multi</em>.
 See the <a href="tqlistbox.html#multiSelection-prop">"multiSelection"</a> property for details.
diff --git a/src/widgets/tqcombobox.cpp b/src/widgets/tqcombobox.cpp
index f6f7736dc..c918225ad 100644
--- a/src/widgets/tqcombobox.cpp
+++ b/src/widgets/tqcombobox.cpp
@@ -1075,6 +1075,36 @@ void TQComboBox::setCurrentItem( int index )
     currentChanged();
 }
 
+/*!
+    Clears the current item selection without removing any item. The current
+    item index becomes -1 and the line edit text is left unchanged; use
+    clearEdit() to clear that text.
+*/
+
+void TQComboBox::clearCurrentItem()
+{
+    bool hadCurrent = d->current >= 0;
+    if ( hadCurrent ) {
+	if ( d->popup() ) {
+	    if ( style().styleHint(TQStyle::SH_ComboBox_Popup, this) )
+		d->popup()->setItemChecked(d->current, false);
+	    if ( d->poppedUp )
+		d->popup()->setActiveItem(-1);
+	}
+
+	d->current = -1;
+	d->completeAt = 0;
+    }
+
+    // Reset the list box in sync with the combo's current index; list box
+    // observers may query the combo synchronously from the notification.
+    if ( d->usingListBox() && d->listBox() )
+	d->listBox()->clearCurrentItem();
+
+    if ( hadCurrent )
+	currentChanged();
+}
+
 bool TQComboBox::autoResize() const
 {
     return d->autoresize;
@@ -1437,7 +1467,9 @@ void TQComboBox::keyPressEvent( TQKeyEvent *e )
 	}
 	return;
     } else if ( d->usingListBox() && e->key() == Key_Up ) {
-	if ( c > 0 )
+	if ( c < 0 && count() && !d->ed )
+	    setCurrentItem( count()-1 );
+	else if ( c > 0 )
 	    setCurrentItem( c-1 );
     } else if ( d->usingListBox() && e->key() == Key_Down ) {
 	if ( ++c < count() )
@@ -1475,9 +1507,12 @@ void TQComboBox::keyPressEvent( TQKeyEvent *e )
     }
 
     c = currentItem();
-    if ( count() && !text( c ).isNull() )
-	emit activated( text( c ) );
-    emit activated( c );
+
+    if ( !d->usingListBox() || d->ed || ( c >= 0 && c < count() ) ) {
+	if ( !text( c ).isNull() )
+	    emit activated( text( c ) );
+	emit activated( c );
+    }
 }
 
 
@@ -1513,6 +1548,8 @@ void TQComboBox::wheelEvent( TQWheelEvent *e )
     } else {
 	if ( e->delta() > 0 ) {
 	    int c = currentItem();
+	    if ( c < 0 && !d->ed )
+		c = count();
 	    if ( c > 0 ) {
 		setCurrentItem( c-1 );
 		emit activated( currentItem() );
@@ -1631,13 +1668,22 @@ void TQComboBox::popup()
 
 	currentLBItem = currentLBItem ? currentLBItem : lb->item( d->current );
 
-	lb->setCurrentItem( currentLBItem );
-	lb->setContentsPos( lb->contentsX(),
-			    lb->viewportToContents( lb->itemRect( currentLBItem ).topLeft() ).y() );
+	if ( !currentLBItem && d->current == -1 && !d->ed ) {
+	    // Cleared state: open with no current item so no phantom selection
+	    // is shown; the first arrow key establishes it naturally.
+	    lb->clearCurrentItem();
+	    if ( lb->count() )
+		lb->setContentsPos( lb->contentsX(),
+				    lb->viewportToContents( lb->itemRect( lb->item( 0 ) ).topLeft() ).y() );
+	} else {
+	    lb->setCurrentItem( currentLBItem );
+	    lb->setContentsPos( lb->contentsX(),
+				lb->viewportToContents( lb->itemRect( currentLBItem ).topLeft() ).y() );
 
-	// set the current item to also be the selected item if it isn't already
-	if ( currentLBItem && currentLBItem->isSelectable() && !currentLBItem->isSelected() )
-	    lb->setSelected( currentLBItem, true );
+	    // set the current item to also be the selected item if it isn't already
+	    if ( currentLBItem && currentLBItem->isSelectable() && !currentLBItem->isSelected() )
+		lb->setSelected( currentLBItem, true );
+	}
 	lb->blockSignals( block );
 	lb->setVScrollBarMode(TQScrollView::Auto);
 
@@ -1681,7 +1727,10 @@ void TQComboBox::popDownListBox()
     d->listBox()->removeEventFilter( this );
     d->listBox()->viewport()->removeEventFilter( this );
     d->listBox()->hide();
-    d->listBox()->setCurrentItem( d->current );
+    if ( d->current == -1 && !d->ed )
+	d->listBox()->clearCurrentItem();
+    else
+	d->listBox()->setCurrentItem( d->current );
     if ( d->arrowDown ) {
 	d->arrowDown = false;
 	repaint( false );
diff --git a/src/widgets/tqcombobox.h b/src/widgets/tqcombobox.h
index 9771f9bec..19fdf90dc 100644
--- a/src/widgets/tqcombobox.h
+++ b/src/widgets/tqcombobox.h
@@ -92,6 +92,7 @@ public:
 
     int		currentItem() const;
     virtual void setCurrentItem( int index );
+    void	clearCurrentItem();
 
     TQString 	currentText() const;
     virtual void setCurrentText( const TQString& );
diff --git a/src/widgets/tqlistbox.cpp b/src/widgets/tqlistbox.cpp
index f03872062..7fff4cfd5 100644
--- a/src/widgets/tqlistbox.cpp
+++ b/src/widgets/tqlistbox.cpp
@@ -82,7 +82,8 @@ public:
 	dirtyDrag ( false ),
 	variableHeight( true /* !!! ### false */ ),
 	variableWidth( false ),
-	inMenuMode( false )
+	inMenuMode( false ),
+	currentItemCleared( false )
     {}
     int findItemByName( int item, const TQString &text );
     ~TQListBoxPrivate();
@@ -139,6 +140,7 @@ public:
     uint variableHeight :1;
     uint variableWidth :1;
     uint inMenuMode :1;
+    uint currentItemCleared :1;
 
     TQRect *rubber;
     TQPtrDict<bool> selectable;
@@ -1474,7 +1476,7 @@ void TQListBox::insertItem( const TQListBoxItem *lbi, int index )
 	}
     }
 
-    if ( hasFocus() && !d->current ) {
+    if ( hasFocus() && !d->current && !d->currentItemCleared ) {
 	d->current = d->head;
 	updateItem( d->current );
 	emit highlighted( d->current );
@@ -1530,7 +1532,7 @@ void TQListBox::insertItem( const TQListBoxItem *lbi, const TQListBoxItem *after
     if ( after == d->last )
 	d->last = (TQListBoxItem*) lbi;
 
-    if ( hasFocus() && !d->current ) {
+    if ( hasFocus() && !d->current && !d->currentItemCleared ) {
 	d->current = d->head;
 	updateItem( d->current );
 	emit highlighted( d->current );
@@ -1642,6 +1644,8 @@ void TQListBox::clear()
     d->mouseMoveRow = -1;
     d->mouseMoveColumn = -1;
     d->selectable.clear();
+    d->selectAnchor = nullptr;
+    d->currentItemCleared = false;
     clearSelection();
     blockSignals( blocked );
     triggerUpdate( true );
@@ -1843,6 +1847,8 @@ void TQListBox::setCurrentItem( TQListBoxItem * i )
     if ( !i || d->current == i || numRows() == 0 )
 	return;
 
+    d->currentItemCleared = false;
+
     TQRect mfrect = itemRect( i );
     if ( mfrect.isValid() )
 	setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), false );
@@ -1897,6 +1903,58 @@ void TQListBox::setCurrentItem( TQListBoxItem * i )
 }
 
 
+/*!
+    Clears the current item, if any. After this call currentItem() is -1:
+    the list box has no current item at all, and any selection on the
+    former current item is cleared. The items themselves are left in place.
+    The cleared state is retained when the list box receives focus; the
+    next keyboard navigation or pointer selection establishes a current item.
+    If the former current item was selected, selectionChanged() is emitted
+    before currentChanged(0). currentChanged(0) is emitted whenever a current
+    item is cleared.
+
+    The next keyboard navigation action establishes a new current item;
+    for example, pressing Down from this state selects the first item.
+
+    \sa setCurrentItem(), currentItem(), clearSelection()
+*/
+
+void TQListBox::clearCurrentItem()
+{
+    TQListBoxItem *o = d->current;
+
+    d->currentItemCleared = true;
+    d->selectAnchor = nullptr;
+
+    if ( !o )
+	return;
+
+    bool wasSelected = o->s;
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+    int oldIndex = index( o );
+#endif
+
+    d->current = nullptr;
+    d->currentRow = d->currentColumn = -1;
+    d->tmpCurrent = nullptr;
+
+    if ( wasSelected ) {
+	o->s = false;
+	emit selectionChanged();
+    }
+#if defined(QT_ACCESSIBILITY_SUPPORT)
+    TQAccessible::updateAccessibility( viewport(), oldIndex + 1, TQAccessible::StateChanged );
+    if ( wasSelected ) {
+	TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+	if ( selectionMode() != Single )
+	    TQAccessible::updateAccessibility( viewport(), oldIndex + 1, TQAccessible::SelectionRemove );
+    }
+#endif
+    updateItem( o );
+    emit currentChanged( (TQListBoxItem *)0 );
+}
+
+
 /*!
     Returns a pointer to the item at position \a index, or 0 if \a
     index is out of bounds.
@@ -2025,6 +2083,7 @@ void TQListBox::mousePressEventEx( TQMouseEvent *e )
     TQListBoxItem * i = itemAt( e->pos() );
 
     if ( !i && !d->current && d->head ) {
+	d->currentItemCleared = false;
 	d->current = d->head;
 	updateItem( d->head );
     }
@@ -2452,9 +2511,9 @@ void TQListBox::keyPressEvent( TQKeyEvent *e )
 
     TQListBoxItem *old = d->current;
     if ( !old ) {
-	setCurrentItem( d->head );
-	if ( d->selectionMode == Single )
-	    setSelected( d->head, true );
+	setCurrentItem( e->key() == Key_Up ? d->last : d->head );
+	if ( d->selectionMode == Single && d->current )
+	    setSelected( d->current, true );
 	e->ignore();
 	return;
     }
@@ -2698,7 +2757,8 @@ void TQListBox::focusInEvent( TQFocusEvent* )
     d->mousePressRow = -1;
     d->mousePressColumn = -1;
     d->inMenuMode = false;
-    if ( TQFocusEvent::reason() != TQFocusEvent::Mouse && !d->current && d->head ) {
+    if ( TQFocusEvent::reason() != TQFocusEvent::Mouse && !d->current && d->head &&
+	 !d->currentItemCleared ) {
 	d->current = d->head;
 	TQListBoxItem *i = d->current;
 	TQString tmp;
@@ -2904,6 +2964,7 @@ void TQListBox::setSelected( TQListBoxItem * item, bool select )
 	    if ( d->current && d->current->s )
 		d->current->s = false;
 	    d->current = item;
+	    d->currentItemCleared = false;
 #if defined(QT_ACCESSIBILITY_SUPPORT)
 	    TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::Focus );
 #endif
diff --git a/src/widgets/tqlistbox.h b/src/widgets/tqlistbox.h
index 2b357633f..ad0d7b356 100644
--- a/src/widgets/tqlistbox.h
+++ b/src/widgets/tqlistbox.h
@@ -115,6 +115,7 @@ public:
     TQString currentText() const { return text(currentItem()); }
     virtual void setCurrentItem( int index );
     virtual void setCurrentItem( TQListBoxItem * );
+    void clearCurrentItem();
     void centerCurrentItem() { ensureCurrentVisible(); }
     int topItem() const;
     virtual void setTopItem( int index );
-- 
cgit v1.2.3

