]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/progdlg.cpp
Use the data scheme to load resources in the WebKitGTK+ implementation, rather than...
[wxWidgets.git] / src / msw / progdlg.cpp
index affd761eda2b9c02ffcebe158949e31039ccc05e..a39706ed2994d15e1e43701460acd46dbecea7a6 100644 (file)
 
 #if wxUSE_PROGRESSDLG && wxUSE_THREADS
 
 
 #if wxUSE_PROGRESSDLG && wxUSE_THREADS
 
-#include "wx/msw/private/msgdlg.h"
 #include "wx/progdlg.h"
 #include "wx/progdlg.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/msgdlg.h"
+    #include "wx/stopwatch.h"
+    #include "wx/msw/private.h"
+#endif
+
+#include "wx/msw/private/msgdlg.h"
 #include "wx/evtloop.h"
 
 using namespace wxMSWMessageDialog;
 #include "wx/evtloop.h"
 
 using namespace wxMSWMessageDialog;
@@ -73,10 +81,12 @@ public:
         m_progressBarMarquee = false;
         m_skipped = false;
         m_notifications = 0;
         m_progressBarMarquee = false;
         m_skipped = false;
         m_notifications = 0;
+        m_parent = NULL;
     }
 
     wxCriticalSection m_cs;
 
     }
 
     wxCriticalSection m_cs;
 
+    wxWindow *m_parent;     // Parent window only used to center us over it.
     HWND m_hwnd;            // Task dialog handler
     long m_style;           // wxProgressDialog style
     int m_value;
     HWND m_hwnd;            // Task dialog handler
     long m_style;           // wxProgressDialog style
     int m_value;
@@ -151,14 +161,6 @@ protected:
 // Helper functions
 // ============================================================================
 
 // Helper functions
 // ============================================================================
 
