]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/msgdlg.cpp
use GTK-specific method to delete selection
[wxWidgets.git] / src / msw / msgdlg.cpp
index 35332c4d70544e2785cb58e52be02c4eb26755b3..56c2885867525d4ac649994019090f356b73fcc0 100644 (file)
@@ -18,8 +18,6 @@
 
 #if wxUSE_MSGDLG
 
-#include "wx/ptr_scpd.h"
-
 // there is no hook support under CE so we can't use the code for message box
 // positioning there
 #ifndef __WXWINCE__
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/msgdlg.h"
     #include "wx/app.h"
     #include "wx/intl.h"
     #include "wx/utils.h"
-    #include "wx/dialog.h"
+    #include "wx/msw/private.h"
     #if wxUSE_MSGBOX_HOOK
         #include "wx/hashmap.h"
     #endif
 #endif
 
+#include "wx/ptr_scpd.h"
 #include "wx/dynlib.h"
-#include "wx/msw/private.h"
 #include "wx/msw/private/button.h"
 #include "wx/msw/private/metrics.h"
 #include "wx/msw/private/msgdlg.h"
-#include "wx/msgdlg.h"
+#include "wx/modalhook.h"
 
 #if wxUSE_MSGBOX_HOOK
     #include "wx/fontutil.h"
     #include "wx/msw/wince/missing.h"
 #endif
 
+// Interestingly, this symbol currently seems to be absent from Platform SDK
+// headers but it is documented at MSDN.
+#ifndef TDF_SIZE_TO_CONTENT
+    #define TDF_SIZE_TO_CONTENT 0x1000000
+#endif
+
 using namespace wxMSWMessageDialog;
 
 IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
@@ -255,8 +260,10 @@ void wxMessageDialog::ReplaceStaticWithEdit()
     {
         if ( *i != '\n' )
         {
-            // found last non-newline char, remove everything after it and stop
-            text.erase(i.base() + 1, text.end());
+            // found last non-newline char, remove anything after it if
+            // necessary and stop in any case
+            if ( i != text.rbegin() )
+                text.erase(i.base() + 1, text.end());
             break;
         }
     }
@@ -265,7 +272,7 @@ void wxMessageDialog::ReplaceStaticWithEdit()
     HWND hwndEdit = ::CreateWindow
                       (
                         wxT("EDIT"),
-                        wxTextBuffer::Translate(text).wx_str(),
+                        wxTextBuffer::Translate(text).t_str(),
                         WS_CHILD | WS_VSCROLL | WS_VISIBLE |
                         ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL,
                         rc.left, rc.top,
@@ -367,7 +374,7 @@ void wxMessageDialog::AdjustButtonLabels()
         if ( widthNeeded > wBtnNew )
             wBtnNew = widthNeeded;
 
-        ::SetWindowText(hwndBtn, label.wx_str());
+        ::SetWindowText(hwndBtn, label.t_str());
     }
 
     if ( wBtnNew <= wBtnOld )
@@ -454,12 +461,16 @@ int wxMessageDialog::ShowMessageBox()
 #if wxUSE_INTL
     // native message box always uses the current user locale but the program
     // may be using a different one and in this case we need to manually
-    // translate the button labels to avoid mismatch between the language of
-    // the message box text and its buttons
+    // translate the default button labels (if they're non default we have no
+    // way to translate them and so we must assume they were already
+    // translated) to avoid mismatch between the language of the message box
+    // text and its buttons
     wxLocale * const loc = wxGetLocale();
     if ( loc && loc->GetLanguage() != wxLocale::GetSystemLanguage() )
     {
-        if ( m_dialogStyle & wxYES_NO )
+        if ( m_dialogStyle & wxYES_NO &&
+                (GetCustomYesLabel().empty() && GetCustomNoLabel().empty()) )
+
         {
             // use the strings with mnemonics here as the native message box
             // does
@@ -475,7 +486,8 @@ int wxMessageDialog::ShowMessageBox()
         // native message box (which probably doesn't use them because
         // Enter/Esc keys can be already used to dismiss the message box
         // using keyboard)
-        SetOKCancelLabels(_("OK"), _("Cancel"));
+        if ( GetCustomOKLabel().empty() && GetCustomCancelLabel().empty() )
+            SetOKCancelLabels(_("OK"), _("Cancel"));
     }
 #endif // wxUSE_INTL
 
@@ -511,6 +523,11 @@ int wxMessageDialog::ShowMessageBox()
         }
     }
 
