+ // Check if local setting overrides the global setting
+ bool layoutEnabled = (GetLayoutAdaptationMode() == wxDIALOG_ADAPTATION_MODE_ENABLED) || (IsLayoutAdaptationEnabled() && (GetLayoutAdaptationMode() != wxDIALOG_ADAPTATION_MODE_DISABLED));
+
+ return (layoutEnabled && !m_layoutAdaptationDone && GetLayoutAdaptationLevel() != 0 && GetLayoutAdapter() != NULL && GetLayoutAdapter()->CanDoLayoutAdaptation((wxDialog*) this));
+}
+
+/// Set scrolling adapter class, returning old adapter
+wxDialogLayoutAdapter* wxDialogBase::SetLayoutAdapter(wxDialogLayoutAdapter* adapter)
+{
+ wxDialogLayoutAdapter* oldLayoutAdapter = sm_layoutAdapter;
+ sm_layoutAdapter = adapter;
+ return oldLayoutAdapter;
+}
+
+/*!
+ * Standard adapter
+ */
+
+IMPLEMENT_CLASS(wxDialogLayoutAdapter, wxObject)
+
+IMPLEMENT_CLASS(wxStandardDialogLayoutAdapter, wxDialogLayoutAdapter)
+
+// Allow for caption size on wxWidgets < 2.9
+#if defined(__WXGTK__) && !wxCHECK_VERSION(2,9,0)
+#define wxEXTRA_DIALOG_HEIGHT 30
+#else
+#define wxEXTRA_DIALOG_HEIGHT 0
+#endif
+
+/// Indicate that adaptation should be done
+bool wxStandardDialogLayoutAdapter::CanDoLayoutAdaptation(wxDialog* dialog)
+{
+ if (dialog->GetSizer())
+ {
+ wxSize windowSize, displaySize;
+ return MustScroll(dialog, windowSize, displaySize) != 0;
+ }
+ else
+ return false;
+}
+
+bool wxStandardDialogLayoutAdapter::DoLayoutAdaptation(wxDialog* dialog)
+{
+ if (dialog->GetSizer())
+ {
+#if wxUSE_BOOKCTRL
+ wxBookCtrlBase* bookContentWindow = wxDynamicCast(dialog->GetContentWindow(), wxBookCtrlBase);
+
+ if (bookContentWindow)
+ {
+ // If we have a book control, make all the pages (that use sizers) scrollable
+ wxWindowList windows;
+ for (size_t i = 0; i < bookContentWindow->GetPageCount(); i++)
+ {
+ wxWindow* page = bookContentWindow->GetPage(i);
+
+ wxScrolledWindow* scrolledWindow = wxDynamicCast(page, wxScrolledWindow);
+ if (scrolledWindow)
+ windows.Append(scrolledWindow);
+ else if (!scrolledWindow && page->GetSizer())
+ {
+ // Create a scrolled window and reparent
+ scrolledWindow = CreateScrolledWindow(page);
+ wxSizer* oldSizer = page->GetSizer();
+
+ wxSizer* newSizer = new wxBoxSizer(wxVERTICAL);
+ newSizer->Add(scrolledWindow,1, wxEXPAND, 0);
+
+ page->SetSizer(newSizer, false /* don't delete the old sizer */);
+
+ scrolledWindow->SetSizer(oldSizer);
+
+ ReparentControls(page, scrolledWindow);
+
+ windows.Append(scrolledWindow);
+ }
+ }
+
+ FitWithScrolling(dialog, windows);
+ }
+ else
+#endif // wxUSE_BOOKCTRL
+ {
+#if wxUSE_BUTTON
+ // If we have an arbitrary dialog, create a scrolling area for the main content, and a button sizer
+ // for the main buttons.
+ wxScrolledWindow* scrolledWindow = CreateScrolledWindow(dialog);
+
+ int buttonSizerBorder = 0;
+
+ // First try to find a wxStdDialogButtonSizer
+ wxSizer* buttonSizer = FindButtonSizer(true /* find std button sizer */, dialog, dialog->GetSizer(), buttonSizerBorder);
+
+ // Next try to find a wxBoxSizer containing the controls
+ if (!buttonSizer && dialog->GetLayoutAdaptationLevel() > wxDIALOG_ADAPTATION_STANDARD_SIZER)
+ buttonSizer = FindButtonSizer(false /* find ordinary sizer */, dialog, dialog->GetSizer(), buttonSizerBorder);
+
+ // If we still don't have a button sizer, collect any 'loose' buttons in the layout
+ if (!buttonSizer && dialog->GetLayoutAdaptationLevel() > wxDIALOG_ADAPTATION_ANY_SIZER)
+ {
+ int count = 0;
+ wxStdDialogButtonSizer* stdButtonSizer = new wxStdDialogButtonSizer;
+ buttonSizer = stdButtonSizer;
+
+ FindLooseButtons(dialog, stdButtonSizer, dialog->GetSizer(), count);
+ if (count > 0)
+ stdButtonSizer->Realize();
+ else
+ {
+ wxDELETE(buttonSizer);
+ }
+ }
+
+ if (buttonSizerBorder == 0)
+ buttonSizerBorder = 5;
+
+ ReparentControls(dialog, scrolledWindow, buttonSizer);
+
+ wxBoxSizer* newTopSizer = new wxBoxSizer(wxVERTICAL);
+ wxSizer* oldSizer = dialog->GetSizer();
+
+ dialog->SetSizer(newTopSizer, false /* don't delete old sizer */);
+
+ newTopSizer->Add(scrolledWindow, 1, wxEXPAND|wxALL, 0);
+ if (buttonSizer)
+ newTopSizer->Add(buttonSizer, 0, wxEXPAND|wxALL, buttonSizerBorder);
+
+ scrolledWindow->SetSizer(oldSizer);
+
+ FitWithScrolling(dialog, scrolledWindow);
+#endif // wxUSE_BUTTON
+ }
+ }
+
+ dialog->SetLayoutAdaptationDone(true);
+ return true;
+}
+
+// Create the scrolled window
+wxScrolledWindow* wxStandardDialogLayoutAdapter::CreateScrolledWindow(wxWindow* parent)
+{
+ wxScrolledWindow* scrolledWindow = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxVSCROLL|wxHSCROLL|wxBORDER_NONE);
+ return scrolledWindow;
+}
+
+#if wxUSE_BUTTON
+
+/// Find and remove the button sizer, if any
+wxSizer* wxStandardDialogLayoutAdapter::FindButtonSizer(bool stdButtonSizer, wxDialog* dialog, wxSizer* sizer, int& retBorder, int accumlatedBorder)
+{
+ for ( wxSizerItemList::compatibility_iterator node = sizer->GetChildren().GetFirst();
+ node; node = node->GetNext() )
+ {
+ wxSizerItem *item = node->GetData();
+ wxSizer *childSizer = item->GetSizer();
+
+ if ( childSizer )
+ {
+ int newBorder = accumlatedBorder;
+ if (item->GetFlag() & wxALL)
+ newBorder += item->GetBorder();
+
+ if (stdButtonSizer) // find wxStdDialogButtonSizer
+ {
+ wxStdDialogButtonSizer* buttonSizer = wxDynamicCast(childSizer, wxStdDialogButtonSizer);
+ if (buttonSizer)
+ {
+ sizer->Detach(childSizer);
+ retBorder = newBorder;
+ return buttonSizer;
+ }
+ }
+ else // find a horizontal box sizer containing standard buttons
+ {
+ wxBoxSizer* buttonSizer = wxDynamicCast(childSizer, wxBoxSizer);
+ if (buttonSizer && IsOrdinaryButtonSizer(dialog, buttonSizer))
+ {
+ sizer->Detach(childSizer);
+ retBorder = newBorder;
+ return buttonSizer;
+ }
+ }
+
+ wxSizer* s = FindButtonSizer(stdButtonSizer, dialog, childSizer, retBorder, newBorder);
+ if (s)
+ return s;
+ }
+ }
+ return NULL;
+}
+
+/// Check if this sizer contains standard buttons, and so can be repositioned in the dialog
+bool wxStandardDialogLayoutAdapter::IsOrdinaryButtonSizer(wxDialog* dialog, wxBoxSizer* sizer)
+{
+ if (sizer->GetOrientation() != wxHORIZONTAL)
+ return false;
+
+ for ( wxSizerItemList::compatibility_iterator node = sizer->GetChildren().GetFirst();
+ node; node = node->GetNext() )
+ {
+ wxSizerItem *item = node->GetData();
+ wxButton *childButton = wxDynamicCast(item->GetWindow(), wxButton);
+
+ if (childButton && IsStandardButton(dialog, childButton))
+ return true;
+ }
+ return false;
+}
+
+/// Check if this is a standard button
+bool wxStandardDialogLayoutAdapter::IsStandardButton(wxDialog* dialog, wxButton* button)
+{
+ wxWindowID id = button->GetId();
+
+ return (id == wxID_OK || id == wxID_CANCEL || id == wxID_YES || id == wxID_NO || id == wxID_SAVE ||
+ id == wxID_APPLY || id == wxID_HELP || id == wxID_CONTEXT_HELP || dialog->IsMainButtonId(id));
+}
+
+/// Find 'loose' main buttons in the existing layout and add them to the standard dialog sizer
+bool wxStandardDialogLayoutAdapter::FindLooseButtons(wxDialog* dialog, wxStdDialogButtonSizer* buttonSizer, wxSizer* sizer, int& count)
+{
+ wxSizerItemList::compatibility_iterator node = sizer->GetChildren().GetFirst();
+ while (node)
+ {
+ wxSizerItemList::compatibility_iterator next = node->GetNext();
+ wxSizerItem *item = node->GetData();
+ wxSizer *childSizer = item->GetSizer();
+ wxButton *childButton = wxDynamicCast(item->GetWindow(), wxButton);
+
+ if (childButton && IsStandardButton(dialog, childButton))
+ {
+ sizer->Detach(childButton);
+ buttonSizer->AddButton(childButton);
+ count ++;
+ }
+
+ if (childSizer)
+ FindLooseButtons(dialog, buttonSizer, childSizer, count);
+
+ node = next;
+ }
+ return true;