1
//---------------------------------------------------------------------------------------
2
// LenMus Phonascus: The teacher of music
3
// Copyright (c) 2002-2011 LenMus project
5
// This program is free software; you can redistribute it and/or modify it under the
6
// terms of the GNU General Public License as published by the Free Software Foundation,
7
// either version 3 of the License, or (at your option) any later version.
9
// This program is distributed in the hope that it will be useful, but WITHOUT ANY
10
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11
// PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
// You should have received a copy of the GNU General Public License along with this
14
// program. If not, see <http://www.gnu.org/licenses/>.
16
// For any comment, suggestion or feature request, please contact the manager of
17
// the project at cecilios@users.sourceforge.net
19
//---------------------------------------------------------------------------------------
22
#include "lenmus_app.h"
23
#include "lenmus_config.h"
25
#include "lenmus_main_frame.h"
26
#include "lenmus_art_provider.h"
27
#include "lenmus_paths.h"
28
#include "lenmus_midi_server.h"
35
// This macro will allow wxWindows to create the application object during program
36
// execution (it's better than using a static object for many reasons) and also
37
// declares the accessor function wxGetApp() which will return the reference of
38
// the right type (i.e. TheApp and not wxApp)
39
IMPLEMENT_APP(lenmus::TheApp)
45
//=======================================================================================
46
// TheApp implementation
47
//=======================================================================================
51
, m_pInstanceChecker((wxSingleInstanceChecker*)NULL)
52
// , m_pDocManager((lmDocManager*)NULL)
58
// //in release version we will deal with crashes.
59
// //tell base class to call our OnFatalException()
60
// wxHandleFatalExceptions();
64
//---------------------------------------------------------------------------------------
67
//A wxWidgets application does not have a main procedure; the equivalent is
68
//this: the OnInit member
69
//The method builds the objects necessary to run the application (it is like
70
//the 'constructor'. It must return true to continue, and in this case, control
71
//is transferred to OnRun(). Otherwise the application is terminated witout further
74
if (!do_application_setup())
77
// if (!wxApp::OnInit())
79
// do_application_cleanup();
83
// //wxApp::OnInit() will invoke OnInitCmdLine() and OnCmdLineParsed()
84
// //Therefore, at this point command line is parsed, and all options set up
87
// do_application_cleanup();
88
// return false; //stop
92
// ::wxBeginBusyCursor();
93
// wait_and_destroy_splash();
94
show_welcome_window();
95
// RecoverScoreIfPreviousCrash();
96
// ::wxEndBusyCursor();
100
// m_frame->RunUnitTests();
107
//---------------------------------------------------------------------------------------
108
bool TheApp::do_application_setup()
110
// set information about this application
111
wxString& sAppName = m_appScope.get_app_name();
112
SetVendorName( m_appScope.get_vendor_name() );
113
SetAppName(sAppName);
115
// verify that this is the only instance running
116
wxString name = sAppName + _T("-") + m_appScope.get_version_string()
117
+ _T("-") + wxGetUserId();
118
m_pInstanceChecker = new wxSingleInstanceChecker(name);
119
if ( m_pInstanceChecker->IsAnotherRunning() )
121
wxString msg = wxString::Format(_("Another instance of %s is already running."),
122
m_appScope.get_app_name().c_str() );
123
wxMessageBox(msg, sAppName, wxOK | wxICON_EXCLAMATION );
127
create_paths_object();
128
create_needed_folders_if_dont_exist();
129
//All paths, except user configurable ones, are valid from this point
131
m_appScope.create_preferences_object();
132
//Now preferences object and root path are set up. We can proceed to initialize
133
//global variables that depend on user preferences.
135
// // Load user preferences or default values if first run
136
load_user_preferences();
137
// InitPreferences();
138
// g_pPaths->LoadUserPreferences();
141
// // AWARE: All paths, even user configurable ones, are valid from this point
142
// // *************************************************************************
146
// g_pColors = new lmColors();
149
// // Error reporting and trace/dump logs
152
// g_pLogger = new lmLogger();
154
// // For debugging: send log messages to a file
155
// wxString sUserId = ::wxGetUserId();
156
// wxString sLogFile = g_pPaths->GetLogPath() + sUserId + _T("_Debug_log.txt");
157
// wxLog *logger = new wxLogStderr( wxFopen(sLogFile.c_str(), _T("w")) );
158
// new wxLogChain(logger);
160
// // open data log file and re-direct all loging there
161
// sLogFile = g_pPaths->GetLogPath() + sUserId + _T("_DataError_log.txt");
162
// g_pLogger->SetDataErrorTarget(sLogFile);
164
// SetUpCurrentLanguage();
166
// //UploadForensicLogIfExists();
167
// //Upload forensic log, if exists
169
// // open forensic log file
170
// sLogFile = g_pPaths->GetLogPath() + sUserId + _T("_forensic_log.txt");
171
// wxString sLogScore = g_pPaths->GetLogPath() + sUserId + _T("_score.lmb");
172
// if (g_pLogger->IsValidForensicTarget(sLogFile))
174
// //previous program run terminated with a crash and forensic log was not
175
// //uploaded (probably we were in debug mode and program execution was
176
// //cancelled. Inform user and request permision to submit file for bug
178
// SendForensicLog(sLogFile, false); //false: not handling a crash
180
// g_pLogger->SetForensicTarget(sLogFile, sLogScore);
182
// DefineTraceMasks();
183
// // AWARE: Log/debug methods are available from this point
185
// wxLogMessage(_T("[TheApp::OnInit] Config file: ") + oCfgFile.GetFullPath() );
189
// Define handlers for the image types managed by the application
190
// BMP handler is by default always defined
191
wxImage::AddHandler( new wxPNGHandler );
192
wxImage::AddHandler( new wxJPEGHandler );
194
// Set the art provider and get current user selected background bitmap
195
wxArtProvider::Push(new ArtProvider(m_appScope));
196
//m_background = wxArtProvider::GetBitmap(_T("backgrnd"));
198
// //Include support for zip files
199
// wxFileSystem::AddHandler(new wxZipFSHandler);
201
// InitializeXrcResources();
202
// CreateDocumentManager();
203
// CreateDocumentTemplates();
206
////#if defined(_LM_DEBUG_) && defined(_LM_LINUX_)
207
//// //For Linux in Debug build, use a window to show wxLog messages. This is
208
//// //the only way I found to see wxLog messages with Code::Blocks
209
//// wxLogWindow* pMyLog = new wxLogWindow(m_frame, _T("Debug window: wxLogMessages"));
210
//// wxLog::SetActiveTarget(pMyLog);
211
//// wxLogMessage(_T("[TheApp::OnInit] Config file: ") + oCfgFile.GetFullPath() );
212
//// pMyLog->Flush();
215
// // create global data structures for printer settings
216
// g_pPrintData = new wxPrintData;
217
// g_pPaperSetupData = new wxPageSetupDialogData;
219
// //Seed the random-number generator with current time so that
220
// //the numbers will be different every time we run.
221
// srand( (unsigned)time( NULL ) );
228
//---------------------------------------------------------------------------------------
229
void TheApp::create_paths_object()
231
#if (LENMUS_PLATFORM_WIN32 == 1 || LENMUS_PLATFORM_UNIX == 1)
232
// On Linux, Windows and Mac OS X the path to the LenMus program is in argv[0]
233
wxString sBinPath = wxPathOnly(argv[0]);
234
//wxLogMessage(_T("[TheApp::create_paths_object] sBinPath='%s'"), sBinPath.c_str());
235
//but in console mode fails!
236
if (sBinPath.IsEmpty())
237
sBinPath = wxGetCwd();
238
//#elif defined(__MACOS9__)
239
// // On Mac OS 9, the initial working directory is the one that
240
// // contains the program.
241
// wxString sBinPath = wxGetCwd();
243
#error "Unknown operating system!"
246
m_appScope.set_bin_folder(sBinPath);
249
//---------------------------------------------------------------------------------------
250
void TheApp::create_needed_folders_if_dont_exist()
252
Paths* pPaths = m_appScope.get_paths();
253
pPaths->create_folders();
256
//---------------------------------------------------------------------------------------
257
void TheApp::load_user_preferences()
259
//wxConfigBase* pPrefs = m_appScope.get_preferences();
261
//pPrefs->Read(_T("/Options/EnableAnswerSounds"), &g_fAnswerSoundsEnabled, true);
262
//pPrefs->Read(_T("/Options/AutoNewProblem"), &g_fAutoNewProblem, true);
263
//pPrefs->Read(_T("/Options/AutoBeam"), &g_fAutoBeam, true);
266
////---------------------------------------------------------------------------------------
267
//void TheApp::OpenDataBase()
269
// //initialize DataBase support and open database
272
// //wxSQLite3Database::InitializeSQLite();
273
// g_pDB = new wxSQLite3Database();
274
// wxFileName oDBFile(g_pPaths->GetConfigPath(), _T("lenmus"), _T("db") );
275
// wxLogMessage(_T("[TheApp::OnInit] SQLite3 Version: %s. DB file: '%s'"),
276
// g_pDB->GetVersion().c_str(), oDBFile.GetFullPath().c_str() );
277
// g_pDB->Open(oDBFile.GetFullPath());
279
// catch (wxSQLite3Exception& e)
281
// wxLogMessage(_T("Error code: %d, Message: '%s'"),
282
// e.GetErrorCode(), e.GetMessage().c_str() );
286
////---------------------------------------------------------------------------------------
287
//void TheApp::DefineTraceMasks()
290
// //define trace masks to be known by trace system
291
// g_pLogger->DefineTraceMask(_T("lmCadence"));
292
// g_pLogger->DefineTraceMask(_T("lmChord"));
293
// g_pLogger->DefineTraceMask(_T("lmColStaffObjs::Delete"));
294
// g_pLogger->DefineTraceMask(_T("lmColStaffObjs::Insert"));
295
// g_pLogger->DefineTraceMask(_T("lmComposer6"));
296
// g_pLogger->DefineTraceMask(_T("lmComposer6::AssignNonChordNotes"));
297
// g_pLogger->DefineTraceMask(_T("lmComposer6::FunctionToChordNotes"));
298
// g_pLogger->DefineTraceMask(_T("lmComposer6::GenerateContour"));
299
// g_pLogger->DefineTraceMask(_T("lmComposer6::InstantiateNotes"));
300
// g_pLogger->DefineTraceMask(_T("lmComposer6::NearestNoteOnChord"));
301
// g_pLogger->DefineTraceMask(_T("Formater4"));
302
// g_pLogger->DefineTraceMask(_T("Formatter4.Step1"));
303
// g_pLogger->DefineTraceMask(_T("lmFragmentsTable::GetFirstSegmentDuracion"));
304
// g_pLogger->DefineTraceMask(_T("lmIdfyScalesCtrol"));
305
// g_pLogger->DefineTraceMask(_T("lmIdfyCadencesCtrol"));
306
// g_pLogger->DefineTraceMask(_T("lmInterval"));
307
// g_pLogger->DefineTraceMask(_T("lmKeySignature"));
308
// g_pLogger->DefineTraceMask(_T("lmLDPParser"));
309
// g_pLogger->DefineTraceMask(_T("LDPParser_beams"));
310
// g_pLogger->DefineTraceMask(_T("lmMusicXMLParser"));
311
// g_pLogger->DefineTraceMask(_T("OnMouseEvent"));
312
// g_pLogger->DefineTraceMask(_T("lmScoreAuxCtrol"));
313
// g_pLogger->DefineTraceMask(_T("lmScoreCtrolParams"));
314
// g_pLogger->DefineTraceMask(_T("Timing: Score renderization"));
315
// g_pLogger->DefineTraceMask(_T("lmTheoKeySignCtrol"));
316
// g_pLogger->DefineTraceMask(_T("lmUpdater"));
320
////---------------------------------------------------------------------------------------
321
//void TheApp::CreateDocumentManager()
323
// m_pDocManager = new lmDocManager();
324
// m_pDocManager->LoadRecentFiles(g_pPrefs, _T("/RecentFiles/"));
326
// //if no recent files, load some samples
327
// if (m_pDocManager->NumFilesInHistory() == 0)
329
// wxString sPath = g_pPaths->GetSamplesPath();
330
// wxFileName oFile1(sPath, _T("greensleeves_v15.lms"));
331
// wxFileName oFile2(sPath, _T("chopin_prelude20_v15.lms"));
332
// wxFileName oFile3(sPath, _T("beethoven_moonlight_sonata_v15.lms"));
333
// //wxLogMessage(_T("[MainFrame::LoadRecentFiles] sPath='%s', sFile1='%s'"),
334
// // sPath.c_str(), oFile1.GetFullPath().c_str() );
335
// m_pDocManager->AddToHistory(oFile1.GetFullPath());
336
// m_pDocManager->AddToHistory(oFile2.GetFullPath());
337
// m_pDocManager->AddToHistory(oFile3.GetFullPath());
340
// // Sets the directory to be displayed to the user when opening a score.
341
// m_pDocManager->SetLastDirectory(g_pPaths->GetScoresPath());
344
////---------------------------------------------------------------------------------------
345
//void TheApp::CreateDocumentTemplates()
347
// // Create a template relating score documents to their views
348
// (void) new wxDocTemplate(m_pDocManager, _T("LenMus score"), _T("*.lms"), _T(""), _T("lms"), _T("LenMus score"), _T("lmScore View"),
349
// CLASSINFO(lmDocument), CLASSINFO(lmScoreView));
350
// (void) new wxDocTemplate(m_pDocManager, _T("MusicXML score"), _T("*.xml;*.*"), _T(""), _T("xml"), _T("MusicXML score"), _T("lmScore View"),
351
// CLASSINFO(lmDocument), CLASSINFO(lmScoreView), wxTEMPLATE_INVISIBLE );
353
// // wxFileName::MacRegisterDefaultTypeAndCreator( wxT("lms") , 'WXMB' , 'WXMA' ) ;
357
////---------------------------------------------------------------------------------------
358
//void TheApp::InitializeXrcResources()
360
// // Initialize all the XRC handlers.
361
// wxXmlResource::Get()->InitAllHandlers();
363
// // get path for xrc resources
364
// wxString sPath = g_pPaths->GetXrcPath();
366
// // Load all of the XRC files that will be used. You can put everything
367
// // into one giant XRC file if you wanted, but then they become more
368
// // difficult to manage, and harder to reuse in later projects.
370
// // The score generation settings dialog
371
// wxFileName oXrcFile(sPath, _T("DlgCfgScoreReading"), _T("xrc"), wxPATH_NATIVE);
372
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
374
// // Configuration options: toolbars panel
375
// oXrcFile = wxFileName(sPath, _T("ToolbarsOptPanel"), _T("xrc"), wxPATH_NATIVE);
376
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
378
// // Configuration options: languages panel
379
// oXrcFile = wxFileName(sPath, _T("LangOptionsPanel"), _T("xrc"), wxPATH_NATIVE);
380
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
382
// // Configuration options: Internet options panel
383
// oXrcFile = wxFileName(sPath, _T("InternetOptPanel"), _T("xrc"), wxPATH_NATIVE);
384
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
386
// // Ear Interval exercises: configuration dialog
387
// oXrcFile = wxFileName(sPath, _T("DlgCfgEarIntervals"), _T("xrc"), wxPATH_NATIVE);
388
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
390
// // Chord identification exercises: configuration dialog
391
// oXrcFile = wxFileName(sPath, _T("DlgCfgIdfyChord"), _T("xrc"), wxPATH_NATIVE);
392
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
394
// // Scales identification exercises: configuration dialog
395
// oXrcFile = wxFileName(sPath, _T("DlgCfgIdfyScale"), _T("xrc"), wxPATH_NATIVE);
396
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
398
// // Cedences identification exercises: configuration dialog
399
// oXrcFile = wxFileName(sPath, _T("DlgCfgIdfyCadence"), _T("xrc"), wxPATH_NATIVE);
400
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
402
// // Pattern Editor dialog
403
// oXrcFile = wxFileName(sPath, _T("DlgPatternEditor"), _T("xrc"), wxPATH_NATIVE);
404
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
406
// // Updater dialog: start
407
// oXrcFile = wxFileName(sPath, _T("UpdaterDlgStart"), _T("xrc"), wxPATH_NATIVE);
408
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
410
// // Updater dialog: info
411
// oXrcFile = wxFileName(sPath, _T("UpdaterDlgInfo"), _T("xrc"), wxPATH_NATIVE);
412
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
415
// // Debug: masks to trace dialog
416
// oXrcFile = wxFileName(sPath, _T("DlgDebugTrace"), _T("xrc"), wxPATH_NATIVE);
417
// wxXmlResource::Get()->Load( oXrcFile.GetFullPath() );
421
//---------------------------------------------------------------------------------------
422
void TheApp::create_main_frame()
424
m_nSplashVisibleMilliseconds = 3000L; // at least visible for 3 seconds
425
m_nSplashStartTime = long( time(NULL) );
427
create_GUI(m_nSplashVisibleMilliseconds, true); //true=first time
430
////---------------------------------------------------------------------------------------
431
//void TheApp::wait_and_destroy_splash()
433
// // check if the splash window display time is ellapsed and wait if not
437
// m_nSplashVisibleMilliseconds -= ((long)time( NULL ) - m_nSplashStartTime);
438
// if (m_nSplashVisibleMilliseconds > 0) ::wxMilliSleep( m_nSplashVisibleMilliseconds );
439
// m_pSplash->AllowDestroy(); // allow to destroy the splash
443
//---------------------------------------------------------------------------------------
444
void TheApp::show_welcome_window()
446
#if 0 //while in development, start with nothing displayed
447
m_frame->show_welcome_window();
451
////---------------------------------------------------------------------------------------
452
//void TheApp::RecoverScoreIfPreviousCrash()
454
// //open any existing score being edited before a crash
455
// wxString sUserId = ::wxGetUserId();
456
// wxString sLogScore = g_pPaths->GetLogPath() + sUserId + _T("_score.lmb");
457
// if (::wxFileExists(sLogScore))
459
// wxString sQuestion =
460
// _("An score being edited before a program crash has been detected!");
461
// sQuestion += _T("\n\n");
462
// sQuestion += _("Should the program attempt to recover it?");
463
// lmQuestionBox oQB(sQuestion, 2, //msge, num buttons,
464
// //labels (2 per button: button text + explanation)
465
// _("Yes"), _("Yes, try to recover the score"),
466
// _("No"), _("No, forget about that score")
468
// int nAnswer = oQB.ShowModal();
470
// if (nAnswer == 0) //'Yes' button
471
// m_frame->OpenScore(sLogScore, true); //true: as new file
475
////---------------------------------------------------------------------------------------
476
//void TheApp::CheckForUpdates()
478
// //check for updates if this option is set up. Default: do check
479
// wxString sCheckFreq = g_pPrefs->Read(_T("/Options/CheckForUpdates/Frequency"), _T("Weekly") );
480
// if (sCheckFreq != _T("Never")) {
481
// //get date of last sucessful check
482
// bool fDoCheck = false;
483
// wxString sLastCheckDate =
484
// g_pPrefs->Read(_T("/Options/CheckForUpdates/LastCheck"), _T(""));
485
// if (sLastCheckDate == _T("")) {
489
// wxDateTime dtLastCheck, dtNextCheck;
490
// wxDateSpan dsSpan;
491
// const wxChar *p = dtLastCheck.ParseDate(sLastCheckDate);
493
// wxLogMessage(_T("[TheApp::OnInit] Error parsing the last check for updates date '%s'.\n"), sLastCheckDate.c_str());
497
// //verify elapsed time
498
// if (sCheckFreq == _T("Daily"))
499
// dsSpan = wxDateSpan::Days(1);
500
// else if (sCheckFreq == _T("Weekly"))
501
// dsSpan = wxDateSpan::Weeks(1);
503
// dsSpan = wxDateSpan::Months(1);
505
// dtNextCheck = dtLastCheck;
506
// dtNextCheck.Add(dsSpan);
507
// fDoCheck = (dtNextCheck <= wxDateTime::Now());
510
// wxString sDoCheck = fDoCheck ? _T("True") : _T("False");
511
// wxLogMessage(_T("[TheApp::OnInit] CheckForUpdates: dtLastCheck='%s', sCheckFreq=%s (%d), dtNextCheck='%s', fDoCheck=%s"),
512
// dtLastCheck.Format(_T("%x")).c_str(),
513
// sCheckFreq.c_str(), dsSpan.GetTotalDays(),
514
// dtNextCheck.Format(_T("%x")).c_str(),
515
// sDoCheck.c_str() );
519
// // if time for another check, do it
521
// m_frame->SilentlyCheckForUpdates(true);
522
// wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, lmMENU_CheckForUpdates);
523
// wxPostEvent(m_frame, event);
528
//---------------------------------------------------------------------------------------
529
void TheApp::configure_midi()
531
MidiServer* pMidi = m_appScope.get_midi_server();
533
//if MIDI not set, force to run the MIDI wizard
534
if (!pMidi->is_configured())
535
m_frame->run_midi_wizard();
537
//Set up MIDI devices
538
pMidi->SetUpCurrentConfig();
540
//set sound for metronome
541
wxMidiOutDevice* pMidiOut = pMidi->get_out_device();
543
pMidiOut->ProgramChange(pMidi->MtrChannel(), pMidi->MtrInstr());
546
//---------------------------------------------------------------------------------------
547
void TheApp::do_application_cleanup()
549
// delete all objects used by TheApp
551
//Paths* pPaths = m_appScope.get_paths();
552
//pPaths->SaveUserPreferences();
554
// // the Midi configuration and related objects
558
// // the wave sound manager object
559
// lmWaveManager::Destroy();
561
// //delete the docManager
562
// delete m_pDocManager;
567
// wxSQLite3Database::ShutdownSQLite();
569
// //remove forensic log and delete logger
570
// g_pLogger->DeleteForensicTarget();
573
// // the printer setup data
574
// delete g_pPrintData;
575
// delete g_pPaperSetupData;
577
//the single instance checker
578
delete m_pInstanceChecker;
581
// delete g_pColors; //colors object
582
// lmPgmOptions::DeleteInstance(); //the program options object
583
// delete m_pLocale; //locale object
584
// lmMusicFontManager::DeleteInstance(); //music font manager
585
// lmProcessorMngr::DeleteInstance(); //Processor manager
586
// lmChordsDB::DeleteInstance(); //Chords Database
589
////---------------------------------------------------------------------------------------
590
//void TheApp::ParseCommandLine()
592
// wxCmdLineParser parser;
593
// OnInitCmdLine(parser);
594
// OnCmdLineParsed(parser);
597
////---------------------------------------------------------------------------------------
598
//void TheApp::OnInitCmdLine(wxCmdLineParser& parser)
600
// static const wxCmdLineEntryDesc cmdLineDesc[] =
602
// { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _("Show this help message"),
603
// wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
604
// { wxCMD_LINE_SWITCH, _T("t"), _T("test"), _T("Run unit tests"),
605
// wxCMD_LINE_VAL_NONE },
607
// //end of table entry
608
// { wxCMD_LINE_NONE, _T(""), _T(""), _T(""), wxCMD_LINE_VAL_NONE }
611
// parser.SetDesc(cmdLineDesc);
612
// parser.SetSwitchChars(_T("-")); //use '-' as parameter starter
615
////---------------------------------------------------------------------------------------
616
//bool TheApp::OnCmdLineParsed(wxCmdLineParser& parser)
618
// m_fUseGui = !parser.Found(_T("t"));
620
// if ( parser.Found(_T("t")) )
623
// lmTestRunner oTR((wxWindow*)NULL);
628
// //http://forums.wxwidgets.org/viewtopic.php?t=22211
629
// //According to this article (see the second Q&A)
631
// // http://msdn.microsoft.com/en-ca/magazine/cc164023.aspx
633
// //getting the output to go into the same command-line window as the one that
634
// //started the program is not possible under Windows, because when executing a
635
// //GUI program, the command prompt does not wait for the program to finish
636
// //executing, so the command prompt will be screwed up if you try to write
637
// //in the same console. The fault is with Windows, not with wxWidgets.
642
////---------------------------------------------------------------------------------------
643
//void TheApp::SetUpCurrentLanguage()
645
// wxString lang = g_pPrefs->Read(_T("/Locale/Language"), _T(""));
646
// if (lang.IsEmpty())
648
// //The language is not set. This will only happen the first time
649
// //the program is run or if lenmus.ini file is deleted
651
// // try to get installer choosen language and use it if found
652
// lang = GetInstallerLanguage();
654
// if (lang.IsEmpty())
656
// // Not found. Pop up a dialog to choose language.
657
// lang = ChooseLanguage(NULL);
659
// g_pPrefs->Write(_T("/Locale/Language"), lang);
662
// // Now that language code is known we can finish lmPaths initialization
663
// // and load locale catalogs
664
// SetUpLocale(lang);
667
////---------------------------------------------------------------------------------------
668
//void TheApp::OnChangeLanguage(wxCommandEvent& WXUNUSED(event))
670
// SetUpCurrentLanguage();
671
// create_GUI(0, false); //0 = No splash, false=not first time
672
// show_welcome_window();
675
////---------------------------------------------------------------------------------------
676
//void TheApp::SetUpLocale(wxString lang)
678
// // lmPaths re-initialization
679
// g_pPaths->SetLanguageCode(lang);
681
// //get wxLanguage code and name
682
// const wxLanguageInfo* pInfo = wxLocale::FindLanguageInfo(lang);
684
// wxString sLangName;
686
// nLang = pInfo->Language;
687
// sLangName = pInfo->Description;
690
// nLang = wxLANGUAGE_ENGLISH;
691
// sLangName = _T("English");
692
// wxLogMessage(_T("[TheApp::SetUpLocale] Language '%s' not found. Update lmApp.cpp?"), lang.c_str());
696
// // locale object re-initialization
697
// if (m_pLocale) delete m_pLocale;
698
// m_pLocale = new wxLocale();
699
// if (!m_pLocale->Init(_T(""), lang, _T(""), false, true)) {
700
// //if (!m_pLocale->Init( nLang, wxLOCALE_CONV_ENCODING )) {
701
// wxMessageBox( wxString::Format(_T("Language %s can not be set. ")
702
// _T("Please, verify that any required language codepages are installed in your system."),
703
// sLangName.c_str()));
706
// wxString sPath = g_pPaths->GetLocaleRootPath();
707
// m_pLocale->AddCatalogLookupPathPrefix( sPath );
709
// wxString sNil = _T("");
710
// sCtlg = sNil + _T("lenmus_") + lang; //m_pLocale->GetName();
711
// if (!m_pLocale->AddCatalog(sCtlg))
712
// wxLogMessage(_T("[TheApp::SetUpLocale] Failure to load catalog '%s'. Path='%s'"),
713
// sCtlg.c_str(), sPath.c_str());
714
// sCtlg = sNil + _T("wxwidgets_") + lang;
715
// if (!m_pLocale->AddCatalog(sCtlg))
716
// wxLogMessage(_T("[TheApp::SetUpLocale] Failure to load catalog '%s'. Path='%s'"),
717
// sCtlg.c_str(), sPath.c_str());
718
// sCtlg = sNil + _T("wxmidi_") + lang;
719
// if (!m_pLocale->AddCatalog(sCtlg))
720
// wxLogMessage(_T("[TheApp::SetUpLocale] Failure to load catalog '%s'. Path='%s'"),
721
// sCtlg.c_str(), sPath.c_str());
725
//---------------------------------------------------------------------------------------
726
int TheApp::OnExit(void)
728
do_application_cleanup();
732
//---------------------------------------------------------------------------------------
733
void TheApp::get_default_placement(wxRect *defRect)
737
wxClientDisplayRect(&screenRect.x, &screenRect.y,
738
&screenRect.width, &screenRect.height);
740
//default size/pos: full screen
743
defRect->width = screenRect.width;
744
defRect->height = screenRect.height;
747
//---------------------------------------------------------------------------------------
748
void TheApp::get_main_window_placement(wxRect* frameRect, bool* fMaximized)
750
// *fMaximized = false; // default: not maximized
752
// set the default window size
754
get_default_placement(&defWndRect);
755
wxLogMessage( wxString::Format(_T("default: x=%d, y=%d, w=%d, h=%d"),
756
defWndRect.x, defWndRect.y, defWndRect.width, defWndRect.height));
758
//Read the values from the config file, or use the defaults
759
wxConfigBase* pConfig = m_appScope.get_preferences();
760
frameRect->SetWidth(pConfig->Read(_T("/MainFrame/Width"), defWndRect.GetWidth()));
761
frameRect->SetHeight(pConfig->Read(_T("/MainFrame/Height"), defWndRect.GetHeight()));
762
frameRect->SetLeft(pConfig->Read(_T("/MainFrame/Left"), defWndRect.GetLeft() ));
763
frameRect->SetTop(pConfig->Read(_T("/MainFrame/Top"), defWndRect.GetTop() ));
765
pConfig->Read(_T("/MainFrame/Maximized"), fMaximized);
767
//--- Make sure that the Window will be completely visible -------------
769
//Get the size of the screen
771
wxClientDisplayRect(&screenRect.x, &screenRect.y,
772
&screenRect.width, &screenRect.height);
773
wxLogMessage( wxString::Format(_T("screen: x=%d, y=%d, w=%d, h=%d"),
774
screenRect.x, screenRect.y, screenRect.width, screenRect.height));
776
//If we have hit the bottom of the screen restore default position on the screen
777
if (frameRect->y + frameRect->height > screenRect.y + screenRect.height)
779
frameRect->x = defWndRect.x;
780
frameRect->y = defWndRect.y;
783
//if we have hit the right side of the screen restore default position
784
if (frameRect->x + frameRect->width > screenRect.x + screenRect.width)
786
frameRect->x = defWndRect.x;
787
frameRect->y = defWndRect.y;
790
//Next check if the screen is too small for the default width and height
791
if ((frameRect->x + frameRect->width > screenRect.x + screenRect.width) ||
792
(frameRect->y + frameRect->height > screenRect.y + screenRect.height) )
794
//Resize the main window to fit in the screen
795
frameRect->width = screenRect.width - frameRect->x;
796
frameRect->height = screenRect.height - frameRect->y;
798
wxLogMessage( wxString::Format(_T("proposed: x=%d, y=%d, w=%d, h=%d"),
799
frameRect->x, frameRect->y, frameRect->width, frameRect->height));
802
////---------------------------------------------------------------------------------------
803
//wxString TheApp::ChooseLanguage(wxWindow *parent)
805
// //Pop up a language asking the user to choose a language for the user interface.
806
// //Generally only popped up once, the first time the program is run.
808
// lmLangChoiceDlg dlog(parent, -1, _("LenMus First Run"));
809
// dlog.CentreOnParent();
811
// return dlog.GetLang();
814
////---------------------------------------------------------------------------------------
815
//const wxString TheApp::GetCurrentUser()
817
// wxString sUser = ::wxGetUserId();
821
//---------------------------------------------------------------------------------------
822
SplashFrame* TheApp::create_GUI(int nMilliseconds, bool fFirstTime)
824
bool fRestarting = false;
825
MainFrame* pMainFrame = dynamic_cast<MainFrame*>( GetTopWindow() );
826
if(pMainFrame && !fFirstTime)
829
pMainFrame->Destroy();
835
get_main_window_placement(&wndRect, &fMaximized);
838
Paths* pPaths = m_appScope.get_paths();
839
wxString path = pPaths->GetConfigPath();
840
wxLogMessage( wxString::Format(_T("preferences: <%s>"), path.c_str()));
841
wxLogMessage( wxString::Format(_T("create_GUI: x=%d, y=%d, w=%d, h=%d"),
842
wndRect.x, wndRect.y, wndRect.width, wndRect.height));
844
m_frame = new MainFrame(m_appScope
845
, wxPoint(wndRect.x, wndRect.y) // origin
846
, wxSize(wndRect.width, wndRect.height) ); // size
848
m_frame->create_controls();
851
m_frame->Maximize(true);
854
// Create and show the splash window. The splash can have a non-rectangular
855
// shape. The color specified as second parameter of SplashFrame creation will
856
// be used as the mask color to set the shape
859
SplashFrame* pSplash = NULL;
860
// if (nMilliseconds > 0 && !fRestarting)
862
// wxBitmap bitmap = wxArtProvider::GetBitmap(_T("app_splash"), wxART_OTHER);
863
// if (bitmap.Ok() && bitmap.GetHeight() > 100)
865
// //the bitmap exists and it is not the error bitmap (height > 100 pixels). Show it
866
// wxColour colorTransparent(255, 0, 255); //cyan mask
867
// pSplash = new SplashFrame(bitmap, colorTransparent,
868
// lmSPLASH_CENTRE_ON_PARENT | lmSPLASH_TIMEOUT,
869
// nMilliseconds, m_frame, wxID_ANY, wxDefaultPosition, wxDefaultSize,
870
// wxBORDER_SIMPLE|wxSTAY_ON_TOP);
876
SetTopWindow(m_frame);
881
////---------------------------------------------------------------------------------------
882
//wxString TheApp::GetInstallerLanguage()
884
// wxString sLang = _T("");
885
// wxString sPath = g_pPaths->GetBinPath();
886
// wxFileName oFilename(sPath, _T("config_ini"), _T("txt"), wxPATH_NATIVE);
887
// wxFileInputStream inFile( oFilename.GetFullPath() );
888
// if (!inFile.Ok()) return sLang;
889
// wxTextInputStream inTextFile(inFile);
890
// sLang = inTextFile.ReadWord();
892
// //verify that the read string is one of the supported languages
894
// wxArrayString cLangCodes;
895
// wxArrayString cLangNames;
896
// GetLanguages(cLangCodes, cLangNames);
897
// nNumLangs = cLangNames.GetCount();
900
// for(i=0; i < nNumLangs; i++)
901
// if(cLangCodes[i] == sLang) return sLang;
903
// // not found. Return empty string
908
////---------------------------------------------------------------------------------------
909
//int TheApp::FilterEvent(wxEvent& event)
911
// if (event.GetEventType()==wxEVT_KEY_DOWN)
913
// if( ((wxKeyEvent&)event).GetKeyCode()==WXK_F1 && m_frame
914
// && m_frame->IsToolBoxVisible())
916
// lmController* pController = m_frame->GetActiveController();
919
// lmToolBox* pTB = m_frame->GetActiveToolBox();
922
// pTB->OnKeyPress((wxKeyEvent&)event);
923
// return true; //true: the event had been already processed
926
// return -1; //process the event normally
929
// //m_frame->OnHelpF1( (wxKeyEvent&)event );
930
// //return true; //true: the event had been already processed
931
// // //false: the event is not going to be processed at all
935
// return -1; //process the event normally
938
////---------------------------------------------------------------------------------------
939
//void TheApp::OnFatalException()
941
// //called when a crash occurs in this application
943
// // open forensic log file
944
// wxString sUserId = ::wxGetUserId();
945
// wxString sLogFile = g_pPaths->GetLogPath() + sUserId + _T("_forensic_log.txt");
946
// if (g_pLogger->IsValidForensicTarget(sLogFile))
948
// //previous program run terminated with a crash.
949
// //inform user and request permision to submit file for bug analysis
950
// SendForensicLog(sLogFile, true); //true: handling a crash
954
////---------------------------------------------------------------------------------------
955
//void TheApp::SendForensicLog(wxString& sLogFile, bool fHandlingCrash)
957
// //upload the report
959
// //wxString sURL = _T("http://localhost/forensic.php/");
960
// wxString sURL = _T("http://www.lenmus.org/forensic.php/");
961
// wxString sCurlPath = g_pPaths->GetBinPath();
962
// lmForensicLog oFLog(sLogFile, sCurlPath);
963
// oFLog.UploadLog(sURL, _T("file"), _T(""), fHandlingCrash);
964
// //AWARE: In Windows, after a crash program execution never returns to here because
965
// //the main loop to handle events was stopped in previous sentence!
970
////---------------------------------------------------------------------------------------
971
////---------------------------------------------------------------------------------------
972
//// Global functions
973
////---------------------------------------------------------------------------------------
974
////---------------------------------------------------------------------------------------
977
//MainFrame* GetMainFrame(void)