1 /* 2 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3 3 * http://www.gnu.org/licenses/lgpl-3.0.html 4 */ 5 6 #ifndef CCMANAGER_H 7 #define CCMANAGER_H 8 9 #include "manager.h" 10 11 #ifndef CB_PRECOMP 12 #include <wx/timer.h> 13 #include "cbplugin.h" 14 #endif 15 16 class UnfocusablePopupWindow; 17 class wxHtmlLinkEvent; 18 class wxHtmlWindow; 19 class wxListEvent; 20 class wxListView; 21 class wxScintillaEvent; 22 23 /** Code Completion Plugin Manager 24 * 25 * This class manages all kinds of code completion plugins. For example, the native C/C++ code 26 * completion plugin, the Fortran code completion plugin and Python code completion plugin. 27 * The ccmanager asks some informations from the managed ccplugins. The major value passes from the 28 * ccmanager and the ccplugins are CCCallTip and CCToken. 29 * 30 * The CCToken is needed when ccmanager needs to fill a code suggestion list, it is the ccplugin's 31 * duty to supply a collection of CCTokens. 32 * 33 * When user is entering some function call statement, CCCallTip is used to show the function 34 * information, and especially it can highlight the current function argument. 35 * 36 * Another kind of tip is the tooltip, this is the tip window shown when mouse hover on a specified 37 * token(such as variable token), ccmanager queries this information by asking CCToken information 38 * from ccplugin. 39 * 40 * Note: Under Windows, scroll events are always directed to the window in focus, making it 41 * difficult to scroll the autocomplete list and the doxygen popup with the mouse. So, under 42 * Windows we catch scroll requests to the cbStyledTextCtrl, and run them through 43 * CCManager::OnPopupScroll(). This filters the event, and if the mouse is over the autocomplete 44 * list or the doxygen popup, the scroll event is instead sent there (and skipped for the editor 45 * window). 46 */ 47 class DLLIMPORT CCManager : public Mgr<CCManager>, wxEvtHandler 48 { 49 public: 50 friend class Mgr<CCManager>; 51 friend class Manager; // give Manager access to our private members 52 53 /** Get the ccPlugin instant for the cbEditor. 54 * 55 * If the editor opened a c/c++ file, then it returns the native c/c++ ccPlugin. 56 * @param ed input editor, uses active editor if one is not passed; has (minimal) cache optimization 57 */ 58 cbCodeCompletionPlugin* GetProviderFor(cbEditor* ed = nullptr); 59 60 /** Register a new set of characters that, when typed, invoke calltip requests. 61 * 62 * Use this if the default set is not appropriate. 63 */ 64 void RegisterCallTipChars(const wxString& chars, cbCodeCompletionPlugin* registrant); 65 66 67 /** Register a new set of characters that, when typed, auto-launch codecomplete requests. 68 * 69 * Use this if the default set is not appropriate. 70 */ 71 void RegisterAutoLaunchChars(const wxString& chars, cbCodeCompletionPlugin* registrant); 72 73 /** Let CCManager know that new results are available from cbCodeCompletionPlugin::GetDocumentation(). */ 74 void NotifyDocumentation(); 75 /** Let CCManager know that a change (e.g. active lexer is switched) may invalidate cached active ccPlugin. */ 76 void NotifyPluginStatus(); 77 78 /** If for some reason you *need* to use wxScintilla::AutoCompShow(), call this instead so CCManager does not step on you. */ 79 void InjectAutoCompShow(int lenEntered, const wxString& itemList); 80 81 /** Used by cbStyledTextCtrl to process ArrowUp and ArrowDown key press. 82 * 83 * This is not intended to be called by ccPlugins. 84 */ 85 bool ProcessArrow(int key); 86 87 /** Called after env settings have changed, so the changes can be applied. */ 88 void UpdateEnvSettings(); 89 private: 90 CCManager(); 91 ~CCManager() override; 92 93 /** Event handler to list the suggestion, when a user press Ctrl-space (by default). */ 94 void OnCompleteCode(CodeBlocksEvent& event); 95 96 /** Event handler to avoid tooltips getting stuck active. */ 97 void OnDeactivateApp(CodeBlocksEvent& event); 98 /** Event handler to avoid tooltips getting stuck active. */ 99 void OnDeactivateEd(CodeBlocksEvent& event); 100 /** Event handler to avoid tooltips getting stuck active. */ 101 void OnEditorOpen(CodeBlocksEvent& event); 102 /** Event handler to avoid tooltips getting stuck active. */ 103 void OnEditorClose(CodeBlocksEvent& event); 104 105 /** Hook to the editor. 106 * 107 * This is used so that we know some specific chars were entered, then we can decide 108 * whether it time to show a calltip or suggestion list. 109 */ 110 void OnEditorHook(cbEditor* ed, wxScintillaEvent& event); 111 112 /** Mouse hover event. */ 113 void OnEditorTooltip(CodeBlocksEvent& event); 114 115 /** Event handler to show the call tip, when user press Ctrl-Shift-Space. */ 116 void OnShowCallTip(CodeBlocksEvent& event); 117 118 /** Event handler to show documentation, when user changes autocomplete selection. */ 119 void OnAutocompleteSelect(wxListEvent& event); 120 121 /** Event handler to tear down documentation, when autocomplete closes. */ 122 void OnAutocompleteHide(wxShowEvent& event); 123 124 /** Defer showing the calltip to avoid a crash issue. 125 * 126 * Launching this event directly seems to be a candidate for race condition 127 * and crash in OnShowCallTip() so we attempt to serialize it. 128 */ 129 void OnDeferredCallTipShow(wxCommandEvent& event); 130 131 /** Defer canceling the calltip to avoid a crash issue. @see CCManager::OnDeferredCallTipShow */ 132 void OnDeferredCallTipCancel(wxCommandEvent& event); 133 134 #ifdef __WXMSW__ 135 /** Intercept cbStyledTextCtrl scroll events and forward to autocomplete/documentation popups. */ 136 void OnPopupScroll(wxMouseEvent& event); 137 #endif // __WXMSW__ 138 139 /** A link is clicked in the document window. */ 140 void OnHtmlLink(wxHtmlLinkEvent& event); 141 142 /** Grouped event handler for several timers. */ 143 void OnTimer(wxTimerEvent& event); 144 145 /** Handle the CC related menu click. */ 146 void OnMenuSelect(wxCommandEvent& event); 147 148 /** CC launched in the same state as last run, display via cached data. */ 149 void DoBufferedCC(cbStyledTextCtrl* stc); 150 151 /** Hide the documentation popup. */ 152 void DoHidePopup(); 153 154 /** Show the documentation popup. */ 155 void DoShowDocumentation(cbEditor* ed); 156 157 /** Update which tip to show next and where to show it. */ 158 void DoUpdateCallTip(cbEditor* ed); 159 160 /** User click the next or previous small button of the tip window. */ 161 enum Direction { Previous, Next }; 162 163 /**Switch the tip window to the next item. */ 164 void AdvanceTip(Direction direction); 165 166 /** Format tips by breaking long lines at (hopefully) logical places. */ 167 void DoShowTips(const wxStringVec& tips, cbStyledTextCtrl* stc, int pos, int argsPos, int hlStart, int hlEnd); 168 169 /** Code completion as just insert some text in the editor, ask the smart indent plugin to adjust the indent. */ 170 void CallSmartIndentCCDone(cbEditor* ed); 171 172 typedef std::map< cbCodeCompletionPlugin*, std::set<wxChar> > CCPluginCharMap; 173 CCPluginCharMap m_CallTipChars; //!< Chars each plugin is interested in for calltip state. 174 CCPluginCharMap m_AutoLaunchChars; //!< Chars each plugin is interested in for autocomplete. 175 int m_EditorHookID; 176 int m_AutocompPosition; //!< Location of caret when autocomplete timer starts, if caret is still there, launch autocomplete. 177 int m_CallTipActive; //!< Is CCManager currently displaying a calltip, and if so, where. 178 int m_LastAutocompIndex; //!< Index of currently selected entry in autocomplete popup. 179 int m_LastTipPos; //!< Last location a tool/call tip was displayed. 180 int m_WindowBound; //!< Right-most boundary the documentation popup is allowed to stretch to. 181 bool m_OwnsAutocomp; //!< Do we control the current autocomplete popup? 182 typedef std::vector<cbCodeCompletionPlugin::CCCallTip> CallTipVec; 183 CallTipVec m_CallTips; //!< Cached calltips 184 CallTipVec::const_iterator m_CurCallTip; //!< Remember current choice. 185 std::map<int, size_t> m_CallTipChoiceDict; //!< Remember past choices. 186 std::map<int, size_t> m_CallTipFuzzyChoiceDict; //!< Remember past choices based on prefix. 187 wxTimer m_CallTipTimer; 188 wxTimer m_AutoLaunchTimer; 189 wxTimer m_AutocompSelectTimer; 190 wxSize m_DocSize; //!< Size of the documentation popup. 191 wxPoint m_DocPos; //!< Location of the documentation popup. 192 193 #ifdef __WXMSW__ 194 /** a handle to the autocomplete list window created by (wx)scintilla, needed under Windows 195 * to determine its dimensions (so the scroll event can be sent to it, if relevant) 196 */ 197 wxListView* m_pAutocompPopup; 198 #endif // __WXMSW__ 199 200 cbEditor* m_pLastEditor; //!< Last editor operated on. 201 cbCodeCompletionPlugin* m_pLastCCPlugin; //!< The plugin handling m_pLastEditor. 202 203 /** Container for documentation popup. 204 * the window for the doxygen popup, with properties so it is always on top, 205 * but cannot be focused. 206 */ 207 UnfocusablePopupWindow* m_pPopup; 208 209 /** Documentation popup. 210 * it is the rendered doxygen documentation to display in the popup 211 */ 212 wxHtmlWindow* m_pHtml; 213 214 struct LastACLaunchState 215 { initLastACLaunchState216 void init(int caret, int token, int zoom) 217 { 218 caretStart = caret; 219 tokenStart = token; 220 editorZoom = zoom; 221 } 222 223 int caretStart; 224 int tokenStart; 225 int editorZoom; 226 }; 227 228 LastACLaunchState m_LastACLaunchState; 229 230 /** Cached autocomplete list. 231 * It is the data CCManager uses to populate the (wx)scintilla autocomplete list window 232 */ 233 std::vector<cbCodeCompletionPlugin::CCToken> m_AutocompTokens; 234 }; 235 236 #endif // CCMANAGER_H 237