From 3aa8e4ea6db0478d3bc862f59f100408bdc8732f Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Sat, 29 Dec 2007 16:35:39 +0000
Subject: [PATCH] Added automatic dialog scrolling ability Added ability to
 resize wizard bitmaps automatically Made it easier to derive from wxWizard
 and override behaviour, mainly by making members protected instead of private

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50942 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt                      |   6 +
 docs/latex/wx/classes.tex             |   1 +
 docs/latex/wx/dialog.tex              | 150 +++++++++-
 docs/latex/wx/dialoglayoutadapter.tex |  48 +++
 docs/latex/wx/propdlg.tex             |   5 +
 docs/latex/wx/tdialog.tex             |  92 +++++-
 docs/latex/wx/wizard.tex              |  86 ++++++
 include/wx/dialog.h                   | 157 ++++++++++
 include/wx/generic/propdlg.h          |   3 +
 include/wx/generic/wizard.h           |  36 ++-
 include/wx/wizard.h                   |   9 +
 samples/wizard/wizard.cpp             |  32 +-
 samples/wizard/wizard.rc              |   3 +-
 src/cocoa/dialog.mm                   |   4 +
 src/common/dlgcmn.cpp                 | 415 ++++++++++++++++++++++++++
 src/generic/propdlg.cpp               |   6 +
 src/generic/wizard.cpp                | 179 ++++++++++-
 src/gtk/dialog.cpp                    |   3 +
 src/gtk1/dialog.cpp                   |   3 +
 src/mac/carbon/dialog.cpp             |   3 +
 src/motif/dialog.cpp                  |   3 +
 src/msw/dialog.cpp                    |   3 +
 src/os2/dialog.cpp                    |   3 +
 src/palmos/dialog.cpp                 |   6 +
 src/univ/dialog.cpp                   |   7 +-
 25 files changed, 1234 insertions(+), 29 deletions(-)
 create mode 100644 docs/latex/wx/dialoglayoutadapter.tex

diff --git a/docs/changes.txt b/docs/changes.txt
index 0a05c3f33e..0ffe732f14 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -249,6 +249,12 @@ All (GUI):
   to wxRichTextBuffer to reduce wxFont consumption and increase performance.
 - Optimize wxGenericTreeCtrl::Collapse/ExpandAllChildren(). (Szczepan Holyszewski)
 - Added <scrollrate> parameter to wxScrolledWindow XRC handler.
+- Added support for automatic dialog scrolling, via the new wxDialogLayoutAdapter
+  class and various new wxDialog functions. See the topic "Automatic Scrolling
+  Dialogs" in the manual for further details.
+- Added support for resizing wxWizard bitmaps to the current page height,
+  via SetBitmapPlacement, SetBitmapBackgroundColour and SetMinimumBitmapWidth.
+  Also made it easier to derive from wxWizard and override behaviour.
 
 wxGTK:
 
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 7bfffc689f..d0fd86c69d 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -114,6 +114,7 @@
 \input debugrptup.tex
 \input delgrend.tex
 \input dialog.tex
+\input dialoglayoutadapter.tex
 \input dialevt.tex
 \input dialup.tex
 \input dir.tex
diff --git a/docs/latex/wx/dialog.tex b/docs/latex/wx/dialog.tex
index 31818d2c9b..f6fa0d8261 100644
--- a/docs/latex/wx/dialog.tex
+++ b/docs/latex/wx/dialog.tex
@@ -15,6 +15,7 @@ A dialog box is a window with a title bar and sometimes a system menu, which
 can be moved around the screen. It can contain controls and other windows and
 is often used to allow the user to make some choice or to answer a question.
 
+Dialogs can be made scrollable, automatically: please see \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for further details.
 
 \wxheading{Dialog Buttons}
 
@@ -31,8 +32,6 @@ Also notice that the \helpref{CreateButtonSizer()}{wxdialogcreatebuttonsizer}
 should be used to create the buttons appropriate for the current platform and
 positioned correctly (including their order which is platform-dependent).
 
-
-
 \wxheading{Derived from}
 
 \helpref{wxTopLevelWindow}{wxtoplevelwindow}\\
@@ -177,6 +176,22 @@ individual dialog boxes.}
 
 Destructor. Deletes any child windows before deleting the physical window.
 
+\membersection{wxDialog::AddMainButtonId}\label{wxdialogaddmainbuttonid}
+
+\func{void}{AddMainButtonId}{\param{wxWindowID}{ id}}
+
+Adds an identifier to be regarded as a main button for the non-scrolling area of a dialog.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+\membersection{wxDialog::CanDoLayoutAdaptation}\label{wxdialogcandolayoutadaptation}
+
+\func{bool}{CanDoLayoutAdapation}{\void}
+
+Returns \true if this dialog can and should perform layout adaptation using \helpref{DoLayoutAdaptation}{wxdialogdolayoutadaptation}, usually if
+the dialog is too large to fit on the display.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
 
 \membersection{wxDialog::Centre}\label{wxdialogcentre}
 
@@ -241,6 +256,13 @@ wxHELP, wxNO\_DEFAULT.
 
 The sizer lays out the buttons in a manner appropriate to the platform.
 
+\membersection{wxDialog::DoLayoutAdaptation}\label{wxdialogdolayoutadaptation}
+
+\func{bool}{DoLayoutAdapation}{\void}
+
+Performs layout adaptation, usually if the dialog is too large to fit on the display.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
 
 \membersection{wxDialog::DoOK}\label{wxdialogdook}
 
@@ -251,6 +273,14 @@ A command event for the identifier returned by GetAffirmativeId is sent by
 default. You can override this function. If the function returns false, wxWidgets
 will call Close() for the dialog.
 
+\membersection{wxDialog::EnableLayoutAdaptation}\label{wxdialogenablelayoutadaptation}
+
+\func{static void}{EnableLayoutAdaptation}{\param{bool}{ enable}}
+
+A static function enabling or disabling layout adaptation for all dialogs.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
 
 \membersection{wxDialog::EndModal}\label{wxdialogendmodal}
 
@@ -281,6 +311,13 @@ dialog.
 
 \helpref{wxDialog::SetAffirmativeId}{wxdialogsetaffirmativeid}
 
+\membersection{wxDialog::GetContentWindow}\label{wxdialoggetcontentwindow}
+
+\constfunc{wxWindow*}{GetContentWindow}{\void}
+
+Override this to return a window containing the main content of the dialog. This is
+particularly useful when the dialog implements pages, such as wxPropertySheetDialog,
+and allows the \helpref{layout adaptation code}{wxdialogoverview} to know that only the pages need to be made scrollable.
 
 \membersection{wxDialog::GetEscapeId}\label{wxdialoggetescapeid}
 
@@ -294,6 +331,50 @@ button to.
 \helpref{wxDialog::SetEscapeId}{wxdialogsetescapeid}
 
 
+\membersection{wxDialog::GetLayoutAdaptationDone}\label{wxdialoggetlayoutadaptationdone}
+
+\constfunc{bool}{GetLayoutAdaptationDone}{\void}
+
+Returns \true if the dialog has been adapted, usually by making it scrollable to work with a small display.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::GetLayoutAdaptationLevel}\label{wxdialoggetlayoutadaptationlevel}
+
+\func{int}{GetLayoutAdaptationLevel}{\void}
+
+Gets a value representing the aggressiveness of search for buttons and sizers to be in the non-scrolling part of a layout-adapted dialog.
+Zero switches off adaptation, and 3 allows search for standard buttons anywhere in the dialog.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::GetLayoutAdaptationMode}\label{wxdialoggetlayoutadaptationmode}
+
+\constfunc{wxDialogLayoutAdaptationMode}{GetLayoutAdaptationMode}{\void}
+
+Gets the adaptation mode, overriding the global adaptation flag.
+
+See also \helpref{SetLayoutAdaptationMode}{wxdialogsetlayoutadaptationmode} and \helpref{Automatic scrolling dialogs}{autoscrollingdialogs}.
+
+\membersection{wxDialog::GetLayoutAdapter}\label{wxdialoggetlayoutadapter}
+
+\func{static wxDialogLayoutAdapter*}{GetLayoutAdapter}{\void}
+
+A static function getting the current layout adapter object.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::GetMainButtonIds}\label{wxdialoggetmainbuttonids}
+
+\func{wxArrayInt\&}{GetMainButtonIds}{\void}
+
+Returns an array of identifiers to be regarded as the main buttons for the non-scrolling area of a dialog.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
 \membersection{wxDialog::GetReturnCode}\label{wxdialoggetreturncode}
 
 \func{int}{GetReturnCode}{\void}
