|
blueshake
|
 |
« on: March 08, 2010, 08:47:42 am » |
|
dear all: mybe you have the function of eclipse,in eclipse editor,when you type "tab",and if the next char is one of ")]}",it will skip it. see the screen shot.so if we want to implement this function,we need to hook getkey donw message,in codelite, it just simple handle it in this way.see the quote. and in codeblock ,I can not figure out how to do this.can somebode tell me how to do this in codeblock,thanks. BEGIN_EVENT_TABLE(LEditor, wxScintilla)
EVT_SCI_CHARADDED (wxID_ANY, LEditor::OnCharAdded) EVT_SCI_MARGINCLICK (wxID_ANY, LEditor::OnMarginClick) EVT_SCI_CALLTIP_CLICK (wxID_ANY, LEditor::OnCallTipClick) EVT_SCI_DWELLEND (wxID_ANY, LEditor::OnDwellEnd) EVT_SCI_UPDATEUI (wxID_ANY, LEditor::OnSciUpdateUI) EVT_SCI_SAVEPOINTREACHED (wxID_ANY, LEditor::OnSavePoint) EVT_SCI_SAVEPOINTLEFT (wxID_ANY, LEditor::OnSavePoint) EVT_SCI_MODIFIED (wxID_ANY, LEditor::OnChange) EVT_CONTEXT_MENU (LEditor::OnContextMenu) EVT_KEY_DOWN (LEditor::OnKeyDown) EVT_LEFT_DOWN (LEditor::OnLeftDown) EVT_MIDDLE_DOWN (LEditor::OnMiddleDown) EVT_MIDDLE_UP (LEditor::OnMiddleUp) EVT_LEFT_UP (LEditor::OnLeftUp) EVT_LEAVE_WINDOW (LEditor::OnLeaveWindow) EVT_KILL_FOCUS (LEditor::OnFocusLost) EVT_SCI_DOUBLECLICK (wxID_ANY, LEditor::OnLeftDClick) EVT_COMMAND (wxID_ANY, wxEVT_FRD_FIND_NEXT, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_FRD_REPLACE, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_FRD_REPLACEALL, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_FRD_BOOKMARKALL, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_FRD_CLOSE, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_FRD_CLEARBOOKMARKS, LEditor::OnFindDialog) EVT_COMMAND (wxID_ANY, wxEVT_CMD_JOB_STATUS_VOID_PTR, LEditor::OnHighlightThread) EVT_COMMAND (wxID_ANY, wxCMD_EVENT_REMOVE_MATCH_INDICATOR, LEditor::OnRemoveMatchInidicator) END_EVENT_TABLE()
|
|
|
|
|
Logged
|
Keep low and hear the sadness of little dog. I fall in love with a girl,but I don't dare to tell her.What should I do?
|
|
|
|
ollydbg
|
 |
« Reply #1 on: March 08, 2010, 09:17:47 am » |
|
I have tried, but failed.  In the codelite editor, say LEditor class, it is just derived from wxScintilla class, so it can hook the EVT_KEY_DOWN message. But in Codeblocks, cbEditor class use wxScintilla as its member, I don't know how to hook the Key_down event. By the way, if we can handle the message SCI_TAB from scintilla (see: http://www.scintilla.org/ScintillaDoc.html#KeyboardCommands), we can do the same thing. hope some one can help you.
|
|
|
|
|
Logged
|
If some piece of memory should be reused, turn them to variables (or const variables). If some piece of operations should be reused, turn them to functions. If they happened together, then turn them to classes.
|
|
|
|
MortenMacFly
|
 |
« Reply #2 on: March 08, 2010, 11:44:07 am » |
|
and in codeblock ,I can not figure out how to do this.can somebode tell me how to do this in codeblock,thanks.
Look into: void cbEditor::OnScintillaEvent(wxScintillaEvent& event) Notice that you should do any listening via an (the) editor hook. It can even be implemented as plugin btw!
|
|
|
|
|
Logged
|
|
|
|
|
blueshake
|
 |
« Reply #3 on: March 08, 2010, 01:41:40 pm » |
|
@morten thanks for your answer.I will check into it. 
|
|
|
|
|
Logged
|
Keep low and hear the sadness of little dog. I fall in love with a girl,but I don't dare to tell her.What should I do?
|
|
|
|
ollydbg
|
 |