-// This function returns true if the progress dialog with the given style
-// (combination of wxPD_XXX constants) needs the "Close" button and this button
-// only, i.e. not a "Cancel" one.
-bool UsesCloseButtonOnly(long style)
-{
-    return !(style & (wxPD_CAN_ABORT | wxPD_AUTO_HIDE));
-}
-
 BOOL CALLBACK DisplayCloseButton(HWND hwnd, LPARAM lParam)
 {
     wxProgressDialogSharedData *sharedData =
 BOOL CALLBACK DisplayCloseButton(HWND hwnd, LPARAM lParam)
 {
     wxProgressDialogSharedData *sharedData =
@@ -307,7 +309,7 @@ wxProgressDialog::wxProgressDialog( const wxString& title,
       m_title(title)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
       m_title(title)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         SetMaximum(maximum);
 
     {
         SetMaximum(maximum);
 
@@ -347,7 +349,7 @@ wxProgressDialog::~wxProgressDialog()
 bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         {
             wxCriticalSectionLocker locker(m_sharedData->m_cs);
     {
         {
             wxCriticalSectionLocker locker(m_sharedData->m_cs);
@@ -390,7 +392,10 @@ bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
             m_state = Finished;
             m_sharedData->m_state = Finished;
             m_sharedData->m_notifications |= wxSPDD_FINISHED;
             m_state = Finished;
             m_sharedData->m_state = Finished;
             m_sharedData->m_notifications |= wxSPDD_FINISHED;
-            if ( !HasPDFlag(wxPD_AUTO_HIDE) && newmsg.empty() )
+            if ( HasPDFlag(wxPD_AUTO_HIDE) )
+                return true;
+
+            if ( newmsg.empty() )
             {
                 // Provide the finishing message if the application didn't.
                 m_message = _("Done.");
             {
                 // Provide the finishing message if the application didn't.
                 m_message = _("Done.");
@@ -414,7 +419,7 @@ bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip)
 bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
 
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
 
@@ -449,7 +454,7 @@ bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip)
 bool wxProgressDialog::DoNativeBeforeUpdate(bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::DoNativeBeforeUpdate(bool *skip)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         if ( m_sharedData->m_skipped  )
         {
     {
         if ( m_sharedData->m_skipped  )
         {
@@ -479,7 +484,7 @@ void wxProgressDialog::Resume()
     wxGenericProgressDialog::Resume();
 
 #ifdef wxHAS_MSW_TASKDIALOG
     wxGenericProgressDialog::Resume();
 
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         HWND hwnd;
 
     {
         HWND hwnd;
 
@@ -491,7 +496,8 @@ void wxProgressDialog::Resume()
             // it now.
             m_sharedData->m_notifications |= wxSPDD_ENABLE_SKIP;
 
             // it now.
             m_sharedData->m_notifications |= wxSPDD_ENABLE_SKIP;
 
-            if ( !UsesCloseButtonOnly(GetPDStyle()) )
+            // Also re-enable "Cancel" itself
+            if ( HasPDFlag(wxPD_CAN_ABORT) )
                 m_sharedData->m_notifications |= wxSPDD_ENABLE_ABORT;
 
             hwnd = m_sharedData->m_hwnd;
                 m_sharedData->m_notifications |= wxSPDD_ENABLE_ABORT;
 
             hwnd = m_sharedData->m_hwnd;
@@ -515,7 +521,7 @@ void wxProgressDialog::Resume()
 int wxProgressDialog::GetValue() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 int wxProgressDialog::GetValue() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
         return m_sharedData->m_value;
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
         return m_sharedData->m_value;
@@ -528,7 +534,7 @@ int wxProgressDialog::GetValue() const
 wxString wxProgressDialog::GetMessage() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 wxString wxProgressDialog::GetMessage() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
         return m_message;
 #endif // wxHAS_MSW_TASKDIALOG
 
         return m_message;
 #endif // wxHAS_MSW_TASKDIALOG
 
@@ -538,7 +544,7 @@ wxString wxProgressDialog::GetMessage() const
 void wxProgressDialog::SetRange(int maximum)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 void wxProgressDialog::SetRange(int maximum)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         SetMaximum(maximum);
 
     {
         SetMaximum(maximum);
 
@@ -557,7 +563,7 @@ void wxProgressDialog::SetRange(int maximum)
 bool wxProgressDialog::WasSkipped() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::WasSkipped() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         if ( !m_sharedData )
         {
     {
         if ( !m_sharedData )
         {
@@ -576,7 +582,7 @@ bool wxProgressDialog::WasSkipped() const
 bool wxProgressDialog::WasCancelled() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::WasCancelled() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
         return m_sharedData->m_state == Canceled;
     {
         wxCriticalSectionLocker locker(m_sharedData->m_cs);
         return m_sharedData->m_state == Canceled;
@@ -589,7 +595,7 @@ bool wxProgressDialog::WasCancelled() const
 void wxProgressDialog::SetTitle(const wxString& title)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 void wxProgressDialog::SetTitle(const wxString& title)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         m_title = title;
 
     {
         m_title = title;
 
@@ -608,7 +614,7 @@ void wxProgressDialog::SetTitle(const wxString& title)
 wxString wxProgressDialog::GetTitle() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 wxString wxProgressDialog::GetTitle() const
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
         return m_title;
 #endif // wxHAS_MSW_TASKDIALOG
 
         return m_title;
 #endif // wxHAS_MSW_TASKDIALOG
 
@@ -618,7 +624,7 @@ wxString wxProgressDialog::GetTitle() const
 bool wxProgressDialog::Show(bool show)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 bool wxProgressDialog::Show(bool show)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
-    if ( HasNativeProgressDialog() )
+    if ( HasNativeTaskDialog() )
     {
         // The dialog can't be hidden at all and showing it again after it had
         // been shown before doesn't do anything.
     {
         // The dialog can't be hidden at all and showing it again after it had
         // been shown before doesn't do anything.
@@ -636,14 +642,17 @@ bool wxProgressDialog::Show(bool show)
         m_sharedData->m_range = m_maximum;
         m_sharedData->m_state = Uncancelable;
         m_sharedData->m_style = GetPDStyle();
         m_sharedData->m_range = m_maximum;
         m_sharedData->m_state = Uncancelable;
         m_sharedData->m_style = GetPDStyle();
+        m_sharedData->m_parent = GetTopParent();
 
         if ( HasPDFlag(wxPD_CAN_ABORT) )
         {
             m_sharedData->m_state = Continue;
             m_sharedData->m_labelCancel = _("Cancel");
         }
 
         if ( HasPDFlag(wxPD_CAN_ABORT) )
         {
             m_sharedData->m_state = Continue;
             m_sharedData->m_labelCancel = _("Cancel");
         }
-        else if ( !HasPDFlag(wxPD_AUTO_HIDE) )
+        else // Dialog can't be cancelled.
         {
         {
+            // We still must have at least a single button in the dialog so
+            // just don't call it "Cancel" in this case.
             m_sharedData->m_labelCancel = _("Close");
         }
 
             m_sharedData->m_labelCancel = _("Close");
         }
 
@@ -676,22 +685,6 @@ bool wxProgressDialog::Show(bool show)
     return wxGenericProgressDialog::Show( show );
 }
 
     return wxGenericProgressDialog::Show( show );
 }
 
-bool wxProgressDialog::HasNativeProgressDialog() const
-{
-#ifdef wxHAS_MSW_TASKDIALOG
-    // Native task dialog, if available, can't be used without any buttons so
-    // we fall back to the generic one if none of "Skip", "Cancel" and "Close"
-    // buttons is used.
-    return HasNativeTaskDialog()
-            && (HasPDFlag(wxPD_CAN_SKIP | wxPD_CAN_ABORT) ||
-                    !HasPDFlag(wxPD_AUTO_HIDE));
-#else // !wxHAS_MSW_TASKDIALOG
-    // This shouldn't be even called in !wxHAS_MSW_TASKDIALOG case but as we
-    // still must define the function as returning something, return false.
-    return false;
-#endif // wxHAS_MSW_TASKDIALOG/!wxHAS_MSW_TASKDIALOG
-}
-
 void wxProgressDialog::UpdateExpandedInformation(int value)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
 void wxProgressDialog::UpdateExpandedInformation(int value)
 {
 #ifdef wxHAS_MSW_TASKDIALOG
@@ -768,6 +761,11 @@ void* wxProgressDialogTaskRunner::Entry()
         wxTdc.caption = m_sharedData.m_title.wx_str();
         wxTdc.message = m_sharedData.m_message.wx_str();
 
         wxTdc.caption = m_sharedData.m_title.wx_str();
         wxTdc.message = m_sharedData.m_message.wx_str();
 
+        // MSWCommonTaskDialogInit() will add an IDCANCEL button but we need to
+        // give it the correct label.
+        wxTdc.btnOKLabel = m_sharedData.m_labelCancel;
+        wxTdc.useCustomLabels = true;
+
         wxTdc.MSWCommonTaskDialogInit( tdc );
         tdc.pfCallback = TaskDialogCallbackProc;
         tdc.lpCallbackData = (LONG_PTR) &m_sharedData;
         wxTdc.MSWCommonTaskDialogInit( tdc );
         tdc.pfCallback = TaskDialogCallbackProc;
         tdc.lpCallbackData = (LONG_PTR) &m_sharedData;
@@ -776,20 +774,9 @@ void* wxProgressDialogTaskRunner::Entry()
         tdc.dwFlags &= ~TDF_EXPAND_FOOTER_AREA; // Expand in content area.
         tdc.dwCommonButtons = 0; // Don't use common buttons.
 
         tdc.dwFlags &= ~TDF_EXPAND_FOOTER_AREA; // Expand in content area.
         tdc.dwCommonButtons = 0; // Don't use common buttons.
 
-        wxTdc.useCustomLabels = true;
-
         if ( m_sharedData.m_style & wxPD_CAN_SKIP )
             wxTdc.AddTaskDialogButton( tdc, Id_SkipBtn, 0, _("Skip") );
 
         if ( m_sharedData.m_style & wxPD_CAN_SKIP )
             wxTdc.AddTaskDialogButton( tdc, Id_SkipBtn, 0, _("Skip") );
 
-        // Use a Cancel button when requested or use a Close button when
-        // the dialog does not automatically hide.
-        if ( (m_sharedData.m_style & wxPD_CAN_ABORT)
-             || !(m_sharedData.m_style & wxPD_AUTO_HIDE) )
-        {
-            wxTdc.AddTaskDialogButton( tdc, IDCANCEL, 0,
-                                       m_sharedData.m_labelCancel );
-        }
-
         tdc.dwFlags |= TDF_CALLBACK_TIMER | TDF_SHOW_PROGRESS_BAR;
 
         if ( !m_sharedData.m_expandedInformation.empty() )
         tdc.dwFlags |= TDF_CALLBACK_TIMER | TDF_SHOW_PROGRESS_BAR;
 
         if ( !m_sharedData.m_expandedInformation.empty() )
@@ -843,7 +830,30 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc
                            0,
                            MAKELPARAM(0, sharedData->m_range) );
 
                            0,
                            MAKELPARAM(0, sharedData->m_range) );
 
-            if ( UsesCloseButtonOnly(sharedData->m_style) )
+            // We always create this task dialog with NULL parent because our
+            // parent in wx sense is a window created from a different thread
+            // and so can't be used as our real parent. However we still center
+            // this window on the parent one as the task dialogs do with their
+            // real parent usually.
+            if ( sharedData->m_parent )
+            {
+                wxRect rect(wxRectFromRECT(wxGetWindowRect(hwnd)));
+                rect = rect.CentreIn(sharedData->m_parent->GetRect());
+                ::SetWindowPos(hwnd,
+                               NULL,
+                               rect.x,
+                               rect.y,
+                               -1,
+                               -1,
+                               SWP_NOACTIVATE |
+                               SWP_NOOWNERZORDER |
+                               SWP_NOSIZE |
+                               SWP_NOZORDER);
+            }
+
+            // If we can't be aborted, the "Close" button will only be enabled
+            // when the progress ends (and not even then with wxPD_AUTO_HIDE).
+            if ( !(sharedData->m_style & wxPD_CAN_ABORT) )
                 ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, FALSE );
             break;
 
                 ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, FALSE );
             break;
 
@@ -869,7 +879,7 @@ wxProgressDialogTaskRunner::TaskDialogCallbackProc
                     // Close button on the window triggers an IDCANCEL press,
                     // don't allow it when it should only be possible to close
                     // a finished dialog.
                     // Close button on the window triggers an IDCANCEL press,
                     // don't allow it when it should only be possible to close
                     // a finished dialog.
-                    if ( !UsesCloseButtonOnly(sharedData->m_style) )
+                    if ( sharedData->m_style & wxPD_CAN_ABORT )
                     {
                         wxCHECK_MSG
                         (
                     {
                         wxCHECK_MSG
                         (