@@ -352,6 +433,24 @@ Returns true if the dialog box is iconized. Windows only.
 Always returns false under Windows since dialogs cannot be iconized.
 
 
+\membersection{wxDialog::IsLayoutAdaptationEnabled}\label{wxdialogislayoutadaptationenabled}
+
+\func{static bool}{IsLayoutAdaptationEnabled}{\void}
+
+A static function returning \true if layout adaptation is enabled for all dialogs.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::IsMainButton}\label{wxdialogismainbutton}
+
+\constfunc{bool}{IsMainButton}{\param{wxWindowID\& }{id}}
+
+Returns \true if {\it id} is in the array of identifiers to be regarded as the main buttons for the non-scrolling area of a dialog.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
 \membersection{wxDialog::IsModal}\label{wxdialogismodal}
 
 \constfunc{bool}{IsModal}{\void}
@@ -448,6 +547,53 @@ Sets the icons for this dialog.
 See also \helpref{wxIconBundle}{wxiconbundle}.
 
 
+\membersection{wxDialog::SetLayoutAdaptationDone}\label{wxdialogsetlayoutadaptationdone}
+
+\func{void}{SetLayoutAdaptationDone}{\param{bool }{done}}
+
+Marks the dialog as having been adapted, usually by making it scrollable to work with a small display.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::SetLayoutAdaptationLevel}\label{wxdialogsetlayoutadaptationlevel}
+
+\func{void}{SetLayoutAdaptationLevel}{\param{int }{level}}
+
+Sets the aggressiveness of search for buttons and sizers to be in the non-scrolling part of a layout-adapted dialog.
+Zero switches off adaptation, and 3 allows search for standard buttons anywhere in the dialog.
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::SetLayoutAdaptationMode}\label{wxdialogsetlayoutadaptationmode}
+
+\func{void}{SetLayoutAdaptationMode}{\param{wxDialogLayoutAdaptationMode }{mode}}
+
+Sets the adaptation mode, overriding the global adaptation flag. {\it mode} may be one of the following values:
+
+\begin{verbatim}
+enum wxDialogLayoutAdaptationMode
+{
+    wxDIALOG_ADAPTATION_MODE_DEFAULT = 0,   // use global adaptation enabled status
+    wxDIALOG_ADAPTATION_MODE_ENABLED = 1,   // enable this dialog overriding global status
+    wxDIALOG_ADAPTATION_MODE_DISABLED = 2   // disable this dialog overriding global status
+};
+\end{verbatim}
+
+See also \helpref{Automatic scrolling dialogs}{autoscrollingdialogs} for more on layout adaptation.
+
+
+\membersection{wxDialog::SetLayoutAdapter}\label{wxdialogsetlayoutadapter}
+
+\func{static wxDialogLayoutAdapter*}{SetLayoutAdapter}{\param{wxDialogLayoutAdapter*}{ adapter}}
+
+A static function for setting the current layout adapter object, returning the old adapter. If you call this, you should
+delete the old adapter object.
+
+See also \helpref{wxDialogLayoutAdapter}{wxdialoglayoutadapter} and \helpref{Automatic scrolling dialogs}{autoscrollingdialogs}.
+
+
 \membersection{wxDialog::SetModal}\label{wxdialogsetmodal}
 
 \func{void}{SetModal}{\param{bool}{ flag}}
diff --git a/docs/latex/wx/dialoglayoutadapter.tex b/docs/latex/wx/dialoglayoutadapter.tex
new file mode 100644
index 0000000000..f8a607bdd4
--- /dev/null
+++ b/docs/latex/wx/dialoglayoutadapter.tex
@@ -0,0 +1,48 @@
+\section{\class{wxDialogLayoutAdapter}}\label{wxdialoglayoutadapter}
+
+This abstract class is the base for classes that help wxWidgets peform run-time layout adaptation of dialogs. Principally,
+this is to cater for small displays by making part of the dialog scroll, but the application developer may find other
+uses for layout adaption.
+
+By default, there is one instance of wxStandardDialogLayoutAdapter
+which can perform adaptation for most custom dialogs and dialogs with book controls
+such as \helpref{wxPropertySheetDialog}{wxpropertysheetdialog}.
+
+\wxheading{Derived from}
+
+\helpref{wxObject}{wxobject}
+
+\wxheading{Include files}
+
+<wx/dialog.h>
+
+\wxheading{Library}
+
+\helpref{wxCore}{librarieslist}
+
+\wxheading{See also}
+
+\helpref{Automatic scrolling dialogs}{autoscrollingdialogs}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+
+\membersection{wxDialogLayoutAdapter::wxDialogLayoutAdapter}\label{wxdialoglayoutadapterctor}
+
+\func{}{wxDialogLayoutAdapter}{\void}
+
+Default constructor.
+
+\membersection{wxDialogLayoutAdapter::CanDoLayoutAdaptation}\label{wxdialoglayoutadaptercandolayoutadaptation}
+
+\func{bool}{CanDoLayoutAdaptation}{\param{wxDialog*}{ dialog}}
+
+Override this to returns \true if adaptation can and should be done.
+
+\membersection{wxDialogLayoutAdapter::DoLayoutAdaptation}\label{wxdialoglayoutadapterdolayoutadaptation}
+
+\func{bool}{DoLayoutAdaptation}{\param{wxDialog*}{ dialog}}
+
+Override this to perform layout adaptation, such as making parts of the dialog scroll and resizing the dialog to fit the display.
+Normally this function will be called just before the dialog is shown.
+
diff --git a/docs/latex/wx/propdlg.tex b/docs/latex/wx/propdlg.tex
index 166b2fb570..72a41e449a 100644
--- a/docs/latex/wx/propdlg.tex
+++ b/docs/latex/wx/propdlg.tex
@@ -36,6 +36,11 @@ before calling Create.
 The dialogs sample shows this class being used with notebook and toolbook controllers (for
 Windows-style and Mac-style settings dialogs).
 
+To make pages of the dialog scroll when the display is too small to fit the whole dialog, you can switch
+layout adaptation on globally with \helpref{wxDialog::EnableLayoutAdaptation}{wxdialogenablelayoutadaptation} or
+per dialog with \helpref{wxDialog::SetLayoutAdaptationMode}{wxdialogsetlayoutadaptationmode}. For more
+about layout adaptation, see \helpref{Automatic scrolling dialogs}{autoscrollingdialogs}.
+
 \wxheading{Derived from}
 
 \helpref{wxDialog}{wxdialog}\\
diff --git a/docs/latex/wx/tdialog.tex b/docs/latex/wx/tdialog.tex
index 94a06e5149..c172d53779 100644
--- a/docs/latex/wx/tdialog.tex
+++ b/docs/latex/wx/tdialog.tex
@@ -1,6 +1,6 @@
 \section{wxDialog overview}\label{wxdialogoverview}
 
-Classes: \helpref{wxDialog}{wxdialog}
+Classes: \helpref{wxDialog}{wxdialog}, \helpref{wxDialogLayoutAdapter}{wxdialoglayoutadapter}
 
 A dialog box is similar to a panel, in that it is a window which can
 be used for placing controls, with the following exceptions:
