#ifndef KEYS_H_INCLUDED
#define KEYS_H_INCLUDED
// For compilers that support precompilation, includes <wx/wx.h>
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <cbplugin.h> // for "class cbPlugin"
class wxKeyEvent;
class keys : public cbPlugin
{
public:
keys();
virtual ~keys();
virtual void BuildMenu(wxMenuBar* menuBar){}
virtual void BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = 0){}
virtual bool BuildToolBar(wxToolBar* toolBar){ return false; }
protected:
virtual void OnAttach();
virtual void OnRelease(bool appShutDown);
private:
void OnKeyUp(wxKeyEvent& event);
DECLARE_EVENT_TABLE()
};
#endif // KEYS_H_INCLUDED
#include <sdk.h> // Code::Blocks SDK
#include <configurationpanel.h>
#include "keys.h"
namespace
{
PluginRegistrant<keys> reg(_T("keys"));
}
BEGIN_EVENT_TABLE(keys,cbPlugin)
EVT_KEY_UP(keys::OnKeyUp)
END_EVENT_TABLE()
// constructor
keys::keys()
{
if(!Manager::LoadResource(_T("keys.zip")))
{
NotifyMissingFile(_T("keys.zip"));
}
}
// destructor
keys::~keys()
{
}
void keys::OnAttach()
{
}
void keys::OnRelease(bool appShutDown)
{
}
void keys::OnKeyUp(wxKeyEvent& event)
{
if( !IsAttached() )
return;
Manager::Get()->GetLogManager()->Log( _("key up") );
}
void CodeCompletion::OnAttach()
{
m_PageIndex = -1;
m_InitDone = false;
m_EditMenu = 0;
m_SearchMenu = 0;
m_ViewMenu = 0;
m_Function = 0;
m_Scope = 0;
m_ParsedProjects.clear();
m_FunctionsScope.clear();
m_NameSpaces.clear();
m_AllFunctionsScopes.clear();
m_ToolbarChanged = true; // by default
m_LastFile = wxEmptyString;
LoadTokenReplacements();
RereadOptions();
m_LastPosForCodeCompletion = -1;
m_StartIdxNameSpaceInScope = -1;
m_NativeParser.SetNextHandler(this);
m_NativeParser.CreateClassBrowser();
// hook to editors
EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<CodeCompletion>(this, &CodeCompletion::EditorEventHook);
m_EditorHookId = EditorHooks::RegisterHook(myhook);
// register event sinks
Manager* pm = Manager::Get();
pm->RegisterEventSink(cbEVT_EDITOR_SAVE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnReparseActiveEditor));
pm->RegisterEventSink(cbEVT_EDITOR_OPEN, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorOpen));
pm->RegisterEventSink(cbEVT_EDITOR_ACTIVATED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorActivated));
pm->RegisterEventSink(cbEVT_EDITOR_TOOLTIP, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnValueTooltip));
pm->RegisterEventSink(cbEVT_EDITOR_CLOSE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnEditorClosed));
pm->RegisterEventSink(cbEVT_APP_STARTUP_DONE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnAppDoneStartup));
pm->RegisterEventSink(cbEVT_WORKSPACE_CHANGED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnWorkspaceChanged));
pm->RegisterEventSink(cbEVT_PROJECT_ACTIVATE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectActivated));
pm->RegisterEventSink(cbEVT_PROJECT_CLOSE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectClosed));
pm->RegisterEventSink(cbEVT_PROJECT_SAVE, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectSaved));
pm->RegisterEventSink(cbEVT_PROJECT_FILE_ADDED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectFileAdded));
pm->RegisterEventSink(cbEVT_PROJECT_FILE_REMOVED, new cbEventFunctor<CodeCompletion, CodeBlocksEvent>(this, &CodeCompletion::OnProjectFileRemoved));
}
I expected the releasing of any key to print to the Log Manager, but nothing so far.
Care to help?
void keys::OnAttach()
{
// hook events to editors
EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<keys>(this, &keys::EditorEventHook);
this->m_EditorHookId = EditorHooks::RegisterHook(myhook);
}
void keys::EditorEventHook(cbEditor* editor, wxScintillaEvent& event)
{
wxString str(_T("keys::EditorEventHook:"));
str += _(" event type:");
std::stringstream ss;
ss << event.GetEventType();
str += wxString(ss.str().c_str(), wxConvUTF8);
str += _(" event key:");
ss.str("");
ss << event.GetKey();
str += wxString(ss.str().c_str(), wxConvUTF8);
Manager::Get()->GetLogManager()->Log(str);
// if(event.GetEventType() == wxEVT_SCI_KEY)
// Manager::Get()->GetLogManager()->Log(_("key event type"));
if(event.GetControl())
Manager::Get()->GetLogManager()->Log(_("ctrl"));
if(event.GetKey() == wxSCI_KEY_UP)
Manager::Get()->GetLogManager()->Log(_("key up event"));
if(event.GetKey() == wxSCI_KEY_DOWN)
Manager::Get()->GetLogManager()->Log(_("key down event"));
//if(event.GetEventType() == wxEVT_CHAR)
// Manager::Get()->GetLogManager()->Log(_("key character event"));
// allow others to handle this event
event.Skip();
}
If I leave the "if(event.GetControl())" line, i get an "undefined reference to `_imp___ZNK16wxScintillaEvent10GetControlEv' in keys.cpp :|
In the same way, if i leave the "wxEVT_SCI_KEY" check, i get another unexpected linker error...
The code looks nicely organized, but it's a bit overwhelming to the newbie, lots of different libraries mixed together and not many comments in the code make it a bit hard to follow.
did you try looking at void CodeCompletion::EditorEventHook(cbEditor* editor, wxScintillaEvent& event) in src/plugins/codecompletion/codecompletion.cpp (approx line 1850)?Yes, it's been my main source of reference. But it doesn't handle extended keys. From the wxScintilla events I'm printing, I don't think the Ctrl/Alt/Shift keys generate wxScintillaEvents, unless it's in combination with. My guess is Scintilla is too high level for a Ctrl key event, and i have to go lower level. I'll now try your first suggestion, using Connect() and associating it with the currently selected Editor.
you need to link against the wxscintilla .dll or .so (again see how its done in codecompletion)Thanks, i was a bit tired and did not realize wxscintilla.dll was not being linked.
I'm not too confident with the code to suggest a proper solution yet (or to realize that this is in fact a real problem), but i just tend to leave lots of comments everywhere on my code. Some people have called me on that, saying that code looks dirty :)QuoteThe code looks nicely organized, but it's a bit overwhelming to the newbie, lots of different libraries mixed together and not many comments in the code make it a bit hard to follow.
agree, but not easy to fix. suggetions?
I guess most of my doubts can be resolved with source code digging and checking out what each 3rd party library inner workings are,
but it takes a lot longer than simply looking at the wiki's tutorials
what you are doing with your event table is telling wxWidgets you want to capture key events from your plugin and any of its children. one problem: your plugin is not the parent of the editors.
void keys::OnAttach()
{
this->Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp), NULL, this); // does nothing
//Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp), NULL, this); // this does nothing as well
//Connect(wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp)); // neither does this
}
Improving the wiki tutorials would probably be one of the the most valuable things we can do, but it does take quite a bit of work to put tutorials together and keep them up to date.I'd contribute, if i can ever get this thing off the ground. Maybe i should go play with event catching in wxWidgets first to make sure i can make it work and then try in CodeBlocks.
Quotewhat you are doing with your event table is telling wxWidgets you want to capture key events from your plugin and any of its children. one problem: your plugin is not the parent of the editors.
Which is theeditor'splugin's parent? The wxWindow from which the editor inherits, or the EditorManager, or some other class?
I've tried using the Connect as mentioned in the post, but keys::OnKeyUp is never called. It now looks like:Codevoid keys::OnAttach()
{
this->Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp), NULL, this); // does nothing
//Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp), NULL, this); // this does nothing as well
//Connect(wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp)); // neither does this
}
this->Connect(...);
target_window->Connect(wxEVT_KEY_UP, wxKeyEventHandler(keys::OnKeyUp), NULL, this);
target_window->PushEventHandler(this);
I'd contribute, if i can ever get this thing off the ground. Maybe i should go play with event catching in wxWidgets first to make sure i can make it work and then try in CodeBlocks.
svn checkout http://svn.berlios.de/svnroot/repos/cbilplugin/branches/EditorTweaks
/***************************************************************
* Name: keys
* Purpose: Code::Blocks plugin
* Author: (Turbo)
* Created: 2009-12-06
* Copyright:
* License: GPL
**************************************************************/
#ifndef KEYS_H_INCLUDED
#define KEYS_H_INCLUDED
// For compilers that support precompilation, includes <wx/wx.h>
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <cbplugin.h>
#include <wx/wxscintilla.h> // for wxScintillaEvent
class CodeBlocksEvent;
class cbEditor;
class keys : public cbPlugin
{
public:
/** Constructor. */
keys();
/** Destructor. */
virtual ~keys();
virtual void BuildMenu(wxMenuBar* menuBar){}
virtual void BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = 0){}
virtual bool BuildToolBar(wxToolBar* toolBar){ return false; }
protected:
virtual void OnAttach();
virtual void OnRelease(bool appShutDown);
private:
void OnKeyUp(wxKeyEvent& event);
private:
int m_EditorHookId;
};
#endif // KEYS_H_INCLUDED
#include <sdk.h> // Code::Blocks SDK
#include <configurationpanel.h>
#include "keys.h"
#include <manager.h>
#include <sdk_events.h>
#include <editorbase.h>
#include <editor_hooks.h>
#include <wx/wxscintilla.h>
#include "cbstyledtextctrl.h"
#include <sstream>
// Register the plugin with Code::Blocks.
// We are using an anonymous namespace so we don't litter the global one.
namespace
{
PluginRegistrant<keys> reg(_T("keys"));
}
// constructor
keys::keys()
{
// Make sure our resources are available.
// In the generated boilerplate code we have no resources but when
// we add some, it will be nice that this code is in place already ;)
if(!Manager::LoadResource(_T("keys.zip")))
{
NotifyMissingFile(_T("keys.zip"));
}
}
// destructor
keys::~keys()
{
}
void keys::OnAttach()
{
// do whatever initialization you need for your plugin
// NOTE: after this function, the inherited member variable
// m_IsAttached will be TRUE...
// You should check for it in other functions, because if it
// is FALSE, it means that the application did *not* "load"
// (see: does not need) this plugin...
// hook "key up" event with member callback function
EditorManager* em = Manager::Get()->GetEditorManager();
for(int i=0;i<em->GetEditorsCount();i++)
{
cbEditor* ed=em->GetBuiltinEditor(i);
if(ed && ed->GetControl())
{
ed->GetControl()->SetOvertype(false);
ed->GetControl()->Connect(wxEVT_KEY_UP,(wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction)&keys::OnKeyUp,NULL,this);
}
}
}
void keys::OnRelease(bool appShutDown)
{
// do de-initialization for your plugin
// if appShutDown is true, the plugin is unloaded because Code::Blocks is being shut down,
// which means you must not use any of the SDK Managers
// NOTE: after this function, the inherited member variable
// m_IsAttached will be FALSE...
// unregister hook
EditorManager* em = Manager::Get()->GetEditorManager();
for(int i=0;i<em->GetEditorsCount();i++)
{
cbEditor* ed=em->GetBuiltinEditor(i);
if(ed && ed->GetControl())
ed->GetControl()->Disconnect(wxEVT_NULL,(wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction)&keys::OnKeyUp);
}
}
void keys::OnKeyUp(wxKeyEvent& event)
{
if( !IsAttached() )
return;
if(event.GetKeyCode() == WXK_CONTROL)
Manager::Get()->GetLogManager()->Log(wxString::Format(_("CTRL DOWN")));
else
{
Manager::Get()->GetLogManager()->Log(wxString::Format(wxT("%i"),event.GetKeyCode()));
}
event.Skip(); // allow event to propagate
}
void keys::OnAttach()
{
// do whatever initialization you need for your plugin
// NOTE: after this function, the inherited member variable
// m_IsAttached will be TRUE...
// You should check for it in other functions, because if it
// is FALSE, it means that the application did *not* "load"
// (see: does not need) this plugin...
// hook "key up" event with member callback function
EditorManager* em = Manager::Get()->GetEditorManager();
for(int i=0;i<em->GetEditorsCount();i++)
{
cbEditor* ed=em->GetBuiltinEditor(i);
if(ed && ed->GetControl())
{
ed->GetControl()->SetOvertype(false);
ed->GetControl()->Connect(wxEVT_KEY_UP,(wxObjectEventFunction) (wxEventFunction) (wxCharEventFunction)&keys::OnKeyUp,NULL,this);
}
}
}
Manager::Get()->RegisterEventSink(cbEVT_EDITOR_ACTIVATED, new cbEventFunctor<JumpTracker, CodeBlocksEvent>(this, &JumpTracker::OnEditorActivated));
ed->GetControl()->SetOvertype(false);