]> git.saurik.com Git - wxWidgets.git/commitdiff
1. small dnd compilation fixes (no attempt to make icon setting work though)
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 25 Oct 1999 15:51:37 +0000 (15:51 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 25 Oct 1999 15:51:37 +0000 (15:51 +0000)
2. wxMenuItemBase appears
3. more key combinations handled by wxGTK for menu accels

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4184 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

17 files changed:
include/wx/dnd.h
include/wx/gtk/menu.h
include/wx/gtk/menuitem.h
include/wx/gtk1/menu.h
include/wx/gtk1/menuitem.h
include/wx/menuitem.h
include/wx/msw/menu.h
include/wx/msw/menuitem.h
include/wx/ownerdrw.h
include/wx/utils.h
src/common/utilscmn.cpp
src/gtk/dnd.cpp
src/gtk/menu.cpp
src/gtk1/dnd.cpp
src/gtk1/menu.cpp
src/msw/menu.cpp
src/msw/menuitem.cpp

index 0d113904ec00d431dd801c97b3a77866d54e7922..6233f1525a2c51a37f64424207489ed70d3101d9 100644 (file)
@@ -17,6 +17,7 @@
 #if wxUSE_DRAG_AND_DROP
 
 #include "wx/dataobj.h"
+#include "wx/cursor.h"
 
 // ----------------------------------------------------------------------------
 // constants
index dfa05697189c8f6a64cc5370ed4319e2d9f23dc4..9d4b13d2d0cbb429d31e3f10f2afe9f295c3d68d 100644 (file)
@@ -29,12 +29,6 @@ class wxMenuBar;
 class wxMenuItem;
 class wxMenu;
 
-//-----------------------------------------------------------------------------
-// const
-//-----------------------------------------------------------------------------
-
-#define   ID_SEPARATOR    (-1)
-
 //-----------------------------------------------------------------------------
 // wxMenuBar
 //-----------------------------------------------------------------------------
index 500e235d6814fdde5730c337a51152ac4e2435e6..8152ab4d6af51ce867db77647c45ba3b54114f7c 100644 (file)
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-#include "wx/string.h"
-
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-#define   ID_SEPARATOR    (-1)
-
-//-----------------------------------------------------------------------------
-// classes
-//-----------------------------------------------------------------------------
-
-class wxMenuItem;
-class wxMenu;
-
 //-----------------------------------------------------------------------------
 // wxMenuItem
 //-----------------------------------------------------------------------------
 
-class wxMenuItem : public wxObject
+class wxMenuItem : public wxMenuItemBase
 {
-DECLARE_DYNAMIC_CLASS(wxMenuItem)
-
 public:
-    wxMenuItem();
+    wxMenuItem(wxMenu *parentMenu = (wxMenu *)NULL,
+               int id = wxID_SEPARATOR,
+               const wxString& text = wxEmptyString,
+               const wxString& help = wxEmptyString,
+               bool isCheckable = FALSE,
+               wxMenu *subMenu = (wxMenu *)NULL);
     ~wxMenuItem();
 
-    // accessors
-        // id
-    void SetId(int id) { m_id = id; }
-    int  GetId() const { return m_id; }
-    bool IsSeparator() const { return m_id == ID_SEPARATOR; }
-
-        // the item's text = name
-    void SetName(const wxString& str);
-    void SetText(const wxString& str) { SetName(str); } // compatibility
-    const wxString& GetName() const { return m_text; }
-    const wxString& GetText() const { return GetName(); }
-
-        // what kind of menu item we are
-    void SetCheckable(bool checkable) { m_isCheckMenu = checkable; }
-    bool IsCheckable() const { return m_isCheckMenu; }
-    void SetSubMenu(wxMenu *menu) { m_subMenu = menu; }
-    wxMenu *GetSubMenu() const { return m_subMenu; }
-    bool IsSubMenu() const { return m_subMenu != NULL; }
-
-        // state
-    void Enable( bool enable = TRUE );
-    bool IsEnabled() const { return m_isEnabled; }
-    void Check( bool check = TRUE );
-    bool IsChecked() const;
-
-        // help string (displayed in the status bar by default)
-    void SetHelp(const wxString& str) { m_helpStr = str; }
-    const wxString& GetHelp() const { return m_helpStr; }
+    // implement base class virtuals
+    virtual void SetText( const wxString& str ) { DoSetText(str); }
+    virtual void Enable( bool enable = TRUE );
+    virtual void Check( bool check = TRUE );
+    virtual bool IsChecked() const;
 
     // implementation
     void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
     GtkWidget *GetMenuItem() const { return m_menuItem; }
-    
-    wxString GetHotKey() const { return m_hotKey; }
 
-    void SetCheckedFlag(bool checked) { m_isChecked = checked; }
-    bool GetCheckedFlag() const { return m_isChecked; }
+    wxString GetHotKey() const { return m_hotKey; }
 
 private:
-    int           m_id;
-    wxString      m_text;
-    wxString      m_hotKey;
-    bool          m_isCheckMenu;
-    bool          m_isChecked;
-    bool          m_isEnabled;
-    wxMenu       *m_subMenu;
-    wxString      m_helpStr;
+    // DoSetText() transforms the accel mnemonics in our label from MSW/wxWin
+    // style to GTK+ and is called from ctor and SetText()
+    void DoSetText(const wxString& text);
+
+    wxString  m_hotKey;
+
+    GtkWidget *m_menuItem;  // GtkMenuItem
 
-    GtkWidget    *m_menuItem;  // GtkMenuItem
+    DECLARE_DYNAMIC_CLASS(wxMenuItem)
 };
 
 
index dfa05697189c8f6a64cc5370ed4319e2d9f23dc4..9d4b13d2d0cbb429d31e3f10f2afe9f295c3d68d 100644 (file)
@@ -29,12 +29,6 @@ class wxMenuBar;
 class wxMenuItem;
 class wxMenu;
 
-//-----------------------------------------------------------------------------
-// const
-//-----------------------------------------------------------------------------
-
-#define   ID_SEPARATOR    (-1)
-
 //-----------------------------------------------------------------------------
 // wxMenuBar
 //-----------------------------------------------------------------------------
index 500e235d6814fdde5730c337a51152ac4e2435e6..8152ab4d6af51ce867db77647c45ba3b54114f7c 100644 (file)
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-#include "wx/string.h"
-
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-#define   ID_SEPARATOR    (-1)
-
-//-----------------------------------------------------------------------------
-// classes
-//-----------------------------------------------------------------------------
-
-class wxMenuItem;
-class wxMenu;
-
 //-----------------------------------------------------------------------------
 // wxMenuItem
 //-----------------------------------------------------------------------------
 
-class wxMenuItem : public wxObject
+class wxMenuItem : public wxMenuItemBase
 {
-DECLARE_DYNAMIC_CLASS(wxMenuItem)
-
 public:
-    wxMenuItem();
+    wxMenuItem(wxMenu *parentMenu = (wxMenu *)NULL,
+               int id = wxID_SEPARATOR,
+               const wxString& text = wxEmptyString,
+               const wxString& help = wxEmptyString,
+               bool isCheckable = FALSE,
+               wxMenu *subMenu = (wxMenu *)NULL);
     ~wxMenuItem();
 
-    // accessors
-        // id
-    void SetId(int id) { m_id = id; }
-    int  GetId() const { return m_id; }
-    bool IsSeparator() const { return m_id == ID_SEPARATOR; }
-
-        // the item's text = name
-    void SetName(const wxString& str);
-    void SetText(const wxString& str) { SetName(str); } // compatibility
-    const wxString& GetName() const { return m_text; }
-    const wxString& GetText() const { return GetName(); }
-
-        // what kind of menu item we are
-    void SetCheckable(bool checkable) { m_isCheckMenu = checkable; }
-    bool IsCheckable() const { return m_isCheckMenu; }
-    void SetSubMenu(wxMenu *menu) { m_subMenu = menu; }
-    wxMenu *GetSubMenu() const { return m_subMenu; }
-    bool IsSubMenu() const { return m_subMenu != NULL; }
-
-        // state
-    void Enable( bool enable = TRUE );
-    bool IsEnabled() const { return m_isEnabled; }
-    void Check( bool check = TRUE );
-    bool IsChecked() const;
-
-        // help string (displayed in the status bar by default)
-    void SetHelp(const wxString& str) { m_helpStr = str; }
-    const wxString& GetHelp() const { return m_helpStr; }
+    // implement base class virtuals
+    virtual void SetText( const wxString& str ) { DoSetText(str); }
+    virtual void Enable( bool enable = TRUE );
+    virtual void Check( bool check = TRUE );
+    virtual bool IsChecked() const;
 
     // implementation
     void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
     GtkWidget *GetMenuItem() const { return m_menuItem; }
-    
-    wxString GetHotKey() const { return m_hotKey; }
 
-    void SetCheckedFlag(bool checked) { m_isChecked = checked; }
-    bool GetCheckedFlag() const { return m_isChecked; }
+    wxString GetHotKey() const { return m_hotKey; }
 
 private:
-    int           m_id;
-    wxString      m_text;
-    wxString      m_hotKey;
-    bool          m_isCheckMenu;
-    bool          m_isChecked;
-    bool          m_isEnabled;
-    wxMenu       *m_subMenu;
-    wxString      m_helpStr;
+    // DoSetText() transforms the accel mnemonics in our label from MSW/wxWin
+    // style to GTK+ and is called from ctor and SetText()
+    void DoSetText(const wxString& text);
+
+    wxString  m_hotKey;
+
+    GtkWidget *m_menuItem;  // GtkMenuItem
 
-    GtkWidget    *m_menuItem;  // GtkMenuItem
+    DECLARE_DYNAMIC_CLASS(wxMenuItem)
 };
 
 
index c19c785ffeb14297df67b52ff0443841e3b3ce42..ea5ac56053b7ef35fcdbb1ee0d256c801fa0b982 100644 (file)
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/menuitem.h
+// Purpose:     wxMenuItem class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     25.10.99
+// RCS-ID:      $Id$
+// Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
 #ifndef _WX_MENUITEM_H_BASE_
 #define _WX_MENUITEM_H_BASE_
 
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "wx/object.h"  // base class
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// id for a separator line in the menu (invalid for normal item)
+#define wxID_SEPARATOR (-1)
+
+#ifndef ID_SEPARATOR    // for compatibility only, don't use in new code
+    #define ID_SEPARATOR    wxID_SEPARATOR
+#endif
+
+// ----------------------------------------------------------------------------
+// forward declarations
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMenuItem;
+class WXDLLEXPORT wxMenu;
+
+// ----------------------------------------------------------------------------
+// wxMenuItem is an item in the menu which may be either a normal item, a sub
+// menu or a separator
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxMenuItemBase : public wxObject
+{
+public:
+    // creation
+    static wxMenuItem *New(wxMenu *parentMenu = (wxMenu *)NULL,
+                           int id = wxID_SEPARATOR,
+                           const wxString& text = wxEmptyString,
+                           const wxString& help = wxEmptyString,
+                           bool isCheckable = FALSE,
+                           wxMenu *subMenu = (wxMenu *)NULL);
+
+    // get/set id
+    void SetId(int id) { m_id = id; }
+    int  GetId() const { return m_id; }
+    bool IsSeparator() const { return m_id == wxID_SEPARATOR; }
+
+    // the item's text (or name, or label...)
+    virtual void SetText(const wxString& str) { m_text = str; }
+    const wxString& GetText() const { return m_text; }
+
+    // what kind of menu item we are
+    virtual void SetCheckable(bool checkable) { m_isCheckable = checkable; }
+    bool IsCheckable() const { return m_isCheckable; }
+
+    bool IsSubMenu() const { return m_subMenu != NULL; }
+    void SetSubMenu(wxMenu *menu) { m_subMenu = menu; }
+    wxMenu *GetSubMenu() const { return m_subMenu; }
+
+    // state
+    virtual void Enable(bool enable = TRUE) { m_isEnabled = enable; }
+    virtual bool IsEnabled() const { return m_isEnabled; }
+    virtual void Check(bool check = TRUE) { m_isChecked = check; }
+    virtual bool IsChecked() const { return m_isChecked; }
+
+    // help string (displayed in the status bar by default)
+    void SetHelp(const wxString& str) { m_help = str; }
+    const wxString& GetHelp() const { return m_help; }
+
+    // compatibility only, use new functions in the new code
+    void SetName(const wxString& str) { SetText(str); }
+    const wxString& GetName() const { return GetText(); }
+
+protected:
+    int           m_id;             // numeric id of the item >= 0 or -1
+    wxMenu       *m_parentMenu,     // the menu we belong to
+                 *m_subMenu;        // our sub menu or NULL
+    wxString      m_text,           // label of the item
+                  m_help;           // the help string for the item
+    bool          m_isCheckable;    // can be checked?
+    bool          m_isChecked;      // is checked?
+    bool          m_isEnabled;      // is enabled?
+};
+
+// ----------------------------------------------------------------------------
+// include the real class declaration
+// ----------------------------------------------------------------------------
+
+#ifdef wxUSE_BASE_CLASSES_ONLY
+    #define wxMenuItem wxMenuItemBase
+#else // !wxUSE_BASE_CLASSES_ONLY
 #if defined(__WXMSW__)
-#include "wx/msw/menuitem.h"
+    #include "wx/msw/menuitem.h"
 #elif defined(__WXMOTIF__)
-#include "wx/motif/menuitem.h"
+    #include "wx/motif/menuitem.h"
 #elif defined(__WXGTK__)
-#include "wx/gtk/menuitem.h"
+    #include "wx/gtk/menuitem.h"
 #elif defined(__WXQT__)
-#include "wx/qt/menuitem.h"
+    #include "wx/qt/menuitem.h"
 #elif defined(__WXMAC__)
-#include "wx/mac/menuitem.h"
+    #include "wx/mac/menuitem.h"
 #elif defined(__WXPM__)
-#include "wx/os2/menuitem.h"
+    #include "wx/os2/menuitem.h"
 #elif defined(__WXSTUBS__)
-#include "wx/stubs/menuitem.h"
+    #include "wx/stubs/menuitem.h"
 #endif
+#endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY
 
 #endif
     // _WX_MENUITEM_H_BASE_
index 9d2ca80bd8f63c33d8b8c0b511def5d4b1063b85..e8fed5225a7e219f40cb3a8d4b69fea0139b9b88 100644 (file)
@@ -22,7 +22,7 @@
 #include "wx/string.h"
 
 #if wxUSE_ACCEL
-#include "wx/accel.h"
+    #include "wx/accel.h"
 #endif // wxUSE_ACCEL
 
 class WXDLLEXPORT wxMenuItem;
@@ -32,6 +32,8 @@ class WXDLLEXPORT wxFrame;
 
 WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
 
+WX_DEFINE_ARRAY(wxAcceleratorEntry *, wxAcceleratorArray);
+
 // ----------------------------------------------------------------------------
 // Menu
 // ----------------------------------------------------------------------------
@@ -50,7 +52,7 @@ public:
 
     wxMenu( long WXUNUSED(style) )
     {
-       Init( wxEmptyString );
+        Init( wxEmptyString );
     }
 
     wxMenu(const wxString& title = wxEmptyString, long WXUNUSED(style) = 0)
@@ -147,7 +149,7 @@ public:
     void Detach();
 
 #if wxUSE_ACCEL
-    size_t GetAccelCount() const { return m_accelKeyCodes.GetCount(); }
+    size_t GetAccelCount() const { return m_accels.GetCount(); }
     size_t CopyAccels(wxAcceleratorEntry *accels) const;
 #endif // wxUSE_ACCEL
 
@@ -186,8 +188,8 @@ private:
     void*             m_clientData;
 
 #if wxUSE_ACCEL
-    // the accelerators data
-    wxArrayInt        m_accelKeyCodes, m_accelFlags, m_accelIds;
+    // the accelerators for our menu items
+    wxAcceleratorArray m_accels;
 #endif // wxUSE_ACCEL
 };
 