@@ -13,19 +13,89 @@ be used for placing controls, with the following exceptions:
   until the dialog box is dismissed.
 \end{enumerate}
 
-Under Windows 3, modal dialogs have to be emulated using
-modeless dialogs and a message loop. This is because Windows 3 expects
-the contents of a modal dialog to be loaded from a resource file or
-created on receipt of a dialog initialization message. This is too
-restrictive for wxWidgets, where any window may be created and displayed
-before its contents are created.
-
 For a set of dialog convenience functions, including file selection, see
 \rtfsp\helpref{Dialog functions}{dialogfunctions}.
 
-See also \helpref{wxPanel}{wxpanel} and \helpref{wxWindow}{wxwindow} for inherited
-member functions. Validation of data in controls is covered
-in \helpref{Validator overview}{validatoroverview}.
+See also \helpref{wxTopLevelWindow}{wxtoplevelwindow} and \helpref{wxWindow}{wxwindow} for inherited
+member functions. Validation of data in controls is covered in \helpref{Validator overview}{validatoroverview}.
+
+\subsection{Automatic scrolling dialogs}\label{autoscrollingdialogs}
+
+As an ever greater variety of mobile hardware comes to market, it becomes more imperative for wxWidgets applications to adapt
+to these platforms without putting too much burden on the programmer. One area where wxWidgets can help is in adapting
+dialogs for the lower resolution screens that inevitably accompany a smaller form factor. wxDialog therefore supplies
+a global \helpref{wxDialogLayoutAdapter}{wxdialoglayoutadapter} class that implements automatic scrolling adaptation for most sizer-based custom dialogs.
+Many applications should therefore be able to adapt to small displays with little or no work, as far as dialogs are concerned.
+
+By default this adaptation is off. To switch scrolling adaptation on globally in your application, call the static function\rtfsp
+\helpref{wxDialog::EnableLayoutAdaptation}{wxdialogenablelayoutadaptation} passing \true. You can also adjust adaptation on a per-dialog basis by calling\rtfsp
+\helpref{wxDialog::SetLayoutAdaptationMode}{wxdialogsetlayoutadaptationmode} with one of {\tt wxDIALOG\_ADAPTATION\_MODE\_DEFAULT} (use the global setting), {\tt wxDIALOG\_ADAPTATION\_MODE\_ENABLED} or {\tt wxDIALOG\_ADAPTATION\_MODE\_DISABLED}.
+The last two modes override the global adaptation setting.
+
+With adaptation enabled, if the display size is too small for the dialog, wxWidgets (or rather the
+standard adapter class wxStandardDialogLayoutAdapter) will
+make part of the dialog scrolling, leaving standard buttons in a non-scrolling part at the bottom of the dialog.
+
+This is done as follows, in \helpref{wxDialogLayoutAdapter::DoLayoutAdaptation}{wxdialoglayoutadapterdolayoutadaptation} called from within wxDialog::Show or wxDialog::ShowModal:
+
+\begin{enumerate}
+\item If \helpref{wxDialog::GetContentWindow}{wxdialoggetcontentwindow} returns a window derived from wxBookCtrlBase, the pages are made scrollable and
+no other adaptation is done.
+\item wxWidgets looks for a \helpref{wxStdDialogButtonSizer}{wxstddialogbuttonsizer} and uses it for the non-scrolling part.
+\item If that search failed, wxWidgets looks for a horizontal \helpref{wxBoxSizer}{wxboxsizer} with one or more
+standard buttons, with identifiers such as {\tt wxID\_OK} and {\tt wxID\_CANCEL}.
+\item If that search failed too, wxWidgets finds 'loose' standard buttons (in any kind of sizer) and adds them to a \helpref{wxStdDialogButtonSizer}{wxstddialogbuttonsizer}.
+If no standard buttons were found, the whole dialog content will scroll.
+\item All the children apart from standard buttons are reparented onto a new \helpref{wxScrolledWindow}{wxscrolledwindow} object,
+using the old top-level sizer for the scrolled window and creating a new top-level sizer to lay out the scrolled window and
+standard button sizer.
+\end{enumerate}
+
+\wxheading{Customising scrolling adaptation}
+
+In addition to switching adaptation on and off globally and per dialog, you can choose how aggressively wxWidgets will
+search for standard buttons by setting \helpref{wxDialog::SetLayoutAdaptationLevel}{wxdialogsetlayoutadaptationlevel}. By default,
+all the steps described above will be performed but by setting the level to 1, for example, you can choose to only look for wxStdDialogButtonSizer.
+
+You can use \helpref{wxDialog::AddMainButtonId}{wxdialogaddmainbuttonid} to add identifiers for buttons that should also be
+treated as standard buttons for the non-scrolling area.
+
+You can derive your own class from \helpref{wxDialogLayoutAdapter}{wxdialoglayoutadapter} or wxStandardDialogLayoutAdapter and call\rtfsp
+\helpref{wxDialog::SetLayoutAdapter}{wxdialogsetlayoutadapter}, deleting the old object that this function returns. Override
+the functions CanDoLayoutAdaptation and DoLayoutAdaptation to test for adaptation applicability and perform the adaptation.
+
+You can also override \helpref{wxDialog::CanDoLayoutAdaptation}{wxdialogcandolayoutadaptation} and \helpref{wxDialog::DoLayoutAdaptation}{wxdialogdolayoutadaptation} in a class derived from wxDialog.
+
+\wxheading{Situations where automatic scrolling adaptation may fail}
+
+Because adaptation rearranges your sizer and window hierarchy, it is not fool-proof, and may fail in the following situations.
+
+\begin{itemize}
+\item The dialog doesn't use sizers.
+\item The dialog implementation makes assumptions about the window hierarchy, for example getting the parent of a control and casting to the dialog class.
+\item The dialog does custom painting and/or event handling not handled by the scrolled window. If this problem can be solved globally,
+you can derive a new adapter class from wxStandardDialogLayoutAdapter and override its CreateScrolledWindow function to return an instance of your own class.
+\item The dialog has unusual layout, for example a vertical sizer containing a mixture of standard buttons and other controls.
+\item The dialog makes assumptions about the sizer hierarchy, for example to show or hide children of the top-level sizer. However, the original sizer hierarchy will still hold
+until Show or ShowModal is called.
+\end{itemize}
+
+You can help make sure that your dialogs will continue to function after adaptation by:
+
+\begin{itemize}
+\item avoiding the above situations and assumptions;
+\item using \helpref{wxStdDialogButtonSizer}{wxstddialogbuttonsizer};
+\item only making assumptions about hierarchy immediately after the dialog is created;
+\item using an intermediate sizer under the main sizer, a false top-level sizer that can be relied on to exist
+for the purposes of manipulating child sizers and windows;
+\item overriding \helpref{wxDialog::GetContentWindow}{wxdialoggetcontentwindow} to return a book control if your dialog implements pages: wxWidgets will then only make the pages
+scrollable.
+\end{itemize}
+
+\wxheading{wxPropertySheetDialog and wxWizard}
 
+Adaptation for wxPropertySheetDialog is always done by simply making the pages scrollable, since \helpref{wxDialog::GetContentWindow}{wxdialoggetcontentwindow} returns
+the dialog's book control and this is handled by the standard layout adapter.
 
+wxWizard uses its own CanDoLayoutAdaptation and DoLayoutAdaptation functions rather than the global adapter: again, only the wizard pages are made scrollable.
 
diff --git a/docs/latex/wx/wizard.tex b/docs/latex/wx/wizard.tex
index 298417376c..59c8e1e034 100644
--- a/docs/latex/wx/wizard.tex
+++ b/docs/latex/wx/wizard.tex
@@ -26,6 +26,16 @@ using either the non-default constructor or a default one followed by call to th
 want the wizard to show and call \helpref{RunWizard}{wxwizardrunwizard}.
 Finally, don't forget to call {\tt wizard->Destroy()}, otherwise your application will hang on exit due to an undestroyed window.
 
