]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/framecmn.cpp
Applied and extended patch 886524 (wxGridCellFloatEditor doesn't
[wxWidgets.git] / src / common / framecmn.cpp
index 8ab73139d86d4f4a59444f19f49378c18d18cfa2..2070a9cde307f4550b38acfdaca9b67ba6213dbf 100644 (file)
@@ -4,7 +4,7 @@
 // Author:      Julian Smart, Vadim Zeitlin
 // Created:     01/02/97
 // Id:          $Id$
-// Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
+// Copyright:   (c) 1998 Robert Roebling and Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
@@ -16,7 +16,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "framebase.h"
 #endif
 
     #include "wx/statusbr.h"
 #endif
 
-// FIXME - temporary hack in absence of wxTLW in all ports!
-#ifndef wxTopLevelWindowNative
-    #define wxTopLevelWindow wxTopLevelWindowBase
-#endif
-
 // ----------------------------------------------------------------------------
 // event table
 // ----------------------------------------------------------------------------
 
+#if wxUSE_MENUS && wxUSE_STATUSBAR
+
 BEGIN_EVENT_TABLE(wxFrameBase, wxTopLevelWindow)
-    EVT_IDLE(wxFrameBase::OnIdle)
+    EVT_MENU_OPEN(wxFrameBase::OnMenuOpen)
+    EVT_MENU_CLOSE(wxFrameBase::OnMenuClose)
+
     EVT_MENU_HIGHLIGHT_ALL(wxFrameBase::OnMenuHighlight)
 END_EVENT_TABLE()
 
+#endif // wxUSE_MENUS && wxUSE_STATUSBAR
+
 // ============================================================================
 // implementation
 // ============================================================================
@@ -127,20 +128,20 @@ bool wxFrameBase::IsOneOfBars(const wxWindow *win) const
 {
 #if wxUSE_MENUS
     if ( win == GetMenuBar() )
-        return TRUE;
+        return true;
 #endif // wxUSE_MENUS
 
 #if wxUSE_STATUSBAR
     if ( win == GetStatusBar() )
-        return TRUE;
+        return true;
 #endif // wxUSE_STATUSBAR
 
 #if wxUSE_TOOLBAR
     if ( win == GetToolBar() )
-        return TRUE;
+        return true;
 #endif // wxUSE_TOOLBAR
 
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
@@ -154,7 +155,7 @@ wxPoint wxFrameBase::GetClientAreaOrigin() const
 {
     wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
 
-#if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__)
+#if wxUSE_TOOLBAR && !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__)
     wxToolBar *toolbar = GetToolBar();
     if ( toolbar && toolbar->IsShown() )
     {
@@ -184,7 +185,7 @@ bool wxFrameBase::ProcessCommand(int id)
 #if wxUSE_MENUS
     wxMenuBar *bar = GetMenuBar();
     if ( !bar )
-        return FALSE;
+        return false;
 
     wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
     commandEvent.SetEventObject(this);
@@ -193,7 +194,7 @@ bool wxFrameBase::ProcessCommand(int id)
     if (item)
     {
         if (!item->IsEnabled())
-            return TRUE;
+            return true;
 
         if (item->IsCheckable())
         {
@@ -204,16 +205,47 @@ bool wxFrameBase::ProcessCommand(int id)
         }
     }
 
-    return GetEventHandler()->ProcessEvent(commandEvent);
+    GetEventHandler()->ProcessEvent(commandEvent);
+    return true;
 #else // !wxUSE_MENUS
-    return FALSE;
+    return false;
 #endif // wxUSE_MENUS/!wxUSE_MENUS
 }
 
+// Do the UI update processing for this window. This is
+// provided for the application to call if it wants to
+// force a UI update, particularly for the menus and toolbar.
+void wxFrameBase::UpdateWindowUI(long flags)
+{
+    wxWindowBase::UpdateWindowUI(flags);
+    
+#if wxUSE_TOOLBAR
+    if (GetToolBar())
+        GetToolBar()->UpdateWindowUI(flags);
+#endif
+
+#if wxUSE_MENUS
+    if (GetMenuBar())
+    {
+        if ((flags & wxUPDATE_UI_FROMIDLE) && !wxUSE_IDLEMENUUPDATES)
+        {
+            // If coming from an idle event, we only
+            // want to update the menus if we're
+            // in the wxUSE_IDLEMENUUPDATES configuration:
+            // so if we're not, do nothing
+        }
+        else
+            DoMenuUpdates();
+    }
+#endif // wxUSE_MENUS
+}
+
 // ----------------------------------------------------------------------------
-// event handlers
+// event handlers for status bar updates from menus
 // ----------------------------------------------------------------------------
 
+#if wxUSE_MENUS && wxUSE_STATUSBAR
+
 void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
 {
 #if wxUSE_STATUSBAR
@@ -221,11 +253,44 @@ void wxFrameBase::OnMenuHighlight(wxMenuEvent& event)
 #endif // wxUSE_STATUSBAR
 }
 
-void wxFrameBase::OnIdle(wxIdleEvent& WXUNUSED(event) )
+#if !wxUSE_IDLEMENUUPDATES
+void wxFrameBase::OnMenuOpen(wxMenuEvent& event)
+#else
+void wxFrameBase::OnMenuOpen(wxMenuEvent& WXUNUSED(event))
+#endif
 {
-#if wxUSE_MENUS
-    DoMenuUpdates();
-#endif // wxUSE_MENUS
+#if !wxUSE_IDLEMENUUPDATES
+    DoMenuUpdates(event.GetMenu());
+#endif // !wxUSE_IDLEMENUUPDATES
+}
+
+void wxFrameBase::OnMenuClose(wxMenuEvent& WXUNUSED(event))
+{
+    // do we have real status text to restore?
+    if ( m_oldStatusText.length() > 1 || m_oldStatusText[0u] )
+    {
+        if ( m_statusBarPane >= 0 )
+        {
+            wxStatusBar *statbar = GetStatusBar();
+            if ( statbar )
+                statbar->SetStatusText(m_oldStatusText, m_statusBarPane);
+        }
+
+        m_oldStatusText.clear();
+    }
+}
+
+#endif // wxUSE_MENUS && wxUSE_STATUSBAR
+
+// Implement internal behaviour (menu updating on some platforms)
+void wxFrameBase::OnInternalIdle()
+{
+    wxTopLevelWindow::OnInternalIdle();
+    
+#if wxUSE_MENUS && wxUSE_IDLEMENUUPDATES
+    if (wxUpdateUIEvent::CanUpdate(this))
+        DoMenuUpdates();
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -293,18 +358,6 @@ void wxFrameBase::PopStatusText(int number)
     m_frameStatusBar->PopStatusText(number);
 }
 
-void wxFrameBase::DoGiveHelp(const wxString& text, bool show)
-{
-#if wxUSE_STATUSBAR
-    if ( m_statusBarPane < 0 ) return;
-    wxStatusBar* statbar = GetStatusBar();
-    if ( !statbar ) return;
-
-    wxString help = show ? text : wxString();
-    statbar->SetStatusText( help, m_statusBarPane );
-#endif // wxUSE_STATUSBAR
-}
-
 bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId)
 {
 #if wxUSE_MENUS
@@ -329,12 +382,54 @@ bool wxFrameBase::ShowMenuHelp(wxStatusBar *WXUNUSED(statbar), int menuId)
 
     return !helpString.IsEmpty();
 #else // !wxUSE_MENUS
-    return FALSE;
+    return false;
 #endif // wxUSE_MENUS/!wxUSE_MENUS
 }
 
 #endif // wxUSE_STATUSBAR
 
+void wxFrameBase::DoGiveHelp(const wxString& text, bool show)
+{
+#if wxUSE_STATUSBAR
+    if ( m_statusBarPane < 0 )
+    {
+        // status bar messages disabled
+        return;
+    }
+
+    wxStatusBar *statbar = GetStatusBar();
+    if ( !statbar )
+        return;
+
+    wxString help;
+    if ( show )
+        help = text;
+
+    // remember the old status bar text if this is the first time we're called
+    // since the menu has been opened as we're going to overwrite it in our
+    // DoGiveHelp() and we want to restore it when the menu is closed
+    //
+    // note that it would be logical to do this in OnMenuOpen() but under MSW
+    // we get an EVT_MENU_HIGHLIGHT before EVT_MENU_OPEN, strangely enough, and
+    // so this doesn't work and instead we use the ugly trick with using
+    // special m_oldStatusText value as "menu opened" (but it is arguably
+    // better than adding yet another member variable to wxFrame on all
+    // platforms)
+    if ( m_oldStatusText.empty() )
+    {
+        m_oldStatusText = statbar->GetStatusText(m_statusBarPane);
+        if ( m_oldStatusText.empty() )
+        {
+            // use special value to prevent us from doing this the next time
+            m_oldStatusText += _T('\0');
+        }
+    }
+
+    statbar->SetStatusText(help, m_statusBarPane);
+#endif // wxUSE_STATUSBAR
+}
+
+
 // ----------------------------------------------------------------------------
 // toolbar stuff
 // ----------------------------------------------------------------------------
@@ -350,6 +445,18 @@ wxToolBar* wxFrameBase::CreateToolBar(long style,
     wxCHECK_MSG( !m_frameToolBar, (wxToolBar *)NULL,
                  wxT("recreating toolbar in wxFrame") );
 
+    if ( style == -1 )
+    {
+        // use default style
+        //
+        // NB: we don't specify the default value in the method declaration
+        //     because
+        //      a) this allows us to have different defaults for different
+        //         platforms (even if we don't have them right now)
+        //      b) we don't need to include wx/toolbar.h in the header then
+        style = wxBORDER_NONE | wxTB_HORIZONTAL | wxTB_FLAT;
+    }
+
     m_frameToolBar = OnCreateToolBar(style, id, name);
 
     return m_frameToolBar;
@@ -373,51 +480,18 @@ wxToolBar* wxFrameBase::OnCreateToolBar(long style,
 #if wxUSE_MENUS
 
 // update all menus
-void wxFrameBase::DoMenuUpdates()
+void wxFrameBase::DoMenuUpdates(wxMenu* menu)
 {
+    wxEvtHandler* source = GetEventHandler();
     wxMenuBar* bar = GetMenuBar();
 
-#ifdef __WXMSW__
-    wxWindow* focusWin = wxFindFocusDescendant((wxWindow*) this);
-#else
-    wxWindow* focusWin = (wxWindow*) NULL;
-#endif
-    if ( bar != NULL )
+    if (menu)
+        menu->UpdateUI(source);
+    else if ( bar != NULL )
     {
         int nCount = bar->GetMenuCount();
         for (int n = 0; n < nCount; n++)
-            DoMenuUpdates(bar->GetMenu(n), focusWin);
-    }
-}
-
-// update a menu and all submenus recursively
-void wxFrameBase::DoMenuUpdates(wxMenu* menu, wxWindow* focusWin)
-{
-    wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler();
-    wxMenuItemList::Node* node = menu->GetMenuItems().GetFirst();
-    while (node)
-    {
-        wxMenuItem* item = node->GetData();
-        if ( !item->IsSeparator() )
-        {
-            wxWindowID id = item->GetId();
-            wxUpdateUIEvent event(id);
-            event.SetEventObject( this );
-
-            if (evtHandler->ProcessEvent(event))
-            {
-                if (event.GetSetText())
-                    menu->SetLabel(id, event.GetText());
-                if (event.GetSetChecked())
-                    menu->Check(id, event.GetChecked());
-                if (event.GetSetEnabled())
-                    menu->Enable(id, event.GetEnabled());
-            }
-
-            if (item->GetSubMenu())
-                DoMenuUpdates(item->GetSubMenu(), (wxWindow*) NULL);
-        }
-        node = node->GetNext();
+            bar->GetMenu(n)->UpdateUI(source);
     }
 }
 
@@ -449,7 +523,7 @@ void wxFrameBase::SetMenuBar(wxMenuBar *menubar)
 
     DetachMenuBar();
 
-    AttachMenuBar(menubar);
+    this->AttachMenuBar(menubar);
 }
 
 #endif // wxUSE_MENUS