index 28e8e1c9db31f89a0a125f1b31c31dc20f1436e9..aa26ee21582fd6cde6809a4623d197c5c062cca2 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
-#include "wx/setup.h"
-
-// an exception to the general rule that a normal header doesn't include other
-// headers - only because ownerdrw.h is not always included and I don't want
-// to write #ifdef's everywhere...
 #if wxUSE_OWNER_DRAWN
-    #include  "wx/ownerdrw.h"
+    #include  "wx/ownerdrw.h"   // base class
 #endif
 
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-// id for a separator line in the menu (invalid for normal item)
-#define   ID_SEPARATOR    (-1)
-
 // ----------------------------------------------------------------------------
 // wxMenuItem: an item in the menu, optionally implements owner-drawn behaviour
 // ----------------------------------------------------------------------------
-class WXDLLEXPORT wxMenuItem: public wxObject
+
+class WXDLLEXPORT wxMenuItem : public wxMenuItemBase
 #if wxUSE_OWNER_DRAWN
-                            , public wxOwnerDrawn
+                             , public wxOwnerDrawn
 #endif
 {
-DECLARE_DYNAMIC_CLASS(wxMenuItem)
-
 public:
-  // ctor & dtor
-  wxMenuItem(wxMenu *pParentMenu = NULL, int id = ID_SEPARATOR,
-             const wxString& strName = "", const wxString& wxHelp = "",
-             bool bCheckable = FALSE, wxMenu *pSubMenu = NULL);
-  virtual ~wxMenuItem();
-
-  // accessors (some more are inherited from wxOwnerDrawn or are below)
-  bool              IsSeparator() const { return m_idItem == ID_SEPARATOR;  }
-  bool              IsEnabled()   const { return m_bEnabled;                }
-  bool              IsChecked()   const { return m_bChecked;                }
-  bool              IsSubMenu()   const { return GetSubMenu() != NULL;      }
-
-  int               GetId()       const { return m_idItem;    }
-  const wxString&   GetHelp()     const { return m_strHelp;   }
-  wxMenu           *GetSubMenu()  const { return m_pSubMenu;  }
-
-  // the id for a popup menu is really its menu handle (as required by
-  // ::AppendMenu() API)
-  int               GetRealId()   const;
-
-  // operations
-  void SetName(const wxString& strName);
-  void SetHelp(const wxString& strHelp) { m_strHelp = strHelp; }
-
-  void Enable(bool bDoEnable = TRUE);
-  void Check(bool bDoCheck = TRUE);
-
-  void DeleteSubMenu();
+    // ctor & dtor
+    wxMenuItem(wxMenu *parentMenu = (wxMenu *)NULL,
+               int id = wxID_SEPARATOR,
+               const wxString& name = wxEmptyString,
+               const wxString& help = wxEmptyString,
+               bool isCheckable = FALSE,
+               wxMenu *subMenu = (wxMenu *)NULL);
+    virtual ~wxMenuItem();
+
+    // override base class virtuals
+    virtual void SetText(const wxString& strName);
+    virtual void SetCheckable(bool checkable);
+
+    virtual void Enable(bool bDoEnable = TRUE);
+    virtual void Check(bool bDoCheck = TRUE);
+
+    // unfortunately needed to resolve ambiguity between
+    // wxMenuItemBase::IsCheckable() and wxOwnerDrawn::IsCheckable()
+    bool IsCheckable() const { return wxMenuItemBase::IsCheckable(); }
+
+    // the id for a popup menu is really its menu handle (as required by
+    // ::AppendMenu() API), so this function will return either the id or the
+    // menu handle depending on what we're
+    int GetRealId() const;
+
+    // delete the submenu
+    void DeleteSubMenu();
 
 private:
-  int         m_idItem;         // numeric id of the item
-  wxString    m_strHelp;        // associated help string
-  wxMenu     *m_pSubMenu,       // may be NULL
-             *m_pParentMenu;    // menu this item is contained in
-  bool        m_bEnabled,       // enabled or greyed?
-              m_bChecked;       // checked? (only if checkable)
-
-#if wxUSE_OWNER_DRAWN
-  // wxOwnerDrawn base class already has these variables - nothing to do
-
-#else   //!owner drawn
-  bool        m_bCheckable;     // can be checked?
-  wxString    m_strName;        // name or label of the item
-
-public:
-  const wxString&   GetName()     const { return m_strName;    }
-  bool              IsCheckable() const { return m_bCheckable; }
-#endif  //owner drawn
+    DECLARE_DYNAMIC_CLASS(wxMenuItem)
 };
 
 #endif  //_MENUITEM_H
