summaryrefslogtreecommitdiff
path: root/muse2/muse/app.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/app.cpp')
-rw-r--r--muse2/muse/app.cpp306
1 files changed, 238 insertions, 68 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index bd6bc560..148f3072 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -4,6 +4,7 @@
// $Id: app.cpp,v 1.113.2.68 2009/12/21 14:51:51 spamatica Exp $
//
// (C) Copyright 1999-2011 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Tim E. Real (terminator356 on sourceforge)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@ -33,6 +34,8 @@
#include <QProgressDialog>
#include <QMdiArea>
#include <QMdiSubWindow>
+#include <QSocketNotifier>
+#include <QString>
#include <iostream>
@@ -55,6 +58,7 @@
#include "filedialog.h"
#include "gconfig.h"
#include "gui.h"
+#include "helper.h"
#include "icons.h"
#include "instruments/editinstrument.h"
#include "listedit.h"
@@ -84,8 +88,11 @@ extern void exitJackAudio();
extern void exitDummyAudio();
extern void exitOSC();
extern void exitMidiAlsa();
-}
+extern void initMidiSequencer();
+extern void initAudio();
+extern void initAudioPrefetch();
+}
namespace MusEGui {
@@ -94,12 +101,12 @@ namespace MusEGui {
static pthread_t watchdogThread;
//ErrorHandler *error;
-
#define PROJECT_LIST_LEN 6
static QString* projectList[PROJECT_LIST_LEN];
#ifdef HAVE_LASH
#include <lash/lash.h>
+#include <lo/lo_osc_types.h>
lash_client_t * lash_client = 0;
extern snd_seq_t * alsaSeq;
#endif /* HAVE_LASH */
@@ -171,14 +178,7 @@ bool MusE::seqStart()
if(MusEGlobal::realTimeScheduling)
{
{
- //pfprio = MusEGlobal::realTimePriority - 5;
- // p3.3.40
pfprio = MusEGlobal::realTimePriority + 1;
-
- //midiprio = MusEGlobal::realTimePriority - 2;
- // p3.3.37
- //midiprio = MusEGlobal::realTimePriority + 1;
- // p3.3.40
midiprio = MusEGlobal::realTimePriority + 2;
}
}
@@ -198,9 +198,6 @@ bool MusE::seqStart()
MusEGlobal::audioPrefetch->msgSeek(0, true); // force
- //MusEGlobal::midiSeqRunning = !midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0);
- // Changed by Tim. p3.3.22
- //MusEGlobal::midiSeq->start(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0);
MusEGlobal::midiSeq->start(midiprio);
int counter=0;
@@ -224,7 +221,7 @@ bool MusE::seqStart()
}
return true;
}
-
+
//---------------------------------------------------------
// stop
//---------------------------------------------------------
@@ -258,6 +255,7 @@ bool MusE::seqRestart()
}
seqStop();
}
+
if(!seqStart())
return false;
@@ -299,7 +297,7 @@ void addProject(const QString& name)
//---------------------------------------------------------
//MusE::MusE(int argc, char** argv) : QMainWindow(0, "mainwindow")
-MusE::MusE(int argc, char** argv) : QMainWindow()
+MusE::MusE(int /*argc*/, char** /*argv*/) : QMainWindow()
{
// By T356. For LADSPA plugins in plugin.cpp
// QWidgetFactory::addWidgetFactory( new PluginWidgetFactory ); ddskrjo
@@ -333,6 +331,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
progress = 0;
activeTopWin = NULL;
currentMenuSharingTopwin = NULL;
+ waitingForTopwin = NULL;
appName = QString("MusE");
setWindowTitle(appName);
@@ -346,8 +345,6 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::heartBeatTimer = new QTimer(this);
MusEGlobal::heartBeatTimer->setObjectName("timer");
connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), MusEGlobal::song, SLOT(beat()));
-
-
connect(this, SIGNAL(activeTopWinChanged(MusEGui::TopWin*)), SLOT(activeTopWinChangedSlot(MusEGui::TopWin*)));
#ifdef ENABLE_PYTHON
@@ -460,7 +457,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::panicAction->setWhatsThis(tr("send note off to all midi channels"));
connect(MusEGlobal::panicAction, SIGNAL(activated()), MusEGlobal::song, SLOT(panic()));
- MusECore::initMidiInstruments();
+ MusECore::initMidiInstruments();
MusECore::initMidiPorts();
MusECore::initMidiDevices();
@@ -706,7 +703,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
//rlimit lim;
//getrlimit(RLIMIT_RTPRIO, &lim);
//printf("RLIMIT_RTPRIO soft:%d hard:%d\n", lim.rlim_cur, lim.rlim_max); // Reported 80, 80 even with non-RT kernel.
-
+
if (MusEGlobal::realTimePriority < sched_get_priority_min(SCHED_FIFO))
MusEGlobal::realTimePriority = sched_get_priority_min(SCHED_FIFO);
else if (MusEGlobal::realTimePriority > sched_get_priority_max(SCHED_FIFO))
@@ -721,18 +718,19 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
MusEGlobal::midiRTPrioOverride = sched_get_priority_max(SCHED_FIFO);
}
- // Changed by Tim. p3.3.17
- //MusEGlobal::midiSeq = new MusECore::MidiSeq(MusEGlobal::realTimeScheduling ? MusEGlobal::realTimePriority : 0, "Midi");
- MusEGlobal::midiSeq = new MusECore::MidiSeq("Midi");
- MusEGlobal::audio = new MusECore::Audio();
- //MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch(0, "Disc");
- MusEGlobal::audioPrefetch = new MusECore::AudioPrefetch("Prefetch");
-
+ MusECore::initMidiSequencer();
+ MusECore::initAudio();
+
+ // Moved here from Audio::Audio
+ QSocketNotifier* ss = new QSocketNotifier(MusEGlobal::audio->getFromThreadFdr(), QSocketNotifier::Read, this);
+ connect(ss, SIGNAL(activated(int)), MusEGlobal::song, SLOT(seqSignal(int)));
+
+ MusECore::initAudioPrefetch();
+
//---------------------------------------------------
// Popups
//---------------------------------------------------
-
// when adding a menu to the main window, remember adding it to
// either the leadingMenus or trailingMenus list!
// also do NOT use menuBar()->addMenu(QString&), but ALWAYS
@@ -961,6 +959,11 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
transport = new MusEGui::Transport(this, "transport");
bigtime = 0;
+ MusEGlobal::song->blockSignals(false);
+
+ // Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+ /*
+
//---------------------------------------------------
// load project
// if no songname entered on command line:
@@ -975,7 +978,8 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
name = argv[0];
else if (MusEGlobal::config.startMode == 0) {
if (argc < 2)
- name = projectList[0] ? *projectList[0] : QString("untitled");
+ //name = projectList[0] ? *projectList[0] : QString("untitled");
+ name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40
else
name = argv[0];
printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
@@ -989,19 +993,47 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
name = MusEGlobal::config.startSong;
}
- MusEGlobal::song->blockSignals(false);
- loadProjectFile(name, useTemplate, true);
-
+
+ // loadProjectFile(name, useTemplate, true); //commented out by flo: see below (*)
+ */
+
changeConfig(false);
QSettings settings("MusE", "MusE-qt");
restoreGeometry(settings.value("MusE/geometry").toByteArray());
//restoreState(settings.value("MusE/windowState").toByteArray());
- MusEGlobal::song->update();
-
- updateWindowMenu();
+ MusEGlobal::song->update(); // commented out by flo: will be done by the below (*)
+ updateWindowMenu(); // same here
+
+ // Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+ /*
+
+ // this is (*).
+ // this is a really hackish workaround for the loading-on-startup problem.
+ // i have absolutely no idea WHY it breaks when using loadProjectFile()
+ // above, but it does on my machine (it doesn't on others!).
+ // the problem can be worked around by delaying loading the song file.
+ // i use hackishSongOpenTimer for this, which calls after 10ms a slot
+ // which then does the actual loadProjectFile() call.
+ // FIXME: please, if anyone finds the real problem, FIX it and
+ // remove that dirty, dirty workaround!
+ hackishSongOpenFilename=name;
+ hackishSongOpenUseTemplate=useTemplate;
+ hackishSongOpenTimer=new QTimer(this);
+ hackishSongOpenTimer->setInterval(10);
+ hackishSongOpenTimer->setSingleShot(true);
+ connect(hackishSongOpenTimer, SIGNAL(timeout()), this, SLOT(hackishSongOpenTimerTimeout()));
+ hackishSongOpenTimer->start();
+ */
}
+// Load start song moved to main.cpp p4.0.41 REMOVE Tim.
+//void MusE::hackishSongOpenTimerTimeout()
+//{
+ ///loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, true);
+ //loadProjectFile(hackishSongOpenFilename, hackishSongOpenUseTemplate, !hackishSongOpenUseTemplate);
+//}
+
MusE::~MusE()
{
}
@@ -1015,6 +1047,44 @@ void MusE::setHeartBeat()
MusEGlobal::heartBeatTimer->start(1000/MusEGlobal::config.guiRefresh);
}
+//---------------------------------------------------
+// loadDefaultSong
+// if no songname entered on command line:
+// startMode: 0 - load last song
+// 1 - load default template
+// 2 - load configured start song
+//---------------------------------------------------
+
+void MusE::loadDefaultSong(int argc, char** argv)
+{
+ QString name;
+ bool useTemplate = false;
+ if (argc >= 2)
+ name = argv[0];
+ else if (MusEGlobal::config.startMode == 0) {
+ if (argc < 2)
+ //name = projectList[0] ? *projectList[0] : QString("untitled");
+ name = projectList[0] ? *projectList[0] : MusEGui::getUniqueUntitledName(); // p4.0.40
+ else
+ name = argv[0];
+ printf("starting with selected song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
+ }
+ else if (MusEGlobal::config.startMode == 1) {
+ printf("starting with default template\n");
+ name = MusEGlobal::museGlobalShare + QString("/templates/default.med");
+ useTemplate = true;
+ }
+ else if (MusEGlobal::config.startMode == 2) {
+ printf("starting with pre configured song %s\n", MusEGlobal::config.startSong.toLatin1().constData());
+ name = MusEGlobal::config.startSong;
+ }
+ //loadProjectFile(name, useTemplate, true);
+ loadProjectFile(name, useTemplate, !useTemplate);
+
+ //MusEGlobal::song->update();
+ //updateWindowMenu();
+}
+
//---------------------------------------------------------
// resetDevices
//---------------------------------------------------------
@@ -1156,7 +1226,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
QApplication::restoreOverrideCursor();
return;
}
- project.setFile("untitled");
+ //project.setFile("untitled");
+ project.setFile(MusEGui::getUniqueUntitledName()); // p4.0.40
MusEGlobal::museProject = MusEGlobal::museProjectInitPath;
}
else {
@@ -1214,7 +1285,8 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
}
if (!songTemplate) {
addProject(project.absoluteFilePath());
- setWindowTitle(QString("MusE: Song: ") + project.completeBaseName());
+ //setWindowTitle(QString("MusE: Song: ") + project.completeBaseName());
+ setWindowTitle(QString("MusE: Song: ") + MusEGui::projectTitleFromFilename(project.absoluteFilePath()));
}
MusEGlobal::song->dirty = false;
progress->setValue(30);
@@ -1236,7 +1308,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
// set the geometry if the mixer has already been created.
if(mixer1)
{
- //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // p3.3.53 Moved below
+ //if(mixer1->geometry().size() != MusEGlobal::config.mixer1.geometry.size()) // Moved below
// mixer1->resize(MusEGlobal::config.mixer1.geometry.size());
if(mixer1->geometry().topLeft() != MusEGlobal::config.mixer1.geometry.topLeft())
@@ -1244,7 +1316,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
}
if(mixer2)
{
- //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // p3.3.53 Moved below
+ //if(mixer2->geometry().size() != MusEGlobal::config.mixer2.geometry.size()) // Moved below
// mixer2->resize(MusEGlobal::config.mixer2.geometry.size());
if(mixer2->geometry().topLeft() != MusEGlobal::config.mixer2.geometry.topLeft())
@@ -1273,7 +1345,7 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
arrangerView->scoreNamingChanged(); // inform the score menus about the new scores and their names
progress->setValue(50);
- // p3.3.53 Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now.
+ // Try this AFTER the song update above which does a mixer update... Tested OK - mixers resize properly now.
if (loadAll)
{
if(mixer1)
@@ -1336,10 +1408,13 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll
void MusE::setUntitledProject()
{
setConfigDefaults();
- QString name("untitled");
+ //QString name("untitled");
+ QString name(MusEGui::getUniqueUntitledName()); // p4.0.40
+
MusEGlobal::museProject = "./"; //QFileInfo(name).absolutePath();
project.setFile(name);
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name)));
}
//---------------------------------------------------------
@@ -1391,14 +1466,14 @@ void MusE::loadTemplate()
if (!fn.isEmpty()) {
// MusEGlobal::museProject = QFileInfo(fn).absolutePath();
- loadProjectFile(fn, true, true);
+ //loadProjectFile(fn, true, true);
// With templates, don't clear midi ports.
// Any named ports in the template file are useless since they likely
// would not be found on other users' machines.
// So keep whatever the user currently has set up for ports.
// Note that this will also keep the current window configurations etc.
// but actually that's also probably a good thing. p4.0.17 Tim. TESTING: Maybe some problems...
- //loadProjectFile(fn, true, false);
+ loadProjectFile(fn, true, false);
setUntitledProject();
}
@@ -1410,7 +1485,11 @@ void MusE::loadTemplate()
bool MusE::save()
{
- if (project.completeBaseName() == "untitled")
+ //if (project.completeBaseName() == "untitled") // p4.0.40 Must catch "untitled 1" "untitled 2" etc
+ //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == "untitled")
+ //if (MusEGui::projectTitleFromFilename(project.absoluteFilePath()) == MusEGui::getUniqueUntitledName())
+ ///if (project.absoluteFilePath() == MusEGui::getUniqueUntitledName())
+ if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath )
return saveAs();
else
return save(project.filePath(), false);
@@ -1542,7 +1621,7 @@ void MusE::closeEvent(QCloseEvent* event)
MusECore::exitMetronome();
// Make sure to delete the menu. ~routingPopupMenu() will NOT be called automatically.
- // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus. p4.0.26
+ // Even though it is a child of MusE, it just passes MusE onto the underlying PopupMenus.
if(routingPopupMenu)
delete routingPopupMenu;
#if 0
@@ -1572,7 +1651,7 @@ void MusE::closeEvent(QCloseEvent* event)
}
#ifdef HAVE_LASH
- // Disconnect gracefully from LASH. Tim. p3.3.14
+ // Disconnect gracefully from LASH.
if(lash_client)
{
if(MusEGlobal::debugMsg)
@@ -1590,7 +1669,6 @@ void MusE::closeEvent(QCloseEvent* event)
printf("MusE: Exiting OSC\n");
MusECore::exitOSC();
- // p3.3.47
delete MusEGlobal::audioPrefetch;
delete MusEGlobal::audio;
delete MusEGlobal::midiSeq;
@@ -1619,8 +1697,8 @@ void MusE::showMarker(bool flag)
markerView = new MusEGui::MarkerView(this);
connect(markerView, SIGNAL(closed()), SLOT(markerClosed()));
- toplevels.push_back(markerView);
markerView->show();
+ toplevels.push_back(markerView);
}
markerView->setVisible(flag);
viewMarkerAction->setChecked(flag);
@@ -1642,6 +1720,20 @@ void MusE::markerClosed()
setCurrentMenuSharingTopwin(NULL);
updateWindowMenu();
+
+ // focus the last activated topwin which is not the marker view
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != markerView)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
+
}
//---------------------------------------------------------
@@ -1675,6 +1767,20 @@ void MusE::arrangerClosed()
{
viewArrangerAction->setChecked(false);
updateWindowMenu();
+
+ // focus the last activated topwin which is not the arranger view
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != arrangerView)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed arranger window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
+
}
//---------------------------------------------------------
@@ -1716,7 +1822,7 @@ MusEGui::RoutePopupMenu* MusE::getRoutingPopupMenu()
bool MusE::saveAs()
{
QString name;
- if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) {
+ //if (MusEGlobal::museProject == MusEGlobal::museProjectInitPath ) // Use project dialog always now.
if (MusEGlobal::config.useProjectSaveDialog) {
MusEGui::ProjectCreateImpl pci(MusEGlobal::muse);
if (pci.exec() == QDialog::Rejected) {
@@ -1737,10 +1843,11 @@ bool MusE::saveAs()
QMessageBox::warning(this,"Path error","Can't create project path", QMessageBox::Ok);
return false;
}
- }
- else {
- name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As"));
- }
+ //}
+ //else {
+ // name = MusEGui::getSaveFileName(QString(""), MusEGlobal::med_file_save_pattern, this, tr("MusE: Save As"));
+ //}
+
bool ok = false;
if (!name.isEmpty()) {
QString tempOldProj = MusEGlobal::museProject;
@@ -1748,7 +1855,8 @@ bool MusE::saveAs()
ok = save(name, true);
if (ok) {
project.setFile(name);
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(name)));
addProject(name);
}
else
@@ -1830,8 +1938,8 @@ void MusE::openInScoreEdit(MusEGui::ScoreEdit* destination, MusECore::PartList*
if (destination==NULL) // if no destination given, create a new one
{
destination = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue());
- destination->show();
toplevels.push_back(destination);
+ destination->show();
connect(destination, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(destination, SIGNAL(name_changed()), arrangerView, SLOT(scoreNamingChanged()));
//connect(muse, SIGNAL(configChanged()), destination, SLOT(config_changed()));
@@ -1866,10 +1974,10 @@ void MusE::startPianoroll(MusECore::PartList* pl, bool showDefaultCtrls)
{
MusEGui::PianoRoll* pianoroll = new MusEGui::PianoRoll(pl, this, 0, _arranger->cursorValue());
- if(showDefaultCtrls) // p4.0.12
+ if(showDefaultCtrls)
pianoroll->addCtrl();
- pianoroll->show();
toplevels.push_back(pianoroll);
+ pianoroll->show();
connect(pianoroll, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
updateWindowMenu();
@@ -1890,8 +1998,8 @@ void MusE::startListEditor()
void MusE::startListEditor(MusECore::PartList* pl)
{
MusEGui::ListEdit* listEditor = new MusEGui::ListEdit(pl);
- listEditor->show();
toplevels.push_back(listEditor);
+ listEditor->show();
connect(listEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse,SIGNAL(configChanged()), listEditor, SLOT(configChanged()));
updateWindowMenu();
@@ -1904,8 +2012,8 @@ void MusE::startListEditor(MusECore::PartList* pl)
void MusE::startMasterEditor()
{
MusEGui::MasterEdit* masterEditor = new MusEGui::MasterEdit();
- masterEditor->show();
toplevels.push_back(masterEditor);
+ masterEditor->show();
connect(masterEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -1917,8 +2025,8 @@ void MusE::startMasterEditor()
void MusE::startLMasterEditor()
{
MusEGui::LMaster* lmaster = new MusEGui::LMaster();
- lmaster->show();
toplevels.push_back(lmaster);
+ lmaster->show();
connect(lmaster, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), lmaster, SLOT(configChanged()));
updateWindowMenu();
@@ -1939,10 +2047,10 @@ void MusE::startDrumEditor()
void MusE::startDrumEditor(MusECore::PartList* pl, bool showDefaultCtrls)
{
MusEGui::DrumEdit* drumEditor = new MusEGui::DrumEdit(pl, this, 0, _arranger->cursorValue());
- if(showDefaultCtrls) // p4.0.12
+ if(showDefaultCtrls)
drumEditor->addCtrl();
- drumEditor->show();
toplevels.push_back(drumEditor);
+ drumEditor->show();
connect(drumEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
updateWindowMenu();
@@ -1966,8 +2074,8 @@ void MusE::startWaveEditor(MusECore::PartList* pl)
{
MusEGui::WaveEdit* waveEditor = new MusEGui::WaveEdit(pl);
waveEditor->show();
- connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
toplevels.push_back(waveEditor);
+ connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
connect(waveEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -2088,6 +2196,19 @@ void MusE::toplevelDeleting(MusEGui::TopWin* tl)
{
activeTopWin=NULL;
emit activeTopWinChanged(NULL);
+
+ // focus the last activated topwin which is not the deleting one
+ QList<QMdiSubWindow*> l = mdiArea->subWindowList(QMdiArea::StackingOrder);
+ for (QList<QMdiSubWindow*>::iterator lit=l.begin(); lit!=l.end(); lit++)
+ if ((*lit)->isVisible() && (*lit)->widget() != tl)
+ {
+ if (MusEGlobal::debugMsg)
+ printf("bringing '%s' to front instead of closed window\n",(*lit)->widget()->windowTitle().toAscii().data());
+
+ bringToFront((*lit)->widget());
+
+ break;
+ }
}
if (tl == currentMenuSharingTopwin)
@@ -2168,7 +2289,7 @@ void MusE::kbAccel(int key)
MusEGlobal::song->setPlay(true);
}
- // p4.0.10 Tim. Normally each editor window handles these, to inc by the editor's raster snap value.
+ // Normally each editor window handles these, to inc by the editor's raster snap value.
// But users were asking for a global version - "they don't work when I'm in mixer or transport".
// Since no editor claimed the key event, we don't know a specific editor's snap setting,
// so adopt a policy where the arranger is the 'main' raster reference, I guess...
@@ -2649,7 +2770,8 @@ MusE::lash_idle_cb ()
int ok = save (ss.toAscii(), false);
if (ok) {
project.setFile(ss.toAscii());
- setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ //setWindowTitle(tr("MusE: Song: %1").arg(project.completeBaseName()));
+ setWindowTitle(tr("MusE: Song: %1").arg(MusEGui::projectTitleFromFilename(project.absoluteFilePath())));
addProject(ss.toAscii());
MusEGlobal::museProject = QFileInfo(ss.toAscii()).absolutePath();
}
@@ -3071,21 +3193,32 @@ void MusE::focusChanged(QWidget*, QWidget* now)
if (currentMenuSharingTopwin && (currentMenuSharingTopwin!=activeTopWin))
currentMenuSharingTopwin->storeInitialState();
-
+ // if the activated widget is a QMdiSubWindow containing some TopWin
+ if ( (dynamic_cast<QMdiSubWindow*>(ptr)!=0) &&
+ (dynamic_cast<MusEGui::TopWin*>( ((QMdiSubWindow*)ptr)->widget() )!=0) )
+ {
+ waitingForTopwin=(MusEGui::TopWin*) ((QMdiSubWindow*)ptr)->widget();
+ return;
+ }
while (ptr)
{
+ if (MusEGlobal::heavyDebugMsg)
+ printf("focusChanged: at widget %p with type %s\n",ptr, typeid(*ptr).name());
+
if ( (dynamic_cast<MusEGui::TopWin*>(ptr)!=0) || // *ptr is a TopWin or a derived class
(ptr==this) ) // the main window is selected
break;
ptr=dynamic_cast<QWidget*>(ptr->parent()); //in the unlikely case that ptr is a QObject, this returns NULL, which stops the loop
}
+ MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(ptr);
// ptr is either NULL, this or the pointer to a TopWin
- if (ptr!=this) // if the main win is selected, don't treat that as "none", but also don't handle it
+
+ // if the main win or some deleting topwin is selected,
+ // don't treat that as "none", but also don't handle it
+ if (ptr!=this && (!win || !win->deleting()) )
{
- MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(ptr);
-
// now 'win' is either NULL or the pointer to the active TopWin
if (win!=activeTopWin)
{
@@ -3233,6 +3366,26 @@ void MusE::shareMenuAndToolbarChanged(MusEGui::TopWin* win, bool val)
}
}
+void MusE::topwinMenuInited(MusEGui::TopWin* topwin)
+{
+ if (topwin==NULL)
+ return;
+
+ if (topwin == waitingForTopwin)
+ {
+ if (waitingForTopwin->deleting())
+ {
+ waitingForTopwin=NULL;
+ }
+ else
+ {
+ activeTopWin=waitingForTopwin;
+ waitingForTopwin=NULL;
+ emit activeTopWinChanged(activeTopWin);
+ }
+ }
+}
+
void MusE::updateWindowMenu()
{
bool sep;
@@ -3286,6 +3439,8 @@ void MusE::updateWindowMenu()
void MusE::bringToFront(QWidget* widget)
{
MusEGui::TopWin* win=dynamic_cast<MusEGui::TopWin*>(widget);
+ if (!win) return;
+
if (win->isMdiWin())
{
win->show();
@@ -3449,4 +3604,19 @@ void MusE::tileSubWindows()
}
}
+QString MusE::projectTitle() const
+{
+ return MusEGui::projectTitleFromFilename(project.fileName());
+}
+
+QString MusE::projectPath() const
+{
+ return MusEGui::projectPathFromFilename(project.absoluteFilePath());
+}
+
+QString MusE::projectExtension() const
+{
+ return MusEGui::projectExtensionFromFilename(project.fileName());
+}
+
} //namespace MusEGui