~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/plugins/contrib/BrowseTracker/BrowseTracker.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        This file is part of Browse Tracker, a plugin for Code::Blocks
 
3
        Copyright (C) 2007 Pecan Heber
 
4
 
 
5
        This program is free software; you can redistribute it and/or
 
6
        modify it under the terms of the GNU General Public License
 
7
        as published by the Free Software Foundation; either version 2
 
8
        of the License, or (at your option) any later version.
 
9
 
 
10
        This program is distributed in the hope that it will be useful,
 
11
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
        GNU General Public License for more details.
 
14
 
 
15
        You should have received a copy of the GNU General Public License
 
16
        along with this program; if not, write to the Free Software
 
17
        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
18
*/
 
19
// RCS-ID: $Id: BrowseTracker.cpp 47 2008-01-12 20:18:59Z Pecan $
 
20
 
 
21
// Notes:
 
22
//      There is no way to know when a project is loading. So we have to accept
 
23
//      editors that are activated during the loading process, then remove them
 
24
//      after the loading finishes.
 
25
//      Trying to use OnProjectLoadingHook did not work because it is not called
 
26
//      if the project xml file has no "extensions" entry.
 
27
//
 
28
//      cbProject::IsLoading/IsLoadingProject is actually turned OFF while editor
 
29
//      loading takes place. Very wierd.
 
30
//
 
31
//  OnProjectOpened
 
32
//      Remove loaded editors from our array that the user did not activate.
 
33
//      Open the layout file and build an array of old BrowseMarks.
 
34
//      These will be used on the first activation of an editor.
 
35
//  OnProjectActivated
 
36
//      Compress the arrays of pointers so we have more usable slots.
 
37
//  OnEditorActivated
 
38
//      If we've never seen this editor before, build containers to hold
 
39
//      the mouse click (BrowseMarks) locations.
 
40
//      Copy the archived layout BrowseMarks to an active BrowseMarks container
 
41
//      and have scintilla mark the lines with a "..." icon.
 
42
//  OnEditorOpened
 
43
//      Add the editor pointer to an array of active editors.
 
44
//      Set pointers that track "active" editors & projects.
 
45
//  OnEditorClosed
 
46
//      Copy the editor BrowseMarks back to the BrowseMark archive so we can
 
47
//      use them if the user reopens this editor.
 
48
//      Clear this editor out of our containers and arrays. (Except the archive)
 
49
//  OnStartShutdown/OnRelease
 
50
//      This happens before the editors are actually closed.
 
51
//      We simulate closing the editors to force the current Markers into
 
52
//      the ProjectData archive markers. Then write a layout
 
53
//      file containing the BrowseMarks for each open file.
 
54
//      Free the ProjectData container for the current project
 
55
//  Containers
 
56
//      EbBrowse_MarksHash:      EditorBase*, BrowseMarks*
 
57
//      EdBook_MarksHash:        EditorBase*, BrowseMarks*
 
58
//      ProjectDataHash:         cbProject*,  ProjectData*
 
59
//      ArrayOfEditorBasePtrs:   EditorBase*'s of user activated editors
 
60
//      FileBrowse_MarksArchive: EditorBase*, Book_Marks* of archived bookmarks
 
61
//                               (layout BrowseMarks, closed editor BrowseMarks etc)
 
62
//      FileBook_MarksArchive:   filePath, BrowseMarks*
 
63
//      BrowseMarks              wxArray containing editor cursor locations
 
64
 
 
65
 
 
66
#if defined(CB_PRECOMP)
 
67
#include "sdk.h"
 
68
#else
 
69
    #include "sdk_common.h"
 
70
        #include "sdk_events.h"
 
71
        #include "manager.h"
 
72
        #include "editormanager.h"
 
73
        #include "editorbase.h"
 
74
        #include "cbeditor.h"
 
75
        #include "projectmanager.h"
 
76
        #include "cbproject.h"
 
77
#endif
 
78
#include "projectloader_hooks.h"
 
79
 
 
80
    #include <wx/dynarray.h> //for wxArray and wxSortedArray
 
81
    #include <cbstyledtextctrl.h>
 
82
    #include <editor_hooks.h>
 
83
    #include "personalitymanager.h"
 
84
        #include <wx/stdpaths.h>
 
85
        #include <wx/app.h>
 
86
        #include <wx/menu.h>
 
87
        #include <wx/xrc/xmlres.h>
 
88
 
 
89
//-#include "wx/wxFlatNotebook/wxFlatNotebook.h"
 
90
#include "Version.h"
 
91
#include "BrowseTracker.h"
 
92
#include "BrowseSelector.h"
 
93
#include "BrowseMarks.h"
 
94
#include "BrowseTrackerDefs.h"
 
95
#include "ProjectData.h"
 
96
#include "BrowseTrackerCfg.h"
 
97
//#define BROWSETRACKER_MARKER        9
 
98
//#define BROWSETRACKER_MARKER_STYLE  wxSCI_MARK_DOTDOTDOT
 
99
// ----------------------------------------------------------------------------
 
100
//  Globals
 
101
// ----------------------------------------------------------------------------
 
102
        int     gBrowse_MarkerId;       //scintilla marker id
 
103
        int     gBrowse_MarkerStyle;    //scintialla marker style
 
104
        int     GetBrowseMarkerId(){return gBrowse_MarkerId;}
 
105
        int     GetBrowseMarkerStyle(){return gBrowse_MarkerStyle;}
 
106
 
 
107
// ----------------------------------------------------------------------------
 
108
namespace
 
109
// ----------------------------------------------------------------------------
 
110
{
 
111
    // Register the plugin
 
112
    PluginRegistrant<BrowseTracker> reg(_T("BrowseTracker"));
 
113
 
 
114
    int idMenuViewTracker           = wxNewId();
 
115
    int idMenuTrackerforward        = wxNewId();
 
116
    int idMenuTrackerBackward       = wxNewId();
 
117
    int idMenuTrackerClear          = wxNewId();
 
118
    int idMenuBrowseMarkPrevious    = wxNewId();
 
119
    int idMenuBrowseMarkNext        = wxNewId();
 
120
    int idMenuRecordBrowseMark      = wxNewId();
 
121
    int idMenuClearBrowseMark       = wxNewId();
 
122
    int idMenuClearAllBrowse_Marks  = wxNewId();
 
123
    int idMenuSortBrowse_Marks      = wxNewId();
 
124
    int idMenuConfigBrowse_Marks    = wxNewId();
 
125
    #ifdef LOGGING
 
126
    int idMenuTrackerDump           = wxNewId();
 
127
    #endif
 
128
    int idEditBookmarksToggle = XRCID("idEditBookmarksToggle");
 
129
};
 
130
 
 
131
// ----------------------------------------------------------------------------
 
132
// Event hooks
 
133
// ----------------------------------------------------------------------------
 
134
BEGIN_EVENT_TABLE(BrowseTracker, cbPlugin)
 
135
 
 
136
        //-EVT_UPDATE_UI(idMenuViewTracker, BrowseTracker::OnUpdateUI)
 
137
    EVT_IDLE(                BrowseTracker::OnIdle)
 
138
        // --
 
139
        // The following replaced by OnMenuTrackerSelect() dialog popup
 
140
        //EVT_MENU(     idMenuTrackerBackward,  BrowseTracker::OnMenuTrackBackward)
 
141
        //EVT_MENU(     idMenuTrackerforward,  BrowseTracker::OnMenuTrackforward)
 
142
 
 
143
        EVT_MENU(     idMenuTrackerBackward,    BrowseTracker::OnMenuTrackerSelect)
 
144
        EVT_MENU(     idMenuTrackerforward,     BrowseTracker::OnMenuTrackerSelect)
 
145
        EVT_MENU(     idMenuTrackerClear,       BrowseTracker::OnMenuTrackerClear)
 
146
        EVT_MENU(     idMenuBrowseMarkPrevious, BrowseTracker::OnMenuBrowseMarkPrevious)
 
147
        EVT_MENU(     idMenuBrowseMarkNext,     BrowseTracker::OnMenuBrowseMarkNext)
 
148
        EVT_MENU(     idMenuRecordBrowseMark,   BrowseTracker::OnMenuRecordBrowseMark)
 
149
        EVT_MENU(     idMenuClearBrowseMark,    BrowseTracker::OnMenuClearBrowseMark)
 
150
        EVT_MENU(     idMenuClearAllBrowse_Marks,BrowseTracker::OnMenuClearAllBrowse_Marks)
 
151
        EVT_MENU(     idMenuSortBrowse_Marks,    BrowseTracker::OnMenuSortBrowse_Marks)
 
152
        EVT_MENU(     idMenuConfigBrowse_Marks,  BrowseTracker::OnMenuConfigBrowse_Marks)
 
153
   #ifdef LOGGING
 
154
        EVT_MENU(     idMenuTrackerDump,        BrowseTracker::OnMenuTrackerDump)
 
155
   #endif
 
156
   // -- BOOK Marks --
 
157
    EVT_MENU(idEditBookmarksToggle, BrowseTracker::OnBook_MarksToggle)
 
158
    // --
 
159
    //-EVT_FLATNOTEBOOK_PAGE_CHANGED(ID_NBEditorManager, BrowseTracker::OnPageChanged)
 
160
END_EVENT_TABLE()
 
161
 
 
162
// ----------------------------------------------------------------------------
 
163
BrowseTracker::BrowseTracker()
 
164
// ----------------------------------------------------------------------------
 
165
{
 
166
    //ctor
 
167
    //-m_nCurrentEditorIndex = 0;
 
168
    m_CurrEditorIndex = 0;
 
169
    m_LastEditorIndex = 0;
 
170
    m_bProjectIsLoading = false;
 
171
        m_UpdateUIFocusEditor = false;
 
172
    m_nRemoveEditorSentry = 0;
 
173
    m_nBrowseMarkPreviousSentry = 0;
 
174
    m_nBrowseMarkNextSentry = 0;
 
175
    m_nBrowsedEditorCount = 0;
 
176
    //-m_pLoadingProject = 0;
 
177
 
 
178
    m_MouseDownTime = 0;
 
179
    m_ToggleKey = Left_Mouse;
 
180
    m_LeftMouseDelay = 200;
 
181
    m_ClearAllKey = ClearAllOnSingleClick;
 
182
    m_IsMouseDoubleClick = false;
 
183
 
 
184
}
 
185
// ----------------------------------------------------------------------------
 
186
BrowseTracker::~BrowseTracker()
 
187
// ----------------------------------------------------------------------------
 
188
{
 
189
    //dtor
 
190
}
 
191
 
 
192
// ----------------------------------------------------------------------------
 
193
void BrowseTracker::OnAttach()
 
194
// ----------------------------------------------------------------------------
 
195
{
 
196
 
 
197
        m_InitDone = false;
 
198
        m_CurrEditorIndex = 0;
 
199
        m_LastEditorIndex = MaxEntries-1;
 
200
        m_apEditors.Alloc(MaxEntries);
 
201
        for (int i=0; i<MaxEntries ; ++i ) m_apEditors[i] = 0;
 
202
        m_nBrowsedEditorCount = 0;
 
203
        m_UpdateUIFocusEditor = false;
 
204
        m_nRemoveEditorSentry = 0;
 
205
    m_nBrowseMarkPreviousSentry = 0;
 
206
    m_nBrowseMarkNextSentry = 0;
 
207
    m_OnEditorEventHookIgnoreMarkerChanges = true; //used to avoid editor hook overhead
 
208
 
 
209
    //-m_pActiveCBProject = 0;
 
210
    //-m_pActiveProjectData = 0;
 
211
    //-m_pLoadingProject = 0;
 
212
    m_LoadingProjectFilename = wxT("");
 
213
    m_pEdMgr = Manager::Get()->GetEditorManager();
 
214
    m_pPrjMgr = Manager::Get()->GetProjectManager();
 
215
 
 
216
    // initialize version and logging
 
217
    m_pAppWin  = Manager::Get()->GetAppWindow();
 
218
    m_pMenuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
 
219
 
 
220
    AppVersion pgmVersion;
 
221
    m_AppName = wxT("BrowseTracker");
 
222
 
 
223
    #if LOGGING
 
224
     wxLog::EnableLogging(true);
 
225
     m_pLog = new wxLogWindow( m_pAppWin, _T(" BrowseTracker Plugin"),true,false);
 
226
     wxLog::SetActiveTarget( m_pLog);
 
227
     m_pLog->GetFrame()->SetSize(20,30,600,300);
 
228
     LOGIT( _T("BrowseTracker Plugin Logging Started[%s]"),pgmVersion.GetVersion().c_str());
 
229
     m_pLog->Flush();
 
230
    #endif
 
231
 
 
232
    // Set current plugin version
 
233
        PluginInfo* pInfo = (PluginInfo*)(Manager::Get()->GetPluginManager()->GetPluginInfo(this));
 
234
        pInfo->version = pgmVersion.GetVersion();
 
235
 
 
236
    // ---------------------------------------
 
237
    // determine location of settings
 
238
    // ---------------------------------------
 
239
    wxStandardPaths stdPaths;
 
240
    // memorize the key file name as {%HOME%}\codesnippets.ini
 
241
    m_ConfigFolder = stdPaths.GetUserDataDir();
 
242
    #if defined(LOGGING)
 
243
     LOGIT( _T("Argv[0][%s] Cwd[%s]"), wxTheApp->argv[0], ::wxGetCwd().GetData() );
 
244
    #endif
 
245
    m_ExecuteFolder = FindAppPath(wxTheApp->argv[0], ::wxGetCwd(), wxEmptyString);
 
246
 
 
247
    //GTK GetConfigFolder is returning double "//?, eg, "/home/pecan//.codeblocks"
 
248
    // remove the double //s from filename //+v0.4.11
 
249
    m_ConfigFolder.Replace(_T("//"),_T("/"));
 
250
    m_ExecuteFolder.Replace(_T("//"),_T("/"));
 
251
    #if defined(LOGGING)
 
252
        LOGIT(wxT("CfgFolder[%s]"),m_ConfigFolder.c_str());
 
253
        LOGIT(wxT("ExecFolder[%s]"),m_ExecuteFolder.c_str());
 
254
    #endif
 
255
 
 
256
    // get the CodeBlocks "personality" argument
 
257
    wxString m_Personality = Manager::Get()->GetPersonalityManager()->GetPersonality();
 
258
        if (m_Personality == wxT("default")) m_Personality = wxEmptyString;
 
259
 
 
260
    // if codesnippets.ini is in the executable folder, use it
 
261
    // else use the default config folder
 
262
    m_CfgFilenameStr = m_ExecuteFolder + wxFILE_SEP_PATH;
 
263
    if (not m_Personality.IsEmpty()) m_CfgFilenameStr << m_Personality + wxT(".") ;
 
264
    m_CfgFilenameStr << m_AppName + _T(".ini");
 
265
 
 
266
    if (::wxFileExists(m_CfgFilenameStr)) {;/*OK Use exe path*/}
 
267
    else // use the default.conf folder
 
268
    {   m_CfgFilenameStr = m_ConfigFolder + wxFILE_SEP_PATH;
 
269
        if (not m_Personality.IsEmpty()) m_CfgFilenameStr <<  m_Personality + wxT(".") ;
 
270
        m_CfgFilenameStr << m_AppName + _T(".ini");
 
271
        // if default doesn't exist, create it
 
272
        if (not ::wxDirExists(m_ConfigFolder))
 
273
            ::wxMkdir(m_ConfigFolder);
 
274
    }
 
275
    // ---------------------------------------
 
276
    // Initialize Globals
 
277
    // ---------------------------------------
 
278
    TrackerCfgFullPath = m_CfgFilenameStr;
 
279
    #if defined(LOGGING)
 
280
     LOGIT( _T("TrackerCfgFullPath[%s]"),TrackerCfgFullPath.c_str() );
 
281
    #endif
 
282
 
 
283
    // SettingLoad() of user options;
 
284
    BrowseTrackerCfg btCfg;
 
285
    btCfg.ReadUserOptions(m_CfgFilenameStr);
 
286
    m_BrowseMarksEnabled = btCfg.m_BrowseMarksEnabled;
 
287
    m_UserMarksStyle    = btCfg.m_UserMarksStyle;
 
288
    m_ToggleKey         = btCfg.m_ToggleKey;
 
289
    m_LeftMouseDelay    = btCfg.m_LeftMouseDelay;
 
290
    m_ClearAllKey       = btCfg.m_ClearAllKey;
 
291
 
 
292
    switch(m_UserMarksStyle)
 
293
    {
 
294
        case BrowseMarksStyle:
 
295
        {
 
296
            gBrowse_MarkerId = BROWSETRACKER_MARKER ;
 
297
            gBrowse_MarkerStyle  = BROWSETRACKER_MARKER_STYLE;
 
298
            break;
 
299
        }
 
300
        case BookMarksStyle:
 
301
        {
 
302
            gBrowse_MarkerId = BOOKMARK_MARKER;
 
303
            gBrowse_MarkerStyle  = BOOKMARK_STYLE;
 
304
            break;
 
305
        }
 
306
        case HiddenMarksStyle:
 
307
        {
 
308
            gBrowse_MarkerId = BROWSETRACKER_MARKER;
 
309
            gBrowse_MarkerStyle  = BROWSETRACKER_HIDDEN_STYLE;
 
310
            break;
 
311
        }
 
312
    }//switch
 
313
 
 
314
        // Hook to plugin events
 
315
 
 
316
    // EVT_APP_START_SHUTDOWN(  BrowseTracker::OnRelease)
 
317
    Manager::Get()->RegisterEventSink(cbEVT_APP_START_SHUTDOWN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnStartShutdown));
 
318
 
 
319
    // -- Editor Events
 
320
    // EVT_EDITOR_ACTIVATED(   BrowseTracker::OnEditorActivated)
 
321
    Manager::Get()->RegisterEventSink(cbEVT_EDITOR_ACTIVATED, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorActivated));
 
322
    // EVT_EDITOR_DEACTIVATED(   BrowseTracker::OnEditorActivated)
 
323
    //-Manager::Get()->RegisterEventSink(cbEVT_EDITOR_DEACTIVATED, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorDeactivated));
 
324
    // EVT_EDITOR_CLOSE(       BrowseTracker::OnEditorClosed)
 
325
    Manager::Get()->RegisterEventSink(cbEVT_EDITOR_CLOSE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorClosed));
 
326
    // EVT_EDITOR_OPEN(       BrowseTracker::OnEditorOpen)
 
327
    Manager::Get()->RegisterEventSink(cbEVT_EDITOR_OPEN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorOpened));
 
328
 
 
329
    // -- Project events
 
330
    // EVT_PROJECT_OPEN(       BrowseTracker::OnProjectOpened)
 
331
    Manager::Get()->RegisterEventSink(cbEVT_PROJECT_OPEN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectOpened));
 
332
    // EVT_PROJECT_CLOSE(       BrowseTracker::OnProjectOpened)
 
333
    Manager::Get()->RegisterEventSink(cbEVT_PROJECT_CLOSE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectClosing));
 
334
 
 
335
    // EVT_PROJECT_ACTIVATE(   BrowseTracker::OnProjectActivated)
 
336
    Manager::Get()->RegisterEventSink(cbEVT_PROJECT_ACTIVATE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectActivatedEvent));
 
337
 
 
338
    // hook to project loading procedure
 
339
    // This hook only occurs if the project has an "extension" xml entry
 
340
    ProjectLoaderHooks::HookFunctorBase* myProjhook = new ProjectLoaderHooks::HookFunctor<BrowseTracker>(this, &BrowseTracker::OnProjectLoadingHook);
 
341
    m_ProjectHookId = ProjectLoaderHooks::RegisterHook(myProjhook);
 
342
 
 
343
    // hook to editors
 
344
    EditorHooks::HookFunctorBase* myEdhook = new EditorHooks::HookFunctor<BrowseTracker>(this, &BrowseTracker::OnEditorEventHook);
 
345
    m_EditorHookId = EditorHooks::RegisterHook(myEdhook);
 
346
 
 
347
}//OnAttach
 
348
 
 
349
// ----------------------------------------------------------------------------
 
350
void BrowseTracker::OnRelease(bool appShutDown)
 
351
// ----------------------------------------------------------------------------
 
352
{
 
353
    // ------------------------------------------------------------
 
354
    // watch out, CodeBlocks can enter this routine multiple times
 
355
    // ------------------------------------------------------------
 
356
 
 
357
    if ( m_InitDone )
 
358
    {
 
359
        //*SDK Gotcha* A cbEVT_PROJECT_CLOSE is issued, but only
 
360
        // after the plugin OnRelease() is called. So we
 
361
        // simulate closing all open projects in order to save
 
362
        // current Browse/Book marks in layout
 
363
        ProjectsArray* pPrjs = m_pPrjMgr->GetProjects();
 
364
        for (size_t i=0; i<pPrjs->GetCount(); ++i )
 
365
        {
 
366
            CodeBlocksEvent evtpa(cbEVT_PROJECT_ACTIVATE);
 
367
            evtpa.SetProject(pPrjs->Item(i));
 
368
            OnProjectActivatedEvent(evtpa);
 
369
 
 
370
            CodeBlocksEvent evtpc(cbEVT_PROJECT_CLOSE);
 
371
            evtpc.SetProject(pPrjs->Item(i));
 
372
            OnProjectClosing(evtpc);
 
373
        }
 
374
 
 
375
        // remove project load/save hook
 
376
        ProjectLoaderHooks::UnregisterHook(m_ProjectHookId, true);
 
377
 
 
378
        // remove editor/scintilla hook
 
379
        EditorHooks::UnregisterHook(m_EditorHookId, true);
 
380
 
 
381
        //  Remove menu item
 
382
        int idx = m_pMenuBar->FindMenu(_("View"));
 
383
        if (idx != wxNOT_FOUND)
 
384
        {
 
385
            wxMenu* viewMenu = m_pMenuBar->GetMenu(idx);
 
386
            viewMenu->Destroy(idMenuViewTracker);
 
387
        }
 
388
 
 
389
        // *Book_Marks* release the editor hash table ptrs to Book_Marks
 
390
        for (EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.begin(); it != m_EdBook_MarksHash.end(); ++it)
 
391
        {
 
392
            delete it->second;
 
393
        }
 
394
        m_EdBook_MarksHash.clear();
 
395
 
 
396
        // *BrowseMarks* release the editor hash table ptrs to BrowseMarks
 
397
        for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); ++it)
 
398
        {
 
399
            delete it->second;
 
400
        }
 
401
        m_EbBrowse_MarksHash.clear();
 
402
 
 
403
        // *ProjectData* release any ProjectData remaining in the ProjectDataHash
 
404
        for (ProjectDataHash::iterator it = m_ProjectDataHash.begin(); it != m_ProjectDataHash.end(); ++it)
 
405
        {
 
406
            delete it->second;
 
407
        }
 
408
        m_ProjectDataHash.clear();
 
409
 
 
410
    }
 
411
        m_InitDone = false;
 
412
}
 
413
// ----------------------------------------------------------------------------
 
414
void BrowseTracker::BuildMenu(wxMenuBar* menuBar)
 
415
// ----------------------------------------------------------------------------
 
416
{
 
417
    m_pMenuBar = menuBar;
 
418
 
 
419
        int idx = menuBar->FindMenu(_("View"));
 
420
        if (idx != wxNOT_FOUND)
 
421
        {
 
422
                wxMenu* viewMenu = menuBar->GetMenu(idx);
 
423
 
 
424
            wxMenu* pforwardBackwardSubMenu = new wxMenu(wxT(""));
 
425
        pforwardBackwardSubMenu->Append(idMenuTrackerBackward, _("Backward Ed\tAlt-Left"), _("Browse Backward"));
 
426
        pforwardBackwardSubMenu->Append(idMenuTrackerforward, _("Forward Ed\tAlt-Right"), _("Browse forward"));
 
427
        pforwardBackwardSubMenu->Append(idMenuBrowseMarkPrevious, _("Prev Mark\tAlt-Up"), _("Browse Up"));
 
428
        pforwardBackwardSubMenu->Append(idMenuBrowseMarkNext, _("Next Mark\tAlt-Down"), _("Browse Down"));
 
429
        pforwardBackwardSubMenu->AppendSeparator();
 
430
        pforwardBackwardSubMenu->Append(idMenuRecordBrowseMark, _("Set BrowseMark"), _("Record Browse Mark"));
 
431
        pforwardBackwardSubMenu->Append(idMenuClearBrowseMark,  _("Clear BrowseMark"), _("Unset Browse Mark"));
 
432
        pforwardBackwardSubMenu->Append(idMenuSortBrowse_Marks,  _("Sort BrowseMarks"), _("Sort Browse Marks"));
 
433
        pforwardBackwardSubMenu->Append(idMenuClearAllBrowse_Marks,  _("Clear All BrowseMarks"), _("Unset All Browse Marks"));
 
434
        pforwardBackwardSubMenu->AppendSeparator();
 
435
        pforwardBackwardSubMenu->Append(idMenuTrackerClear,     _("Clear All"), _("Clear History"));
 
436
        pforwardBackwardSubMenu->Append(idMenuConfigBrowse_Marks,     _("Settings"), _("Configure"));
 
437
       #ifdef LOGGING
 
438
        pforwardBackwardSubMenu->Append(idMenuTrackerDump, _("Dump Arrays"), _("Dump Arrays"));
 
439
       #endif
 
440
        viewMenu->Append(idMenuViewTracker, _("Browse Tracker"), pforwardBackwardSubMenu , _("Browse Tracker"));
 
441
 
 
442
        }
 
443
    #if defined(LOGGING)
 
444
     LOGIT(wxT("Menubar[%p]idMenuViewTracker[%d]"),menuBar, idMenuViewTracker);
 
445
    #endif
 
446
 
 
447
        m_InitDone = true;
 
448
}
 
449
// ----------------------------------------------------------------------------
 
450
void BrowseTracker::BuildModuleMenu(const ModuleType type, wxMenu* popup, const FileTreeData* data)
 
451
// ----------------------------------------------------------------------------
 
452
{
 
453
        //Some library module is ready to display a pop-up menu.
 
454
        //Check the parameter \"type\" and see which module it is
 
455
        //and append any items you need in the menu...
 
456
        //TIP: for consistency, add a separator as the first item...
 
457
 
 
458
    if (not IsAttached() ) return;
 
459
    if (type != mtEditorManager) return;
 
460
 
 
461
    // obtain ptr to menus menu
 
462
    wxMenuBar* pMenuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
 
463
    wxMenu* pbtMenu = 0;
 
464
    // Ask for the submenu containing the first BrowseTracker menu item
 
465
    wxMenuItem* pbtMenuItem = pMenuBar->FindItem(idMenuTrackerforward, &pbtMenu);
 
466
    if (not pbtMenuItem) return;
 
467
 
 
468
    // Reproduce the BrowseTracker menu onto a Context Menu sub_menu
 
469
    int knt = pbtMenu->GetMenuItemCount();
 
470
    if (not knt) return;
 
471
 
 
472
    wxMenu* sub_menu = new wxMenu;
 
473
    // search the BrowseTracker main menu, duplicating each macro item
 
474
    // on to a context menu sub-menu without the command keys.
 
475
    for (int i=0; i<knt; ++i)
 
476
    {
 
477
        wxMenuItem* item = pbtMenu->FindItemByPosition(i);
 
478
        int menuId = item->GetId();
 
479
        wxString menuLabel = item->GetLabel();
 
480
        ///LOGIT( _T("OnContextMenu insert[%s]"),menuLabel.c_str() );
 
481
        wxMenuItem* pContextItem= new wxMenuItem(0, menuId, menuLabel);
 
482
        sub_menu->Append( pContextItem );
 
483
    }
 
484
    popup->AppendSeparator();
 
485
    pbtMenuItem = new wxMenuItem(0, wxID_ANY, _("Browse Tracker"), _T(""), wxITEM_NORMAL);
 
486
    pbtMenuItem->SetSubMenu(sub_menu);
 
487
    popup->Append(pbtMenuItem);
 
488
 
 
489
}//BuildModuleMenu
 
490
// ----------------------------------------------------------------------------
 
491
wxString BrowseTracker::GetPageFilename(int index)
 
492
// ----------------------------------------------------------------------------
 
493
{
 
494
    // Load BrowseTracker XML history file for this project
 
495
    wxString filename = wxEmptyString;
 
496
    EditorBase* eb = GetEditor(index);
 
497
    if (not eb) return filename;
 
498
 
 
499
    EditorManager* EdMgr = Manager::Get()->GetEditorManager();
 
500
 
 
501
    if (-1 == EdMgr->FindPageFromEditor(eb) )
 
502
    {   // this entry has been closed behind our backs
 
503
 
 
504
        ///#if defined(LOGGING)
 
505
        /// LOGIT( _T("GetEditorFilename Removing ed[%p]"), GetEditor(index) );
 
506
        ///#endif
 
507
        RemoveEditor( GetEditor(index) );
 
508
        return filename;
 
509
    }
 
510
    filename = eb->GetShortName();
 
511
    return filename;
 
512
}
 
513
// ----------------------------------------------------------------------------
 
514
wxString BrowseTracker::GetPageFilename(EditorBase* eb)
 
515
// ----------------------------------------------------------------------------
 
516
{
 
517
    // Ask Notebook for short file name of EditorBase.
 
518
    // If no page returned, file is not open
 
519
 
 
520
    wxString filename = wxEmptyString;
 
521
    if (not eb) return filename;
 
522
 
 
523
    if (-1 == Manager::Get()->GetEditorManager()->FindPageFromEditor(eb) )
 
524
    {   // this entry has been closed behind our backs
 
525
        return filename;
 
526
    }
 
527
 
 
528
    filename = eb->GetShortName();
 
529
    return filename;
 
530
}
 
531
// ----------------------------------------------------------------------------
 
532
int BrowseTracker::GetEditor(EditorBase* eb)
 
533
// ----------------------------------------------------------------------------
 
534
{
 
535
    // return the editor index from our array of user activated editos
 
536
    for (int i=0; i<MaxEntries; ++i )
 
537
        if ( m_apEditors[i] == eb ) return i;
 
538
    return -1;
 
539
}
 
540
// ----------------------------------------------------------------------------
 
541
EditorBase* BrowseTracker::GetEditor(int index)
 
542
// ----------------------------------------------------------------------------
 
543
{
 
544
    // return the EditorBase* from our array of user activated editors
 
545
    return m_apEditors[index];
 
546
}
 
547
// ----------------------------------------------------------------------------
 
548
EditorBase* BrowseTracker::GetCurrentEditor()
 
549
// ----------------------------------------------------------------------------
 
550
{
 
551
    // return the EditorBase* of the currently activated editor
 
552
    return GetEditor(m_CurrEditorIndex);
 
553
}
 
554
// ----------------------------------------------------------------------------
 
555
int BrowseTracker::GetCurrentEditorIndex()
 
556
// ----------------------------------------------------------------------------
 
557
{
 
558
    // return the index of the currently activated editor
 
559
    if ( GetEditorBrowsedCount() )
 
560
        return m_CurrEditorIndex;
 
561
    return -1;
 
562
}
 
563
// ----------------------------------------------------------------------------
 
564
EditorBase* BrowseTracker::GetPreviousEditor()
 
565
// ----------------------------------------------------------------------------
 
566
{
 
567
    // return the EditorBase* of the previoiusly user activated editor
 
568
    EditorBase* p = 0;
 
569
    int index = m_CurrEditorIndex;
 
570
    for (int i = 0; i<MaxEntries; ++i)
 
571
    {
 
572
        --index;
 
573
        if (index < 0) index = MaxEntries-1;
 
574
        p = GetEditor(index);
 
575
        if ( p != 0 ) break;
 
576
    }
 
577
    return p;
 
578
}
 
579
// ----------------------------------------------------------------------------
 
580
int BrowseTracker::GetEditorBrowsedCount()
 
581
// ----------------------------------------------------------------------------
 
582
{
 
583
    #if defined(LOGGING)
 
584
    ///LOGIT( _T("GetEditorBrowsedCount()[%d]"), m_nBrowsedEditorCount );
 
585
    #endif
 
586
    return m_nBrowsedEditorCount;
 
587
}
 
588
// ----------------------------------------------------------------------------
 
589
int BrowseTracker::GetPreviousEditorIndex()
 
590
// ----------------------------------------------------------------------------
 
591
{
 
592
    // return the index of the previously user activated editor
 
593
 
 
594
    EditorBase* eb = 0;
 
595
    int index = m_CurrEditorIndex;
 
596
    // scan for previous editor, skipping nulls (null is a closed editors)
 
597
    for (int i=0; i<MaxEntries; ++i)
 
598
    {
 
599
        --index;
 
600
        if ( index < 0 ) index = MaxEntries-1;
 
601
        eb = GetEditor(index);
 
602
        if ( eb ) break;
 
603
    }//for
 
604
 
 
605
    #if defined(LOGGING)
 
606
    /// LOGIT( _T("GetPreviousEditorIndex[%d][%p][%s]"), index, eb, eb?eb->GetShortName().c_str():wxEmptyString );
 
607
    #endif
 
608
    if ( not eb) index = -1;
 
609
    return index;
 
610
}
 
611
// ----------------------------------------------------------------------------
 
612
void BrowseTracker::SetSelection(int index)
 
613
// ----------------------------------------------------------------------------
 
614
{
 
615
    // user has selected an editor, make it active
 
616
 
 
617
    if ((index < 0) || (index >= MaxEntries )) return;
 
618
 
 
619
    EditorBase* eb = GetEditor(index);
 
620
    if (eb)
 
621
    {
 
622
        //-int page = Manager::Get()->GetEditorManager()->FindPageFromEditor(eb);
 
623
        Manager::Get()->GetEditorManager()->SetActiveEditor(eb);
 
624
        #if defined(LOGGING)
 
625
        LOGIT( _T("SetSelection[%d] editor[%p][%s]"), index, eb, eb->GetShortName().c_str() );
 
626
        #endif
 
627
 
 
628
        // Tell OnIdle to focus the new editor. CB sdk editorManager::OnUpdateUI used to
 
629
        // do this for us, but someone broke it.
 
630
        m_UpdateUIFocusEditor = true;
 
631
    }
 
632
}
 
633
// ----------------------------------------------------------------------------
 
634
void BrowseTracker::OnMenuTrackerSelect(wxCommandEvent& event)
 
635
// ----------------------------------------------------------------------------
 
636
{
 
637
    // create a selection popup, allow user to choose an editor to activate
 
638
 
 
639
    if ( GetEditorBrowsedCount() == 0) return;
 
640
 
 
641
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
642
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
643
    if ((not eb) || (not cbed)) return;
 
644
 
 
645
    m_popupWin = new BrowseSelector( wxTheApp->GetTopWindow(), this, event.GetId() == idMenuTrackerforward );
 
646
    m_popupWin->ShowModal();
 
647
    m_popupWin->Destroy();
 
648
    m_popupWin = 0;
 
649
}
 
650
// ----------------------------------------------------------------------------
 
651
void BrowseTracker::OnMenuBrowseMarkPrevious(wxCommandEvent& event)
 
652
// ----------------------------------------------------------------------------
 
653
{
 
654
    // For cbEditors, position to previous memorized cursor position
 
655
 
 
656
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
657
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
658
    if (cbed) do
 
659
    {
 
660
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
661
        {
 
662
            GetCurrentScreenPositions();
 
663
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
664
            int newPos = EdBrowse_Marks.GetMarkCurrent();
 
665
                //#if defined(LOGGING)
 
666
                //LOGIT( _T("curPos[%d]m_CurrScrTopPosn[%d]m_CurrScrLastPosn[%d]"),
 
667
                //    newPos, m_CurrScrTopPosn, m_CurrScrLastPosn);
 
668
                //#endif
 
669
 
 
670
            // if current browse mark is off screen, go to "current", not "pevious"
 
671
            if ( ((newPos < m_CurrScrTopPosn) || (newPos > m_CurrScrLastPosn))
 
672
                && (newPos != -1) )
 
673
                /*use current mark*/;
 
674
            else newPos = EdBrowse_Marks.GetMarkPrevious();
 
675
            if (newPos == -1) break;
 
676
 
 
677
            cbStyledTextCtrl* control = cbed->GetControl();
 
678
            int line = control->LineFromPosition(newPos);
 
679
            if ( LineHasBrowseMarker(control, line) )
 
680
            {   // center the BrowseMark line if off screen
 
681
                if ( (line < m_CurrScrTopLine) || (line > m_CurrScrLastLine ))
 
682
                    cbed->GotoLine(line, true);    // gotoline centers the line on the screen
 
683
                control->GotoPos(newPos);          // gotopos puts cursor at correct offset
 
684
                GetCurrentScreenPositions();
 
685
                #if defined(LOGGING)
 
686
                ///LOGIT( _T("OnMenuBrowseMarkPrev: pos[%d]line[%d]eb[%p][%s]"),
 
687
                ///    newPos, control->LineFromPosition(newPos), eb, eb->GetShortName().c_str() );
 
688
                #endif
 
689
            }//if
 
690
            else
 
691
            {
 
692
                // rebuild and retry, but guard against any possible loop
 
693
                if ( m_nBrowseMarkPreviousSentry++ ) break;
 
694
                EdBrowse_Marks.ImportBrowse_Marks(); // Browse marks out of sync
 
695
                OnMenuBrowseMarkPrevious( event ); //retry
 
696
            }
 
697
        }//if
 
698
    }while(0);//if do
 
699
 
 
700
    m_nBrowseMarkPreviousSentry = 0;
 
701
 
 
702
}//OnMenuBrowseMarkPrevious
 
703
// ----------------------------------------------------------------------------
 
704
void BrowseTracker::OnMenuBrowseMarkNext(wxCommandEvent& event)
 
705
// ----------------------------------------------------------------------------
 
706
{
 
707
    // For cbEditors, position to next memorized cursor position
 
708
 
 
709
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
710
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
711
    if (cbed) do
 
712
    {
 
713
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
714
        {
 
715
            GetCurrentScreenPositions();
 
716
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
717
            int newPos = EdBrowse_Marks.GetMarkCurrent();
 
718
            // if current browse mark is off screen, go to "current", not "next"
 
719
            if ( ((newPos < m_CurrScrTopPosn) || (newPos > m_CurrScrLastPosn))
 
720
                && (newPos != -1) )
 
721
                /*use current mark*/;
 
722
            else newPos = EdBrowse_Marks.GetMarkNext();
 
723
            if (newPos == -1) break;
 
724
 
 
725
            cbStyledTextCtrl* control = cbed->GetControl();
 
726
            int line = control->LineFromPosition(newPos);
 
727
            if ( LineHasBrowseMarker(control, line) )
 
728
            {   // center the BrowseMark line if off screen
 
729
                if ( (line < m_CurrScrTopLine)  || (line > m_CurrScrLastLine) )
 
730
                    cbed->GotoLine(line, true);    // gotoline centers the line on the screen
 
731
                control->GotoPos(newPos);          // gotopos puts cursor at correct offset
 
732
                GetCurrentScreenPositions();
 
733
                #if defined(LOGGING)
 
734
                ///LOGIT( _T("OnMenuBrowseMarkNext: pos[%d]line[%d]eb[%p][%s]"),
 
735
                ///    newPos, control->LineFromPosition(newPos), eb, eb->GetShortName().c_str() );
 
736
                #endif
 
737
            }
 
738
            else
 
739
            {
 
740
                // rebuild, but guard against any possible loop
 
741
                if ( m_nBrowseMarkNextSentry++ ) break;
 
742
                EdBrowse_Marks.ImportBrowse_Marks(); // Browse marks out of sync
 
743
                OnMenuBrowseMarkNext( event ); // retry
 
744
            }
 
745
        }//if
 
746
    }while(0);//if do
 
747
 
 
748
    m_nBrowseMarkNextSentry = 0;
 
749
 
 
750
}//OnMenuBrowseMarkNext
 
751
// ----------------------------------------------------------------------------
 
752
void BrowseTracker::OnMenuRecordBrowseMark(wxCommandEvent& event)
 
753
// ----------------------------------------------------------------------------
 
754
{
 
755
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
756
    if (eb) RecordBrowseMark(eb);
 
757
}
 
758
// ----------------------------------------------------------------------------
 
759
void BrowseTracker::OnMenuClearBrowseMark(wxCommandEvent& event)
 
760
// ----------------------------------------------------------------------------
 
761
{
 
762
    //LOGIT( _T("ClearBrowseMark") );
 
763
    bool removeScreenMark = true;
 
764
    ClearLineBrowseMark(removeScreenMark);
 
765
    if ( GetBrowseMarkerId() == BOOKMARK_MARKER ) ClearLineBookMark();
 
766
}
 
767
// ----------------------------------------------------------------------------
 
768
void BrowseTracker::ClearLineBrowseMark(bool removeScreenMark)
 
769
// ----------------------------------------------------------------------------
 
770
{
 
771
    // clear BrowseMarks for a current line. If the line has no marker
 
772
    // clear All markers.
 
773
 
 
774
    ///LOGIT( _T("ClearBrowseMark") );
 
775
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
776
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
777
    if (cbed) do
 
778
    {
 
779
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
780
        {
 
781
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
782
            GetCurrentScreenPositions();
 
783
            EdBrowse_Marks.ClearMark( m_CurrScrLineStartPosn, m_CurrScrLineEndPosn);
 
784
            cbStyledTextCtrl* control = cbed->GetControl();
 
785
            int line = control->LineFromPosition(m_CurrScrLineStartPosn);
 
786
            if ( removeScreenMark )
 
787
                if ( LineHasBrowseMarker(control,line) )
 
788
                    MarkRemove(cbed->GetControl(), line);
 
789
            #if defined(LOGGING)
 
790
            LOGIT( _T("ClearLineBROWSEMark Current Line[%d]"),m_CurrScrLine );
 
791
            #endif
 
792
        }
 
793
    }while(0);
 
794
}
 
795
////// ----------------------------------------------------------------------------
 
796
////void BrowseTracker::ClearLineBrowseMark(int posn)
 
797
////// ----------------------------------------------------------------------------
 
798
////{
 
799
////    // clear BrowseMarks for a single line
 
800
////
 
801
////    ///LOGIT( _T("ClearBrowseMark") );
 
802
////    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
803
////    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
804
////    if (cbed) do
 
805
////    {
 
806
////        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
807
////        {
 
808
////            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
809
////            cbStyledTextCtrl* control = cbed->GetControl();
 
810
////            int line = control->LineFromPosition(posn);
 
811
////            int start = control->PositionFromLine( line );
 
812
////            int end   = start + control->LineLength( line );
 
813
////            EdBrowse_Marks.ClearMark( start, end );
 
814
////            if ( LineHasBrowseMarker(control,line) )
 
815
////                MarkRemove( control, line);
 
816
////            #if defined(LOGGING)
 
817
////            LOGIT( _T("ClearLineBrowse_MarksByPosn Line[%d]Posn[%d]"), line, posn );
 
818
////            #endif
 
819
////        }
 
820
////    }while(0);
 
821
////}
 
822
// ----------------------------------------------------------------------------
 
823
void BrowseTracker::SetBrowseMarksStyle( int userStyle)
 
824
// ----------------------------------------------------------------------------
 
825
{
 
826
    // BrowseMarks, BookMarks, or Hidden style
 
827
 
 
828
    BrowseMarks* pBrowse_Marks = 0;
 
829
    for (int i=0; i<MaxEntries ; ++i )
 
830
    {
 
831
        EditorBase* eb = GetEditor(i);
 
832
        if (eb) pBrowse_Marks = GetBrowse_MarksFromHash(  eb);
 
833
        if (eb && pBrowse_Marks) pBrowse_Marks->SetBrowseMarksStyle( userStyle);
 
834
    }//for
 
835
}
 
836
// ----------------------------------------------------------------------------
 
837
void BrowseTracker::OnMenuSortBrowse_Marks( wxCommandEvent& event)
 
838
// ----------------------------------------------------------------------------
 
839
{
 
840
    // sort the BrowseMarks by simply importing them from scintilla
 
841
 
 
842
    EditorBase* eb = GetCurrentEditor();
 
843
    BrowseMarks* pBrowse_Marks = GetBrowse_MarksFromHash(  eb);
 
844
    if (eb && pBrowse_Marks) pBrowse_Marks->ImportBrowse_Marks();
 
845
}
 
846
// ----------------------------------------------------------------------------
 
847
void BrowseTracker::OnMenuConfigBrowse_Marks( wxCommandEvent& event)
 
848
// ----------------------------------------------------------------------------
 
849
{
 
850
    // Show user options
 
851
 
 
852
    int  oldUserMarksStyle = m_UserMarksStyle;
 
853
    bool oldBrowseMarksEnabled = m_BrowseMarksEnabled;
 
854
    //invoke user options dialog
 
855
    BrowseTrackerCfg btCfg;
 
856
    btCfg.GetUserOptions( m_CfgFilenameStr );
 
857
 
 
858
    // reset options according to user responses
 
859
    m_BrowseMarksEnabled = btCfg.m_BrowseMarksEnabled;
 
860
    m_UserMarksStyle = btCfg.m_UserMarksStyle;
 
861
    m_ToggleKey = btCfg.m_ToggleKey;
 
862
    m_LeftMouseDelay = btCfg.m_LeftMouseDelay;
 
863
    m_ClearAllKey = btCfg.m_ClearAllKey;
 
864
 
 
865
    // Don't allow set and clear_all key to be the same
 
866
    while ( (m_ToggleKey == Ctrl_Left_Mouse) && (m_ClearAllKey == ClearAllOnSingleClick) )
 
867
    {   wxString msg;
 
868
        msg.Printf(_("Program cannot use CTRL-LEFT_MOUSE as both a \nToggle key *AND* a Clear-All-Key"));
 
869
        cbMessageBox(msg, _("Error"), wxICON_ERROR);
 
870
 
 
871
        m_ClearAllKey = ClearAllOnDoubleClick;
 
872
        btCfg.GetUserOptions( m_CfgFilenameStr );
 
873
 
 
874
        m_UserMarksStyle = btCfg.m_UserMarksStyle;
 
875
        m_ToggleKey = btCfg.m_ToggleKey;
 
876
        m_LeftMouseDelay = btCfg.m_LeftMouseDelay;
 
877
        m_ClearAllKey = btCfg.m_ClearAllKey;
 
878
    }
 
879
 
 
880
    // Don't allow set and clear all key to be the same
 
881
    if ( (m_ToggleKey == Ctrl_Left_Mouse) && (m_ClearAllKey == ClearAllOnSingleClick) )
 
882
        m_ClearAllKey = ClearAllOnDoubleClick;
 
883
 
 
884
        #if defined(LOGGING)
 
885
        LOGIT( _T("New Config values: BrowseMarksStyle[%d]ToggleKey[%d]MouseDelay[%d]ClearKey[%d]"),
 
886
            m_UserMarksStyle, m_ToggleKey, m_LeftMouseDelay, m_ClearAllKey);
 
887
        #endif
 
888
    if (oldUserMarksStyle not_eq m_UserMarksStyle)
 
889
        SetBrowseMarksStyle( m_UserMarksStyle );
 
890
 
 
891
    if (oldBrowseMarksEnabled not_eq m_BrowseMarksEnabled )
 
892
    {
 
893
        // Simulate activation of the current editor so mouse
 
894
        // events get connected.
 
895
        EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
 
896
        if ( eb )
 
897
        {
 
898
            CodeBlocksEvent evt;
 
899
            evt.SetEditor(eb);
 
900
            OnEditorActivated(evt);
 
901
        }
 
902
    }
 
903
}
 
904
// ----------------------------------------------------------------------------
 
905
void BrowseTracker::OnMenuClearAllBrowse_Marks(wxCommandEvent& event)
 
906
// ----------------------------------------------------------------------------
 
907
{
 
908
    ClearAllBrowse_Marks(/*clearScreenMarks*/true);
 
909
}
 
910
// ----------------------------------------------------------------------------
 
911
void BrowseTracker::ClearAllBrowse_Marks(bool clearScreenMarks)
 
912
// ----------------------------------------------------------------------------
 
913
{
 
914
    // Clear every BrowseMark for the currently active editor
 
915
 
 
916
    ///LOGIT( _T("ClearAllBrowseMark") );
 
917
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
918
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
919
    if (cbed) do
 
920
    {
 
921
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
922
        {
 
923
            cbStyledTextCtrl* control = cbed->GetControl();
 
924
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
925
            EdBrowse_Marks.ClearAllBrowse_Marks();
 
926
            if (clearScreenMarks) control->MarkerDeleteAll( GetBrowseMarkerId());
 
927
            #if defined(LOGGING)
 
928
            LOGIT( _T("ClearAllBrowseMarks()") );
 
929
            #endif
 
930
        }
 
931
        // When using Book marks as Browse marks, clear book marks also
 
932
        if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
 
933
        if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
 
934
        {
 
935
            cbStyledTextCtrl* control = cbed->GetControl();
 
936
            BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
 
937
            EdBook_Marks.ClearAllBrowse_Marks();
 
938
            if (clearScreenMarks) control->MarkerDeleteAll( GetBrowseMarkerId());
 
939
            #if defined(LOGGING)
 
940
            LOGIT( _T("ClearAllBookMarks()") );
 
941
            #endif
 
942
        }
 
943
    }while(0);
 
944
}
 
945
// ----------------------------------------------------------------------------
 
946
void BrowseTracker::GetCurrentScreenPositions()
 
947
// ----------------------------------------------------------------------------
 
948
{
 
949
    // Update copy of current editor screen data
 
950
 
 
951
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
952
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
953
    if (cbed) do
 
954
    {
 
955
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
956
        {
 
957
            //-BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
958
            cbStyledTextCtrl* control = cbed->GetControl();
 
959
            int m_CurrScrPosn = control->GetCurrentPos();
 
960
            //-if (curPos == -1) break;
 
961
 
 
962
            m_CurrScrLine       = control->LineFromPosition(m_CurrScrPosn);
 
963
            m_CurrScrTopLine    = control->GetFirstVisibleLine();
 
964
            m_CurrLinesOnScreen = control->LinesOnScreen();
 
965
            m_CurrScrLastLine   = m_CurrScrTopLine + m_CurrLinesOnScreen;
 
966
 
 
967
            m_CurrScrTopPosn    = control->PositionFromLine(m_CurrScrTopLine);
 
968
            m_CurrScrLastPosn   = control->PositionFromLine(m_CurrScrLastLine);
 
969
            // Lines might not fill the screen.
 
970
            if (m_CurrScrLastPosn == -1)
 
971
                m_CurrScrLastPosn = control->PositionFromLine(control->GetLineCount());
 
972
 
 
973
            m_CurrScrLineStartPosn  = control->PositionFromLine(m_CurrScrLine);
 
974
            m_CurrScrLineLength     = control->LineLength(m_CurrScrLine);
 
975
            m_CurrScrLineEndPosn    = m_CurrScrLineStartPosn + m_CurrScrLineLength;
 
976
 
 
977
            #if defined(LOGGING)
 
978
                //LOGIT( _T("UpdateCurrent: CurentLine[%d]TopLine[%d]ScrnLines[%d]LastLine[%d]"),
 
979
                //    m_CurrScrLine, m_CurrScrTopLine, m_CurrLinesOnScreen, m_CurrScrLastLine );
 
980
                //LOGIT( _T("UpdateCurrent: CurrPosn[%d]TopPosn[%d]LastPosn[%d]"),
 
981
                //    m_CurrScrPosn, m_CurrScrTopPosn, m_CurrScrLastPosn );
 
982
            #endif
 
983
        }//if
 
984
    }while(0);//if do
 
985
}
 
986
// ----------------------------------------------------------------------------
 
987
void BrowseTracker::OnMouseKeyEvent(wxMouseEvent& event)
 
988
// ----------------------------------------------------------------------------
 
989
{
 
990
    // Record the cursor position when user holds down the left mouse key;
 
991
    // If user is also holding down the control key, clear the browse marks
 
992
    // on this line.
 
993
 
 
994
    if ( (not IsAttached()) || (not m_InitDone) )
 
995
        { event.Skip(); return; }
 
996
    if (not IsBrowseMarksEnabled() )
 
997
        { event.Skip(); return; }
 
998
 
 
999
    if (   ( event.GetEventType() ==  wxEVT_LEFT_UP)
 
1000
        || ( event.GetEventType() ==  wxEVT_LEFT_DOWN)
 
1001
        || ( event.GetEventType() ==  wxEVT_LEFT_DCLICK)
 
1002
        || ( event.GetEventType() ==  wxEVT_MOTION)
 
1003
    ) do
 
1004
    {
 
1005
        // -- MOUSE_MOTION -------------------------------------------
 
1006
        if (event.GetEventType() == wxEVT_MOTION)
 
1007
        {
 
1008
            // ignore dragging events even if key is held down
 
1009
            if (event.LeftIsDown() && event.Dragging())
 
1010
            {   //allow nervous movement if not really dragging
 
1011
                if ( (abs(event.GetX() - m_MouseXPosn) >3)
 
1012
                  or (abs(event.GetY() - m_MouseYPosn) >3) )
 
1013
                m_IsMouseDoubleClick = true;
 
1014
            }
 
1015
            break;
 
1016
        }
 
1017
        // Skip unmonitored editors
 
1018
        EditorBase* eb = m_pEdMgr->GetActiveEditor();
 
1019
        if (m_EbBrowse_MarksHash.find(eb) == m_EbBrowse_MarksHash.end() )
 
1020
            break;
 
1021
        cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
 
1022
        if (not cbed) break;
 
1023
        cbStyledTextCtrl* pControl = cbed->GetControl();
 
1024
 
 
1025
        // -- MOUSE_KEY_DOWN --------------------------------------------
 
1026
        if (event.GetEventType() == wxEVT_LEFT_DOWN)
 
1027
        {   //Record the mouse down time
 
1028
            #if defined(LOGGING)
 
1029
            ////LOGIT( _T("Mouse DOWN") );
 
1030
            #endif
 
1031
            m_MouseDownTime = ::wxGetLocalTimeMillis();
 
1032
            m_MouseXPosn = event.GetX(); m_MouseYPosn = event.GetY();
 
1033
            // A double click substitutes for the Mouse_Down event
 
1034
            // so we can clear it here.
 
1035
            m_IsMouseDoubleClick = false;
 
1036
            break;
 
1037
        }
 
1038
 
 
1039
        // -- MOUSE_KEY_DCLICK ------------------------------------
 
1040
        if (event.GetEventType() == wxEVT_LEFT_DCLICK)
 
1041
        {   // Tell wxEVT_LEFT_UP about double clicks
 
1042
            #if defined(LOGGING)
 
1043
            ////LOGIT( _T("Double Click") );
 
1044
            #endif
 
1045
            m_IsMouseDoubleClick = true;
 
1046
            break;
 
1047
        }
 
1048
 
 
1049
        // -- MOUSE_KEY_UP ----------------------------------------
 
1050
        if (event.GetEventType() == wxEVT_LEFT_UP)
 
1051
        {   // we're monitoring this editor, record/clear this cursor position
 
1052
            #if defined(LOGGING)
 
1053
            ////LOGIT( _T("Mouse UP") );
 
1054
            #endif
 
1055
 
 
1056
            bool ctrlKeyIsDown          = ::wxGetMouseState().ControlDown();
 
1057
            bool useOnlyLeftMouse       = (m_ToggleKey == Left_Mouse);
 
1058
            bool useCtrlLeftMouse       = (m_ToggleKey == Ctrl_Left_Mouse);
 
1059
            bool clearUsesDoubleClick   = (m_ClearAllKey == ClearAllOnDoubleClick);
 
1060
            bool clearUsesSingleClick   = (m_ClearAllKey == ClearAllOnSingleClick);
 
1061
 
 
1062
            // -- ONLY_LEFT_MOUSE --
 
1063
            if ( useOnlyLeftMouse )
 
1064
            {   if( ctrlKeyIsDown && clearUsesDoubleClick && m_IsMouseDoubleClick)
 
1065
                {   //Clear all on Ctrl Double Click
 
1066
                    ClearAllBrowse_Marks(/*clearScreenMarks*/true);
 
1067
                    m_IsMouseDoubleClick = false;
 
1068
                    pControl->SetSelection (-1, pControl->GetCurrentPos()); //clear selection
 
1069
                    break;
 
1070
                }
 
1071
                if (ctrlKeyIsDown && clearUsesSingleClick)
 
1072
                {   //Clear all on Ctrl Single Click
 
1073
                    ClearAllBrowse_Marks(/*clearScreenMarks*/true);
 
1074
                    break;
 
1075
                }
 
1076
                if ( ctrlKeyIsDown) break; //This is useOnlyLeftMouse w/o ctrl
 
1077
                if ( m_IsMouseDoubleClick) break;
 
1078
                wxLongLong mouseDwellMillisecs = ::wxGetLocalTimeMillis() - m_MouseDownTime;
 
1079
                if (mouseDwellMillisecs >= m_LeftMouseDelay)
 
1080
                        RecordBrowseMark(eb);
 
1081
                break;
 
1082
            }//if useOnlyLeftMouse
 
1083
 
 
1084
            // -- CTRL-LEFT_MOUSE --
 
1085
            if ( useCtrlLeftMouse && ctrlKeyIsDown)
 
1086
            {   if( clearUsesDoubleClick && m_IsMouseDoubleClick)
 
1087
                {   //Clear all on Ctrl Double Click
 
1088
                    ClearAllBrowse_Marks(/*clearScreenMarks*/true);
 
1089
                    m_IsMouseDoubleClick = false;
 
1090
                    pControl->SetSelection (-1, pControl->GetCurrentPos()); //clear selection
 
1091
                    break;
 
1092
                }
 
1093
                RecordBrowseMark(eb);
 
1094
                break;
 
1095
            }//if useCtrlLeftMouse
 
1096
        }//if MOUSE_KEY_UP
 
1097
    }while(0);
 
1098
 
 
1099
    event.Skip();
 
1100
 
 
1101
}//OnMouseKeyEvent
 
1102
// ----------------------------------------------------------------------------
 
1103
//  BROWSETRACKER_MARKER scintilla test/set/unset marker routines
 
1104
// ----------------------------------------------------------------------------
 
1105
bool BrowseTracker::LineHasBookMarker(cbStyledTextCtrl* pControl, int line) const
 
1106
{
 
1107
    if (line == -1)
 
1108
        line = pControl->GetCurrentLine();
 
1109
    //-return pControl->MarkerGet(line) & (1 << BOOKMARK_MARKER);
 
1110
    return pControl->MarkerGet(line) & (1 << GetBrowseMarkerId());
 
1111
}
 
1112
// ----------------------------------------------------------------------------
 
1113
bool BrowseTracker::LineHasBrowseMarker(cbStyledTextCtrl* pControl, int line) const
 
1114
{
 
1115
    if (line == -1)
 
1116
        line = pControl->GetCurrentLine();
 
1117
    //-return pControl->MarkerGet(line) & (1 << BROWSETRACKER_MARKER);
 
1118
    return pControl->MarkerGet(line) & (1 << GetBrowseMarkerId());
 
1119
}
 
1120
// ----------------------------------------------------------------------------
 
1121
void BrowseTracker::MarkerToggle(cbStyledTextCtrl* pControl, int line)
 
1122
{
 
1123
    if (line == -1)
 
1124
        line = pControl->GetCurrentLine();
 
1125
    if (LineHasBrowseMarker(pControl, line))
 
1126
        //-pControl->MarkerDelete(line, BROWSETRACKER_MARKER);
 
1127
        pControl->MarkerDelete(line, GetBrowseMarkerId());
 
1128
    else
 
1129
    //-pControl->MarkerAdd(line, BROWSETRACKER_MARKER);
 
1130
    pControl->MarkerAdd(line, GetBrowseMarkerId());
 
1131
}
 
1132
// ----------------------------------------------------------------------------
 
1133
void BrowseTracker::MarkerNext(cbStyledTextCtrl* pControl)
 
1134
{
 
1135
    int line = pControl->GetCurrentLine() + 1;
 
1136
    //-int newLine = pControl->MarkerNext(line, 1 << BROWSETRACKER_MARKER);
 
1137
    int newLine = pControl->MarkerNext(line, 1 << GetBrowseMarkerId());
 
1138
    if (newLine != -1)
 
1139
        pControl->GotoLine(newLine);
 
1140
}
 
1141
// ----------------------------------------------------------------------------
 
1142
void BrowseTracker::MarkerPrevious(cbStyledTextCtrl* pControl)
 
1143
{
 
1144
    int line = pControl->GetCurrentLine() - 1;
 
1145
    //-int newLine = pControl->MarkerPrevious(line, 1 << BROWSETRACKER_MARKER);
 
1146
    int newLine = pControl->MarkerPrevious(line, 1 << GetBrowseMarkerId());
 
1147
    if (newLine != -1)
 
1148
        pControl->GotoLine(newLine);
 
1149
}
 
1150
// ----------------------------------------------------------------------------
 
1151
void BrowseTracker::MarkLine(cbStyledTextCtrl* pControl, int line)
 
1152
{
 
1153
    if (line == -1)
 
1154
        //-pControl->MarkerDeleteAll(BROWSETRACKER_MARKER);
 
1155
        pControl->MarkerDeleteAll(GetBrowseMarkerId());
 
1156
    else
 
1157
        //-pControl->MarkerAdd(line, BROWSETRACKER_MARKER);
 
1158
        pControl->MarkerAdd(line, GetBrowseMarkerId());
 
1159
}
 
1160
// ----------------------------------------------------------------------------
 
1161
void BrowseTracker::MarkRemove(cbStyledTextCtrl* pControl, int line)
 
1162
{
 
1163
    if (line == -1)
 
1164
        line = pControl->GetCurrentLine();
 
1165
    if (LineHasBrowseMarker(pControl, line))
 
1166
        //-pControl->MarkerDelete(line, BROWSETRACKER_MARKER);
 
1167
        pControl->MarkerDelete(line, GetBrowseMarkerId());
 
1168
}
 
1169
// ----------------------------------------------------------------------------
 
1170
void BrowseTracker::RecordBrowseMark(EditorBase* eb)
 
1171
// ----------------------------------------------------------------------------
 
1172
{
 
1173
    // stow a browse mark by EditorBase current line
 
1174
 
 
1175
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
1176
    if (cbed) do
 
1177
    {
 
1178
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
1179
        {
 
1180
            cbStyledTextCtrl* control = cbed->GetControl();
 
1181
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
1182
            GetCurrentScreenPositions();
 
1183
            // Toggle BrowseMark
 
1184
            if ( LineHasBrowseMarker(control, m_CurrScrLine) )
 
1185
            {
 
1186
                ClearLineBrowseMark(/*removeScreenmark*/true); //clear previous marks
 
1187
                if ( GetBrowseMarkerId() == BOOKMARK_MARKER ) ClearLineBookMark();
 
1188
                return;
 
1189
            }
 
1190
            int pos = control->GetCurrentPos();
 
1191
            EdBrowse_Marks.RecordMark(pos);
 
1192
            MarkLine( control, m_CurrScrLine);
 
1193
            #if defined(LOGGING)
 
1194
            LOGIT( _T("RecordBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
 
1195
                pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
 
1196
            if (not LineHasBrowseMarker(control, m_CurrScrLine)  ) {asm("int3"); /*trap*/}
 
1197
            #endif
 
1198
        }//if
 
1199
    }while(0);//if do
 
1200
}//RecordBrowseMark
 
1201
////// ----------------------------------------------------------------------------
 
1202
////void BrowseTracker::RecordBrowseMarkPosition(EditorBase* eb, int posn)
 
1203
////// ----------------------------------------------------------------------------
 
1204
////{
 
1205
////    // stow a browse mark by editor cursor position
 
1206
////
 
1207
////    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
1208
////    if (cbed) do
 
1209
////    {
 
1210
////        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
1211
////        {
 
1212
////            cbStyledTextCtrl* control = cbed->GetControl();
 
1213
////            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
1214
////            int line = control->LineFromPosition(posn);
 
1215
////            ClearLineBrowseMark( posn ); //clear previous marks
 
1216
////            EdBrowse_Marks.RecordMark( posn );
 
1217
////            //-if (not LineHasMarker( control,line))
 
1218
////                MarkLine( control, line);
 
1219
////            #if defined(LOGGING)
 
1220
////            LOGIT( _T("RecordBrowseMarkByPosn: pos[%d]line[%d]eb[%p][%s]"),
 
1221
////                posn, line,eb, eb->GetShortName().c_str() );
 
1222
////            if (not LineHasBrowseMarker(control, line)) {asm("int3"); /*trap*/}
 
1223
////            #endif
 
1224
////        }//if
 
1225
////    }while(0);//if do
 
1226
////}//RecordBrowseMarkPosition
 
1227
// ----------------------------------------------------------------------------
 
1228
void BrowseTracker::OnMenuTrackerDump(wxCommandEvent& event)
 
1229
// ----------------------------------------------------------------------------
 
1230
{
 
1231
    // For debugging. Dump arrays and pointers
 
1232
 
 
1233
   #ifdef LOGGING
 
1234
        LOGIT( _T("--Browsed--Editors-------------") );
 
1235
        LOGIT( _T("CurrIndex[%d]LastIndex[%d]count[%d]"), m_CurrEditorIndex, m_LastEditorIndex, GetEditorBrowsedCount() );
 
1236
        for (int i=0;i<MaxEntries ;++i )
 
1237
        {
 
1238
            wxString edName = GetPageFilename(i);
 
1239
            LOGIT( _T("Index[%d]Editor[%p]Name[%s]"), i, GetEditor(i), edName.c_str()  );;
 
1240
        }
 
1241
        for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); ++it)
 
1242
        {
 
1243
            LOGIT( _T("Hash Ed[%p] AryPtr[%p]"), it->first, it->second );
 
1244
        }
 
1245
 
 
1246
        // dump the array containing the current editors BrowseMarks
 
1247
        EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
1248
        cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
1249
        if (cbed) do
 
1250
        {
 
1251
            if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
1252
            {
 
1253
                //cbStyledTextCtrl* control = cbed->GetControl();
 
1254
                BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
1255
                LOGIT( _T("--Browse--Marks--for--[%s]----"), eb->GetShortName().c_str() );
 
1256
                EdBrowse_Marks.Dump();
 
1257
            }//if
 
1258
        }while(0);//if do
 
1259
        // dump the current Project ProjectData
 
1260
        ProjectData* pProjectData = GetProjectDataByEditorName( eb->GetFilename() );
 
1261
        if (not pProjectData)
 
1262
        {
 
1263
            LOGIT( _T("*CRASH* BrowseTracker::OnMenuTrackerDump No project pointer") );
 
1264
            return;
 
1265
        }
 
1266
        LOGIT( _T("ProjectData for[%s]"),pProjectData->GetProjectFilename().c_str() );
 
1267
        pProjectData->DumpHash(wxT("BrowseMarks"));
 
1268
        pProjectData->DumpHash(wxT("BookMarks"));
 
1269
   #endif
 
1270
}
 
1271
 
 
1272
// ----------------------------------------------------------------------------
 
1273
void BrowseTracker::OnMenuTrackerClear(wxCommandEvent& event)
 
1274
// ----------------------------------------------------------------------------
 
1275
{
 
1276
    // Clear the editor array of pointers (History)
 
1277
 
 
1278
    if (IsAttached() && m_InitDone)
 
1279
    {
 
1280
        TrackerClearAll();
 
1281
    }
 
1282
}
 
1283
// ----------------------------------------------------------------------------
 
1284
void BrowseTracker::TrackerClearAll()
 
1285
// ----------------------------------------------------------------------------
 
1286
{
 
1287
    // Clear the editor array of pointers (History)
 
1288
 
 
1289
    if (IsAttached() && m_InitDone)
 
1290
    {
 
1291
        for (int i=0; i<MaxEntries ; ++i )
 
1292
            RemoveEditor(GetEditor(i));
 
1293
        m_CurrEditorIndex = 0;
 
1294
        m_LastEditorIndex = MaxEntries-1;
 
1295
    }
 
1296
 
 
1297
    // Simulate activation of the current editor. If the list is empty
 
1298
    // it'll hang the selector dialog
 
1299
    EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
 
1300
    if ( eb )
 
1301
    {
 
1302
        CodeBlocksEvent evt;
 
1303
        evt.SetEditor(eb);
 
1304
        OnEditorActivated(evt);
 
1305
    }
 
1306
 
 
1307
}
 