index e92483cc61ac4274642b1d1dc8aa7cd5dbac1173..3008d453a8c90b656715aa6df2101ff0a655fab0 100644 (file)
 #ifndef   _OWNERDRW_H
 #define   _OWNERDRW_H
 
+#include "wx/setup.h"
+
+#if wxUSE_OWNER_DRAWN
+
 #ifdef    __GNUG__
-#pragma interface "ownerdrw.h"
+    #pragma interface "ownerdrw.h"
 #endif
 
-#include <stddef.h>
-
 // ----------------------------------------------------------------------------
 // wxOwnerDrawn - a mix-in base class, derive from it to implement owner-drawn
 //                behaviour
 // also supports 3 bitmaps: either a checked/unchecked bitmap for a checkable
 // element or one unchangeable bitmap otherwise.
 // ----------------------------------------------------------------------------
+
 class WXDLLEXPORT wxOwnerDrawn
 {
 public:
   // ctor & dtor
-  wxOwnerDrawn(const wxString& str = "",
+  wxOwnerDrawn(const wxString& str = wxEmptyString,
                bool bCheckable = FALSE,
                bool bMenuItem = FALSE); // FIXME kludge for colors
   virtual ~wxOwnerDrawn() { }
@@ -78,17 +81,18 @@ public:
   static int GetDefaultMarginWidth() { return (int) ms_nDefaultMarginWidth; }
 
   // accessors
-  void            SetName(const wxString& strName)  { m_strName = strName; }
-  const wxString& GetName()       const             { return m_strName;    }
-  bool            IsCheckable()   const             { return m_bCheckable; }
+  void SetName(const wxString& strName)  { m_strName = strName; }
+  const wxString& GetName() const { return m_strName;    }
+  void SetCheckable(bool checkable) { m_bCheckable = checkable; }
+  bool IsCheckable() const { return m_bCheckable; }
 
   // this function might seem strange, but if it returns FALSE it means that
   // no non-standard attribute are set, so there is no need for this control
   // to be owner-drawn. Moreover, you can force owner-drawn to FALSE if you
   // want to change, say, the color for the item but only if it is owner-drawn
   // (see wxMenuItem::wxMenuItem for example)
-  bool     IsOwnerDrawn()  const             { return m_bOwnerDrawn;   }
-  void     ResetOwnerDrawn()                 { m_bOwnerDrawn = FALSE;  }
+  bool IsOwnerDrawn() const { return m_bOwnerDrawn;   }
+  void ResetOwnerDrawn() { m_bOwnerDrawn = FALSE;  }
 
 public:
   // constants used in OnDrawItem
@@ -125,14 +129,16 @@ private:
             m_bOwnerDrawn;  // true if something is non standard
 
   wxFont    m_font;         // font to use for drawing
-  wxColour   m_colText,      // color ----"---"---"----
+  wxColour  m_colText,      // color ----"---"---"----
             m_colBack;      // background color
   wxBitmap  m_bmpChecked,   // bitmap to put near the item
             m_bmpUnchecked; // (checked is used also for 'uncheckable' items)
 
-  size_t      m_nHeight,      // font height
+  size_t    m_nHeight,      // font height
             m_nMarginWidth; // space occupied by bitmap to the left of the item
 };
 
+#endif // wxUSE_OWNER_DRAWN
+
 #endif
   // _OWNERDRW_H
index 9e964e7a3dbce39918875ea6c4acc536da682a57..35b2496ab908b95cfe349f13667f42c45e9c54c2 100644 (file)
@@ -221,12 +221,17 @@ WXDLLEXPORT wxChar* wxGetUserHome(const wxString& user = wxEmptyString);
 #if wxUSE_GUI // GUI only things from now on
 
 // ----------------------------------------------------------------------------
-// Strip out any menu codes
+// Menu accelerators related things
 // ----------------------------------------------------------------------------
 
 WXDLLEXPORT wxChar* wxStripMenuCodes(wxChar *in, wxChar *out = (wxChar *) NULL);
 WXDLLEXPORT wxString wxStripMenuCodes(const wxString& str);
 
+#if wxUSE_ACCEL
+class WXDLLEXPORT wxAcceleratorEntry;
+WXDLLEXPORT wxAcceleratorEntry *wxGetAccelFromString(const wxString& label);
+#endif // wxUSE_ACCEL
+
 // ----------------------------------------------------------------------------
 // Window search
 // ----------------------------------------------------------------------------
index 1fcc2b7346842ebc35b522901631e4002d2a5620..2491395090c8759d889366b53433aee68fe3dbdc 100644 (file)
@@ -32,6 +32,8 @@
     #include "wx/defs.h"
     #include "wx/string.h"
     #include "wx/utils.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
 
     #if wxUSE_GUI
         #include "wx/window.h"
         #include "wx/frame.h"
         #include "wx/msgdlg.h"
         #include "wx/textdlg.h"
+        #if wxUSE_ACCEL
+            #include "wx/menuitem.h"
+            #include "wx/accel.h"
+        #endif // wxUSE_ACCEL
     #endif // wxUSE_GUI
 #endif // WX_PRECOMP
 
@@ -392,7 +398,7 @@ wxString wxNow()
 #if wxUSE_GUI
 
 // ----------------------------------------------------------------------------
-// Strip out any menu codes
+// Menu accelerators related functions
 // ----------------------------------------------------------------------------
 
 wxChar *wxStripMenuCodes (wxChar *in, wxChar *out)
@@ -439,6 +445,91 @@ wxString wxStripMenuCodes(const wxString& str)
     return str1;
 }
 