« Reply #4 on: March 09, 2010, 03:30:37 am » |
|
I don't know we can do it in the OnScintillaEvent(), because we don't have a wxEVT_SCI_TAB defined in wxscintilla.h See the code snippet : cbStyledTextCtrl* cbEditor::CreateEditor() { m_ID = wxNewId();
// avoid gtk-critical because of sizes less than -1 (can happen with wxAuiNotebook/cbAuiNotebook) wxSize size = m_pControl ? wxDefaultSize : GetSize(); size.x = std::max(size.x, -1); size.y = std::max(size.y, -1);
cbStyledTextCtrl* control = new cbStyledTextCtrl(this, m_ID, wxDefaultPosition, size); control->UsePopUp(false);
wxString enc_name = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/default_encoding"), wxEmptyString); m_pData->m_encoding = wxFontMapper::GetEncodingFromName(enc_name);
// dynamic events Connect( m_ID, -1, wxEVT_SCI_MARGINCLICK, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnMarginClick ); Connect( m_ID, -1, wxEVT_SCI_UPDATEUI, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorUpdateUI ); Connect( m_ID, -1, wxEVT_SCI_CHANGE, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorChange ); Connect( m_ID, -1, wxEVT_SCI_CHARADDED, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorCharAdded ); Connect( m_ID, -1, wxEVT_SCI_DWELLSTART, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorDwellStart ); Connect( m_ID, -1, wxEVT_SCI_DWELLEND, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorDwellEnd ); Connect( m_ID, -1, wxEVT_SCI_USERLISTSELECTION, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnUserListSelection ); Connect( m_ID, -1, wxEVT_SCI_MODIFIED, (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnEditorModified );
// Now bind all *other* scintilla events to a common function so that editor hooks // can be informed for them too. // If you implement one of these events using a different function, do the following: // * comment it out here, // * "connect" it in the above block // * and make sure you call OnScintillaEvent() from your new handler function // This will make sure that all editor hooks will be called when needed. int scintilla_events[] = { // wxEVT_SCI_CHANGE, wxEVT_SCI_STYLENEEDED, // wxEVT_SCI_CHARADDED, wxEVT_SCI_SAVEPOINTREACHED, wxEVT_SCI_SAVEPOINTLEFT, wxEVT_SCI_ROMODIFYATTEMPT, wxEVT_SCI_KEY, wxEVT_SCI_DOUBLECLICK, // wxEVT_SCI_UPDATEUI, // wxEVT_SCI_MODIFIED, wxEVT_SCI_MACRORECORD, // wxEVT_SCI_MARGINCLICK, wxEVT_SCI_NEEDSHOWN, wxEVT_SCI_PAINTED, // wxEVT_SCI_USERLISTSELECTION, wxEVT_SCI_URIDROPPED, // wxEVT_SCI_DWELLSTART, // wxEVT_SCI_DWELLEND, wxEVT_SCI_START_DRAG, wxEVT_SCI_DRAG_OVER, wxEVT_SCI_DO_DROP, wxEVT_SCI_ZOOM, wxEVT_SCI_HOTSPOT_CLICK, wxEVT_SCI_HOTSPOT_DCLICK, wxEVT_SCI_CALLTIP_CLICK, wxEVT_SCI_AUTOCOMP_SELECTION, // wxEVT_SCI_INDICATOR_CLICK, // wxEVT_SCI_INDICATOR_RELEASE,
-1 // to help enumeration of this array }; int i = 0; while (scintilla_events[i] != -1) { Connect( m_ID, -1, scintilla_events[i], (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction) &cbEditor::OnScintillaEvent ); ++i; }
return control; }
We can only handle all the events in the scintilla_events array, either commented events or uncommented events. But the "tab" event will never carried in the wxEVT_SCI_KEY, because from the docs: http://www.scintilla.org/ScintillaDoc.html#SCN_KEYSCN_KEY Reports all keys pressed but not consumed by Scintilla. Since I think the "tab" event is already consumed by Scintilla internally, the only chance we can hook the tab event is the "SCI_TAB" stated in the http://www.scintilla.org/ScintillaDoc.html#KeyboardCommandswhich is not implemented in wxScintilla. I'm not sure all my comments is right. 
|
|
|
|
« Last Edit: March 09, 2010, 03:32:24 am by ollydbg »
|
Logged
|
If some piece of memory should be reused, turn them to variables (or const variables). If some piece of operations should be reused, turn them to functions. If they happened together, then turn them to classes.
|
|
|
|
Loaden
|
 |
« Reply #5 on: March 24, 2010, 02:12:05 pm » |
|
I solved this problem. cbStyledTextCtrl* cbEditor::CreateEditor() { m_ID = wxNewId();
// avoid gtk-critical because of sizes less than -1 (can happen with wxAuiNotebook/cbAuiNotebook) wxSize size = m_pControl ? wxDefaultSize : GetSize(); size.x = std::max(size.x, -1); size.y = std::max(size.y, -1);
cbStyledTextCtrl* control = new cbStyledTextCtrl(this, m_ID, wxDefaultPosition, size); control->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(cbEditor::OnKeyDown)); Notice: control->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(cbEditor::OnKeyDown));
|
|
|
|
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
Loaden
|
 |
