/***************************************************************
 * Name:      cbkeybinder.h
 * Purpose:   Code::Blocks plugin
 * Author:    Pecan Heber
 * Copyright: (c) Pecan Heber
 * License:   GPL
 **************************************************************/
// RCS-ID:      $Id: cbkeybinder.h 13514 2024-04-29 18:47:20Z pecanh $
//cause a commit 2020/04/7
#ifndef CBKEYBINDER_H
#define CBKEYBINDER_H

#include <wx/string.h>
#include <wx/listbook.h>
#include <wx/textfile.h>

#include "cbplugin.h" // the base class we 're inheriting
#include "configurationpanel.h"
#include "clKeyboardManager.h"
#include "keybinder.h"
#include "cbKeyConfigPanel.h"

// Modified Keybinder for CodeBlocks KeyBnder v2.0

// --Version-Rlease-Feature-Fix-------
#define VERSION "2.0.20 24/04/29"
// -----------------------------------
class wxKeyConfigPanel;
class wxWindow;
class wxEvent;
class wxMenuBar;
class wxLogWindow;
class cbKeyBinder;
// ----------------------------------------------------------------------------
//  cbKeyBinder class (the plugin)
// ----------------------------------------------------------------------------
class cbKeyBinder : public cbPlugin
{
	public:
		cbKeyBinder();
		~cbKeyBinder();

		int GetConfigurationGroup() const { return cgEditor; }
        cbConfigurationPanel* GetConfigurationPanel(wxWindow* parent);

		void BuildMenu(wxMenuBar* menuBar);
		void BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = 0);
		bool BuildToolBar(wxToolBar* toolBar);
		void OnAttach();                    // fires when the plugin is attached to the application
		void OnRelease(bool appShutDown);   // fires when the plugin is released from the application
        void OnKeyBinderRefreshRequested(wxCommandEvent& event);

      #ifdef LOGGING
        // allocate wxLogWindow when debugging
        wxLogWindow* m_pMyLog;
      #endif

        //memorized menubar from BuildMenu(...)
        wxMenuBar* m_pMenuBar;

        // Users Key file name eg. %HOME%\cbKeybinder.ini
        wxString m_OldKeyBinderFullFilePath;
        wxString m_UserPersonality;

        int RemoveKeyBindingsFor(const wxString& strKeyCode, wxKeyProfile* pkp);

    protected:

    private:
        void OnAppStartupDone(CodeBlocksEvent& event);
        void OnAppStartShutdown(CodeBlocksEvent& event);

        wxString GetUserPersonality() {return m_UserPersonality; }
        bool     CreateKeyBindDefaultFile(bool refresh);
        bool     OnSaveKbOldFormatCfgFile(wxKeyProfileArray* pKeyProfileArray, wxString oldFmtMnuScanFilePath, bool backitup);
        int      ConvertMenuScanToKeyMnuAcceratorsConf(wxString keybinderFile, wxString acceratorFile);
        int      ConvertOldKeybinderIniToAcceratorsConf(wxString keybinderFile, wxString acceleratorFile);
        bool     MergeAcceleratorTable(wxTextFile& textOutFile);
        int      RemoveCopyPasteBindings(wxKeyProfile* pkp);
        wxString FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName);
        wxString GetPluginVersion();

        wxString      GetStringsFromArray(const wxArrayString& array, const wxString& separator, bool SeparatorAtEnd);
        wxArrayString GetArrayFromStrings(const wxString& text, const wxString& separator, bool trimSpaces);
        int           FindLineInFileContaining(wxTextFile& txtFile, wxString& pattern);

        wxString GetTempOldFmtMnuScanFilename()
        {
            wxFileName fnTempOldFmtMnuScan(wxStandardPaths::Get().GetTempDir(), _T("keyOldFmtMnuScan.ini"));
            wxString pid_string = wxString::Format(_T("_%lu"), wxGetProcessId());
            fnTempOldFmtMnuScan.SetName(fnTempOldFmtMnuScan.GetName() + pid_string);
            return fnTempOldFmtMnuScan.GetFullPath();
        }

        void ReportThisFailure(const wxString& text); //Report error to forum
        void SetCallingFunction(const wxString& funcName, int funcLine)
        {
            callingFunction = wxString::Format("%s:%d", funcName, funcLine) ;
        }
        void ClearCallingFunction()
        {
            callingFunction.Empty();
        }

        wxWindow*       pcbWindow;              //main app window

    private:
        bool            m_bAppShutDown;
        bool            m_menuPreviouslyBuilt;
        int             m_mode;
        bool            m_AppStartupDone;
        UsrConfigPanel* m_pUsrConfigPanel;
        bool            m_KeyBinderRefreshRequested;
        wxString        m_cbExeTimeStampstr;

        clKeyboardManager* m_pKBMgr;

        // Trying to catch a failure call; see ReportThisFailure()
        wxString callingFunction;

		DECLARE_EVENT_TABLE()

};//class cbKeyBinder