+#if wxUSE_ACCEL
+
+// return wxAcceleratorEntry for the given menu string or NULL if none
+// specified
+wxAcceleratorEntry *wxGetAccelFromString(const wxString& label)
+{
+    // check for accelerators: they are given after '\t'
+    int posTab = label.Find(wxT('\t'));
+    if ( posTab != wxNOT_FOUND ) {
+        // parse the accelerator string
+        int keyCode = 0;
+        int accelFlags = wxACCEL_NORMAL;
+        wxString current;
+        for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
+            if ( (label[n] == '+') || (label[n] == '-') ) {
+                if ( current == _("ctrl") )
+                    accelFlags |= wxACCEL_CTRL;
+                else if ( current == _("alt") )
+                    accelFlags |= wxACCEL_ALT;
+                else if ( current == _("shift") )
+                    accelFlags |= wxACCEL_SHIFT;
+                else {
+                    wxLogDebug(wxT("Unknown accel modifier: '%s'"),
+                               current.c_str());
+                }
+
+                current.Empty();
+            }
+            else {
+                current += wxTolower(label[n]);
+            }
+        }
+
+        if ( current.IsEmpty() ) {
+            wxLogDebug(wxT("No accel key found, accel string ignored."));
+        }
+        else {
+            if ( current.Len() == 1 ) {
+                // it's a letter
+                keyCode = wxToupper(current[0U]);
+            }
+            else {
+                // is it a function key?
+                if ( current[0U] == 'f' && isdigit(current[1U]) &&
+                     (current.Len() == 2 ||
+                     (current.Len() == 3 && isdigit(current[2U]))) ) {
+                    int n;
+                    wxSscanf(current.c_str() + 1, wxT("%d"), &n);
+
+                    keyCode = WXK_F1 + n - 1;
+                }
+                else {
+#if 0 // this is not supported by GTK+, apparently
+                    // several special cases
+                    current.MakeUpper();
+                    if ( current == wxT("DEL") ) {
+                        keyCode = VK_DELETE;
+                    }
+                    else if ( current == wxT("PGUP") ) {
+                        keyCode = VK_PRIOR;
+                    }
+                    else if ( current == wxT("PGDN") ) {
+                        keyCode = VK_NEXT;
+                    }
+                    else
+#endif // 0
+                    {
+                        wxLogDebug(wxT("Unrecognized accel key '%s', accel "
+                                       "string ignored."), current.c_str());
+                    }
+                }
+            }
+        }
+
+        if ( keyCode ) {
+            // we do have something
+            return new wxAcceleratorEntry(accelFlags, keyCode);
+        }
+    }
+
+    return NULL;
+}
+
+#endif // wxUSE_ACCEL
+
 // ----------------------------------------------------------------------------
 // Window search functions
 // ----------------------------------------------------------------------------
index fbd0ec5b86f7cee4c9b943c7449ef3455c7cc298..fdd1f25e8f8b234cee7562f72024c90509b32ecb 100644 (file)
@@ -628,7 +628,7 @@ gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigur
     if (source->m_dragContext->action == GDK_ACTION_COPY) action = wxDragCopy;
     if (source->m_dragContext->action == GDK_ACTION_MOVE) action = wxDragMove;
 
-    source->GiveFeedback( action, FALSE );
+    source->GiveFeedback( action );
 
     return 0;
 }
index 35a6a05cd034939ef8e8e856b123b00dff525c5e..de0b18636ff5872b24400b996947fbe791565419 100644 (file)
 #include "wx/intl.h"
 #include "wx/app.h"
 
+#if wxUSE_ACCEL
+    #include "wx/accel.h"
+#endif // wxUSE_ACCEL
+
 #include "gdk/gdk.h"
 #include "gtk/gtk.h"
 
@@ -85,7 +89,7 @@ wxMenuBar::wxMenuBar()
         wxFAIL_MSG( wxT("wxMenuBar creation failed") );
         return;
     }
-    
+
     m_menus.DeleteContents( TRUE );
 
     /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
@@ -113,7 +117,7 @@ static void wxMenubarUnsetInvokingWindow( wxMenu *menu, wxWindow *win )
 
 #if (GTK_MINOR_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native hot keys  */
@@ -136,7 +140,7 @@ static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 
 #if (GTK_MINOR_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native hot keys  */
@@ -158,7 +162,7 @@ void wxMenuBar::SetInvokingWindow( wxWindow *win )
     m_invokingWindow = win;
 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native key accelerators indicated by underscroes */
@@ -179,7 +183,7 @@ void wxMenuBar::UnsetInvokingWindow( wxWindow *win )
     m_invokingWindow = (wxWindow*) NULL;
 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native key accelerators indicated by underscroes */
@@ -257,7 +261,7 @@ void wxMenuBar::Append( wxMenu *menu, const wxString &title )
     {
        // contrary to the common sense, we must throw out _all_ underscores,
        // (i.e. "Hello__World" => "HelloWorld" and not "Hello_World" as we
-       // might naively think). IMHO it's a bug in GTK+ (VZ) 
+       // might naively think). IMHO it's a bug in GTK+ (VZ)
        while (*pc == wxT('_'))
            pc++;
        tmp << *pc;
@@ -488,15 +492,17 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
 
     if (item->IsCheckable())
     {
-        if (item->GetCheckedFlag() == item->IsChecked())
+        bool isReallyChecked = item->IsChecked();
+        if ( item->wxMenuItemBase::IsChecked() == isReallyChecked )
         {
             /* the menu item has been checked by calling wxMenuItem->Check() */
             return;
         }
         else
         {
-            /* the user pressed on the menu item -> report */
-            item->SetCheckedFlag(item->IsChecked());  /* make consistent again */
+            /* the user pressed on the menu item -> report and make consistent
+             * again */
+            item->wxMenuItemBase::Check(isReallyChecked);
         }
     }
 
@@ -573,16 +579,37 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu )
 // wxMenuItem
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxMenuItemBase)
+
+wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
+                                int id,
+                                const wxString& name,
+                                const wxString& help,
+                                bool isCheckable,
+                                wxMenu *subMenu)
+{
+    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+}
 
-wxMenuItem::wxMenuItem()
+wxMenuItem::wxMenuItem(wxMenu *parentMenu,
+                       int id,
+                       const wxString& text,
+                       const wxString& help,
+                       bool isCheckable,
+                       wxMenu *subMenu)
 {
-    m_id = ID_SEPARATOR;
-    m_isCheckMenu = FALSE;
+    m_id = id;
+    m_isCheckable = isCheckable;
     m_isChecked = FALSE;
     m_isEnabled = TRUE;
-    m_subMenu = (wxMenu *) NULL;
+    m_subMenu = subMenu;
+    m_parentMenu = parentMenu;
+    m_help = help;
+
     m_menuItem = (GtkWidget *) NULL;
+
+    // call it after initializing m_menuItem to NULL
+    DoSetText(text);
 }
 
 wxMenuItem::~wxMenuItem()
