Merge branch 'qt-fixups'

Various fixes and improvements for wxQt.

Closes #22932.
This commit is contained in:
Vadim Zeitlin 2022-11-12 17:37:54 +01:00
commit b200d7032f
15 changed files with 124 additions and 65 deletions

View file

@ -76,6 +76,8 @@ public:
virtual void WriteText(const wxString &value) override;
virtual void SetInsertionPoint(long insertion) override;
virtual long GetInsertionPoint() const override;
virtual bool IsEditable() const override;
virtual void SetEditable(bool editable) override;
virtual void Popup();
virtual void Dismiss();

View file

@ -458,4 +458,28 @@ protected:
}
};
// RAII wrapper for blockSignals(). It blocks signals in its constructor and in
// the destructor it restores the state to what it was before the constructor ran.
class wxQtEnsureSignalsBlocked
{
public:
// Use QObject instead of QWidget to avoid including <QWidget> from here.
wxQtEnsureSignalsBlocked(QObject *widget) :
m_widget(widget)
{
m_restore = m_widget->blockSignals(true);
}
~wxQtEnsureSignalsBlocked()
{
m_widget->blockSignals(m_restore);
}
private:
QObject* const m_widget;
bool m_restore;
wxDECLARE_NO_COPY_CLASS(wxQtEnsureSignalsBlocked);
};
#endif

View file

@ -137,9 +137,8 @@ bool wxCalendarCtrl::SetDate(const wxDateTime& date)
wxQtConvertDate( date ) < m_qtCalendar->minimumDate() )
return false;
m_qtCalendar->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtCalendar);
m_qtCalendar->setSelectedDate(wxQtConvertDate(date));
m_qtCalendar->blockSignals(false);
return true;
}
@ -158,10 +157,9 @@ bool wxCalendarCtrl::SetDateRange(const wxDateTime& lowerdate,
if ( !m_qtCalendar )
return false;
m_qtCalendar->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtCalendar);
m_qtCalendar->setMinimumDate(wxQtConvertDate(lowerdate));
m_qtCalendar->setMaximumDate(wxQtConvertDate(upperdate));
m_qtCalendar->blockSignals(false);
return true;
}

View file

@ -9,6 +9,7 @@
#include "wx/wxprec.h"
#include "wx/checklst.h"
#include "wx/qt/private/winevent.h"
#include <QtWidgets/QListWidgetItem>
@ -80,8 +81,11 @@ bool wxCheckListBox::IsChecked(unsigned int n) const
void wxCheckListBox::Check(unsigned int n, bool check )
{
// Prevent the emission of wxEVT_CHECKLISTBOX event by temporarily blocking all
// signals on m_qtListWidget object.
wxQtEnsureSignalsBlocked blocker(m_qtListWidget);
QListWidgetItem* item = m_qtListWidget->item(n);
wxCHECK_RET(item != nullptr, wxT("wrong listbox index") );
return item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
item->setCheckState(check ? Qt::Checked : Qt::Unchecked);
}

View file

@ -161,6 +161,8 @@ unsigned wxChoice::GetCount() const
wxString wxChoice::GetString(unsigned int n) const
{
wxCHECK_MSG(n < GetCount(), wxString(), "invalid index");
return wxQtConvertString( m_qtComboBox->itemText(n) );
}
@ -172,9 +174,8 @@ void wxChoice::SetString(unsigned int n, const wxString& s)
void wxChoice::SetSelection(int n)
{
m_qtComboBox->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtComboBox);
m_qtComboBox->setCurrentIndex(n);
m_qtComboBox->blockSignals(false);
}
int wxChoice::GetSelection() const

View file