#endif // CBKEYBINDER_H
// ----------------------------------------------------------------------------
// Versons Release.Interface change.fix
// ----------------------------------------------------------------------------
// 2024/04/29 2.0.20 For C++20 change "==" comparisons to function const to avoid constipation errors.
// ----------------------------------------------------------------------------
// Commit   2.0.19 23/07/4
//          Add code to catch missing globals in keybinder20.conf file
//          Fix scrambled bindings caused by multiple duplicate id's within the
//          global accelerator table that reference menu entries.
// ----------------------------------------------------------------------------
// Commit   2.0.18 23/04/25
//          2.0.18 23/03/8
//          Refactor clKeyboardManager for simplicity and clarity
//          Save .conf file at app shutdown to fix missing user globals after debugging
//              with same personality and having changed the key bindings during debugging.
//          2.0.18 23/03/4
//          Release() clKeyboardManager at app shutdown which also saves the key binds
//          Remove redundant calls to Save() in clKeyboardManager::Initialize()
// ----------------------------------------------------------------------------
//  Commit 2.0.17 2022/12/21
//          Prevent KeyBinder from issuing shortcut conflict msg during pluigin management
// ----------------------------------------------------------------------------
//  Commit 2.0.16 2020/07/14
//          Fix duplicate keybindings in internationalizations
//          Remove duplicate global keybindings
//          http://forums.codeblocks.org/index.php/topic,23358.msg162587.html#msg162587
// ----------------------------------------------------------------------------
//  Commit 2.0.15 2020/05/30
//          Do not allow non-ascii unicode chars in accelerators
//          see wxKeyMonitorTextCtrl::OnKey()
//          clKeyboardManager::DoLoadDefaultAccelerators()
// ----------------------------------------------------------------------------
//  Commit 2.0.14 2020/04/9
//          Changes to fix crash when OnPageChanging() called.
//          Removed old duplicated configurationpanel.h & cpp causing crash
//          Removed wxListBook events in lieu of using new OnPageChanging() UI
// ----------------------------------------------------------------------------
//  Commit 2.0.13 2020/04/6
//          More comparisons in Initialize() to capture changed menu items from build to build.
// ----------------------------------------------------------------------------
//  Commit 2.0.12 2020/03/23
//          Match .conf and menu structure (by menu titles) to replace old menu ids with newer.
// ----------------------------------------------------------------------------
//  Commit 2.0.11 2020/03/02
//          Check for mismatched menu id's to global accelerators id's
//          Cf.,This will allow a global to override an old menu item.This happends when a new build does not match the current .conf file
//          The non-matching .conf menu item has an incorrect id anyway.
//
//          When a .conf menu id matches a default( current structure) menu id, also make sure the menu path (parentMenu) also matches.
//          It can mismatch when using a .conf configured from a previously built version of CodeBlocks on a newer build.
//
//          Set the global accelerators has table before Initilaize/Update() else globals are missed on the
//          first invocation of KeyBinder/Configure.
// ----------------------------------------------------------------------------
//  Commit 2.0.10 2020/02/25
//          Add "_pid#" to temporary filenames to avoid conflicts with linux permissions
//          eg. createing files with root, then running as a user.
// ----------------------------------------------------------------------------
//  Commit  1.0.51 2015/08/21
//          51) fixes for wxWidgets 3.0 using negative menu id's
// ----------------------------------------------------------------------------
//          2.0.00 2019/04/7
//              Rewrite using CodeLite method for global accelerator table shortcuts
//              Removes use of a bazillion wxEvtHandlers
//          2.0.06 2019/06/29
//              Re-instate clKeyboardManager.cpp lines 187-193
//          2.0.07 2019/07/2
//              Setting new accel in Linux will not work unless also set in global acceleratorTable
//              Use ancient "cbKeyBinder10.ini" standalone when no <personality>.cbKeyBinder10.ini exists
//          2.0.08 2019/10/16
//              Remove duplicate key bindings displayed in config panel
//              Sort key binding by parent menu before stowing into .conf file
//          2.0.09 2020/01/31
//              Special treatement for text "Code::Blocks" in menu label
// ----------------------------------------------------------------------------
//  Commit  1.0.50 2012/09/1
//          50) Merge global accelerators into keybinder, leave the rest alone
//              Remove bindings for Ctrl-C/P/X, allowing native behavior
// ----------------------------------------------------------------------------
//  Commit  1.0.49 2010/03/3
//          49) Apply patch 2885 by techy
// ----------------------------------------------------------------------------
//  Commit  1.0.48 2009/06/8
//          47) If tree item is a sub-menu don't allow key assignment
//          48) Change KeyBinder menu access from GetLabel() to GetLabel().Trim() (wx2.8.9/10)
// ----------------------------------------------------------------------------
//  commit  1.0.46 2008/02/12
//          45) Killerbot changes to header includes 2008/12/28
//          46) Fixed: [ Bug #12823 ] keybinder breaks layout submenu on linux
// ----------------------------------------------------------------------------
//  commit  1.0.44 2007/12/2
//          43) add non-pch logmanager headers
//          44) fix skipping of previously opened editors
// ----------------------------------------------------------------------------
//  Commit  1.0.42 2007/08/12
//          42) Change AddPendingEvent() to ProcessEvent() in wxMenuCmd::Exec()
//              to avoid crashes when secondary command key would close editors wx284
// ----------------------------------------------------------------------------
//  Commit  1.0.41 2007/07/30
//          40) check for numeric menu items that start with "_" wxGTK 2.8.4
//          41) Fixed disappearing/reappearing command keys on wxGTK 2.8.4 by
//              trimming all menu items and conf strings before comparing
// ----------------------------------------------------------------------------
//  Commit  1.0.39
//          39) mandrav changes for sdk RegisterEventSink
// ----------------------------------------------------------------------------
//  Commit  1.0.38 2007/06/15
//          36) Use full menu path as key value in external storage
//          37) Resolve unmatched menu id's with full menu path
//          38) Add Tool menu shortcut preservation via cbEVT_MENUBAR_CREATE_BEGIN/END events
// ----------------------------------------------------------------------------
//  Commit  1.0.35 2007/06/7
//          35) Prepend --personality arg to cbKeybinder.ini filename
// ----------------------------------------------------------------------------
//  Commit  1.0.34 2007/05/31
//          34) Re-enabled dynamic merge eliminating consideration of duplicates
// ----------------------------------------------------------------------------
//  Commit  1.0.33 2007/05/11
//          33) Fixes for use of non-precompiled headers
// ----------------------------------------------------------------------------
//  Commit  1.0.32 2007/05/10
//          31) Removed OnIdle() dynamic merging. Set Merge just before user definitions.
//          32) Fixed disappearing "duplicate" menu items. If mismatched id, just leave 'em alone.
// ----------------------------------------------------------------------------
//  Commit  1.0.30 2007/05/2
//          25) Create backup keys .ini.bak only on successful user definition save
//          26) Set guards against merging when possible app shutdown
//          27) Add ConfigBusy guard to OnIdle() merging
//          28) Added EVT_MENUBAR_CREATE_BEGIN/END, but they're never called. Even if
//              they were, they're not called during Tools menu changes.
//          29) Corrected for warning msg in wx2.8.3
//          30) Removed key assignment via text search when id search fails.(wxKeyBinder::UpdateSubMenu).
//               Causes too much grief.
// ----------------------------------------------------------------------------
//  Commit  1.0.24 2007/03/31
//          23) Remove dynamic merge from OnRelease() to avoid recording CB core menu deletions
//          24) Reinstate Menu UpdateByLabel when UpdateByID fails
// ----------------------------------------------------------------------------
//  Commit  1.0.22 2007/03/9
//          22) [ Patch #1913 ] Patch Key Binder plugin for wxW28 with disable_compat26
// ----------------------------------------------------------------------------
//  Commit  1.0.21 2007/02/23
//          20) Allow override of predefined menu accelerators set in Main.cpp
//          21) Use cbKeyBinder##.ini file when in executable folder
// ----------------------------------------------------------------------------
//  Commit  1.0.19 2007/01/23
//          17) Fixed: CB Plugins->ManagePlugins->disable plugin is completely
//              re-building the menuBar at another address causing Keybinder to crash.
//          18) Fixed: CB Plugins->ManagePlugins->disable plugin is re-entering
//              KeyBinders BuildMenu() routine causing crashes.
//          19) Re-initialize KeyBinder on next OnEditorOpen() when re-enabled by Plugin Manager.
// ----------------------------------------------------------------------------
//  Commit  1.0.16 2007/01/19
//          16) Fixed for missing *nix menu mnemonics
// ----------------------------------------------------------------------------
//  Commit  1.0.15 2007/01/18
//          15) Empty profile written when CB re-enables KeyBinder and no events occur.
// ----------------------------------------------------------------------------
//  Commit  1.0.14 2007/01/13
//          14) Applied patch 1821 by DerMeister
//              This patch fixes a crash in the *nix keybinder plugin.
//              See http://forums.codeblocks.org/index.php?topic=4927.0 for more information.
//              https://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=1821&group_id=5358
//  Commit  1.0.13 2006/12/30
//          13) Re-instated 2.6.2 version of RebuildMenuItem() with TimS additions
//              to solve missing menu icon problem (wx2.6.2 dejavu).
//              Completely rebuilds menuItems with changed shortcut and a bitmapped icon.
//              Works with wx2.6.3 w/fixes and wx2.8.0 according to TimS.
// ----------------------------------------------------------------------------
//  Commit  1.0.12 2006/12/29
//          10) redefine WXK_PRIOR and WXK_NEXT for wx2.8.0 allowing expected code behavior
//          11) remove case stmts for wx2.8.0
//          12) Fixed secondary profile keys leaking into primary profile
//              Fixed inability to delete secondary profiles
//  Commit  1.0.9 2006/12/19
//          8) Removed dependency on event EVT_APP_STARTUP_DONE to avoid "uninitialized" crashes
//          9) Set all EOL to dos ala TimS instructions & {svn propset eol-style native" *.h and *.cpp
// ----------------------------------------------------------------------------
//  Commit  1.0.8 2006/12/14
//          2) Added code to remove stale dynamic menu items
//          3) Added MergeDynamicMenu() & OnSave() at plugin termination
//          4) In IsValidKeyComb() changed '+' to '-'
//          5) Disallowed single key cmdStrings in wxKeyMonitorTextCtrl::OnKey()
//          6) Reduced size of .ini fileName
//          7) Fixed broken OnKey() to accept function keys w/o Ctrl- Alt- or Shift-
// -----------------------------------------------------------------------------
//  Commit  1.0.1 2006/10/27
//          Change OnIdle to OnTimer as per Denk advice
//          On new version, copy old key defs file if compatible
// -----------------------------------------------------------------------------
//  closed  2006/12/12 open    2006/12/12
//          Update/Merge the current array of keybindings via WalkMenuStructure
//          ala Rebind() but without clobbering other arrayss
//          A: Forget it. It'll wipe out the user secondary command settings.
//  closed  2006/12/12
//          When merging, verify menu id and delete from array if absent.
//  closed  when menuItems are changed without an attached() window, they arnt saved
//          A: no window was being attached at OnLoad() & UpdateArr(), so UpdateAllCmd()
//          was not being run. "flatnotebook" named had changed to "flat notebook"
//  closed  The OnKey() fix now doesnt allow F1-F9 etc
//  closed  2006/12/29
//          If a key is defined in the secondary profile, then user changes to primary
//          profile, key will be "saved" there also. Next load will have key in wrong
//          profile. EG. define secondary About=Alt-Shift-H. Then change to primary.
//          The definition will be saved in primary also.
//          All defs need to be cleared when a different profile is loaded. This might
//          cause havoc with dynamic keys
//          A: fixed, see next two items.
//  closed  The only way to clear a def thats in both the primary and secondary is:
//          Remove one def, do OK, reload, remove the secondary def. This is probably a
//          side effect of dynamic merging.
//          A: caused by merging before invoking UpdateArr() in OnLoad().
//  closed  Deleteing a secondary profile fails when no keys were changed.
//          A: caused by profile compare code in OnKeyConfigDialogDone() reporting
//             no changes even when a secondary profile was deleted.
//  Todo    2007/01/29
//          Save() .ini file to .ini.bak, then rename it to .ini
// -----------------------------------------------------------------------------
//  Commit  v0.4.26 2006/09/23
//          - minor #defines for WXMAC
//          - stop OnProfileSelected() from saving blank keyProfile
// -----------------------------------------------------------------------------
//  commit   v0.4.25d 2006/09/20
//          - recording dynamically changed menu items
//          - Get menu shortcuts via wxAcceratorEntry
//          - Add file name to corrupted file message
//          - Non Destructive update of menu items
//          - backup of .ini file before delete/save
// -----------------------------------------------------------------------------
//  note    2006/09/2
//          wxWidgets 2.6.3 fixed the bitmapped menu icon being clobbered when
//          SetText() was issued.
//          When, in wxKeyBinder::MergeSubMenu(), a RemoveShortcut() or
//          AddShortCut() is issued, Update() is called to update the app menu item.
//          Update() Destroy()ed and New'ed the app menuitem. This caused MergeSubMenu
//          to crash because the app menu chain was changed within this recursive
//          routine.
//          Because 2.6.3 was fixed, I removed the RebuildMenuItem() routine to
//          avoid altering the menuitem chain and to avoid the crash.
//          But this means that the bitmaps will be clobbered by SetText()
//          under 2.6.2 or earlier.
//  note    2006/09/2
//          Was testing on wxGTK 2.6.2. wxMenuItem->GetText() did not return the shortcut
//          key with the string. Had to use wxAcceleratorEntry routines to get the keys.
//          This works also for wxMSW. Had to trim all Labels and Texts from wxGTK
//          menu items. GTK resets all shortcut keys with +'s and keyBinder appends a space
//          to the SetText() menu items to avoid a GTK optimization.
//
//          GTK onIdle() is entered at much longer intervals than MSW, so dynamic
//          shortcut changes are recorded only on "idle" entries, but no shorter than
//          15 second intervals.
// -----------------------------------------------------------------------------
//  commit  2006/08/13 v0.4.24
// -----------------------------------------------------------------------------
//  opened  2006/08/20
//          Not recognizing dynamically assigned menu keys after initialization.
//          Re-setting F1 back to first menu item when plugin had set another.
//  fixed   2006/08/31
//          Added MergeDynamicMenuItems() to update key profile array
//          Added dynamic scan and save() at wxIdleEvent every 15 seconds.
// -----------------------------------------------------------------------------
//  commit  2006/07/29 v0.4.23
//          reverted  2006/07/29 to v0.4.20 CB 2761
//          crashes during CB exit
// -----------------------------------------------------------------------------
//  fixed   2006/08/11 v0.4.24
//          Reapplied recursive UpdateAll() to update sub menus and catch
//          duplicate key definitions. Had been removed by reverting to v0.4.20
// -----------------------------------------------------------------------------
//  fixed   2006/08/11 v0.4.24
//          Reapplied fix for multiple key profiles to compare arrays and update
//          key definitions. Had been removed by reverting to v0.4.20
// -----------------------------------------------------------------------------
//  commit  2006/07/19 v0.22 reverted
//          Temporary hack to ignore "Quit" menu redefinitions to avoid
//          crashes during CB termination.
// -----------------------------------------------------------------------------
//  open    2006/07/19 reverted
//          Secondary keys do not work from the main html window.
//          Even hooking all windows does not allow seconary keys to work at htmlWindow.
//          Primary keys work ok.
//          The following does *not* solve the problem
//          if ( pcbWindow->GetName() eq _T("frame") )
//              pcbWindow->SetName(_T("Code::Blocks"));
// -----------------------------------------------------------------------------
//  commit  v0.4.21 2006/07/17 reverted
// -----------------------------------------------------------------------------
//  closed  open    2006/07/19 v0.4.23a reverted
//          Allowing secondary key definitions on "Quit" causes CB to crash
//          during termination. A hack ignores these keys in wxKeyBinder::OnChar.
//          But this needs to be fixed.
//          Tried: Sending the quit keys to the main application window does not
//          solve the crashes.
//  closed  2006/08/11 open    2006/07/19
//          I experienced again that the menus did not show key redefinitions that
//          actually were working and showed correctly in the dialog. As if updateAll
//          was screwed up again.
// -----------------------------------------------------------------------------
//  commit  2006/06/15 v0.4.20
// -----------------------------------------------------------------------------
//  closed  2006/07/12 open    2006/07/11 reverted
//          Remove dependency on CodeBlocks editor open/close events
//          in order to avoid leaks on splitWindows.
//          Solution: removed pushed evenHandlers and used Connect()/Disconnect()
// -----------------------------------------------------------------------------
//  closed  2006/07/12 open 2006/07/12 reverted
//          Secondary profiles are not being recorded. Getting
//          "DialogDone: NO key changes" message, the Primary is then set
//          Resolution: cbKeyBinder::OnKeyConfigDialogDone compare function not
//          taking into account multiple keyprofiles in the keyBinderProfileArray.
// -----------------------------------------------------------------------------
//  closed  2006/07/15 open    2006/07/15 reverted
//          keybinder not clearing previous profile keys when loading other
//          profiles.
//          Resolution: Code not updating deep menu items. Walk down to deepest menu
//          items in wxKeyBinder::UpdateAllCmd via new UpdateSubMenu recursion.
// -----------------------------------------------------------------------------
//  commit  2006/06/14 v0.4.19
// -----------------------------------------------------------------------------
//  fixed   Getting compile error on linux. Missing editormanager.h
// -----------------------------------------------------------------------------
//  commit  2006/04/23 v0.4.17
// -----------------------------------------------------------------------------
//  fixed   2006/06/12 v0.4.19
//          Added EVT_CREATE & EVT_DESTROY to catch wxSplitterWindow activity.
//          CodeBlocks provided no events for split/unsplit windows
// -----------------------------------------------------------------------------
//  closed  2006/06/12 opened    2006/06/12
//          Duplicate key problem again. On restart, the second duplicate menu
//          item takes on its default value. eg., File/New Project=Ctrl+Alt+5,
//          but Project/New Project=Ctrl+Shift+N. I suspect because there is no
//          entry in the key file for the duplicate menu item.
//          A: Caused by misspelled "flatnotebook". We need at least one attach
//          to take place for UpdateAllCmd(pMenuBar) to update the menu items.
// ----------------------------------------------------------------------------
//  commit  2006/03/25 v 0.4.15
// ----------------------------------------------------------------------------
//  fixed   possible array overflow and unitialized integer
// ----------------------------------------------------------------------------
//  closed  2006/04/23  open    2006/04/10 v0.4.16
//          Ctrl-Shift-N cannot be overridden unless its the first accelerator set
//          on a menu item.
//          There are two NewProject menu items/accerators with the same id
//          on the menu and keybinder never recorded the second.
//          Removing the second definition of Ctrl-Shift-N from main_menu.xrc would
//          solve the problem.
// -----------------------------------------------------------------------------
//  fixed   2006/04/22 v0.4.17
//          Appease linux gcc 4.0.2 compiler by putting extra ()'s
//          around keybinder.cpp 2219 if(assignment statement)
//          Removed RC2 code and references
//          Fixed duplicate menu items not being updated by using the menu bar
//          as the source to search the keybinder array rather than the reverse.
// ----------------------------------------------------------------------------
// commit   2/9/2006 v0.4.15
// ----------------------------------------------------------------------------
//  mod     1/25/2006 12:00 PM v0.4.14
//          removed delete dlg from cbKeyBinder.cpp since it's handed
//          off to CodeBlocks cbConfigureationDialog
//  mod     Removed full class names from cbKeyBinder.H event table.
//          as requested by bug report
//          http://sourceforge.net/tracker/index.php?func=detail&aid=1411997&group_id=126998&atid=707418
//          fixed {PRIOR/NEXT} keys unrecognized by wxGetAccelFromString()
// ----------------------------------------------------------------------------
// commit 1/23/2006 v0.4.13
// ----------------------------------------------------------------------------
//  mod     1/22/2006 5:33 PM
//          m_PluginInfo.hasConfigure removed by SDK change
//  closed  1/23/2006 V0.4.13
//          SDK settings scheme broke keybinder updates
//
// ----------------------------------------------------------------------------
//commit 1/17/2006 v0.4.11
// ----------------------------------------------------------------------------
//	closed  1/17/2006 9:04 PM open	]1/17/2006 11:07 AM
//		    GTK Update() menuitems crashing on disappearing & numeric menuitems
//          GetConfigFolder() returning double "//"s like "/home/pecan//.codeblocks" ?
//  closed  1/17/2006 9:05 PM open    1/17/2006 5:50 PM
//          GTK - keybinder file is not being saved.
//  mod     1/17/2006 5:51 PM
//          moved UpdateAllCmd() to cbKeybinder.cpp Updatearr instead of
//          keybinder::Attach() becaue it was being invoked for every attach()
//          made to an object. Very slow on GTK
//
// ----------------------------------------------------------------------------
//commit 1/11/2006 3 PM v0.4.10
// ----------------------------------------------------------------------------
//	closed  open	1/11/2006 2:28 PM
//		    GTK mnemonics incorrectly updated;
//		    completely seperated out the GTK Update() routine
//
// ----------------------------------------------------------------------------
//commit 1/11/2006 1:22 PM v0.4.9
// ----------------------------------------------------------------------------
// Modify   1/11/2006 10:50 AM
//          changed direct stow of wxBinderEventHander::m_pTarget to SetInvalid()
//          from keybinder::DetachAll() to avoid crash on closed window pointer;
//
//  closed  1/11/2006 1:20 PM opened 1/11/2006 1:20 PM
//          Re: wxKeyBinder problems/solutions discussion
//          « Reply #7 on: Today at 01:06:03 PM »
//      	Reply with quote
//          Quote from: Pecan on January 10, 2006, 06:40:49 PM
//          ...Have commited KeyBinder v0.4.8 (svn 1708)...
//          you've used wxMenuItem::SetFont & ::GetFont
//          these are windows-only ! your plugin doesn't build under linux
//          Code:
//          menuutils.cpp: In member function 'void wxMenuCmd::RebuildMenuitem()':
//          menuutils.cpp:162: error: 'class wxMenuItem' has no member named 'SetFont'
//          menuutils.cpp:162: error: 'class wxMenuItem' has no member named 'GetFont'
// ----------------------------------------------------------------------------
//commit 1/10/2006 5:56 PM v0.4.8
// ----------------------------------------------------------------------------
//  closed  1/10/2006 4:14 PM opened 12/15/2005 5:42 PM
//          Adding hotkey to Plugins works, but doesnt show
//           A: havent been able to reproduce since above changes
//          On occation, hotkeys don't show on the menus but they still work.
//          Had been adding/removing a lot of keys.
//          Especially noticed in plugin menu items.
//          Removed a key, then they appeared.
//          See the -disappeared- item above
//          A: ini file had duplicate menuitems, one from settings
//          and one from help. The Help entry would reset the "settings"
//          menuitem because it had no accerator and we searched by
//          text. Fixed by searching first by id+text in keybinder::CreateNew()
// closed   1/10/2006 5:57 PM
//          found potential crash situation when event handler tried to
//          free itself but the window had already been closed.
//          A: if NOT winExists, RemoveEvtHandler() using main window ptr
//          in wxKeybinder::DetachAll() and wxBinderEventHander::~dtor
//
// ---------------------------------------------------------------------------
//commit 1/9/2006 9 AM v0.4.6
// ---------------------------------------------------------------------------
//  closed  1/9/2006 9 PM opened    1/7/2006 8:47 PM
//          modifying menuitem modifies bitmap spacing/margins?
//          menus items dont align vertically after modification
//          A: rebuild (Destroy/Insert) items with bitmaps
//
// ---------------------------------------------------------------------------
//  open    1/7/2006 8:44 PM
//          Detach() may be leaking when winExist==false
//          verify eventhandler is off the event chain
//
// ---------------------------------------------------------------------------
//commit 1/8/2006 9:47 AM v0.4.5
// ---------------------------------------------------------------------------
//  closed  new windows code in Update() was clobbersing GTK code
//          surrounded "OwnerDrawn" code with # if/endif(s)
//
// ---------------------------------------------------------------------------
// commit 1/7/2006
// ---------------------------------------------------------------------------
//Commited Keybinder ver 0.4.4 1/7/2006 10:56 PM
//
//Re: keybinder clobbers menuitems with bitmaps.
//
//It's been a real educational tracing through WX262 menu
//code this past week. It appears to me that the menu bitmap code
//is a paste and forget job. Very disappointing.
//
//The XRC code "owner draws" the bitmap onto the menu, then
//the menu code willy nilly turns off the "m_bOwnerDrawn" flag.
//Bitmapped menuitems are not supported in WX, menu code, only OwnerDrawn.
//
//Reason: Looks like a Win98 thingie. But...
//
//The next time the menuitem is updated, ownerdrawn attributes, bitmaps
//etc are clobbered because, of course, the owner drawn code is never called.
//
//If the modifying coder turns owner drawn back on, the width of the
//menuitem is ignored, the accelerator is drawn "right aligned", thus
//clobbering (drawing over) the menuitem text.
//
//Hack: SetText without OwnerDrawn to guarantee the menuitem width, then do it again
//with OwnerDrawn true to redraw/reinstate the bitmap. Jeeezzh!!!
//
//[code]
//		// set "un-ownerdrawn" text to preserve menu width
//        m_pItem->SetText(newtext);
//        //now redraw the menuitem if bitmapped
//		if (m_pItem->GetBitmap().GetWidth())
//        {   m_pItem->SetOwnerDrawn();
//            m_pItem->SetText(newtext);
//        }
//        //-m_pItem->GetMenu()->UpdateAccel(m_pItem); //<--does nothing previous SetTExt() didnt
//[/code]
//
//The results are not pretty. The margins between the bitmap and the text is changed,
//and the accelerator is vertically misaligned with its siblings  because it's
//drawn "right aligned" into the menuitem. Yuk!
//
//So: I'm commiting the "fixed" keybinder, and will now find a way to draw
//it as pretty as XRC does it. I think this is important, because we're all
//gonna have to mangle a menu someday.
//
//thanks
//pecan
//  closed  1/7/2006 8:42 PM
//          adding/removing/loading keys clobbered menu bitmaps
//          loading keys clobbered menu nmemonics
//          attaching to unwanted windows
//          crashing when "panel" disappeared
// ---------------------------------------------------------------------------
// Commit 12/14/2005 9:15 AM
// ---------------------------------------------------------------------------
//   closed  Project tree Ctrl+Shift+{ or } gets following log msgs:
//              15:01:24: wxMenuCmd::Update - setting the new text to [Activate prior project	Alt+F5]
//              15:01:24: wxKeyBind::KeyCodeToString - unknown key: [123]
//              15:01:24: wxMenuCmd::Update - setting the new text to [Move project up	Ctrl+Shift+]
//              15:01:24: wxKeyBind::KeyCodeToString - unknown key: [125]
//           A: checked keys as "isPrintable" instead of "isAlNum"

