+
+/// 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;
+}
+
+/// Reparent the controls to the scrolled window
+void wxStandardDialogLayoutAdapter::ReparentControls(wxWindow* parent, wxWindow* reparentTo, wxSizer* buttonSizer)
+{
+ DoReparentControls(parent, reparentTo, buttonSizer);
+}
+
+void wxStandardDialogLayoutAdapter::DoReparentControls(wxWindow* parent, wxWindow* reparentTo, wxSizer* buttonSizer)
+{
+ wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindowList::compatibility_iterator next = node->GetNext();
+
+ wxWindow *win = node->GetData();
+
+ // Don't reparent the scrolled window or buttons in the button sizer
+ if (win != reparentTo && (!buttonSizer || !buttonSizer->GetItem(win)))
+ {
+ win->Reparent(reparentTo);
+#ifdef __WXMSW__
+ // Restore correct tab order
+ ::SetWindowPos((HWND) win->GetHWND(), HWND_BOTTOM, -1, -1, -1, -1, SWP_NOMOVE|SWP_NOSIZE);
+#endif
+ }
+
+ node = next;
+ }
+}
+
+/// Find whether scrolling will be necessary for the dialog, returning wxVERTICAL, wxHORIZONTAL or both
+int wxStandardDialogLayoutAdapter::MustScroll(wxDialog* dialog, wxSize& windowSize, wxSize& displaySize)
+{
+ return DoMustScroll(dialog, windowSize, displaySize);
+}
+
+/// Find whether scrolling will be necessary for the dialog, returning wxVERTICAL, wxHORIZONTAL or both
+int wxStandardDialogLayoutAdapter::DoMustScroll(wxDialog* dialog, wxSize& windowSize, wxSize& displaySize)
+{
+ wxSize minWindowSize = dialog->GetSizer()->GetMinSize();
+ windowSize = dialog->GetSize();
+ windowSize = wxSize(wxMax(windowSize.x, minWindowSize.x), wxMax(windowSize.y, minWindowSize.y));
+#if wxUSE_DISPLAY
+ displaySize = wxDisplay(wxDisplay::GetFromWindow(dialog)).GetClientArea().GetSize();
+#else
+ displaySize = wxGetClientDisplayRect().GetSize();
+#endif
+
+ int flags = 0;
+
+ if (windowSize.y >= (displaySize.y - wxEXTRA_DIALOG_HEIGHT))
+ flags |= wxVERTICAL;
+ if (windowSize.x >= displaySize.x)
+ flags |= wxHORIZONTAL;
+
+ return flags;
+}
+
+// A function to fit the dialog around its contents, and then adjust for screen size.
+// If scrolled windows are passed, scrolling is enabled in the required orientation(s).
+bool wxStandardDialogLayoutAdapter::FitWithScrolling(wxDialog* dialog, wxWindowList& windows)
+{
+ return DoFitWithScrolling(dialog, windows);
+}
+
+// A function to fit the dialog around its contents, and then adjust for screen size.
+// If a scrolled window is passed, scrolling is enabled in the required orientation(s).
+bool wxStandardDialogLayoutAdapter::FitWithScrolling(wxDialog* dialog, wxScrolledWindow* scrolledWindow)
+{
+ return DoFitWithScrolling(dialog, scrolledWindow);
+}
+
+// A function to fit the dialog around its contents, and then adjust for screen size.
+// If a scrolled window is passed, scrolling is enabled in the required orientation(s).
+bool wxStandardDialogLayoutAdapter::DoFitWithScrolling(wxDialog* dialog, wxScrolledWindow* scrolledWindow)
+{
+ wxWindowList windows;
+ windows.Append(scrolledWindow);
+ return DoFitWithScrolling(dialog, windows);
+}
+
+bool wxStandardDialogLayoutAdapter::DoFitWithScrolling(wxDialog* dialog, wxWindowList& windows)
+{
+ wxSizer* sizer = dialog->GetSizer();
+ if (!sizer)
+ return false;
+
+ sizer->SetSizeHints(dialog);
+
+ wxSize windowSize, displaySize;
+ int scrollFlags = DoMustScroll(dialog, windowSize, displaySize);
+ int scrollBarSize = 20;
+
+ if (scrollFlags)
+ {
+ int scrollBarExtraX = 0, scrollBarExtraY = 0;
+ bool resizeHorizontally = (scrollFlags & wxHORIZONTAL) != 0;
+ bool resizeVertically = (scrollFlags & wxVERTICAL) != 0;
+
+ if (windows.GetCount() != 0)
+ {
+ // Allow extra for a scrollbar, assuming we resizing in one direction only.
+ if ((resizeVertically && !resizeHorizontally) && (windowSize.x < (displaySize.x - scrollBarSize)))
+ scrollBarExtraX = scrollBarSize;
+ if ((resizeHorizontally && !resizeVertically) && (windowSize.y < (displaySize.y - scrollBarSize)))
+ scrollBarExtraY = scrollBarSize;
+ }
+
+ wxWindowList::compatibility_iterator node = windows.GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ wxScrolledWindow* scrolledWindow = wxDynamicCast(win, wxScrolledWindow);
+ if (scrolledWindow)
+ {
+ scrolledWindow->SetScrollRate(resizeHorizontally ? 10 : 0, resizeVertically ? 10 : 0);
+
+ if (scrolledWindow->GetSizer())
+ scrolledWindow->GetSizer()->Fit(scrolledWindow);
+ }
+
+ node = node->GetNext();
+ }
+
+ wxSize limitTo = windowSize + wxSize(scrollBarExtraX, scrollBarExtraY);
+ if (resizeVertically)
+ limitTo.y = displaySize.y - wxEXTRA_DIALOG_HEIGHT;
+ if (resizeHorizontally)
+ limitTo.x = displaySize.x;
+
+ dialog->SetMinSize(limitTo);
+ dialog->SetSize(limitTo);
+
+ dialog->SetSizeHints( limitTo.x, limitTo.y, dialog->GetMaxWidth(), dialog->GetMaxHeight() );
+ }
+
+ return true;
+}
+
+/*!
+ * Module to initialise standard adapter
+ */
+
+class wxDialogLayoutAdapterModule: public wxModule
+{
+ DECLARE_DYNAMIC_CLASS(wxDialogLayoutAdapterModule)
+public:
+ wxDialogLayoutAdapterModule() {}
+ virtual void OnExit() { delete wxDialogBase::SetLayoutAdapter(NULL); }
+ virtual bool OnInit() { wxDialogBase::SetLayoutAdapter(new wxStandardDialogLayoutAdapter); return true; }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxDialogLayoutAdapterModule, wxModule)