1
/***************************************************************
2
* Name: CodeSnippetsApp.cpp
3
* Purpose: Code for Application Class
8
**************************************************************/
10
This file is part of Code Snippets, a plugin for Code::Blocks
11
Copyright (C) 2007 Pecan Heber
13
This program is free software; you can redistribute it and/or
14
modify it under the terms of the GNU General Public License
15
as published by the Free Software Foundation; either version 2
16
of the License, or (at your option) any later version.
18
This program is distributed in the hope that it will be useful,
19
but WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
GNU General Public License for more details.
23
You should have received a copy of the GNU General Public License
24
along with this program; if not, write to the Free Software
25
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
// RCS-ID: $Id: codesnippetsapp.cpp 103 2007-10-30 19:17:39Z Pecan $
37
#include <wx/stdpaths.h>
38
#include <wx/process.h>
39
#include <wx/filename.h>
42
#include "codesnippetsapp.h"
43
#include "codesnippetswindow.h"
44
#include "snippetsconfig.h"
45
#include "snippetsimages.h"
46
#include "messagebox.h"
47
#include "memorymappedfile.h"
49
// The app needs a flag to disable some plugin calls
50
#if defined(BUILDING_PLUGIN)
51
#error preprocessor BUILDING_PLUGIN flag must *not* be defined for this target
55
// missing mingw header definitions
56
#define MAPVK_VK_TO_VSC 0
58
IMPLEMENT_APP(CodeSnippetsApp);
60
int fileOpenRecentFilesSubMenu = wxNewId();
61
int idFileOpenRecentFileClearHistory = wxNewId();
62
int idFileOpenRecentFile = wxNewId();
64
BEGIN_EVENT_TABLE(CodeSnippetsApp, wxApp)
65
// --- See below for CodeSnippetsAppFrame events ---
68
// ----------------------------------------------------------------------------
69
bool CodeSnippetsApp::OnInit()
70
// ----------------------------------------------------------------------------
72
// Initialize the one and only global
73
// Must be done first to allocate config file
74
g_pConfig = new CodeSnippetsConfig;
75
g_pConfig->m_bIsPlugin = false;
77
CodeSnippetsAppFrame* frame = new CodeSnippetsAppFrame(0L, _("CodeSnippets"));
78
if (GetConfig()->m_sWindowHandle.IsEmpty() ) return false;
83
//// ----------------------------------------------------------------------------
84
//void CodeSnippetsApp::OnActivate(wxActivateEvent& event)
85
//// ----------------------------------------------------------------------------
88
// LOGIT( _T("App OnActivate") );
93
// ----------------------------------------------------------------------------
94
///////////////////////////////////////////////////////////////////////////////
97
/***************************************************************
98
* Name: CodeSnippetsAppMain.cpp
99
* Purpose: Code for Application Frame
101
* Created: 2007-03-18
102
* Copyright: pecan ()
104
**************************************************************/
112
#endif //__BORLANDC__
116
enum wxbuildinfoformat {
119
wxString wxbuildinfo(wxbuildinfoformat format)
121
wxString wxbuild(wxVERSION_STRING);
123
if (format == long_f )
125
#if defined(__WXMSW__)
126
wxbuild << _T("-Windows");
127
#elif defined(__UNIX__)
128
wxbuild << _T("-Linux");
132
wxbuild << _T("-Unicode build");
134
wxbuild << _T("-ANSI build");
135
#endif // wxUSE_UNICODE
140
// dummy definition of idViewSnippets because it exists in the plugin
141
// but not in the app. But is referenced in the app anyway because the CB
142
// linux makefile does not allow preprocessor definitions to get rid of it
143
int idViewSnippets = wxNewId();
145
int idMenuFileOpen = wxNewId();
146
int idMenuFileSave = wxNewId();
147
int idMenuFileSaveAs = wxNewId();
148
int idMenuFileBackup = wxNewId();
149
int idMenuQuit = wxNewId();
150
int idMenuSettingsOptions = wxNewId();
151
int idMenuProperties = wxNewId();
152
int idMenuAbout = wxNewId();
153
// ----------------------------------------------------------------------------
154
BEGIN_EVENT_TABLE(CodeSnippetsAppFrame, wxFrame)
155
EVT_MENU(idMenuFileOpen, CodeSnippetsAppFrame::OnFileLoad)
156
EVT_MENU(idMenuFileSave, CodeSnippetsAppFrame::OnFileSave)
157
EVT_MENU(idMenuFileSaveAs, CodeSnippetsAppFrame::OnFileSaveAs)
158
EVT_MENU(idMenuFileBackup, CodeSnippetsAppFrame::OnFileBackup)
159
EVT_MENU(idMenuAbout, CodeSnippetsAppFrame::OnAbout)
160
EVT_MENU(idMenuQuit, CodeSnippetsAppFrame::OnQuit)
161
EVT_MENU(idMenuSettingsOptions, CodeSnippetsAppFrame::OnSettings)
163
EVT_TIMER(-1, CodeSnippetsAppFrame::OnTimerAlarm)
165
EVT_ACTIVATE( CodeSnippetsAppFrame::OnActivate)
166
EVT_CLOSE( CodeSnippetsAppFrame::OnClose)
167
EVT_IDLE( CodeSnippetsAppFrame::OnIdle)
168
// -- recently used --
169
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, CodeSnippetsAppFrame::OnRecentFileReopen)
170
EVT_MENU(idFileOpenRecentFileClearHistory, CodeSnippetsAppFrame::OnRecentFileClearHistory)
174
// ----------------------------------------------------------------------------
175
CodeSnippetsAppFrame::CodeSnippetsAppFrame(wxFrame *frame, const wxString& title)
176
// ----------------------------------------------------------------------------
177
: wxFrame(frame, -1, title)
180
GetConfig()->pMainFrame = 0;
181
GetConfig()->pSnippetsWindow = 0;
182
GetConfig()->m_appIsShutdown = 0;
183
GetConfig()->m_appIsDisabled = 0;
184
m_bOnActivateBusy = 0;
189
wxStandardPaths stdPaths;
191
// -------------------------------
192
// initialize version and logging
193
// -------------------------------
194
AppVersion* pVersion = new AppVersion;
195
GetConfig()->pMainFrame = this;
196
//-GetConfig()->AppName = wxTheApp->GetAppName();
197
GetConfig()->AppName = wxT("codesnippets");
199
wxWindow* m_pAppWin = this;
200
wxLog::EnableLogging(true);
201
m_pLog = new wxLogWindow( m_pAppWin, _T(" CodeSnippets Log"),true,false);
202
wxLog::SetActiveTarget( m_pLog);
204
m_pLog->GetFrame()->SetSize(20,20,600,300);
205
LOGIT( _T("CodeSnippets App Logging Started[%s]"),pVersion->GetVersion().c_str());
207
LOGIT(wxT("AppName is[%s]"),GetConfig()->AppName.c_str());
210
// Create filename like codesnippets.ini
211
//memorize the key file name as {%HOME%}\codesnippets.ini
212
wxString m_ConfigFolder = stdPaths.GetUserDataDir();
213
//-wxString m_ExecuteFolder = stdPaths.GetDataDir(); Incorrect report on Linux
214
wxString m_ExecuteFolder = FindAppPath(wxTheApp->argv[0], ::wxGetCwd(), wxEmptyString);
216
//GTK GetConfigFolder is returning double "//", eg, "/home/pecan//.codeblocks"
217
// remove the double //s from filename //+v0.4.11
218
m_ConfigFolder.Replace(_T("//"),_T("/"));
219
m_ExecuteFolder.Replace(_T("//"),_T("/"));
220
LOGIT(wxT("CfgFolder[%s]"),m_ConfigFolder.c_str());
221
LOGIT(wxT("ExecFolder[%s]"),m_ExecuteFolder.c_str());
223
// --------------------
224
// Find the config file
225
// --------------------
226
wxString cfgFilenameStr;
228
// if codesnippets.ini is in the executable folder, use it
229
cfgFilenameStr = m_ExecuteFolder + wxFILE_SEP_PATH + GetConfig()->AppName + _T(".ini");
230
LOGIT( _T("ExecCfgName[%s]"),cfgFilenameStr.c_str() );
231
if (::wxFileExists(cfgFilenameStr)) break;
233
//if codeblocks has codesnippets.ini, use it
234
cfgFilenameStr = m_ConfigFolder+wxFILE_SEP_PATH + GetConfig()->AppName + _T(".ini");
235
LOGIT( _T("MSWCfgName 1[%s]"),cfgFilenameStr.c_str() );
236
cfgFilenameStr = cfgFilenameStr.Lower();
237
LOGIT( _T("MSWCfgName 2[%s]"),cfgFilenameStr.c_str() );
238
cfgFilenameStr.Replace(wxT("codesnippets"), wxT("codeblocks"),false);
239
LOGIT( _T("MSWCfgName 3[%s]"),cfgFilenameStr.c_str() );
240
if (::wxFileExists(cfgFilenameStr) ) break;
242
// if Linux has codesnippets.ini, use it
243
cfgFilenameStr.Replace(wxT("codeblocks"),wxT(".codeblocks"));
244
LOGIT( _T("UNXCfgName[%s]"),cfgFilenameStr.c_str() );
245
if (::wxFileExists(cfgFilenameStr)) break;
247
//use the default.conf folder
248
cfgFilenameStr = m_ConfigFolder + wxFILE_SEP_PATH + GetConfig()->AppName + _T(".ini");
249
LOGIT( _T("DefaultCfgName[%s]"),cfgFilenameStr.c_str() );
252
// ---------------------
253
// Initialize Globals
254
// ---------------------
255
GetConfig()->SettingsSnippetsCfgFullPath = cfgFilenameStr;
256
LOGIT( _T("SettingsSnippetsCfgFullPath[%s]"),GetConfig()->SettingsSnippetsCfgFullPath.c_str() );
257
GetConfig()->SettingsLoad();
259
#if defined(__WXMSW__)
260
// -----------------------------------------
261
// Check for pgm instance already running
262
// -----------------------------------------
263
const wxString name = wxString::Format(wxT("CodeSnippets-%s"), wxGetUserId().c_str());
264
m_checker = new wxSingleInstanceChecker(name);
266
if ( m_checker->IsAnotherRunning() )
267
{ // Previous instance is running.
268
// Minimize then restore the first instance so pgm appears on active screen
269
// Get the first instance handle of the window from the config file
271
//-cfgFile.Read( wxT("WindowHandle"), &windowHandle ) ;
273
if ( GetConfig()->m_sWindowHandle.ToULong( &val, 16) )
274
pFirstInstance = (HWND)val;
275
if (pFirstInstance && ::IsWindow(pFirstInstance) )
277
//wxMessageBox(wxT("CodeSnippets is already running."), name);
278
SwitchToThisWindow( pFirstInstance, true );
279
//-::ShowWindow(pFirstInstance,SW_FORCEMINIMIZE); //minimize the window
280
//-::ShowWindow(pFirstInstance,SW_RESTORE); //restore the window
281
//-::BringWindowToTop(pFirstInstance);
283
// Tell app class we're terminating
284
GetConfig()->m_sWindowHandle = wxEmptyString;
289
// This is first instance of program
290
// write the window handle to the config file for other instance loads
291
GetConfig()->m_sWindowHandle = wxString::Format( wxT("%p"),this->GetHandle());
292
GetConfig()->SettingsSaveString(wxT("WindowHandle"), GetConfig()->m_sWindowHandle);
297
wxMenuBar* mbar = new wxMenuBar();
298
wxMenu* fileMenu = new wxMenu(_T(""));
299
fileMenu->Append(idMenuFileOpen, _("&Load Index...\tCtrl-O"), _("Load Snippets"));
300
fileMenu->Append(idMenuFileSave, _("&Save Index\tCtrl-S"), _("Save Snippets"));
301
fileMenu->Append(idMenuFileSaveAs, _("Save Index &As..."), _("Save Snippets As..."));
302
fileMenu->Append(idMenuFileBackup, _("Backup Index "), _("Backup Snippets Index"));
304
wxMenu* fileOpenRecentFilesSubMenu = new wxMenu(wxT(""));
305
fileOpenRecentFilesSubMenu->Append(idFileOpenRecentFileClearHistory, _("Clear History"), _("Clear Recent History"));
306
fileMenu->Append(idFileOpenRecentFile, _("Recent History"), fileOpenRecentFilesSubMenu , _("Recent Files History"));
307
fileMenu->Append(idMenuQuit, _("&Quit\tAlt-F4"), _("Quit the application"));
308
mbar->Append(fileMenu, _("&File"));
311
wxMenu* settingsMenu = new wxMenu(_T(""));
312
settingsMenu->Append(idMenuSettingsOptions, _("Options..."), _("Configuration Options"));
313
//settingsMenu->Append(idMenuSettingsSave, _("Save"), _("Save Settings"));
314
mbar->Append(settingsMenu, _("Settings"));
316
wxMenu* helpMenu = new wxMenu(_T(""));
317
helpMenu->Append(idMenuAbout, _("&About\tF1"), _("Show info about this application"));
318
mbar->Append(helpMenu, _("&Help"));
321
GetConfig()->m_pMenuBar = mbar;
323
// Initialize recent files history
324
InitializeRecentFilesHistory();
326
// -------------------
328
// -------------------
329
// create a status bar with wxWidgets info
331
versionStr = versionStr + wxT("CodeSnippets") + wxT(" ") + pVersion->GetVersion();
332
SetStatusText( versionStr, 0);
333
SetStatusText(wxbuildinfo(short_f), 1);
335
// set the frame icon
336
GetConfig()->pSnipImages = new SnipImages();
337
SetIcon(GetConfig()->GetSnipImages()->GetSnipListIcon(TREE_IMAGE_ALL_SNIPPETS));
339
// ----------------------------
341
// -----------------------------
342
// Create CodeSnippetsWindow with snippet tree
343
GetConfig()->pMainFrame = this;
344
GetConfig()->pSnippetsWindow = new CodeSnippetsWindow(this);
345
// dont allow window to disappear
346
if ( GetConfig()->windowWidth<20 ) {GetConfig()->windowWidth = 100;}
347
if ( GetConfig()->windowHeight<40 ) {GetConfig()->windowHeight = 200;}
348
SetSize(GetConfig()->windowXpos, GetConfig()->windowYpos,
349
GetConfig()->windowWidth, GetConfig()->windowHeight);
351
buildInfo = wxbuildinfo(long_f);
353
pgmVersionString = wxT("CodeSnippets v") + pVersion->GetVersion();
354
buildInfo = wxT("\t")+pgmVersionString + wxT("\n")+ wxT("\t")+buildInfo;
355
buildInfo = buildInfo + wxT("\n\n\t")+wxT("Original Code by Arto Jonsson");
356
buildInfo = buildInfo + wxT("\n\t")+wxT("Modified/Enhanced by Pecan Heber");
358
// -------------------------------------
359
// Setup KeepAlive check
360
// -------------------------------------
361
// we may have been invoked with a parameter of KeepAlivePid=####
362
if ( wxTheApp->argc >1 ) do
364
wxString keepAliveArg = wxTheApp->argv[1];
365
if ( not keepAliveArg.Contains(wxT("KeepAlivePid")) ) break;
366
wxString keepAlivePid = keepAliveArg.AfterLast('=');
367
keepAlivePid.ToLong(&m_lKeepAlivePid);
368
LOGIT( _T("App: KeepAlivePid is [%lu]"), m_lKeepAlivePid );
370
// Find the "semaphore" file and map it to memory, when the plugin
371
// clears the KeepAlivePid string, we'll terminate.
372
// To memory map a file there must exists a non-zero length file
373
wxString tempDir = GetConfig()->GetTempDir();
374
wxString mappedFileName = tempDir + wxT("/cbsnippetspid") +keepAlivePid+ wxT(".plg");
375
LOGIT( _T("mappedFileName[%s]"),mappedFileName.GetData() );
377
m_pMappedFile = new wxMemoryMappedFile( mappedFileName, true);
378
if ( not m_pMappedFile ) break;
379
if ( not m_pMappedFile->IsOk() )
381
messageBox(wxString::Format(wxT("Error %d allocating\n%s\n\n"), m_pMappedFile->GetLastError(), mappedFileName.GetData() ));
382
delete m_pMappedFile;
387
if ( m_lKeepAlivePid )
388
{ StartKeepAliveTimer( 2 );
389
LOGIT( _T("StartKeepAliveTimer for[%lu]"),m_lKeepAlivePid );
395
// ----------------------------------------------------------------------------
396
CodeSnippetsAppFrame::~CodeSnippetsAppFrame()
397
// ----------------------------------------------------------------------------
400
// ----------------------------------------------------------------------------
401
wxString CodeSnippetsAppFrame::FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName)
402
// ----------------------------------------------------------------------------
404
// Find the absolute path where this application has been run from.
405
// argv0 is wxTheApp->argv[0]
406
// cwd is the current working directory (at startup)
407
// appVariableName is the name of a variable containing the directory for this app, e.g.
408
// MYAPPDIR. This is checked first.
412
// Try appVariableName
413
if (!appVariableName.IsEmpty())
415
str = wxGetenv(appVariableName);
420
#if defined(__WXMAC__) && !defined(__DARWIN__)
421
// On Mac, the current directory is the relevant one when
422
// the application starts.
426
wxString argv0Str = argv0;
427
#if defined(__WXMSW__)
429
if (argv0Str.Contains(wxT(".exe")) ) break;
430
if (argv0Str.Contains(wxT(".bat")) ) break;
431
if (argv0Str.Contains(wxT(".cmd")) ) break;
432
argv0Str.Append(wxT(".exe"));
436
if (wxIsAbsolutePath(argv0Str))
438
LOGIT( _T("FindAppPath: AbsolutePath[%s]"), wxPathOnly(argv0Str).GetData() );
439
return wxPathOnly(argv0Str);
443
// Is it a relative path?
444
wxString currentDir(cwd);
445
if (currentDir.Last() != wxFILE_SEP_PATH)
446
currentDir += wxFILE_SEP_PATH;
448
str = currentDir + argv0Str;
449
if (wxFileExists(str))
451
LOGIT( _T("FindAppPath: RelativePath[%s]"), wxPathOnly(str).GetData() );
452
return wxPathOnly(str);
456
// OK, it's neither an absolute path nor a relative path.
460
pathList.AddEnvList(wxT("PATH"));
461
str = pathList.FindAbsoluteValidPath(argv0Str);
464
LOGIT( _T("FindAppPath: SearchPath[%s]"), wxPathOnly(str).GetData() );
465
return wxPathOnly(str);
469
LOGIT( _T("FindAppPath: Failed, returning cwd") );
470
return wxEmptyString;
474
// ----------------------------------------------------------------------------
475
void CodeSnippetsAppFrame::OnClose(wxCloseEvent &event)
476
// ----------------------------------------------------------------------------
478
// Don't close down if file checking is active
479
if (m_bOnActivateBusy)
482
// EVT_CLOSE is never called for codesnippetswindow. Maybe bec it derives from
483
// wxPanel, not wxWindow, so we'll invoke it here. It saves the xml indexes.
484
if ( GetConfig()->GetSnippetsWindow() )
485
GetConfig()->GetSnippetsWindow()->OnClose(event);
486
ReleaseMemoryMappedFile();
487
// save recently opened indexes
488
TerminateRecentFilesHistory();
493
// ----------------------------------------------------------------------------
494
void CodeSnippetsAppFrame::OnQuit(wxCommandEvent &event)
495
// ----------------------------------------------------------------------------
497
// Don't close down if file checking is active
498
if (m_bOnActivateBusy)
500
wxCloseEvent evtClose;
504
// ----------------------------------------------------------------------------
505
void CodeSnippetsAppFrame::OnAbout(wxCommandEvent &event)
506
// ----------------------------------------------------------------------------
508
GetSnippetsWindow()->ShowSnippetsAbout( buildInfo );
511
// ----------------------------------------------------------------------------
512
void CodeSnippetsAppFrame::OnSettings(wxCommandEvent& event)
513
// ----------------------------------------------------------------------------
515
SetActiveMenuId( event.GetId() );
516
GetSnippetsWindow()->OnMnuSettings(event);
518
// ----------------------------------------------------------------------------
519
void CodeSnippetsAppFrame::OnFileLoad(wxCommandEvent& event)
520
// ----------------------------------------------------------------------------
522
// Load main xml file from user specified filename
523
SetActiveMenuId( event.GetId() );
525
// Save any previously modified file
526
if ( GetFileChanged() )
527
{ // Ask users if they want to save the snippet xml file
528
int answer = messageBox( wxT("Save Snippets file?\n\n")+GetConfig()->SettingsSnippetsXmlFullPath,
529
wxT("Open"),wxYES_NO );
530
if ( answer == wxYES)
533
//SaveSnippetsToFile( GetConfig()->SettingsSnippetsXmlFullPath );
538
GetConfig()->pSnippetsWindow->OnMnuLoadSnippetsFromFile( event);
539
AddToRecentFilesHistory( GetConfig()->SettingsSnippetsXmlFullPath );
542
// ----------------------------------------------------------------------------
543
void CodeSnippetsAppFrame::OnFileSave(wxCommandEvent& event)
544
// ----------------------------------------------------------------------------
546
// save main xml file to fileName configured in Settings
547
SetActiveMenuId( event.GetId() );
550
LOGIT( _T("Saving XML file[%s]"), GetConfig()->SettingsSnippetsXmlFullPath.GetData() );
553
GetSnippetsWindow()->OnMnuSaveSnippets( event );
557
// ----------------------------------------------------------------------------
558
void CodeSnippetsAppFrame::OnFileSaveAs(wxCommandEvent& event)
559
// ----------------------------------------------------------------------------
561
// save the main xml file to another file name
563
SetActiveMenuId( event.GetId() );
565
GetConfig()->GetSnippetsWindow()->OnMnuSaveSnippetsAs( event );
569
// ----------------------------------------------------------------------------
570
void CodeSnippetsAppFrame::OnFileBackup(wxCommandEvent& event)
571
// ----------------------------------------------------------------------------
573
// backup the main xml file to file name with a sequential extension number
575
SetActiveMenuId( event.GetId() );
577
GetConfig()->GetSnippetsWindow()->OnMnuFileBackup( event );
581
// ----------------------------------------------------------------------------
582
void CodeSnippetsAppFrame::OnActivate(wxActivateEvent& event)
583
// ----------------------------------------------------------------------------
585
// Application/Codeblocks has been activated
587
if ( m_bOnActivateBusy ) {event.Skip();return;}
590
// Check that it's us that got activated
591
if (not event.GetActive()) break;
593
// Check that CodeSnippets actually has a file open
594
if (not GetConfig()->GetSnippetsWindow() ) break;
595
if (not GetConfig()->GetSnippetsTreeCtrl() ) break;
597
CodeSnippetsWindow* p = GetConfig()->GetSnippetsWindow();
599
p->CheckForExternallyModifiedFiles();
602
m_bOnActivateBusy = 0;
606
// ----------------------------------------------------------------------------
607
void CodeSnippetsAppFrame::OnTimerAlarm(wxTimerEvent& event)
608
// ----------------------------------------------------------------------------
610
// Check the memory mapped file to see if CodeSnippets plugin
611
// cleared its pid. If so, terminate
613
char* pMappedData = (char*)m_pMappedFile->GetStream();
614
long lPluginPid = atol(pMappedData);
615
wxString keepAlivePid(wxString::Format(wxT("%lu"),m_lKeepAlivePid));
616
// LOGIT( _T("lPluginPid[%lu] KeepAlivePid[%lu]"), lPluginPid, m_lKeepAlivePid );
619
if ( lPluginPid != m_lKeepAlivePid )
621
ReleaseMemoryMappedFile();
622
wxCloseEvent evtClose;
627
// When this pgm is invoked by another pgm, we got a pid argument
628
// if our creator pid is gone, terminate this pgm
629
if ( m_lKeepAlivePid && (not wxProcess::Exists( m_lKeepAlivePid )) )
631
ReleaseMemoryMappedFile();
632
wxCloseEvent evtClose;
637
// our creator is still alive
638
StartKeepAliveTimer( 1 );
640
// ----------------------------------------------------------------------------
641
void CodeSnippetsAppFrame::OnIdle(wxIdleEvent& event)
642
// ----------------------------------------------------------------------------
644
if ( GetConfig()->m_appIsShutdown) { event.Skip(); return;}
646
// when menu help clears the statusbar, put back the version string
647
wxStatusBar* sb = GetStatusBar();
649
if (GetConfig()->m_appIsShutdown)
650
{ event.Skip(); return; }
652
if ( sb->GetStatusText() == wxEmptyString )
653
{ sb->SetStatusText( versionStr);
656
// see if user changed from "external" to "docked" or "floating"
657
if ( GetConfig()->m_bWindowStateChanged )
659
// Don't close down if file checking is active
660
if (m_bOnActivateBusy)
661
{event.Skip(); return;}
662
wxCloseEvent evtClose;
664
GetConfig()->m_bWindowStateChanged = false;
667
CodeSnippetsTreeCtrl* pTree = GetConfig()->GetSnippetsTreeCtrl();
668
if ( pTree ) pTree->OnIdle();
672
// ----------------------------------------------------------------------------
673
bool CodeSnippetsAppFrame::ReleaseMemoryMappedFile()
674
// ----------------------------------------------------------------------------
676
// Unmap & delete the memory mapped file used to communicate with the
677
// external snippets process
678
if ( not m_pMappedFile ) return true;
679
if ( m_pMappedFile->IsOk() )
680
m_pMappedFile->UnmapFile();
681
delete m_pMappedFile;
683
wxString tempDir = GetConfig()->GetTempDir();
684
wxString keepAlivePid(wxString::Format(wxT("%lu"), m_lKeepAlivePid));
685
wxString mappedFileName = tempDir + wxT("/cbsnippetspid") +keepAlivePid+ wxT(".plg");
686
bool result = ::wxRemoveFile( mappedFileName );
689
// ----------------------------------------------------------------------------
690
void CodeSnippetsAppFrame::InitializeRecentFilesHistory()
691
// ----------------------------------------------------------------------------
693
TerminateRecentFilesHistory();
695
wxMenuBar* mbar = GetMenuBar();
698
int pos = mbar->FindMenu(_("&File"));
699
if (pos != wxNOT_FOUND)
701
m_pFilesHistory = new wxFileHistory(9, wxID_FILE1);
703
wxMenu* menu = mbar->GetMenu(pos);
706
wxMenu* recentFiles = 0;
707
wxMenuItem* clear = menu->FindItem(idFileOpenRecentFileClearHistory, &recentFiles);
710
recentFiles->Remove(clear);
712
wxFileConfig& cfgFile = *(GetConfig()->GetCfgFile());
713
m_pFilesHistory->Load( cfgFile );
715
//int fknt = (int)m_pFilesHistory->GetCount();
716
for (int i = 0; i < (int)m_pFilesHistory->GetCount(); ++i)
717
files.Add(m_pFilesHistory->GetHistoryFile(i) ) ;
719
for (int i = (int)files.GetCount() - 1; i >= 0; --i)
721
if(wxFileExists(files[i]))
722
m_pFilesHistory->AddFileToHistory(files[i]);
724
m_pFilesHistory->UseMenu(recentFiles);
725
m_pFilesHistory->AddFilesToMenu(recentFiles);
726
if (recentFiles->GetMenuItemCount())
727
recentFiles->AppendSeparator();
728
recentFiles->Append(clear);
731
}//InitializeRecentFilesHistory
732
// ----------------------------------------------------------------------------
733
void CodeSnippetsAppFrame::AddToRecentFilesHistory(const wxString& FileName)
734
// ----------------------------------------------------------------------------
736
wxString filename = FileName;
738
// for windows, look for case-insensitive matches
739
// if found, don't add it
740
wxString low = filename.Lower();
741
for (size_t i = 0; i < m_pFilesHistory->GetCount(); ++i)
743
if (low == m_pFilesHistory->GetHistoryFile(i).Lower())
744
{ // it exists, set filename to the existing name, so it can become
745
// the most recent one
746
filename = m_pFilesHistory->GetHistoryFile(i);
752
m_pFilesHistory->AddFileToHistory(filename);
754
// because we append "clear history" menu to the end of the list,
755
// each time we must add a history item we have to:
756
// a) remove "Clear history"
758
// c) fill it with the history items
759
// and d) append "Clear history"...
760
wxMenuBar* mbar = GetMenuBar();
763
int pos = mbar->FindMenu(_("&File"));
764
if (pos == wxNOT_FOUND)
766
wxMenu* menu = mbar->GetMenu(pos);
769
wxMenu* recentFiles = 0;
770
wxMenuItem* clear = menu->FindItem(idFileOpenRecentFileClearHistory, &recentFiles);
771
if (clear && recentFiles)
774
recentFiles->Remove(clear);
776
m_pFilesHistory->RemoveMenu(recentFiles);
777
while (recentFiles->GetMenuItemCount())
778
recentFiles->Delete(recentFiles->GetMenuItems()[0]);
780
m_pFilesHistory->UseMenu(recentFiles);
781
m_pFilesHistory->AddFilesToMenu(recentFiles);
783
if (recentFiles->GetMenuItemCount())
784
recentFiles->AppendSeparator();
785
recentFiles->Append(clear);
787
//-b_RecentFilesModified = true;
789
}//AddToRecentFilesHistory
790
// ----------------------------------------------------------------------------
791
void CodeSnippetsAppFrame::TerminateRecentFilesHistory()
792
// ----------------------------------------------------------------------------
797
for (unsigned int i = 0; i < m_pFilesHistory->GetCount(); ++i)
798
files.Add(m_pFilesHistory->GetHistoryFile(i));
800
wxFileConfig& cfgFile = *(GetConfig()->GetCfgFile());
801
m_pFilesHistory->Save( cfgFile );
804
wxMenuBar* mbar = GetMenuBar();
807
int pos = mbar->FindMenu(_("&File"));
808
if (pos != wxNOT_FOUND)
810
wxMenu* menu = mbar->GetMenu(pos);
813
wxMenu* recentFiles = 0;
814
menu->FindItem(idFileOpenRecentFileClearHistory, &recentFiles);
816
m_pFilesHistory->RemoveMenu(recentFiles);
820
delete m_pFilesHistory;
823
//-b_RecentFilesModified = false;
824
}//TerminateRecentFilesHistory
825
// ----------------------------------------------------------------------------
826
void CodeSnippetsAppFrame::OnRecentFileReopen(wxCommandEvent& event)
827
// ----------------------------------------------------------------------------
829
size_t id = event.GetId() - wxID_FILE1;
830
wxString fname = m_pFilesHistory->GetHistoryFile(id);
831
//// if (!OpenGeneric(fname, true))
833
//// AskToRemoveFileFromHistory(m_pFilesHistory, id);
837
if (GetFileChanged() ) OnFileSave(event);
839
// load specified recent xml index
840
if (::wxFileExists(fname))
842
GetConfig()->SettingsSnippetsXmlFullPath = fname;
843
GetSnippetsWindow()->GetSnippetsTreeCtrl()->LoadItemsFromFile( fname, false);
844
GetSnippetsWindow()->GetSnippetsTreeCtrl()->SetFileChanged(false);
845
GetSnippetsWindow()->GetSnippetsTreeCtrl()->SaveFileModificationTime();
849
wxString msg(wxString::Format(wxT("File not found:\n%s\n\n"),fname.GetData()));
853
// ----------------------------------------------------------------------------
854
void CodeSnippetsAppFrame::OnRecentFileClearHistory(wxCommandEvent& event)
855
// ----------------------------------------------------------------------------
857
while (m_pFilesHistory->GetCount())
859
m_pFilesHistory->RemoveFileFromHistory(0);
862
}//OnFileOpenRecentClearHistory
863
// ----------------------------------------------------------------------------