1308
// ----------------------------------------------------------------------------
 
1309
cbProject* BrowseTracker::GetProject(EditorBase* eb)
 
1310
// ----------------------------------------------------------------------------
 
1311
{
 
1312
    cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
 
1313
    if ( not cbed ) {return 0;}
 
1314
    ProjectFile* pPrjFile = cbed->GetProjectFile();
 
1315
    if ( not pPrjFile ) {return 0;}
 
1316
    cbProject* pProject = pPrjFile->GetParentProject();
 
1317
    return pProject;
 
1318
}
 
1319
// ----------------------------------------------------------------------------
 
1320
void BrowseTracker::OnEditorActivated(CodeBlocksEvent& event)
 
1321
// ----------------------------------------------------------------------------
 
1322
{
 
1323
    // Record this activation event and place activation in history
 
1324
    // Create structures to hold new editor info if we never saw this editor before.
 
1325
    // Structures are: a hash to point to a class holding editor cursor postiions used
 
1326
    // as a history to place markers.
 
1327
 
 
1328
    //NB: This event is entered twice when an editor is activated. The first has
 
1329
    // no cbEditor attached. The second does.
 
1330
 
 
1331
    event.Skip();
 
1332
 
 
1333
    if (IsAttached() && m_InitDone) do
 
1334
    {
 
1335
 
 
1336
        EditorBase* eb = event.GetEditor();
 
1337
        wxString editorFullPath = eb->GetFilename();
 
1338
        cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
1339
 
 
1340
        if ( m_bProjectIsLoading )
 
1341
        {
 
1342
            #if defined(LOGGING)
 
1343
            LOGIT( _T("[OnEditorActivated ignored: Project Loading[ %s]"), editorFullPath.c_str());
 
1344
            #endif
 
1345
             return;
 
1346
        }
 
1347
 
 
1348
        if (not cbed)
 
1349
        {
 
1350
            #if defined(LOGGING)
 
1351
            //LOGIT( _T("[OnEditorActivated ignored:no cbEditor[%s]"), editorFullPath.c_str());
 
1352
            #endif
 
1353
            break;
 
1354
        }
 
1355
 
 
1356
        #if defined(LOGGING)
 
1357
        LOGIT( _T("Editor Activated[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1358
        #endif
 
1359
 
 
1360
 
 
1361
        // New editor, append to circular queue
 
1362
        // remove previous entries for this editor first
 
1363
        for (int i=0; i < MaxEntries; ++i)
 
1364
            if (eb == GetEditor(i)) ClearEditor(i);
 
1365
        // compress the array
 
1366
        if ( GetEditorBrowsedCount() )
 
1367
            for (int i=0; i < MaxEntries-1; ++i)
 
1368
            {
 
1369
                if (m_apEditors[i] == 0)
 
1370
                {   m_apEditors[i] = m_apEditors[i+1];
 
1371
                    m_apEditors[i+1] = 0;
 
1372
                    if ( m_CurrEditorIndex == (i+1) ) --m_CurrEditorIndex;
 
1373
                    if ( m_LastEditorIndex == (i+1) ) --m_LastEditorIndex;
 
1374
                }
 
1375
            }
 
1376
        AddEditor(eb);
 
1377
        #if defined(LOGGING)
 
1378
        LOGIT( _T("OnEditorActivated AddedEditor[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1379
        #endif
 
1380
        m_CurrEditorIndex = m_LastEditorIndex;
 
1381
 
 
1382
        // ---------------------------------------------------------------------
 
1383
        // For new cbEditors, add an entry to the editor cursor positions hash
 
1384
        // and allocate a cursor positions array to hold the cursor positions
 
1385
        // Set hooks to catch mouse activity
 
1386
        // ---------------------------------------------------------------------
 
1387
 
 
1388
        if ( IsBrowseMarksEnabled()
 
1389
            && (not GetBrowse_MarksFromHash( eb )) ) //guard against duplicates
 
1390
        {   // new editor
 
1391
            if (cbed)
 
1392
            {
 
1393
                HashAddBrowse_Marks( eb->GetFilename() ); //create hashs and book/browse marks arrays
 
1394
 
 
1395
                ////DumpHash(wxT("BrowseMarks"));
 
1396
                ////DumpHash(wxT("BookMarks"));
 
1397
                ////m_pActiveProjectData->DumpHash(wxT("BrowseMarks"));
 
1398
                ////m_pActiveProjectData->DumpHash(wxT("BookMarks"));
 
1399
 
 
1400
                cbStyledTextCtrl* control = cbed->GetControl();
 
1401
                // Setting the initial browsemark
 
1402
                //-int pos = control->GetCurrentPos();
 
1403
                control->Connect(wxEVT_LEFT_UP,
 
1404
                                (wxObjectEventFunction)(wxEventFunction)
 
1405
                                (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1406
                                 NULL, this);
 
1407
                control->Connect(wxEVT_LEFT_DOWN,
 
1408
                                (wxObjectEventFunction)(wxEventFunction)
 
1409
                                (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1410
                                 NULL, this);
 
1411
                control->Connect(wxEVT_LEFT_DCLICK,
 
1412
                                (wxObjectEventFunction)(wxEventFunction)
 
1413
                                (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1414
                                 NULL, this);
 
1415
                control->Connect(wxEVT_MOTION,
 
1416
                                (wxObjectEventFunction)(wxEventFunction)
 
1417
                                (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1418
                                 NULL, this);
 
1419
                control->Connect(wxEVT_CONTEXT_MENU,
 
1420
                                (wxObjectEventFunction)(wxEventFunction)
 
1421
                                (wxContextMenuEventFunction)&BrowseTracker::OnMarginContextMenu,
 
1422
                                 NULL, this);
 
1423
                #if defined(LOGGING)
 
1424
                LOGIT( _T("Added hash entry for [%p][%s]"), eb, eb->GetShortName().c_str() );
 
1425
                #endif
 
1426
                // Define scintilla BrowseTracker margin marker
 
1427
                //ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("app"));
 
1428
                //control->SetMarginWidth(1, 16);
 
1429
                //control->SetMarginType(1, wxSCI_MARGIN_SYMBOL);
 
1430
                //control->SetMarginSensitive(1, mgr->ReadBool(_T("/margin_1_sensitive"), true));
 
1431
                //control->SetMarginMask(1, (1 << BOOKMARK_MARKER) |
 
1432
                //                             (1 << BREAKPOINT_MARKER) |
 
1433
                //                             (1 << DEBUG_MARKER) |
 
1434
                //                             (1 << ERROR_MARKER));
 
1435
                //control->MarkerDefine(BOOKMARK_MARKER, BOOKMARK_STYLE);
 
1436
                //control->MarkerSetBackground(BOOKMARK_MARKER, wxColour(0xA0, 0xA0, 0xFF));
 
1437
                int marginMask = control->GetMarginMask(1);
 
1438
                control->SetMarginMask( 1, marginMask | (1<<GetBrowseMarkerId()) );
 
1439
                control->MarkerDefine( GetBrowseMarkerId(), GetBrowseMarkerStyle() );
 
1440
                // the following stmt seems to do nothing for wxSCI_MARK_DOTDOTDOT
 
1441
                control->MarkerSetBackground( GetBrowseMarkerId(), wxColour(0xA0, 0xA0, 0xFF));
 
1442
                #if defined(LOGGING)
 
1443
                //LOGIT( _T("UserStyle[%d]MarkerId[%d]MarkerStyle[%d]"),m_UserMarksStyle,GetBrowseMarkerId(), GetBrowseMarkerStyle());
 
1444
                #endif
 
1445
                // Set archived Layout browse marks in the editor
 
1446
                ProjectData* pProjectData = GetProjectDataByEditorName(eb->GetFilename() );
 
1447
                    #if defined(LOGGING)
 
1448
                    if (not pProjectData)
 
1449
                        LOGIT( _T("OnEditorActivated FAILED TO FIND PROJECT for [%s]"), eb->GetShortName().c_str() );
 
1450
                    #endif
 
1451
                if ( pProjectData )
 
1452
                {   // Set the Book/Browse marks from the Layout/History arrays
 
1453
                    BrowseMarks* pBrowse_MarksArc = pProjectData->GetBrowse_MarksFromHash( eb->GetFilename());
 
1454
                        //#if defined(LOGGING)
 
1455
                        //LOGIT( _T("\nDumping ARCHIVE data for[%s]"), eb->GetFilename().c_str());
 
1456
                        //LOGIT( _T("Project Data[%s]"),pProjectData->GetProjectFilename().c_str() );
 
1457
                        //pBrowse_MarksArc->Dump();
 
1458
                        //#endif
 
1459
                    if (pBrowse_MarksArc)
 
1460
                        m_EbBrowse_MarksHash[eb]->RecordMarksFrom( *pBrowse_MarksArc);
 
1461
                            //LOGIT( _T("Dumping CURRENT data for[%s]"), eb->GetFilename().c_str());
 
1462
                            //m_EbBrowse_MarksHash[eb]->Dump();
 
1463
 
 
1464
                    // record the current cursor position
 
1465
                    //-if (not LineHasBrowseMarker(control, control->LineFromPosition(pos)))
 
1466
                    //-if ( not m_EbBrowse_MarksHash[eb]->GetMarkCount() )
 
1467
                    //-    RecordBrowseMark(eb);
 
1468
 
 
1469
                        ////DumpHash(wxT("BrowseMarks"));
 
1470
                        ////DumpHash(wxT("BookMarks"));
 
1471
                        ////m_pActiveProjectData->DumpHash(wxT("BrowseMarks"));
 
1472
                        ////m_pActiveProjectData->DumpBrowse_Marks(wxT("BrowseMarks"));
 
1473
                        ////pBrowse_MarksArc->Dump();
 
1474
                        ////m_pActiveProjectData->DumpHash(wxT("BookMarks"));
 
1475
 
 
1476
                    // copy/set the old book marks, if any
 
1477
                    BrowseMarks* pCurrBook_Marks = GetBook_MarksFromHash( eb->GetFilename());
 
1478
                    BrowseMarks* pArchBook_Marks = pProjectData->GetBook_MarksFromHash(eb->GetFilename());
 
1479
                    if (pArchBook_Marks && pCurrBook_Marks)
 
1480
                        pCurrBook_Marks->ToggleBook_MarksFrom(*pArchBook_Marks);
 
1481
                }//if project
 
1482
 
 
1483
            }//if cbed
 
1484
        }//if new editor
 
1485
    }while(0);
 
1486
 
 
1487
}//OnEditorActivated
 
1488
// ----------------------------------------------------------------------------
 
1489
void BrowseTracker::OnUpdateUI(wxUpdateUIEvent& event)
 
1490
// ----------------------------------------------------------------------------
 
1491
{
 
1492
    // unused
 
1493
    event.Skip();
 
1494
}
 
1495
// ----------------------------------------------------------------------------
 
1496
void BrowseTracker::OnIdle(wxIdleEvent& event)
 
1497
// ----------------------------------------------------------------------------
 
1498
{
 
1499
 
 
1500
    // Focus the new selected editor. This doesn't work if a long compile
 
1501
    // is active since there's no idle time. User will have to click into
 
1502
    // the editor window to activate it.
 
1503
    // This used to be done by the CB editor manager, but someone removed the UI hook.
 
1504
    if (!Manager::Get()->IsAppShuttingDown() && m_UpdateUIFocusEditor)
 
1505
    {
 
1506
        cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
 
1507
        if (ed)
 
1508
        {    ed->GetControl()->SetFocus();
 
1509
            #if defined(LOGGING)
 
1510
            ////LOGIT( _T("OnIdle Focused Editor[%p] Title[%s]"), ed, ed->GetTitle().c_str() );
 
1511
            #endif
 
1512
        }
 
1513
        m_UpdateUIFocusEditor = false;
 
1514
    }
 
1515
     event.Skip();
 
1516
}
 
1517
// ----------------------------------------------------------------------------
 
1518
void BrowseTracker::OnStartShutdown(CodeBlocksEvent& event)
 
1519
// ----------------------------------------------------------------------------
 
1520
{
 
1521
    event.Skip();
 
1522
    OnRelease(true);
 
1523
}
 
1524
// ----------------------------------------------------------------------------
 
1525
void BrowseTracker::OnEditorDeactivated(CodeBlocksEvent& event)
 
1526
// ----------------------------------------------------------------------------
 
1527
{
 
1528
    // This event is practically useless. When an editor is opened you get the
 
1529
    // following:
 
1530
    //12:14:33: Editor DE-activated[03894E88][]
 
1531
    //12:14:33: OnEditorOpen ebase[03894E88]cbed[03894E88]stc[03894C88][Version.cpp]
 
1532
    //12:14:33: Editor DE-activated[03894E88][Version.cpp]
 
1533
    //12:14:33: Editor Activated[03894E88][Version.cpp]
 
1534
 
 
1535
    EditorBase* eb = event.GetEditor();
 
1536
    if (IsAttached() && m_InitDone)
 
1537
    {
 
1538
        #if defined(LOGGING)
 
1539
        ///LOGIT( _T("Editor DE-ACTIVATED[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1540
        wxUnusedVar(eb);
 
1541
        #endif
 
1542
    }
 
1543
    #if not defined(LOGGING)
 
1544
        wxUnusedVar(eb);
 
1545
    #endif
 
1546
 
 
1547
    event.Skip();
 
1548
}
 
1549
// ----------------------------------------------------------------------------
 
1550
void BrowseTracker::OnEditorOpened(CodeBlocksEvent& event)
 
1551
// ----------------------------------------------------------------------------
 
1552
{
 
1553
    // When editor belongs to a project, tell ProjectData about it.
 
1554
 
 
1555
    event.Skip();
 
1556
 
 
1557
    if (IsAttached() && m_InitDone)
 
1558
    {
 
1559
 
 
1560
        EditorBase* eb = event.GetEditor();
 
1561
        cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
1562
        if (not cbed) return;
 
1563
 
 
1564
        cbStyledTextCtrl* control = 0;
 
1565
        if (cbed) control = cbed->GetControl();
 
1566
        // validate cbProject has been set
 
1567
        cbProject* pcbProject = GetProject( eb );
 
1568
        #if defined(LOGGING)
 
1569
         LOGIT( _T("OnEditorOpen ebase[%p]cbed[%p]stc[%p][%s]"), eb, cbed, control, eb->GetShortName().c_str() );
 
1570
        #endif
 
1571
 
 
1572
        // stow opened editor info in the ProjectData class
 
1573
        if (pcbProject)
 
1574
        {    ProjectData* pProjectData = GetProjectDataFromHash(pcbProject);
 
1575
            if (pProjectData) pProjectData->AddEditor( eb->GetFilename() );
 
1576
        }
 
1577
 
 
1578
            //This code shows that the cbProject*'s are empty at this event
 
1579
            // That seems very odd ?
 
1580
            //#if defined(LOGGING)
 
1581
            ////NB: There is no cbEditor::ProjectFile* or ProjectFile::GetBaseName()
 
1582
            ////    and there's no initialized Project* that I can find.
 
1583
            //ProjectFile* pProjectFile = cbed->GetProjectFile();
 
1584
            //wxString projectBaseName = pProjectFile?pProjectFile->GetBaseName() :*wxEmptyString;
 
1585
            // LOGIT( _T("OnEditorOpen project[%p]projectBaseName[%s]"), pProjectFile, projectBaseName.c_str() );
 
1586
            //// -- there is no intialized cbProject* yet for the opening project.
 
1587
            ////Note here, that the returned project is the project about to be deactivated.
 
1588
            //ProjectManager* prjMgr = Manager::Get()->GetProjectManager();
 
1589
            //cbProject* pcbProject = prjMgr->GetActiveProject();
 
1590
            //wxString filename  = pcbProject?pcbProject->GetFilename():*wxEmptyString;
 
1591
            // LOGIT( _T("OnEditorOpen cbProject[%p]filename[%s]"), pcbProject, filename.c_str() );
 
1592
            // #endif
 
1593
 
 
1594
    }//if
 
1595
}
 
1596
// ----------------------------------------------------------------------------
 
1597
void BrowseTracker::OnEditorClosed(CodeBlocksEvent& event)
 
1598
// ----------------------------------------------------------------------------
 
1599
{
 
1600
    // clear this editor out of our arrays and pointers
 
1601
 
 
1602
    //NOTE: using Manager::Get->GetEditorManager()->GetEditor... etc will
 
1603
    //      fail in this codeblocks event.
 
1604
    //      The cbEditors are nolonger available
 
1605
    event.Skip();
 
1606
 
 
1607
    if (IsAttached() && m_InitDone)
 
1608
    {
 
1609
        EditorBase* eb = event.GetEditor();
 
1610
        wxString filePath = event.GetString();
 
1611
        ProjectData* pProjectData = GetProjectDataByEditorName( filePath);
 
1612
 
 
1613
        #if defined(LOGGING)
 
1614
            LOGIT( _T("Closing Eb[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1615
            ///LOGIT( _T("Closing Eb[%p][%s]"), eb, eb->GetFilename().c_str() );
 
1616
        #endif
 
1617
 
 
1618
        //-cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
 
1619
        //-if (not cbed) return;
 
1620
 
 
1621
        // If not our editor, or editor already closed, return
 
1622
        if ( GetEditor(eb) == -1) return;
 
1623
 
 
1624
        // If editor belong to a project,
 
1625
        // Copy current Browse/Book marks to archive so we have
 
1626
        // them if the user reopens this editor
 
1627
        if ( pProjectData )
 
1628
        {
 
1629
            BrowseMarks* pArchBook_Marks = pProjectData->GetBook_MarksFromHash( eb->GetFilename());
 
1630
            BrowseMarks* pCurrBook_Marks = GetBook_MarksFromHash( eb->GetFilename());
 
1631
            //*note* cannot get access to scintilla book marks here because the cbStyledTextCtrl
 
1632
            // is not accessible
 
1633
            if (pCurrBook_Marks && pArchBook_Marks)
 
1634
                pArchBook_Marks->CopyMarksFrom(*pCurrBook_Marks);
 
1635
 
 
1636
            // Copy current BrowseMarks to archive BrowseMarks so we have
 
1637
            // them if the user reopens this editor
 
1638
            BrowseMarks* pArchBrowse_Marks = pProjectData->GetBrowse_MarksFromHash( eb->GetFilename());
 
1639
            BrowseMarks* pCurrBrowse_Marks = GetBrowse_MarksFromHash( eb);
 
1640
            if (pCurrBrowse_Marks && pArchBrowse_Marks)
 
1641
                pArchBrowse_Marks->CopyMarksFrom(*pCurrBrowse_Marks);
 
1642
        }
 
1643
        // Clean up the closed editor and its associated Book/BrowseMarks
 
1644
        for (int i=0; i<MaxEntries; ++i )
 
1645
            if ( eb == GetEditor(i)  )
 
1646
            {
 
1647
                #if defined(LOGGING)
 
1648
                LOGIT( _T("OnEditorClosed cleared[%p]"), GetEditor(i));
 
1649
                #endif
 
1650
                RemoveEditor(GetEditor(i));
 
1651
            }//if
 
1652
    }//if
 
1653
}//OnEditorClosed
 
1654
// ----------------------------------------------------------------------------
 
1655
void BrowseTracker::AddEditor(EditorBase* eb)
 
1656
// ----------------------------------------------------------------------------
 
1657
{
 
1658
    // Add this editor the array of activated editors
 
1659
 
 
1660
    if (not eb) return;
 
1661
    if ( ++m_LastEditorIndex >= MaxEntries ) m_LastEditorIndex = 0;
 
1662
    m_apEditors[m_LastEditorIndex] = eb;
 
1663
    ++m_nBrowsedEditorCount;
 
1664
    #if defined(LOGGING)
 
1665
    //LOGIT( _T("AddEditor[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1666
    #endif
 
1667
}
 
1668
// ----------------------------------------------------------------------------
 
1669
BrowseMarks* BrowseTracker::HashAddBrowse_Marks( const wxString fullPath)
 
1670
// ----------------------------------------------------------------------------
 
1671
{
 
1672
    // EditorManager calls fail during the OnEditorClose event
 
1673
    // eg,EditorBase* eb = Manager::Get()->GetEditorManager()->GetEditor(filename);
 
1674
 
 
1675
    EditorBase* eb = m_pEdMgr->GetEditor(fullPath);
 
1676
    if (not eb) return 0;
 
1677
    // don't add duplicates
 
1678
    EbBrowse_MarksHash& hash = m_EbBrowse_MarksHash;
 
1679
    BrowseMarks* pBrowse_Marks = GetBrowse_MarksFromHash( eb);
 
1680
    if (not pBrowse_Marks)
 
1681
    {   pBrowse_Marks = new BrowseMarks(eb->GetFilename() );
 
1682
        hash[eb] = pBrowse_Marks;
 
1683
    }
 
1684
 
 
1685
    // Allocate book marks array also
 
1686
    HashAddBook_Marks( fullPath);
 
1687
 
 
1688
    // If this editor belongs to a project,
 
1689
    // Ask ProjectData to alloc the archive Browse/Book marks arrays
 
1690
    ProjectData* pProjectData = GetProjectDataByEditorName( fullPath );
 
1691
    if(pProjectData)
 
1692
        pProjectData->HashAddBrowse_Marks( fullPath );
 
1693
 
 
1694
    #if defined(LOGGING)
 
1695
    ///LOGIT( _T("HashAddBrowse_Marks[%s]"), eb->GetFilename().c_str() );
 
1696
    #endif
 
1697
    return pBrowse_Marks;
 
1698
}
 
1699
// ----------------------------------------------------------------------------
 
1700
BrowseMarks* BrowseTracker::HashAddBook_Marks( const wxString fullPath)
 
1701
// ----------------------------------------------------------------------------
 
1702
{
 
1703
    // EditorManager calls fail during the OnEditorClose event
 
1704
    // eg,EditorBase* eb = Manager::Get()->GetEditorManager()->GetEditor(filename);
 
1705
 
 
1706
    EditorBase* eb = m_pEdMgr->GetEditor(fullPath);
 
1707
    if (not eb) return 0;
 
1708
    EbBrowse_MarksHash& hash = m_EdBook_MarksHash;
 
1709
    BrowseMarks* pBook_Marks = GetBook_MarksFromHash( eb);
 
1710
    if (not pBook_Marks)
 
1711
    {   pBook_Marks = new BrowseMarks(fullPath);
 
1712
        hash[eb] = pBook_Marks;
 
1713
    }
 
1714
 
 
1715
    // If this editor belongs to a project
 
1716
    // Ask ProjectData to alloc the archive Browse/Book marks arrays
 
1717
    ProjectData* pProjectData = GetProjectDataByEditorName( fullPath );
 
1718
    if(pProjectData)
 
1719
        pProjectData->HashAddBook_Marks( eb->GetFilename());
 
1720
 
 
1721
    #if defined(LOGGING)
 
1722
    ///LOGIT( _T("HashAddBOOKMakrs[%s]"), eb->GetFilename().c_str() );
 
1723
    #endif
 
1724
    return pBook_Marks;
 
1725
}
 
1726
// ----------------------------------------------------------------------------
 
1727
void BrowseTracker::ClearEditor(int index)
 
1728
// ----------------------------------------------------------------------------
 
1729
{
 
1730
    // Used to remove duplicate editors without deleting array data
 
1731
    // Duplicates especially occur when a previous editor is re-activated after
 
1732
    // a secondary project is closed.
 
1733
 
 
1734
    if (index < 0) return;
 
1735
    m_apEditors[index] = 0;
 
1736
    --m_nBrowsedEditorCount;
 
1737
}
 
1738
// ----------------------------------------------------------------------------
 
1739
void BrowseTracker::RemoveEditor(EditorBase* eb)
 
1740
// ----------------------------------------------------------------------------
 
1741
{
 
1742
    // clear this editor out of our arrays and pointers
 
1743
    // ie, reverse of the processing in OnEditorActivated()
 
1744
 
 
1745
    // don't allow recursion from our called routines.
 
1746
    if (m_nRemoveEditorSentry) return;
 
1747
    if (not eb) return;
 
1748
 
 
1749
    ++m_nRemoveEditorSentry;
 
1750
 
 
1751
    if (IsAttached() && m_InitDone) do
 
1752
    {
 
1753
        #if defined(LOGGING)
 
1754
        //Dont use eb to reference data. It may have already been destroyed.
 
1755
         //LOGIT( _T("Removing[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1756
         ///LOGIT( _T("RemoveEditor[%p]"), eb );
 
1757
        #endif
 
1758
 
 
1759
        for (int i=0; i<MaxEntries; ++i )
 
1760
            if ( eb == GetEditor(i)  )
 
1761
                ClearEditor(i);
 
1762
 
 
1763
        // remove the hash entry for this editor
 
1764
        if ( m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end())
 
1765
        {
 
1766
            delete m_EbBrowse_MarksHash[eb]; //Browse Marks
 
1767
            m_EbBrowse_MarksHash.erase(eb);
 
1768
            delete m_EdBook_MarksHash[eb];   //Book Marks
 
1769
            m_EdBook_MarksHash.erase(eb);
 
1770
 
 
1771
            // using a stale eb will cause a crash
 
1772
            if (-1 != m_pEdMgr->FindPageFromEditor(eb) )
 
1773
            {
 
1774
                wxWindow* win = wxWindow::FindWindowByName(wxT("SCIwindow"),eb);
 
1775
                if ( win )
 
1776
                {
 
1777
                    win->Disconnect(wxEVT_LEFT_UP,
 
1778
                                    (wxObjectEventFunction)(wxEventFunction)
 
1779
                                    (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1780
                                     NULL, this);
 
1781
                    win->Disconnect(wxEVT_LEFT_DOWN,
 
1782
                                    (wxObjectEventFunction)(wxEventFunction)
 
1783
                                    (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1784
                                     NULL, this);
 
1785
                    win->Disconnect(wxEVT_LEFT_DCLICK,
 
1786
                                    (wxObjectEventFunction)(wxEventFunction)
 
1787
                                    (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1788
                                     NULL, this);
 
1789
                    win->Disconnect(wxEVT_MOTION,
 
1790
                                    (wxObjectEventFunction)(wxEventFunction)
 
1791
                                    (wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
 
1792
                                     NULL, this);
 
1793
                    win->Disconnect(wxEVT_CONTEXT_MENU,
 
1794
                                    (wxObjectEventFunction)(wxEventFunction)
 
1795
                                    (wxCommandEventFunction)&BrowseTracker::OnMarginContextMenu,
 
1796
                                     NULL, this);
 
1797
                }//if win
 
1798
            }//if find page from editor
 
1799
            #if defined(LOGGING)
 
1800
            ///LOGIT( _T("RemoveEditor Erased hash entry[%p]"), eb );
 
1801
            #endif
 
1802
        }
 
1803
    }while(0);
 
1804
 
 
1805
    m_nRemoveEditorSentry = 0;
 
1806
}
 
1807
// ----------------------------------------------------------------------------
 
1808
void BrowseTracker::OnProjectOpened(CodeBlocksEvent& event)
 
1809
// ----------------------------------------------------------------------------
 
1810
{
 
1811
    // NB: EVT_PROJECT_ACTIVATE is occuring before EVT_PROJECT_OPEN
 
1812
    // NB: EVT_EDITOR_ACTIVATE events occur before EVT_PROJECT_ACTIVATE or EVT_PROJECT_OPEN
 
1813
    // Currently, this event is a hack to us since it occurs AFTER editors are activated
 
1814
    //  and AFTER the project is activated
 
1815
 
 
1816
    // But since the editors are now already open, we can read the layout file
 
1817
    // that saved previous BrowseMark and book mark history, and use that data
 
1818
    // to build/set old saved Browse/Book marks.
 
1819
 
 
1820
    if ( not IsBrowseMarksEnabled() )
 
1821
        return;
 
1822
 
 
1823
    cbProject* pProject = event.GetProject();
 
1824
 
 
1825
    if ( not pProject )
 
1826
    {   //caused when project imported
 
1827
        m_bProjectIsLoading = false;
 
1828
        return;
 
1829
    }
 
1830
    #if defined(LOGGING)
 
1831
     LOGIT( _T("-----------------------------------"));
 
1832
     LOGIT( _T("Project OPENED[%s]"), event.GetProject()->GetFilename().c_str() );
 
1833
    #endif
 
1834
 
 
1835
    wxString projectFilename = event.GetProject()->GetFilename();
 
1836
 
 
1837
 
 
1838
    // allocate a ProjectData to hold activated editors
 
1839
    cbProject* pCBProject = event.GetProject();
 
1840
    ProjectData* pProjectData = GetProjectDataFromHash( pCBProject);
 
1841
    if (not pProjectData)
 
1842
    {   pProjectData = new ProjectData(pCBProject);
 
1843
        m_ProjectDataHash[pCBProject] = pProjectData;
 
1844
    }
 
1845
 
 
1846
    // Read the layout file for this project, build BrowseMarks for each editor
 
1847
    pProjectData = GetProjectDataFromHash( event.GetProject() );
 
1848
    if ( pProjectData)
 
1849
        if (not pProjectData->IsLayoutLoaded() )
 
1850
            pProjectData->LoadLayout();
 
1851
 
 
1852
    // There is a bug such that the project loading hook is *not* called
 
1853
    // for some projects with a stray </unit> in its xml file.
 
1854
    // Remove all the activated editors for this project when
 
1855
    // the project was loaded. We don't want to see them if the user
 
1856
    // didn't manually activate them.
 
1857
    if (not m_bProjectIsLoading)
 
1858
    {
 
1859
        int fileCount = pProject->GetFilesCount();
 
1860
        for (int i=0; i<fileCount; ++i)
 
1861
        {
 
1862
            for (int j=0; j<MaxEntries; ++j)
 
1863
            {
 
1864
                if ( GetEditor(j) == 0 ) continue;
 
1865
                //#if defined(LOGGING)
 
1866
                //LOGIT( _T("eb[%s]projectFile[%s]"),
 
1867
                //    GetEditor(j)->GetFilename().c_str(), pProject->GetFile(i)->file.GetFullPath().c_str() );
 
1868
                //#endif
 
1869
                if ( pProject->GetFile(i)->file.GetFullPath() ==  GetEditor(j)->GetFilename())
 
1870
                {
 
1871
                    //#if defined(LOGGING)
 
1872
                    //LOGIT( _T("OnProjectOpened:Removing[%s]"),GetEditor(j)->GetFilename().c_str() );
 
1873
                    //#endif
 
1874
                    RemoveEditor(GetEditor(j));
 
1875
                    break;
 
1876
                }
 
1877
            }
 
1878
        }//for
 
1879
    }//if
 
1880
 
 
1881
    // Turn off "project loading" in order to record the last activated editor
 
1882
    m_bProjectIsLoading = false;
 
1883
 
 
1884
    // Record the last CB activated editor as if the user activate it.
 
1885
    EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
 
1886
    if ( eb && (eb != GetCurrentEditor()) )
 
1887
    {
 
1888
        CodeBlocksEvent evt;
 
1889
        evt.SetEditor(eb);
 
1890
        OnEditorActivated(evt);
 
1891
        #if defined(LOGGING)
 
1892
        LOGIT( _T("OnProjectOpened Activated Editor[%p][%s]"), eb, eb->GetShortName().c_str() );
 
1893
        #endif
 
1894
    }
 
1895
    //*Testing*
 
1896
    //for (EbBrowse_MarksHash::iterator it = m_EdBrowse_MarksArchive.begin(); it !=m_EdBrowse_MarksArchive.end(); ++it )
 
1897
    //  it->second->Dump();
 
1898
 
 
1899
    event.Skip();
 
1900
 
 
1901
}//OnProjectOpened
 
1902
// ----------------------------------------------------------------------------
 
1903
void BrowseTracker::OnProjectClosing(CodeBlocksEvent& event)
 
1904
// ----------------------------------------------------------------------------
 
1905
{
 
1906
    // This hook occurs before the editors are closed. That allows
 
1907
    // us to reference CB project and editor related data before CB
 
1908
    // deletes it all.
 
1909
 
 
1910
    if (not IsBrowseMarksEnabled())
 
1911
        return;
 
1912
 
 
1913
    cbProject* pProject = event.GetProject();
 
1914
    if (not pProject) return; //It happens!
 
1915
 
 
1916
    #if defined(LOGGING)
 
1917
     LOGIT( _T("Project CLOSING[%p][%s]"), pProject, pProject->GetFilename().c_str() );
 
1918
    #endif
 
1919
 
 
1920
    // Simulate closing the remaining editors here so that we can write
 
1921
    // a layout file containing the BrowseMarks and Book_Marks
 
1922
    // This is the last chance we get to write a layout file.
 
1923
 
 
1924
    ProjectData* pProjectData = GetProjectDataFromHash( pProject);
 
1925
    #if defined(LOGGING)
 
1926
        if ( not pProjectData )
 
1927
            LOGIT( _T("*CRASH* OnProjectClosing entered w/o project pointer") );
 
1928
    #endif
 
1929
    if ( not pProjectData ) return;
 
1930
    // Close editors that belong to the current project
 
1931
    for (int i=0; i < m_pEdMgr->GetEditorsCount(); ++i)
 
1932
    {
 
1933
        EditorBase* eb = m_pEdMgr->GetEditor(i);
 
1934
        // Simulate closing editors that belong to the current project
 
1935
        if ( pProjectData->FindFilename(eb->GetFilename()) )
 
1936
        {
 
1937
            CodeBlocksEvent evt(cbEVT_EDITOR_CLOSE);
 
1938
            evt.SetEditor(eb);
 
1939
            evt.SetString(eb->GetFilename());
 
1940
            OnEditorClosed( evt );
 
1941
        }
 
1942
        else{
 
1943
            #if defined(LOGGING)
 
1944
            ////LOGIT( _T("ProjectClosing failed to find[%s]"), eb->GetFilename().c_str() );
 
1945
            #endif
 
1946
        }
 
1947
    }
 
1948
 
 
1949
    // Write the layout for this project
 
1950
    if (pProjectData) pProjectData->SaveLayout();
 
1951
 
 
1952
    // Free the ProjectData
 
1953
    if ( pProjectData )
 
1954
    {
 
1955
        #if defined(LOGGING)
 
1956
        LOGIT( _T("deleting ProjectData[%p][%s]"), pProjectData, pProjectData->GetProjectFilename().c_str()  );
 
1957
        #endif
 
1958
        delete pProjectData;
 
1959
        m_ProjectDataHash.erase(pProject);
 
1960
    }
 
1961
 
 
1962
        //-wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
 
1963
        //-OnMenuTrackerDump(evt);
 
1964
 
 
1965
    event.Skip();
 
1966
 
 
1967
}//OnProjectClosing
 
1968
// ----------------------------------------------------------------------------
 
1969
void BrowseTracker::OnProjectActivatedEvent(CodeBlocksEvent& event)
 
1970
// ----------------------------------------------------------------------------
 
1971
{
 
1972
    // NB: EVT_PROJECT_ACTIVATE is occuring before EVT_PROJECT_OPEN
 
1973
    // NB: EVT_EDITOR_ACTIVATE event occur before EVT_PROJECT_ACTIVATE or EVT_PROJECT_OPEN
 
1974
 
 
1975
    // *NOTE* when a secondary project closes and re-activates a previous one,
 
1976
    // *NO* cbEVT_PROJECT_ACTIVATE occurs. We end up with the wrong active project
 
1977
    // pointer. Only a cbEVT_EDITOR_ACTIVATE occurs.
 
1978
 
 
1979
    event.Skip();
 
1980
 
 
1981
    if (not IsBrowseMarksEnabled() )
 
1982
        return;
 
1983
 
 
1984
    // allocate a ProjectData to hold activated editors
 
1985
    cbProject* pCBProject = event.GetProject();
 
1986
 
 
1987
    if (not pCBProject) return; //caused by importing a project
 
1988
 
 
1989
    #if defined(LOGGING)
 
1990
    LOGIT( _T("-----------------------------------"));
 
1991
    LOGIT( _T("Project ACTIVATED[%p][%s]"), pCBProject,  pCBProject->GetFilename().c_str() );
 
1992
    #endif
 
1993
 
 
1994
    ProjectData* pProjectData = GetProjectDataFromHash( pCBProject);
 
1995
    if (not pProjectData)
 
1996
    {   pProjectData = new ProjectData(pCBProject);
 
1997
        m_ProjectDataHash[pCBProject] = pProjectData;
 
1998
    }
 
1999
    pProjectData->IncrementActivationCount();
 
2000
 
 
2001
    // store the current editor in BrowseTracker array
 
2002
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
2003
        //LOGIT( _T("ProjectActivated eb[%p][%s]Current[%p][%s]"),
 
2004
        //    eb, GetEditorFilename(eb).c_str(),
 
2005
        //    m_pCurrentEditor, GetEditorFilename(m_pCurrentEditor).c_str());
 
2006
 
 
2007
    // Record the last CB activated editor as if the user activate it.
 
2008
    // See OnEditorActivated()
 
2009
    if ( eb && (eb != GetCurrentEditor()) )
 
2010
    {
 
2011
        CodeBlocksEvent evt;
 
2012
        evt.SetEditor(eb);
 
2013
        OnEditorActivated(evt);
 
2014
        //LOGIT( _T("OnProjectActivated Editor[%p][%s]"), eb, GetEditorFilename(eb).c_str()  );
 
2015
    }
 
2016
 
 
2017
    // Compress the editor pointer array to allow all "forward" available slots
 
2018
    int index = GetCurrentEditorIndex();
 
2019
    if ( GetEditorBrowsedCount() )
 
2020
    {
 
2021
        ArrayOfEditorBasePtrs tmpArray;
 
2022
        tmpArray.Alloc(MaxEntries);
 
2023
        // copy current editors & clear for compression
 
2024
        for (int i = 0; i<MaxEntries; ++i)
 
2025
        {   tmpArray[i] = m_apEditors[i];
 
2026
            m_apEditors[i] = 0;
 
2027
        }//for
 
2028
        m_CurrEditorIndex = 0;
 
2029
        m_LastEditorIndex = MaxEntries-1;
 
2030
        for (int i = 0; i<MaxEntries; ++i)
 
2031
        {
 
2032
            if ( tmpArray[index] )
 
2033
            {   if (++m_LastEditorIndex >= MaxEntries) m_LastEditorIndex = 0;
 
2034
                 m_apEditors[m_LastEditorIndex] = tmpArray[index];
 
2035
            }
 
2036
            if (++index >= MaxEntries) index = 0;
 
2037
        }//for
 
2038
    }//if
 
2039
    else
 
2040
    {   m_CurrEditorIndex = 0;
 
2041
        m_LastEditorIndex = MaxEntries-1;
 
2042
    }
 
2043
 
 
2044
}//OnProjectActivatedEvent
 
2045
// ----------------------------------------------------------------------------
 
2046
void BrowseTracker::OnProjectLoadingHook(cbProject* project, TiXmlElement* elem, bool loading)
 
2047
// ----------------------------------------------------------------------------
 
2048
{
 
2049
    // This turned out to be a problem. It isn't always called for old type projects
 
2050
    // or a project with an extra </unit> in it.
 
2051
 
 
2052
    // CB does not issue Project_Opened or Project_activated events until
 
2053
    // after the editors are loaded and activated. That causes us to record
 
2054
    // the loading editors as if the user activated them manually.
 
2055
    // So we use this hook to tell the recorder NOT to record the loading editors.
 
2056
 
 
2057
    // *Logic Gothcha* When a work space loads, OnProjectActivated() is called for
 
2058
    // the active project, then loading proceeds for other projects. This can cause
 
2059
    // the m_bProjectIsLoading flag to be set forever.
 
2060
 
 
2061
    #if defined(LOGGING)
 
2062
    //-LOGIT( _T("OnProjectLoadingHook [%s]"), loading? wxT("Loading"):wxT("Saving") );
 
2063
    #endif
 
2064
 
 
2065
    if (not IsBrowseMarksEnabled() )
 
2066
        return;
 
2067
 
 
2068
    if (loading)
 
2069
    {
 
2070
        // dont record CB activated editors while project is loading
 
2071
        //-------------------------------
 
2072
        m_bProjectIsLoading = true;
 
2073
        //-------------------------------
 
2074
 
 
2075
        m_LoadingProjectFilename = project->GetFilename();
 
2076
 
 
2077
        #if defined(LOGGING)
 
2078
        LOGIT( _T("----------------------------------------------") );
 
2079
        LOGIT( _T("ProjectLoadingHook::LOADING[%p][%s]"), project, m_LoadingProjectFilename.c_str() );
 
2080
        #endif
 
2081
    }
 
2082
    else //saving project
 
2083
    {
 
2084
            //#if defined(LOGGING)
 
2085
            //LOGIT( _T("ProjectLoadingHook::SAVING[]TiXmlElement[%p]"), elem  );
 
2086
            //#endif
 
2087
    }
 
2088
}//OnProjectLoadingHook
 
2089
// ----------------------------------------------------------------------------
 
2090
void BrowseTracker::OnEditorEventHook(cbEditor* pcbEditor, wxScintillaEvent& event)
 
2091
// ----------------------------------------------------------------------------
 
2092
{
 
2093
    // Rebuild the BrowseMarks array if user deletes/adds editor lines
 
2094
 
 
2095
//    wxString txt = _T("OnEditorModified(): ");
 
2096
//    int flags = event.GetModificationType();
 
2097
//    if (flags & wxSCI_MOD_CHANGEMARKER) txt << _T("wxSCI_MOD_CHANGEMARKER, ");
 
2098
//    if (flags & wxSCI_MOD_INSERTTEXT) txt << _T("wxSCI_MOD_INSERTTEXT, ");
 
2099
//    if (flags & wxSCI_MOD_DELETETEXT) txt << _T("wxSCI_MOD_DELETETEXT, ");
 
2100
//    if (flags & wxSCI_MOD_CHANGEFOLD) txt << _T("wxSCI_MOD_CHANGEFOLD, ");
 
2101
//    if (flags & wxSCI_PERFORMED_USER) txt << _T("wxSCI_PERFORMED_USER, ");
 
2102
//    if (flags & wxSCI_MOD_BEFOREINSERT) txt << _T("wxSCI_MOD_BEFOREINSERT, ");
 
2103
//    if (flags & wxSCI_MOD_BEFOREDELETE) txt << _T("wxSCI_MOD_BEFOREDELETE, ");
 
2104
//    txt << _T("pos=")
 
2105
//        << wxString::Format(_T("%d"), event.GetPosition())
 
2106
//        << _T(", line=")
 
2107
//        << wxString::Format(_T("%d"), event.GetLine())
 
2108
//        << _T(", linesAdded=")
 
2109
//        << wxString::Format(_T("%d"), event.GetLinesAdded());
 
2110
//    Manager::Get()->GetLogManager()->DebugLog(txt);
 
2111
 
 
2112
    event.Skip();
 
2113
 
 
2114
    if (not IsBrowseMarksEnabled())
 
2115
        return;
 
2116
 
 
2117
    //if ( event.GetEventType() != wxEVT_SCI_MODIFIED )
 
2118
    if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
 
2119
    {
 
2120
        // Whenever event.GetLinesAdded() != 0, we must re-set BrowseMarks for lines greater
 
2121
        // than LineFromPosition(event.GetPosition())
 
2122
 
 
2123
        int linesAdded = event.GetLinesAdded();
 
2124
        bool isAdd = event.GetModificationType() & wxSCI_MOD_INSERTTEXT;
 
2125
        bool isDel = event.GetModificationType() & wxSCI_MOD_DELETETEXT;
 
2126
        if ((isAdd || isDel) && linesAdded != 0)
 
2127
        {
 
2128
            #if defined(LOGGING)
 
2129
            //LOGIT( _T("EditorEventHook isAdd[%d]isDel[%d]lines[%d]"), isAdd, isDel, linesAdded );
 
2130
            #endif
 
2131
            // rebuild BrowseMarks from scintilla marks
 
2132
            RebuildBrowse_Marks( pcbEditor, isAdd );
 
2133
        }//if
 
2134
    }//wxEVT_SCI_MODIFIED
 
2135
 
 
2136
    // wxSCI_MOD_CHANGEMARKER is an extremely expensive call. It's called
 
2137
    // for each line during a file load, and for every change to every
 
2138
    // margin marker in the known cosmos. So here we allow a "one shot only"
 
2139
    // to catch the marker changed by a margin context menu.
 
2140
    // cf: CloneBookMarkFromEditor() and OnMarginContextMenu()
 
2141
    if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
 
2142
    do{
 
2143
        if ( m_OnEditorEventHookIgnoreMarkerChanges )
 
2144
            break;
 
2145
        int flags = event.GetModificationType();
 
2146
        if (flags & wxSCI_MOD_CHANGEMARKER )
 
2147
        {
 
2148
            m_OnEditorEventHookIgnoreMarkerChanges = true;
 
2149
            int line = event.GetLine();
 
2150
            #if defined(LOGGING)
 
2151
            //LOGIT( _T("wxSCI_MOD_CHANGEMARKER line[%d]"), line );
 
2152
            #endif
 
2153
            CloneBookMarkFromEditor( line );
 
2154
        }
 
2155
    }while(false);
 
2156
 
 
2157
}//OnEditorEventHook
 
2158
// ----------------------------------------------------------------------------
 
2159
void BrowseTracker::CloneBookMarkFromEditor( int line )
 
2160
// ----------------------------------------------------------------------------
 
2161
{
 
2162
    // Record the editor bookmark as is.
 
2163
 
 
2164
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
2165
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
2166
    if (cbed)
 
2167
    {
 
2168
        cbStyledTextCtrl* control = cbed->GetControl();
 
2169
        if ( LineHasBookMarker(control, line) )
 
2170
            AddBook_Mark( eb );
 
2171
        else
 
2172
            ClearLineBookMark();
 
2173
        #if defined(LOGGING)
 
2174
        //LOGIT( _T("CloneBookMarkFromEditor[%d][%s]"), line,
 
2175
        //    LineHasBookMarker( control, line)?wxT("Added"):wxT("Cleared") );
 
2176
        #endif
 
2177
    }
 
2178
}
 
2179
// ----------------------------------------------------------------------------
 
2180
void BrowseTracker::OnMarginContextMenu(wxContextMenuEvent& event)
 
2181
// ----------------------------------------------------------------------------
 
2182
{
 
2183
    // User has invoked the context menu. Set a flag to allow
 
2184
    // OnEditorEventHook wxSCI_MOD_CHANGEMARKER overhead
 
2185
    // If the user clicked withing the number margins, the hook
 
2186
    // will see it, do its thing, then turn the overhead off.
 
2187
    // If the user does not change the a marker, the hook will not turn
 
2188
    // the overhead off, but the next invocatin of OnEditorEventHook will.
 
2189
    // turn it off anyway.
 
2190
 
 
2191
    m_OnEditorEventHookIgnoreMarkerChanges = false;
 
2192
 
 
2193
    event.Skip();
 
2194
    return;
 
2195
}
 
2196
// ----------------------------------------------------------------------------
 
2197
void BrowseTracker::OnBook_MarksToggle(wxCommandEvent& event)
 
2198
// ----------------------------------------------------------------------------
 
2199
{
 
2200
    // a Book mark has been toggled
 
2201
    event.Skip();
 
2202
    #if defined(LOGGING)
 
2203
    LOGIT( _T("OnBook_MarksToggle") );
 
2204
    #endif
 
2205
    ToggleBook_Mark(GetCurrentEditor() );
 
2206
}
 
2207
// ----------------------------------------------------------------------------
 
2208
void BrowseTracker::AddBook_Mark(EditorBase* eb, int line/*=-1*/)
 
2209
// ----------------------------------------------------------------------------
 
2210
{
 
2211
    // Stow a Book mark by EditorBase current line
 
2212
    // Note: the book mark has not been cleared/set by scintilla yet
 
2213
 
 
2214
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
2215
    if (cbed)
 
2216
    {
 
2217
        if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
 
2218
        do {
 
2219
            cbStyledTextCtrl* control = cbed->GetControl();
 
2220
            BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
 
2221
            GetCurrentScreenPositions();
 
2222
            int pos = control->GetCurrentPos();
 
2223
            EdBook_Marks.RecordMark(pos);
 
2224
            #if defined(LOGGING)
 
2225
            LOGIT( _T("AddBook_Mark: pos[%d]line[%d]eb[%p][%s]"),
 
2226
                pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
 
2227
            ///EdBook_Marks.Dump();
 
2228
            #endif
 
2229
        }while(false);//if do
 
2230
 
 
2231
        // When using BookMarks as BrowseMarks toggle the BrowseMark also.
 
2232
        if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
 
2233
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
2234
        do {
 
2235
            cbStyledTextCtrl* control = cbed->GetControl();
 
2236
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
2237
            GetCurrentScreenPositions();
 
2238
            int pos = control->GetCurrentPos();
 
2239
            EdBrowse_Marks.RecordMark(pos);
 
2240
            #if defined(LOGGING)
 
2241
            LOGIT( _T("AddBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
 
2242
                pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
 
2243
            #endif
 
2244
        }while(false);//if do
 
2245
 
 
2246
    }//if
 
2247
}//ToggleBook_Mark
 
2248
// ----------------------------------------------------------------------------
 
2249
void BrowseTracker::ToggleBook_Mark(EditorBase* eb)
 
2250
// ----------------------------------------------------------------------------
 
2251
{
 
2252
    // Stow a Book mark by EditorBase current line
 
2253
    // Note: the book mark has not been cleared/set by scintilla yet
 
2254
 
 
2255
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
2256
    if (cbed)
 
2257
    {
 
2258
        if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
 
2259
        do {
 
2260
            cbStyledTextCtrl* control = cbed->GetControl();
 
2261
            BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
 
2262
            GetCurrentScreenPositions();
 
2263
            // Toggle BookMark
 
2264
            if ( LineHasBookMarker(control, m_CurrScrLine) )
 
2265
            {
 
2266
                ClearLineBookMark(); //clear previous marks
 
2267
                break;
 
2268
            }
 
2269
            int pos = control->GetCurrentPos();
 
2270
            EdBook_Marks.RecordMark(pos);
 
2271
            #if defined(LOGGING)
 
2272
            LOGIT( _T("RecordBook_Mark: pos[%d]line[%d]eb[%p][%s]"),
 
2273
                pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
 
2274
            ///EdBook_Marks.Dump();
 
2275
            #endif
 
2276
        }while(false);//if do
 
2277
 
 
2278
        // When using BookMarks as BrowseMarks toggle the BrowseMark also.
 
2279
        if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
 
2280
        if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
2281
        do {
 
2282
            cbStyledTextCtrl* control = cbed->GetControl();
 
2283
            BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
2284
            GetCurrentScreenPositions();
 
2285
            // Toggle BrowseMark
 
2286
            if ( LineHasBrowseMarker(control, m_CurrScrLine) )
 
2287
            {
 
2288
                ClearLineBrowseMark(/*markRemove*/false);
 
2289
                break;
 
2290
            }
 
2291
            int pos = control->GetCurrentPos();
 
2292
            EdBrowse_Marks.RecordMark(pos);
 
2293
            #if defined(LOGGING)
 
2294
            LOGIT( _T("RecordBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
 
2295
                pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
 
2296
            #endif
 
2297
        }while(false);//if do
 
2298
 
 
2299
    }//if
 
2300
}//ToggleBook_Mark
 
2301
// ----------------------------------------------------------------------------
 
2302
void BrowseTracker::ClearLineBookMark()
 
2303
// ----------------------------------------------------------------------------
 
2304
{
 
2305
    // clear BookMark entry for a single line out of our history array
 
2306
 
 
2307
    ///LOGIT( _T("ClearBookMark") );
 
2308
 
 
2309
    EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
 
2310
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
2311
    if (cbed)
 
2312
    {
 
2313
        if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
 
2314
        {
 
2315
            BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
 
2316
            GetCurrentScreenPositions();
 
2317
            EdBook_Marks.ClearMark( m_CurrScrLineStartPosn, m_CurrScrLineEndPosn);
 
2318
            #if defined(LOGGING)
 
2319
            LOGIT( _T("ClearLineBookMark") );
 
2320
            #endif
 
2321
        }
 
2322
 
 
2323
    }
 
2324
}//ClearLineBookMark
 
2325
// ----------------------------------------------------------------------------
 
2326
void BrowseTracker::RebuildBrowse_Marks(cbEditor* pcbEditor, bool addedLines)
 
2327
// ----------------------------------------------------------------------------
 
2328
{
 
2329
    // Adjust BrowseMarks from scintilla moved markers
 
2330
 
 
2331
    #if defined(LOGGING)
 
2332
    ///LOGIT( _T("RebuildBrowse_Marks") );
 
2333
    #endif
 
2334
    EditorBase* eb = GetCurrentEditor();
 
2335
    if (not eb) return;
 
2336
    cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
 
2337
    if (not cbed) return;
 
2338
 
 
2339
    if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
 
2340
    {
 
2341
        BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
 
2342
        EdBrowse_Marks.RebuildBrowse_Marks( cbed, addedLines);
 
2343
    }
 
2344
 
 
2345
}//RebuildBrowse_Marks
 
2346
// ----------------------------------------------------------------------------
 
2347
ProjectData* BrowseTracker::GetProjectDataByEditorName( wxString filePath)
 
2348
// ----------------------------------------------------------------------------
 
2349
{
 
2350
    wxString reason = wxT("");
 
2351
    do {
 
2352
        EditorBase* eb = m_pEdMgr->GetEditor( filePath );
 
2353
        reason = wxT("eb");
 
2354
        if ( not eb ) break;
 
2355
        cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
 
2356
        reason = wxT("cbed");
 
2357
        if (not cbed) break;
 
2358
        ProjectFile* pf = cbed->GetProjectFile();
 
2359
        reason = wxT("ProjectFile");
 
2360
        if (not pf) break;
 
2361
        cbProject* pcbProject = pf->GetParentProject();
 
2362
        reason = wxT("cbProject");
 
2363
        if (not pcbProject) break;
 
2364
        return GetProjectDataFromHash( pcbProject);
 
2365
    }while(0);
 
2366
 
 
2367
    #if defined(LOGGING)
 
2368
    //LOGIT( _T("GetProjectDataByEditorName FAILED to find [%s] for [%s]"), reason.c_str(), filePath.c_str() );
 
2369
    #endif
 
2370
 
 
2371
    // At this point CB has failed to find the project by its editor filename
 
2372
    // So search our own ProjectData objects the hard way.
 
2373
    for (ProjectDataHash::iterator it = m_ProjectDataHash.begin(); it != m_ProjectDataHash.end(); ++it)
 
2374
    {
 
2375
        ProjectData* pProjectData = it->second;
 
2376
        if ( pProjectData->GetBrowse_MarksFromHash( filePath) )
 
2377
            return pProjectData;
 
2378
    }
 
2379
 
 
2380
    #if defined(LOGGING)
 
2381
    //LOGIT( _T("GetProjectDataByEditorName FAILED to find [%s] for [%s]"), wxT("Hash entry"), filePath.c_str() );
 
2382
    #endif
 
2383
    return 0;
 
2384
}//GetProjectDataByEditorName
 
2385
// ----------------------------------------------------------------------------
 
2386
ProjectData* BrowseTracker::GetProjectDataByProjectName( wxString projectFilePath)
 
2387
// ----------------------------------------------------------------------------
 
2388
{
 
2389
    cbProject* pProject = m_pPrjMgr->IsOpen(projectFilePath);
 
2390
    if (not pProject) return 0;
 
2391
    return GetProjectDataFromHash( pProject);
 
2392
}
 
2393
// ----------------------------------------------------------------------------
 
2394
ProjectData* BrowseTracker::GetProjectDataFromHash( cbProject* pProject)
 
2395
// ----------------------------------------------------------------------------
 
2396
{
 
2397
    // Get the ProjectData* that's associated with this cbProject&
 
2398
    // eg. cbProject* pProjectData = GetProjectFromHash(m_ProjectDataHash, pProject);
 
2399
    ProjectDataHash& hash = m_ProjectDataHash;
 
2400
    ProjectDataHash::iterator it = hash.find( pProject );
 
2401
    if ( it == hash.end() ) return 0;
 
2402
    return it->second;
 
2403
}
 
2404
// ----------------------------------------------------------------------------
 
2405
BrowseMarks* BrowseTracker::GetBrowse_MarksFromHash( EditorBase* eb)
 
2406
// ----------------------------------------------------------------------------
 
2407
{
 
2408
    // Return the BrowseMarks array associated with the Editor
 
2409
    //EbBrowse_MarksHash m_EdBrowse_MarksArchive;
 
2410
    EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.find(eb);
 
2411
    if ( it == m_EbBrowse_MarksHash.end() ) return 0;
 
2412
    return it->second;
 
2413
}
 
2414
// ----------------------------------------------------------------------------
 
2415
BrowseMarks* BrowseTracker::GetBrowse_MarksFromHash( wxString filePath)
 
2416
// ----------------------------------------------------------------------------
 
2417
{
 
2418
    // Return the BrowseMarks array associated with this file path
 
2419
 
 
2420
    for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); it++)
 
2421
    {
 
2422
        BrowseMarks* p = it->second;
 
2423
        if ( p->GetFilePath() == filePath ) {return p;}
 
2424
    }
 
2425
 
 
2426
    return 0;
 
2427
}
 
2428
// ----------------------------------------------------------------------------
 
2429
BrowseMarks* BrowseTracker::GetBook_MarksFromHash( EditorBase* eb)
 
2430
// ----------------------------------------------------------------------------
 
2431
{
 
2432
    // return the Book marks history array associated with this editor
 
2433
    EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.find(eb);
 
2434
    if ( it == m_EdBook_MarksHash.end() ) return 0;
 
2435
    return it->second;
 
2436
}
 
2437
// ----------------------------------------------------------------------------
 
2438
BrowseMarks* BrowseTracker::GetBook_MarksFromHash( wxString filePath)
 
2439
// ----------------------------------------------------------------------------
 
2440
{
 
2441
    // return the Book marks history array associated with this file path
 
2442
    #if defined(LOGGING)
 
2443
    ///LOGIT( _T("GetBook_MarksFromHash looking for[%s]"),filePath.c_str() );
 
2444
    #endif
 
2445
 
 
2446
    for (EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.begin(); it != m_EdBook_MarksHash.end(); it++)
 
2447
    {
 
2448
        BrowseMarks* p = it->second;
 
2449
        #if defined(LOGGING)
 
2450
        ///LOGIT( _T("GetBook_MarksFromHash finding[%s]"),p->GetFilePath().c_str() );
 
2451
        #endif
 
2452
        if ( p->GetFilePath() == filePath ) {return p;}
 
2453
    }
 
2454
 
 
2455
    return 0;
 
2456
}
 
2457
// ----------------------------------------------------------------------------
 
2458
void BrowseTracker::DumpHash( const wxString hashType)
 
2459
// ----------------------------------------------------------------------------
 
2460
{
 
2461
 
 
2462
    #if defined(LOGGING)
 
2463
    LOGIT( _T("--- DumpHash ---[%s]"), hashType.c_str()  );
 
2464
 
 
2465
    EbBrowse_MarksHash* phash = &m_EbBrowse_MarksHash;
 
2466
    if ( hashType == wxT("BookMarks") )
 
2467
        phash = &m_EdBook_MarksHash;
 
2468
    EbBrowse_MarksHash& hash = *phash;
 
2469
 
 
2470
    for (EbBrowse_MarksHash::iterator it = hash.begin(); it != hash.end(); it++)
 
2471
    {
 
2472
        EditorBase* eb = it->first;
 
2473
        BrowseMarks* p = it->second;
 
2474
        LOGIT( _T("eb*[%p]%s*[%p]name[%s]"), eb, hashType.c_str(), p, p->GetFilePath().c_str() );
 
2475
    }
 
2476
 
 
2477
    #endif
 
2478
}
 
2479
// ----------------------------------------------------------------------------
 
2480
wxString BrowseTracker::FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
 
2481
// ----------------------------------------------------------------------------
 
2482
{
 
2483
    // Find the absolute path from where this application has been run.
 
2484
    // argv0 is wxTheApp->argv[0]
 
2485
    // cwd is the current working directory (at startup)
 
2486
    // appVariableName is the name of a variable containing the directory for this app, e.g.
 
2487
    // MYAPPDIR. This is checked first.
 
2488
 
 
2489
    wxString str;
 
2490
 
 
2491
    // Try appVariableName
 
2492
    if (!appVariableName.IsEmpty())
 
2493
    {
 
2494
        str = wxGetenv(appVariableName);
 
2495
        if (!str.IsEmpty())
 
2496
            return str;
 
2497
    }
 
2498
 
 
2499
#if defined(__WXMAC__) && !defined(__DARWIN__)
 
2500
    // On Mac, the current directory is the relevant one when
 
2501
    // the application starts.
 
2502
    return cwd;
 
2503
#endif
 
2504
 
 
2505
    wxString argv0Str = argv0;
 
2506
    #if defined(__WXMSW__)
 
2507
        do{
 
2508
            if (argv0Str.Contains(wxT(".exe")) ) break;
 
2509
            if (argv0Str.Contains(wxT(".bat")) ) break;
 
2510
            if (argv0Str.Contains(wxT(".cmd")) ) break;
 
2511
            argv0Str.Append(wxT(".exe"));
 
2512
        }while(0);
 
2513
    #endif
 
2514
 
 
2515
    if (wxIsAbsolutePath(argv0Str))
 
2516
    {
 
2517
        #if defined(LOGGING)
 
2518
        LOGIT( _T("FindAppPath: AbsolutePath[%s]"), wxPathOnly(argv0Str).GetData() );
 
2519
        #endif
 
2520
        return wxPathOnly(argv0Str);
 
2521
    }
 
2522
    else
 
2523
    {
 
2524
        // Is it a relative path?
 
2525
        wxString currentDir(cwd);
 
2526
        if (currentDir.Last() != wxFILE_SEP_PATH)
 
2527
            currentDir += wxFILE_SEP_PATH;
 
2528
 
 
2529
        str = currentDir + argv0Str;
 
2530
        if (wxFileExists(str))
 
2531
        {
 
2532
            #if defined(LOGGING)
 
2533
            LOGIT( _T("FindAppPath: RelativePath[%s]"), wxPathOnly(str).GetData() );
 
2534
            #endif
 
2535
            return wxPathOnly(str);
 
2536
        }
 
2537
    }
 
2538
 
 
2539
    // OK, it's neither an absolute path nor a relative path.
 
2540
    // Search PATH.
 
2541
 
 
2542
    wxPathList pathList;
 
2543
    pathList.AddEnvList(wxT("PATH"));
 
2544
    str = pathList.FindAbsoluteValidPath(argv0Str);
 
2545
    if (!str.IsEmpty())
 
2546
    {
 
2547
        #if defined(LOGGING)
 
2548
        LOGIT( _T("FindAppPath: SearchPath[%s]"), wxPathOnly(str).GetData() );
 
2549
        #endif
 
2550
        return wxPathOnly(str);
 
2551
    }
 
2552
 
 
2553
    // Failed
 
2554
    #if defined(LOGGING)
 
2555
     LOGIT(  _T("FindAppPath: Failed, returning cwd") );
 
2556
    #endif
 
2557
    return wxEmptyString;
 
2558
    //return cwd;
 
2559
}//FindAppPath
 
2560
 
 
2561
//// ----------------------------------------------------------------------------
 
2562
//void BrowseTracker::OnMenuTrackBackward(wxCommandEvent& event)
 
2563
//// ----------------------------------------------------------------------------
 
2564
//{
 
2565
//    // *** Deprecated *** unused *** routine
 
2566
//    // Browse Tracker menu Backward
 
2567
//
 
2568
//    EditorManager* EdMgr = Manager::Get()->GetEditorManager();
 
2569
//    EditorBase* eb = 0;
 
2570
//    EditorBase* ebCurrent = EdMgr->GetActiveEditor();
 
2571
//
 
2572
//    int index = m_nCurrentEditorIndex-1;
 
2573
//    // scan for previous editor, skipping nulls (null is a closed editors)
 
2574
//    for (int i=0; i<MaxEntries; ++i)
 
2575
//    {
 
2576
//        if ( index < 0 ) index = MaxEntries-1;
 
2577
//        eb = m_apEditors[index];
 
2578
//        LOGIT( _T("Backward:m_nCurrentEditorIndex[%d]index[%d]eb[%p][%s]"),m_nCurrentEditorIndex, index, eb, GetEditorFilename(eb).c_str() );
 
2579
//        if ( eb )
 
2580
//        {
 
2581
//            if ( eb == ebCurrent ) { --index; continue;}
 
2582
//            if (-1 == EdMgr->FindPageFromEditor(eb) )
 
2583
//            {   // this entry has been closed behind our backs
 
2584
//                m_apEditors[index] = 0; { --index; continue;}
 
2585
//            }
 
2586
//            m_bProjectIsLoading = true;
 
2587
//            eb->Activate();
 
2588
//            m_bProjectIsLoading = false;
 
2589
//            m_nCurrentEditorIndex = index;
 
2590
//            m_pCurrentEditor = eb;
 
2591
//            break;
 
2592
//        }
 
2593
//        else --index;
 
2594
//    }//for
 
2595
//}
 
2596
//// ----------------------------------------------------------------------------
 
2597
//void BrowseTracker::OnMenuTrackforward(wxCommandEvent& event)
 
2598
//// ----------------------------------------------------------------------------
 
2599
//{
 
2600
//    // *** Deprecated *** unused *** routine
 
2601
//    // Browse Tracker menu forward
 
2602
//
 
2603
//    EditorBase* eb = 0;
 
2604
//    EditorManager* EdMgr = Manager::Get()->GetEditorManager();
 
2605
//    EditorBase* ebCurrent = EdMgr->GetActiveEditor();
 
2606
//
 
2607
//    int index = m_nCurrentEditorIndex+1;
 
2608
//    // scan for previous editor, skipping nulls (null is a closed editors)
 
2609
//    for (int i=0; i<MaxEntries; ++i)
 
2610
//    {
 
2611
//        if ( index >= MaxEntries ) index = 0;
 
2612
//        eb = m_apEditors[index];
 
2613
//         //LOGIT( _T("Forward:m_nCurrentEditorIndex[%d]index[%d]eb[%p]"),m_nCurrentEditorIndex, index, eb );
 
2614
//        if ( eb )
 
2615
//        {
 
2616
//            if ( eb == ebCurrent ) { ++index; continue;}
 
2617
//            if (-1 == EdMgr->FindPageFromEditor(eb) )
 
2618
//            {   // this entry has been closed behind our backs
 
2619
//                m_apEditors[index] = 0; {++index; continue;}
 
2620
//            }
 
2621
//
 
2622
//            m_bProjectIsLoading = true;
 
2623
//            eb->Activate();
 
2624
//            m_bProjectIsLoading = false;
 
2625
//            m_nCurrentEditorIndex = index;
 
2626
//            m_pCurrentEditor = eb;
 
2627
//            break;
 
2628
//        }
 
2629
//        else ++index;
 
2630
//    }//for
 
2631
//}
 
2632
////// ----------------------------------------------------------------------------
 
2633
////void BrowseTracker::OnPageChanged(wxFlatNotebookEvent& event)
 
2634
////// ----------------------------------------------------------------------------
 
2635
////{
 
2636
////    event.Skip(); // allow others to process it too
 
2637
////
 
2638
////    //-EditorBase* eb = static_cast<EditorBase*>(m_pNotebook->GetPage(event.GetSelection()));
 
2639
////    wxFlatNotebook* pNotebook = (wxFlatNotebook*)event.GetEventObject();
 
2640
////    int page = event.GetSelection();
 
2641
////    EditorBase* eb = static_cast<EditorBase*>(pNotebook->GetPage(page));
 
2642
////    LOGIT( _T("OnPageChanged eb[%p] title[%s]"), eb, eb ? eb->GetTitle().c_str() : _T(""));
 
2643
////
 
2644
////    // focus editor
 
2645
////    // The following still doesn't set focus to the new editor/page
 
2646
////    if (eb) eb->Show();
 
2647
////    if (eb) eb->SetFocus();
 
2648
////    // Try to focus the editor in UpdateUI;
 
2649
////    m_UpdateUIFocusEditor = true;
 
2650
////}
 
2651
// ----------------------------------------------------------------------------