+You can supply a bitmap to display on the left of the wizard, either for all pages
+or for individual pages. If you need to have the bitmap resize to the height of the wizard,
+call \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement} and if necessary,\rtfsp
+\helpref{wxWizard::SetBitmapBackgroundColour}{wxwizardsetbitmapbackgroundcolour} and \helpref{wxWizard::SetMinimumBitmapWidth}{wxwizardsetminimumbitmapheight}.
+
+To make wizard pages scroll when the display is too small to fit the whole dialog, you can switch
+layout adaptation on globally with \helpref{wxDialog::EnableLayoutAdaptation}{wxdialogenablelayoutadaptation} or
+per dialog with \helpref{wxDialog::SetLayoutAdaptationMode}{wxdialogsetlayoutadaptationmode}. For more
+about layout adaptation, see \helpref{Automatic scrolling dialogs}{autoscrollingdialogs}.
+
 \wxheading{Derived from}
 
 \helpref{wxDialog}{wxdialog}\\
@@ -167,6 +177,28 @@ from a single one and you should call {\it Fit} separately for the others.
 
 Returns the bitmap used for the wizard.
 
+
+\membersection{wxWizard::GetBitmapBackgroundColour}\label{wxwizardgetbitmapbackgroundcolour}
+
+\constfunc{const wxColour\&}{GetBitmapBackgroundColour}{\void}
+
+Returns the colour that should be used to fill the area not taken up by the wizard or page bitmap,
+if a non-zero bitmap placement flag has been set.
+
+See also \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement}.
+
+
+
+\membersection{wxWizard::GetBitmapPlacement}\label{wxwizardgetbitmapplacement}
+
+\func{int}{GetBitmapPlacement}{\void}
+
+Returns the flags indicating how the wizard or page bitmap should be expanded and positioned to fit the
+page height. By default, placement is 0 (no expansion is done).
+
+See also \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement} for the possible values.
+
+
 \membersection{wxWizard::GetCurrentPage}\label{wxwizardgetcurrentpage}
 
 \constfunc{wxWizardPage*}{GetCurrentPage}{\void}
@@ -175,6 +207,16 @@ Get the current page while the wizard is running. {\tt NULL} is returned if
 \helpref{RunWizard()}{wxwizardrunwizard} is not being executed now.
 
 
+\membersection{wxWizard::GetMinimumBitmapWidth}\label{wxwizardgetminimumbitmapwidth}
+
+\constfunc{int}{GetMinimumBitmapWidth}{\void}
+
+Returns the minimum width for the bitmap that will be constructed to contain the actual wizard or page bitmap
+if a non-zero bitmap placement flag has been set.
+
+See also \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement}.
+
+
 \membersection{wxWizard::GetPageAreaSizer}\label{wxwizardgetpageareasizer}
 
 \constfunc{virtual wxSizer*}{GetPageAreaSizer}{\void}
@@ -256,6 +298,50 @@ can not be {\tt NULL}.
 
 Sets the bitmap used for the wizard.
 
+
+\membersection{wxWizard::SetBitmapBackgroundColour}\label{wxwizardsetbitmapbackgroundcolour}
+
+\func{void}{SetBitmapBackgroundColour}{\param{const wxColour\&}{ colour}}
+
+Sets the colour that should be used to fill the area not taken up by the wizard or page bitmap,
+if a non-zero bitmap placement flag has been set.
+
+See also \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement}.
+
+
+\membersection{wxWizard::SetBitmapPlacement}\label{wxwizardsetbitmapplacement}
+
+\func{void}{SetBitmapPlacement}{\param{int}{ placement}}
+
+Sets the flags indicating how the wizard or page bitmap should be expanded and positioned to fit the
+page height. By default, placement is 0 (no expansion is done). {\it placement} is a bitlist with the
+following possible values:
+
+\begin{twocollist}\itemsep=0pt
+\twocolitem{\windowstyle{wxWIZARD\_VALIGN\_TOP}}{Aligns the bitmap at the top.}
+\twocolitem{\windowstyle{wxWIZARD\_VALIGN\_CENTRE}}{Centres the bitmap vertically.}
+\twocolitem{\windowstyle{wxWIZARD\_VALIGN\_BOTTOM}}{Aligns the bitmap at the bottom.}
+\twocolitem{\windowstyle{wxWIZARD\_HALIGN\_LEFT}}{Left-aligns the bitmap.}
+\twocolitem{\windowstyle{wxWIZARD\_HALIGN\_CENTRE}}{Centres the bitmap horizontally.}
+\twocolitem{\windowstyle{wxWIZARD\_HALIGN\_RIGHT}}{Right-aligns the bitmap.}
+\twocolitem{\windowstyle{wxWIZARD\_TILE}}{}
+\end{twocollist}
+
+See also \helpref{wxWizard::SetMinimumBitmapWidth}{wxwizardsetminimumbitmapwidth}.
+
+
+\membersection{wxWizard::SetMinimumBitmapWidth}\label{wxwizardsetminimumbitmapwidth}
+
+\func{void}{SetMinimumBitmapWidth}{\param{int}{ width}}
+
+Sets the minimum width for the bitmap that will be constructed to contain the actual wizard or page bitmap
+if a non-zero bitmap placement flag has been set. If this is not set when using bitmap placement, the initial
+layout may be incorrect.
+
+See also \helpref{wxWizard::SetBitmapPlacement}{wxwizardsetbitmapplacement}.
+
+
+
 \membersection{wxWizard::SetPageSize}\label{wxwizardsetpagesize}
 
 \func{void}{SetPageSize}{\param{const wxSize\& }{sizePage}}
diff --git a/include/wx/dialog.h b/include/wx/dialog.h
index 271c0c32be..62bfb79265 100644
--- a/include/wx/dialog.h
+++ b/include/wx/dialog.h
@@ -17,6 +17,11 @@
 
 class WXDLLIMPEXP_FWD_CORE wxSizer;
 class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
+class WXDLLIMPEXP_FWD_CORE wxBoxSizer;
+class WXDLLIMPEXP_FWD_CORE wxDialogLayoutAdapter;
+class WXDLLIMPEXP_FWD_CORE wxDialog;
+class WXDLLIMPEXP_FWD_CORE wxButton;
+class WXDLLIMPEXP_FWD_CORE wxScrolledWindow;
 
 #define wxDIALOG_NO_PARENT      0x0001  // Don't make owned by apps top window
 
@@ -26,6 +31,28 @@ class WXDLLIMPEXP_FWD_CORE wxStdDialogButtonSizer;
 #define wxDEFAULT_DIALOG_STYLE  (wxCAPTION | wxSYSTEM_MENU | wxCLOSE_BOX)
 #endif
 
+// Layout adaptation levels, for SetLayoutAdaptationLevel
+
+// Don't do any layout adaptation
+#define wxDIALOG_ADAPTATION_NONE             0
+
+// Only look for wxStdDialogButtonSizer for non-scrolling part
+#define wxDIALOG_ADAPTATION_STANDARD_SIZER   1
+
+// Also look for any suitable sizer for non-scrolling part
+#define wxDIALOG_ADAPTATION_ANY_SIZER        2
+
+// Also look for 'loose' standard buttons for non-scrolling part
+#define wxDIALOG_ADAPTATION_LOOSE_BUTTONS    3
+
+// Layout adaptation mode, for SetLayoutAdaptationMode
+enum wxDialogLayoutAdaptationMode
+{
+    wxDIALOG_ADAPTATION_MODE_DEFAULT = 0,   // use global adaptation enabled status
+    wxDIALOG_ADAPTATION_MODE_ENABLED = 1,   // enable this dialog overriding global status
+    wxDIALOG_ADAPTATION_MODE_DISABLED = 2   // disable this dialog overriding global status
+};
+
 extern WXDLLEXPORT_DATA(const char) wxDialogNameStr[];
 
 class WXDLLEXPORT wxDialogBase : public wxTopLevelWindow