//   closed 12/15/2005 3:38 PM
//          Ctrl+Alt+Up/Down Ctrl+Shift+Up/Down dont record at all
//          A:wxWidgets2.6.2 returns false on modifier keys for Ctrl+Alt+UP/DOWN combination.
//          It returns Ctrl+Alt+PRIOR/NEXT instead of UP/DOWN and shows false for ctrl & alt.
//          Same is true for Ctrl+Shift+UP/Down.
//          Alt+Shift+Up/Down work ok.
//

//   closed 12/15/2005 5:37 PM
//          Shift-UP recorded as shift+{ and shift+down=shift+}
//          Any UP is getting recorded as {
//          Looks like all the UP/DOWN/LEFT/RIGHT are being turned to alpha
//          AND, they dont work
//          A: keys not defined in StringToKeyCode()
//

//  closed  12/16/2005 8:52 PM opened    12/15/2005 10:29 PM
//          wxMenuCmd::Update() is verifying by id, not text
//          could be causing the missing hotkey label above
// ----------------------------------------------------------------------------
//== bugs ==
// -done- Second hotkey doesnt trigger
// -done- Adding hotkey to third level menus doesnt trigger
//
// -done- getting periodic crashes defining key in dlg, Detatch??
//      happens when a new project is opened. Keys are lost and
//      invoking cbKeyBinder/Apply crashes C::B
//      A: wxCmdItem.GetLabel() unable to handle menu items with
//       filenames. the '\'s gave it a pain in the asm
//
// -done- bindings are being lost periodically also
//          A: same as above
// -done- Save/Load hotkeys
//          A: taken care of by dialog plus Onsave/OnLoad

