~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

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

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

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