@@ -89,6 +116,46 @@ public:
     wxStdDialogButtonSizer *CreateStdDialogButtonSizer( long flags );
 #endif // wxUSE_BUTTON
 
+    // Do layout adaptation
+    virtual bool DoLayoutAdaptation();
+
+    // Can we do layout adaptation?
+    virtual bool CanDoLayoutAdaptation();
+
+    // Returns a content window if there is one. This can be used by the layout adapter, for
+    // example to make the pages of a book control into scrolling windows
+    virtual wxWindow* GetContentWindow() const { return NULL; }
+
+    // Add an id to the list of main button identifiers that should be in the button sizer
+    void AddMainButtonId(wxWindowID id) { m_mainButtonIds.Add((int) id); }
+    wxArrayInt& GetMainButtonIds() { return m_mainButtonIds; }
+
+    // Is this id in the main button id array?
+    bool IsMainButtonId(wxWindowID id) const { return (m_mainButtonIds.Index((int) id) != wxNOT_FOUND); }
+
+    // Level of adaptation, from none (Level 0) to full (Level 3). To disable adaptation,
+    // set level 0, for example in your dialog constructor. You might
+    // do this if you know that you are displaying on a large screen and you don't want the
+    // dialog changed.
+    void SetLayoutAdaptationLevel(int level) { m_layoutAdaptationLevel = level; }
+    int GetLayoutAdaptationLevel() const { return m_layoutAdaptationLevel; }
+
+    /// Override global adaptation enabled/disabled status
+    void SetLayoutAdaptationMode(wxDialogLayoutAdaptationMode mode) { m_layoutAdaptationMode = mode; }
+    wxDialogLayoutAdaptationMode GetLayoutAdaptationMode() const { return m_layoutAdaptationMode; }
+
+    // Returns true if the adaptation has been done
+    void SetLayoutAdaptationDone(bool adaptationDone) { m_layoutAdaptationDone = adaptationDone; }
+    bool GetLayoutAdaptationDone() const { return m_layoutAdaptationDone; }
+
+    // Set layout adapter class, returning old adapter
+    static wxDialogLayoutAdapter* SetLayoutAdapter(wxDialogLayoutAdapter* adapter);
+    static wxDialogLayoutAdapter* GetLayoutAdapter() { return sm_layoutAdapter; }
+
+    // Global switch for layout adaptation
+    static bool IsLayoutAdaptationEnabled() { return sm_layoutAdaptation; }
+    static void EnableLayoutAdaptation(bool enable) { sm_layoutAdaptation = enable; }
+
 protected:
     // emulate click of a button with the given id if it's present in the dialog
     //
@@ -121,6 +188,25 @@ protected:
     // The identifier for cancel button (usually wxID_CANCEL)
     int m_escapeId;
 
+    // Flags whether layout adaptation has been done for this dialog
+    bool                                m_layoutAdaptationDone;
+
+    // Extra button identifiers to be taken as 'main' button identifiers
+    // to be placed in the non-scrolling area
+    wxArrayInt                          m_mainButtonIds;
+
+    // Adaptation level
+    int                                 m_layoutAdaptationLevel;
+
+    // Local override for global adaptation enabled status
+    wxDialogLayoutAdaptationMode        m_layoutAdaptationMode;
+
+    // Global layout adapter
+    static wxDialogLayoutAdapter*       sm_layoutAdapter;
+
+    // Global adaptation switch
+    static bool                         sm_layoutAdaptation;
+
 private:
     // common part of all ctors
     void Init();
@@ -142,6 +228,77 @@ private:
     DECLARE_EVENT_TABLE()
 };
 
+/*!
+ * Base class for layout adapters - code that, for example, turns a dialog into a
+ * scrolling dialog if there isn't enough screen space. You can derive further
+ * adapter classes to do any other kind of adaptation, such as applying a watermark, or adding
+ * a help mechanism.
+ */
+
+class WXDLLEXPORT wxDialogLayoutAdapter: public wxObject
+{
+    DECLARE_CLASS(wxDialogLayoutAdapter)
+public:
+    wxDialogLayoutAdapter() {}
+
+    // Override this function to indicate that adaptation should be done
+    virtual bool CanDoLayoutAdaptation(wxDialog* dialog) = 0;
+
+    // Override this function to do the adaptation
+    virtual bool DoLayoutAdaptation(wxDialog* dialog) = 0;
+};
+
+/*!
+ * Standard adapter. Does scrolling adaptation for paged and regular dialogs.
+ *
+ */
+
+class WXDLLEXPORT wxStandardDialogLayoutAdapter: public wxDialogLayoutAdapter
+{
+    DECLARE_CLASS(wxStandardDialogLayoutAdapter)
+public:
+    wxStandardDialogLayoutAdapter() {}
+
+// Overrides
+
+    // Indicate that adaptation should be done
+    virtual bool CanDoLayoutAdaptation(wxDialog* dialog);
+
+    // Do layout adaptation
+    virtual bool DoLayoutAdaptation(wxDialog* dialog);
+
+// Implementation
+
+    // Create the scrolled window
+    virtual wxScrolledWindow* CreateScrolledWindow(wxWindow* parent);
+
+    // Find a standard or horizontal box sizer
+    virtual wxSizer* FindButtonSizer(bool stdButtonSizer, wxDialog* dialog, wxSizer* sizer, int& retBorder, int accumlatedBorder = 0);
+
+    // Check if this sizer contains standard buttons, and so can be repositioned in the dialog
+    virtual bool IsOrdinaryButtonSizer(wxDialog* dialog, wxBoxSizer* sizer);
+
+    // Check if this is a standard button
+    virtual bool IsStandardButton(wxDialog* dialog, wxButton* button);
+
+    // Find 'loose' main buttons in the existing layout and add them to the standard dialog sizer
+    virtual bool FindLooseButtons(wxDialog* dialog, wxStdDialogButtonSizer* buttonSizer, wxSizer* sizer, int& count);
+
+    // Reparent the controls to the scrolled window, except those in buttonSizer
+    virtual void ReparentControls(wxWindow* parent, wxWindow* reparentTo, wxSizer* buttonSizer = NULL);
+    static void DoReparentControls(wxWindow* parent, wxWindow* reparentTo, wxSizer* buttonSizer = NULL);
+
+    // 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).
+    virtual bool FitWithScrolling(wxDialog* dialog, wxScrolledWindow* scrolledWindow);
+    virtual bool FitWithScrolling(wxDialog* dialog, wxWindowList& windows);
+    static bool DoFitWithScrolling(wxDialog* dialog, wxScrolledWindow* scrolledWindow);
+    static bool DoFitWithScrolling(wxDialog* dialog, wxWindowList& windows);
+
+    // Find whether scrolling will be necessary for the dialog, returning wxVERTICAL, wxHORIZONTAL or both
+    virtual int MustScroll(wxDialog* dialog, wxSize& windowSize, wxSize& displaySize);
+    static int DoMustScroll(wxDialog* dialog, wxSize& windowSize, wxSize& displaySize);
+};
 
 #if defined(__WXUNIVERSAL__) && !defined(__WXMICROWIN__)
     #include "wx/univ/dialog.h"
diff --git a/include/wx/generic/propdlg.h b/include/wx/generic/propdlg.h
index b6c60227d4..66a0a796cb 100644
--- a/include/wx/generic/propdlg.h
+++ b/include/wx/generic/propdlg.h
@@ -103,6 +103,9 @@ public:
     void SetBookCtrl(wxBookCtrlBase* book) { m_bookCtrl = book; }
     wxBookCtrlBase* GetBookCtrl() const { return m_bookCtrl; }
 