//== Needs ==
// put messageboxs' 'ok' box under the mouse cursor
// -done Avoid running multiple copies or multiple versions
//      mutex would be nice
//      using version in file name
// Avoid running after C::B has own wxKeyBinder
// Add macro keys ability eg. Ctrl+Enter = {END}{ENTER}
//  yeah, Right!

//RC3 2005 Dec 10
//+v0.4
//  -done- Change file name to RC3 location + codeblocks version
//  -done- Dont memorize "filename" menu items
//  -done- Find correct eventHandler to pop (not just first)
//
//  -done-mandrav- Use the .conf way to save keybindings file ala mandrav 12/12/2005
//
//  -done-?what is
//  -done-    DetachAll - detaching from all my [0] targets message when
//  -done-    invoking dlg
//  -done-    A: caused by Rebind() doing DetachAll()/cleanup() before UpdateArr()
//  -done-      Ok. No harm done.
//
//  -done- Any keys refuse to be bound? 12/12/2005
//  -done- Re-Allow Secondary/Additional profiles v0.4.2
//  -done-mandrav=Find better way to load keys after CB initialization 12/12/2005
//  -done- After a plugin Menu change a plugin Shortcut key is assigned to wrong menu itme
//         A: verified key from file by Menu name NOT menu id
//  -done- After re-assignment and re-saving(the above), File description is wrong on disk
//  -done-  checkout MainWin vs cbMainWindow and remove code
//          A: attach()ing to "notebook" instead

// v0.4.1 12/30/2005
//  added event.Skip() to cbKeyBinder::OnAppStartupDone(CodeBlocksEvent& event)
//  enabled multiple profiles

// v0.4.2 1/2/2006 6PM
// keybinder attaching some windows named 's'
// so verify full name of window not just substring
// attach to text windows allowing keybinder invocation when no editor

// v0.4.4 1/7/2006 1
// additions to keybinder::Update() for use of bitmapped menuitems
// made keybinder "usableWindow" filter efficient (cf. Attach())
// add recursive "winExist" check to stop disappearing panels crash
// ----------------------------------------------------------------------------
// 11/9/2005
// C::B KeyBinder
// 2005 Nov 17
// ----------------------------------------------------------------------------
//cbKeyBinder is an adaptation of wxKeyBinder as a Code::Blocks plugin.
//
//It provides the C::B user an ability to bind custom key combinations to
//the C::B menu items.
//
//Some key combinations cannot be overridden by cbKeyBinder.
//For example, Ctrl+B executes Toggle Bookmark even when
//assigned to another menu item. The same is true for Ctrl+Shift+N
//(New Project). Some keys belong to wxScintilla and others have mutilple
// definitions and the second menu item is not overridden by keybinder.
//