@ -190,6 +190,20 @@ bool wxComboBox::IsReadOnly() const
return HasFlag( wxCB_READONLY );
}
bool wxComboBox::IsEditable() const
{
// Only editable combo boxes have a line edit.
QLineEdit* const lineEdit = m_qtComboBox->lineEdit();
return lineEdit && !lineEdit->isReadOnly();
}
void wxComboBox::SetEditable(bool editable)
{
QLineEdit* const lineEdit = m_qtComboBox->lineEdit();
if ( lineEdit )
lineEdit->setReadOnly(!editable);
}
void wxComboBox::SetValue(const wxString& value)
{
SetActualValue( value );

View file

@ -373,6 +373,21 @@ void wxQtDCImpl::DoGetTextExtent(const wxString& string,
wxCoord *externalLeading,
const wxFont *theFont ) const
{
if ( x )
*x = 0;
if ( y )
*y = 0;
if ( descent )
*descent = 0;
if ( externalLeading )
*externalLeading = 0;
// We can skip computing the string width and height if it is empty, but
// not its descent and/or external leading, which still needs to be
// returned even for an empty string.
if ( string.empty() && !descent && !externalLeading )
return;
QFont f;
if (theFont != nullptr)
f = theFont->GetHandle();

View file

@ -960,6 +960,21 @@ public:
wxCHECK_RET( !m_font.IsNull(),
"wxQtContext::GetTextExtent - no valid font set" );
if ( width )
*width = 0;
if ( height )
*height = 0;
if ( descent )
*descent = 0;
if ( externalLeading )
*externalLeading = 0;
// We can skip computing the string width and height if it is empty, but
// not its descent and/or external leading, which still needs to be
// returned even for an empty string.
if ( str.empty() && !descent && !externalLeading )
return;
EnsurePainterIsActive active(m_qtPainter);
const wxQtFontData*

View file

@ -654,15 +654,15 @@ public:
beginInsertColumns(QModelIndex(), newColumnIndex, newColumnIndex);
std::vector<ColumnItem>::iterator i = m_headers.begin();
std::advance(i, newColumnIndex);
m_headers.insert(i, newColumn);
std::vector<ColumnItem>::iterator it = m_headers.begin();
std::advance(it, newColumnIndex);
m_headers.insert(it, newColumn);
const int numberOfRows = m_rows.size();
for (int i = 0; i < numberOfRows; ++i )
{
std::vector<ColumnItem>::iterator it = m_rows[i].m_columns.begin();
it = m_rows[i].m_columns.begin();
std::advance(it, newColumnIndex);
m_rows[i].m_columns.insert(it, newColumn);
}

View file

@ -178,15 +178,11 @@ bool wxNotebook::DeleteAllPages()
// Block signals to not receive selection changed updates
// which are sent by Qt after the selected page was deleted.
m_qtTabWidget->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtTabWidget);
// Pages will be deleted one by one in the base class.
// There's no need to explicitly clear() the Qt control.
bool deleted = wxNotebookBase::DeleteAllPages();
m_qtTabWidget->blockSignals(false);
return deleted;
return wxNotebookBase::DeleteAllPages();
}
int wxNotebook::SetSelection(size_t page)
@ -206,13 +202,9 @@ int wxNotebook::ChangeSelection(size_t nPage)
{
// ChangeSelection() is not supposed to generate events, unlike
// SetSelection().
m_qtTabWidget->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtTabWidget);
const int selOld = SetSelection(nPage);
m_qtTabWidget->blockSignals(false);
return selOld;
return SetSelection(nPage);
}
wxWindow *wxNotebook::DoRemovePage(size_t page)

View file

@ -101,9 +101,10 @@ void wxScrollBar::SetScrollbar(int position, int WXUNUSED(thumbSize),
{
m_qtScrollBar->setRange( 0, range - pageSize );
m_qtScrollBar->setPageStep( pageSize );
m_qtScrollBar->blockSignals(true);
m_qtScrollBar->setValue( position );
m_qtScrollBar->blockSignals(false);
{
wxQtEnsureSignalsBlocked blocker(m_qtScrollBar);
m_qtScrollBar->setValue( position );
}
m_qtScrollBar->show();
}
else

View file

@ -77,9 +77,8 @@ bool wxSlider::Create(wxWindow *parent,
m_qtSlider->setInvertedAppearance( style & wxSL_INVERSE );
m_qtSlider->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtSlider);
SetRange( minValue, maxValue );
m_qtSlider->blockSignals(false);
SetPageSize(wxMax(1, (maxValue - minValue) / 10));
#if 0 // there are not normally ticks for a wxSlider
@ -105,16 +104,14 @@ int wxSlider::GetValue() const
void wxSlider::SetValue(int value)
{
m_qtSlider->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtSlider);
m_qtSlider->setValue( value );
m_qtSlider->blockSignals(false);
}
void wxSlider::SetRange(int minValue, int maxValue)
{
m_qtSlider->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtSlider);
m_qtSlider->setRange( minValue, maxValue );
m_qtSlider->blockSignals(false);
}
int wxSlider::GetMin() const