+    // Override function in base
+    virtual wxWindow* GetContentWindow() const;
+
     // Set and get the inner sizer
     void SetInnerSize(wxSizer* sizer) { m_innerSizer = sizer; }
     wxSizer* GetInnerSizer() const { return m_innerSizer ; }
diff --git a/include/wx/generic/wizard.h b/include/wx/generic/wizard.h
index 4a738c69f1..49f7dd06f5 100644
--- a/include/wx/generic/wizard.h
+++ b/include/wx/generic/wizard.h
@@ -68,17 +68,40 @@ public:
     // show the prev/next page, but call TransferDataFromWindow on the current
     // page first and return false without changing the page if
     // TransferDataFromWindow() returns false - otherwise, returns true
-    bool ShowPage(wxWizardPage *page, bool goingForward = true);
+    virtual bool ShowPage(wxWizardPage *page, bool goingForward = true);
 
     // do fill the dialog with controls
     // this is app-overridable to, for example, set help and tooltip text
     virtual void DoCreateControls();
 
+    // Do the adaptation
+    virtual bool DoLayoutAdaptation();
+
+    // Set/get bitmap background colour
+    void SetBitmapBackgroundColour(const wxColour& colour) { m_bitmapBackgroundColour = colour; }
+    const wxColour& GetBitmapBackgroundColour() const { return m_bitmapBackgroundColour; }
+
+    // Set/get bitmap placement (centred, tiled etc.)
+    void SetBitmapPlacement(int placement) { m_bitmapPlacement = placement; }
+    int GetBitmapPlacement() const { return m_bitmapPlacement; }
+
+    // Set/get minimum bitmap width
+    void SetMinimumBitmapWidth(int w) { m_bitmapMinimumWidth = w; }
+    int GetMinimumBitmapWidth() const { return m_bitmapMinimumWidth; }
+
+    // Tile bitmap
+    static bool TileBitmap(const wxRect& rect, wxDC& dc, const wxBitmap& bitmap);
+
 protected:
     // for compatibility only, doesn't do anything any more
     void FinishLayout() { }
 
-private:
+    // Do fit, and adjust to screen size if necessary
+    virtual void DoWizardLayout();
+
+    // Resize bitmap if necessary
+    virtual bool ResizeBitmap(wxBitmap& bmp);
+
     // was the dialog really created?
     bool WasCreated() const { return m_btnPrev != NULL; }
 
@@ -127,6 +150,15 @@ private:
     // Actual position and size of pages
     wxWizardSizer *m_sizerPage;
 
+    // Bitmap background colour if resizing bitmap
+    wxColour    m_bitmapBackgroundColour;
+
+    // Bitmap placement flags
+    int         m_bitmapPlacement;
+
+    // Minimum bitmap width
+    int         m_bitmapMinimumWidth;
+
     friend class wxWizardSizer;
 
     DECLARE_DYNAMIC_CLASS(wxWizard)
diff --git a/include/wx/wizard.h b/include/wx/wizard.h
index 77a5a73883..0ec7ffd222 100644
--- a/include/wx/wizard.h
+++ b/include/wx/wizard.h
@@ -33,6 +33,15 @@
 // Extended style to specify a help button
 #define wxWIZARD_EX_HELPBUTTON   0x00000010
 
+// Placement flags
+#define wxWIZARD_VALIGN_TOP       0x01
+#define wxWIZARD_VALIGN_CENTRE    0x02
+#define wxWIZARD_VALIGN_BOTTOM    0x04
+#define wxWIZARD_HALIGN_LEFT      0x08
+#define wxWIZARD_HALIGN_CENTRE    0x10
+#define wxWIZARD_HALIGN_RIGHT     0x20
+#define wxWIZARD_TILE             0x40
+
 // forward declarations
 class WXDLLIMPEXP_FWD_ADV wxWizard;
 
diff --git a/samples/wizard/wizard.cpp b/samples/wizard/wizard.cpp
index 49ce4a5857..efb436c0d8 100644
--- a/samples/wizard/wizard.cpp
+++ b/samples/wizard/wizard.cpp
@@ -38,11 +38,14 @@
     #include "wx/sizer.h"
 #endif
 
+#include "wx/textctrl.h"
 #include "wx/wizard.h"
 
 #include "wiztest.xpm"
 #include "wiztest2.xpm"
 
+#include "../sample.xpm"
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -50,11 +53,15 @@
 // ids for menu items
 enum
 {
+    Wizard_About = wxID_ABOUT,
     Wizard_Quit = wxID_EXIT,
     Wizard_RunModal = wxID_HIGHEST,
+
     Wizard_RunNoSizer,
     Wizard_RunModeless,
-    Wizard_About = wxID_ABOUT
+
+    Wizard_LargeWizard,
+    Wizard_ExpandBitmap
 };
 
 // ----------------------------------------------------------------------------
@@ -299,6 +306,14 @@ public:
         );
 #endif // wxUSE_CHECKLISTBOX
 
+        wxSize textSize = wxSize(150, 200);
+        if (((wxFrame*) wxTheApp->GetTopWindow())->GetMenuBar()->IsChecked(Wizard_LargeWizard))
+            textSize = wxSize(150, wxGetClientDisplayRect().GetHeight() - 200);
+
+
+        wxTextCtrl* textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, textSize, wxTE_MULTILINE);
+        mainSizer->Add(textCtrl, 0, wxALL|wxEXPAND, 5);
+
         SetSizer(mainSizer);
         mainSizer->Fit(this);
     }