« Reply #6 on: March 25, 2010, 05:18:13 pm » |
|
I make a patch for this, welcome to test.
|
|
|
|
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
ollydbg
|
 |
« Reply #7 on: March 26, 2010, 01:59:31 am » |
|
I make a patch for this, welcome to test.
I found a bug: When I enter this: void f( Then, I will get the close parenthesis auto added. void f(|) But at this moment, I press backspace key, then the opening parenthesis was deleted but the close parenthesis still there. void f) Except this bug, all the other functions works really nice!!! Thanks for the contribution.
|
|
|
|
|
Logged
|
If some piece of memory should be reused, turn them to variables (or const variables). If some piece of operations should be reused, turn them to functions. If they happened together, then turn them to classes.
|
|
|
|
Loaden
|
 |
« Reply #8 on: March 26, 2010, 04:29:42 am » |
|
I make a patch for this, welcome to test.
I found a bug: When I enter this: void f( Then, I will get the close parenthesis auto added. void f(|) But at this moment, I press backspace key, then the opening parenthesis was deleted but the close parenthesis still there. void f) Except this bug, all the other functions works really nice!!! Thanks for the contribution. Fix now.
|
|
|
|
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
MortenMacFly
|
 |
« Reply #9 on: March 26, 2010, 07:24:48 am » |
|
Fix now.
Some remarks concerning this patch: 1.) Methods should not start like " No", " Dont", " Not". This is hard to read. Instead always call a method like e.g. "AllowTabSmartJump" and change the break statement to " if (!AllowTabSmartJump()) break;" 2.) The trial for AllowTabSmartJump() should be the first statement in the method, like: if (!AllowTabSmartJump()) { event.Skip(); return; }
3.) These statements look weird to me: case _T('\''): case 57: // ( case 0x91: // {
You are using character comparison, then integer and finally hex. Why? Couldn't this be consistent, readable like e.g. all of type char? 4.) It does not use our code style (indention of 4 spaces) ...if you keep that in mind then it easier for us to integrate with the C::B sources. ...sorry for nut-picking. Take it as a hint for future work.
|
|
|
|
« Last Edit: March 26, 2010, 07:26:53 am by MortenMacFly »
|
Logged
|
|
|
|
|
Loaden
|
 |
