2
This file is part of Browse Tracker, a plugin for Code::Blocks
3
Copyright (C) 2007 Pecan Heber
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.
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.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
// RCS-ID: $Id: BrowseTracker.cpp 47 2008-01-12 20:18:59Z Pecan $
22
// There is no way to know when a project is loading. So we have to accept
23
// editors that are activated during the loading process, then remove them
24
// after the loading finishes.
25
// Trying to use OnProjectLoadingHook did not work because it is not called
26
// if the project xml file has no "extensions" entry.
28
// cbProject::IsLoading/IsLoadingProject is actually turned OFF while editor
29
// loading takes place. Very wierd.
32
// Remove loaded editors from our array that the user did not activate.
33
// Open the layout file and build an array of old BrowseMarks.
34
// These will be used on the first activation of an editor.
36
// Compress the arrays of pointers so we have more usable slots.
38
// If we've never seen this editor before, build containers to hold
39
// the mouse click (BrowseMarks) locations.
40
// Copy the archived layout BrowseMarks to an active BrowseMarks container
41
// and have scintilla mark the lines with a "..." icon.
43
// Add the editor pointer to an array of active editors.
44
// Set pointers that track "active" editors & projects.
46
// Copy the editor BrowseMarks back to the BrowseMark archive so we can
47
// use them if the user reopens this editor.
48
// Clear this editor out of our containers and arrays. (Except the archive)
49
// OnStartShutdown/OnRelease
50
// This happens before the editors are actually closed.
51
// We simulate closing the editors to force the current Markers into
52
// the ProjectData archive markers. Then write a layout
53
// file containing the BrowseMarks for each open file.
54
// Free the ProjectData container for the current project
56
// EbBrowse_MarksHash: EditorBase*, BrowseMarks*
57
// EdBook_MarksHash: EditorBase*, BrowseMarks*
58
// ProjectDataHash: cbProject*, ProjectData*
59
// ArrayOfEditorBasePtrs: EditorBase*'s of user activated editors
60
// FileBrowse_MarksArchive: EditorBase*, Book_Marks* of archived bookmarks
61
// (layout BrowseMarks, closed editor BrowseMarks etc)
62
// FileBook_MarksArchive: filePath, BrowseMarks*
63
// BrowseMarks wxArray containing editor cursor locations
66
#if defined(CB_PRECOMP)
69
#include "sdk_common.h"
70
#include "sdk_events.h"
72
#include "editormanager.h"
73
#include "editorbase.h"
75
#include "projectmanager.h"
76
#include "cbproject.h"
78
#include "projectloader_hooks.h"
80
#include <wx/dynarray.h> //for wxArray and wxSortedArray
81
#include <cbstyledtextctrl.h>
82
#include <editor_hooks.h>
83
#include "personalitymanager.h"
84
#include <wx/stdpaths.h>
87
#include <wx/xrc/xmlres.h>
89
//-#include "wx/wxFlatNotebook/wxFlatNotebook.h"
91
#include "BrowseTracker.h"
92
#include "BrowseSelector.h"
93
#include "BrowseMarks.h"
94
#include "BrowseTrackerDefs.h"
95
#include "ProjectData.h"
96
#include "BrowseTrackerCfg.h"
97
//#define BROWSETRACKER_MARKER 9
98
//#define BROWSETRACKER_MARKER_STYLE wxSCI_MARK_DOTDOTDOT
99
// ----------------------------------------------------------------------------
101
// ----------------------------------------------------------------------------
102
int gBrowse_MarkerId; //scintilla marker id
103
int gBrowse_MarkerStyle; //scintialla marker style
104
int GetBrowseMarkerId(){return gBrowse_MarkerId;}
105
int GetBrowseMarkerStyle(){return gBrowse_MarkerStyle;}
107
// ----------------------------------------------------------------------------
109
// ----------------------------------------------------------------------------
111
// Register the plugin
112
PluginRegistrant<BrowseTracker> reg(_T("BrowseTracker"));
114
int idMenuViewTracker = wxNewId();
115
int idMenuTrackerforward = wxNewId();
116
int idMenuTrackerBackward = wxNewId();
117
int idMenuTrackerClear = wxNewId();
118
int idMenuBrowseMarkPrevious = wxNewId();
119
int idMenuBrowseMarkNext = wxNewId();
120
int idMenuRecordBrowseMark = wxNewId();
121
int idMenuClearBrowseMark = wxNewId();
122
int idMenuClearAllBrowse_Marks = wxNewId();
123
int idMenuSortBrowse_Marks = wxNewId();
124
int idMenuConfigBrowse_Marks = wxNewId();
126
int idMenuTrackerDump = wxNewId();
128
int idEditBookmarksToggle = XRCID("idEditBookmarksToggle");
131
// ----------------------------------------------------------------------------
133
// ----------------------------------------------------------------------------
134
BEGIN_EVENT_TABLE(BrowseTracker, cbPlugin)
136
//-EVT_UPDATE_UI(idMenuViewTracker, BrowseTracker::OnUpdateUI)
137
EVT_IDLE( BrowseTracker::OnIdle)
139
// The following replaced by OnMenuTrackerSelect() dialog popup
140
//EVT_MENU( idMenuTrackerBackward, BrowseTracker::OnMenuTrackBackward)
141
//EVT_MENU( idMenuTrackerforward, BrowseTracker::OnMenuTrackforward)
143
EVT_MENU( idMenuTrackerBackward, BrowseTracker::OnMenuTrackerSelect)
144
EVT_MENU( idMenuTrackerforward, BrowseTracker::OnMenuTrackerSelect)
145
EVT_MENU( idMenuTrackerClear, BrowseTracker::OnMenuTrackerClear)
146
EVT_MENU( idMenuBrowseMarkPrevious, BrowseTracker::OnMenuBrowseMarkPrevious)
147
EVT_MENU( idMenuBrowseMarkNext, BrowseTracker::OnMenuBrowseMarkNext)
148
EVT_MENU( idMenuRecordBrowseMark, BrowseTracker::OnMenuRecordBrowseMark)
149
EVT_MENU( idMenuClearBrowseMark, BrowseTracker::OnMenuClearBrowseMark)
150
EVT_MENU( idMenuClearAllBrowse_Marks,BrowseTracker::OnMenuClearAllBrowse_Marks)
151
EVT_MENU( idMenuSortBrowse_Marks, BrowseTracker::OnMenuSortBrowse_Marks)
152
EVT_MENU( idMenuConfigBrowse_Marks, BrowseTracker::OnMenuConfigBrowse_Marks)
154
EVT_MENU( idMenuTrackerDump, BrowseTracker::OnMenuTrackerDump)
157
EVT_MENU(idEditBookmarksToggle, BrowseTracker::OnBook_MarksToggle)
159
//-EVT_FLATNOTEBOOK_PAGE_CHANGED(ID_NBEditorManager, BrowseTracker::OnPageChanged)
162
// ----------------------------------------------------------------------------
163
BrowseTracker::BrowseTracker()
164
// ----------------------------------------------------------------------------
167
//-m_nCurrentEditorIndex = 0;
168
m_CurrEditorIndex = 0;
169
m_LastEditorIndex = 0;
170
m_bProjectIsLoading = false;
171
m_UpdateUIFocusEditor = false;
172
m_nRemoveEditorSentry = 0;
173
m_nBrowseMarkPreviousSentry = 0;
174
m_nBrowseMarkNextSentry = 0;
175
m_nBrowsedEditorCount = 0;
176
//-m_pLoadingProject = 0;
179
m_ToggleKey = Left_Mouse;
180
m_LeftMouseDelay = 200;
181
m_ClearAllKey = ClearAllOnSingleClick;
182
m_IsMouseDoubleClick = false;
185
// ----------------------------------------------------------------------------
186
BrowseTracker::~BrowseTracker()
187
// ----------------------------------------------------------------------------
192
// ----------------------------------------------------------------------------
193
void BrowseTracker::OnAttach()
194
// ----------------------------------------------------------------------------
198
m_CurrEditorIndex = 0;
199
m_LastEditorIndex = MaxEntries-1;
200
m_apEditors.Alloc(MaxEntries);
201
for (int i=0; i<MaxEntries ; ++i ) m_apEditors[i] = 0;
202
m_nBrowsedEditorCount = 0;
203
m_UpdateUIFocusEditor = false;
204
m_nRemoveEditorSentry = 0;
205
m_nBrowseMarkPreviousSentry = 0;
206
m_nBrowseMarkNextSentry = 0;
207
m_OnEditorEventHookIgnoreMarkerChanges = true; //used to avoid editor hook overhead
209
//-m_pActiveCBProject = 0;
210
//-m_pActiveProjectData = 0;
211
//-m_pLoadingProject = 0;
212
m_LoadingProjectFilename = wxT("");
213
m_pEdMgr = Manager::Get()->GetEditorManager();
214
m_pPrjMgr = Manager::Get()->GetProjectManager();
216
// initialize version and logging
217
m_pAppWin = Manager::Get()->GetAppWindow();
218
m_pMenuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
220
AppVersion pgmVersion;
221
m_AppName = wxT("BrowseTracker");
224
wxLog::EnableLogging(true);
225
m_pLog = new wxLogWindow( m_pAppWin, _T(" BrowseTracker Plugin"),true,false);
226
wxLog::SetActiveTarget( m_pLog);
227
m_pLog->GetFrame()->SetSize(20,30,600,300);
228
LOGIT( _T("BrowseTracker Plugin Logging Started[%s]"),pgmVersion.GetVersion().c_str());
232
// Set current plugin version
233
PluginInfo* pInfo = (PluginInfo*)(Manager::Get()->GetPluginManager()->GetPluginInfo(this));
234
pInfo->version = pgmVersion.GetVersion();
236
// ---------------------------------------
237
// determine location of settings
238
// ---------------------------------------
239
wxStandardPaths stdPaths;
240
// memorize the key file name as {%HOME%}\codesnippets.ini
241
m_ConfigFolder = stdPaths.GetUserDataDir();
243
LOGIT( _T("Argv[0][%s] Cwd[%s]"), wxTheApp->argv[0], ::wxGetCwd().GetData() );
245
m_ExecuteFolder = FindAppPath(wxTheApp->argv[0], ::wxGetCwd(), wxEmptyString);
247
//GTK GetConfigFolder is returning double "//?, eg, "/home/pecan//.codeblocks"
248
// remove the double //s from filename //+v0.4.11
249
m_ConfigFolder.Replace(_T("//"),_T("/"));
250
m_ExecuteFolder.Replace(_T("//"),_T("/"));
252
LOGIT(wxT("CfgFolder[%s]"),m_ConfigFolder.c_str());
253
LOGIT(wxT("ExecFolder[%s]"),m_ExecuteFolder.c_str());
256
// get the CodeBlocks "personality" argument
257
wxString m_Personality = Manager::Get()->GetPersonalityManager()->GetPersonality();
258
if (m_Personality == wxT("default")) m_Personality = wxEmptyString;
260
// if codesnippets.ini is in the executable folder, use it
261
// else use the default config folder
262
m_CfgFilenameStr = m_ExecuteFolder + wxFILE_SEP_PATH;
263
if (not m_Personality.IsEmpty()) m_CfgFilenameStr << m_Personality + wxT(".") ;
264
m_CfgFilenameStr << m_AppName + _T(".ini");
266
if (::wxFileExists(m_CfgFilenameStr)) {;/*OK Use exe path*/}
267
else // use the default.conf folder
268
{ m_CfgFilenameStr = m_ConfigFolder + wxFILE_SEP_PATH;
269
if (not m_Personality.IsEmpty()) m_CfgFilenameStr << m_Personality + wxT(".") ;
270
m_CfgFilenameStr << m_AppName + _T(".ini");
271
// if default doesn't exist, create it
272
if (not ::wxDirExists(m_ConfigFolder))
273
::wxMkdir(m_ConfigFolder);
275
// ---------------------------------------
276
// Initialize Globals
277
// ---------------------------------------
278
TrackerCfgFullPath = m_CfgFilenameStr;
280
LOGIT( _T("TrackerCfgFullPath[%s]"),TrackerCfgFullPath.c_str() );
283
// SettingLoad() of user options;
284
BrowseTrackerCfg btCfg;
285
btCfg.ReadUserOptions(m_CfgFilenameStr);
286
m_BrowseMarksEnabled = btCfg.m_BrowseMarksEnabled;
287
m_UserMarksStyle = btCfg.m_UserMarksStyle;
288
m_ToggleKey = btCfg.m_ToggleKey;
289
m_LeftMouseDelay = btCfg.m_LeftMouseDelay;
290
m_ClearAllKey = btCfg.m_ClearAllKey;
292
switch(m_UserMarksStyle)
294
case BrowseMarksStyle:
296
gBrowse_MarkerId = BROWSETRACKER_MARKER ;
297
gBrowse_MarkerStyle = BROWSETRACKER_MARKER_STYLE;
302
gBrowse_MarkerId = BOOKMARK_MARKER;
303
gBrowse_MarkerStyle = BOOKMARK_STYLE;
306
case HiddenMarksStyle:
308
gBrowse_MarkerId = BROWSETRACKER_MARKER;
309
gBrowse_MarkerStyle = BROWSETRACKER_HIDDEN_STYLE;
314
// Hook to plugin events
316
// EVT_APP_START_SHUTDOWN( BrowseTracker::OnRelease)
317
Manager::Get()->RegisterEventSink(cbEVT_APP_START_SHUTDOWN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnStartShutdown));
320
// EVT_EDITOR_ACTIVATED( BrowseTracker::OnEditorActivated)
321
Manager::Get()->RegisterEventSink(cbEVT_EDITOR_ACTIVATED, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorActivated));
322
// EVT_EDITOR_DEACTIVATED( BrowseTracker::OnEditorActivated)
323
//-Manager::Get()->RegisterEventSink(cbEVT_EDITOR_DEACTIVATED, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorDeactivated));
324
// EVT_EDITOR_CLOSE( BrowseTracker::OnEditorClosed)
325
Manager::Get()->RegisterEventSink(cbEVT_EDITOR_CLOSE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorClosed));
326
// EVT_EDITOR_OPEN( BrowseTracker::OnEditorOpen)
327
Manager::Get()->RegisterEventSink(cbEVT_EDITOR_OPEN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnEditorOpened));
330
// EVT_PROJECT_OPEN( BrowseTracker::OnProjectOpened)
331
Manager::Get()->RegisterEventSink(cbEVT_PROJECT_OPEN, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectOpened));
332
// EVT_PROJECT_CLOSE( BrowseTracker::OnProjectOpened)
333
Manager::Get()->RegisterEventSink(cbEVT_PROJECT_CLOSE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectClosing));
335
// EVT_PROJECT_ACTIVATE( BrowseTracker::OnProjectActivated)
336
Manager::Get()->RegisterEventSink(cbEVT_PROJECT_ACTIVATE, new cbEventFunctor<BrowseTracker, CodeBlocksEvent>(this, &BrowseTracker::OnProjectActivatedEvent));
338
// hook to project loading procedure
339
// This hook only occurs if the project has an "extension" xml entry
340
ProjectLoaderHooks::HookFunctorBase* myProjhook = new ProjectLoaderHooks::HookFunctor<BrowseTracker>(this, &BrowseTracker::OnProjectLoadingHook);
341
m_ProjectHookId = ProjectLoaderHooks::RegisterHook(myProjhook);
344
EditorHooks::HookFunctorBase* myEdhook = new EditorHooks::HookFunctor<BrowseTracker>(this, &BrowseTracker::OnEditorEventHook);
345
m_EditorHookId = EditorHooks::RegisterHook(myEdhook);
349
// ----------------------------------------------------------------------------
350
void BrowseTracker::OnRelease(bool appShutDown)
351
// ----------------------------------------------------------------------------
353
// ------------------------------------------------------------
354
// watch out, CodeBlocks can enter this routine multiple times
355
// ------------------------------------------------------------
359
//*SDK Gotcha* A cbEVT_PROJECT_CLOSE is issued, but only
360
// after the plugin OnRelease() is called. So we
361
// simulate closing all open projects in order to save
362
// current Browse/Book marks in layout
363
ProjectsArray* pPrjs = m_pPrjMgr->GetProjects();
364
for (size_t i=0; i<pPrjs->GetCount(); ++i )
366
CodeBlocksEvent evtpa(cbEVT_PROJECT_ACTIVATE);
367
evtpa.SetProject(pPrjs->Item(i));
368
OnProjectActivatedEvent(evtpa);
370
CodeBlocksEvent evtpc(cbEVT_PROJECT_CLOSE);
371
evtpc.SetProject(pPrjs->Item(i));
372
OnProjectClosing(evtpc);
375
// remove project load/save hook
376
ProjectLoaderHooks::UnregisterHook(m_ProjectHookId, true);
378
// remove editor/scintilla hook
379
EditorHooks::UnregisterHook(m_EditorHookId, true);
382
int idx = m_pMenuBar->FindMenu(_("View"));
383
if (idx != wxNOT_FOUND)
385
wxMenu* viewMenu = m_pMenuBar->GetMenu(idx);
386
viewMenu->Destroy(idMenuViewTracker);
389
// *Book_Marks* release the editor hash table ptrs to Book_Marks
390
for (EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.begin(); it != m_EdBook_MarksHash.end(); ++it)
394
m_EdBook_MarksHash.clear();
396
// *BrowseMarks* release the editor hash table ptrs to BrowseMarks
397
for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); ++it)
401
m_EbBrowse_MarksHash.clear();
403
// *ProjectData* release any ProjectData remaining in the ProjectDataHash
404
for (ProjectDataHash::iterator it = m_ProjectDataHash.begin(); it != m_ProjectDataHash.end(); ++it)
408
m_ProjectDataHash.clear();
413
// ----------------------------------------------------------------------------
414
void BrowseTracker::BuildMenu(wxMenuBar* menuBar)
415
// ----------------------------------------------------------------------------
417
m_pMenuBar = menuBar;
419
int idx = menuBar->FindMenu(_("View"));
420
if (idx != wxNOT_FOUND)
422
wxMenu* viewMenu = menuBar->GetMenu(idx);
424
wxMenu* pforwardBackwardSubMenu = new wxMenu(wxT(""));
425
pforwardBackwardSubMenu->Append(idMenuTrackerBackward, _("Backward Ed\tAlt-Left"), _("Browse Backward"));
426
pforwardBackwardSubMenu->Append(idMenuTrackerforward, _("Forward Ed\tAlt-Right"), _("Browse forward"));
427
pforwardBackwardSubMenu->Append(idMenuBrowseMarkPrevious, _("Prev Mark\tAlt-Up"), _("Browse Up"));
428
pforwardBackwardSubMenu->Append(idMenuBrowseMarkNext, _("Next Mark\tAlt-Down"), _("Browse Down"));
429
pforwardBackwardSubMenu->AppendSeparator();
430
pforwardBackwardSubMenu->Append(idMenuRecordBrowseMark, _("Set BrowseMark"), _("Record Browse Mark"));
431
pforwardBackwardSubMenu->Append(idMenuClearBrowseMark, _("Clear BrowseMark"), _("Unset Browse Mark"));
432
pforwardBackwardSubMenu->Append(idMenuSortBrowse_Marks, _("Sort BrowseMarks"), _("Sort Browse Marks"));
433
pforwardBackwardSubMenu->Append(idMenuClearAllBrowse_Marks, _("Clear All BrowseMarks"), _("Unset All Browse Marks"));
434
pforwardBackwardSubMenu->AppendSeparator();
435
pforwardBackwardSubMenu->Append(idMenuTrackerClear, _("Clear All"), _("Clear History"));
436
pforwardBackwardSubMenu->Append(idMenuConfigBrowse_Marks, _("Settings"), _("Configure"));
438
pforwardBackwardSubMenu->Append(idMenuTrackerDump, _("Dump Arrays"), _("Dump Arrays"));
440
viewMenu->Append(idMenuViewTracker, _("Browse Tracker"), pforwardBackwardSubMenu , _("Browse Tracker"));
444
LOGIT(wxT("Menubar[%p]idMenuViewTracker[%d]"),menuBar, idMenuViewTracker);
449
// ----------------------------------------------------------------------------
450
void BrowseTracker::BuildModuleMenu(const ModuleType type, wxMenu* popup, const FileTreeData* data)
451
// ----------------------------------------------------------------------------
453
//Some library module is ready to display a pop-up menu.
454
//Check the parameter \"type\" and see which module it is
455
//and append any items you need in the menu...
456
//TIP: for consistency, add a separator as the first item...
458
if (not IsAttached() ) return;
459
if (type != mtEditorManager) return;
461
// obtain ptr to menus menu
462
wxMenuBar* pMenuBar = Manager::Get()->GetAppFrame()->GetMenuBar();
464
// Ask for the submenu containing the first BrowseTracker menu item
465
wxMenuItem* pbtMenuItem = pMenuBar->FindItem(idMenuTrackerforward, &pbtMenu);
466
if (not pbtMenuItem) return;
468
// Reproduce the BrowseTracker menu onto a Context Menu sub_menu
469
int knt = pbtMenu->GetMenuItemCount();
472
wxMenu* sub_menu = new wxMenu;
473
// search the BrowseTracker main menu, duplicating each macro item
474
// on to a context menu sub-menu without the command keys.
475
for (int i=0; i<knt; ++i)
477
wxMenuItem* item = pbtMenu->FindItemByPosition(i);
478
int menuId = item->GetId();
479
wxString menuLabel = item->GetLabel();
480
///LOGIT( _T("OnContextMenu insert[%s]"),menuLabel.c_str() );
481
wxMenuItem* pContextItem= new wxMenuItem(0, menuId, menuLabel);
482
sub_menu->Append( pContextItem );
484
popup->AppendSeparator();
485
pbtMenuItem = new wxMenuItem(0, wxID_ANY, _("Browse Tracker"), _T(""), wxITEM_NORMAL);
486
pbtMenuItem->SetSubMenu(sub_menu);
487
popup->Append(pbtMenuItem);
490
// ----------------------------------------------------------------------------
491
wxString BrowseTracker::GetPageFilename(int index)
492
// ----------------------------------------------------------------------------
494
// Load BrowseTracker XML history file for this project
495
wxString filename = wxEmptyString;
496
EditorBase* eb = GetEditor(index);
497
if (not eb) return filename;
499
EditorManager* EdMgr = Manager::Get()->GetEditorManager();
501
if (-1 == EdMgr->FindPageFromEditor(eb) )
502
{ // this entry has been closed behind our backs
504
///#if defined(LOGGING)
505
/// LOGIT( _T("GetEditorFilename Removing ed[%p]"), GetEditor(index) );
507
RemoveEditor( GetEditor(index) );
510
filename = eb->GetShortName();
513
// ----------------------------------------------------------------------------
514
wxString BrowseTracker::GetPageFilename(EditorBase* eb)
515
// ----------------------------------------------------------------------------
517
// Ask Notebook for short file name of EditorBase.
518
// If no page returned, file is not open
520
wxString filename = wxEmptyString;
521
if (not eb) return filename;
523
if (-1 == Manager::Get()->GetEditorManager()->FindPageFromEditor(eb) )
524
{ // this entry has been closed behind our backs
528
filename = eb->GetShortName();
531
// ----------------------------------------------------------------------------
532
int BrowseTracker::GetEditor(EditorBase* eb)
533
// ----------------------------------------------------------------------------
535
// return the editor index from our array of user activated editos
536
for (int i=0; i<MaxEntries; ++i )
537
if ( m_apEditors[i] == eb ) return i;
540
// ----------------------------------------------------------------------------
541
EditorBase* BrowseTracker::GetEditor(int index)
542
// ----------------------------------------------------------------------------
544
// return the EditorBase* from our array of user activated editors
545
return m_apEditors[index];
547
// ----------------------------------------------------------------------------
548
EditorBase* BrowseTracker::GetCurrentEditor()
549
// ----------------------------------------------------------------------------
551
// return the EditorBase* of the currently activated editor
552
return GetEditor(m_CurrEditorIndex);
554
// ----------------------------------------------------------------------------
555
int BrowseTracker::GetCurrentEditorIndex()
556
// ----------------------------------------------------------------------------
558
// return the index of the currently activated editor
559
if ( GetEditorBrowsedCount() )
560
return m_CurrEditorIndex;
563
// ----------------------------------------------------------------------------
564
EditorBase* BrowseTracker::GetPreviousEditor()
565
// ----------------------------------------------------------------------------
567
// return the EditorBase* of the previoiusly user activated editor
569
int index = m_CurrEditorIndex;
570
for (int i = 0; i<MaxEntries; ++i)
573
if (index < 0) index = MaxEntries-1;
574
p = GetEditor(index);
579
// ----------------------------------------------------------------------------
580
int BrowseTracker::GetEditorBrowsedCount()
581
// ----------------------------------------------------------------------------
584
///LOGIT( _T("GetEditorBrowsedCount()[%d]"), m_nBrowsedEditorCount );
586
return m_nBrowsedEditorCount;
588
// ----------------------------------------------------------------------------
589
int BrowseTracker::GetPreviousEditorIndex()
590
// ----------------------------------------------------------------------------
592
// return the index of the previously user activated editor
595
int index = m_CurrEditorIndex;
596
// scan for previous editor, skipping nulls (null is a closed editors)
597
for (int i=0; i<MaxEntries; ++i)
600
if ( index < 0 ) index = MaxEntries-1;
601
eb = GetEditor(index);
606
/// LOGIT( _T("GetPreviousEditorIndex[%d][%p][%s]"), index, eb, eb?eb->GetShortName().c_str():wxEmptyString );
608
if ( not eb) index = -1;
611
// ----------------------------------------------------------------------------
612
void BrowseTracker::SetSelection(int index)
613
// ----------------------------------------------------------------------------
615
// user has selected an editor, make it active
617
if ((index < 0) || (index >= MaxEntries )) return;
619
EditorBase* eb = GetEditor(index);
622
//-int page = Manager::Get()->GetEditorManager()->FindPageFromEditor(eb);
623
Manager::Get()->GetEditorManager()->SetActiveEditor(eb);
625
LOGIT( _T("SetSelection[%d] editor[%p][%s]"), index, eb, eb->GetShortName().c_str() );
628
// Tell OnIdle to focus the new editor. CB sdk editorManager::OnUpdateUI used to
629
// do this for us, but someone broke it.
630
m_UpdateUIFocusEditor = true;
633
// ----------------------------------------------------------------------------
634
void BrowseTracker::OnMenuTrackerSelect(wxCommandEvent& event)
635
// ----------------------------------------------------------------------------
637
// create a selection popup, allow user to choose an editor to activate
639
if ( GetEditorBrowsedCount() == 0) return;
641
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
642
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
643
if ((not eb) || (not cbed)) return;
645
m_popupWin = new BrowseSelector( wxTheApp->GetTopWindow(), this, event.GetId() == idMenuTrackerforward );
646
m_popupWin->ShowModal();
647
m_popupWin->Destroy();
650
// ----------------------------------------------------------------------------
651
void BrowseTracker::OnMenuBrowseMarkPrevious(wxCommandEvent& event)
652
// ----------------------------------------------------------------------------
654
// For cbEditors, position to previous memorized cursor position
656
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
657
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
660
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
662
GetCurrentScreenPositions();
663
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
664
int newPos = EdBrowse_Marks.GetMarkCurrent();
665
//#if defined(LOGGING)
666
//LOGIT( _T("curPos[%d]m_CurrScrTopPosn[%d]m_CurrScrLastPosn[%d]"),
667
// newPos, m_CurrScrTopPosn, m_CurrScrLastPosn);
670
// if current browse mark is off screen, go to "current", not "pevious"
671
if ( ((newPos < m_CurrScrTopPosn) || (newPos > m_CurrScrLastPosn))
673
/*use current mark*/;
674
else newPos = EdBrowse_Marks.GetMarkPrevious();
675
if (newPos == -1) break;
677
cbStyledTextCtrl* control = cbed->GetControl();
678
int line = control->LineFromPosition(newPos);
679
if ( LineHasBrowseMarker(control, line) )
680
{ // center the BrowseMark line if off screen
681
if ( (line < m_CurrScrTopLine) || (line > m_CurrScrLastLine ))
682
cbed->GotoLine(line, true); // gotoline centers the line on the screen
683
control->GotoPos(newPos); // gotopos puts cursor at correct offset
684
GetCurrentScreenPositions();
686
///LOGIT( _T("OnMenuBrowseMarkPrev: pos[%d]line[%d]eb[%p][%s]"),
687
/// newPos, control->LineFromPosition(newPos), eb, eb->GetShortName().c_str() );
692
// rebuild and retry, but guard against any possible loop
693
if ( m_nBrowseMarkPreviousSentry++ ) break;
694
EdBrowse_Marks.ImportBrowse_Marks(); // Browse marks out of sync
695
OnMenuBrowseMarkPrevious( event ); //retry
700
m_nBrowseMarkPreviousSentry = 0;
702
}//OnMenuBrowseMarkPrevious
703
// ----------------------------------------------------------------------------
704
void BrowseTracker::OnMenuBrowseMarkNext(wxCommandEvent& event)
705
// ----------------------------------------------------------------------------
707
// For cbEditors, position to next memorized cursor position
709
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
710
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
713
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
715
GetCurrentScreenPositions();
716
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
717
int newPos = EdBrowse_Marks.GetMarkCurrent();
718
// if current browse mark is off screen, go to "current", not "next"
719
if ( ((newPos < m_CurrScrTopPosn) || (newPos > m_CurrScrLastPosn))
721
/*use current mark*/;
722
else newPos = EdBrowse_Marks.GetMarkNext();
723
if (newPos == -1) break;
725
cbStyledTextCtrl* control = cbed->GetControl();
726
int line = control->LineFromPosition(newPos);
727
if ( LineHasBrowseMarker(control, line) )
728
{ // center the BrowseMark line if off screen
729
if ( (line < m_CurrScrTopLine) || (line > m_CurrScrLastLine) )
730
cbed->GotoLine(line, true); // gotoline centers the line on the screen
731
control->GotoPos(newPos); // gotopos puts cursor at correct offset
732
GetCurrentScreenPositions();
734
///LOGIT( _T("OnMenuBrowseMarkNext: pos[%d]line[%d]eb[%p][%s]"),
735
/// newPos, control->LineFromPosition(newPos), eb, eb->GetShortName().c_str() );
740
// rebuild, but guard against any possible loop
741
if ( m_nBrowseMarkNextSentry++ ) break;
742
EdBrowse_Marks.ImportBrowse_Marks(); // Browse marks out of sync
743
OnMenuBrowseMarkNext( event ); // retry
748
m_nBrowseMarkNextSentry = 0;
750
}//OnMenuBrowseMarkNext
751
// ----------------------------------------------------------------------------
752
void BrowseTracker::OnMenuRecordBrowseMark(wxCommandEvent& event)
753
// ----------------------------------------------------------------------------
755
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
756
if (eb) RecordBrowseMark(eb);
758
// ----------------------------------------------------------------------------
759
void BrowseTracker::OnMenuClearBrowseMark(wxCommandEvent& event)
760
// ----------------------------------------------------------------------------
762
//LOGIT( _T("ClearBrowseMark") );
763
bool removeScreenMark = true;
764
ClearLineBrowseMark(removeScreenMark);
765
if ( GetBrowseMarkerId() == BOOKMARK_MARKER ) ClearLineBookMark();
767
// ----------------------------------------------------------------------------
768
void BrowseTracker::ClearLineBrowseMark(bool removeScreenMark)
769
// ----------------------------------------------------------------------------
771
// clear BrowseMarks for a current line. If the line has no marker
772
// clear All markers.
774
///LOGIT( _T("ClearBrowseMark") );
775
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
776
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
779
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
781
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
782
GetCurrentScreenPositions();
783
EdBrowse_Marks.ClearMark( m_CurrScrLineStartPosn, m_CurrScrLineEndPosn);
784
cbStyledTextCtrl* control = cbed->GetControl();
785
int line = control->LineFromPosition(m_CurrScrLineStartPosn);
786
if ( removeScreenMark )
787
if ( LineHasBrowseMarker(control,line) )
788
MarkRemove(cbed->GetControl(), line);
790
LOGIT( _T("ClearLineBROWSEMark Current Line[%d]"),m_CurrScrLine );
795
////// ----------------------------------------------------------------------------
796
////void BrowseTracker::ClearLineBrowseMark(int posn)
797
////// ----------------------------------------------------------------------------
799
//// // clear BrowseMarks for a single line
801
//// ///LOGIT( _T("ClearBrowseMark") );
802
//// EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
803
//// cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
806
//// if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
808
//// BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
809
//// cbStyledTextCtrl* control = cbed->GetControl();
810
//// int line = control->LineFromPosition(posn);
811
//// int start = control->PositionFromLine( line );
812
//// int end = start + control->LineLength( line );
813
//// EdBrowse_Marks.ClearMark( start, end );
814
//// if ( LineHasBrowseMarker(control,line) )
815
//// MarkRemove( control, line);
816
//// #if defined(LOGGING)
817
//// LOGIT( _T("ClearLineBrowse_MarksByPosn Line[%d]Posn[%d]"), line, posn );
822
// ----------------------------------------------------------------------------
823
void BrowseTracker::SetBrowseMarksStyle( int userStyle)
824
// ----------------------------------------------------------------------------
826
// BrowseMarks, BookMarks, or Hidden style
828
BrowseMarks* pBrowse_Marks = 0;
829
for (int i=0; i<MaxEntries ; ++i )
831
EditorBase* eb = GetEditor(i);
832
if (eb) pBrowse_Marks = GetBrowse_MarksFromHash( eb);
833
if (eb && pBrowse_Marks) pBrowse_Marks->SetBrowseMarksStyle( userStyle);
836
// ----------------------------------------------------------------------------
837
void BrowseTracker::OnMenuSortBrowse_Marks( wxCommandEvent& event)
838
// ----------------------------------------------------------------------------
840
// sort the BrowseMarks by simply importing them from scintilla
842
EditorBase* eb = GetCurrentEditor();
843
BrowseMarks* pBrowse_Marks = GetBrowse_MarksFromHash( eb);
844
if (eb && pBrowse_Marks) pBrowse_Marks->ImportBrowse_Marks();
846
// ----------------------------------------------------------------------------
847
void BrowseTracker::OnMenuConfigBrowse_Marks( wxCommandEvent& event)
848
// ----------------------------------------------------------------------------
852
int oldUserMarksStyle = m_UserMarksStyle;
853
bool oldBrowseMarksEnabled = m_BrowseMarksEnabled;
854
//invoke user options dialog
855
BrowseTrackerCfg btCfg;
856
btCfg.GetUserOptions( m_CfgFilenameStr );
858
// reset options according to user responses
859
m_BrowseMarksEnabled = btCfg.m_BrowseMarksEnabled;
860
m_UserMarksStyle = btCfg.m_UserMarksStyle;
861
m_ToggleKey = btCfg.m_ToggleKey;
862
m_LeftMouseDelay = btCfg.m_LeftMouseDelay;
863
m_ClearAllKey = btCfg.m_ClearAllKey;
865
// Don't allow set and clear_all key to be the same
866
while ( (m_ToggleKey == Ctrl_Left_Mouse) && (m_ClearAllKey == ClearAllOnSingleClick) )
868
msg.Printf(_("Program cannot use CTRL-LEFT_MOUSE as both a \nToggle key *AND* a Clear-All-Key"));
869
cbMessageBox(msg, _("Error"), wxICON_ERROR);
871
m_ClearAllKey = ClearAllOnDoubleClick;
872
btCfg.GetUserOptions( m_CfgFilenameStr );
874
m_UserMarksStyle = btCfg.m_UserMarksStyle;
875
m_ToggleKey = btCfg.m_ToggleKey;
876
m_LeftMouseDelay = btCfg.m_LeftMouseDelay;
877
m_ClearAllKey = btCfg.m_ClearAllKey;
880
// Don't allow set and clear all key to be the same
881
if ( (m_ToggleKey == Ctrl_Left_Mouse) && (m_ClearAllKey == ClearAllOnSingleClick) )
882
m_ClearAllKey = ClearAllOnDoubleClick;
885
LOGIT( _T("New Config values: BrowseMarksStyle[%d]ToggleKey[%d]MouseDelay[%d]ClearKey[%d]"),
886
m_UserMarksStyle, m_ToggleKey, m_LeftMouseDelay, m_ClearAllKey);
888
if (oldUserMarksStyle not_eq m_UserMarksStyle)
889
SetBrowseMarksStyle( m_UserMarksStyle );
891
if (oldBrowseMarksEnabled not_eq m_BrowseMarksEnabled )
893
// Simulate activation of the current editor so mouse
894
// events get connected.
895
EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
900
OnEditorActivated(evt);
904
// ----------------------------------------------------------------------------
905
void BrowseTracker::OnMenuClearAllBrowse_Marks(wxCommandEvent& event)
906
// ----------------------------------------------------------------------------
908
ClearAllBrowse_Marks(/*clearScreenMarks*/true);
910
// ----------------------------------------------------------------------------
911
void BrowseTracker::ClearAllBrowse_Marks(bool clearScreenMarks)
912
// ----------------------------------------------------------------------------
914
// Clear every BrowseMark for the currently active editor
916
///LOGIT( _T("ClearAllBrowseMark") );
917
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
918
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
921
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
923
cbStyledTextCtrl* control = cbed->GetControl();
924
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
925
EdBrowse_Marks.ClearAllBrowse_Marks();
926
if (clearScreenMarks) control->MarkerDeleteAll( GetBrowseMarkerId());
928
LOGIT( _T("ClearAllBrowseMarks()") );
931
// When using Book marks as Browse marks, clear book marks also
932
if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
933
if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
935
cbStyledTextCtrl* control = cbed->GetControl();
936
BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
937
EdBook_Marks.ClearAllBrowse_Marks();
938
if (clearScreenMarks) control->MarkerDeleteAll( GetBrowseMarkerId());
940
LOGIT( _T("ClearAllBookMarks()") );
945
// ----------------------------------------------------------------------------
946
void BrowseTracker::GetCurrentScreenPositions()
947
// ----------------------------------------------------------------------------
949
// Update copy of current editor screen data
951
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
952
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
955
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
957
//-BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
958
cbStyledTextCtrl* control = cbed->GetControl();
959
int m_CurrScrPosn = control->GetCurrentPos();
960
//-if (curPos == -1) break;
962
m_CurrScrLine = control->LineFromPosition(m_CurrScrPosn);
963
m_CurrScrTopLine = control->GetFirstVisibleLine();
964
m_CurrLinesOnScreen = control->LinesOnScreen();
965
m_CurrScrLastLine = m_CurrScrTopLine + m_CurrLinesOnScreen;
967
m_CurrScrTopPosn = control->PositionFromLine(m_CurrScrTopLine);
968
m_CurrScrLastPosn = control->PositionFromLine(m_CurrScrLastLine);
969
// Lines might not fill the screen.
970
if (m_CurrScrLastPosn == -1)
971
m_CurrScrLastPosn = control->PositionFromLine(control->GetLineCount());
973
m_CurrScrLineStartPosn = control->PositionFromLine(m_CurrScrLine);
974
m_CurrScrLineLength = control->LineLength(m_CurrScrLine);
975
m_CurrScrLineEndPosn = m_CurrScrLineStartPosn + m_CurrScrLineLength;
978
//LOGIT( _T("UpdateCurrent: CurentLine[%d]TopLine[%d]ScrnLines[%d]LastLine[%d]"),
979
// m_CurrScrLine, m_CurrScrTopLine, m_CurrLinesOnScreen, m_CurrScrLastLine );
980
//LOGIT( _T("UpdateCurrent: CurrPosn[%d]TopPosn[%d]LastPosn[%d]"),
981
// m_CurrScrPosn, m_CurrScrTopPosn, m_CurrScrLastPosn );
986
// ----------------------------------------------------------------------------
987
void BrowseTracker::OnMouseKeyEvent(wxMouseEvent& event)
988
// ----------------------------------------------------------------------------
990
// Record the cursor position when user holds down the left mouse key;
991
// If user is also holding down the control key, clear the browse marks
994
if ( (not IsAttached()) || (not m_InitDone) )
995
{ event.Skip(); return; }
996
if (not IsBrowseMarksEnabled() )
997
{ event.Skip(); return; }
999
if ( ( event.GetEventType() == wxEVT_LEFT_UP)
1000
|| ( event.GetEventType() == wxEVT_LEFT_DOWN)
1001
|| ( event.GetEventType() == wxEVT_LEFT_DCLICK)
1002
|| ( event.GetEventType() == wxEVT_MOTION)
1005
// -- MOUSE_MOTION -------------------------------------------
1006
if (event.GetEventType() == wxEVT_MOTION)
1008
// ignore dragging events even if key is held down
1009
if (event.LeftIsDown() && event.Dragging())
1010
{ //allow nervous movement if not really dragging
1011
if ( (abs(event.GetX() - m_MouseXPosn) >3)
1012
or (abs(event.GetY() - m_MouseYPosn) >3) )
1013
m_IsMouseDoubleClick = true;
1017
// Skip unmonitored editors
1018
EditorBase* eb = m_pEdMgr->GetActiveEditor();
1019
if (m_EbBrowse_MarksHash.find(eb) == m_EbBrowse_MarksHash.end() )
1021
cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
1022
if (not cbed) break;
1023
cbStyledTextCtrl* pControl = cbed->GetControl();
1025
// -- MOUSE_KEY_DOWN --------------------------------------------
1026
if (event.GetEventType() == wxEVT_LEFT_DOWN)
1027
{ //Record the mouse down time
1028
#if defined(LOGGING)
1029
////LOGIT( _T("Mouse DOWN") );
1031
m_MouseDownTime = ::wxGetLocalTimeMillis();
1032
m_MouseXPosn = event.GetX(); m_MouseYPosn = event.GetY();
1033
// A double click substitutes for the Mouse_Down event
1034
// so we can clear it here.
1035
m_IsMouseDoubleClick = false;
1039
// -- MOUSE_KEY_DCLICK ------------------------------------
1040
if (event.GetEventType() == wxEVT_LEFT_DCLICK)
1041
{ // Tell wxEVT_LEFT_UP about double clicks
1042
#if defined(LOGGING)
1043
////LOGIT( _T("Double Click") );
1045
m_IsMouseDoubleClick = true;
1049
// -- MOUSE_KEY_UP ----------------------------------------
1050
if (event.GetEventType() == wxEVT_LEFT_UP)
1051
{ // we're monitoring this editor, record/clear this cursor position
1052
#if defined(LOGGING)
1053
////LOGIT( _T("Mouse UP") );
1056
bool ctrlKeyIsDown = ::wxGetMouseState().ControlDown();
1057
bool useOnlyLeftMouse = (m_ToggleKey == Left_Mouse);
1058
bool useCtrlLeftMouse = (m_ToggleKey == Ctrl_Left_Mouse);
1059
bool clearUsesDoubleClick = (m_ClearAllKey == ClearAllOnDoubleClick);
1060
bool clearUsesSingleClick = (m_ClearAllKey == ClearAllOnSingleClick);
1062
// -- ONLY_LEFT_MOUSE --
1063
if ( useOnlyLeftMouse )
1064
{ if( ctrlKeyIsDown && clearUsesDoubleClick && m_IsMouseDoubleClick)
1065
{ //Clear all on Ctrl Double Click
1066
ClearAllBrowse_Marks(/*clearScreenMarks*/true);
1067
m_IsMouseDoubleClick = false;
1068
pControl->SetSelection (-1, pControl->GetCurrentPos()); //clear selection
1071
if (ctrlKeyIsDown && clearUsesSingleClick)
1072
{ //Clear all on Ctrl Single Click
1073
ClearAllBrowse_Marks(/*clearScreenMarks*/true);
1076
if ( ctrlKeyIsDown) break; //This is useOnlyLeftMouse w/o ctrl
1077
if ( m_IsMouseDoubleClick) break;
1078
wxLongLong mouseDwellMillisecs = ::wxGetLocalTimeMillis() - m_MouseDownTime;
1079
if (mouseDwellMillisecs >= m_LeftMouseDelay)
1080
RecordBrowseMark(eb);
1082
}//if useOnlyLeftMouse
1084
// -- CTRL-LEFT_MOUSE --
1085
if ( useCtrlLeftMouse && ctrlKeyIsDown)
1086
{ if( clearUsesDoubleClick && m_IsMouseDoubleClick)
1087
{ //Clear all on Ctrl Double Click
1088
ClearAllBrowse_Marks(/*clearScreenMarks*/true);
1089
m_IsMouseDoubleClick = false;
1090
pControl->SetSelection (-1, pControl->GetCurrentPos()); //clear selection
1093
RecordBrowseMark(eb);
1095
}//if useCtrlLeftMouse
1102
// ----------------------------------------------------------------------------
1103
// BROWSETRACKER_MARKER scintilla test/set/unset marker routines
1104
// ----------------------------------------------------------------------------
1105
bool BrowseTracker::LineHasBookMarker(cbStyledTextCtrl* pControl, int line) const
1108
line = pControl->GetCurrentLine();
1109
//-return pControl->MarkerGet(line) & (1 << BOOKMARK_MARKER);
1110
return pControl->MarkerGet(line) & (1 << GetBrowseMarkerId());
1112
// ----------------------------------------------------------------------------
1113
bool BrowseTracker::LineHasBrowseMarker(cbStyledTextCtrl* pControl, int line) const
1116
line = pControl->GetCurrentLine();
1117
//-return pControl->MarkerGet(line) & (1 << BROWSETRACKER_MARKER);
1118
return pControl->MarkerGet(line) & (1 << GetBrowseMarkerId());
1120
// ----------------------------------------------------------------------------
1121
void BrowseTracker::MarkerToggle(cbStyledTextCtrl* pControl, int line)
1124
line = pControl->GetCurrentLine();
1125
if (LineHasBrowseMarker(pControl, line))
1126
//-pControl->MarkerDelete(line, BROWSETRACKER_MARKER);
1127
pControl->MarkerDelete(line, GetBrowseMarkerId());
1129
//-pControl->MarkerAdd(line, BROWSETRACKER_MARKER);
1130
pControl->MarkerAdd(line, GetBrowseMarkerId());
1132
// ----------------------------------------------------------------------------
1133
void BrowseTracker::MarkerNext(cbStyledTextCtrl* pControl)
1135
int line = pControl->GetCurrentLine() + 1;
1136
//-int newLine = pControl->MarkerNext(line, 1 << BROWSETRACKER_MARKER);
1137
int newLine = pControl->MarkerNext(line, 1 << GetBrowseMarkerId());
1139
pControl->GotoLine(newLine);
1141
// ----------------------------------------------------------------------------
1142
void BrowseTracker::MarkerPrevious(cbStyledTextCtrl* pControl)
1144
int line = pControl->GetCurrentLine() - 1;
1145
//-int newLine = pControl->MarkerPrevious(line, 1 << BROWSETRACKER_MARKER);
1146
int newLine = pControl->MarkerPrevious(line, 1 << GetBrowseMarkerId());
1148
pControl->GotoLine(newLine);
1150
// ----------------------------------------------------------------------------
1151
void BrowseTracker::MarkLine(cbStyledTextCtrl* pControl, int line)
1154
//-pControl->MarkerDeleteAll(BROWSETRACKER_MARKER);
1155
pControl->MarkerDeleteAll(GetBrowseMarkerId());
1157
//-pControl->MarkerAdd(line, BROWSETRACKER_MARKER);
1158
pControl->MarkerAdd(line, GetBrowseMarkerId());
1160
// ----------------------------------------------------------------------------
1161
void BrowseTracker::MarkRemove(cbStyledTextCtrl* pControl, int line)
1164
line = pControl->GetCurrentLine();
1165
if (LineHasBrowseMarker(pControl, line))
1166
//-pControl->MarkerDelete(line, BROWSETRACKER_MARKER);
1167
pControl->MarkerDelete(line, GetBrowseMarkerId());
1169
// ----------------------------------------------------------------------------
1170
void BrowseTracker::RecordBrowseMark(EditorBase* eb)
1171
// ----------------------------------------------------------------------------
1173
// stow a browse mark by EditorBase current line
1175
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
1178
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
1180
cbStyledTextCtrl* control = cbed->GetControl();
1181
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
1182
GetCurrentScreenPositions();
1183
// Toggle BrowseMark
1184
if ( LineHasBrowseMarker(control, m_CurrScrLine) )
1186
ClearLineBrowseMark(/*removeScreenmark*/true); //clear previous marks
1187
if ( GetBrowseMarkerId() == BOOKMARK_MARKER ) ClearLineBookMark();
1190
int pos = control->GetCurrentPos();
1191
EdBrowse_Marks.RecordMark(pos);
1192
MarkLine( control, m_CurrScrLine);
1193
#if defined(LOGGING)
1194
LOGIT( _T("RecordBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
1195
pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
1196
if (not LineHasBrowseMarker(control, m_CurrScrLine) ) {asm("int3"); /*trap*/}
1201
////// ----------------------------------------------------------------------------
1202
////void BrowseTracker::RecordBrowseMarkPosition(EditorBase* eb, int posn)
1203
////// ----------------------------------------------------------------------------
1205
//// // stow a browse mark by editor cursor position
1207
//// cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
1210
//// if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
1212
//// cbStyledTextCtrl* control = cbed->GetControl();
1213
//// BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
1214
//// int line = control->LineFromPosition(posn);
1215
//// ClearLineBrowseMark( posn ); //clear previous marks
1216
//// EdBrowse_Marks.RecordMark( posn );
1217
//// //-if (not LineHasMarker( control,line))
1218
//// MarkLine( control, line);
1219
//// #if defined(LOGGING)
1220
//// LOGIT( _T("RecordBrowseMarkByPosn: pos[%d]line[%d]eb[%p][%s]"),
1221
//// posn, line,eb, eb->GetShortName().c_str() );
1222
//// if (not LineHasBrowseMarker(control, line)) {asm("int3"); /*trap*/}
1225
//// }while(0);//if do
1226
////}//RecordBrowseMarkPosition
1227
// ----------------------------------------------------------------------------
1228
void BrowseTracker::OnMenuTrackerDump(wxCommandEvent& event)
1229
// ----------------------------------------------------------------------------
1231
// For debugging. Dump arrays and pointers
1234
LOGIT( _T("--Browsed--Editors-------------") );
1235
LOGIT( _T("CurrIndex[%d]LastIndex[%d]count[%d]"), m_CurrEditorIndex, m_LastEditorIndex, GetEditorBrowsedCount() );
1236
for (int i=0;i<MaxEntries ;++i )
1238
wxString edName = GetPageFilename(i);
1239
LOGIT( _T("Index[%d]Editor[%p]Name[%s]"), i, GetEditor(i), edName.c_str() );;
1241
for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); ++it)
1243
LOGIT( _T("Hash Ed[%p] AryPtr[%p]"), it->first, it->second );
1246
// dump the array containing the current editors BrowseMarks
1247
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
1248
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
1251
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
1253
//cbStyledTextCtrl* control = cbed->GetControl();
1254
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
1255
LOGIT( _T("--Browse--Marks--for--[%s]----"), eb->GetShortName().c_str() );
1256
EdBrowse_Marks.Dump();
1259
// dump the current Project ProjectData
1260
ProjectData* pProjectData = GetProjectDataByEditorName( eb->GetFilename() );
1261
if (not pProjectData)
1263
LOGIT( _T("*CRASH* BrowseTracker::OnMenuTrackerDump No project pointer") );
1266
LOGIT( _T("ProjectData for[%s]"),pProjectData->GetProjectFilename().c_str() );
1267
pProjectData->DumpHash(wxT("BrowseMarks"));
1268
pProjectData->DumpHash(wxT("BookMarks"));
1272
// ----------------------------------------------------------------------------
1273
void BrowseTracker::OnMenuTrackerClear(wxCommandEvent& event)
1274
// ----------------------------------------------------------------------------
1276
// Clear the editor array of pointers (History)
1278
if (IsAttached() && m_InitDone)
1283
// ----------------------------------------------------------------------------
1284
void BrowseTracker::TrackerClearAll()
1285
// ----------------------------------------------------------------------------
1287
// Clear the editor array of pointers (History)
1289
if (IsAttached() && m_InitDone)
1291
for (int i=0; i<MaxEntries ; ++i )
1292
RemoveEditor(GetEditor(i));
1293
m_CurrEditorIndex = 0;
1294
m_LastEditorIndex = MaxEntries-1;
1297
// Simulate activation of the current editor. If the list is empty
1298
// it'll hang the selector dialog
1299
EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
1302
CodeBlocksEvent evt;
1304
OnEditorActivated(evt);
1308
// ----------------------------------------------------------------------------
1309
cbProject* BrowseTracker::GetProject(EditorBase* eb)
1310
// ----------------------------------------------------------------------------
1312
cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
1313
if ( not cbed ) {return 0;}
1314
ProjectFile* pPrjFile = cbed->GetProjectFile();
1315
if ( not pPrjFile ) {return 0;}
1316
cbProject* pProject = pPrjFile->GetParentProject();
1319
// ----------------------------------------------------------------------------
1320
void BrowseTracker::OnEditorActivated(CodeBlocksEvent& event)
1321
// ----------------------------------------------------------------------------
1323
// Record this activation event and place activation in history
1324
// Create structures to hold new editor info if we never saw this editor before.
1325
// Structures are: a hash to point to a class holding editor cursor postiions used
1326
// as a history to place markers.
1328
//NB: This event is entered twice when an editor is activated. The first has
1329
// no cbEditor attached. The second does.
1333
if (IsAttached() && m_InitDone) do
1336
EditorBase* eb = event.GetEditor();
1337
wxString editorFullPath = eb->GetFilename();
1338
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
1340
if ( m_bProjectIsLoading )
1342
#if defined(LOGGING)
1343
LOGIT( _T("[OnEditorActivated ignored: Project Loading[ %s]"), editorFullPath.c_str());
1350
#if defined(LOGGING)
1351
//LOGIT( _T("[OnEditorActivated ignored:no cbEditor[%s]"), editorFullPath.c_str());
1356
#if defined(LOGGING)
1357
LOGIT( _T("Editor Activated[%p][%s]"), eb, eb->GetShortName().c_str() );
1361
// New editor, append to circular queue
1362
// remove previous entries for this editor first
1363
for (int i=0; i < MaxEntries; ++i)
1364
if (eb == GetEditor(i)) ClearEditor(i);
1365
// compress the array
1366
if ( GetEditorBrowsedCount() )
1367
for (int i=0; i < MaxEntries-1; ++i)
1369
if (m_apEditors[i] == 0)
1370
{ m_apEditors[i] = m_apEditors[i+1];
1371
m_apEditors[i+1] = 0;
1372
if ( m_CurrEditorIndex == (i+1) ) --m_CurrEditorIndex;
1373
if ( m_LastEditorIndex == (i+1) ) --m_LastEditorIndex;
1377
#if defined(LOGGING)
1378
LOGIT( _T("OnEditorActivated AddedEditor[%p][%s]"), eb, eb->GetShortName().c_str() );
1380
m_CurrEditorIndex = m_LastEditorIndex;
1382
// ---------------------------------------------------------------------
1383
// For new cbEditors, add an entry to the editor cursor positions hash
1384
// and allocate a cursor positions array to hold the cursor positions
1385
// Set hooks to catch mouse activity
1386
// ---------------------------------------------------------------------
1388
if ( IsBrowseMarksEnabled()
1389
&& (not GetBrowse_MarksFromHash( eb )) ) //guard against duplicates
1393
HashAddBrowse_Marks( eb->GetFilename() ); //create hashs and book/browse marks arrays
1395
////DumpHash(wxT("BrowseMarks"));
1396
////DumpHash(wxT("BookMarks"));
1397
////m_pActiveProjectData->DumpHash(wxT("BrowseMarks"));
1398
////m_pActiveProjectData->DumpHash(wxT("BookMarks"));
1400
cbStyledTextCtrl* control = cbed->GetControl();
1401
// Setting the initial browsemark
1402
//-int pos = control->GetCurrentPos();
1403
control->Connect(wxEVT_LEFT_UP,
1404
(wxObjectEventFunction)(wxEventFunction)
1405
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1407
control->Connect(wxEVT_LEFT_DOWN,
1408
(wxObjectEventFunction)(wxEventFunction)
1409
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1411
control->Connect(wxEVT_LEFT_DCLICK,
1412
(wxObjectEventFunction)(wxEventFunction)
1413
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1415
control->Connect(wxEVT_MOTION,
1416
(wxObjectEventFunction)(wxEventFunction)
1417
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1419
control->Connect(wxEVT_CONTEXT_MENU,
1420
(wxObjectEventFunction)(wxEventFunction)
1421
(wxContextMenuEventFunction)&BrowseTracker::OnMarginContextMenu,
1423
#if defined(LOGGING)
1424
LOGIT( _T("Added hash entry for [%p][%s]"), eb, eb->GetShortName().c_str() );
1426
// Define scintilla BrowseTracker margin marker
1427
//ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("app"));
1428
//control->SetMarginWidth(1, 16);
1429
//control->SetMarginType(1, wxSCI_MARGIN_SYMBOL);
1430
//control->SetMarginSensitive(1, mgr->ReadBool(_T("/margin_1_sensitive"), true));
1431
//control->SetMarginMask(1, (1 << BOOKMARK_MARKER) |
1432
// (1 << BREAKPOINT_MARKER) |
1433
// (1 << DEBUG_MARKER) |
1434
// (1 << ERROR_MARKER));
1435
//control->MarkerDefine(BOOKMARK_MARKER, BOOKMARK_STYLE);
1436
//control->MarkerSetBackground(BOOKMARK_MARKER, wxColour(0xA0, 0xA0, 0xFF));
1437
int marginMask = control->GetMarginMask(1);
1438
control->SetMarginMask( 1, marginMask | (1<<GetBrowseMarkerId()) );
1439
control->MarkerDefine( GetBrowseMarkerId(), GetBrowseMarkerStyle() );
1440
// the following stmt seems to do nothing for wxSCI_MARK_DOTDOTDOT
1441
control->MarkerSetBackground( GetBrowseMarkerId(), wxColour(0xA0, 0xA0, 0xFF));
1442
#if defined(LOGGING)
1443
//LOGIT( _T("UserStyle[%d]MarkerId[%d]MarkerStyle[%d]"),m_UserMarksStyle,GetBrowseMarkerId(), GetBrowseMarkerStyle());
1445
// Set archived Layout browse marks in the editor
1446
ProjectData* pProjectData = GetProjectDataByEditorName(eb->GetFilename() );
1447
#if defined(LOGGING)
1448
if (not pProjectData)
1449
LOGIT( _T("OnEditorActivated FAILED TO FIND PROJECT for [%s]"), eb->GetShortName().c_str() );
1452
{ // Set the Book/Browse marks from the Layout/History arrays
1453
BrowseMarks* pBrowse_MarksArc = pProjectData->GetBrowse_MarksFromHash( eb->GetFilename());
1454
//#if defined(LOGGING)
1455
//LOGIT( _T("\nDumping ARCHIVE data for[%s]"), eb->GetFilename().c_str());
1456
//LOGIT( _T("Project Data[%s]"),pProjectData->GetProjectFilename().c_str() );
1457
//pBrowse_MarksArc->Dump();
1459
if (pBrowse_MarksArc)
1460
m_EbBrowse_MarksHash[eb]->RecordMarksFrom( *pBrowse_MarksArc);
1461
//LOGIT( _T("Dumping CURRENT data for[%s]"), eb->GetFilename().c_str());
1462
//m_EbBrowse_MarksHash[eb]->Dump();
1464
// record the current cursor position
1465
//-if (not LineHasBrowseMarker(control, control->LineFromPosition(pos)))
1466
//-if ( not m_EbBrowse_MarksHash[eb]->GetMarkCount() )
1467
//- RecordBrowseMark(eb);
1469
////DumpHash(wxT("BrowseMarks"));
1470
////DumpHash(wxT("BookMarks"));
1471
////m_pActiveProjectData->DumpHash(wxT("BrowseMarks"));
1472
////m_pActiveProjectData->DumpBrowse_Marks(wxT("BrowseMarks"));
1473
////pBrowse_MarksArc->Dump();
1474
////m_pActiveProjectData->DumpHash(wxT("BookMarks"));
1476
// copy/set the old book marks, if any
1477
BrowseMarks* pCurrBook_Marks = GetBook_MarksFromHash( eb->GetFilename());
1478
BrowseMarks* pArchBook_Marks = pProjectData->GetBook_MarksFromHash(eb->GetFilename());
1479
if (pArchBook_Marks && pCurrBook_Marks)
1480
pCurrBook_Marks->ToggleBook_MarksFrom(*pArchBook_Marks);
1487
}//OnEditorActivated
1488
// ----------------------------------------------------------------------------
1489
void BrowseTracker::OnUpdateUI(wxUpdateUIEvent& event)
1490
// ----------------------------------------------------------------------------
1495
// ----------------------------------------------------------------------------
1496
void BrowseTracker::OnIdle(wxIdleEvent& event)
1497
// ----------------------------------------------------------------------------
1500
// Focus the new selected editor. This doesn't work if a long compile
1501
// is active since there's no idle time. User will have to click into
1502
// the editor window to activate it.
1503
// This used to be done by the CB editor manager, but someone removed the UI hook.
1504
if (!Manager::Get()->IsAppShuttingDown() && m_UpdateUIFocusEditor)
1506
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
1508
{ ed->GetControl()->SetFocus();
1509
#if defined(LOGGING)
1510
////LOGIT( _T("OnIdle Focused Editor[%p] Title[%s]"), ed, ed->GetTitle().c_str() );
1513
m_UpdateUIFocusEditor = false;
1517
// ----------------------------------------------------------------------------
1518
void BrowseTracker::OnStartShutdown(CodeBlocksEvent& event)
1519
// ----------------------------------------------------------------------------
1524
// ----------------------------------------------------------------------------
1525
void BrowseTracker::OnEditorDeactivated(CodeBlocksEvent& event)
1526
// ----------------------------------------------------------------------------
1528
// This event is practically useless. When an editor is opened you get the
1530
//12:14:33: Editor DE-activated[03894E88][]
1531
//12:14:33: OnEditorOpen ebase[03894E88]cbed[03894E88]stc[03894C88][Version.cpp]
1532
//12:14:33: Editor DE-activated[03894E88][Version.cpp]
1533
//12:14:33: Editor Activated[03894E88][Version.cpp]
1535
EditorBase* eb = event.GetEditor();
1536
if (IsAttached() && m_InitDone)
1538
#if defined(LOGGING)
1539
///LOGIT( _T("Editor DE-ACTIVATED[%p][%s]"), eb, eb->GetShortName().c_str() );
1543
#if not defined(LOGGING)
1549
// ----------------------------------------------------------------------------
1550
void BrowseTracker::OnEditorOpened(CodeBlocksEvent& event)
1551
// ----------------------------------------------------------------------------
1553
// When editor belongs to a project, tell ProjectData about it.
1557
if (IsAttached() && m_InitDone)
1560
EditorBase* eb = event.GetEditor();
1561
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
1562
if (not cbed) return;
1564
cbStyledTextCtrl* control = 0;
1565
if (cbed) control = cbed->GetControl();
1566
// validate cbProject has been set
1567
cbProject* pcbProject = GetProject( eb );
1568
#if defined(LOGGING)
1569
LOGIT( _T("OnEditorOpen ebase[%p]cbed[%p]stc[%p][%s]"), eb, cbed, control, eb->GetShortName().c_str() );
1572
// stow opened editor info in the ProjectData class
1574
{ ProjectData* pProjectData = GetProjectDataFromHash(pcbProject);
1575
if (pProjectData) pProjectData->AddEditor( eb->GetFilename() );
1578
//This code shows that the cbProject*'s are empty at this event
1579
// That seems very odd ?
1580
//#if defined(LOGGING)
1581
////NB: There is no cbEditor::ProjectFile* or ProjectFile::GetBaseName()
1582
//// and there's no initialized Project* that I can find.
1583
//ProjectFile* pProjectFile = cbed->GetProjectFile();
1584
//wxString projectBaseName = pProjectFile?pProjectFile->GetBaseName() :*wxEmptyString;
1585
// LOGIT( _T("OnEditorOpen project[%p]projectBaseName[%s]"), pProjectFile, projectBaseName.c_str() );
1586
//// -- there is no intialized cbProject* yet for the opening project.
1587
////Note here, that the returned project is the project about to be deactivated.
1588
//ProjectManager* prjMgr = Manager::Get()->GetProjectManager();
1589
//cbProject* pcbProject = prjMgr->GetActiveProject();
1590
//wxString filename = pcbProject?pcbProject->GetFilename():*wxEmptyString;
1591
// LOGIT( _T("OnEditorOpen cbProject[%p]filename[%s]"), pcbProject, filename.c_str() );
1596
// ----------------------------------------------------------------------------
1597
void BrowseTracker::OnEditorClosed(CodeBlocksEvent& event)
1598
// ----------------------------------------------------------------------------
1600
// clear this editor out of our arrays and pointers
1602
//NOTE: using Manager::Get->GetEditorManager()->GetEditor... etc will
1603
// fail in this codeblocks event.
1604
// The cbEditors are nolonger available
1607
if (IsAttached() && m_InitDone)
1609
EditorBase* eb = event.GetEditor();
1610
wxString filePath = event.GetString();
1611
ProjectData* pProjectData = GetProjectDataByEditorName( filePath);
1613
#if defined(LOGGING)
1614
LOGIT( _T("Closing Eb[%p][%s]"), eb, eb->GetShortName().c_str() );
1615
///LOGIT( _T("Closing Eb[%p][%s]"), eb, eb->GetFilename().c_str() );
1618
//-cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
1619
//-if (not cbed) return;
1621
// If not our editor, or editor already closed, return
1622
if ( GetEditor(eb) == -1) return;
1624
// If editor belong to a project,
1625
// Copy current Browse/Book marks to archive so we have
1626
// them if the user reopens this editor
1629
BrowseMarks* pArchBook_Marks = pProjectData->GetBook_MarksFromHash( eb->GetFilename());
1630
BrowseMarks* pCurrBook_Marks = GetBook_MarksFromHash( eb->GetFilename());
1631
//*note* cannot get access to scintilla book marks here because the cbStyledTextCtrl
1632
// is not accessible
1633
if (pCurrBook_Marks && pArchBook_Marks)
1634
pArchBook_Marks->CopyMarksFrom(*pCurrBook_Marks);
1636
// Copy current BrowseMarks to archive BrowseMarks so we have
1637
// them if the user reopens this editor
1638
BrowseMarks* pArchBrowse_Marks = pProjectData->GetBrowse_MarksFromHash( eb->GetFilename());
1639
BrowseMarks* pCurrBrowse_Marks = GetBrowse_MarksFromHash( eb);
1640
if (pCurrBrowse_Marks && pArchBrowse_Marks)
1641
pArchBrowse_Marks->CopyMarksFrom(*pCurrBrowse_Marks);
1643
// Clean up the closed editor and its associated Book/BrowseMarks
1644
for (int i=0; i<MaxEntries; ++i )
1645
if ( eb == GetEditor(i) )
1647
#if defined(LOGGING)
1648
LOGIT( _T("OnEditorClosed cleared[%p]"), GetEditor(i));
1650
RemoveEditor(GetEditor(i));
1654
// ----------------------------------------------------------------------------
1655
void BrowseTracker::AddEditor(EditorBase* eb)
1656
// ----------------------------------------------------------------------------
1658
// Add this editor the array of activated editors
1661
if ( ++m_LastEditorIndex >= MaxEntries ) m_LastEditorIndex = 0;
1662
m_apEditors[m_LastEditorIndex] = eb;
1663
++m_nBrowsedEditorCount;
1664
#if defined(LOGGING)
1665
//LOGIT( _T("AddEditor[%p][%s]"), eb, eb->GetShortName().c_str() );
1668
// ----------------------------------------------------------------------------
1669
BrowseMarks* BrowseTracker::HashAddBrowse_Marks( const wxString fullPath)
1670
// ----------------------------------------------------------------------------
1672
// EditorManager calls fail during the OnEditorClose event
1673
// eg,EditorBase* eb = Manager::Get()->GetEditorManager()->GetEditor(filename);
1675
EditorBase* eb = m_pEdMgr->GetEditor(fullPath);
1676
if (not eb) return 0;
1677
// don't add duplicates
1678
EbBrowse_MarksHash& hash = m_EbBrowse_MarksHash;
1679
BrowseMarks* pBrowse_Marks = GetBrowse_MarksFromHash( eb);
1680
if (not pBrowse_Marks)
1681
{ pBrowse_Marks = new BrowseMarks(eb->GetFilename() );
1682
hash[eb] = pBrowse_Marks;
1685
// Allocate book marks array also
1686
HashAddBook_Marks( fullPath);
1688
// If this editor belongs to a project,
1689
// Ask ProjectData to alloc the archive Browse/Book marks arrays
1690
ProjectData* pProjectData = GetProjectDataByEditorName( fullPath );
1692
pProjectData->HashAddBrowse_Marks( fullPath );
1694
#if defined(LOGGING)
1695
///LOGIT( _T("HashAddBrowse_Marks[%s]"), eb->GetFilename().c_str() );
1697
return pBrowse_Marks;
1699
// ----------------------------------------------------------------------------
1700
BrowseMarks* BrowseTracker::HashAddBook_Marks( const wxString fullPath)
1701
// ----------------------------------------------------------------------------
1703
// EditorManager calls fail during the OnEditorClose event
1704
// eg,EditorBase* eb = Manager::Get()->GetEditorManager()->GetEditor(filename);
1706
EditorBase* eb = m_pEdMgr->GetEditor(fullPath);
1707
if (not eb) return 0;
1708
EbBrowse_MarksHash& hash = m_EdBook_MarksHash;
1709
BrowseMarks* pBook_Marks = GetBook_MarksFromHash( eb);
1710
if (not pBook_Marks)
1711
{ pBook_Marks = new BrowseMarks(fullPath);
1712
hash[eb] = pBook_Marks;
1715
// If this editor belongs to a project
1716
// Ask ProjectData to alloc the archive Browse/Book marks arrays
1717
ProjectData* pProjectData = GetProjectDataByEditorName( fullPath );
1719
pProjectData->HashAddBook_Marks( eb->GetFilename());
1721
#if defined(LOGGING)
1722
///LOGIT( _T("HashAddBOOKMakrs[%s]"), eb->GetFilename().c_str() );
1726
// ----------------------------------------------------------------------------
1727
void BrowseTracker::ClearEditor(int index)
1728
// ----------------------------------------------------------------------------
1730
// Used to remove duplicate editors without deleting array data
1731
// Duplicates especially occur when a previous editor is re-activated after
1732
// a secondary project is closed.
1734
if (index < 0) return;
1735
m_apEditors[index] = 0;
1736
--m_nBrowsedEditorCount;
1738
// ----------------------------------------------------------------------------
1739
void BrowseTracker::RemoveEditor(EditorBase* eb)
1740
// ----------------------------------------------------------------------------
1742
// clear this editor out of our arrays and pointers
1743
// ie, reverse of the processing in OnEditorActivated()
1745
// don't allow recursion from our called routines.
1746
if (m_nRemoveEditorSentry) return;
1749
++m_nRemoveEditorSentry;
1751
if (IsAttached() && m_InitDone) do
1753
#if defined(LOGGING)
1754
//Dont use eb to reference data. It may have already been destroyed.
1755
//LOGIT( _T("Removing[%p][%s]"), eb, eb->GetShortName().c_str() );
1756
///LOGIT( _T("RemoveEditor[%p]"), eb );
1759
for (int i=0; i<MaxEntries; ++i )
1760
if ( eb == GetEditor(i) )
1763
// remove the hash entry for this editor
1764
if ( m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end())
1766
delete m_EbBrowse_MarksHash[eb]; //Browse Marks
1767
m_EbBrowse_MarksHash.erase(eb);
1768
delete m_EdBook_MarksHash[eb]; //Book Marks
1769
m_EdBook_MarksHash.erase(eb);
1771
// using a stale eb will cause a crash
1772
if (-1 != m_pEdMgr->FindPageFromEditor(eb) )
1774
wxWindow* win = wxWindow::FindWindowByName(wxT("SCIwindow"),eb);
1777
win->Disconnect(wxEVT_LEFT_UP,
1778
(wxObjectEventFunction)(wxEventFunction)
1779
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1781
win->Disconnect(wxEVT_LEFT_DOWN,
1782
(wxObjectEventFunction)(wxEventFunction)
1783
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1785
win->Disconnect(wxEVT_LEFT_DCLICK,
1786
(wxObjectEventFunction)(wxEventFunction)
1787
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1789
win->Disconnect(wxEVT_MOTION,
1790
(wxObjectEventFunction)(wxEventFunction)
1791
(wxMouseEventFunction)&BrowseTracker::OnMouseKeyEvent,
1793
win->Disconnect(wxEVT_CONTEXT_MENU,
1794
(wxObjectEventFunction)(wxEventFunction)
1795
(wxCommandEventFunction)&BrowseTracker::OnMarginContextMenu,
1798
}//if find page from editor
1799
#if defined(LOGGING)
1800
///LOGIT( _T("RemoveEditor Erased hash entry[%p]"), eb );
1805
m_nRemoveEditorSentry = 0;
1807
// ----------------------------------------------------------------------------
1808
void BrowseTracker::OnProjectOpened(CodeBlocksEvent& event)
1809
// ----------------------------------------------------------------------------
1811
// NB: EVT_PROJECT_ACTIVATE is occuring before EVT_PROJECT_OPEN
1812
// NB: EVT_EDITOR_ACTIVATE events occur before EVT_PROJECT_ACTIVATE or EVT_PROJECT_OPEN
1813
// Currently, this event is a hack to us since it occurs AFTER editors are activated
1814
// and AFTER the project is activated
1816
// But since the editors are now already open, we can read the layout file
1817
// that saved previous BrowseMark and book mark history, and use that data
1818
// to build/set old saved Browse/Book marks.
1820
if ( not IsBrowseMarksEnabled() )
1823
cbProject* pProject = event.GetProject();
1826
{ //caused when project imported
1827
m_bProjectIsLoading = false;
1830
#if defined(LOGGING)
1831
LOGIT( _T("-----------------------------------"));
1832
LOGIT( _T("Project OPENED[%s]"), event.GetProject()->GetFilename().c_str() );
1835
wxString projectFilename = event.GetProject()->GetFilename();
1838
// allocate a ProjectData to hold activated editors
1839
cbProject* pCBProject = event.GetProject();
1840
ProjectData* pProjectData = GetProjectDataFromHash( pCBProject);
1841
if (not pProjectData)
1842
{ pProjectData = new ProjectData(pCBProject);
1843
m_ProjectDataHash[pCBProject] = pProjectData;
1846
// Read the layout file for this project, build BrowseMarks for each editor
1847
pProjectData = GetProjectDataFromHash( event.GetProject() );
1849
if (not pProjectData->IsLayoutLoaded() )
1850
pProjectData->LoadLayout();
1852
// There is a bug such that the project loading hook is *not* called
1853
// for some projects with a stray </unit> in its xml file.
1854
// Remove all the activated editors for this project when
1855
// the project was loaded. We don't want to see them if the user
1856
// didn't manually activate them.
1857
if (not m_bProjectIsLoading)
1859
int fileCount = pProject->GetFilesCount();
1860
for (int i=0; i<fileCount; ++i)
1862
for (int j=0; j<MaxEntries; ++j)
1864
if ( GetEditor(j) == 0 ) continue;
1865
//#if defined(LOGGING)
1866
//LOGIT( _T("eb[%s]projectFile[%s]"),
1867
// GetEditor(j)->GetFilename().c_str(), pProject->GetFile(i)->file.GetFullPath().c_str() );
1869
if ( pProject->GetFile(i)->file.GetFullPath() == GetEditor(j)->GetFilename())
1871
//#if defined(LOGGING)
1872
//LOGIT( _T("OnProjectOpened:Removing[%s]"),GetEditor(j)->GetFilename().c_str() );
1874
RemoveEditor(GetEditor(j));
1881
// Turn off "project loading" in order to record the last activated editor
1882
m_bProjectIsLoading = false;
1884
// Record the last CB activated editor as if the user activate it.
1885
EditorBase* eb = m_pEdMgr->GetBuiltinActiveEditor();
1886
if ( eb && (eb != GetCurrentEditor()) )
1888
CodeBlocksEvent evt;
1890
OnEditorActivated(evt);
1891
#if defined(LOGGING)
1892
LOGIT( _T("OnProjectOpened Activated Editor[%p][%s]"), eb, eb->GetShortName().c_str() );
1896
//for (EbBrowse_MarksHash::iterator it = m_EdBrowse_MarksArchive.begin(); it !=m_EdBrowse_MarksArchive.end(); ++it )
1897
// it->second->Dump();
1902
// ----------------------------------------------------------------------------
1903
void BrowseTracker::OnProjectClosing(CodeBlocksEvent& event)
1904
// ----------------------------------------------------------------------------
1906
// This hook occurs before the editors are closed. That allows
1907
// us to reference CB project and editor related data before CB
1910
if (not IsBrowseMarksEnabled())
1913
cbProject* pProject = event.GetProject();
1914
if (not pProject) return; //It happens!
1916
#if defined(LOGGING)
1917
LOGIT( _T("Project CLOSING[%p][%s]"), pProject, pProject->GetFilename().c_str() );
1920
// Simulate closing the remaining editors here so that we can write
1921
// a layout file containing the BrowseMarks and Book_Marks
1922
// This is the last chance we get to write a layout file.
1924
ProjectData* pProjectData = GetProjectDataFromHash( pProject);
1925
#if defined(LOGGING)
1926
if ( not pProjectData )
1927
LOGIT( _T("*CRASH* OnProjectClosing entered w/o project pointer") );
1929
if ( not pProjectData ) return;
1930
// Close editors that belong to the current project
1931
for (int i=0; i < m_pEdMgr->GetEditorsCount(); ++i)
1933
EditorBase* eb = m_pEdMgr->GetEditor(i);
1934
// Simulate closing editors that belong to the current project
1935
if ( pProjectData->FindFilename(eb->GetFilename()) )
1937
CodeBlocksEvent evt(cbEVT_EDITOR_CLOSE);
1939
evt.SetString(eb->GetFilename());
1940
OnEditorClosed( evt );
1943
#if defined(LOGGING)
1944
////LOGIT( _T("ProjectClosing failed to find[%s]"), eb->GetFilename().c_str() );
1949
// Write the layout for this project
1950
if (pProjectData) pProjectData->SaveLayout();
1952
// Free the ProjectData
1955
#if defined(LOGGING)
1956
LOGIT( _T("deleting ProjectData[%p][%s]"), pProjectData, pProjectData->GetProjectFilename().c_str() );
1958
delete pProjectData;
1959
m_ProjectDataHash.erase(pProject);
1962
//-wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
1963
//-OnMenuTrackerDump(evt);
1968
// ----------------------------------------------------------------------------
1969
void BrowseTracker::OnProjectActivatedEvent(CodeBlocksEvent& event)
1970
// ----------------------------------------------------------------------------
1972
// NB: EVT_PROJECT_ACTIVATE is occuring before EVT_PROJECT_OPEN
1973
// NB: EVT_EDITOR_ACTIVATE event occur before EVT_PROJECT_ACTIVATE or EVT_PROJECT_OPEN
1975
// *NOTE* when a secondary project closes and re-activates a previous one,
1976
// *NO* cbEVT_PROJECT_ACTIVATE occurs. We end up with the wrong active project
1977
// pointer. Only a cbEVT_EDITOR_ACTIVATE occurs.
1981
if (not IsBrowseMarksEnabled() )
1984
// allocate a ProjectData to hold activated editors
1985
cbProject* pCBProject = event.GetProject();
1987
if (not pCBProject) return; //caused by importing a project
1989
#if defined(LOGGING)
1990
LOGIT( _T("-----------------------------------"));
1991
LOGIT( _T("Project ACTIVATED[%p][%s]"), pCBProject, pCBProject->GetFilename().c_str() );
1994
ProjectData* pProjectData = GetProjectDataFromHash( pCBProject);
1995
if (not pProjectData)
1996
{ pProjectData = new ProjectData(pCBProject);
1997
m_ProjectDataHash[pCBProject] = pProjectData;
1999
pProjectData->IncrementActivationCount();
2001
// store the current editor in BrowseTracker array
2002
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
2003
//LOGIT( _T("ProjectActivated eb[%p][%s]Current[%p][%s]"),
2004
// eb, GetEditorFilename(eb).c_str(),
2005
// m_pCurrentEditor, GetEditorFilename(m_pCurrentEditor).c_str());
2007
// Record the last CB activated editor as if the user activate it.
2008
// See OnEditorActivated()
2009
if ( eb && (eb != GetCurrentEditor()) )
2011
CodeBlocksEvent evt;
2013
OnEditorActivated(evt);
2014
//LOGIT( _T("OnProjectActivated Editor[%p][%s]"), eb, GetEditorFilename(eb).c_str() );
2017
// Compress the editor pointer array to allow all "forward" available slots
2018
int index = GetCurrentEditorIndex();
2019
if ( GetEditorBrowsedCount() )
2021
ArrayOfEditorBasePtrs tmpArray;
2022
tmpArray.Alloc(MaxEntries);
2023
// copy current editors & clear for compression
2024
for (int i = 0; i<MaxEntries; ++i)
2025
{ tmpArray[i] = m_apEditors[i];
2028
m_CurrEditorIndex = 0;
2029
m_LastEditorIndex = MaxEntries-1;
2030
for (int i = 0; i<MaxEntries; ++i)
2032
if ( tmpArray[index] )
2033
{ if (++m_LastEditorIndex >= MaxEntries) m_LastEditorIndex = 0;
2034
m_apEditors[m_LastEditorIndex] = tmpArray[index];
2036
if (++index >= MaxEntries) index = 0;
2040
{ m_CurrEditorIndex = 0;
2041
m_LastEditorIndex = MaxEntries-1;
2044
}//OnProjectActivatedEvent
2045
// ----------------------------------------------------------------------------
2046
void BrowseTracker::OnProjectLoadingHook(cbProject* project, TiXmlElement* elem, bool loading)
2047
// ----------------------------------------------------------------------------
2049
// This turned out to be a problem. It isn't always called for old type projects
2050
// or a project with an extra </unit> in it.
2052
// CB does not issue Project_Opened or Project_activated events until
2053
// after the editors are loaded and activated. That causes us to record
2054
// the loading editors as if the user activated them manually.
2055
// So we use this hook to tell the recorder NOT to record the loading editors.
2057
// *Logic Gothcha* When a work space loads, OnProjectActivated() is called for
2058
// the active project, then loading proceeds for other projects. This can cause
2059
// the m_bProjectIsLoading flag to be set forever.
2061
#if defined(LOGGING)
2062
//-LOGIT( _T("OnProjectLoadingHook [%s]"), loading? wxT("Loading"):wxT("Saving") );
2065
if (not IsBrowseMarksEnabled() )
2070
// dont record CB activated editors while project is loading
2071
//-------------------------------
2072
m_bProjectIsLoading = true;
2073
//-------------------------------
2075
m_LoadingProjectFilename = project->GetFilename();
2077
#if defined(LOGGING)
2078
LOGIT( _T("----------------------------------------------") );
2079
LOGIT( _T("ProjectLoadingHook::LOADING[%p][%s]"), project, m_LoadingProjectFilename.c_str() );
2082
else //saving project
2084
//#if defined(LOGGING)
2085
//LOGIT( _T("ProjectLoadingHook::SAVING[]TiXmlElement[%p]"), elem );
2088
}//OnProjectLoadingHook
2089
// ----------------------------------------------------------------------------
2090
void BrowseTracker::OnEditorEventHook(cbEditor* pcbEditor, wxScintillaEvent& event)
2091
// ----------------------------------------------------------------------------
2093
// Rebuild the BrowseMarks array if user deletes/adds editor lines
2095
// wxString txt = _T("OnEditorModified(): ");
2096
// int flags = event.GetModificationType();
2097
// if (flags & wxSCI_MOD_CHANGEMARKER) txt << _T("wxSCI_MOD_CHANGEMARKER, ");
2098
// if (flags & wxSCI_MOD_INSERTTEXT) txt << _T("wxSCI_MOD_INSERTTEXT, ");
2099
// if (flags & wxSCI_MOD_DELETETEXT) txt << _T("wxSCI_MOD_DELETETEXT, ");
2100
// if (flags & wxSCI_MOD_CHANGEFOLD) txt << _T("wxSCI_MOD_CHANGEFOLD, ");
2101
// if (flags & wxSCI_PERFORMED_USER) txt << _T("wxSCI_PERFORMED_USER, ");
2102
// if (flags & wxSCI_MOD_BEFOREINSERT) txt << _T("wxSCI_MOD_BEFOREINSERT, ");
2103
// if (flags & wxSCI_MOD_BEFOREDELETE) txt << _T("wxSCI_MOD_BEFOREDELETE, ");
2104
// txt << _T("pos=")
2105
// << wxString::Format(_T("%d"), event.GetPosition())
2107
// << wxString::Format(_T("%d"), event.GetLine())
2108
// << _T(", linesAdded=")
2109
// << wxString::Format(_T("%d"), event.GetLinesAdded());
2110
// Manager::Get()->GetLogManager()->DebugLog(txt);
2114
if (not IsBrowseMarksEnabled())
2117
//if ( event.GetEventType() != wxEVT_SCI_MODIFIED )
2118
if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
2120
// Whenever event.GetLinesAdded() != 0, we must re-set BrowseMarks for lines greater
2121
// than LineFromPosition(event.GetPosition())
2123
int linesAdded = event.GetLinesAdded();
2124
bool isAdd = event.GetModificationType() & wxSCI_MOD_INSERTTEXT;
2125
bool isDel = event.GetModificationType() & wxSCI_MOD_DELETETEXT;
2126
if ((isAdd || isDel) && linesAdded != 0)
2128
#if defined(LOGGING)
2129
//LOGIT( _T("EditorEventHook isAdd[%d]isDel[%d]lines[%d]"), isAdd, isDel, linesAdded );
2131
// rebuild BrowseMarks from scintilla marks
2132
RebuildBrowse_Marks( pcbEditor, isAdd );
2134
}//wxEVT_SCI_MODIFIED
2136
// wxSCI_MOD_CHANGEMARKER is an extremely expensive call. It's called
2137
// for each line during a file load, and for every change to every
2138
// margin marker in the known cosmos. So here we allow a "one shot only"
2139
// to catch the marker changed by a margin context menu.
2140
// cf: CloneBookMarkFromEditor() and OnMarginContextMenu()
2141
if ( event.GetEventType() == wxEVT_SCI_MODIFIED )
2143
if ( m_OnEditorEventHookIgnoreMarkerChanges )
2145
int flags = event.GetModificationType();
2146
if (flags & wxSCI_MOD_CHANGEMARKER )
2148
m_OnEditorEventHookIgnoreMarkerChanges = true;
2149
int line = event.GetLine();
2150
#if defined(LOGGING)
2151
//LOGIT( _T("wxSCI_MOD_CHANGEMARKER line[%d]"), line );
2153
CloneBookMarkFromEditor( line );
2157
}//OnEditorEventHook
2158
// ----------------------------------------------------------------------------
2159
void BrowseTracker::CloneBookMarkFromEditor( int line )
2160
// ----------------------------------------------------------------------------
2162
// Record the editor bookmark as is.
2164
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
2165
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
2168
cbStyledTextCtrl* control = cbed->GetControl();
2169
if ( LineHasBookMarker(control, line) )
2172
ClearLineBookMark();
2173
#if defined(LOGGING)
2174
//LOGIT( _T("CloneBookMarkFromEditor[%d][%s]"), line,
2175
// LineHasBookMarker( control, line)?wxT("Added"):wxT("Cleared") );
2179
// ----------------------------------------------------------------------------
2180
void BrowseTracker::OnMarginContextMenu(wxContextMenuEvent& event)
2181
// ----------------------------------------------------------------------------
2183
// User has invoked the context menu. Set a flag to allow
2184
// OnEditorEventHook wxSCI_MOD_CHANGEMARKER overhead
2185
// If the user clicked withing the number margins, the hook
2186
// will see it, do its thing, then turn the overhead off.
2187
// If the user does not change the a marker, the hook will not turn
2188
// the overhead off, but the next invocatin of OnEditorEventHook will.
2189
// turn it off anyway.
2191
m_OnEditorEventHookIgnoreMarkerChanges = false;
2196
// ----------------------------------------------------------------------------
2197
void BrowseTracker::OnBook_MarksToggle(wxCommandEvent& event)
2198
// ----------------------------------------------------------------------------
2200
// a Book mark has been toggled
2202
#if defined(LOGGING)
2203
LOGIT( _T("OnBook_MarksToggle") );
2205
ToggleBook_Mark(GetCurrentEditor() );
2207
// ----------------------------------------------------------------------------
2208
void BrowseTracker::AddBook_Mark(EditorBase* eb, int line/*=-1*/)
2209
// ----------------------------------------------------------------------------
2211
// Stow a Book mark by EditorBase current line
2212
// Note: the book mark has not been cleared/set by scintilla yet
2214
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
2217
if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
2219
cbStyledTextCtrl* control = cbed->GetControl();
2220
BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
2221
GetCurrentScreenPositions();
2222
int pos = control->GetCurrentPos();
2223
EdBook_Marks.RecordMark(pos);
2224
#if defined(LOGGING)
2225
LOGIT( _T("AddBook_Mark: pos[%d]line[%d]eb[%p][%s]"),
2226
pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
2227
///EdBook_Marks.Dump();
2229
}while(false);//if do
2231
// When using BookMarks as BrowseMarks toggle the BrowseMark also.
2232
if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
2233
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
2235
cbStyledTextCtrl* control = cbed->GetControl();
2236
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
2237
GetCurrentScreenPositions();
2238
int pos = control->GetCurrentPos();
2239
EdBrowse_Marks.RecordMark(pos);
2240
#if defined(LOGGING)
2241
LOGIT( _T("AddBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
2242
pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
2244
}while(false);//if do
2248
// ----------------------------------------------------------------------------
2249
void BrowseTracker::ToggleBook_Mark(EditorBase* eb)
2250
// ----------------------------------------------------------------------------
2252
// Stow a Book mark by EditorBase current line
2253
// Note: the book mark has not been cleared/set by scintilla yet
2255
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
2258
if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
2260
cbStyledTextCtrl* control = cbed->GetControl();
2261
BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
2262
GetCurrentScreenPositions();
2264
if ( LineHasBookMarker(control, m_CurrScrLine) )
2266
ClearLineBookMark(); //clear previous marks
2269
int pos = control->GetCurrentPos();
2270
EdBook_Marks.RecordMark(pos);
2271
#if defined(LOGGING)
2272
LOGIT( _T("RecordBook_Mark: pos[%d]line[%d]eb[%p][%s]"),
2273
pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
2274
///EdBook_Marks.Dump();
2276
}while(false);//if do
2278
// When using BookMarks as BrowseMarks toggle the BrowseMark also.
2279
if ( GetBrowseMarkerId() == BOOKMARK_MARKER )
2280
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
2282
cbStyledTextCtrl* control = cbed->GetControl();
2283
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
2284
GetCurrentScreenPositions();
2285
// Toggle BrowseMark
2286
if ( LineHasBrowseMarker(control, m_CurrScrLine) )
2288
ClearLineBrowseMark(/*markRemove*/false);
2291
int pos = control->GetCurrentPos();
2292
EdBrowse_Marks.RecordMark(pos);
2293
#if defined(LOGGING)
2294
LOGIT( _T("RecordBrowseMarkByEb: pos[%d]line[%d]eb[%p][%s]"),
2295
pos, m_CurrScrLine, eb, eb->GetShortName().c_str() );
2297
}while(false);//if do
2301
// ----------------------------------------------------------------------------
2302
void BrowseTracker::ClearLineBookMark()
2303
// ----------------------------------------------------------------------------
2305
// clear BookMark entry for a single line out of our history array
2307
///LOGIT( _T("ClearBookMark") );
2309
EditorBase* eb = Manager::Get()->GetEditorManager()->GetActiveEditor();
2310
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
2313
if (m_EdBook_MarksHash.find(eb) != m_EdBook_MarksHash.end() )
2315
BrowseMarks& EdBook_Marks = *m_EdBook_MarksHash[eb];
2316
GetCurrentScreenPositions();
2317
EdBook_Marks.ClearMark( m_CurrScrLineStartPosn, m_CurrScrLineEndPosn);
2318
#if defined(LOGGING)
2319
LOGIT( _T("ClearLineBookMark") );
2324
}//ClearLineBookMark
2325
// ----------------------------------------------------------------------------
2326
void BrowseTracker::RebuildBrowse_Marks(cbEditor* pcbEditor, bool addedLines)
2327
// ----------------------------------------------------------------------------
2329
// Adjust BrowseMarks from scintilla moved markers
2331
#if defined(LOGGING)
2332
///LOGIT( _T("RebuildBrowse_Marks") );
2334
EditorBase* eb = GetCurrentEditor();
2336
cbEditor* cbed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(eb);
2337
if (not cbed) return;
2339
if (m_EbBrowse_MarksHash.find(eb) != m_EbBrowse_MarksHash.end() )
2341
BrowseMarks& EdBrowse_Marks = *m_EbBrowse_MarksHash[eb];
2342
EdBrowse_Marks.RebuildBrowse_Marks( cbed, addedLines);
2345
}//RebuildBrowse_Marks
2346
// ----------------------------------------------------------------------------
2347
ProjectData* BrowseTracker::GetProjectDataByEditorName( wxString filePath)
2348
// ----------------------------------------------------------------------------
2350
wxString reason = wxT("");
2352
EditorBase* eb = m_pEdMgr->GetEditor( filePath );
2354
if ( not eb ) break;
2355
cbEditor* cbed = m_pEdMgr->GetBuiltinEditor(eb);
2356
reason = wxT("cbed");
2357
if (not cbed) break;
2358
ProjectFile* pf = cbed->GetProjectFile();
2359
reason = wxT("ProjectFile");
2361
cbProject* pcbProject = pf->GetParentProject();
2362
reason = wxT("cbProject");
2363
if (not pcbProject) break;
2364
return GetProjectDataFromHash( pcbProject);
2367
#if defined(LOGGING)
2368
//LOGIT( _T("GetProjectDataByEditorName FAILED to find [%s] for [%s]"), reason.c_str(), filePath.c_str() );
2371
// At this point CB has failed to find the project by its editor filename
2372
// So search our own ProjectData objects the hard way.
2373
for (ProjectDataHash::iterator it = m_ProjectDataHash.begin(); it != m_ProjectDataHash.end(); ++it)
2375
ProjectData* pProjectData = it->second;
2376
if ( pProjectData->GetBrowse_MarksFromHash( filePath) )
2377
return pProjectData;
2380
#if defined(LOGGING)
2381
//LOGIT( _T("GetProjectDataByEditorName FAILED to find [%s] for [%s]"), wxT("Hash entry"), filePath.c_str() );
2384
}//GetProjectDataByEditorName
2385
// ----------------------------------------------------------------------------
2386
ProjectData* BrowseTracker::GetProjectDataByProjectName( wxString projectFilePath)
2387
// ----------------------------------------------------------------------------
2389
cbProject* pProject = m_pPrjMgr->IsOpen(projectFilePath);
2390
if (not pProject) return 0;
2391
return GetProjectDataFromHash( pProject);
2393
// ----------------------------------------------------------------------------
2394
ProjectData* BrowseTracker::GetProjectDataFromHash( cbProject* pProject)
2395
// ----------------------------------------------------------------------------
2397
// Get the ProjectData* that's associated with this cbProject&
2398
// eg. cbProject* pProjectData = GetProjectFromHash(m_ProjectDataHash, pProject);
2399
ProjectDataHash& hash = m_ProjectDataHash;
2400
ProjectDataHash::iterator it = hash.find( pProject );
2401
if ( it == hash.end() ) return 0;
2404
// ----------------------------------------------------------------------------
2405
BrowseMarks* BrowseTracker::GetBrowse_MarksFromHash( EditorBase* eb)
2406
// ----------------------------------------------------------------------------
2408
// Return the BrowseMarks array associated with the Editor
2409
//EbBrowse_MarksHash m_EdBrowse_MarksArchive;
2410
EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.find(eb);
2411
if ( it == m_EbBrowse_MarksHash.end() ) return 0;
2414
// ----------------------------------------------------------------------------
2415
BrowseMarks* BrowseTracker::GetBrowse_MarksFromHash( wxString filePath)
2416
// ----------------------------------------------------------------------------
2418
// Return the BrowseMarks array associated with this file path
2420
for (EbBrowse_MarksHash::iterator it = m_EbBrowse_MarksHash.begin(); it != m_EbBrowse_MarksHash.end(); it++)
2422
BrowseMarks* p = it->second;
2423
if ( p->GetFilePath() == filePath ) {return p;}
2428
// ----------------------------------------------------------------------------
2429
BrowseMarks* BrowseTracker::GetBook_MarksFromHash( EditorBase* eb)
2430
// ----------------------------------------------------------------------------
2432
// return the Book marks history array associated with this editor
2433
EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.find(eb);
2434
if ( it == m_EdBook_MarksHash.end() ) return 0;
2437
// ----------------------------------------------------------------------------
2438
BrowseMarks* BrowseTracker::GetBook_MarksFromHash( wxString filePath)
2439
// ----------------------------------------------------------------------------
2441
// return the Book marks history array associated with this file path
2442
#if defined(LOGGING)
2443
///LOGIT( _T("GetBook_MarksFromHash looking for[%s]"),filePath.c_str() );
2446
for (EbBrowse_MarksHash::iterator it = m_EdBook_MarksHash.begin(); it != m_EdBook_MarksHash.end(); it++)
2448
BrowseMarks* p = it->second;
2449
#if defined(LOGGING)
2450
///LOGIT( _T("GetBook_MarksFromHash finding[%s]"),p->GetFilePath().c_str() );
2452
if ( p->GetFilePath() == filePath ) {return p;}
2457
// ----------------------------------------------------------------------------
2458
void BrowseTracker::DumpHash( const wxString hashType)
2459
// ----------------------------------------------------------------------------
2462
#if defined(LOGGING)
2463
LOGIT( _T("--- DumpHash ---[%s]"), hashType.c_str() );
2465
EbBrowse_MarksHash* phash = &m_EbBrowse_MarksHash;
2466
if ( hashType == wxT("BookMarks") )
2467
phash = &m_EdBook_MarksHash;
2468
EbBrowse_MarksHash& hash = *phash;
2470
for (EbBrowse_MarksHash::iterator it = hash.begin(); it != hash.end(); it++)
2472
EditorBase* eb = it->first;
2473
BrowseMarks* p = it->second;
2474
LOGIT( _T("eb*[%p]%s*[%p]name[%s]"), eb, hashType.c_str(), p, p->GetFilePath().c_str() );
2479
// ----------------------------------------------------------------------------
2480
wxString BrowseTracker::FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
2481
// ----------------------------------------------------------------------------
2483
// Find the absolute path from where this application has been run.
2484
// argv0 is wxTheApp->argv[0]
2485
// cwd is the current working directory (at startup)
2486
// appVariableName is the name of a variable containing the directory for this app, e.g.
2487
// MYAPPDIR. This is checked first.
2491
// Try appVariableName
2492
if (!appVariableName.IsEmpty())
2494
str = wxGetenv(appVariableName);
2499
#if defined(__WXMAC__) && !defined(__DARWIN__)
2500
// On Mac, the current directory is the relevant one when
2501
// the application starts.
2505
wxString argv0Str = argv0;
2506
#if defined(__WXMSW__)
2508
if (argv0Str.Contains(wxT(".exe")) ) break;
2509
if (argv0Str.Contains(wxT(".bat")) ) break;
2510
if (argv0Str.Contains(wxT(".cmd")) ) break;
2511
argv0Str.Append(wxT(".exe"));
2515
if (wxIsAbsolutePath(argv0Str))
2517
#if defined(LOGGING)
2518
LOGIT( _T("FindAppPath: AbsolutePath[%s]"), wxPathOnly(argv0Str).GetData() );
2520
return wxPathOnly(argv0Str);
2524
// Is it a relative path?
2525
wxString currentDir(cwd);
2526
if (currentDir.Last() != wxFILE_SEP_PATH)
2527
currentDir += wxFILE_SEP_PATH;
2529
str = currentDir + argv0Str;
2530
if (wxFileExists(str))
2532
#if defined(LOGGING)
2533
LOGIT( _T("FindAppPath: RelativePath[%s]"), wxPathOnly(str).GetData() );
2535
return wxPathOnly(str);
2539
// OK, it's neither an absolute path nor a relative path.
2542
wxPathList pathList;
2543
pathList.AddEnvList(wxT("PATH"));
2544
str = pathList.FindAbsoluteValidPath(argv0Str);
2547
#if defined(LOGGING)
2548
LOGIT( _T("FindAppPath: SearchPath[%s]"), wxPathOnly(str).GetData() );
2550
return wxPathOnly(str);
2554
#if defined(LOGGING)
2555
LOGIT( _T("FindAppPath: Failed, returning cwd") );
2557
return wxEmptyString;
2561
//// ----------------------------------------------------------------------------
2562
//void BrowseTracker::OnMenuTrackBackward(wxCommandEvent& event)
2563
//// ----------------------------------------------------------------------------
2565
// // *** Deprecated *** unused *** routine
2566
// // Browse Tracker menu Backward
2568
// EditorManager* EdMgr = Manager::Get()->GetEditorManager();
2569
// EditorBase* eb = 0;
2570
// EditorBase* ebCurrent = EdMgr->GetActiveEditor();
2572
// int index = m_nCurrentEditorIndex-1;
2573
// // scan for previous editor, skipping nulls (null is a closed editors)
2574
// for (int i=0; i<MaxEntries; ++i)
2576
// if ( index < 0 ) index = MaxEntries-1;
2577
// eb = m_apEditors[index];
2578
// LOGIT( _T("Backward:m_nCurrentEditorIndex[%d]index[%d]eb[%p][%s]"),m_nCurrentEditorIndex, index, eb, GetEditorFilename(eb).c_str() );
2581
// if ( eb == ebCurrent ) { --index; continue;}
2582
// if (-1 == EdMgr->FindPageFromEditor(eb) )
2583
// { // this entry has been closed behind our backs
2584
// m_apEditors[index] = 0; { --index; continue;}
2586
// m_bProjectIsLoading = true;
2588
// m_bProjectIsLoading = false;
2589
// m_nCurrentEditorIndex = index;
2590
// m_pCurrentEditor = eb;
2596
//// ----------------------------------------------------------------------------
2597
//void BrowseTracker::OnMenuTrackforward(wxCommandEvent& event)
2598
//// ----------------------------------------------------------------------------
2600
// // *** Deprecated *** unused *** routine
2601
// // Browse Tracker menu forward
2603
// EditorBase* eb = 0;
2604
// EditorManager* EdMgr = Manager::Get()->GetEditorManager();
2605
// EditorBase* ebCurrent = EdMgr->GetActiveEditor();
2607
// int index = m_nCurrentEditorIndex+1;
2608
// // scan for previous editor, skipping nulls (null is a closed editors)
2609
// for (int i=0; i<MaxEntries; ++i)
2611
// if ( index >= MaxEntries ) index = 0;
2612
// eb = m_apEditors[index];
2613
// //LOGIT( _T("Forward:m_nCurrentEditorIndex[%d]index[%d]eb[%p]"),m_nCurrentEditorIndex, index, eb );
2616
// if ( eb == ebCurrent ) { ++index; continue;}
2617
// if (-1 == EdMgr->FindPageFromEditor(eb) )
2618
// { // this entry has been closed behind our backs
2619
// m_apEditors[index] = 0; {++index; continue;}
2622
// m_bProjectIsLoading = true;
2624
// m_bProjectIsLoading = false;
2625
// m_nCurrentEditorIndex = index;
2626
// m_pCurrentEditor = eb;
2632
////// ----------------------------------------------------------------------------
2633
////void BrowseTracker::OnPageChanged(wxFlatNotebookEvent& event)
2634
////// ----------------------------------------------------------------------------
2636
//// event.Skip(); // allow others to process it too
2638
//// //-EditorBase* eb = static_cast<EditorBase*>(m_pNotebook->GetPage(event.GetSelection()));
2639
//// wxFlatNotebook* pNotebook = (wxFlatNotebook*)event.GetEventObject();
2640
//// int page = event.GetSelection();
2641
//// EditorBase* eb = static_cast<EditorBase*>(pNotebook->GetPage(page));
2642
//// LOGIT( _T("OnPageChanged eb[%p] title[%s]"), eb, eb ? eb->GetTitle().c_str() : _T(""));
2644
//// // focus editor
2645
//// // The following still doesn't set focus to the new editor/page
2646
//// if (eb) eb->Show();
2647
//// if (eb) eb->SetFocus();
2648
//// // Try to focus the editor in UpdateUI;
2649
//// m_UpdateUIFocusEditor = true;
2651
// ----------------------------------------------------------------------------