@@ -591,10 +618,10 @@ wxMenuItem::~wxMenuItem()
 }
 
 // it's valid for this function to be called even if m_menuItem == NULL
-void wxMenuItem::SetName( const wxString& str )
+void wxMenuItem::DoSetText( const wxString& str )
 {
     /* '\t' is the deliminator indicating a hot key */
-    m_text = wxT("");
+    m_text.Empty();
     const wxChar *pc = str;
     for (; (*pc != wxT('\0')) && (*pc != wxT('\t')); pc++ )
     {
@@ -639,9 +666,10 @@ void wxMenuItem::Check( bool check )
 
     wxCHECK_RET( IsCheckable(), wxT("Can't check uncheckable item!") )
 
-    if (check == m_isChecked) return;
+    if (check == m_isChecked)
+        return;
 
-    m_isChecked = check;
+    wxMenuItemBase::Check( check );
     gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check );
 }
 
@@ -650,18 +678,17 @@ void wxMenuItem::Enable( bool enable )
     wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
 
     gtk_widget_set_sensitive( m_menuItem, enable );
-    m_isEnabled = enable;
+    wxMenuItemBase::Enable( enable );
 }
 
 bool wxMenuItem::IsChecked() const
 {
     wxCHECK_MSG( m_menuItem, FALSE, wxT("invalid menu item") );
 
-    wxCHECK( IsCheckable(), FALSE ); // can't get state of uncheckable item!
-
-    bool bIsChecked = ((GtkCheckMenuItem*)m_menuItem)->active != 0;
+    wxCHECK_MSG( IsCheckable(), FALSE,
+                 wxT("can't get state of uncheckable item!") );
 
-    return bIsChecked;
+    return ((GtkCheckMenuItem*)m_menuItem)->active != 0;
 }
 
 //-----------------------------------------------------------------------------
@@ -727,14 +754,14 @@ wxMenu::~wxMenu()
     while (node)
     {
         wxMenuItem *item = (wxMenuItem*)node->Data();
-       wxMenu *submenu = item->GetSubMenu();
-       if (submenu)
-          delete submenu;
+        wxMenu *submenu = item->GetSubMenu();
+        if (submenu)
+           delete submenu;
         node = node->Next();
     }
 
    gtk_widget_destroy( m_menu );
-   
+
    gtk_object_unref( GTK_OBJECT(m_factory) );
 }
 
@@ -751,8 +778,7 @@ const wxString wxMenu::GetTitle() const
 
 void wxMenu::AppendSeparator()
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(ID_SEPARATOR);
+    wxMenuItem *mitem = new wxMenuItem(this, wxID_SEPARATOR);
 
 #if (GTK_MINOR_VERSION > 0)
     GtkItemFactoryEntry entry;
@@ -776,53 +802,65 @@ void wxMenu::AppendSeparator()
     m_items.Append( mitem );
 }
 
-#if (GTK_MINOR_VERSION > 0)
-static char* GetHotKey( const wxString &hotkey, char *hotbuf )
+#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
+static wxString GetHotKey( const wxMenuItem& item )
 {
-    if (hotkey.IsEmpty()) return (char*) NULL;
+    wxString hotkey;
 
-    switch (hotkey[0])
+    // as wxGetAccelFromString() looks for TAB, insert a dummy one here
+    wxString label;
+    label << wxT('\t') << item.GetHotKey();
+    wxAcceleratorEntry *accel = wxGetAccelFromString(label);
+    if ( accel )
     {
-        case wxT('a'):   /* Alt */
-        case wxT('A'):
-        case wxT('m'):   /* Meta */
-        case wxT('M'):
-        {
-            strcpy( hotbuf, "<alt>" );
-            wxString last = hotkey.Right(1);
-            strcat( hotbuf, last.mb_str() );
-            return hotbuf;
-        }
-        case wxT('c'):    /* Ctrl */
-        case wxT('C'):
-        case wxT('s'):    /* Strg, yeah man, I'm German */
-        case wxT('S'):
-        {
-            strcpy( hotbuf, "<control>" );
-            wxString last = hotkey.Right(1);
-            strcat( hotbuf, last.mb_str() );
-            return hotbuf;
-        }
-        case wxT('F'):   /* function keys */
-        {
-            strcpy( hotbuf, hotkey.mb_str() );
-            return hotbuf;
-        }
-        default:
+        int flags = accel->GetFlags();
+        if ( flags & wxACCEL_ALT )
+            hotkey += wxT("<alt>");
+        if ( flags & wxACCEL_CTRL )
+            hotkey += wxT("<control>");
+        if ( flags & wxACCEL_SHIFT )
+            hotkey += wxT("<shift>");
+
+        int code = accel->GetKeyCode();
+        switch ( code )
         {
+            case WXK_F1:
+            case WXK_F2:
+            case WXK_F3:
+            case WXK_F4:
+            case WXK_F5:
+            case WXK_F6:
+            case WXK_F7:
+            case WXK_F8:
+            case WXK_F9:
+            case WXK_F10:
+            case WXK_F11:
+            case WXK_F12:
+                hotkey << wxT('F') << code = WXK_F1 + 1;
+                break;
+
+            // if there are any other keys wxGetAccelFromString() may return,
+            // we should process them here
+
+            default:
+                if ( wxIsalnum(code) )
+                {
+                    hotkey << (wxChar)code;
+
+                    break;
+                }
+
+                wxFAIL_MSG( wxT("unknown keyboard accel") );
         }
     }
-    return (char*) NULL;
+
+    return hotkey;
 }
-#endif
+#endif // wxUSE_ACCEL
 
 void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(id);
-    mitem->SetText(item);
-    mitem->SetHelp(helpStr);
-    mitem->SetCheckable(checkable);
+    wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, checkable);
 
 #if (GTK_MINOR_VERSION > 0)
     /* text has "_" instead of "&" after mitem->SetText() */
@@ -842,8 +880,16 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
     else
         entry.item_type = "<Item>";
 
-    char hotbuf[50];
-    entry.accelerator = GetHotKey( mitem->GetHotKey(), hotbuf );
+#if wxUSE_ACCEL
+    // due to an apparent bug in GTK+, we have to use a static buffer here -
+    // otherwise GTK+ 1.2.2 manages to override the memory we pass to it
+    // somehow! (VZ)
+    static char s_accel[32]; // must be big enough for <control><alt><shift>F12
+    strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
+    entry.accelerator = s_accel;
+#else
+    entry.accelerator = NULL;
+#endif
 
     gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 );  /* what is 2 ? */
 
@@ -886,10 +932,7 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
 
 void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(id);
-    mitem->SetText(item);
-    mitem->SetHelp(helpStr);
+    wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, FALSE, subMenu);
 
 #if (GTK_MINOR_VERSION > 0)
     /* text has "_" instead of "&" after mitem->SetText() */
@@ -938,7 +981,6 @@ void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxStri
     gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
 
     mitem->SetMenuItem(menuItem);
-    mitem->SetSubMenu(subMenu);
 
     m_items.Append( mitem );
 }
@@ -988,8 +1030,8 @@ void wxMenu::Delete( int id )
         wxMenuItem *item = (wxMenuItem*)node->Data();
         if (item->GetId() == id)
         {
-           gtk_widget_destroy( item->GetMenuItem() );
-           m_items.DeleteNode( node );
+            gtk_widget_destroy( item->GetMenuItem() );
+            m_items.DeleteNode( node );
             return;
         }
         node = node->Next();
index fbd0ec5b86f7cee4c9b943c7449ef3455c7cc298..fdd1f25e8f8b234cee7562f72024c90509b32ecb 100644 (file)
@@ -628,7 +628,7 @@ gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigur
     if (source->m_dragContext->action == GDK_ACTION_COPY) action = wxDragCopy;
     if (source->m_dragContext->action == GDK_ACTION_MOVE) action = wxDragMove;
 
-    source->GiveFeedback( action, FALSE );
+    source->GiveFeedback( action );
 
     return 0;
 }