@@ -375,6 +390,16 @@ MyWizard::MyWizard(wxFrame *frame, bool useSizer)
                    wxBitmap(wiztest_xpm),wxDefaultPosition,
                    wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
 {
+    SetIcon(wxIcon(sample_xpm));
+
+    // Allow the bitmap to be expanded to fit the page height
+    if (frame->GetMenuBar()->IsChecked(Wizard_ExpandBitmap))
+        SetBitmapPlacement(wxWIZARD_VALIGN_CENTRE);
+
+    // Enable scrolling adaptation
+    if (frame->GetMenuBar()->IsChecked(Wizard_LargeWizard))
+        SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
+
     // a wizard page may be either an object of predefined class
     m_page1 = new wxWizardPageSimple(this);
 
@@ -421,12 +446,17 @@ MyFrame::MyFrame(const wxString& title)
     menuFile->AppendSeparator();
     menuFile->Append(Wizard_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
 
+    wxMenu *menuOptions = new wxMenu;
+    menuOptions->AppendCheckItem(Wizard_LargeWizard, _T("&Scroll Wizard Pages"));
+    menuOptions->AppendCheckItem(Wizard_ExpandBitmap, _T("Si&ze Bitmap To Page"));
+
     wxMenu *helpMenu = new wxMenu;
     helpMenu->Append(Wizard_About, _T("&About...\tF1"), _T("Show about dialog"));
 
     // now append the freshly created menu to the menu bar...
     wxMenuBar *menuBar = new wxMenuBar();
     menuBar->Append(menuFile, _T("&File"));
+    menuBar->Append(menuOptions, _T("&Options"));
     menuBar->Append(helpMenu, _T("&Help"));
 
     // ... and attach this menu bar to the frame
diff --git a/samples/wizard/wizard.rc b/samples/wizard/wizard.rc
index 82bdf07561..6078cc5252 100644
--- a/samples/wizard/wizard.rc
+++ b/samples/wizard/wizard.rc
@@ -1,2 +1,3 @@
-#include "wx/msw/wx.rc"
+mondrian ICON "..\sample.ico"
 
+#include "wx/msw/wx.rc"
diff --git a/src/cocoa/dialog.mm b/src/cocoa/dialog.mm
index 1f412b0a33..9c2be1a64f 100644
--- a/src/cocoa/dialog.mm
+++ b/src/cocoa/dialog.mm
@@ -99,6 +99,10 @@ bool wxDialog::Show(bool show)
     if(show)
     {
         wxAutoNSAutoreleasePool pool;
+
+    	if (CanDoLayoutAdaptation())
+        	DoLayoutAdaptation();
+
         InitDialog();
         if(IsModal())
         {   // ShowModal() will show the dialog
diff --git a/src/common/dlgcmn.cpp b/src/common/dlgcmn.cpp
index 5621cbc6a9..31c5aa60ec 100644
--- a/src/common/dlgcmn.cpp
+++ b/src/common/dlgcmn.cpp
@@ -39,8 +39,13 @@
 
 #include "wx/statline.h"
 #include "wx/sysopt.h"
+#include "wx/module.h"
 #include "wx/private/stattext.h"
+#include "wx/bookctrl.h"
 
+#if wxUSE_DISPLAY
+#include "wx/display.h"
+#endif
 
 // ----------------------------------------------------------------------------
 // wxDialogBase
@@ -54,11 +59,17 @@ BEGIN_EVENT_TABLE(wxDialogBase, wxTopLevelWindow)
     EVT_CHAR_HOOK(wxDialogBase::OnCharHook)
 END_EVENT_TABLE()
 
+wxDialogLayoutAdapter* wxDialogBase::sm_layoutAdapter = NULL;
+bool wxDialogBase::sm_layoutAdaptation = false;
+
 void wxDialogBase::Init()
 {
     m_returnCode = 0;
     m_affirmativeId = wxID_OK;
     m_escapeId = wxID_ANY;
+    m_layoutAdaptationLevel = 3;
+    m_layoutAdaptationDone = FALSE;
+    m_layoutAdaptationMode = wxDIALOG_ADAPTATION_MODE_DEFAULT;
 
     // the dialogs have this flag on by default to prevent the events from the
     // dialog controls from reaching the parent frame which is usually
@@ -459,3 +470,407 @@ void wxDialogBase::OnSysColourChanged(wxSysColourChangedEvent& event)
 
     event.Skip();
 }
+
+/// Do the adaptation
+bool wxDialogBase::DoLayoutAdaptation()
+{
+    if (GetLayoutAdapter())
+        return GetLayoutAdapter()->DoLayoutAdaptation((wxDialog*) this);
+    else
+        return false;
+}
+
+/// Can we do the adaptation?
+bool wxDialogBase::CanDoLayoutAdaptation()
+{
+    // 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())
+    {
+        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
+        {
+            // 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
+                {
+                    delete buttonSizer;
+                    buttonSizer = NULL;
+                }
+            }
+
+            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);
+        }
+    }
+
+    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;
+}
+
+/// 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;
+}
+
+/// 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();
+#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)
diff --git a/src/generic/propdlg.cpp b/src/generic/propdlg.cpp
index fa41bed4a8..939ff9ee85 100644
--- a/src/generic/propdlg.cpp
+++ b/src/generic/propdlg.cpp
@@ -225,4 +225,10 @@ void wxPropertySheetDialog::OnIdle(wxIdleEvent& event)
     }
 }
 
+// Override function in base
+wxWindow* wxPropertySheetDialog::GetContentWindow() const
+{
+    return GetBookCtrl();
+}
+
 #endif // wxUSE_BOOKCTRL
diff --git a/src/generic/wizard.cpp b/src/generic/wizard.cpp
index c3d603509e..b7446b440d 100644
--- a/src/generic/wizard.cpp
+++ b/src/generic/wizard.cpp
@@ -228,6 +228,8 @@ wxSize wxWizardSizer::GetMaxChildSize()
         maxOfMin.IncTo(SiblingSize(child));
     }
 
+    // No longer applicable since we may change sizes when size adaptation is done
+#if 0
 #ifdef __WXDEBUG__
     if ( m_childSize.IsFullySpecified() && m_childSize != maxOfMin )
     {
@@ -239,6 +241,7 @@ wxSize wxWizardSizer::GetMaxChildSize()
         return m_childSize;
     }
 #endif // __WXDEBUG__
