]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/dialogs/dialogs.cpp
reset deferred position/size if the window was moved immediately (#10073)
[wxWidgets.git] / samples / dialogs / dialogs.cpp
index 29195ad6dfc566b7327b5830c8e8edc1a03dd744..0a3c4638ba2bea4797623b80603cdf2f4287b7a3 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "../sample.xpm"
 
+#include "wx/apptrait.h"
 #include "wx/datetime.h"
 #include "wx/image.h"
 #include "wx/bookctrl.h"
     #include "wx/fdrepdlg.h"
 #endif // wxUSE_FINDREPLDLG
 
-#if wxUSE_SPINCTRL
 #include "wx/spinctrl.h"
-#endif
-
 #include "wx/propdlg.h"
 
 #include "dialogs.h"
@@ -118,6 +116,7 @@ END_EVENT_TABLE()
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 #if wxUSE_MSGDLG
     EVT_MENU(DIALOGS_MESSAGE_BOX,                   MyFrame::MessageBox)
+    EVT_MENU(DIALOGS_MESSAGE_DIALOG,                MyFrame::MessageBoxDialog)
     EVT_MENU(DIALOGS_MESSAGE_BOX_WXINFO,            MyFrame::MessageBoxInfo)
 #endif // wxUSE_MSGDLG
 #if wxUSE_COLOURDLG
@@ -223,6 +222,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 #endif // USE_SETTINGS_DIALOG
 
     EVT_MENU(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG,  MyFrame::OnStandardButtonsSizerDialog)
+    EVT_MENU(DIALOGS_TEST_DEFAULT_ACTION,           MyFrame::OnTestDefaultActionDialog)
 
     EVT_MENU(DIALOGS_REQUEST,                       MyFrame::OnRequestUserAttention)
 #if wxUSE_NOTIFICATION_MESSAGE
@@ -274,6 +274,7 @@ bool MyApp::OnInit()
     wxMenu *menuDlg = new wxMenu;
 
     menuDlg->Append(DIALOGS_MESSAGE_BOX, _T("&Message box\tCtrl-M"));
+    menuDlg->Append(DIALOGS_MESSAGE_DIALOG, _T("Message dialog\tShift-Ctrl-M"));
 
 
 #if wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG
@@ -336,12 +337,12 @@ bool MyApp::OnInit()
     filedlg_menu->Append(DIALOGS_FILES_OPEN,  _T("Open &files\tCtrl-Q"));
     filedlg_menu->Append(DIALOGS_FILE_SAVE,  _T("Sa&ve file\tCtrl-S"));
 
-    #if USE_FILEDLG_GENERIC
-        filedlg_menu->AppendSeparator();
-        filedlg_menu->Append(DIALOGS_FILE_OPEN_GENERIC,  _T("&Open file (generic)"));
-        filedlg_menu->Append(DIALOGS_FILES_OPEN_GENERIC,  _T("Open &files (generic)"));
-        filedlg_menu->Append(DIALOGS_FILE_SAVE_GENERIC,  _T("Sa&ve file (generic)"));
-    #endif // USE_FILEDLG_GENERIC
+#if USE_FILEDLG_GENERIC
+    filedlg_menu->AppendSeparator();
+    filedlg_menu->Append(DIALOGS_FILE_OPEN_GENERIC, _T("&Open file (generic)"));
+    filedlg_menu->Append(DIALOGS_FILES_OPEN_GENERIC, _T("Open &files (generic)"));
+    filedlg_menu->Append(DIALOGS_FILE_SAVE_GENERIC, _T("Sa&ve file (generic)"));
+#endif // USE_FILEDLG_GENERIC
 
     menuDlg->Append(wxID_ANY,_T("&File operations"),filedlg_menu);
 
@@ -439,6 +440,7 @@ bool MyApp::OnInit()
     menuDlg->AppendSubMenu(menuNotif, "&User notifications");
 
     menuDlg->Append(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, _T("&Standard Buttons Sizer Dialog"));
+    menuDlg->Append(DIALOGS_TEST_DEFAULT_ACTION, _T("&Test dialog default action"));
 
     menuDlg->AppendSeparator();
     menuDlg->Append(wxID_EXIT, _T("E&xit\tAlt-X"));
@@ -648,21 +650,34 @@ void MyFrame::LogDialog(wxCommandEvent& WXUNUSED(event))
 #endif // wxUSE_LOG_DIALOG
 
 #if wxUSE_MSGDLG
-void MyFrame::MessageBox(wxCommandEvent& WXUNUSED(event) )
-{
-    wxMessageDialog dialog(NULL,
-                           _T("This is a message box\nA long, long string to test out the message box properly"),
-                           _T("Message box text"),
-                           wxNO_DEFAULT | wxYES_NO | wxCANCEL | wxICON_INFORMATION);
-
-    if ( dialog.SetYesNoLabels(_T("Answer &Yes"),_T("Answer &No")) )
+void MyFrame::MessageBox(wxCommandEvent& WXUNUSED(event))
+{
+    wxMessageDialog dialog(this,
+                           "This is a message box\n"
+                           "A long, long string to test out the message box "
+                           "layout properly.",
+                           "Message box text",
+                           wxVSCROLL | wxCENTER |
+                           wxNO_DEFAULT | wxYES_NO | wxCANCEL |
+                           wxICON_INFORMATION);
+
+    wxString extmsg;
+    if ( dialog.SetYesNoCancelLabels
+                (
+                    "Answer &Yes",
+                    "Answer &No",
+                    "Refuse to answer"
+                ) )
     {
-        dialog.SetExtendedMessage(_T("This platform supports custom button labels"));
+        extmsg = "This platform supports custom button labels,\n"
+                 "so you should see the descriptive labels below.";
     }
     else
     {
-        dialog.SetExtendedMessage(_T("Custom button labels are not supported."));
+        extmsg = "Custom button labels are not supported on this platform,\n"
+                 "so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used.";
     }
+    dialog.SetExtendedMessage(extmsg);
 
     switch ( dialog.ShowModal() )
     {
@@ -683,6 +698,12 @@ void MyFrame::MessageBox(wxCommandEvent& WXUNUSED(event) )
     }
 }
 
+void MyFrame::MessageBoxDialog(wxCommandEvent& WXUNUSED(event))
+{
+    TestMessageBoxDialog dlg(this);
+    dlg.ShowModal();
+}
+
 void MyFrame::MessageBoxInfo(wxCommandEvent& WXUNUSED(event))
 {
     ::wxInfoMessageBox(this);
@@ -797,6 +818,43 @@ void MyFrame::MultiChoice(wxCommandEvent& WXUNUSED(event) )
 #endif // wxUSE_CHOICEDLG
 
 #if wxUSE_FILEDLG
+
+// panel with custom controls for file dialog
+class MyExtraPanel : public wxPanel
+{
+public:
+    MyExtraPanel(wxWindow *parent);
+    void OnCheckBox(wxCommandEvent& event) { m_btn->Enable(event.IsChecked()); }
+    wxString GetInfo() const
+    {
+        return wxString::Format("checkbox value = %d", (int) m_cb->GetValue());
+    }
+private:
+    wxButton *m_btn;
+    wxCheckBox *m_cb;
+};
+
+MyExtraPanel::MyExtraPanel(wxWindow *parent)
+            : wxPanel(parent)
+{
+    m_btn = new wxButton(this, -1, _T("Custom Button"));
+    m_btn->Enable(false);
+    m_cb = new wxCheckBox(this, -1, _T("Enable Custom Button"));
+    m_cb->Connect(wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED,
+                  wxCommandEventHandler(MyExtraPanel::OnCheckBox), NULL, this);
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+    sizerTop->Add(m_cb, wxSizerFlags().Centre().Border());
+    sizerTop->AddStretchSpacer();
+    sizerTop->Add(m_btn, wxSizerFlags().Right().Border());
+    SetSizerAndFit(sizerTop);
+}
+
+// a static method can be used instead of a function with most of compilers
+static wxWindow* createMyExtraPanel(wxWindow *parent)
+{
+    return new MyExtraPanel(parent);
+}
+
 void MyFrame::FileOpen(wxCommandEvent& WXUNUSED(event) )
 {
     wxFileDialog dialog
@@ -812,18 +870,23 @@ void MyFrame::FileOpen(wxCommandEvent& WXUNUSED(event) )
 #endif
                  );
 
+    dialog.SetExtraControlCreator(&createMyExtraPanel);
     dialog.CentreOnParent();
     dialog.SetDirectory(wxGetHomeDir());
 
     if (dialog.ShowModal() == wxID_OK)
     {
         wxString info;
+        MyExtraPanel *extra_panel
+            = static_cast<MyExtraPanel*>(dialog.GetExtraControl());
         info.Printf(_T("Full file name: %s\n")
                     _T("Path: %s\n")
-                    _T("Name: %s"),
+                    _T("Name: %s\n")
+                    _T("Custom window: %s"),
                     dialog.GetPath().c_str(),
                     dialog.GetDirectory().c_str(),
-                    dialog.GetFilename().c_str());
+                    dialog.GetFilename().c_str(),
+                    extra_panel->GetInfo().c_str());
         wxMessageDialog dialog2(this, info, _T("Selected file"));
         dialog2.ShowModal();
     }
@@ -931,6 +994,7 @@ void MyFrame::FileOpenGeneric(wxCommandEvent& WXUNUSED(event) )
                     _T("C++ files (*.cpp;*.h)|*.cpp;*.h")
                  );
 
+    dialog.SetExtraControlCreator(&createMyExtraPanel);
     dialog.SetDirectory(wxGetHomeDir());
 
     if (dialog.ShowModal() == wxID_OK)
@@ -1222,6 +1286,65 @@ void MyFrame::OnStandardButtonsSizerDialog(wxCommandEvent& WXUNUSED(event))
     dialog.ShowModal();
 }
 