index 35a6a05cd034939ef8e8e856b123b00dff525c5e..de0b18636ff5872b24400b996947fbe791565419 100644 (file)
 #include "wx/intl.h"
 #include "wx/app.h"
 
+#if wxUSE_ACCEL
+    #include "wx/accel.h"
+#endif // wxUSE_ACCEL
+
 #include "gdk/gdk.h"
 #include "gtk/gtk.h"
 
@@ -85,7 +89,7 @@ wxMenuBar::wxMenuBar()
         wxFAIL_MSG( wxT("wxMenuBar creation failed") );
         return;
     }
-    
+
     m_menus.DeleteContents( TRUE );
 
     /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
@@ -113,7 +117,7 @@ static void wxMenubarUnsetInvokingWindow( wxMenu *menu, wxWindow *win )
 
 #if (GTK_MINOR_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native hot keys  */
@@ -136,7 +140,7 @@ static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
 
 #if (GTK_MINOR_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native hot keys  */
@@ -158,7 +162,7 @@ void wxMenuBar::SetInvokingWindow( wxWindow *win )
     m_invokingWindow = win;
 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native key accelerators indicated by underscroes */
@@ -179,7 +183,7 @@ void wxMenuBar::UnsetInvokingWindow( wxWindow *win )
     m_invokingWindow = (wxWindow*) NULL;
 #if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
     wxWindow *top_frame = win;
-    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame)) 
+    while (top_frame->GetParent() && !(top_frame->GetParent()->m_isFrame))
         top_frame = top_frame->GetParent();
 
     /* support for native key accelerators indicated by underscroes */
@@ -257,7 +261,7 @@ void wxMenuBar::Append( wxMenu *menu, const wxString &title )
     {
        // contrary to the common sense, we must throw out _all_ underscores,
        // (i.e. "Hello__World" => "HelloWorld" and not "Hello_World" as we
-       // might naively think). IMHO it's a bug in GTK+ (VZ) 
+       // might naively think). IMHO it's a bug in GTK+ (VZ)
        while (*pc == wxT('_'))
            pc++;
        tmp << *pc;
@@ -488,15 +492,17 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
 
     if (item->IsCheckable())
     {
-        if (item->GetCheckedFlag() == item->IsChecked())
+        bool isReallyChecked = item->IsChecked();
+        if ( item->wxMenuItemBase::IsChecked() == isReallyChecked )
         {
             /* the menu item has been checked by calling wxMenuItem->Check() */
             return;
         }
         else
         {
-            /* the user pressed on the menu item -> report */
-            item->SetCheckedFlag(item->IsChecked());  /* make consistent again */
+            /* the user pressed on the menu item -> report and make consistent
+             * again */
+            item->wxMenuItemBase::Check(isReallyChecked);
         }
     }
 
@@ -573,16 +579,37 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu )
 // wxMenuItem
 //-----------------------------------------------------------------------------
 
-IMPLEMENT_DYNAMIC_CLASS(wxMenuItem,wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxMenuItemBase)
+
+wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
+                                int id,
+                                const wxString& name,
+                                const wxString& help,
+                                bool isCheckable,
+                                wxMenu *subMenu)
+{
+    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+}
 
-wxMenuItem::wxMenuItem()
+wxMenuItem::wxMenuItem(wxMenu *parentMenu,
+                       int id,
+                       const wxString& text,
+                       const wxString& help,
+                       bool isCheckable,
+                       wxMenu *subMenu)
 {
-    m_id = ID_SEPARATOR;
-    m_isCheckMenu = FALSE;
+    m_id = id;
+    m_isCheckable = isCheckable;
     m_isChecked = FALSE;
     m_isEnabled = TRUE;
-    m_subMenu = (wxMenu *) NULL;
+    m_subMenu = subMenu;
+    m_parentMenu = parentMenu;
+    m_help = help;
+
     m_menuItem = (GtkWidget *) NULL;
+
+    // call it after initializing m_menuItem to NULL
+    DoSetText(text);
 }
 
 wxMenuItem::~wxMenuItem()
@@ -591,10 +618,10 @@ wxMenuItem::~wxMenuItem()
 }
 
 // it's valid for this function to be called even if m_menuItem == NULL
-void wxMenuItem::SetName( const wxString& str )
+void wxMenuItem::DoSetText( const wxString& str )
 {
     /* '\t' is the deliminator indicating a hot key */
-    m_text = wxT("");
+    m_text.Empty();
     const wxChar *pc = str;
     for (; (*pc != wxT('\0')) && (*pc != wxT('\t')); pc++ )
     {
@@ -639,9 +666,10 @@ void wxMenuItem::Check( bool check )
 
     wxCHECK_RET( IsCheckable(), wxT("Can't check uncheckable item!") )
 
-    if (check == m_isChecked) return;
+    if (check == m_isChecked)
+        return;
 
-    m_isChecked = check;
+    wxMenuItemBase::Check( check );
     gtk_check_menu_item_set_state( (GtkCheckMenuItem*)m_menuItem, (gint)check );
 }
 
@@ -650,18 +678,17 @@ void wxMenuItem::Enable( bool enable )
     wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
 
     gtk_widget_set_sensitive( m_menuItem, enable );
-    m_isEnabled = enable;
+    wxMenuItemBase::Enable( enable );
 }
 
 bool wxMenuItem::IsChecked() const
 {
     wxCHECK_MSG( m_menuItem, FALSE, wxT("invalid menu item") );
 
-    wxCHECK( IsCheckable(), FALSE ); // can't get state of uncheckable item!
-
-    bool bIsChecked = ((GtkCheckMenuItem*)m_menuItem)->active != 0;
+    wxCHECK_MSG( IsCheckable(), FALSE,
+                 wxT("can't get state of uncheckable item!") );
 
-    return bIsChecked;
+    return ((GtkCheckMenuItem*)m_menuItem)->active != 0;
 }
 
 //-----------------------------------------------------------------------------
@@ -727,14 +754,14 @@ wxMenu::~wxMenu()
     while (node)
     {
         wxMenuItem *item = (wxMenuItem*)node->Data();
-       wxMenu *submenu = item->GetSubMenu();
-       if (submenu)
-          delete submenu;
+        wxMenu *submenu = item->GetSubMenu();
+        if (submenu)
+           delete submenu;
         node = node->Next();
     }
 
    gtk_widget_destroy( m_menu );
-   
+
    gtk_object_unref( GTK_OBJECT(m_factory) );
 }
 
@@ -751,8 +778,7 @@ const wxString wxMenu::GetTitle() const
 
 void wxMenu::AppendSeparator()
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(ID_SEPARATOR);
+    wxMenuItem *mitem = new wxMenuItem(this, wxID_SEPARATOR);
 
 #if (GTK_MINOR_VERSION > 0)
     GtkItemFactoryEntry entry;
@@ -776,53 +802,65 @@ void wxMenu::AppendSeparator()
     m_items.Append( mitem );
 }
 
-#if (GTK_MINOR_VERSION > 0)
-static char* GetHotKey( const wxString &hotkey, char *hotbuf )
+#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
+static wxString GetHotKey( const wxMenuItem& item )
 {
-    if (hotkey.IsEmpty()) return (char*) NULL;
+    wxString hotkey;
 
-    switch (hotkey[0])
+    // as wxGetAccelFromString() looks for TAB, insert a dummy one here
+    wxString label;
+    label << wxT('\t') << item.GetHotKey();
+    wxAcceleratorEntry *accel = wxGetAccelFromString(label);
+    if ( accel )
     {
-        case wxT('a'):   /* Alt */
-        case wxT('A'):
-        case wxT('m'):   /* Meta */
-        case wxT('M'):
-        {
-            strcpy( hotbuf, "<alt>" );
-            wxString last = hotkey.Right(1);
-            strcat( hotbuf, last.mb_str() );
-            return hotbuf;
-        }
-        case wxT('c'):    /* Ctrl */
-        case wxT('C'):
-        case wxT('s'):    /* Strg, yeah man, I'm German */
-        case wxT('S'):
-        {
-            strcpy( hotbuf, "<control>" );
-            wxString last = hotkey.Right(1);
-            strcat( hotbuf, last.mb_str() );
-            return hotbuf;
-        }
-        case wxT('F'):   /* function keys */
-        {
-            strcpy( hotbuf, hotkey.mb_str() );
-            return hotbuf;
-        }
-        default:
+        int flags = accel->GetFlags();
+        if ( flags & wxACCEL_ALT )
+            hotkey += wxT("<alt>");
+        if ( flags & wxACCEL_CTRL )
+            hotkey += wxT("<control>");
+        if ( flags & wxACCEL_SHIFT )
+            hotkey += wxT("<shift>");
+
+        int code = accel->GetKeyCode();
+        switch ( code )
         {
+            case WXK_F1:
+            case WXK_F2:
+            case WXK_F3:
+            case WXK_F4:
+            case WXK_F5:
+            case WXK_F6:
+            case WXK_F7:
+            case WXK_F8:
+            case WXK_F9:
+            case WXK_F10:
+            case WXK_F11:
+            case WXK_F12:
+                hotkey << wxT('F') << code = WXK_F1 + 1;
+                break;
+
+            // if there are any other keys wxGetAccelFromString() may return,
+            // we should process them here
+
+            default:
+                if ( wxIsalnum(code) )
+                {
+                    hotkey << (wxChar)code;
+
+                    break;
+                }
+
+                wxFAIL_MSG( wxT("unknown keyboard accel") );
         }
     }
-    return (char*) NULL;
+
+    return hotkey;
 }
