mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-28 15:50:17 +08:00
Merge branch 'qt-fixes' of github.com:AliKet/wxWidgets
Miscellaneous wxQt fixes. See #25968.
This commit is contained in:
+5
-4
@@ -36,13 +36,13 @@ public:
|
||||
|
||||
QMdiArea* GetQtMdiArea() const;
|
||||
|
||||
enum class Layout
|
||||
enum class Kind
|
||||
{
|
||||
MDI,
|
||||
Tabbed
|
||||
};
|
||||
|
||||
void QtSetPreferredDILayout(Layout layout);
|
||||
void QtSetPreferredDILayout(Kind layout);
|
||||
|
||||
// override/implement base class [pure] virtual methods
|
||||
// ----------------------------------------------------
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
// The default is to return what wxMDIParentFrame::IsTDI() is supposed to
|
||||
// return under the target platform. i.e. wxMSW and wxOSX return false,
|
||||
// while wxGTK returns true. Use QtSetPreferredDILayout() to change that.
|
||||
static bool IsTDI() { return ms_layout == Layout::Tabbed; }
|
||||
static bool IsTDI() { return ms_layout == Kind::Tabbed; }
|
||||
|
||||
virtual void Cascade() override;
|
||||
virtual void Tile(wxOrientation orient = wxHORIZONTAL) override;
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
|
||||
// TDI=true, MDI=false
|
||||
// Default to false under Windows, true otherwise.
|
||||
static Layout ms_layout;
|
||||
static Kind ms_layout;
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS(wxMDIParentFrame);
|
||||
};
|
||||
@@ -154,6 +154,7 @@ class WXDLLIMPEXP_CORE wxMDIClientWindow : public wxMDIClientWindowBase
|
||||
{
|
||||
public:
|
||||
wxMDIClientWindow() = default;
|
||||
~wxMDIClientWindow();
|
||||
|
||||
virtual bool CreateClient(wxMDIParentFrame *parent, long style = wxVSCROLL | wxHSCROLL) override;
|
||||
|
||||
|
||||
+37
-36
@@ -865,8 +865,17 @@ void wxQtDCImpl::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
|
||||
}
|
||||
|
||||
void wxQtDCImpl::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
|
||||
{
|
||||
DoDrawRotatedText(text, x, y, 0.0);
|
||||
}
|
||||
|
||||
void wxQtDCImpl::DoDrawRotatedText(const wxString& text,
|
||||
wxCoord x, wxCoord y, double angle)
|
||||
{
|
||||
m_qtPainter->save();
|
||||
// Move and rotate (reverse angle direction in Qt and wx)
|
||||
m_qtPainter->translate(x, y);
|
||||
m_qtPainter->rotate(-angle);
|
||||
|
||||
m_qtPainter->setPen(QPen(m_textForegroundColour.GetQColor()));
|
||||
|
||||
@@ -884,57 +893,49 @@ void wxQtDCImpl::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
|
||||
{
|
||||
// text is not mirrored
|
||||
m_qtPainter->scale(-1, 1);
|
||||
x = -x;
|
||||
}
|
||||
|
||||
QRect boundingRect; // Bounding rectangle for non rotated text.
|
||||
QRect* boundingRectPtr = AreAutomaticBoundingBoxUpdatesEnabled()
|
||||
? &boundingRect : nullptr;
|
||||
|
||||
QFontMetrics metrics = m_qtPainter->fontMetrics();
|
||||
|
||||
int lineSpacing = 0;
|
||||
wxStringTokenizer tokenizer(text, "\n");
|
||||
while ( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
const wxString line = tokenizer.GetNextToken();
|
||||
m_qtPainter->drawText(x, y, 1, 1, Qt::TextDontClip, wxQtConvertString(line));
|
||||
y += metrics.lineSpacing();
|
||||
m_qtPainter->drawText(0, lineSpacing, 1, 1, Qt::TextDontClip,
|
||||
wxQtConvertString(line), boundingRectPtr);
|
||||
lineSpacing += metrics.lineSpacing();
|
||||
|
||||
if ( AreAutomaticBoundingBoxUpdatesEnabled() && wxIsNullDouble(angle) )
|
||||
{
|
||||
CalcBoundingBox(wxQtConvertRect(boundingRect));
|
||||
}
|
||||
}
|
||||
|
||||
m_qtPainter->restore();
|
||||
}
|
||||
|
||||
void wxQtDCImpl::DoDrawRotatedText(const wxString& text,
|
||||
wxCoord x, wxCoord y, double angle)
|
||||
{
|
||||
m_qtPainter->save();
|
||||
|
||||
if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
|
||||
m_qtPainter->setBackgroundMode(Qt::OpaqueMode);
|
||||
|
||||
if ( GetLayoutDirection() == wxLayout_RightToLeft )
|
||||
// Calculate bounding rectangle for rotated text.
|
||||
if ( AreAutomaticBoundingBoxUpdatesEnabled() && !wxIsNullDouble(angle) )
|
||||
{
|
||||
m_qtPainter->scale(-1, 1);
|
||||
const double rad = wxDegToRad(angle);
|
||||
|
||||
x = -x;
|
||||
angle = -angle;
|
||||
const QFontMetrics metrics = m_qtPainter->fontMetrics();
|
||||
const QRect rect = metrics.boundingRect(wxQtConvertString(text));
|
||||
const int w = rect.width();
|
||||
const int h = rect.height();
|
||||
|
||||
// "upper left" and "upper right"
|
||||
CalcBoundingBox(x, y, x + wxCoord(w*cos(rad)), y - wxCoord(w*sin(rad)));
|
||||
|
||||
// "bottom left" and "bottom right"
|
||||
x += (wxCoord)(h*sin(rad));
|
||||
y += (wxCoord)(h*cos(rad));
|
||||
CalcBoundingBox(x, y, x + wxCoord(w*cos(rad)), y - wxCoord(w*sin(rad)));
|
||||
}
|
||||
|
||||
//Move and rotate (reverse angle direction in Qt and wx)
|
||||
m_qtPainter->translate(x, y);
|
||||
m_qtPainter->rotate(-angle);
|
||||
|
||||
m_qtPainter->setPen(QPen(m_textForegroundColour.GetQColor()));
|
||||
|
||||
// Disable logical function
|
||||
m_qtPainter->setCompositionMode( QPainter::CompositionMode_SourceOver );
|
||||
|
||||
if (m_backgroundMode == wxBRUSHSTYLE_SOLID)
|
||||
{
|
||||
m_qtPainter->setBackgroundMode(Qt::OpaqueMode);
|
||||
|
||||
m_qtPainter->setBackground(QBrush(m_textBackgroundColour.GetQColor()));
|
||||
}
|
||||
|
||||
m_qtPainter->drawText(0, 0, 1, 1, Qt::TextDontClip, wxQtConvertString(text));
|
||||
|
||||
m_qtPainter->restore();
|
||||
}
|
||||
|
||||
bool wxQtDCImpl::DoBlit(wxCoord xdest, wxCoord ydest,
|
||||
|
||||
+5
-1
@@ -62,9 +62,13 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString& title,
|
||||
{
|
||||
m_qtWindow = new wxQtMainWindow( parent, this );
|
||||
|
||||
// QMainWindow takes ownership of the central widget pointer.
|
||||
// Not using QScrollArea or wxPanel is intentional here as it makes the
|
||||
// implementation simpler and more manageable.
|
||||
//
|
||||
// Quoting the Qt docs [QMainWindow::setCentralWidget()]:
|
||||
// QMainWindow takes ownership of the widget pointer and deletes it at
|
||||
// the appropriate time.
|
||||
//
|
||||
GetQMainWindow()->setCentralWidget( new wxQtCentralWidget( this, this ) );
|
||||
|
||||
if ( !wxFrameBase::Create( parent, id, title, pos, size, style, name ) )
|
||||
|
||||
+23
-10
@@ -27,11 +27,11 @@ static QMdiSubWindow* gs_qtActiveSubWindow = nullptr;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
wxMDIParentFrame::Layout wxMDIParentFrame::ms_layout =
|
||||
wxMDIParentFrame::Kind wxMDIParentFrame::ms_layout =
|
||||
#if defined(__WINDOWS__)
|
||||
Layout::MDI;
|
||||
Kind::MDI;
|
||||
#else // !__WINDOWS__
|
||||
Layout::Tabbed;
|
||||
Kind::Tabbed;
|
||||
#endif // __WINDOWS__
|
||||
|
||||
// Central widget helper (provides an area in which MDI windows are displayed):
|
||||
@@ -89,7 +89,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxMDIParentFrame::QtSetPreferredDILayout(Layout layout)
|
||||
void wxMDIParentFrame::QtSetPreferredDILayout(Kind layout)
|
||||
{
|
||||
ms_layout = layout;
|
||||
|
||||
@@ -97,11 +97,11 @@ void wxMDIParentFrame::QtSetPreferredDILayout(Layout layout)
|
||||
|
||||
switch ( layout )
|
||||
{
|
||||
case Layout::MDI:
|
||||
case Kind::MDI:
|
||||
viewMode = QMdiArea::SubWindowView;
|
||||
break;
|
||||
|
||||
case Layout::Tabbed:
|
||||
case Kind::Tabbed:
|
||||
viewMode = QMdiArea::TabbedView;
|
||||
break;
|
||||
|
||||
@@ -242,10 +242,7 @@ void wxMDIParentFrame::AddWindowMenu()
|
||||
{
|
||||
m_windowMenu = new wxMenu;
|
||||
|
||||
// Qt offers only "Tile" without specifying any direction, so just
|
||||
// reuse one of the predifined ids.
|
||||
|
||||
if ( ms_layout == Layout::MDI )
|
||||
if ( ms_layout == Kind::MDI )
|
||||
{
|
||||
// Qt offers only "Tile" without specifying any direction, so just
|
||||
// reuse one of the predifined ids.
|
||||
@@ -428,6 +425,13 @@ void wxMDIChildFrame::SetMenuBar(wxMenuBar* menuBar)
|
||||
|
||||
m_menuBar = menuBar;
|
||||
|
||||
if ( m_mdiParent->GetActiveChild() == this )
|
||||
{
|
||||
// Attach the menu bar to m_mdiParent immediately if this child
|
||||
// window is active.
|
||||
InternalSetMenuBar();
|
||||
}
|
||||
|
||||
// Don't call wxFrameBase::SetMenuBar() here because m_menuBar will be
|
||||
// attached to m_mdiParent later when this child frame becomes active.
|
||||
}
|
||||
@@ -496,6 +500,15 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long WXUNUSED(sty
|
||||
return true;
|
||||
}
|
||||
|
||||
wxMDIClientWindow::~wxMDIClientWindow()
|
||||
{
|
||||
DestroyChildren();
|
||||
|
||||
// Prevent the base class dtor from destroying the underlying qt window, as
|
||||
// it is owned by QMainWindow.
|
||||
m_qtWindow = nullptr;
|
||||
}
|
||||
|
||||
// Helper implementation:
|
||||
|
||||
wxQtMdiArea::wxQtMdiArea(wxWindow *parent, wxMDIClientWindow *handler )
|
||||
|
||||
@@ -126,6 +126,7 @@ class wxQtTextEdit : public wxQtEventSignalHandler< QTextEdit, wxTextCtrl >
|
||||
{
|
||||
public:
|
||||
wxQtTextEdit( wxWindow *parent, wxTextCtrl *handler );
|
||||
~wxQtTextEdit();
|
||||
|
||||
virtual wxString GetValueForProcessEnter() override
|
||||
{
|
||||
@@ -778,6 +779,11 @@ wxQtTextEdit::wxQtTextEdit( wxWindow *parent, wxTextCtrl *handler )
|
||||
});
|
||||
}
|
||||
|
||||
wxQtTextEdit::~wxQtTextEdit()
|
||||
{
|
||||
delete m_textLimiter;
|
||||
}
|
||||
|
||||
void wxQtTextEdit::SetMaxLength(unsigned long len)
|
||||
{
|
||||
const unsigned long maxlen = std::numeric_limits<int>::max();
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "waitfor.h"
|
||||
#if defined(__WXGTK__) || defined(__WXQT__)
|
||||
#include "waitfor.h"
|
||||
#endif
|
||||
|
||||
// FIXME: Currently under OS X testing paint event doesn't work because neither
|
||||
// calling Refresh()+Update() nor even sending wxPaintEvent directly to
|
||||
@@ -668,6 +670,7 @@ void EventPropagationTestCase::DocViewCommon(wxFrame* (*newParent)(wxDocManager
|
||||
|
||||
wxMenu* const menuChild = CreateTestMenu(child.get());
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// There are a lot of hacks related to child frame menu bar handling in
|
||||
// wxGTK and, in particular, the code in src/gtk/mdi.cpp relies on getting
|
||||
// idle events to really put everything in place. Moreover, as wxGTK uses
|
||||
@@ -679,8 +682,8 @@ void EventPropagationTestCase::DocViewCommon(wxFrame* (*newParent)(wxDocManager
|
||||
// make things work "as usual".
|
||||
child->Show();
|
||||
parent->Show();
|
||||
child->SetFocus(); // Without this, the test would fail on wxGTK2
|
||||
YieldForAWhile();
|
||||
wxYield();
|
||||
#endif // __WXGTK__
|
||||
|
||||
TestEvtSink sinkDoc('d');
|
||||
doc->Connect(wxEVT_MENU,
|
||||
@@ -696,25 +699,7 @@ void EventPropagationTestCase::DocViewCommon(wxFrame* (*newParent)(wxDocManager
|
||||
|
||||
// Check that wxDocument, wxView, wxDocManager, child frame and the parent
|
||||
// get the event in order.
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
// We use wxUIActionSimulator instead of ASSERT_MENU_EVENT_RESULT because
|
||||
// using the latter fails with wxQt on Linux.
|
||||
wxUnusedVar(menuChild);
|
||||
g_str.clear();
|
||||
|
||||
wxUIActionSimulator sim;
|
||||
sim.Char('m', wxMOD_ALT);
|
||||
// N.B.: Don't call wxYield() here, as this will cause the menu to appear
|
||||
// immediately (and enter its internal message loop) and the next line will
|
||||
// never be executed under wxMSW. In other words, the execution would block
|
||||
// indefinitely.
|
||||
sim.Char('a');
|
||||
wxYield();
|
||||
|
||||
CHECK( g_str == "advmcpA" );
|
||||
#else // !wxUSE_UIACTIONSIMULATOR
|
||||
ASSERT_MENU_EVENT_RESULT( menuChild, "advmcpA" );
|
||||
#endif // wxUSE_UIACTIONSIMULATOR
|
||||
|
||||
#if wxUSE_TOOLBAR
|
||||
// Also check that toolbar events get forwarded to the active child.
|
||||
|
||||
Reference in New Issue
Block a user