+// TestDefaultAction
+
+#define ID_CATCH_LISTBOX_DCLICK 100
+#define ID_LISTBOX              101
+
+BEGIN_EVENT_TABLE(TestDefaultActionDialog, wxDialog)
+    EVT_CHECKBOX(ID_CATCH_LISTBOX_DCLICK,    TestDefaultActionDialog::OnCatchListBoxDClick)
+    EVT_LISTBOX_DCLICK(ID_LISTBOX,           TestDefaultActionDialog::OnListBoxDClick)
+END_EVENT_TABLE()
+
+TestDefaultActionDialog::TestDefaultActionDialog( wxWindow *parent ) :
+  wxDialog( parent, -1, "Test default action" )
+{
+    m_catchListBoxDClick = false;
+
+    wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
+
+    wxFlexGridSizer *grid_sizer = new wxFlexGridSizer( 2, 5, 5 );
+
+    wxListBox *listbox = new wxListBox( this, ID_LISTBOX );
+    listbox->Append( "String 1" );
+    listbox->Append( "String 2" );
+    listbox->Append( "String 3" );
+    listbox->Append( "String 4" );
+    grid_sizer->Add( listbox );
+
+    grid_sizer->Add( new wxCheckBox( this, ID_CATCH_LISTBOX_DCLICK, "Catch DoubleClick from wxListBox" ), 0, wxALIGN_CENTRE_VERTICAL );
+
+    grid_sizer->Add( new wxTextCtrl( this, -1, "", wxDefaultPosition, wxSize(80,-1), 0 ), 0, wxALIGN_CENTRE_VERTICAL );
+    grid_sizer->Add( new wxStaticText( this, -1, "wxTextCtrl without wxTE_PROCESS_ENTER" ), 0, wxALIGN_CENTRE_VERTICAL );
+
+    grid_sizer->Add( new wxTextCtrl( this, -1, "", wxDefaultPosition, wxSize(80,-1), wxTE_PROCESS_ENTER ), 0, wxALIGN_CENTRE_VERTICAL );
+    grid_sizer->Add( new wxStaticText( this, -1, "wxTextCtrl with wxTE_PROCESS_ENTER" ), 0, wxALIGN_CENTRE_VERTICAL );
+
+    main_sizer->Add( grid_sizer, 0, wxALL, 10 );
+
+    wxSizer *button_sizer = CreateSeparatedButtonSizer( wxOK|wxCANCEL );
+    if (button_sizer)
+        main_sizer->Add( button_sizer, 0, wxALL|wxGROW, 5 );
+
+    SetSizerAndFit( main_sizer );
+}
+
+void TestDefaultActionDialog::OnListBoxDClick(wxCommandEvent& event)
+{
+    event.Skip( !m_catchListBoxDClick );
+}
+
+void TestDefaultActionDialog::OnCatchListBoxDClick(wxCommandEvent& WXUNUSED(event))
+{
+    m_catchListBoxDClick = !m_catchListBoxDClick;
+}
+
+void MyFrame::OnTestDefaultActionDialog(wxCommandEvent& WXUNUSED(event))
+{
+    TestDefaultActionDialog dialog( this );
+    dialog.ShowModal();
+}
+
 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event) )
 {
     Close(true);
@@ -1330,7 +1453,7 @@ static void InitAboutInfoWebsite(wxAboutDialogInfo& info)
 
 static void InitAboutInfoAll(wxAboutDialogInfo& info)
 {
-    InitAboutInfoMinimal(info);
+    InitAboutInfoWebsite(info);
 
     // we can add a second developer
     info.AddDeveloper(_T("A.N. Other"));
@@ -1589,10 +1712,7 @@ MyModelessDialog::MyModelessDialog(wxWindow *parent)
     sizerTop->Add(btn, 1, wxEXPAND | wxALL, 5);
     sizerTop->Add(check, 1, wxEXPAND | wxALL, 5);
 
-    SetSizer(sizerTop);
-
-    sizerTop->SetSizeHints(this);
-    sizerTop->Fit(this);
+    SetSizerAndFit(sizerTop);
 }
 
 void MyModelessDialog::OnButton(wxCommandEvent& WXUNUSED(event))
@@ -1632,10 +1752,7 @@ MyModalDialog::MyModalDialog(wxWindow *parent)
     sizerTop->Add(m_btnDelete, 0, wxALIGN_CENTER | wxALL, 5);
     sizerTop->Add(btnOk, 0, wxALIGN_CENTER | wxALL, 5);
 
-    SetSizer(sizerTop);
-
-    sizerTop->SetSizeHints(this);
-    sizerTop->Fit(this);
+    SetSizerAndFit(sizerTop);
 
     m_btnModal->SetFocus();
     m_btnModal->SetDefault();
@@ -1738,9 +1855,8 @@ StdButtonSizerDialog::StdButtonSizerDialog(wxWindow *parent)
 
     EnableDisableControls();
 
-    SetSizer(sizerTop);
+    SetSizerAndFit(sizerTop);
 
-    sizerTop->SetSizeHints(this);
     wxCommandEvent ev;
     OnEvent(ev);
 }