-#endif
+#endif // wxUSE_ACCEL
 
 void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(id);
-    mitem->SetText(item);
-    mitem->SetHelp(helpStr);
-    mitem->SetCheckable(checkable);
+    wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, checkable);
 
 #if (GTK_MINOR_VERSION > 0)
     /* text has "_" instead of "&" after mitem->SetText() */
@@ -842,8 +880,16 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
     else
         entry.item_type = "<Item>";
 
-    char hotbuf[50];
-    entry.accelerator = GetHotKey( mitem->GetHotKey(), hotbuf );
+#if wxUSE_ACCEL
+    // due to an apparent bug in GTK+, we have to use a static buffer here -
+    // otherwise GTK+ 1.2.2 manages to override the memory we pass to it
+    // somehow! (VZ)
+    static char s_accel[32]; // must be big enough for <control><alt><shift>F12
+    strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
+    entry.accelerator = s_accel;
+#else
+    entry.accelerator = NULL;
+#endif
 
     gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 );  /* what is 2 ? */
 
@@ -886,10 +932,7 @@ void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool
 
 void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
 {
-    wxMenuItem *mitem = new wxMenuItem();
-    mitem->SetId(id);
-    mitem->SetText(item);
-    mitem->SetHelp(helpStr);
+    wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, FALSE, subMenu);
 
 #if (GTK_MINOR_VERSION > 0)
     /* text has "_" instead of "&" after mitem->SetText() */
@@ -938,7 +981,6 @@ void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxStri
     gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
 
     mitem->SetMenuItem(menuItem);
-    mitem->SetSubMenu(subMenu);
 
     m_items.Append( mitem );
 }
@@ -988,8 +1030,8 @@ void wxMenu::Delete( int id )
         wxMenuItem *item = (wxMenuItem*)node->Data();
         if (item->GetId() == id)
         {
-           gtk_widget_destroy( item->GetMenuItem() );
-           m_items.DeleteNode( node );
+            gtk_widget_destroy( item->GetMenuItem() );
+            m_items.DeleteNode( node );
             return;
         }
         node = node->Next();
index de144548e1ce0509af70d6a96268d6fe3c528070..1d5ff1235070e7acdbd76320b90adba01c943562 100644 (file)
@@ -141,78 +141,9 @@ void wxMenu::Append(wxMenuItem *pItem)
     wxCHECK_RET( pItem != NULL, wxT("can't append NULL item to the menu") );
 
 #if wxUSE_ACCEL
-    // check for accelerators: they are given after '\t'
-    wxString label = pItem->GetName();
-    int posTab = label.Find(wxT('\t'));
-    if ( posTab != wxNOT_FOUND ) {
-        // parse the accelerator string
-        int keyCode = 0;
-        int accelFlags = wxACCEL_NORMAL;
-        wxString current;
-        for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) {
-            if ( (label[n] == '+') || (label[n] == '-') ) {
-                if ( current == _("ctrl") )
-                    accelFlags |= wxACCEL_CTRL;
-                else if ( current == _("alt") )
-                    accelFlags |= wxACCEL_ALT;
-                else if ( current == _("shift") )
-                    accelFlags |= wxACCEL_SHIFT;
-                else {
-                    wxLogDebug(wxT("Unknown accel modifier: '%s'"),
-                               current.c_str());
-                }
-
-                current.Empty();
-            }
-            else {
-                current += wxTolower(label[n]);
-            }
-        }
-
-        if ( current.IsEmpty() ) {
-            wxLogDebug(wxT("No accel key found, accel string ignored."));
-        }
-        else {
-            if ( current.Len() == 1 ) {
-                // it's a letter
-                keyCode = wxToupper(current[0U]);
-            }
-            else {
-                // is it a function key?
-                if ( current[0U] == 'f' && isdigit(current[1U]) &&
-                     (current.Len() == 2 ||
-                     (current.Len() == 3 && isdigit(current[2U]))) ) {
-                    int n;
-                    wxSscanf(current.c_str() + 1, wxT("%d"), &n);
-
-                    keyCode = VK_F1 + n - 1;
-                }
-                else {
-                    // several special cases
-                    current.MakeUpper();
-                    if ( current == wxT("DEL") ) {
-                        keyCode = VK_DELETE;
-                    }
-                    else if ( current == wxT("PGUP") ) {
-                        keyCode = VK_PRIOR;
-                    }
-                    else if ( current == wxT("PGDN") ) {
-                        keyCode = VK_NEXT;
-                    }
-                    else {
-                        wxLogDebug(wxT("Unrecognized accel key '%s', accel "
-                                       "string ignored."), current.c_str());
-                    }
-                }
-            }
-        }
-
-        if ( keyCode ) {
-            // do add an entry
-            m_accelKeyCodes.Add(keyCode);
-            m_accelFlags.Add(accelFlags);
-            m_accelIds.Add(pItem->GetId());
-        }
+    wxAcceleratorEntry *accel = wxGetAccelFromMenuLabel(pItem->GetText());
+    if ( accel ) {
+        m_accels.Add(accel);
     }
 #endif // wxUSE_ACCEL
 
@@ -262,13 +193,7 @@ void wxMenu::Append(wxMenuItem *pItem)
         // menu is just a normal string (passed in data parameter)
         flags |= MF_STRING;
 
-// Don't know what the correct cast should be, but it doesn't
-// compile in BC++/16-bit without this cast.
-#if !defined(__WIN32__)
-        pData = (char*) (const char*) label;
-#else
-        pData = label;
-#endif
+        pData = (char*)pItem->GetText().c_str();
     }
 
     if ( !::AppendMenu(GetHmenu(), flags, id, pData) )
@@ -373,7 +298,7 @@ size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
     size_t count = GetAccelCount();
     for ( size_t n = 0; n < count; n++ )
     {
-        (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]);
+        *accels++ = *m_accels[n];
     }
 
     return count;
@@ -422,7 +347,7 @@ void wxMenu::SetLabel(int id, const wxString& label)
     wxMenuItem *item = FindItemForId(id) ;
     wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
 
-    item->SetName(label);
+    item->SetText(label);
 }
 
 wxString wxMenu::GetLabel(int id) const
@@ -430,7 +355,7 @@ wxString wxMenu::GetLabel(int id) const
     wxString label;
     wxMenuItem *pItem = FindItemForId(id) ;
     if (pItem)
-        label = pItem->GetName() ;
+        label = pItem->GetText() ;
     else
         wxFAIL_MSG(wxT("wxMenu::GetLabel: item doesn't exist"));
 
@@ -592,7 +517,7 @@ int wxMenu::FindItem (const wxString& itemString) const
         }
         else if ( !item->IsSeparator() )
         {
-            wxString label = wxStripMenuCodes(item->GetName());
+            wxString label = wxStripMenuCodes(item->GetText());
             if ( itemLabel == label )
                 return item->GetId();
         }
@@ -812,7 +737,7 @@ void wxMenuBar::SetLabel(int id, const wxString& label)
 
     wxCHECK_RET( item, wxT("wxMenuBar::SetLabel(): no such item") );
 
