summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2011-10-16 21:35:39 +0000
committerTim E. Real <termtech@rogers.com>2011-10-16 21:35:39 +0000
commita65f03f8cefc3e1d2e6b71ace15789fc63795275 (patch)
tree7d7138e88f4dbd6c1dba3a67618dccf37973888c
parentb071fa342f72770346e36b3564c9c225d9af791f (diff)
Fixed crashes reloading songs having open editors. Previous memleak fixes
revealed some problems. Installed bool TopWin::deleting(). It is set true when closeEvent() is called in any self-deleting TopWins. Used it to make all such TopWins and their corresponding child canvasses ignore songChanged signals.
-rw-r--r--muse2/ChangeLog5
-rw-r--r--muse2/muse/app.cpp41
-rw-r--r--muse2/muse/app.h2
-rw-r--r--muse2/muse/cliplist/cliplist.cpp2
-rw-r--r--muse2/muse/cliplist/cliplist.h2
-rw-r--r--muse2/muse/cobject.cpp1
-rw-r--r--muse2/muse/cobject.h10
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp3
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.h2
-rw-r--r--muse2/muse/ctrl/ctrlpanel.cpp3
-rw-r--r--muse2/muse/liste/listedit.cpp6
-rw-r--r--muse2/muse/liste/listedit.h2
-rw-r--r--muse2/muse/master/lmaster.cpp7
-rw-r--r--muse2/muse/master/lmaster.h2
-rw-r--r--muse2/muse/master/masteredit.cpp7
-rw-r--r--muse2/muse/master/masteredit.h2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp7
-rw-r--r--muse2/muse/midiedit/drumedit.h2
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp8
-rw-r--r--muse2/muse/midiedit/pianoroll.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp10
-rw-r--r--muse2/muse/midiedit/scoreedit.h2
-rw-r--r--muse2/muse/songfile.cpp2
-rw-r--r--muse2/muse/waveedit/waveedit.cpp8
-rw-r--r--muse2/muse/waveedit/waveedit.h2
25 files changed, 100 insertions, 40 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index d601817e..26bb1f1e 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,8 @@
+16.10.2011:
+ - Fixed crashes reloading songs having open editors. Previous memleak fixes revealed some problems. (Tim)
+ Installed bool TopWin::deleting(). It is set true when closeEvent() is called in any self-deleting TopWins.
+ Used it to make all such TopWins and their corresponding child canvasses ignore songChanged signals.
+ Test OK so far, multiple reloads of song with all track types, all windows open.
14.10.2011:
- Fixed keyboard navigation in tracks to work with hidden tracks (rj)
12.10.2011:
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 677743b3..50a766dc 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -1844,7 +1844,7 @@ void MusE::openInScoreEdit(MusEGui::ScoreEdit* destination, MusECore::PartList*
destination = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue());
destination->show();
toplevels.push_back(destination);
- connect(destination, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ 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()));
//commented out by flo, because the ScoreEditor connects to all
@@ -1882,7 +1882,7 @@ void MusE::startPianoroll(MusECore::PartList* pl, bool showDefaultCtrls)
pianoroll->addCtrl();
pianoroll->show();
toplevels.push_back(pianoroll);
- connect(pianoroll, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(pianoroll, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), pianoroll, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1904,7 +1904,7 @@ void MusE::startListEditor(MusECore::PartList* pl)
MusEGui::ListEdit* listEditor = new MusEGui::ListEdit(pl);
listEditor->show();
toplevels.push_back(listEditor);
- connect(listEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(listEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse,SIGNAL(configChanged()), listEditor, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1918,7 +1918,7 @@ void MusE::startMasterEditor()
MusEGui::MasterEdit* masterEditor = new MusEGui::MasterEdit();
masterEditor->show();
toplevels.push_back(masterEditor);
- connect(masterEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(masterEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -1931,7 +1931,7 @@ void MusE::startLMasterEditor()
MusEGui::LMaster* lmaster = new MusEGui::LMaster();
lmaster->show();
toplevels.push_back(lmaster);
- connect(lmaster, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(lmaster, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), lmaster, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1955,7 +1955,7 @@ void MusE::startDrumEditor(MusECore::PartList* pl, bool showDefaultCtrls)
drumEditor->addCtrl();
drumEditor->show();
toplevels.push_back(drumEditor);
- connect(drumEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(drumEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(MusEGlobal::muse, SIGNAL(configChanged()), drumEditor, SLOT(configChanged()));
updateWindowMenu();
}
@@ -1980,7 +1980,7 @@ void MusE::startWaveEditor(MusECore::PartList* pl)
waveEditor->show();
connect(MusEGlobal::muse, SIGNAL(configChanged()), waveEditor, SLOT(configChanged()));
toplevels.push_back(waveEditor);
- connect(waveEditor, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(waveEditor, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
updateWindowMenu();
}
@@ -2038,7 +2038,7 @@ void MusE::startClipList(bool checked)
//clipListEdit = new ClipListEdit();
clipListEdit = new MusEGui::ClipListEdit(this);
toplevels.push_back(clipListEdit);
- connect(clipListEdit, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(clipListEdit, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
}
clipListEdit->show();
viewCliplistAction->setChecked(checked);
@@ -2084,10 +2084,10 @@ void MusE::selectProject(QAction* act)
}
//---------------------------------------------------------
-// toplevelDeleted
+// toplevelDeleting
//---------------------------------------------------------
-void MusE::toplevelDeleted(MusEGui::TopWin* tl)
+void MusE::toplevelDeleting(MusEGui::TopWin* tl)
{
for (MusEGui::iToplevel i = toplevels.begin(); i != toplevels.end(); ++i) {
if (*i == tl) {
@@ -2132,19 +2132,17 @@ void MusE::toplevelDeleted(MusEGui::TopWin* tl)
case MusEGui::TopWin::TOPLEVELTYPE_LAST_ENTRY: //to avoid a warning
break;
}
- toplevels.erase(i);
+ toplevels.erase(i);
if (mustUpdateScoreMenus)
arrangerView->updateScoreMenus();
updateWindowMenu();
return;
}
}
- printf("topLevelDeleted: top level %p not found\n", tl);
+ printf("topLevelDeleting: top level %p not found\n", tl);
//assert(false);
}
-
-
//---------------------------------------------------------
// kbAccel
//---------------------------------------------------------
@@ -2750,16 +2748,21 @@ again:
case MusEGui::TopWin::MASTER:
case MusEGui::TopWin::WAVE:
case MusEGui::TopWin::LMASTER:
- tl->close();
- goto again;
-
+ {
+ if(tl->isVisible()) // Don't keep trying to close, only if visible.
+ {
+ if(!tl->close())
+ printf("MusE::clearSong TopWin did not close!\n");
+ goto again;
+ }
+ }
case MusEGui::TopWin::TOPLEVELTYPE_LAST_ENTRY: //to avoid a warning
break;
}
}
- microSleep(100000);
+ microSleep(100000);
MusEGlobal::song->clear(true, clear_all);
- microSleep(100000);
+ microSleep(100000);
return false;
}
diff --git a/muse2/muse/app.h b/muse2/muse/app.h
index 46e9f99b..27722e9a 100644
--- a/muse2/muse/app.h
+++ b/muse2/muse/app.h
@@ -333,7 +333,7 @@ class MusE : public QMainWindow
void closeEvent(QCloseEvent*e);
void loadProjectFile(const QString&);
void loadProjectFile(const QString&, bool songTemplate, bool loadAll);
- void toplevelDeleted(MusEGui::TopWin* tl);
+ void toplevelDeleting(MusEGui::TopWin* tl);
void loadTheme(const QString&);
void loadStyleSheetFile(const QString&);
bool seqRestart();
diff --git a/muse2/muse/cliplist/cliplist.cpp b/muse2/muse/cliplist/cliplist.cpp
index a4702137..1055f449 100644
--- a/muse2/muse/cliplist/cliplist.cpp
+++ b/muse2/muse/cliplist/cliplist.cpp
@@ -194,7 +194,7 @@ void ClipListEdit::updateList()
void ClipListEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
diff --git a/muse2/muse/cliplist/cliplist.h b/muse2/muse/cliplist/cliplist.h
index b490663c..0972df97 100644
--- a/muse2/muse/cliplist/cliplist.h
+++ b/muse2/muse/cliplist/cliplist.h
@@ -73,7 +73,7 @@ class ClipListEdit : public TopWin {
void clicked(QTreeWidgetItem*, int);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
ClipListEdit(QWidget* parent);
diff --git a/muse2/muse/cobject.cpp b/muse2/muse/cobject.cpp
index b4c6537c..92748268 100644
--- a/muse2/muse/cobject.cpp
+++ b/muse2/muse/cobject.cpp
@@ -50,6 +50,7 @@ bool TopWin::initInited=false;
TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlags f)
: QMainWindow(parent, f)
{
+ _isDeleting = false;
if (initInited==false)
initConfiguration();
diff --git a/muse2/muse/cobject.h b/muse2/muse/cobject.h
index c1c45039..309d8424 100644
--- a/muse2/muse/cobject.h
+++ b/muse2/muse/cobject.h
@@ -62,7 +62,8 @@ class TopWin : public QMainWindow
ToplevelType type() const { return _type; }
static QString typeName(ToplevelType t);
-
+ bool deleting() const { return _isDeleting; }
+
virtual void readStatus(MusECore::Xml&);
virtual void writeStatus(int, MusECore::Xml&) const;
@@ -118,6 +119,11 @@ class TopWin : public QMainWindow
QByteArray _savedToolbarState;
+ // Set if close has been called on a TopWin having the WA_DeleteOnClose attribute.
+ // The TopWins and any children should ignore any signals such as songChanged
+ // which may cause a crash while deleting.
+ bool _isDeleting;
+
void initTopwinState();
private slots:
@@ -131,7 +137,7 @@ class TopWin : public QMainWindow
void shareToolsAndMenu(bool);
void restoreMainwinState();
void storeInitialState() const;
-
+
};
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp
index 486e279a..1a155fc4 100644
--- a/muse2/muse/ctrl/ctrlcanvas.cpp
+++ b/muse2/muse/ctrl/ctrlcanvas.cpp
@@ -468,6 +468,9 @@ void CtrlCanvas::configChanged()
void CtrlCanvas::songChanged(int type)
{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
//printf("CtrlCanvas::songChanged type:%x\n", type);
// Is it simply a midi controller value adjustment? Forget it.
if(type == SC_MIDI_CONTROLLER)
diff --git a/muse2/muse/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h
index 815898ac..f9fcb54f 100644
--- a/muse2/muse/ctrl/ctrlcanvas.h
+++ b/muse2/muse/ctrl/ctrlcanvas.h
@@ -176,6 +176,8 @@ class CtrlCanvas : public MusEGui::View {
void updateItems();
void updateSelections();
+ //virtual void closeEvent(QCloseEvent*);
+
private slots:
void songChanged(int type);
void configChanged();
diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp
index 0d981fbd..1889c608 100644
--- a/muse2/muse/ctrl/ctrlpanel.cpp
+++ b/muse2/muse/ctrl/ctrlpanel.cpp
@@ -161,6 +161,9 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, const char* name)
void CtrlPanel::heartBeat()
{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
inHeartBeat = true;
if(_track && _ctrl && _dnum != -1)
diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp
index eadfa68c..e4837bf9 100644
--- a/muse2/muse/liste/listedit.cpp
+++ b/muse2/muse/liste/listedit.cpp
@@ -183,7 +183,8 @@ static QString midiMetaComment(const MusECore::Event& ev)
void ListEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -193,6 +194,9 @@ void ListEdit::closeEvent(QCloseEvent* e)
void ListEdit::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type == 0)
return;
if (type & (SC_PART_REMOVED | SC_PART_MODIFIED
diff --git a/muse2/muse/liste/listedit.h b/muse2/muse/liste/listedit.h
index 7548fc86..1c0c1bd9 100644
--- a/muse2/muse/liste/listedit.h
+++ b/muse2/muse/liste/listedit.h
@@ -86,7 +86,7 @@ class ListEdit : public MidiEditor {
void songChanged(int);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
ListEdit(MusECore::PartList*);
diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp
index bf31cc91..52b488d0 100644
--- a/muse2/muse/master/lmaster.cpp
+++ b/muse2/muse/master/lmaster.cpp
@@ -122,7 +122,9 @@ namespace MusEGui {
void LMaster::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -132,6 +134,9 @@ void LMaster::closeEvent(QCloseEvent* e)
void LMaster::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type & (SC_SIG | SC_TEMPO | SC_KEY ))
updateList();
}
diff --git a/muse2/muse/master/lmaster.h b/muse2/muse/master/lmaster.h
index 6bc90019..33b40f30 100644
--- a/muse2/muse/master/lmaster.h
+++ b/muse2/muse/master/lmaster.h
@@ -173,7 +173,7 @@ class LMaster : public MidiEditor {
void configChanged();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void seekTo(int tick);
public:
diff --git a/muse2/muse/master/masteredit.cpp b/muse2/muse/master/masteredit.cpp
index e9d669e1..c3c66008 100644
--- a/muse2/muse/master/masteredit.cpp
+++ b/muse2/muse/master/masteredit.cpp
@@ -59,7 +59,9 @@ int MasterEdit::_rasterInit = 0;
void MasterEdit::closeEvent(QCloseEvent* e)
{
- emit deleted(static_cast<TopWin*>(this));
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -69,6 +71,9 @@ void MasterEdit::closeEvent(QCloseEvent* e)
void MasterEdit::songChanged(int type)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (type & SC_TEMPO) {
int tempo = MusEGlobal::tempomap.tempo(MusEGlobal::song->cpos());
curTempo->blockSignals(true);
diff --git a/muse2/muse/master/masteredit.h b/muse2/muse/master/masteredit.h
index fdf8dd71..835ca879 100644
--- a/muse2/muse/master/masteredit.h
+++ b/muse2/muse/master/masteredit.h
@@ -91,7 +91,7 @@ class MasterEdit : public MidiEditor {
// void tempoChanged(double);
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
MasterEdit();
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 03580142..19700a4e 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -152,6 +152,8 @@ void DrumEdit::setHeaderToolTips()
void DrumEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Drumedit/geometry", saveGeometry());
settings.setValue("Drumedit/windowState", saveState());
@@ -162,7 +164,7 @@ void DrumEdit::closeEvent(QCloseEvent* e)
_dlistWidthInit = *it; //There are only 2 values stored in the sizelist, size of dlist widget and dcanvas widget
it++;
_dcanvasWidthInit = *it;
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -541,6 +543,9 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
void DrumEdit::songChanged1(int bits)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (bits & SC_SOLO)
{
toolbar->setSolo(canvas->track()->solo());
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 1ca6f989..7ad5aabd 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -137,7 +137,7 @@ class DrumEdit : public MidiEditor {
virtual void updateHScrollRange();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
DrumEdit(MusECore::PartList*, QWidget* parent = 0, const char* name = 0, unsigned initPos = MAXINT);
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 82a75f7f..8a7356aa 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -540,6 +540,8 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
void PianoRoll::songChanged1(int bits)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
if (bits & SC_SOLO)
{
@@ -815,15 +817,19 @@ void PianoRoll::removeCtrl(CtrlEdit* ctrl)
//---------------------------------------------------------
// closeEvent
+// Save state.
+// Disconnect signals which may cause crash due to Qt deferred deletion on close.
//---------------------------------------------------------
void PianoRoll::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Pianoroll/geometry", saveGeometry());
settings.setValue("Pianoroll/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h
index 0b90b1e6..9b73fc1b 100644
--- a/muse2/muse/midiedit/pianoroll.h
+++ b/muse2/muse/midiedit/pianoroll.h
@@ -176,7 +176,7 @@ class PianoRoll : public MidiEditor {
void updateTrackInfo();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public slots:
virtual void updateHScrollRange();
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index ab161946..9ddf8fbb 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -604,6 +604,9 @@ void ScoreEdit::velo_off_box_changed()
void ScoreEdit::song_changed(int flags)
{
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED))
{
map<MusECore::Event*, MusECore::Part*> selection=get_events(score_canvas->get_all_parts(),1);
@@ -671,11 +674,13 @@ void ScoreEdit::viewport_height_changed(int height)
void ScoreEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("ScoreEdit/geometry", saveGeometry());
settings.setValue("ScoreEdit/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -1449,6 +1454,9 @@ void ScoreCanvas::fully_recalculate()
void ScoreCanvas::song_changed(int flags)
{
+ if(parent && parent->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
if (flags & (SC_PART_MODIFIED | SC_PART_REMOVED | SC_PART_INSERTED | SC_TRACK_REMOVED))
{
update_parts();
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 4e2ecf5d..29ab258e 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -184,7 +184,7 @@ class ScoreEdit : public TopWin
void clipboard_changed();
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
void name_changed();
void velo_changed(int);
void velo_off_changed(int);
diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp
index 033122d7..fbcb23cc 100644
--- a/muse2/muse/songfile.cpp
+++ b/muse2/muse/songfile.cpp
@@ -1296,7 +1296,7 @@ void MusE::readToplevels(MusECore::Xml& xml)
MusEGui::ScoreEdit* score = new MusEGui::ScoreEdit(this, 0, _arranger->cursorValue());
score->show();
toplevels.push_back(score);
- connect(score, SIGNAL(deleted(MusEGui::TopWin*)), SLOT(toplevelDeleted(MusEGui::TopWin*)));
+ connect(score, SIGNAL(isDeleting(MusEGui::TopWin*)), SLOT(toplevelDeleting(MusEGui::TopWin*)));
connect(score, SIGNAL(name_changed()), arrangerView, SLOT(scoreNamingChanged()));
score->readStatus(xml);
}
diff --git a/muse2/muse/waveedit/waveedit.cpp b/muse2/muse/waveedit/waveedit.cpp
index 424f0688..8d58cfb3 100644
--- a/muse2/muse/waveedit/waveedit.cpp
+++ b/muse2/muse/waveedit/waveedit.cpp
@@ -64,10 +64,12 @@ namespace MusEGui {
void WaveEdit::closeEvent(QCloseEvent* e)
{
+ _isDeleting = true; // Set flag so certain signals like songChanged, which may cause crash during delete, can be ignored.
+
QSettings settings("MusE", "MusE-qt");
//settings.setValue("Waveedit/geometry", saveGeometry());
settings.setValue("Waveedit/windowState", saveState());
- emit deleted(static_cast<TopWin*>(this));
+ emit isDeleting(static_cast<TopWin*>(this));
e->accept();
}
@@ -458,7 +460,9 @@ void WaveEdit::readStatus(MusECore::Xml& xml)
void WaveEdit::songChanged1(int bits)
{
-
+ if(_isDeleting) // Ignore while while deleting to prevent crash.
+ return;
+
if (bits & SC_SOLO)
{
MusECore::WavePart* part = (MusECore::WavePart*)(parts()->begin()->second);
diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h
index b40aa93a..85e71a60 100644
--- a/muse2/muse/waveedit/waveedit.h
+++ b/muse2/muse/waveedit/waveedit.h
@@ -94,7 +94,7 @@ class WaveEdit : public MidiEditor {
signals:
- void deleted(MusEGui::TopWin*);
+ void isDeleting(MusEGui::TopWin*);
public:
WaveEdit(MusECore::PartList*);