@@ -1953,8 +2069,7 @@ wxPanel* SettingsDialog::CreateGeneralSettingsPage(wxWindow* parent)
 
     topSizer->Add( item0, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );
 
-    panel->SetSizer(topSizer);
-    topSizer->Fit(panel);
+    panel->SetSizerAndFit(topSizer);
 
     return panel;
 }
@@ -2012,10 +2127,229 @@ wxPanel* SettingsDialog::CreateAestheticSettingsPage(wxWindow* parent)
     topSizer->Add( item0, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );
     topSizer->AddSpacer(5);
 
-    panel->SetSizer(topSizer);
-    topSizer->Fit(panel);
+    panel->SetSizerAndFit(topSizer);
 
     return panel;
 }
 
+// ----------------------------------------------------------------------------
+// TestMessageBoxDialog
+// ----------------------------------------------------------------------------
+
+/* static */
+const TestMessageBoxDialog::BtnInfo TestMessageBoxDialog::ms_btnInfo[] =
+{
+    { wxYES,    "&Yes"    },
+    { wxNO,     "&No"     },
+    { wxOK,     "&Ok"     },
+    { wxCANCEL, "&Cancel" },
+};
+
+BEGIN_EVENT_TABLE(TestMessageBoxDialog, wxDialog)
+    EVT_BUTTON(wxID_APPLY, TestMessageBoxDialog::OnApply)
+    EVT_BUTTON(wxID_CLOSE, TestMessageBoxDialog::OnClose)
+END_EVENT_TABLE()
+
+TestMessageBoxDialog::TestMessageBoxDialog(wxWindow *parent)
+                    : wxDialog(parent, wxID_ANY, "Message Box Test Dialog",
+                               wxDefaultPosition, wxDefaultSize,
+                               wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+{
+    wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
+
+    // this sizer allows to configure the messages shown in the message box
+    wxSizer * const
+        sizerMsgs = new wxStaticBoxSizer(wxVERTICAL, this, "&Messages");
+    sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Main message:"));
+    m_textMsg = new wxTextCtrl(this, wxID_ANY, "Hello from a box!",
+                               wxDefaultPosition, wxDefaultSize,
+                               wxTE_MULTILINE);
+    sizerMsgs->Add(m_textMsg, wxSizerFlags(1).Expand().Border(wxBOTTOM));
+
+    sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Extended message:"));
+    m_textExtMsg = new wxTextCtrl(this, wxID_ANY, "",
+                                  wxDefaultPosition, wxDefaultSize,
+                                  wxTE_MULTILINE);
+    sizerMsgs->Add(m_textExtMsg, wxSizerFlags(1).Expand());
+
+    sizerTop->Add(sizerMsgs, wxSizerFlags(1).Expand().Border());
+
+
+    // this one is for configuring the buttons
+    wxFlexGridSizer * const sizerBtns = new wxFlexGridSizer(2, 5, 5);
+    sizerBtns->AddGrowableCol(1);
+
+    sizerBtns->Add(new wxStaticText(this, wxID_ANY, "Button(s)"));
+    sizerBtns->Add(new wxStaticText(this, wxID_ANY, "Custom label"));
+
+    for ( int n = 0; n < Btn_Max; n++ )
+    {
+        m_buttons[n] = new wxCheckBox(this, wxID_ANY, ms_btnInfo[n].name);
+        sizerBtns->Add(m_buttons[n], wxSizerFlags().Centre().Left());
+
+        m_labels[n] = new wxTextCtrl(this, wxID_ANY);
+        sizerBtns->Add(m_labels[n], wxSizerFlags(1).Centre().Expand());
+
+        m_labels[n]->Connect(wxEVT_UPDATE_UI,
+                             wxUpdateUIEventHandler(
+                                 TestMessageBoxDialog::OnUpdateLabelUI),
+                             NULL,
+                             this);
+    }
+
+    wxSizer * const
+        sizerBtnsBox = new wxStaticBoxSizer(wxVERTICAL, this, "&Buttons");
+    sizerBtnsBox->Add(sizerBtns, wxSizerFlags(1).Expand());
+    sizerTop->Add(sizerBtnsBox, wxSizerFlags().Expand().Border());
+
+
+    // icon choice
+    const wxString icons[] = {
+        "&Information", "&Question", "&Warning", "&Error"
+    };
+
+    m_icons = new wxRadioBox(this, wxID_ANY, "&Icon:",
+                             wxDefaultPosition, wxDefaultSize,
+                             WXSIZEOF(icons), icons);
+    sizerTop->Add(m_icons, wxSizerFlags().Expand().Border());
+
+
+    // miscellaneous other stuff
+    wxSizer * const
+        sizerFlags = new wxStaticBoxSizer(wxHORIZONTAL, this, "&Other flags");
+
+    m_chkNoDefault = new wxCheckBox(this, wxID_ANY, "Make \"No\" &default");
+    m_chkNoDefault->Connect(wxEVT_UPDATE_UI,
+                            wxUpdateUIEventHandler(
+                                TestMessageBoxDialog::OnUpdateNoDefaultUI),
+                            NULL,
+                            this);
+    sizerFlags->Add(m_chkNoDefault, wxSizerFlags(1).Border());
+
+    m_chkCentre = new wxCheckBox(this, wxID_ANY, "Centre on &parent");
+    sizerFlags->Add(m_chkCentre, wxSizerFlags(1).Border());
+
+    sizerTop->Add(sizerFlags, wxSizerFlags().Expand().Border());
+
+    // finally buttons to show the resulting message box and close this dialog
+    sizerTop->Add(CreateStdDialogButtonSizer(wxAPPLY | wxCLOSE),
+                  wxSizerFlags().Right().Border());
+
+    SetSizerAndFit(sizerTop);
+
+    m_buttons[Btn_Ok]->SetValue(true);
+}
+
+void TestMessageBoxDialog::OnUpdateLabelUI(wxUpdateUIEvent& event)
+{
+    for ( int n = 0; n < Btn_Max; n++ )
+    {
+        if ( event.GetEventObject() == m_labels[n] )
+        {
+            event.Enable( m_buttons[n]->IsChecked() );
+            return;
+        }
+    }
+
+    wxFAIL_MSG( "called for unknown label" );
+}
+
+void TestMessageBoxDialog::OnUpdateNoDefaultUI(wxUpdateUIEvent& event)
+{
+    event.Enable( m_buttons[Btn_No]->IsChecked() );
+}
+
+void TestMessageBoxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
+{
+    long style = 0;
+
+    for ( int n = 0; n < Btn_Max; n++ )
+    {
+        if ( m_buttons[n]->IsChecked() )
+            style |= ms_btnInfo[n].flag;
+    }
+
+    switch ( m_icons->GetSelection() )
+    {
+        case 0: style |= wxICON_INFORMATION; break;
+        case 1: style |= wxICON_QUESTION; break;
+        case 2: style |= wxICON_WARNING; break;
+        case 3: style |= wxICON_ERROR; break;
+    }
+
+    if ( m_chkCentre->IsChecked() )
+        style |= wxCENTRE;
+
+    if ( m_chkNoDefault->IsEnabled() && m_chkNoDefault->IsChecked() )
+        style |= wxNO_DEFAULT;
+
+
+    wxMessageDialog dlg(this, m_textMsg->GetValue(), "Test Message Box",
+                        style);
+    if ( !m_textExtMsg->IsEmpty() )
+        dlg.SetExtendedMessage(m_textExtMsg->GetValue());
+
+    if ( style & wxYES_NO )
+    {
+        if ( style & wxCANCEL )
+        {
+            dlg.SetYesNoCancelLabels(m_labels[Btn_Yes]->GetValue(),
+                                     m_labels[Btn_No]->GetValue(),
+                                     m_labels[Btn_Cancel]->GetValue());
+        }
+        else
+        {
+            dlg.SetYesNoLabels(m_labels[Btn_Yes]->GetValue(),
+                               m_labels[Btn_No]->GetValue());
+        }
+    }
+    else
+    {
+        if ( style & wxCANCEL )
+        {
+            dlg.SetOKCancelLabels(m_labels[Btn_Ok]->GetValue(),
+                                  m_labels[Btn_Cancel]->GetValue());
+        }
+        else
+        {
+            dlg.SetOKLabel(m_labels[Btn_Ok]->GetValue());
+        }
+    }
+
+    dlg.ShowModal();
+}
+
+void TestMessageBoxDialog::OnClose(wxCommandEvent& WXUNUSED(event))
+{
+    EndModal(wxID_CANCEL);
+}
+
 #endif // USE_SETTINGS_DIALOG
+
+#if wxUSE_LOG
+
+// ----------------------------------------------------------------------------
+// custom log target
+// ----------------------------------------------------------------------------
+
+class MyLogGui : public wxLogGui
+{
+private:
+    virtual void DoShowSingleLogMessage(const wxString& message,
+                                        const wxString& title,
+                                        int style)
+    {
+        wxMessageDialog dlg(NULL, message, title,
+                            wxOK | wxCANCEL | wxCANCEL_DEFAULT | style);
+        dlg.SetOKCancelLabels(wxID_COPY, wxID_OK);
+        dlg.SetExtendedMessage("Note that this is a custom log dialog.");
+        dlg.ShowModal();
+    }
+};
+
+wxLog *MyAppTraits::CreateLogTarget()
+{
+    return new MyLogGui;
+}
+
+#endif // wxUSE_LOG