-    item->SetName(label);
+    item->SetText(label);
 }
 
 wxString wxMenuBar::GetLabel(int id) const
@@ -820,9 +745,10 @@ wxString wxMenuBar::GetLabel(int id) const
     wxMenu *itemMenu = NULL;
     wxMenuItem *item = FindItemForId(id, &itemMenu) ;
 
-    wxCHECK_MSG( item, wxT(""), wxT("wxMenuBar::GetLabel(): no such item") );
+    wxCHECK_MSG( item, wxEmptyString,
+                 wxT("wxMenuBar::GetLabel(): no such item") );
 
-    return item->GetName();
+    return item->GetText();
 }
 
 void wxMenuBar::SetHelpString (int id, const wxString& helpString)
index a4f038f875905ce1fd23b507eb4a611b0b31c86b..09c4986f1538b66c267869c7f4d8123f34aa1895 100644 (file)
     #include "wx/string.h"
 #endif
 
-#include "wx/ownerdrw.h"
 #include "wx/menuitem.h"
 #include "wx/log.h"
 
 #include "wx/msw/private.h"
 
 // ---------------------------------------------------------------------------
-// convenience macro
+// macro
 // ---------------------------------------------------------------------------
 
+// hide the ugly cast
 #define GetHMenuOf(menu)    ((HMENU)menu->GetHMenu())
 
+// conditional compilation
+#if wxUSE_OWNER_DRAWN
+    #define OWNER_DRAWN_ONLY( code ) if ( IsOwnerDrawn() ) code
+#else // !wxUSE_OWNER_DRAWN
+    #define OWNER_DRAWN_ONLY( code )
+#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
+
 // ============================================================================
 // implementation
 // ============================================================================
 // ----------------------------------------------------------------------------
 
 #if     !defined(USE_SHARED_LIBRARY) || !USE_SHARED_LIBRARY
-#if wxUSE_OWNER_DRAWN
-  IMPLEMENT_DYNAMIC_CLASS2(wxMenuItem, wxObject, wxOwnerDrawn)
-#else   //!USE_OWNER_DRAWN
-  IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
-#endif  //USE_OWNER_DRAWN
-
+    #if wxUSE_OWNER_DRAWN
+        IMPLEMENT_DYNAMIC_CLASS2(wxMenuItem, wxMenuItemBase, wxOwnerDrawn)
+    #else   //!USE_OWNER_DRAWN
+        IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxMenuItemBase)
+    #endif  //USE_OWNER_DRAWN
 #endif  //USE_SHARED_LIBRARY
 
 // ----------------------------------------------------------------------------
 // ctor & dtor
 // -----------
 
-wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
-                       const wxString& strName, const wxString& strHelp,
+wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
+                       int id,
+                       const wxString& text,
+                       const wxString& strHelp,
                        bool bCheckable,
                        wxMenu *pSubMenu) :
 #if wxUSE_OWNER_DRAWN
-                        wxOwnerDrawn(strName, bCheckable),
-#else   //no owner drawn support
-                        m_bCheckable(bCheckable),
-                        m_strName(strName),
-#endif  //owner drawn
-                        m_strHelp(strHelp)
+                        wxOwnerDrawn(text, bCheckable)
+#endif // owner drawn
 {
     wxASSERT_MSG( pParentMenu != NULL, wxT("a menu item should have a parent") );
 
@@ -100,13 +104,16 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu, int id,
     ResetOwnerDrawn();
 
     #undef  SYS_COLOR
-#endif
-
-    m_pParentMenu = pParentMenu;
-    m_pSubMenu    = pSubMenu;
-    m_bEnabled    = TRUE;
-    m_bChecked    = FALSE;
-    m_idItem      = id;
+#endif // wxUSE_OWNER_DRAWN
+
+    m_parentMenu  = pParentMenu;
+    m_subMenu     = pSubMenu;
+    m_isEnabled   = TRUE;
+    m_isChecked   = FALSE;
+    m_id          = id;
+    m_text        = text;
+    m_isCheckable = bCheckable;
+    m_help        = strHelp;
 }
 
 wxMenuItem::~wxMenuItem()
@@ -119,15 +126,15 @@ wxMenuItem::~wxMenuItem()
 // return the id for calling Win32 API functions
 int wxMenuItem::GetRealId() const
 {
-    return m_pSubMenu ? (int)m_pSubMenu->GetHMenu() : GetId();
+    return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
 }
 
 // delete the sub menu
 // -------------------
 void wxMenuItem::DeleteSubMenu()
 {
-    delete m_pSubMenu;
-    m_pSubMenu = NULL;
+    delete m_subMenu;
+    m_subMenu = NULL;
 }
 
 // change item state
@@ -135,8 +142,8 @@ void wxMenuItem::DeleteSubMenu()
 
 void wxMenuItem::Enable(bool bDoEnable)
 {
-    if ( m_bEnabled != bDoEnable ) {
-        long rc = EnableMenuItem(GetHMenuOf(m_pParentMenu),
+    if ( m_isEnabled != bDoEnable ) {
+        long rc = EnableMenuItem(GetHMenuOf(m_parentMenu),
                                  GetRealId(),
                                  MF_BYCOMMAND |
                                  (bDoEnable ? MF_ENABLED : MF_GRAYED));
@@ -145,16 +152,16 @@ void wxMenuItem::Enable(bool bDoEnable)
             wxLogLastError("EnableMenuItem");
         }
 
-        m_bEnabled = bDoEnable;
+        wxMenuItemBase::Enable(m_isEnabled);
     }
 }
 
 void wxMenuItem::Check(bool bDoCheck)
 {
-    wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
+    wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
 
-    if ( m_bChecked != bDoCheck ) {
-        long rc = CheckMenuItem(GetHMenuOf(m_pParentMenu),
+    if ( m_isChecked != bDoCheck ) {
+        long rc = CheckMenuItem(GetHMenuOf(m_parentMenu),
                                 GetId(),
                                 MF_BYCOMMAND |
                                 (bDoCheck ? MF_CHECKED : MF_UNCHECKED));
@@ -163,19 +170,20 @@ void wxMenuItem::Check(bool bDoCheck)
             wxLogLastError("CheckMenuItem");
         }
 
-        m_bChecked = bDoCheck;
+        wxMenuItemBase::Check(m_isChecked);
     }
 }
 
-void wxMenuItem::SetName(const wxString& strName)
+void wxMenuItem::SetText(const wxString& text)
 {
     // don't do anything if label didn't change
-    if ( m_strName == strName )
+    if ( m_text == text )
         return;
 
-    m_strName = strName;
+    wxMenuItemBase::SetText(text);
+    OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
 
-    HMENU hMenu = GetHMenuOf(m_pParentMenu);
+    HMENU hMenu = GetHMenuOf(m_parentMenu);
 
     UINT id = GetRealId();
     UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
@@ -193,6 +201,7 @@ void wxMenuItem::SetName(const wxString& strName)
         }
 
         LPCTSTR data;
+
 #if wxUSE_OWNER_DRAWN
         if ( IsOwnerDrawn() )
         {
@@ -203,13 +212,7 @@ void wxMenuItem::SetName(const wxString& strName)
 #endif  //owner drawn
         {
             flagsOld |= MF_STRING;
-// Don't know what the correct cast should be, but it doesn't
-// compile in BC++/16-bit without this cast.
-#if !defined(__WIN32__)
-            data = (char*) (const char*) strName;
-#else
-            data = strName;
-#endif
+            data = (char*) text.c_str();
         }
 
         if ( ::ModifyMenu(hMenu, id,
@@ -221,3 +224,22 @@ void wxMenuItem::SetName(const wxString& strName)
     }
 }
 
+void wxMenuItem::SetCheckable(bool checkable)
+{
+    wxMenuItemBase::SetCheckable(checkable);
+    OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) );
+}
+
+// ----------------------------------------------------------------------------
+// wxMenuItemBase
+// ----------------------------------------------------------------------------
+
+wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
+                                int id,
+                                const wxString& name,
+                                const wxString& help,
+                                bool isCheckable,
+                                wxMenu *subMenu)
+{
+    return new wxMenuItem(parentMenu, id, name, help, isCheckable, subMenu);
+}