+#endif
 
     if ( m_owner->m_started )
     {
@@ -293,6 +296,9 @@ void wxWizard::Init()
     m_started = false;
     m_wasModal = false;
     m_usingSizer = false;
+    m_bitmapBackgroundColour = *wxWHITE;
+    m_bitmapPlacement = 0;
+    m_bitmapMinimumWidth = 115;
 }
 
 bool wxWizard::Create(wxWindow *parent,
@@ -337,7 +343,11 @@ void wxWizard::AddBitmapRow(wxBoxSizer *mainColumn)
 #if wxUSE_STATBMP
     if ( m_bitmap.Ok() )
     {
-        m_statbmp = new wxStaticBitmap(this, wxID_ANY, m_bitmap);
+        wxSize bitmapSize(wxDefaultSize);
+        if (GetBitmapPlacement())
+            bitmapSize.x = GetMinimumBitmapWidth();
+
+        m_statbmp = new wxStaticBitmap(this, wxID_ANY, m_bitmap, wxDefaultPosition, bitmapSize);
         m_sizerBmpAndPage->Add(
             m_statbmp,
             0, // No horizontal stretching
@@ -617,17 +627,21 @@ bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
 
 #if wxUSE_STATBMP
     // update the bitmap if:it changed
+    wxBitmap bmp;
     if ( m_statbmp )
     {
-        wxBitmap bmp = m_page->GetBitmap();
+        bmp = m_page->GetBitmap();
         if ( !bmp.Ok() )
             bmp = m_bitmap;
 
         if ( !bmpPrev.Ok() )
             bmpPrev = m_bitmap;
 
-        if ( !bmp.IsSameAs(bmpPrev) )
-            m_statbmp->SetBitmap(bmp);
+        if (!GetBitmapPlacement())
+        {
+            if ( !bmp.IsSameAs(bmpPrev) )
+                m_statbmp->SetBitmap(bmp);
+        }
     }
 #endif // wxUSE_STATBMP
 
@@ -663,17 +677,40 @@ bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
     {
         m_started = true;
 
-        if ( wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA )
-        {
-            GetSizer()->SetSizeHints(this);
-            if ( m_posWizard == wxDefaultPosition )
-                CentreOnScreen();
-        }
+        DoWizardLayout();
+    }
+
+    if (GetBitmapPlacement())
+    {
+        ResizeBitmap(bmp);
+    
+        if ( !bmp.IsSameAs(bmpPrev) )
+            m_statbmp->SetBitmap(bmp);
+    
+        if (m_usingSizer)
+            m_sizerPage->RecalcSizes();
     }
 
     return true;
 }
 
+/// Do fit, and adjust to screen size if necessary
+void wxWizard::DoWizardLayout()
+{
+    if ( wxSystemSettings::GetScreenType() > wxSYS_SCREEN_PDA )
+    {
+        if (CanDoLayoutAdaptation())
+            DoLayoutAdaptation();
+        else
+            GetSizer()->SetSizeHints(this);
+
+        if ( m_posWizard == wxDefaultPosition )
+            CentreOnScreen();
+    }
+
+    SetLayoutAdaptationDone(true);
+}
+
 bool wxWizard::RunWizard(wxWizardPage *firstPage)
 {
     wxCHECK_MSG( firstPage, false, wxT("can't run empty wizard") );
@@ -863,4 +900,126 @@ wxWizardEvent::wxWizardEvent(wxEventType type, int id, bool direction, wxWizardP
     m_page = page;
 }
 
+/// Do the adaptation
+bool wxWizard::DoLayoutAdaptation()
+{
+    wxWindowList windows;
+    wxWindowList pages;
+
+    // Make all the pages (that use sizers) scrollable
+    for ( wxSizerItemList::compatibility_iterator node = m_sizerPage->GetChildren().GetFirst(); node; node = node->GetNext() )
+    {
+        wxSizerItem * const item = node->GetData();
+        if ( item->IsWindow() )
+        {
+            wxWizardPage* page = wxDynamicCast(item->GetWindow(), wxWizardPage);
+            if (page)
+            {
+                while (page)
+                {
+                    if (!pages.Find(page) && page->GetSizer())
+                    {
+                        // Create a scrolled window and reparent
+                        wxScrolledWindow* scrolledWindow = new wxScrolledWindow(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxVSCROLL|wxHSCROLL|wxBORDER_NONE);
+                        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);
+                        
+                        wxStandardDialogLayoutAdapter::DoReparentControls(page, scrolledWindow);
+                        
+                        pages.Append(page);
+                        windows.Append(scrolledWindow);
+                    }
+                    page = page->GetNext();
+                }
+            }
+        }
+    }
+
+    wxStandardDialogLayoutAdapter::DoFitWithScrolling(this, windows);
+
+    SetLayoutAdaptationDone(true);
+
+    return true;
+}
+
+bool wxWizard::ResizeBitmap(wxBitmap& bmp)
+{
+    if (!GetBitmapPlacement())
+        return false;
+
+    if (bmp.Ok())
+    {
+        wxSize pageSize = m_sizerPage->GetSize();
+        int bitmapWidth = wxMax(bmp.GetWidth(), GetMinimumBitmapWidth());
+        int bitmapHeight = pageSize.y;
+
+        if (bmp.GetHeight() != bitmapHeight)
+        {
+            wxBitmap bitmap(bitmapWidth, bitmapHeight);
+            {
+                wxMemoryDC dc;
+                dc.SelectObject(bitmap);
+                dc.SetBackground(wxBrush(m_bitmapBackgroundColour));
+                dc.Clear();
+
+                if (GetBitmapPlacement() & wxWIZARD_TILE)
+                {
+                    TileBitmap(wxRect(0, 0, bitmapWidth, bitmapHeight), dc, bmp);
+                }
+                else
+                {
+                    int x, y;
+
+                    if (GetBitmapPlacement() & wxWIZARD_HALIGN_LEFT)
+                        x = 0;
+                    else if (GetBitmapPlacement() & wxWIZARD_HALIGN_RIGHT)
+                        x = bitmapWidth - GetBitmap().GetWidth();
+                    else
+                        x = (bitmapWidth - GetBitmap().GetWidth())/2;
+
+                    if (GetBitmapPlacement() & wxWIZARD_VALIGN_TOP)
+                        y = 0;
+                    else if (GetBitmapPlacement() & wxWIZARD_VALIGN_BOTTOM)
+                        y = bitmapHeight - GetBitmap().GetHeight();
+                    else
+                        y = (bitmapHeight - GetBitmap().GetHeight())/2;
+
+                    dc.DrawBitmap(bmp, x, y, true);
+                    dc.SelectObject(wxNullBitmap);
+                }
+            }
+
+            bmp = bitmap;
+        }
+    }
+
+    return true;
+}
+
+bool wxWizard::TileBitmap(const wxRect& rect, wxDC& dc, const wxBitmap& bitmap)
+{
+    int w = bitmap.GetWidth();
+    int h = bitmap.GetHeight();
+
+    wxMemoryDC dcMem;
+
+    dcMem.SelectObjectAsSource(bitmap);
+
+    int i, j;
+    for (i = rect.x; i < rect.x + rect.width; i += w)
+    {
+        for (j = rect.y; j < rect.y + rect.height; j+= h)
+            dc.Blit(i, j, bitmap.GetWidth(), bitmap.GetHeight(), & dcMem, 0, 0);
+    }
+    dcMem.SelectObject(wxNullBitmap);
+
+    return true;
+}
+
 #endif // wxUSE_WIZARDDLG
diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp
index fe9a0036c2..7a4f9e3009 100644
--- a/src/gtk/dialog.cpp
+++ b/src/gtk/dialog.cpp
@@ -66,6 +66,9 @@ bool wxDialog::Show( bool show )
         EndModal( wxID_CANCEL );
     }
 
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     bool ret = wxWindow::Show( show );
 
     if (show) InitDialog();
diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp
index 007c13df28..540910d9dc 100644
--- a/src/gtk1/dialog.cpp
+++ b/src/gtk1/dialog.cpp
@@ -162,6 +162,9 @@ bool wxDialog::Show( bool show )
         GtkOnSize( m_x, m_y, m_width, m_height );
     }
 
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     bool ret = wxWindow::Show( show );
 
     if (show) InitDialog();
diff --git a/src/mac/carbon/dialog.cpp b/src/mac/carbon/dialog.cpp
index 966b6001ba..858736fd33 100644
--- a/src/mac/carbon/dialog.cpp
+++ b/src/mac/carbon/dialog.cpp
@@ -103,6 +103,9 @@ bool wxDialog::Show(bool show)
         // nothing to do
         return false;
 
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     if ( show )
         // usually will result in TransferDataToWindow() being called
         InitDialog();
diff --git a/src/motif/dialog.cpp b/src/motif/dialog.cpp
index 95abbae57c..59b8baf077 100644
--- a/src/motif/dialog.cpp
+++ b/src/motif/dialog.cpp
@@ -252,6 +252,9 @@ bool wxDialog::Show( bool show )
 
     if (show)
     {
+        if (CanDoLayoutAdaptation())
+            DoLayoutAdaptation();
+
         // this usually will result in TransferDataToWindow() being called
         // which will change the controls values so do it before showing as
         // otherwise we could have some flicker
diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp
index 0b4174a8d0..4fce3f8d47 100644
--- a/src/msw/dialog.cpp
+++ b/src/msw/dialog.cpp
@@ -237,6 +237,9 @@ bool wxDialog::Show(bool show)
 
     if ( show )
     {
+        if (CanDoLayoutAdaptation())
+            DoLayoutAdaptation();
+
         // this usually will result in TransferDataToWindow() being called
         // which will change the controls values so do it before showing as
         // otherwise we could have some flicker
diff --git a/src/os2/dialog.cpp b/src/os2/dialog.cpp
index e17a1414d8..abb905f2f8 100644
--- a/src/os2/dialog.cpp
+++ b/src/os2/dialog.cpp
@@ -212,6 +212,9 @@ bool wxDialog::Show( bool bShow )
 
     if (bShow)
     {
+        if (CanDoLayoutAdaptation())
+            DoLayoutAdaptation();
+
         // this usually will result in TransferDataToWindow() being called
         // which will change the controls values so do it before showing as
         // otherwise we could have some flicker
diff --git a/src/palmos/dialog.cpp b/src/palmos/dialog.cpp
index 32535b9bca..c368c78f56 100644
--- a/src/palmos/dialog.cpp
+++ b/src/palmos/dialog.cpp
@@ -168,6 +168,9 @@ wxWindow *wxDialog::FindSuitableParent() const
 
 bool wxDialog::Show(bool show)
 {
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     return wxTopLevelWindowPalm::Show (show);
 }
 
@@ -178,6 +181,9 @@ void wxDialog::Raise()
 // show dialog modally
 int wxDialog::ShowModal()
 {
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     if (errNone == FrmDoDialog ((FormType *)wxTopLevelWindow::GetForm())) {
         return 0;
     }
diff --git a/src/univ/dialog.cpp b/src/univ/dialog.cpp
index 79114b0d36..ad510bd277 100644
--- a/src/univ/dialog.cpp
+++ b/src/univ/dialog.cpp
@@ -71,7 +71,7 @@ bool wxDialog::Create(wxWindow *parent,
 
 void wxDialog::OnApply(wxCommandEvent &WXUNUSED(event))
 {
-    if ( Validate() ) 
+    if ( Validate() )
         TransferDataFromWindow();
 }
 
@@ -150,9 +150,12 @@ bool wxDialog::Show(bool show)
             EndModal(wxID_CANCEL);
     }
 
+    if (show && CanDoLayoutAdaptation())
+        DoLayoutAdaptation();
+
     bool ret = wxDialogBase::Show(show);
 
-    if ( show ) 
+    if ( show )
         InitDialog();
 
     return ret;
-- 
2.50.0