View file

@ -67,17 +67,15 @@ wxString wxSpinCtrlQt< T, Widget >::GetTextValue() const
template< typename T, typename Widget >
void wxSpinCtrlQt< T, Widget >::SetValue( T val )
{
m_qtSpinBox->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtSpinBox);
m_qtSpinBox->setValue( val );
m_qtSpinBox->blockSignals(false);
}
template< typename T, typename Widget >
void wxSpinCtrlQt< T, Widget >::SetRange( T min, T max )
{
m_qtSpinBox->blockSignals(true);
wxQtEnsureSignalsBlocked blocker(m_qtSpinBox);
m_qtSpinBox->setRange( min, max );
m_qtSpinBox->blockSignals(false);
}
template< typename T, typename Widget >

View file

@ -357,9 +357,8 @@ private:
if ( !changingEvent.IsAllowed() )
{
blockSignals(true);
wxQtEnsureSignalsBlocked blocker(this);
setCurrentItem(previous);
blockSignals(false);
return;
}
@ -398,9 +397,8 @@ private:
if ( !collapsingEvent.IsAllowed() )
{
blockSignals(true);
wxQtEnsureSignalsBlocked blocker(this);
item->setExpanded(true);
blockSignals(false);
return;
}
@ -423,9 +421,8 @@ private:
if ( !expandingEvent.IsAllowed() )
{
blockSignals(true);
wxQtEnsureSignalsBlocked blocker(this);
item->setExpanded(false);
blockSignals(false);
return;
}
@ -1116,25 +1113,6 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item)
delete qTreeItem;
}
class wxQtEnsureSignalsBlocked
{
public:
wxQtEnsureSignalsBlocked(QWidget *widget) :
m_widget(widget)
{
m_restore = m_widget->blockSignals(true);
}
~wxQtEnsureSignalsBlocked()
{
m_widget->blockSignals(m_restore);
}
private:
QWidget *m_widget;
bool m_restore;
};
void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
{
wxCHECK_RET(item.IsOk(), "invalid tree item");

View file

@ -419,6 +419,9 @@ void wxWindowQt::PostCreation(bool generic)
GetHandle()->setFont( wxWindowBase::GetFont().GetHandle() );
if ( !IsThisEnabled() )
DoEnable(false);
// The window might have been hidden before Create() and it needs to remain
// hidden in this case, so do it (unfortunately there doesn't seem to be
// any way to create the window initially hidden with Qt).
@ -474,7 +477,8 @@ wxString wxWindowQt::GetLabel() const
void wxWindowQt::DoEnable(bool enable)
{
GetHandle()->setEnabled(enable);
if ( GetHandle() )
GetHandle()->setEnabled(enable);
}
void wxWindowQt::SetFocus()
@ -636,6 +640,21 @@ int wxWindowQt::GetCharWidth() const
void wxWindowQt::DoGetTextExtent(const wxString& string, int *x, int *y, int *descent,
int *externalLeading, const wxFont *font ) const
{
if ( x )
*x = 0;
if ( y )
*y = 0;
if ( descent )
*descent = 0;
if ( externalLeading )
*externalLeading = 0;
// We can skip computing the string width and height if it is empty, but
// not its descent and/or external leading, which still needs to be
// returned even for an empty string.
if ( string.empty() && !descent && !externalLeading )
return;
QFontMetrics fontMetrics( font != nullptr ? font->GetHandle() : GetHandle()->font() );
if ( x != nullptr )
@ -726,9 +745,10 @@ void wxWindowQt::SetScrollbar( int orientation, int pos, int thumbvisible, int r
{
scrollBar->setRange( 0, range - thumbvisible );
scrollBar->setPageStep( thumbvisible );
scrollBar->blockSignals( true );
scrollBar->setValue(pos);
scrollBar->blockSignals( false );
{
wxQtEnsureSignalsBlocked blocker(scrollBar);
scrollBar->setValue(pos);
}
scrollBar->show();
if ( HasFlag(wxALWAYS_SHOW_SB) && (range == 0) )