+    if ( wxStyle & wxHELP )
+    {
+        msStyle |= MB_HELP;
+    }
+
     // set the icon style
     switch ( GetEffectiveIcon() )
     {
@@ -568,13 +585,15 @@ int wxMessageDialog::ShowMessageBox()
 #endif // wxUSE_MSGBOX_HOOK
 
     // do show the dialog
-    int msAns = MessageBox(hWnd, message.wx_str(), m_caption.wx_str(), msStyle);
+    int msAns = MessageBox(hWnd, message.t_str(), m_caption.t_str(), msStyle);
 
     return MSWTranslateReturnCode(msAns);
 }
 
 int wxMessageDialog::ShowModal()
 {
+    WX_HOOK_MODAL_DIALOG();
+
 #ifdef wxHAS_MSW_TASKDIALOG
     if ( HasNativeTaskDialog() )
     {
@@ -593,6 +612,16 @@ int wxMessageDialog::ShowModal()
             return wxID_CANCEL;
         }
 
+        // In case only an "OK" button was specified we actually created a
+        // "Cancel" button (see comment in MSWCommonTaskDialogInit). This
+        // results in msAns being IDCANCEL while we want IDOK (just like
+        // how the native MessageBox function does with only an "OK" button).
+        if ( (msAns == IDCANCEL)
+            && !(GetMessageDialogStyle() & (wxYES_NO|wxCANCEL)) )
+        {
+            msAns = IDOK;
+        }
+
         return MSWTranslateReturnCode( msAns );
     }
 #endif // wxHAS_MSW_TASKDIALOG
@@ -600,6 +629,18 @@ int wxMessageDialog::ShowModal()
     return ShowMessageBox();
 }
 
+long wxMessageDialog::GetEffectiveIcon() const
+{
+    // only use the auth needed icon if available, otherwise fallback to the default logic
+    if ( (m_dialogStyle & wxICON_AUTH_NEEDED) &&
+        wxMSWMessageDialog::HasNativeTaskDialog() )
+    {
+        return wxICON_AUTH_NEEDED;
+    }
+
+    return wxMessageDialogBase::GetEffectiveIcon();
+}
+
 void wxMessageDialog::DoCentre(int dir)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
@@ -610,7 +651,7 @@ void wxMessageDialog::DoCentre(int dir)
         return;
 #endif // wxHAS_MSW_TASKDIALOG
 
-    return wxMessageDialogBase::DoCentre(dir);
+    wxMessageDialogBase::DoCentre(dir);
 }
 
 // ----------------------------------------------------------------------------
@@ -620,7 +661,7 @@ void wxMessageDialog::DoCentre(int dir)
 #ifdef wxHAS_MSW_TASKDIALOG
 
 wxMSWTaskDialogConfig::wxMSWTaskDialogConfig(const wxMessageDialogBase& dlg)