« Reply #10 on: March 26, 2010, 08:21:30 am » |
|
Hi, morten, thanks for your tips. The following patch should solve your related issues. Index: src/include/cbstyledtextctrl.h =================================================================== --- src/include/cbstyledtextctrl.h (revision 6196) +++ src/include/cbstyledtextctrl.h (working copy) @@ -24,9 +24,13 @@ void OnKillFocus(wxFocusEvent& event); void OnGetFocus(wxFocusEvent& event); void OnGPM(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); + bool AllowTabSmartJump(); wxWindow* m_pParent; wxLongLong m_lastFocusTime; + bool m_tabSmartJump; DECLARE_EVENT_TABLE() }; Index: src/sdk/cbstyledtextctrl.cpp =================================================================== --- src/sdk/cbstyledtextctrl.cpp (revision 6196) +++ src/sdk/cbstyledtextctrl.cpp (working copy) @@ -18,17 +18,23 @@ #include "editorbase.h" // DisplayContextMenu #include "prep.h" // platform::gtk +static const wxString s_leftBrace(_T("([{'\"")); +static const wxString s_rightBrace(_T(")]}'\"")); + BEGIN_EVENT_TABLE(cbStyledTextCtrl, wxScintilla) EVT_CONTEXT_MENU(cbStyledTextCtrl::OnContextMenu) EVT_KILL_FOCUS(cbStyledTextCtrl::OnKillFocus) EVT_MIDDLE_DOWN(cbStyledTextCtrl::OnGPM) EVT_SET_FOCUS(cbStyledTextCtrl::OnGetFocus) + EVT_KEY_DOWN(cbStyledTextCtrl::OnKeyDown) + EVT_KEY_UP(cbStyledTextCtrl::OnKeyUp) END_EVENT_TABLE() cbStyledTextCtrl::cbStyledTextCtrl(wxWindow* pParent, int id, const wxPoint& pos, const wxSize& size, long style) : wxScintilla(pParent, id, pos, size, style), m_pParent(pParent), - m_lastFocusTime(0L) + m_lastFocusTime(0L), + m_tabSmartJump(false) { //ctor } @@ -103,3 +109,125 @@ SetSelectionVoid(start, end); } } // end of OnGPM + +void cbStyledTextCtrl::OnKeyDown(wxKeyEvent& event) +{ + int keyCode = event.GetKeyCode(); + switch (keyCode) + { + case WXK_TAB: + { + if (m_tabSmartJump) + { + if (s_rightBrace.Find(GetCharAt(GetCurrentPos())) == wxNOT_FOUND) + { + m_tabSmartJump = false; + } + else + { + CharRight(); + return; + } + } + } + break; + + case WXK_BACK: + { + if (m_tabSmartJump) + { + const int pos = GetCurrentPos(); + const int index = s_leftBrace.Find(GetCharAt(pos - 1)); + if (index != wxNOT_FOUND && GetCharAt(pos) == s_rightBrace.GetChar(index)) + { + CharRight(); + DeleteBack(); + } + } + } + break; + + case WXK_ESCAPE: + { + if (m_tabSmartJump) + { + m_tabSmartJump = false; + CharLeft(); + Tab(); + return; + } + } + break; + + case WXK_RETURN: + { + m_tabSmartJump = false; + } + break; + } + + event.Skip(); +} + +void cbStyledTextCtrl::OnKeyUp(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + switch (keyCode) + { + case _T('['): // [ { + case _T('\''): // ' " + case _T('9'): // ( + { + if (!AllowTabSmartJump()) break; + + wxChar ch = keyCode; + if (event.ShiftDown()) + { + if (keyCode == _T('\'')) ch = _T('"'); + else if (keyCode == _T('9')) ch = _T('('); + else if (keyCode == _T('[')) ch = _T('{'); + } + + int index = s_leftBrace.Find(ch); + if (index != wxNOT_FOUND && GetCharAt(GetCurrentPos()) == s_rightBrace.GetChar(index)) + m_tabSmartJump = true; + else if (keyCode == _T('\'')) // ' " + m_tabSmartJump = false; + } + break; + + case _T(']'): // ] } + case _T('0'): // ) + { + if (!AllowTabSmartJump()) break; + if (keyCode == _T('0') && !event.ShiftDown()) break; + m_tabSmartJump = false; + } + break; + } + + event.Skip(); +} + +bool cbStyledTextCtrl::AllowTabSmartJump() +{ + int style = GetStyleAt(GetCurrentPos() - 2); + switch (GetLexer()) + { + case wxSCI_LEX_CPP: + { + if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER) + return true; + else + return !(style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER); + } + case wxSCI_LEX_D: + { + if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER) + return true; + else + return !(style == wxSCI_D_STRING || style == wxSCI_D_CHARACTER); + } + } + return false; +}
|
|
|
|
« Last Edit: March 26, 2010, 09:02:48 am by Loaden »
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
Loaden
|
 |
« Reply #11 on: March 26, 2010, 08:25:01 am » |
|
But now I encountered difficulties: I do not know how to draw the lines for tips? Moreover, whether it is necessary for drawing the root tips of the lines that do? Everyone's opinion?
|
|
|
|
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
Loaden
|
 |
« Reply #12 on: March 26, 2010, 08:36:00 am » |
|
2.) The trial for AllowTabSmartJump() should be the first statement in the method, like: if (!AllowTabSmartJump()) { event.Skip(); return; }
Here, I do not quite understand: Why did not directly break it, because at the end of the function, there implementation: 'event.Skip ();' ?
|
|
|
|
|
Logged
|
Arch & XP -|- GCC & VC -|- Code::Blocks SVN Latest------------------------------------------ Index for my patches
|
|
|
|
MortenMacFly
|
 |
« Reply #13 on: March 26, 2010, 08:39:09 pm » |
|
Here, I do not quite understand: Why did not directly break it, because at the end of the function, there implementation: 'event.Skip ();' ?
Yes, but there are computations in between which can be avoided. Namely event.GetKeyCode(); and the switch computation.
|
|
|
|
|
Logged
|
|
|
|
|
MortenMacFly
|
 |
« Reply #14 on: March 26, 2010, 08:43:22 pm » |
|
Hehe... now after the modifications, isn't this: Index: src/include/cbstyledtextctrl.h + switch (GetLexer()) + { + case wxSCI_LEX_CPP: + { + if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER) + return true; + else + return !(style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER); + } + case wxSCI_LEX_D: + { + if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER) + return true; + else + return !(style == wxSCI_D_STRING || style == wxSCI_D_CHARACTER); + } + } + return false; +}
The same like this: Index: src/include/cbstyledtextctrl.h + switch (GetLexer()) + { + case wxSCI_LEX_CPP: + { + if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER) + return true; + } + case wxSCI_LEX_D: + { + if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER) + return true; + } + } + return false; +}
??? 
|
|
|
|
|
Logged
|
|
|
|
|