-                     : buttons(new TASKDIALOG_BUTTON[3])
+                     : buttons(new TASKDIALOG_BUTTON[MAX_BUTTONS])
 {
     parent = dlg.GetParentForModalDialog();
     caption = dlg.GetCaption();
@@ -655,13 +696,22 @@ wxMSWTaskDialogConfig::wxMSWTaskDialogConfig(const wxMessageDialogBase& dlg)
     btnNoLabel = dlg.GetNoLabel();
     btnOKLabel = dlg.GetOKLabel();
     btnCancelLabel = dlg.GetCancelLabel();
+    btnHelpLabel = dlg.GetHelpLabel();
 }
 
 void wxMSWTaskDialogConfig::MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc)
 {
-    tdc.dwFlags = TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW;
+    // Use TDF_SIZE_TO_CONTENT to try to prevent Windows from truncating or
+    // ellipsizing the message text. This doesn't always work as Windows will
+    // still do it if the message contains too long "words" (i.e. runs of the
+    // text without spaces) but at least it ensures that the message text is
+    // fully shown for reasonably-sized words whereas without it using almost
+    // any file system path in a message box would result in truncation.
+    tdc.dwFlags = TDF_EXPAND_FOOTER_AREA |
+                  TDF_POSITION_RELATIVE_TO_WINDOW |
+                  TDF_SIZE_TO_CONTENT;
     tdc.hInstance = wxGetInstance();
-    tdc.pszWindowTitle = caption.wx_str();
+    tdc.pszWindowTitle = caption.t_str();
 
     // use the top level window as parent if none specified
     tdc.hwndParent = parent ? GetHwndOf(parent) : NULL;
@@ -678,12 +728,12 @@ void wxMSWTaskDialogConfig::MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc)
     // message in our ctor, see comment there.
     if ( !extendedMessage.empty() )
     {
-        tdc.pszMainInstruction = message.wx_str();
-        tdc.pszContent = extendedMessage.wx_str();
+        tdc.pszMainInstruction = message.t_str();
+        tdc.pszContent = extendedMessage.t_str();
     }
     else
     {
-        tdc.pszContent = message.wx_str();
+        tdc.pszContent = message.t_str();
     }
 
     // set an icon to be used, if possible
@@ -700,6 +750,10 @@ void wxMSWTaskDialogConfig::MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc)
         case wxICON_INFORMATION:
             tdc.pszMainIcon = TD_INFORMATION_ICON;
             break;
+
+        case wxICON_AUTH_NEEDED:
+            tdc.pszMainIcon = TD_SHIELD_ICON;
+            break;
     }
 
     // custom label button array that can hold all buttons in use
@@ -721,16 +775,38 @@ void wxMSWTaskDialogConfig::MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc)
     }
     else // without Yes/No we're going to have an OK button
     {
-        AddTaskDialogButton(tdc, IDOK, TDCBF_OK_BUTTON, btnOKLabel);
-
         if ( style & wxCANCEL )
         {
+            AddTaskDialogButton(tdc, IDOK, TDCBF_OK_BUTTON, btnOKLabel);
             AddTaskDialogButton(tdc, IDCANCEL,
                                 TDCBF_CANCEL_BUTTON, btnCancelLabel);
 
             if ( style & wxCANCEL_DEFAULT )
                 tdc.nDefaultButton = IDCANCEL;
         }
+        else // Only "OK"
+        {
+            // We actually create a "Cancel" button instead because we want to
+            // allow closing the dialog box with Escape (and also Alt-F4 or
+            // clicking the close button in the title bar) which wouldn't work
+            // without a Cancel button.
+            if ( !useCustomLabels )
+            {
+                useCustomLabels = true;
+                btnOKLabel = _("OK");
+            }
+
+            AddTaskDialogButton(tdc, IDCANCEL, TDCBF_CANCEL_BUTTON, btnOKLabel);
+        }
+    }
+
+    if ( style & wxHELP )
+    {
+        // There is no support for "Help" button in the task dialog, it can
+        // only show "Retry" or "Close" ones.
+        useCustomLabels = true;
+
+        AddTaskDialogButton(tdc, IDHELP, 0 /* not used */, btnHelpLabel);
     }
 }
 
@@ -745,8 +821,12 @@ void wxMSWTaskDialogConfig::AddTaskDialogButton(TASKDIALOGCONFIG &tdc,
         TASKDIALOG_BUTTON &tdBtn = buttons[tdc.cButtons];
 
         tdBtn.nButtonID = btnCustomId;
-        tdBtn.pszButtonText = customLabel.wx_str();
+        tdBtn.pszButtonText = customLabel.t_str();
         tdc.cButtons++;
+
+        // We should never have more than 4 buttons currently as this is the
+        // maximal number of buttons supported by the message dialog.
+        wxASSERT_MSG( tdc.cButtons <= MAX_BUTTONS, wxT("Too many buttons") );
     }
     else
     {
@@ -816,6 +896,9 @@ int wxMSWMessageDialog::MSWTranslateReturnCode(int msAns)
         case IDNO:
             ans = wxID_NO;
             break;
+        case IDHELP:
+            ans = wxID_HELP;
+            break;
     }
 
     return ans;