diff options
author | Florian Jung <flo@windfisch.org> | 2011-10-03 15:25:12 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-10-03 15:25:12 +0000 |
commit | 421cb6dbce48a6c1044dd37e8f710b83db5d11a9 (patch) | |
tree | 59a751bf904e6addff34b673f3025f5be8ec5c59 | |
parent | 890ee8999eaca679fa1874adf3f572f365138e29 (diff) | |
parent | f3313cc78e637ec9bc11efce5eb943434da93416 (diff) |
merged with trunk, removed more memory leaks
69 files changed, 896 insertions, 1283 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog index f8032198..4c45bc99 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,22 @@ +02.09.2011: + - SigEdit reworked to use two spinboxes, plan on adding Enter/Return detection so the widget will close when + Enter/Return is pressed (rj) + - Fixed HUGE massive memory leaks in all things using CItemList, and SndFile, dssi, fluidsynth and other huge leaks. (Tim) + Addition of 'delete' in places hopefully does not introduce any new unforseen instabilities. + Result: A song with 20 wave/midi tracks and several dssi, vst and fluidsynths, which leaked HUNDREDS of megabytes, + now only leaks about 2 megabytes. TODO: Still some funny business with ALSA, and dssi scanning. + Post-fix LEAK SUMMARY: definitely lost: 259,863 bytes in 356 blocks indirectly lost: 611,874 bytes in 22,834 blocks + possibly lost: 180,508 bytes in 5,211 blocks still reachable: 1,061,068 bytes in 10,522 blocks +30.09.2011: + - Fixed long-standing problem with themes (Ia Ora / Bespin etc) and MusE button icons. Some themes don't support + multiple-pixmap icons. So mute/solo/rec/stereo/thru always showed the same icon. Replaced w single pm icons. (Tim) + - Fixed midi strip blank automation box at bottom, too high. (Tim) + - Gradient for strip labels. (Hm, too pastel? Had to go top-high. Maybe change colours again Orcan, he he...) (Tim) + - Repaired some non-virtual paintEvent(), resizeEvent(), event() etc. (Tim) +28.09.2011: + - Optimization: Orcan's meters are insanely lightning-fast now. (Tim) + TODO: Fix very slight oversize at bottom upon first showing of mixer. Workaround: Simply resize vertically. + TODO: Redo the VerticalMeter (actually Horz) drawing, else should be easy Horz integration into existing Meter class. 21.09.2011: - Drawing speed boosts in part canvas. TODO Fix slight dashed border shifting. Do 'hidden' polygons (Tim) - Working on meter speed. WIP. Can enable by commenting out #define _USE_NEW_METERS in meter.cpp (Tim) diff --git a/muse2/awl/sigedit.cpp b/muse2/awl/sigedit.cpp index 1d2bce48..74e4b060 100644 --- a/muse2/awl/sigedit.cpp +++ b/muse2/awl/sigedit.cpp @@ -28,6 +28,7 @@ #include <QKeyEvent> #include <QLineEdit> +#include <QPainter> namespace Awl { @@ -38,212 +39,92 @@ namespace Awl { //--------------------------------------------------------- SigEdit::SigEdit(QWidget* parent) - : QAbstractSpinBox(parent) + : QWidget(parent) { initialized = false; - setReadOnly(false); - setMinimumWidth(100); //TD: sizeHint - lineEdit()->setInputMask("99/99"); - } + slash = new QLabel("/",this); + zSpin = new QSpinBox(this); + nSpin = new QSpinBox(this); + zSpin->setRange(1,100); + nSpin->setRange(1,100); + layout = new QHBoxLayout(this); + layout->setContentsMargins(0,0,0,0); + layout->setSpacing(1); + layout->addWidget(zSpin); + layout->addWidget(slash); + layout->addWidget(nSpin); + layout->addSpacing(40); + connect(zSpin, SIGNAL(valueChanged(int)), SLOT(setZ(int))); + connect(nSpin, SIGNAL(valueChanged(int)), SLOT(setN(int))); -SigEdit::~SigEdit() - { } -//--------------------------------------------------------- -// event -// filter Tab and Backtab key events -//--------------------------------------------------------- - -bool SigEdit::event(QEvent* event) - { - if (event->type() == QEvent::KeyPress) { - QKeyEvent* ke = static_cast<QKeyEvent*>(event); - int segment = curSegment(); - if (ke->key() == Qt::Key_Return) - { - int z, n; - sscanf(lineEdit()->text().toLatin1().data(), "%d/%d", &z, &n); - AL::TimeSignature sig(z, n); - _sig = sig; - - emit returnPressed(); - return true; - } - if (ke->key() == Qt::Key_Backtab) { - if (segment == 2) { - lineEdit()->setSelection(5, 2); - return true; - } - if (segment == 1) { - lineEdit()->setSelection(0, 4); - return true; - } - } - if (ke->key() == Qt::Key_Tab) { - if (segment == 0) { - lineEdit()->setSelection(5, 2); - return true; - } - if (segment == 1) { - lineEdit()->setSelection(8, 3); - return true; - } - } - } - else if (event->type() == QEvent::FocusIn) { - QFocusEvent* fe = static_cast<QFocusEvent*>(event); - QAbstractSpinBox::focusInEvent(fe); - int segment = curSegment(); - switch(segment) { - case 0: lineEdit()->setSelection(0,4); break; - case 1: lineEdit()->setSelection(5,2); break; - case 2: lineEdit()->setSelection(8,3); break; - } - return true; - } - return QAbstractSpinBox::event(event); - } - -//--------------------------------------------------------- -// setValue -//--------------------------------------------------------- - -void SigEdit::setValue(const AL::TimeSignature& s) +SigEdit::~SigEdit() { - _sig = s; - updateValue(); + delete layout; + delete zSpin; + delete nSpin; } -void SigEdit::setValue(const QString& s) - { - int z = 4, n = 4; - sscanf(s.toLatin1().constData(), "%d/%d", &z, &n); - AL::TimeSignature sig(z, n); - setValue(sig); - } //--------------------------------------------------------- -// updateValue +// setZ //--------------------------------------------------------- -void SigEdit::updateValue() - { - //printf("updateValue\n"); - char buffer[64]; - sprintf(buffer, "%d/%d", _sig.z, _sig.n); - lineEdit()->setText(buffer); - } - +void SigEdit::setZ(const int z) +{ + _sig.z=z; + if (_sig.isValid()) { + zSpin->setStyleSheet(""); + emit valueChanged(_sig); + } + else + zSpin->setStyleSheet("QSpinBox { background-color: red; }"); +} //--------------------------------------------------------- -// stepEnables +// setN //--------------------------------------------------------- -QAbstractSpinBox::StepEnabled SigEdit::stepEnabled() const - { - int segment = curSegment(); - QAbstractSpinBox::StepEnabled en = QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled; - - switch (segment) { - case 0: - if (_sig.z == 1) - en &= ~QAbstractSpinBox::StepDownEnabled; - break; - case 1: - if (_sig.n == 1) - en &= ~QAbstractSpinBox::StepDownEnabled; - break; - } - return en; - } +void SigEdit::setN(const int n) +{ + _sig.n=n; + if (_sig.isValid()) { + nSpin->setStyleSheet(""); + emit valueChanged(_sig); + } + else + nSpin->setStyleSheet("QSpinBox { background-color: red; }"); -//--------------------------------------------------------- -// fixup -//--------------------------------------------------------- - -void SigEdit::fixup(QString& /*input*/) const - { -// printf("fixup <%s>\n", input.toLatin1().constData()); - } +} //--------------------------------------------------------- -// validate +// setValue //--------------------------------------------------------- -QValidator::State SigEdit::validate(QString&,int&) const +void SigEdit::setValue(const AL::TimeSignature& s) { - // TODO - //printf("validate\n"); - return QValidator::Acceptable; - } - -//--------------------------------------------------------- -// curSegment -//--------------------------------------------------------- + _sig = s; -int SigEdit::curSegment() const - { - QLineEdit* le = lineEdit(); - int pos = le->cursorPosition(); - int segment = -1; - - if (pos >= 0 && pos <= 4) - segment = 0; - else if (pos >= 5 && pos <= 7) - segment = 1; - else if (pos >= 8) - segment = 2; - else - printf("curSegment = -1, pos %d\n", pos); - return segment; + updateValue(); } //--------------------------------------------------------- -// stepBy +// updateValue //--------------------------------------------------------- -void SigEdit::stepBy(int steps) +void SigEdit::updateValue() { - int segment = curSegment(); - int selPos; - int selLen; - - bool changed = false; - AL::TimeSignature osig(_sig); - - switch(segment) { - case 0: - _sig.z += steps; - if (_sig.z < 1) - _sig.z = 1; - selPos = 0; - selLen = 2; - break; - case 1: - _sig.n += steps; - if (_sig.n < 1) - _sig.n = 1; - selPos = 3; - selLen = 2; - break; - default: - return; - } - if (osig.z != _sig.z || osig.n != _sig.n) { - changed = true; - } - if (changed) { - updateValue(); - emit valueChanged(_sig); - } - lineEdit()->setSelection(selPos, selLen); + zSpin->setValue(_sig.z); + nSpin->setValue(_sig.n); } - void SigEdit::paintEvent(QPaintEvent* event) { + void SigEdit::paintEvent(QPaintEvent* event) { if (!initialized) updateValue(); initialized = true; - QAbstractSpinBox::paintEvent(event); + QPainter p(this); + p.fillRect(event->rect(), Qt::white); + QWidget::paintEvent(event); } } diff --git a/muse2/awl/sigedit.h b/muse2/awl/sigedit.h index 259812dd..acb0b9d8 100644 --- a/muse2/awl/sigedit.h +++ b/muse2/awl/sigedit.h @@ -26,7 +26,10 @@ #include "al/sig.h" //#include "sig.h" -#include <QAbstractSpinBox> +#include <QWidget> +#include <QSpinBox> +#include <QHBoxLayout> +#include <QLabel> namespace AL { class TimeSignature; @@ -38,29 +41,29 @@ namespace Awl { // SigEdit //--------------------------------------------------------- -class SigEdit : public QAbstractSpinBox +class SigEdit : public QWidget { Q_OBJECT AL::TimeSignature _sig; bool initialized; + QLabel *slash; + QSpinBox *zSpin; + QSpinBox *nSpin; + QHBoxLayout *layout; virtual void paintEvent(QPaintEvent* event); - virtual void stepBy(int steps); - virtual StepEnabled stepEnabled() const; - virtual void fixup(QString& input) const; - virtual QValidator::State validate(QString&, int&) const; void updateValue(); - int curSegment() const; - virtual bool event(QEvent*); signals: void valueChanged(const AL::TimeSignature&); - void returnPressed(); + + private slots: + void setN(const int n); + void setZ(const int z); public slots: void setValue(const AL::TimeSignature&); - void setValue(const QString& s); public: SigEdit(QWidget* parent = 0); diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 9f858bc3..fd024d57 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -112,6 +112,7 @@ extern void initMidiSynth(); extern void exitJackAudio(); extern void exitDummyAudio(); extern void exitOSC(); +extern void exitMidiAlsa(); #ifdef HAVE_LASH #include <lash/lash.h> @@ -1562,12 +1563,13 @@ void MusE::closeEvent(QCloseEvent* event) } #endif - // Changed by Tim. p3.3.14 - //SynthIList* sl = song->syntis(); - //for (iSynthI i = sl->begin(); i != sl->end(); ++i) - // delete *i; song->cleanupForQuit(); + // Give midi devices a chance to close first, above in cleanupForQuit. + if(MusEGlobal::debugMsg) + printf("Muse: Exiting ALSA midi\n"); + exitMidiAlsa(); + if(MusEGlobal::debugMsg) printf("Muse: Cleaning up temporary wavefiles + peakfiles\n"); // Cleanup temporary wavefiles + peakfiles used for undo diff --git a/muse2/muse/appearance.cpp b/muse2/muse/appearance.cpp index b49b951b..b3e89aa1 100644 --- a/muse2/muse/appearance.cpp +++ b/muse2/muse/appearance.cpp @@ -58,7 +58,7 @@ class BgPreviewWidget : public QWidget { int text_w; protected: - void paintEvent(QPaintEvent* event) + virtual void paintEvent(QPaintEvent* event) { QPainter p(this); int w = t_widget->width() - 65; diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 0de8d278..5b5f3a6f 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -112,6 +112,11 @@ PartCanvas::PartCanvas(int* r, QWidget* parent, int sx, int sy) partsChanged(); } +PartCanvas::~PartCanvas() +{ + //items.clearDelete(); +} + //--------------------------------------------------------- // y2pitch //--------------------------------------------------------- @@ -427,7 +432,8 @@ QPoint PartCanvas::raster(const QPoint& p) const void PartCanvas::partsChanged() { - items.clear(); + //items.clear(); + items.clearDelete(); for (iTrack t = tracks->begin(); t != tracks->end(); ++t) { PartList* pl = (*t)->parts(); for (iPart i = pl->begin(); i != pl->end(); ++i) { diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 3e320e56..e0c601fe 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -171,6 +171,7 @@ class PartCanvas : public MusEWidget::Canvas { CMD_PASTE_DIALOG, CMD_PASTE_CLONE_DIALOG, CMD_INSERT_EMPTYMEAS }; PartCanvas(int* raster, QWidget* parent, int, int); + virtual ~PartCanvas(); void partsChanged(); void cmd(int); public slots: diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index c28a40b2..68f6dceb 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -265,8 +265,11 @@ void TList::paint(const QRect& r) switch (section) { case COL_RECORD: if (track->canRecord() && !header->isSectionHidden(COL_RECORD)) { + //bool aa = p.testRenderHint(QPainter::SmoothPixmapTransform); // Antialiasing); // The rec icon currently looks very jagged. AA should help. + //p.setRenderHint(QPainter::SmoothPixmapTransform); //Antialiasing); drawCenteredPixmap(p, track->recordFlag() ? record_on_Icon : record_off_Icon, r); + //p.setRenderHint(QPainter::SmoothPixmapTransform, aa); //Antialiasing, aa); } break; case COL_CLASS: @@ -1689,10 +1692,10 @@ void TList::setYPos(int y) // resizeEvent //--------------------------------------------------------- -void TList::resizeEvent(QResizeEvent* /*ev*/) - { - - } +//void TList::resizeEvent(QResizeEvent* /*ev*/) +// { +// +// } //--------------------------------------------------------- // classesPopupMenu diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h index 01b13eb3..db19ef6b 100644 --- a/muse2/muse/arranger/tlist.h +++ b/muse2/muse/arranger/tlist.h @@ -103,7 +103,7 @@ class TList : public QWidget { void moveSelection(int n); void adjustScrollbar(); void paint(const QRect& r); - virtual void resizeEvent(QResizeEvent*); + //virtual void resizeEvent(QResizeEvent*); void redraw(const QRect& r); Track* y2Track(int) const; void classesPopupMenu(Track*, int x, int y); diff --git a/muse2/muse/arranger/trackautomationview.h b/muse2/muse/arranger/trackautomationview.h index f169e968..8c7aed84 100644 --- a/muse2/muse/arranger/trackautomationview.h +++ b/muse2/muse/arranger/trackautomationview.h @@ -33,7 +33,7 @@ namespace MusEArranger { class TrackAutomationView : public QWidget { Track *_t; - void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e); std::map<int,int> automationList; public: TrackAutomationView(QWidget *parent, Track *t); diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index 1db8dda3..6426a377 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -202,6 +202,9 @@ AudioTrack::~AudioTrack() } delete[] outBuffers; + for(iCtrlList i = _controller.begin(); i != _controller.end(); ++i) + delete i->second; + } //--------------------------------------------------------- diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp index 6395bf2d..8ad9c510 100644 --- a/muse2/muse/driver/alsamidi.cpp +++ b/muse2/muse/driver/alsamidi.cpp @@ -3,7 +3,7 @@ // Linux Music Editor // $Id: alsamidi.cpp,v 1.8.2.7 2009/11/19 04:20:33 terminator356 Exp $ // (C) Copyright 2000-2001 Werner Schweer (ws@seh.de) -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (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 @@ -42,7 +42,7 @@ static int alsaSeqFdi = -1; static int alsaSeqFdo = -1; -snd_seq_t* alsaSeq; +snd_seq_t* alsaSeq = 0; static snd_seq_addr_t musePort; //--------------------------------------------------------- @@ -795,6 +795,27 @@ bool initMidiAlsa() return false; } +namespace MusEApp { + +//--------------------------------------------------------- +// exitMidiAlsa +//--------------------------------------------------------- + +void exitMidiAlsa() +{ + if(alsaSeq) + { + int error = snd_seq_close(alsaSeq); // FIXME Hm, this did not get rid of a buch of valgrind leaks. + if(error < 0) + { + fprintf(stderr, "Could not close ALSA sequencer: %s\n", snd_strerror(error)); + } + } +} + +} // namespace MusEApp + + struct AlsaPort { snd_seq_addr_t adr; char* name; diff --git a/muse2/muse/driver/alsamidi.h b/muse2/muse/driver/alsamidi.h index 13e07ca4..9badd7c4 100644 --- a/muse2/muse/driver/alsamidi.h +++ b/muse2/muse/driver/alsamidi.h @@ -3,7 +3,7 @@ // Linux Music Editor // $Id: alsamidi.h,v 1.2 2004/01/14 09:06:43 wschweer Exp $ // (C) Copyright 2001 Werner Schweer (ws@seh.de) -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (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 @@ -77,6 +77,7 @@ class MidiAlsaDevice : public MidiDevice { }; extern bool initMidiAlsa(); +extern bool exitMidiAlsa(); extern int alsaSelectRfd(); extern int alsaSelectWfd(); extern void alsaProcessMidiInput(); diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index 42653a91..ad4b2401 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -4,7 +4,7 @@ // $Id: dssihost.cpp,v 1.15.2.16 2009/12/15 03:39:58 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (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 @@ -84,8 +84,6 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument { const DSSI_Descriptor* descr; - // CRAPPY PLUGIN ALERT: - // Out of many plugins, with several, Valgrind says something in here is allocated with new. descr = dssi(i); if (descr == 0) break; @@ -120,8 +118,10 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument break; } if(is != synthis.end()) + { + //delete descr; continue; - + } DssiSynth* s = new DssiSynth(fi, descr); if(MusEGlobal::debugMsg) @@ -149,6 +149,9 @@ static void scanDSSILib(QFileInfo& fi) // ddskrjo removed const for argument synthis.push_back(s); } + //else + // delete descr; + } } dlclose(handle); @@ -270,7 +273,8 @@ DssiSynth::DssiSynth(QFileInfo& fi, const DSSI_Descriptor* d) : // ddskrjo remov DssiSynth::~DssiSynth() { - + if(dssi) + delete dssi; } //--------------------------------------------------------- diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index cea46e69..05e3b91c 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -4,7 +4,7 @@ // $Id: dssihost.h,v 1.10.2.7 2009/12/06 10:05:00 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// (C) Copyright 2011 Tim E. Real (terminator356 on users dot sourceforge dot net) +// (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 diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp index 423e65fa..89a3a48e 100644 --- a/muse2/muse/icons.cpp +++ b/muse2/muse/icons.cpp @@ -367,8 +367,8 @@ QPixmap* soloIconOn; QPixmap* soloIconOff; QPixmap* soloblksqIconOn; QPixmap* soloblksqIconOff; -QIcon* soloIconSet1; -QIcon* soloIconSet2; +//QIcon* soloIconSet1; +//QIcon* soloIconSet2; QPixmap* editmuteIcon; QPixmap* editmuteSIcon; @@ -582,8 +582,12 @@ void initIcons() editpaste2TrackIcon = new MICON(editpaste2track_xpm, NULL); editpasteClone2TrackIcon = new MICON(editpasteclone2track_xpm, NULL); */ - exitIcon = new MPIXMAP(exit_xpm, "application-exit"); - exit1Icon = new MPIXMAP(exit1_xpm, "application-exit"); + + //exitIcon = new MPIXMAP(exit_xpm, "application-exit"); + //exit1Icon = new MPIXMAP(exit1_xpm, "application-exit"); + // Changed by Tim. There are IMO no suitable theme substitutes for these two so far... + exitIcon = new MPIXMAP(exit_xpm, NULL); + exit1Icon = new MPIXMAP(exit1_xpm, NULL); // 2 lines odd code newmuteIcon = new MPIXMAP(newmutebutton_xpm, NULL); @@ -597,12 +601,12 @@ void initIcons() soloIconOff = new MPIXMAP(solobutton_off_xpm, NULL); soloblksqIconOn = new MPIXMAP(solobutton_on_blksq_xpm, NULL); soloblksqIconOff = new MPIXMAP(solobutton_off_blksq_xpm, NULL); - soloIconSet1 = new QIcon(); - soloIconSet2 = new QIcon(); - soloIconSet1->addPixmap(*soloIconOn, QIcon::Normal, QIcon::On); - soloIconSet1->addPixmap(*soloIconOff, QIcon::Normal, QIcon::Off); - soloIconSet2->addPixmap(*soloblksqIconOn, QIcon::Normal, QIcon::On); - soloIconSet2->addPixmap(*soloblksqIconOff, QIcon::Normal, QIcon::Off); + //soloIconSet1 = new QIcon(); + //soloIconSet2 = new QIcon(); + //soloIconSet1->addPixmap(*soloIconOn, QIcon::Normal, QIcon::On); + //soloIconSet1->addPixmap(*soloIconOff, QIcon::Normal, QIcon::Off); + //soloIconSet2->addPixmap(*soloblksqIconOn, QIcon::Normal, QIcon::On); + //soloIconSet2->addPixmap(*soloblksqIconOff, QIcon::Normal, QIcon::Off); redLedIcon = new MPIXMAP(redled_xpm, NULL); darkRedLedIcon = new MPIXMAP(darkredled_xpm, NULL); diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h index 8d55b255..957f4a74 100644 --- a/muse2/muse/icons.h +++ b/muse2/muse/icons.h @@ -151,8 +151,8 @@ extern QPixmap* soloIconOn; extern QPixmap* soloIconOff; extern QPixmap* soloblksqIconOn; extern QPixmap* soloblksqIconOff; -extern QIcon* soloIconSet1; -extern QIcon* soloIconSet2; +//extern QIcon* soloIconSet1; +//extern QIcon* soloIconSet2; extern QPixmap* redLedIcon; extern QPixmap* darkRedLedIcon; diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp index a2cc8538..ce6010c7 100644 --- a/muse2/muse/master/lmaster.cpp +++ b/muse2/muse/master/lmaster.cpp @@ -601,7 +601,8 @@ void LMaster::itemDoubleClicked(QTreeWidgetItem* i) tempo_editor->selectAll(); } else if (editedItem->getType() == LMASTER_SIGEVENT) { // Edit signatur value: - sig_editor->setValue(editedItem->text(LMASTER_VAL_COL)); + //sig_editor->setValue(editedItem->text(LMASTER_VAL_COL)); + sig_editor->setValue(((LMasterSigEventItem*)editedItem)->getEvent()->sig); sig_editor->setGeometry(itemRect); sig_editor->show(); sig_editor->setFocus(); @@ -923,7 +924,7 @@ LMasterSigEventItem::LMasterSigEventItem(QTreeWidget* parent, const AL::SigEvent int msec = int((time - (min*60 + sec)) * 1000.0); c2.sprintf("%03d:%02d:%03d", min, sec, msec); c3 = "Timesig"; - c4.sprintf("%d/%d", ev->sig.z, ev->sig.n); + c4.sprintf("%d / %d", ev->sig.z, ev->sig.n); setText(0, c1); setText(1, c2); setText(2, c3); diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 35236e87..34173780 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -150,6 +150,15 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int))); } +DrumCanvas::~DrumCanvas() +{ + //items.clearDelete(); + + if (must_delete_our_drum_map && ourDrumMap!=NULL) + delete [] ourDrumMap; + delete steprec; +} + //--------------------------------------------------------- // moveCanvasItems //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index e06857a9..9a45f6ac 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -147,6 +147,7 @@ class DrumCanvas : public EventCanvas { }; DrumCanvas(MidiEditor*, QWidget*, int, int, const char* name = 0); + virtual ~DrumCanvas(); void cmd(int); virtual void modifySelected(MusEWidget::NoteInfo::ValType type, int delta); virtual void keyPress(QKeyEvent* event); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 85382c4a..350f5e5e 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -243,7 +243,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev) sInstrument = instrument; drag = START_DRAG; - DCols col = DCols(x2col(x)); //FINDMICH update + DCols col = DCols(x2col(x)); int val; int incVal = 0; diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index cb96118f..b30574f1 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -147,7 +147,8 @@ void EventCanvas::songChanged(int flags) return; if (flags & ~SC_SELECTION) { - items.clear(); + //items.clear(); + items.clearDelete(); start_tick = MAXINT; end_tick = 0; curPart = 0; diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index b96cb47f..b9b4794f 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -110,6 +110,10 @@ PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy) connect(song, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int))); } +PianoCanvas::~PianoCanvas() +{ + delete steprec; +} //--------------------------------------------------------- // pitch2y //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index a44a9a4a..b3a8a288 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -117,6 +117,7 @@ class PianoCanvas : public EventCanvas { }; PianoCanvas(MidiEditor*, QWidget*, int, int); + virtual ~PianoCanvas(); void cmd(int cmd); void setColorMode(int mode) { colorMode = mode; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index cf7d031f..64258f60 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -1257,6 +1257,11 @@ ScoreCanvas::ScoreCanvas(ScoreEdit* pr, QWidget* parent_widget) : View(parent_wi unsetCursor(); } +ScoreCanvas::~ScoreCanvas() +{ + delete steprec; +} + void ScoreCanvas::staffmode_treble_slot() { set_staffmode(current_staff, MODE_TREBLE); @@ -4591,32 +4596,15 @@ void ScoreCanvas::add_new_parts(const std::map< Part*, std::set<Part*> >& param) * * > o drum editor: channel-stuff * o dialog for maintaining drum lists, hide etc - * o grouping * o respect "_drummap_tied_to_patch": IMPLEMENT * o save hide, ordering, track's drumlists - * x hide instruments - * x remember ordering of instruments - * x tracks have own drumlists - * * o "copy drumlist" from one track to another - * - * x each track has its own drumlist and a bool maintained_automatically * o whenever changing the patch and maintained_automatically==true, * the drumlist is replaced by the according one (for example, "jazz" drum kit's list) * o whenever changing the drumlist and maintained_automatically==true, * ask the user if he wants to proceed, and then set maintained_automatically to false * o offer some way to set maintained_automatically to true again - * x each track has a bool hidden[128], which is used for hiding entries. - * when mixing, the values of all tracks are ANDed - * o offer a way to hide/show instruments - * - * o drum editor can: "display each track separately", "mix all with same port, patch and drumlist" - * x a map maps all y-coord.s to { set<Track*>, pitch } - * x either open flo-tracks OR old-style-tracks - * x replace all DRUM_MAPSIZE by instrument_map.size() - * o signal for instrument_map.size or drum_map_size() changed! * o move generation and deletion of ourDrumMap from DCanvas to DrumEditor and remove ugly wrapper functions - * o ... * * o when playing back a flo-drum-track: treat as a MIDI track, * EXCEPT that the drum list's mute entries are respected! diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 046fbf73..8f21e76b 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -811,7 +811,7 @@ class ScoreCanvas : public MusEWidget::View public: ScoreCanvas(ScoreEdit*, QWidget*); - ~ScoreCanvas(){}; + ~ScoreCanvas(); void add_staves(PartList* pl, bool all_in_one); void push_back_staff(staff_t& staff) { staves.push_back(staff); } //FINDMICH dirty. very dirty. diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp index 156017e8..bf31d820 100644 --- a/muse2/muse/mixer/astrip.cpp +++ b/muse2/muse/mixer/astrip.cpp @@ -4,6 +4,7 @@ // $Id: astrip.cpp,v 1.23.2.17 2009/11/16 01:55:55 terminator356 Exp $ // // (C) Copyright 2000-2004 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 @@ -172,28 +173,19 @@ void AudioStrip::songChanged(int val) mute->blockSignals(true); mute->setChecked(src->mute()); mute->blockSignals(false); + mute->setIcon(src->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + //mute->setIconSize(muteIconOn->size()); updateOffState(); } if (solo && (val & SC_SOLO)) { - if((bool)track->internalSolo()) - { - if(!useSoloIconSet2) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - } - else if(useSoloIconSet2) - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - solo->blockSignals(true); solo->setChecked(track->solo()); solo->blockSignals(false); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + //solo->setIconSize(soloIconOn->size()); } if (val & SC_RECFLAG) setRecordFlag(track->recordFlag()); @@ -232,19 +224,31 @@ void AudioStrip::songChanged(int val) if(track->automationType() == AUTO_TOUCH || track->automationType() == AUTO_WRITE) { palette.setColor(QPalette::Button, QColor(215, 76, 39)); // red - //QColor c(Qt::red); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + //palette.setColor(QPalette::Window, QColor(215, 76, 39)); // red + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::red); + //QColor c(215, 76, 39); // red + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else if(track->automationType() == AUTO_READ) { palette.setColor(QPalette::Button, QColor(100, 172, 49)); // green - //QColor c(Qt::green); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + //palette.setColor(QPalette::Window, QColor(100, 172, 49)); // green + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::green); + //QColor c(100, 172, 49); // green + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else @@ -354,6 +358,8 @@ void AudioStrip::updateOffState() off->blockSignals(true); off->setChecked(track->off()); off->blockSignals(false); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + //off->setIconSize(exit1Icon->size()); } } @@ -623,6 +629,8 @@ void AudioStrip::updateChannels() stereo->blockSignals(true); stereo->setChecked(channel == 2); stereo->blockSignals(false); + stereo->setIcon(channel == 2 ? QIcon(*stereoIcon) : QIcon(*monoIcon)); + //stereo->setIconSize(stereoIcon->size()); } //--------------------------------------------------------- @@ -753,15 +761,11 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) stereo = new QToolButton(); stereo->setFont(MusEConfig::config.fonts[1]); - QIcon stereoSet; - stereoSet.addPixmap(*monoIcon, QIcon::Normal, QIcon::Off); - stereoSet.addPixmap(*stereoIcon, QIcon::Normal, QIcon::On); - stereo->setIcon(stereoSet); - stereo->setIconSize(monoIcon->size()); - stereo->setCheckable(true); stereo->setToolTip(tr("1/2 channel")); stereo->setChecked(channel == 2); + stereo->setIcon(channel == 2 ? QIcon(*stereoIcon) : QIcon(*monoIcon)); + stereo->setIconSize(monoIcon->size()); stereo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(stereo, SIGNAL(clicked(bool)), SLOT(stereoToggled(bool))); @@ -868,47 +872,33 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) record->setCheckable(true); record->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); record->setBackgroundRole(QPalette::Mid); - QIcon iconSet; - iconSet.addPixmap(*record_on_Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*record_off_Icon, QIcon::Normal, QIcon::Off); - record->setIcon(iconSet); - record->setIconSize(record_on_Icon->size()); record->setToolTip(tr("record")); record->setChecked(t->recordFlag()); + record->setIcon(t->recordFlag() ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + record->setIconSize(record_on_Icon->size()); connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); } Track::TrackType type = t->type(); mute = new QToolButton(); - QIcon muteSet; - muteSet.addPixmap(*muteIconOn, QIcon::Normal, QIcon::Off); - muteSet.addPixmap(*muteIconOff, QIcon::Normal, QIcon::On); - mute->setIcon(muteSet); - mute->setIconSize(muteIconOn->size()); mute->setCheckable(true); mute->setToolTip(tr("mute")); mute->setChecked(t->mute()); + mute->setIcon(t->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + mute->setIconSize(muteIconOn->size()); mute->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); solo = new QToolButton(); - if((bool)t->internalSolo()) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - else - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - solo->setCheckable(true); solo->setChecked(t->solo()); + if(t->internalSolo()) + solo->setIcon(t->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(t->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + solo->setIconSize(soloIconOn->size()); solo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); if (type == Track::AUDIO_OUTPUT) { @@ -922,16 +912,13 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) } off = new MusEWidget::TransparentToolButton(this); - QIcon iconSet; - iconSet.addPixmap(*exit1Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*exitIcon, QIcon::Normal, QIcon::Off); - off->setIcon(iconSet); - off->setIconSize(exit1Icon->size()); off->setBackgroundRole(QPalette::Mid); off->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); off->setCheckable(true); off->setToolTip(tr("off")); off->setChecked(t->off()); + off->setIcon(t->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + off->setIconSize(exit1Icon->size()); connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); grid->addWidget(off, _curGridRow, 0); @@ -972,6 +959,7 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) autoType = new MusEWidget::ComboBox(); autoType->setFont(MusEConfig::config.fonts[1]); autoType->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + //autoType->setAutoFillBackground(true); autoType->addAction(tr("Off"), AUTO_OFF); autoType->addAction(tr("Read"), AUTO_READ); @@ -983,20 +971,30 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) //QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); if(t->automationType() == AUTO_TOUCH || t->automationType() == AUTO_WRITE) { - palette.setColor(QPalette::Button, QColor(Qt::red)); - //QColor c(Qt::red); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + palette.setColor(QPalette::Button, QColor(215, 76, 39)); // red + /* QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::red); + //QColor c(215, 76, 39); // red + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else if(t->automationType() == AUTO_READ) { - palette.setColor(QPalette::Button, QColor(Qt::green)); - //QColor c(Qt::green); - //gradient.setColorAt(0, c); - //gradient.setColorAt(1, c.darker()); - //palette.setBrush(QPalette::Button, gradient); + palette.setColor(QPalette::Button, QColor(100, 172, 49)); // green + /*QLinearGradient gradient(autoType->geometry().topLeft(), autoType->geometry().bottomLeft()); + QColor c(Qt::green); + //QColor c(100, 172, 49); // green + gradient.setColorAt(0, c.darker()); + gradient.setColorAt(0.5, c); + gradient.setColorAt(1, c.darker()); + palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(autoType->backgroundRole(), gradient); + //palette.setBrush(QPalette::Window, gradient); */ autoType->setPalette(palette); } else diff --git a/muse2/muse/mixer/astrip.h b/muse2/muse/mixer/astrip.h index 72e88cca..3e2b6c1d 100644 --- a/muse2/muse/mixer/astrip.h +++ b/muse2/muse/mixer/astrip.h @@ -4,6 +4,7 @@ // $Id: astrip.h,v 1.8.2.6 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 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 diff --git a/muse2/muse/mixer/mstrip.cpp b/muse2/muse/mixer/mstrip.cpp index c6832e6b..c920d6c6 100644 --- a/muse2/muse/mixer/mstrip.cpp +++ b/muse2/muse/mixer/mstrip.cpp @@ -4,6 +4,7 @@ // $Id: mstrip.cpp,v 1.9.2.13 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 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 @@ -296,48 +297,32 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) record->setBackgroundRole(QPalette::Mid); record->setCheckable(true); record->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); - - QIcon iconSet; - iconSet.addPixmap(*record_on_Icon, QIcon::Normal, QIcon::On); - iconSet.addPixmap(*record_off_Icon, QIcon::Normal, QIcon::Off); - record->setIcon(iconSet); - record->setIconSize(record_on_Icon->size()); record->setToolTip(tr("record")); record->setChecked(track->recordFlag()); + record->setIcon(track->recordFlag() ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + record->setIconSize(record_on_Icon->size()); connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool))); mute = new QToolButton(); - QIcon muteSet; - muteSet.addPixmap(*muteIconOn, QIcon::Normal, QIcon::Off); - muteSet.addPixmap(*muteIconOff, QIcon::Normal, QIcon::On); - mute->setIcon(muteSet); - mute->setIconSize(muteIconOn->size()); mute->setCheckable(true); mute->setToolTip(tr("mute")); mute->setChecked(track->mute()); + mute->setIcon(track->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + mute->setIconSize(muteIconOn->size()); mute->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool))); solo = new QToolButton(); - - if((bool)t->internalSolo()) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - else - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } - //solo->setToolTip(tr("pre fader listening")); solo->setToolTip(tr("solo mode")); solo->setCheckable(true); - solo->setChecked(t->solo()); + solo->setChecked(track->solo()); solo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + solo->setIconSize(soloIconOn->size()); connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool))); /* @@ -363,8 +348,8 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) ///dev_ch_label->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum)); dev_ch_label->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); dev_ch_label->setAlignment(Qt::AlignCenter); - int port = t->outPort(); - int channel = t->outChannel(); + int port = track->outPort(); + int channel = track->outChannel(); QString dcs; dcs.sprintf("%d-%d", port + 1, channel + 1); dev_ch_label->setText(dcs); @@ -377,16 +362,13 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) */ off = new MusEWidget::TransparentToolButton(this); - QIcon iconOff; - iconOff.addPixmap(*exit1Icon, QIcon::Normal, QIcon::On); - iconOff.addPixmap(*exitIcon, QIcon::Normal, QIcon::Off); - off->setIcon(iconOff); - off->setIconSize(exit1Icon->size()); off->setBackgroundRole(QPalette::Mid); off->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); off->setCheckable(true); off->setToolTip(tr("off")); - off->setChecked(t->off()); + off->setChecked(track->off()); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + off->setIconSize(exit1Icon->size()); connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool))); grid->addWidget(off, _curGridRow, 0); @@ -436,6 +418,8 @@ MidiStrip::MidiStrip(QWidget* parent, MidiTrack* t) //autoType->setCurrentItem(t->automationType()); //autoType->setToolTip(tr("automation type")); //connect(autoType, SIGNAL(activated(int)), SLOT(setAutomationType(int))); + autoType->addAction(" ", AUTO_OFF); // Just a dummy text to fix sizing problems. REMOVE later if full automation added. + autoType->setCurrentItem(AUTO_OFF); // grid->addWidget(autoType, _curGridRow++, 0, 1, 2); connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat())); @@ -461,8 +445,9 @@ void MidiStrip::updateOffState() solo->setEnabled(val); if (mute) mute->setEnabled(val); - if (autoType) - autoType->setEnabled(val); + // TODO: Disabled for now. + //if (autoType) + // autoType->setEnabled(val); if (iR) iR->setEnabled(val); // TODO: Disabled for now. @@ -472,6 +457,8 @@ void MidiStrip::updateOffState() off->blockSignals(true); off->setChecked(track->off()); off->blockSignals(false); + off->setIcon(track->off() ? QIcon(*exit1Icon) : QIcon(*exitIcon)); + //off->setIconSize(exit1Icon->size()); } } @@ -483,30 +470,23 @@ void MidiStrip::songChanged(int val) { if (mute && (val & SC_MUTE)) { // mute && off mute->blockSignals(true); - mute->setChecked(track->isMute()); - updateOffState(); + //mute->setChecked(track->isMute()); + mute->setChecked(track->mute()); mute->blockSignals(false); + mute->setIcon(track->mute() ? QIcon(*muteIconOff) : QIcon(*muteIconOn)); + //mute->setIconSize(muteIconOn->size()); + updateOffState(); } if (solo && (val & SC_SOLO)) { - if((bool)track->internalSolo()) - { - if(!useSoloIconSet2) - { - solo->setIcon(*soloIconSet2); - solo->setIconSize(soloIconOn->size()); - useSoloIconSet2 = true; - } - } - else if(useSoloIconSet2) - { - solo->setIcon(*soloIconSet1); - solo->setIconSize(soloblksqIconOn->size()); - useSoloIconSet2 = false; - } solo->blockSignals(true); solo->setChecked(track->solo()); solo->blockSignals(false); + if(track->internalSolo()) + solo->setIcon(track->solo() ? QIcon(*soloblksqIconOn) : QIcon(*soloblksqIconOff)); + else + solo->setIcon(track->solo() ? QIcon(*soloIconOn) : QIcon(*soloIconOff)); + //solo->setIconSize(soloIconOn->size()); } if (val & SC_RECFLAG) diff --git a/muse2/muse/mixer/mstrip.h b/muse2/muse/mixer/mstrip.h index d8e947f9..0535eaa8 100644 --- a/muse2/muse/mixer/mstrip.h +++ b/muse2/muse/mixer/mstrip.h @@ -4,6 +4,7 @@ // $Id: mstrip.h,v 1.4.2.4 2009/10/25 19:26:29 lunar_shuttle Exp $ // // (C) Copyright 2000-2004 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 diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index e9f92e9b..59149222 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -4,6 +4,7 @@ // $Id: strip.cpp,v 1.6.2.5 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 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 @@ -38,6 +39,7 @@ #include "strip.h" #include "meter.h" #include "utils.h" +#include "icons.h" namespace MusEMixer { @@ -51,6 +53,8 @@ void Strip::setRecordFlag(bool flag) record->blockSignals(true); record->setChecked(flag); record->blockSignals(false); + record->setIcon(flag ? QIcon(*record_on_Icon) : QIcon(*record_off_Icon)); + //record->setIconSize(record_on_Icon->size()); } } @@ -75,7 +79,11 @@ void Strip::recordToggled(bool val) } audio->msgSetRecord((AudioOutput*)track, val); if (!((AudioOutput*)track)->recFile()) + { record->setChecked(false); + record->setIcon(QIcon(*record_off_Icon)); + //record->setIconSize(record_on_Icon->size()); + } return; } song->setRecordFlag(track, val); @@ -148,8 +156,18 @@ void Strip::setLabelText() label->setText(track->name()); QPalette palette; - palette.setColor(label->backgroundRole(), c); + //palette.setColor(label->backgroundRole(), c); + QLinearGradient gradient(label->geometry().topLeft(), label->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + palette.setBrush(label->backgroundRole(), gradient); label->setPalette(palette); + //label->setStyleSheet(QString("background-color: ") + c.name()); } @@ -186,18 +204,16 @@ Strip::Strip(QWidget* parent, Track* t) iR = 0; oR = 0; - setBackgroundRole(QPalette::Mid); + ///setBackgroundRole(QPalette::Mid); setFrameStyle(Panel | Raised); setLineWidth(2); // NOTE: Workaround for freakin' improper disabled button text colour (at least with Oxygen colours). // Just set the parent palette. - QPalette pal(palette()); - pal.setColor(QPalette::Disabled, QPalette::ButtonText, - pal.color(QPalette::Disabled, QPalette::WindowText)); - setPalette(pal); - - useSoloIconSet2 = false; + //QPalette pal(palette()); + //pal.setColor(QPalette::Disabled, QPalette::ButtonText, + // pal.color(QPalette::Disabled, QPalette::WindowText)); + //setPalette(pal); track = t; meter[0] = 0; @@ -233,7 +249,7 @@ Strip::Strip(QWidget* parent, Track* t) // Therefore 'fake' set the size of the label now. // Added by Tim. p3.3.9 //label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*frameWidth() - 2*layout->margin(), label->height()); - label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*grid->margin(), label->height()); + ///label->setGeometry(label->x(), label->y(), STRIP_WIDTH - 2*grid->margin(), label->height()); label->setTextFormat(Qt::PlainText); @@ -279,5 +295,14 @@ void Strip::setAutomationType(int t) track->setAutomationType(AutomationType(t)); song->update(SC_AUTOMATION); } + +void Strip::resizeEvent(QResizeEvent* ev) +{ + //printf("Strip::resizeEvent\n"); + QFrame::resizeEvent(ev); + setLabelText(); + setLabelFont(); +} + } // namespace MusEMixer diff --git a/muse2/muse/mixer/strip.h b/muse2/muse/mixer/strip.h index ea4d2693..f5749177 100644 --- a/muse2/muse/mixer/strip.h +++ b/muse2/muse/mixer/strip.h @@ -4,6 +4,7 @@ // $Id: strip.h,v 1.3.2.2 2009/11/14 03:37:48 terminator356 Exp $ // // (C) Copyright 2000-2004 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 @@ -62,7 +63,6 @@ class Strip : public QFrame { QGridLayout* grid; int _curGridRow; MusEWidget::Meter* meter[MAX_CHANNELS]; - bool useSoloIconSet2; QToolButton* record; QToolButton* solo; @@ -72,6 +72,7 @@ class Strip : public QFrame { QGridLayout* sliderGrid; MusEWidget::ComboBox* autoType; void setLabelText(); + virtual void resizeEvent(QResizeEvent*); private slots: void recordToggled(bool); diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp index e7aaa46b..c0d936ec 100644 --- a/muse2/muse/osc.cpp +++ b/muse2/muse/osc.cpp @@ -4,7 +4,7 @@ // $Id: osc.cpp,v 1.0.0.0 2010/04/22 03:39:58 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others -// OSC module added by Tim. +// (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 @@ -28,21 +28,23 @@ // Turn on debugging messages //#define OSC_DEBUG +// Whether to use a QProcess or fork + execlp to start the gui. (Note fork + execlp give problems - zombies when synth window closed.) +#define _USE_QPROCESS_FOR_GUI_ 1 + #include <string.h> -//#include <signal.h> -//#include <dlfcn.h> #include <stdlib.h> -#include <sys/stat.h> -#include <errno.h> -//#include <dssi.h> -//#include <alsa/asoundlib.h> -#include <QDir> #include <QFileInfo> #include <QString> #include <QStringList> -#include <QProcess> -#include <QTimer> + +#ifdef _USE_QPROCESS_FOR_GUI_ + #include <QProcess> +#else + #include <unistd.h> + #include <signal.h> + #include <errno.h> +#endif #include <lo/lo.h> @@ -55,23 +57,11 @@ #include "track.h" #include "song.h" #include "synth.h" -//#include "audio.h" -//#include "jackaudio.h" -//#include "midi.h" -//#include "midiport.h" -//#include "al/al.h" -//#include "al/xml.h" -//#include "xml.h" -//#include "midictrl.h" -//#include "ladspaplugin.h" - #include "app.h" #include "globals.h" #include "globaldefs.h" -//#include "al/dsp.h" static lo_server_thread serverThread = 0; -///static char osc_path_tmp[1024]; static char* url = 0; static bool oscServerRunning = false; @@ -107,7 +97,6 @@ static int oscDebugHandler(const char* path, const char* types, lo_arg** argv, int oscMessageHandler(const char* path, const char* types, lo_arg** argv, int argc, void* data, void* user_data) - //int argc, lo_message data, void* user_data) { const char* p = path; @@ -409,61 +398,6 @@ void stopOSC() } // namespace MusEApp -/* -//--------------------------------------------------------- -// OscControlFifo -// put -// return true on fifo overflow -//--------------------------------------------------------- - -bool OscControlFifo::put(const OscControlValue& event) - { - if (size < OSC_FIFO_SIZE) { - fifo[wIndex] = event; - wIndex = (wIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_increment(&size); - ++size; - return false; - } - return true; - } - -//--------------------------------------------------------- -// get -//--------------------------------------------------------- - -OscControlValue OscControlFifo::get() - { - OscControlValue event(fifo[rIndex]); - rIndex = (rIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_decrement(&size); - --size; - return event; - } - -//--------------------------------------------------------- -// peek -//--------------------------------------------------------- - -const OscControlValue& OscControlFifo::peek(int n) - { - int idx = (rIndex + n) % OSC_FIFO_SIZE; - return fifo[idx]; - } - -//--------------------------------------------------------- -// remove -//--------------------------------------------------------- - -void OscControlFifo::remove() - { - rIndex = (rIndex + 1) % OSC_FIFO_SIZE; - // q_atomic_decrement(&size); - --size; - } -*/ - - //--------------------------------------------------------- // OscIF // Open Sound Control Interface @@ -471,12 +405,6 @@ void OscControlFifo::remove() OscIF::OscIF() { - //_oscPluginI = 0; - - //#ifdef DSSI_SUPPORT - //_oscSynthIF = 0; - //#endif - _uiOscTarget = 0; _uiOscSampleRatePath = 0; _uiOscShowPath = 0; @@ -484,17 +412,17 @@ OscIF::OscIF() _uiOscConfigurePath = 0; _uiOscProgramPath = 0; _uiOscPath = 0; - //guiPid = -1; +#ifdef _USE_QPROCESS_FOR_GUI_ _oscGuiQProc = 0; +#else + _guiPid = -1; +#endif _oscGuiVisible = false; - - //_oscControlFifos = 0; } OscIF::~OscIF() { - //if (guiPid != -1) - // kill(guiPid, SIGHUP); +#ifdef _USE_QPROCESS_FOR_GUI_ if(_oscGuiQProc) { if(_oscGuiQProc->state()) @@ -516,10 +444,20 @@ OscIF::~OscIF() // so kill is not desirable. // We could wait until terminate finished but don't think that's good here. ///QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) ); + _oscGuiQProc->waitForFinished(3000); } - //delete _oscGuiQProc; + delete _oscGuiQProc; } - + +#else // NOT _USE_QPROCESS_FOR_GUI_ + + if (_guiPid != -1) + { + if(kill(_guiPid, SIGHUP) != -1) + _guiPid = -1; + } +#endif // _USE_QPROCESS_FOR_GUI_ + if(_uiOscTarget) lo_address_free(_uiOscTarget); if(_uiOscSampleRatePath) @@ -534,23 +472,7 @@ OscIF::~OscIF() free(_uiOscProgramPath); if(_uiOscPath) free(_uiOscPath); - - //if(_oscControlFifos) - // delete[] _oscControlFifos; -} - -/* -//--------------------------------------------------------- -// oscFifo -//--------------------------------------------------------- - -OscControlFifo* OscIF::oscFifo(unsigned long i) const -{ - if(!_oscControlFifos) - return 0; - return &_oscControlFifos[i]; } -*/ //--------------------------------------------------------- // oscUpdate @@ -709,6 +631,9 @@ int OscIF::oscExiting(lo_arg**) // The gui is gone now, right? _oscGuiVisible = false; +// Just an attempt to really kill the process, an attempt to fix gui not re-showing after closing. Doesn't help. +/* +#ifdef _USE_QPROCESS_FOR_GUI_ if(_oscGuiQProc) { if(_oscGuiQProc->state()) @@ -730,10 +655,34 @@ int OscIF::oscExiting(lo_arg**) // so kill is not desirable. // We could wait until terminate finished but don't think that's good here. ///QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) ); + _oscGuiQProc->waitForFinished(3000); } //delete _oscGuiQProc; + //_oscGuiQProc = 0; } - + + +#else // NOT _USE_QPROCESS_FOR_GUI_ + + if(_guiPid != -1) + { + #ifdef OSC_DEBUG + printf("OscIF::oscExiting hanging up _guiPid:%d\n", _guiPid); + #endif + //if(kill(_guiPid, SIGHUP) != -1) + //if(kill(_guiPid, SIGTERM) != -1) + if(kill(_guiPid, SIGKILL) != -1) + { + #ifdef OSC_DEBUG + printf(" hang up sent\n"); + #endif + _guiPid = -1; + } + } + +#endif // _USE_QPROCESS_FOR_GUI_ +*/ + if(_uiOscTarget) lo_address_free(_uiOscTarget); _uiOscTarget = 0; @@ -756,9 +705,6 @@ int OscIF::oscExiting(lo_arg**) free(_uiOscPath); _uiOscPath = 0; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //const DSSI_Descriptor* dssi = synth->dssi; //const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin; //if(ld->deactivate) @@ -851,14 +797,22 @@ void OscIF::oscSendConfigure(const char *key, const char *val) // oscInitGui //--------------------------------------------------------- -//bool OscIF::oscInitGui() bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QString& name, const QString& label, const QString& filePath, const QString& guiPath) { // Are we already running? We don't want to allow another process do we... +#ifdef _USE_QPROCESS_FOR_GUI_ if((_oscGuiQProc != 0) && (_oscGuiQProc->state())) return true; +#else + if(_guiPid != -1) + return true; +#endif + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui\n"); + #endif + if(!url) { fprintf(stderr, "OscIF::oscInitGui no server url!\n"); @@ -871,198 +825,83 @@ bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QStrin return false; } - // - // start gui - // - //static char oscUrl[1024]; - //char oscUrl[1024]; QString oscUrl; - - //snprintf(oscUrl, 1024, "%s/%s/%s", url, baseName.ascii(), name.ascii()); - //snprintf(oscUrl, 1024, "%s%s/%s/%s", url, typ.toLatin1().constData(), baseName.toLatin1().constData(), name.toLatin1().constData()); - //oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TRANSLATE_NOOP("@default", url))).arg(typ).arg(baseName).arg(name); oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TRANSLATE_NOOP("@default", url))).arg(typ).arg(baseName).arg(label); - // Removed p4.0.19 Tim - /* - //QString guiPath(info.path() + "/" + info.baseName()); - //QString guiPath(synth->info.dirPath() + "/" + synth->info.baseName()); - QString guiPath(dirPath + "/" + baseName); + +#ifdef _USE_QPROCESS_FOR_GUI_ + + // fork + execlp cause the process to remain (zombie) after closing gui, requiring manual kill. + // Using QProcess works OK. + // No QProcess created yet? Do it now. Only once per SynthIF instance. Exists until parent destroyed. + if(_oscGuiQProc == 0) + //_oscGuiQProc = new QProcess(muse); + _oscGuiQProc = new QProcess(); + + QString program(guiPath); + QStringList arguments; + arguments << oscUrl + << filePath + << name + << QString("channel-1"); #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui guiPath:%s\n", guiPath.toLatin1().constData()); + fprintf(stderr, "OscIF::oscInitGui starting QProcess\n"); #endif - - QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files); - if (guiDir.exists()) + _oscGuiQProc->start(program, arguments); + + if(_oscGuiQProc->state()) { - //const QFileInfoList list = guiDir.entryInfoList(); - QStringList list = guiDir.entryList(); - - //for (int i = 0; i < list.size(); ++i) { - for (int i = 0; i < list.count(); ++i) - { - - //QFileInfo fi = list.at(i); - QFileInfo fi(guiPath + QString("/") + list[i]); - - QString gui(fi.filePath()); - if (gui.contains('_') == 0) - continue; - struct stat buf; - - //if (stat(gui.toAscii().data(), &buf)) { - if (stat(gui.toLatin1().constData(), &buf)) { - - perror("stat failed"); - continue; - } - - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui %s %s %s %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - fi.filePath().toLatin1().constData(), - //fi.fileName().ascii(), - - oscUrl.toLatin1().constData(), - - //synth->info.filePath().ascii(), - filePath.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii()); - name.toLatin1().constData()); - #endif - */ - - //if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) && - // (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - //{ - - // Changed by T356. - // fork + execlp were causing the processes to remain after closing gui, requiring manual kill. - // Changed to QProcess, works OK now. - //if((guiPid = fork()) == 0) - //{ - // No QProcess created yet? Do it now. Only once per SynthIF instance. Exists until parent destroyed. - if(_oscGuiQProc == 0) - //_oscGuiQProc = new QProcess(muse); - _oscGuiQProc = new QProcess(); - - //QString program(fi.filePath()); - QString program(guiPath); - QStringList arguments; - arguments << oscUrl - << filePath - << name - << QString("channel-1"); - - /* - fprintf(stderr, "OscIF::oscInitGui %s %s %s %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - guiPath.toLatin1().constData(), - //fi.fileName().ascii(), - - oscUrl.toLatin1().constData(), - - //synth->info.filePath().ascii(), - filePath.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii()); - name.toLatin1().constData()); - */ - - /* Leave out Qt3 stuff for reference - Orcan: - // Don't forget this, he he... - _oscGuiQProc->clearArguments(); - - _oscGuiQProc->addArgument(fi.filePath()); - //_oscGuiQProc->addArgument(fi.fileName()); // No conventional 'Arg0' here. - //_oscGuiQProc->addArgument(QString(oscUrl)); - _oscGuiQProc->addArgument(oscUrl); - //_oscGuiQProc->addArgument(synth->info.filePath()); - _oscGuiQProc->addArgument(filePath); - //_oscGuiQProc->addArgument(synth->name()); - _oscGuiQProc->addArgument(name); - _oscGuiQProc->addArgument(QString("channel-1")); - */ - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui starting QProcess\n"); - #endif - _oscGuiQProc->start(program, arguments); - - - if(_oscGuiQProc->state()) - { - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui started QProcess\n"); - #endif - - //guiPid = _oscGuiQProc->processIdentifier(); - } - else - { - - /* - execlp( - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - fi.filePath().ascii(), - fi.fileName().ascii(), - - oscUrl, - - //info.filePath().toAscii().data(), - //name().toAscii().data(), - synth->info.filePath().ascii(), - synth->name().ascii(), - - "channel 1", (void*)0); - */ - - fprintf(stderr, "exec %s %s %s failed: %s\n", - //fi.filePath().toAscii().data(), - //fi.fileName().toAscii().data(), - //fi.filePath().toLatin1().constData(), - guiPath.toLatin1().constData(), - //fi.fileName().toLatin1().constData(), - - oscUrl.toLatin1().constData(), - - //name().toAscii().data(), - //synth->name().ascii(), - name.toLatin1().constData(), - - strerror(errno)); - - // It's Ok, Keep going. So nothing happens. So what. The timeout in showGui will just leave. - // Maybe it's a 'busy' issue somewhere - allow to try again later + save work now. - //exit(1); + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui started QProcess\n"); + #endif + } + else + { + fprintf(stderr, "exec %s %s %s %s failed: %s\n", + guiPath.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + strerror(errno)); + //exit(1); + } + + #ifdef OSC_DEBUG + fprintf(stderr, "OscIF::oscInitGui after QProcess\n"); + #endif + +#else // NOT _USE_QPROCESS_FOR_GUI_ - } - - #ifdef OSC_DEBUG - fprintf(stderr, "OscIF::oscInitGui after QProcess\n"); - #endif - //} - //} - //} - //synth->_hasGui = true; - /* + #ifdef OSC_DEBUG + fprintf(stderr, "forking...\n"); + #endif + + QString guiName = QFileInfo(guiPath).fileName(); + // Note: fork + execlp cause the process to remain (zombie) after closing gui, requiring manual kill. Use QProcess instead. + if((_guiPid = fork()) == 0) + { + execlp( + guiPath.toLatin1().constData(), + guiName.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + "channel 1", (void*)0); + + // Should not return after execlp. If so it's an error. + fprintf(stderr, "exec %s %s %s %s %s failed: %s\n", + guiPath.toLatin1().constData(), + guiName.toLatin1().constData(), + oscUrl.toLatin1().constData(), + filePath.toLatin1().constData(), + name.toLatin1().constData(), + strerror(errno)); + //exit(1); } - else { - printf("OscIF::oscInitGui %s: no dir for gui found: %s\n", - //name().toAscii().data(), guiPath.toAscii().data()); - //synth->name().ascii(), guiPath.ascii()); - name.toLatin1().constData(), guiPath.toLatin1().constData()); - - //synth->_hasGui = false; - } - */ - + +#endif // _USE_QPROCESS_FOR_GUI_ + return true; } @@ -1080,8 +919,11 @@ void OscIF::oscShowGui(bool v) if (v == oscGuiVisible()) return; - //if(guiPid == -1) +#ifdef _USE_QPROCESS_FOR_GUI_ if((_oscGuiQProc == 0) || (!_oscGuiQProc->state())) +#else + if(_guiPid == -1) +#endif { // We need an indicator that update was called - update must have been called to get new path etc... // If the process is not running this path is invalid, right? @@ -1138,19 +980,9 @@ bool OscIF::oscGuiVisible() const // oscSetSynthIF //--------------------------------------------------------- -//void OscIF::oscSetSynthIF(DssiSynthIF* s) void OscDssiIF::oscSetSynthIF(DssiSynthIF* s) { _oscSynthIF = s; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //_oscControlFifos = 0; - - //if(_oscSynthIF && _oscSynthIF->dssiSynth()) - //{ - // unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); - // _oscControlFifos = new OscControlFifo[ports]; - //} } //--------------------------------------------------------- @@ -1172,58 +1004,6 @@ int OscDssiIF::oscUpdate(lo_arg **argv) if(_oscSynthIF) _oscSynthIF->oscUpdate(); - /* - if(_oscSynthIF) - { - // Send current string configuration parameters. - StringParamMap& map = _oscSynthIF->dssiSynthI()->stringParameters(); - int i = 0; - for(ciStringParamMap r = map.begin(); r != map.end(); ++r) - { - lo_send(_uiOscTarget, _uiOscConfigurePath, "ss", r->first.c_str(), r->second.c_str()); - // Avoid overloading the GUI if there are lots and lots of params. - if((i+1) % 50 == 0) - usleep(300000); - ++i; - } - - // Send current bank and program. - unsigned long bank, prog; - _oscSynthIF->dssiSynthI()->currentProg(&prog, &bank, 0); - lo_send(_uiOscTarget, _uiOscProgramPath, "ii", bank, prog); - - // Send current control values. - unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); - for(unsigned long i = 0; i < ports; ++i) - { - unsigned long k = _oscSynthIF->dssiSynth()->inControlPortIdx(i); - lo_send(_uiOscTarget, _uiOscControlPath, "if", k, _oscSynthIF->getParameter(i)); - // Avoid overloading the GUI if there are lots and lots of ports. - if((i+1) % 50 == 0) - usleep(300000); - } - } - */ - - /* - char uiOscGuiPath[strlen(_uiOscPath)+6]; - sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "show"); - - #ifdef OSC_DEBUG - printf("OscIF::oscUpdate Sending show uiOscGuiPath:%s\n", uiOscGuiPath); - #endif - - lo_send(_uiOscTarget, uiOscGuiPath, ""); - - sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "hide"); - - #ifdef OSC_DEBUG - printf("OscIF::oscUpdate Sending hide uiOscGuiPath:%s\n", uiOscGuiPath); - #endif - - lo_send(_uiOscTarget, uiOscGuiPath, ""); - */ - #if 0 /* Send current bank/program (-FIX- another race...) */ if (instance->pendingProgramChange < 0) { @@ -1256,8 +1036,6 @@ int OscDssiIF::oscUpdate(lo_arg **argv) int OscDssiIF::oscConfigure(lo_arg** argv) { - //OscIF::oscConfigure(argv); - if(_oscSynthIF) _oscSynthIF->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s); return 0; @@ -1269,8 +1047,6 @@ int OscDssiIF::oscConfigure(lo_arg** argv) int OscDssiIF::oscMidi(lo_arg** argv) { - //OscIF::oscMidi(argv); - if(_oscSynthIF) _oscSynthIF->oscMidi(argv[0]->m[1], argv[0]->m[2], argv[0]->m[3]); @@ -1283,8 +1059,6 @@ int OscDssiIF::oscMidi(lo_arg** argv) int OscDssiIF::oscProgram(lo_arg** argv) { - //OscIF::oscProgram(argv); - if(_oscSynthIF) _oscSynthIF->oscProgram(argv[1]->i, argv[0]->i); @@ -1297,8 +1071,6 @@ int OscDssiIF::oscProgram(lo_arg** argv) int OscDssiIF::oscControl(lo_arg** argv) { - //OscIF::oscControl(argv); - int port = argv[0]->i; if(port < 0) return 0; @@ -1319,8 +1091,7 @@ bool OscDssiIF::oscInitGui() return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "dssi_synth"), _oscSynthIF->dssiSynth()->baseName(), _oscSynthIF->dssiSynth()->name(), _oscSynthIF->dssiSynthI()->name(), - //_oscSynthIF->dssiSynth()->filePath(), _oscSynthIF->dssiSynth()->path()); - _oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename()); // p4.0.19 + _oscSynthIF->dssiSynth()->fileName(), _oscSynthIF->dssi_ui_filename()); } #endif // DSSI_SUPPORT @@ -1334,15 +1105,6 @@ bool OscDssiIF::oscInitGui() void OscEffectIF::oscSetPluginI(PluginI* s) { _oscPluginI = s; - //if(_oscControlFifos) - // delete[] _oscControlFifos; - //_oscControlFifos = 0; - - //if(_oscPluginI && _oscPluginI->plugin()) - //{ - // unsigned long ports = _oscPluginI->plugin()->controlInPorts(); - // _oscControlFifos = new OscControlFifo[ports]; - //} } //--------------------------------------------------------- @@ -1370,8 +1132,6 @@ int OscEffectIF::oscUpdate(lo_arg** argv) int OscEffectIF::oscConfigure(lo_arg** argv) { - //OscIF::oscConfigure(argv); - if(_oscPluginI) _oscPluginI->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s); @@ -1384,8 +1144,6 @@ int OscEffectIF::oscConfigure(lo_arg** argv) int OscEffectIF::oscControl(lo_arg** argv) { - //OscIF::oscControl(argv); - int port = argv[0]->i; if(port < 0) return 0; @@ -1406,8 +1164,7 @@ bool OscEffectIF::oscInitGui() return OscIF::oscInitGui(QT_TRANSLATE_NOOP("@default", "ladspa_efx"), _oscPluginI->plugin()->lib(false), _oscPluginI->plugin()->label(), _oscPluginI->label(), - //_oscPluginI->plugin()->filePath(), _oscPluginI->plugin()->dirPath(false)); - _oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename()); // p4.0.19 + _oscPluginI->plugin()->fileName(), _oscPluginI->dssi_ui_filename()); } diff --git a/muse2/muse/osc.h b/muse2/muse/osc.h index a0973ac7..8b6ba746 100644 --- a/muse2/muse/osc.h +++ b/muse2/muse/osc.h @@ -4,6 +4,7 @@ // $Id: osc.h,v 1.0.0.0 2010/04/22 10:05:00 terminator356 Exp $ // // Copyright (C) 1999-2011 by Werner Schweer and others +// (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 @@ -36,101 +37,10 @@ class QString; class PluginI; class OscIF; -/* -// Keep the OSC fifo small. There may be thousands of controls, and each control needs a fifo. -// Oops, no, if the user keeps adjusting a slider without releasing the mouse button, then all of the -// events are sent at once upon releasing the button, meaning there might be thousands of events at once. -#define OSC_FIFO_SIZE 512 - -//--------------------------------------------------------- -// OscControlValue -// Item struct for OscGuiControlFifo. -//--------------------------------------------------------- - -struct OscControlValue -{ - //int idx; - float value; - int frame; // Added p4.0.15 -}; - -//--------------------------------------------------------- -// OscControlFifo -// A fifo for each of the OSC controls. -//--------------------------------------------------------- - -class OscControlFifo -{ - OscControlValue fifo[OSC_FIFO_SIZE]; - volatile int size; - int wIndex; - int rIndex; - - public: - OscControlFifo() { clear(); } - bool put(const OscControlValue& event); // returns true on fifo overflow - OscControlValue get(); - const OscControlValue& peek(int n = 0); - void remove(); - bool isEmpty() const { return size == 0; } - void clear() { size = 0, wIndex = 0, rIndex = 0; } - int getSize() const { return size; } -}; -*/ - -//--------------------------------------------------------- -// OscIF -// Open Sound Control Interface -//--------------------------------------------------------- - -/* -class OscIF -{ - private: - PluginI* _oscPluginI; - - #ifdef DSSI_SUPPORT - DssiSynthIF* _oscSynthIF; - #endif - - QProcess* _oscGuiQProc; - void* _uiOscTarget; - char* _uiOscShowPath; - char* _uiOscControlPath; - char* _uiOscConfigurePath; - char* _uiOscProgramPath; - char* _uiOscPath; - bool _oscGuiVisible; - - OscControlFifo* _oscControlFifos; - - public: - OscIF(); - ~OscIF(); - - void oscSetPluginI(PluginI*); - - #ifdef DSSI_SUPPORT - void oscSetSynthIF(DssiSynthIF*); - #endif - - int oscUpdate(lo_arg**); - int oscProgram(lo_arg**); - int oscControl(lo_arg**); - int oscExiting(lo_arg**); - int oscMidi(lo_arg**); - int oscConfigure(lo_arg**); - - bool oscInitGui(); - void oscShowGui(bool); - bool oscGuiVisible() const; - OscControlFifo* oscFifo(unsigned long) const; -}; -*/ - class OscIF { protected: + pid_t _guiPid; QProcess* _oscGuiQProc; void* _uiOscTarget; char* _uiOscPath; @@ -141,8 +51,6 @@ class OscIF char* _uiOscShowPath; bool _oscGuiVisible; - //OscControlFifo* _oscControlFifos; - virtual bool oscInitGui(const QString& /*typ*/, const QString& /*baseName*/, const QString& /*name*/, const QString& /*label*/, const QString& /*filePath*/, const QString& /*guiPath*/); @@ -150,8 +58,6 @@ class OscIF OscIF(); virtual ~OscIF(); - //OscControlFifo* oscFifo(unsigned long) const; - virtual int oscUpdate(lo_arg**); virtual int oscProgram(lo_arg**) { return 0; } virtual int oscControl(lo_arg**) { return 0; } diff --git a/muse2/muse/part.h b/muse2/muse/part.h index d5b85b03..7042eedf 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -169,6 +169,11 @@ class PartList : public std::multimap<int, Part*, std::less<unsigned> > { void remove(Part* part); int index(Part*); Part* find(int idx); + void clearDelete() { + for (iPart i = begin(); i != end(); ++i) + delete i->second; + clear(); + } }; extern void chainClone(Part* p); diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 53e3d471..7205f482 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -4,6 +4,7 @@ // $Id: plugin.cpp,v 1.21.2.23 2009/12/15 22:07:12 spamatica Exp $ // // (C) Copyright 2000 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 @@ -770,6 +771,8 @@ Plugin::~Plugin() { //if(_portDescriptors) // delete[] _portDescriptors; + if(plugin) + delete plugin; } //--------------------------------------------------------- @@ -851,6 +854,8 @@ int Plugin::incReferences(int val) plugin = descr->LADSPA_Plugin; break; } + //else + // delete descr; } } else @@ -881,6 +886,8 @@ int Plugin::incReferences(int val) break; } + //else + // delete descr; } } } @@ -1106,8 +1113,10 @@ static void loadPluginLib(QFileInfo* fi) { // Make sure it doesn't already exist. if(plugins.find(fi->completeBaseName(), QString(descr->LADSPA_Plugin->Label)) != 0) + { + //delete descr; continue; - + } #ifdef PLUGIN_DEBUGIN fprintf(stderr, "loadPluginLib: dssi effect name:%s inPlaceBroken:%d\n", descr->LADSPA_Plugin->Name, LADSPA_IS_INPLACE_BROKEN(descr->LADSPA_Plugin->Properties)); #endif @@ -1120,6 +1129,8 @@ static void loadPluginLib(QFileInfo* fi) plugins.add(fi, descr->LADSPA_Plugin, true); } + //else + // delete descr; } } else @@ -1152,8 +1163,10 @@ static void loadPluginLib(QFileInfo* fi) // Make sure it doesn't already exist. if(plugins.find(fi->completeBaseName(), QString(descr->Label)) != 0) + { + //delete descr; continue; - + } #ifdef PLUGIN_DEBUGIN fprintf(stderr, "loadPluginLib: ladspa effect name:%s inPlaceBroken:%d\n", descr->Name, LADSPA_IS_INPLACE_BROKEN(descr->Properties)); #endif diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 2a98760e..00144610 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -4,6 +4,7 @@ // $Id: plugin.h,v 1.9.2.13 2009/12/06 01:25:21 terminator356 Exp $ // // (C) Copyright 2000 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 diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 6a43e457..a994b0e6 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -2341,6 +2341,8 @@ void Song::cleanupForQuit() printf("deleting midi devices except synths\n"); for(iMidiDevice imd = midiDevices.begin(); imd != midiDevices.end(); ++imd) { + // Close the device. Handy to do all devices here, including synths. + (*imd)->close(); // Since Syntis are midi devices, there's no need to delete them below. if((*imd)->isSynti()) continue; @@ -2373,12 +2375,16 @@ void Song::cleanupForQuit() continue; delete (*imi); } - midiInstruments.clear(); // midi devices + midiInstruments.clear(); // midi instruments // Nothing required for ladspa plugin list, and rack instances of them // are handled by ~AudioTrack. if(MusEGlobal::debugMsg) + printf("Muse: Deleting sound files\n"); + SndFile::sndFiles.clearDelete(); + + if(MusEGlobal::debugMsg) printf("...finished cleaning up.\n"); } diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 64ad928c..90e9beec 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -253,6 +253,11 @@ Track::Track(const Track& t, bool cloneParts) } } +Track::~Track() +{ + _parts.clearDelete(); +} + //--------------------------------------------------------- // operator = // Added by Tim. Parts' track members MUST point to this track, diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 1df73620..752a79be 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -105,7 +105,7 @@ class Track { Track(TrackType); //Track(const Track&); Track(const Track&, bool cloneParts); - virtual ~Track() {}; + virtual ~Track(); virtual Track& operator=(const Track& t); static const char* _cname[]; diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp index 731606d3..e9fa64d2 100644 --- a/muse2/muse/wave.cpp +++ b/muse2/muse/wave.cpp @@ -90,7 +90,7 @@ SndFile::~SndFile() delete finfo; if (cache) { for (unsigned i = 0; i < channels(); ++i) - delete cache[i]; + delete [] cache[i]; delete[] cache; cache = 0; } @@ -150,7 +150,7 @@ void SndFile::readCache(const QString& path, bool showProgress) if (cache) { for (unsigned i = 0; i < channels(); ++i) - delete cache[i]; + delete [] cache[i]; delete[] cache; } if (samples() == 0) { diff --git a/muse2/muse/wave.h b/muse2/muse/wave.h index 2f97e6c5..231ed7dc 100644 --- a/muse2/muse/wave.h +++ b/muse2/muse/wave.h @@ -42,18 +42,7 @@ struct SampleV { unsigned char rms; }; -//--------------------------------------------------------- -// SndFileList -//--------------------------------------------------------- - -class SndFile; -class SndFileList : public std::list<SndFile*> { - public: - SndFile* search(const QString& name); - }; - -typedef SndFileList::iterator iSndFile; -typedef SndFileList::const_iterator ciSndFile; +class SndFileList; //--------------------------------------------------------- // SndFile @@ -183,6 +172,23 @@ class SndFileR { }; +//--------------------------------------------------------- +// SndFileList +//--------------------------------------------------------- + +class SndFileList : public std::list<SndFile*> { + public: + SndFile* search(const QString& name); + void clearDelete() { + for (SndFileList::iterator i = begin(); i != end(); ++i) + delete *i; + clear(); + } + }; + +typedef SndFileList::iterator iSndFile; +typedef SndFileList::const_iterator ciSndFile; + #if 0 class Clip; diff --git a/muse2/muse/widgets/bigtime.cpp b/muse2/muse/widgets/bigtime.cpp index 572710e2..f4162041 100644 --- a/muse2/muse/widgets/bigtime.cpp +++ b/muse2/muse/widgets/bigtime.cpp @@ -334,6 +334,7 @@ void BigTime::setPos(int idx, unsigned v, bool) void BigTime::resizeEvent(QResizeEvent *ev) { + QWidget::resizeEvent(ev); dwin->resize(ev->size()); QFont f = dwin->font(); QFontMetrics fm(f); diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index c498bfd1..811561e3 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -82,6 +82,11 @@ Canvas::Canvas(QWidget* parent, int sx, int sy, const char* name) connect(song, SIGNAL(posChanged(int, unsigned, bool)), this, SLOT(setPos(int, unsigned, bool))); } +Canvas::~Canvas() +{ + items.clearDelete(); +} + //--------------------------------------------------------- // setPos // set one of three markers diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index 553ef407..954b865d 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -190,6 +190,7 @@ class Canvas : public View { void horizontalZoomOut(); public: Canvas(QWidget* parent, int sx, int sy, const char* name = 0); + virtual ~Canvas(); bool isSingleSelection(); int selectionSize(); Tool tool() const { return _tool; } diff --git a/muse2/muse/widgets/citem.h b/muse2/muse/widgets/citem.h index bdeca213..e2ddd8a0 100644 --- a/muse2/muse/widgets/citem.h +++ b/muse2/muse/widgets/citem.h @@ -101,6 +101,11 @@ class CItemList: public std::multimap<int, CItem*, std::less<int> > { public: void add(CItem*); CItem* find(const QPoint& pos) const; + void clearDelete() { + for (iCItem i = begin(); i != end(); ++i) + delete i->second; + clear(); + } }; } // namespace MusEWidget diff --git a/muse2/muse/widgets/knob.cpp b/muse2/muse/widgets/knob.cpp index 9bc63b33..ac035065 100644 --- a/muse2/muse/widgets/knob.cpp +++ b/muse2/muse/widgets/knob.cpp @@ -327,8 +327,9 @@ void Knob::rangeChange() // resizeEvent //--------------------------------------------------------- -void Knob::resizeEvent(QResizeEvent *) +void Knob::resizeEvent(QResizeEvent* ev) { + MusEWidget::SliderBase::resizeEvent(ev); int width, width_2; const QRect& r = rect(); diff --git a/muse2/muse/widgets/knob.h b/muse2/muse/widgets/knob.h index a629f158..257ff0c7 100644 --- a/muse2/muse/widgets/knob.h +++ b/muse2/muse/widgets/knob.h @@ -78,8 +78,8 @@ class Knob : public SliderBase, public ScaleIf void drawKnob(QPainter *p, const QRect &r); void drawMarker(QPainter *p, double arc, const QColor &c); - void paintEvent(QPaintEvent *); - void resizeEvent(QResizeEvent *e); + virtual void paintEvent(QPaintEvent *); + virtual void resizeEvent(QResizeEvent *e); double getValue(const QPoint &p); void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction ); void scaleChange() { repaint(); } diff --git a/muse2/muse/widgets/meter.cpp b/muse2/muse/widgets/meter.cpp index 50d265b5..590e7f65 100644 --- a/muse2/muse/widgets/meter.cpp +++ b/muse2/muse/widgets/meter.cpp @@ -35,8 +35,8 @@ #include "gconfig.h" #include "fastlog.h" -// Uncomment to use the new meters. Warning: They are currently very time-consuming and unoptimized. -#define _USE_NEW_METERS 1 +// Just an experiment. Some undesirable effects, see below... +//#define _USE_CLIPPER 1 namespace MusEWidget { @@ -50,18 +50,17 @@ Meter::Meter(QWidget* parent, MeterType type) setBackgroundRole(QPalette::NoRole); setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_StaticContents); - // This is absolutely required for speed! Otherwise painfully slow because we get - // full rect paint events even on small scrolls! See help on QPainter::scroll(). - // Commented out for now. Orcan 20110911 - #ifndef _USE_NEW_METERS + // This is absolutely required for speed! Otherwise painfully slow because of full background + // filling, even when requesting small udpdates! Background is drawn by us. (Just small corners.) setAttribute(Qt::WA_OpaquePaintEvent); - #endif //setFrameStyle(QFrame::Raised | QFrame::StyledPanel); mtype = type; overflow = false; cur_yv = -1; // Flag as -1 to initialize in paint. last_yv = 0; + cur_ymax = 0; + last_ymax = 0; val = 0.0; maxVal = 0.0; minScale = mtype == DBMeter ? MusEConfig::config.minMeter : 0.0; // min value in dB or int @@ -154,46 +153,51 @@ void Meter::setVal(double v, double max, bool ovl) } } + double range = maxScale - minScale; + int fw = frameWidth(); + int w = width() - 2*fw; + int h = height() - 2*fw; + QRect udRect; + bool udPeak = false; + if(maxVal != max) { maxVal = max; + if(mtype == DBMeter) + cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); + else + cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); + if(cur_ymax > h) cur_ymax = h; + // Not using regions. Just lump them together. + udRect = QRect(fw, last_ymax, w, 1) | QRect(fw, cur_ymax, w, 1); + //printf("Meter::setVal peak cur_ymax:%d last_ymax:%d\n", cur_ymax, last_ymax); + last_ymax = cur_ymax; ud = true; + udPeak = true; } if(ud) { - #ifdef _USE_NEW_METERS - update(); - - #else - double range = maxScale - minScale; - int fw = frameWidth(); - int w = width() - 2*fw; - int h = height() - 2*fw; - if(mtype == DBMeter) cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); else cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); - if(cur_yv > h) cur_yv = h; - + + //printf("Meter::setVal cur_yv:%d last_yv:%d\n", cur_yv, last_yv); int y1, y2; - if(last_yv < cur_yv) - { - y1 = last_yv; - y2 = cur_yv; - } - else - { - y1 = cur_yv; - y2 = last_yv; - } + if(last_yv < cur_yv) { y1 = last_yv; y2 = cur_yv; } else { y1 = cur_yv; y2 = last_yv; } last_yv = cur_yv; - update(fw, y1, w, y2); - #endif + + if(udPeak) + update(udRect | QRect(fw, y1, w, y2 - y1 + 1)); + //repaint(udRect | QRect(fw, y1, w, y2 - y1 + 1)); + else + update(QRect(fw, y1, w, y2 - y1 + 1)); + //repaint(QRect(fw, y1, w, y2 - y1 + 1)); } } + //--------------------------------------------------------- // resetPeaks // reset peak and overflow indicator @@ -203,6 +207,7 @@ void Meter::resetPeaks() { maxVal = val; overflow = val > 0.0; + cur_yv = -1; // Force re-initialization. update(); } @@ -224,69 +229,91 @@ void Meter::setRange(double min, double max) void Meter::paintEvent(QPaintEvent* ev) { - // TODO: Could make better use of event rectangle, for speed. - QPainter p(this); - #ifdef _USE_NEW_METERS p.setRenderHint(QPainter::Antialiasing); - #endif - + double range = maxScale - minScale; - int fw = frameWidth(); int w = width() - 2*fw; int h = height() - 2*fw; - const QRect& rect = ev->rect(); //printf("Meter::paintEvent rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h); - //p.setClipRect(rect); // Nope, didn't help (I think it's already clipped. So check why we bother to do it in View). + + QPainterPath drawingPath, updatePath, finalPath, cornerPath; + //bool updFull = false; // Initialize. Can't do in ctor, must be done after layouts have been done. Most reliable to do it here. - #ifndef _USE_NEW_METERS if(cur_yv == -1) - #endif { if(mtype == DBMeter) + { cur_yv = val == 0 ? h : int(((maxScale - (fast_log10(val) * 20.0)) * h)/range); + cur_ymax = maxVal == 0 ? fw : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); + } else + { cur_yv = val == 0 ? h : int(((maxScale - val) * h)/range); + cur_ymax = maxVal == 0 ? fw : int(((maxScale - maxVal) * h)/range); + } if(cur_yv > h) cur_yv = h; - //last_yv = cur_yv; + last_yv = cur_yv; + if(cur_ymax > h) cur_ymax = h; + last_ymax = cur_ymax; + //updFull = true; + updatePath.addRect(fw, fw, w, h); // Update the whole thing } + else + updatePath.addRect(rect.x(), rect.y(), rect.width(), rect.height()); // Update only the requested rectangle + + drawingPath.addRoundedRect(fw, fw, w, h, xrad, yrad); // The actual desired shape of the meter + finalPath = drawingPath & updatePath; + + // Draw corners as normal background colour. + cornerPath = updatePath - finalPath; // Elegantly simple. Path subtraction! Wee... + if(!cornerPath.isEmpty()) + p.fillPath(cornerPath, palette().window()); + +#ifdef _USE_CLIPPER + p.setClipPath(finalPath); // Meh, nice but not so good. Clips at edge so antialising has no effect! Can it be done ? +#endif // Draw the red, green, and yellow sections. - drawVU(p, rect, cur_yv); + drawVU(p, rect, finalPath, cur_yv); // Draw the peak white line. - int ymax; - if(mtype == DBMeter) - ymax = maxVal == 0 ? 0 : int(((maxScale - (fast_log10(maxVal) * 20.0)) * h)/range); - else - ymax = maxVal == 0 ? 0 : int(((maxScale - maxVal) * h)/range); - if(ymax >= rect.y() && ymax < rect.height()) + //if(updFull || (cur_ymax >= rect.y() && cur_ymax < rect.height())) { - p.setPen(peak_color); - p.drawLine(0, ymax, w, ymax); + p.setRenderHint(QPainter::Antialiasing, false); // No antialiasing. Makes the line fuzzy, double height, or not visible at all. + + //p.setPen(peak_color); + //p.drawLine(fw, cur_ymax, w, cur_ymax); // Undesirable. Draws outside the top rounded corners. + // + //QPainterPath path; path.moveTo(fw, cur_ymax); path.lineTo(w, cur_ymax); // ? Didn't work. No line at all. + //p.drawPath(path & finalPath); + QPainterPath path; path.addRect(fw, cur_ymax, w, 1); path &= finalPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(peak_color)); } - #ifdef _USE_NEW_METERS // Draw the transparent layer on top of everything to give a 3d look - QPainterPath round_path = MusEUtil::roundedPath(0, 0, w, h, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight | MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - maskGrad.setStart(QPointF(0, 0)); - maskGrad.setFinalStop(QPointF(w, 0)); - p.fillPath(round_path, QBrush(maskGrad)); - #endif + p.setRenderHint(QPainter::Antialiasing); + maskGrad.setStart(QPointF(fw, fw)); + maskGrad.setFinalStop(QPointF(w, fw)); +#ifdef _USE_CLIPPER + p.fillRect(rect, QBrush(maskGrad)); +#else + //QPainterPath path; path.addRect(fw, fw, w); + //p.fillPath(finalPath & path, QBrush(maskGrad)); + p.fillPath(finalPath, QBrush(maskGrad)); +#endif } - //--------------------------------------------------------- // drawVU //--------------------------------------------------------- -void Meter::drawVU(QPainter& p, const QRect& rect, int yv) +void Meter::drawVU(QPainter& p, const QRect& rect, const QPainterPath& drawPath, int yv) { int fw = frameWidth(); int w = width() - 2*fw; @@ -295,370 +322,219 @@ void Meter::drawVU(QPainter& p, const QRect& rect, int yv) // Test OK. We are passed small rectangles on small value changes. //printf("Meter::drawVU rx:%d ry:%d rw:%d rh:%d w:%d h:%d\n", rect.x(), rect.y(), rect.width(), rect.height(), w, h); - #ifdef _USE_NEW_METERS - - if(mtype == DBMeter) - { - double range = maxScale - minScale; - int y1 = int((maxScale - redScale) * h / range); - int y2 = int((maxScale - yellowScale) * h / range); - - darkGradGreen.setStart(QPointF(0, y2)); - darkGradGreen.setFinalStop(QPointF(0, h)); - darkGradYellow.setStart(QPointF(0, y1)); - darkGradYellow.setFinalStop(QPointF(0, y2)); - darkGradRed.setStart(QPointF(0, 0)); - darkGradRed.setFinalStop(QPointF(0, y1)); - - lightGradGreen.setStart(QPointF(0, y2)); - lightGradGreen.setFinalStop(QPointF(0, h)); - lightGradYellow.setStart(QPointF(0, y1)); - lightGradYellow.setFinalStop(QPointF(0, y2)); - lightGradRed.setStart(QPointF(0, 0)); - lightGradRed.setFinalStop(QPointF(0, y1)); - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < y1) - { - - QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark_red); - - // Red section: - p.fillPath(p_dark_red, QBrush(darkGradRed)); // dark red - p.fillPath(p_top, QBrush(lightGradRed)); // light red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(lightGradYellow)); // light yellow - - // Green section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - if(yv < y2) - { - // Red section: - p.fillPath(p_top, QBrush(darkGradRed)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, yv-y1, QBrush(darkGradYellow)); // dark yellow - p.fillRect(0, yv, w, y2-yv, QBrush(lightGradYellow)); // light yellow - - // Green section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - //if(yv <= y3) - { - QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light_green); - - // Red section: - p.fillPath(p_top, QBrush(darkGradRed)); // dark red - - // Yellow section: - p.fillRect(0, y1, w, y2-y1, QBrush(darkGradYellow)); // dark yellow - - // Green section: - p.fillPath(p_bottom, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light_green, QBrush(lightGradGreen)); // light green - } - - p.fillRect(0,y1, w, 1, separator_color); - p.fillRect(0,y2, w, 1, separator_color); - - } - else - { - darkGradGreen.setStart(QPointF(0, 0)); - darkGradGreen.setFinalStop(QPointF(0, h)); - - lightGradGreen.setStart(QPointF(0, 0)); - lightGradGreen.setFinalStop(QPointF(0, h)); - - // We need to draw the meter in two parts. The cutoff for upper rectangle can be - // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. - int cut = yrad; - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < cut) - { - - QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark); - - // top section: - p.fillPath(p_dark, QBrush(darkGradGreen)); // dark green - p.fillPath(p_top, QBrush(lightGradGreen)); // light green - - // bottom section: - p.fillPath(p_bottom, QBrush(lightGradGreen)); // light green - } - else - { - QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light); - - // top section: - p.fillPath(p_top, QBrush(darkGradGreen)); // dark green - - // bottom section: - p.fillPath(p_bottom, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light, QBrush(lightGradGreen)); // light green - } - - } - - /* WIP... - // TODO: Instead of drawing the whole area, make this respect the requested drawing rectangle, for speed... - // Done. But not correct yet. And could possibly simplify the whole drawing some more... QRect pr(0, 0, w, 0); - QPainterPath rectp; - rectp.addRect(rect.x(), rect.y(), rect.width(), rect.height()); - if(mtype == DBMeter) + if(mtype == DBMeter) // Meter type is dB... { double range = maxScale - minScale; int y1 = int((maxScale - redScale) * h / range); int y2 = int((maxScale - yellowScale) * h / range); - darkGradGreen.setStart(QPointF(0, y2)); - darkGradGreen.setFinalStop(QPointF(0, h)); - darkGradYellow.setStart(QPointF(0, y1)); - darkGradYellow.setFinalStop(QPointF(0, y2)); - darkGradRed.setStart(QPointF(0, 0)); - darkGradRed.setFinalStop(QPointF(0, y1)); - - lightGradGreen.setStart(QPointF(0, y2)); - lightGradGreen.setFinalStop(QPointF(0, h)); - lightGradYellow.setStart(QPointF(0, y1)); - lightGradYellow.setFinalStop(QPointF(0, y2)); - lightGradRed.setStart(QPointF(0, 0)); - lightGradRed.setFinalStop(QPointF(0, y1)); - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, y1, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, y2, w, h-y2, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - + darkGradGreen.setStart(QPointF(fw, y2)); + darkGradGreen.setFinalStop(QPointF(fw, h)); + darkGradYellow.setStart(QPointF(fw, y1)); + darkGradYellow.setFinalStop(QPointF(fw, y2)); + darkGradRed.setStart(QPointF(fw, fw)); + darkGradRed.setFinalStop(QPointF(fw, y1)); + + lightGradGreen.setStart(QPointF(fw, y2)); + lightGradGreen.setFinalStop(QPointF(fw, h)); + lightGradYellow.setStart(QPointF(fw, y1)); + lightGradYellow.setFinalStop(QPointF(fw, y2)); + lightGradRed.setStart(QPointF(fw, fw)); + lightGradRed.setFinalStop(QPointF(fw, y1)); + +#ifdef _USE_CLIPPER if(yv < y1) { - - QPainterPath p_dark_red = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark_red); - // Red section: - p.fillPath(p_dark_red & rectp, QBrush(darkGradRed)); // dark red - p.fillPath(p_top & rectp, QBrush(lightGradRed)); // light red - + pr.setTop(fw); pr.setHeight(yv); + p.fillRect(pr, QBrush(darkGradRed)); // dark red + pr.setTop(yv); pr.setHeight(y1-yv); + p.fillRect(pr & rect, QBrush(lightGradRed)); // light red + // Yellow section: pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow - + p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(h-y2); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } else if(yv < y2) { // Red section: - p.fillPath(p_top & rectp, QBrush(darkGradRed)); // dark red - + pr.setTop(fw); pr.setHeight(y1); + p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red + // Yellow section: pr.setTop(y1); pr.setHeight(yv-y1); - p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow + p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow pr.setTop(yv); pr.setHeight(y2-yv); - p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow - + p.fillRect(pr & rect, QBrush(lightGradYellow)); // light yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(h-y2); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } else //if(yv <= y3) { - QPainterPath p_light_green = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light_green); - // Red section: - p.fillPath(p_top & rectp, QBrush(darkGradRed)); // dark red - + pr.setTop(fw); pr.setHeight(y1); + p.fillRect(pr & rect, QBrush(darkGradRed)); // dark red + // Yellow section: pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow - + p.fillRect(pr & rect, QBrush(darkGradYellow)); // dark yellow + // Green section: - p.fillPath(p_bottom & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light_green & rectp, QBrush(lightGradGreen)); // light green + pr.setTop(y2); pr.setHeight(yv-y2); + p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green + pr.setTop(yv); pr.setHeight(h-yv); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green } - - pr.setTop(y1); pr.setHeight(1); - p.fillRect(pr & rect, separator_color); - pr.setTop(y2); //pr.setHeight(1); - p.fillRect(pr & rect, separator_color); - } - else + else // Meter type is linear... { - darkGradGreen.setStart(QPointF(0, 0)); - darkGradGreen.setFinalStop(QPointF(0, h)); - - lightGradGreen.setStart(QPointF(0, 0)); - lightGradGreen.setFinalStop(QPointF(0, h)); - - // We need to draw the meter in two parts. The cutoff for upper rectangle can be - // anywhere between yrad and h-yrad. Without loss of generality we pick the lower limit. - int cut = yrad; - - QPainterPath p_top = MusEUtil::roundedPath(0, 0, w, cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - QPainterPath p_bottom = MusEUtil::roundedPath(0, cut, w, h-cut, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - - if(yv < cut) - { - - QPainterPath p_dark = MusEUtil::roundedPath(0, 0, w, yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::UpperLeft | MusEUtil::UpperRight ) ); - - p_top = p_top.subtracted(p_dark); - - // top section: - p.fillPath(p_dark & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_top & rectp, QBrush(lightGradGreen)); // light green - - // bottom section: - p.fillPath(p_bottom & rectp, QBrush(lightGradGreen)); // light green - } - else - { - QPainterPath p_light = MusEUtil::roundedPath(0, yv, w, h-yv, - xrad, yrad, - (MusEUtil::Corner) (MusEUtil::LowerLeft | MusEUtil::LowerRight ) ); - p_bottom = p_bottom.subtracted(p_light); - - // top section: - p.fillPath(p_top & rectp, QBrush(darkGradGreen)); // dark green + pr.setTop(fw); pr.setHeight(yv); + p.fillRect(pr & rect, QBrush(darkGradGreen)); // dark green + pr.setTop(yv); pr.setHeight(h-yv); + p.fillRect(pr & rect, QBrush(lightGradGreen)); // light green + } - // bottom section: - p.fillPath(p_bottom & rectp, QBrush(darkGradGreen)); // dark green - p.fillPath(p_light & rectp, QBrush(lightGradGreen)); // light green - } +#else // NOT _USE_CLIPPER - } - */ - - #else - - QRect pr(0, 0, w, 0); - if(mtype == DBMeter) - { - double range = maxScale - minScale; - int y1 = int((maxScale - redScale) * h / range); - int y2 = int((maxScale - yellowScale) * h / range); - if(yv < y1) { // Red section: - pr.setTop(0); pr.setHeight(yv); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red - pr.setTop(yv); pr.setHeight(y1-yv); - p.fillRect(pr & rect, QBrush(0xff0000)); // light red + { + QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } + { + QPainterPath path; path.addRect(fw, yv, w, y1-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradRed)); // light red + } // Yellow section: - pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(0xffff00)); // light yellow + { + QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradYellow)); // light yellow + } // Green section: - pr.setTop(y2); pr.setHeight(h-y2); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } else if(yv < y2) { // Red section: - pr.setTop(0); pr.setHeight(y1); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red + { + QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } // Yellow section: - pr.setTop(y1); pr.setHeight(yv-y1); - p.fillRect(pr & rect, QBrush(0x8e8e00)); // dark yellow - pr.setTop(yv); pr.setHeight(y2-yv); - p.fillRect(pr & rect, QBrush(0xffff00)); // light yellow + { + QPainterPath path; path.addRect(fw, y1, w, yv-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradYellow)); // dark yellow + } + { + QPainterPath path; path.addRect(fw, yv, w, y2-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradYellow)); // light yellow + } // Green section: - pr.setTop(y2); pr.setHeight(h-y2); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, h-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } else //if(yv <= y3) { // Red section: - pr.setTop(0); pr.setHeight(y1); - p.fillRect(pr & rect, QBrush(0x8e0000)); // dark red + { + QPainterPath path; path.addRect(fw, fw, w, y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradRed)); // dark red + } // Yellow section: - pr.setTop(y1); pr.setHeight(y2-y1); - p.fillRect(pr & rect, QBrush(0x8e8e00)); // dark yellow + { + QPainterPath path; path.addRect(fw, y1, w, y2-y1); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradYellow)); // dark yellow + } // Green section: - pr.setTop(y2); pr.setHeight(yv-y2); - p.fillRect(pr & rect, QBrush(0x007000)); // dark green - pr.setTop(yv); pr.setHeight(h-yv); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green + { + QPainterPath path; path.addRect(fw, y2, w, yv-y2); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradGreen)); // dark green + } + { + QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } } + + // Separators: + { + QRect r(0, y1, w, 1); r &= rect; + if(!r.isNull()) + p.fillRect(r, separator_color); + } + { + QRect r(0, y2, w, 1); r &= rect; + if(!r.isNull()) + p.fillRect(r, separator_color); + } } - else + else // Meter type is linear... { - pr.setTop(0); pr.setHeight(yv); - p.fillRect(pr & rect, QBrush(0x007000)); // dark green - pr.setTop(yv); pr.setHeight(h-yv); - p.fillRect(pr & rect, QBrush(0x00ff00)); // light green - } - - #endif + darkGradGreen.setStart(QPointF(fw, fw)); + darkGradGreen.setFinalStop(QPointF(fw, h)); + + lightGradGreen.setStart(QPointF(fw, fw)); + lightGradGreen.setFinalStop(QPointF(fw, h)); + + { + QPainterPath path; path.addRect(fw, fw, w, yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(darkGradGreen)); // dark green + } + { + QPainterPath path; path.addRect(fw, yv, w, h-yv); path &= drawPath; + if(!path.isEmpty()) + p.fillPath(path, QBrush(lightGradGreen)); // light green + } + } + +#endif // NOT _USE_CLIPPER + } //--------------------------------------------------------- // resizeEvent //--------------------------------------------------------- -void Meter::resizeEvent(QResizeEvent* /*ev*/) +void Meter::resizeEvent(QResizeEvent* ev) { + QFrame::resizeEvent(ev); cur_yv = -1; // Force re-initialization. } diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h index ba816319..1de3841f 100644 --- a/muse2/muse/widgets/meter.h +++ b/muse2/muse/widgets/meter.h @@ -32,6 +32,7 @@ class QResizeEvent; class QMouseEvent; class QPainter; +class QPainterPath; namespace MusEWidget { @@ -75,6 +76,10 @@ class Meter : public QFrame { QColor peak_color; int xrad, yrad; + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent*); + private: MeterType mtype; bool overflow; @@ -82,13 +87,9 @@ class Meter : public QFrame { double maxVal; double minScale, maxScale; int yellowScale, redScale; - int cur_yv, last_yv; + int cur_yv, last_yv, cur_ymax, last_ymax; - void drawVU(QPainter& p, const QRect&, int); - - void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent*); - void mousePressEvent(QMouseEvent*); + void drawVU(QPainter& p, const QRect&, const QPainterPath&, int); public slots: void resetPeaks(); diff --git a/muse2/muse/widgets/mtrackinfo.cpp b/muse2/muse/widgets/mtrackinfo.cpp index e4c4e217..56429879 100644 --- a/muse2/muse/widgets/mtrackinfo.cpp +++ b/muse2/muse/widgets/mtrackinfo.cpp @@ -2,6 +2,7 @@ // MusE // Linux Music Editor // (C) Copyright 2010 Werner Schweer and others (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 @@ -21,6 +22,9 @@ #include <QTimer> #include <QMessageBox> +#include <QLinearGradient> +#include <QPalette> +#include <QColor> #include <math.h> #include <string.h> @@ -60,8 +64,10 @@ void MidiTrackInfo::setTrack(Track* t) if(!t->isMidiTrack()) return; selected = t; + + trackNameLabel->setObjectName(selected->cname()); - QPalette pal; + /*QPalette pal; if(selected->type() == Track::DRUM) { pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.drumTrackLabelBg); iOutputChannel->setEnabled(false); @@ -69,7 +75,8 @@ void MidiTrackInfo::setTrack(Track* t) pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); iOutputChannel->setEnabled(true); } - trackNameLabel->setPalette(pal); + trackNameLabel->setPalette(pal); */ + //setLabelText(); updateTrackInfo(-1); } @@ -97,10 +104,7 @@ MidiTrackInfo::MidiTrackInfo(QWidget* parent, Track* sel_track) : QWidget(parent //iChanDetectLabel->setPixmap(*darkgreendotIcon); iChanDetectLabel->setPixmap(*darkRedLedIcon); - QIcon recEchoIconSet; - recEchoIconSet.addPixmap(*midiThruOnIcon, QIcon::Normal, QIcon::On); - recEchoIconSet.addPixmap(*midiThruOffIcon, QIcon::Normal, QIcon::Off); - recEchoButton->setIcon(recEchoIconSet); + recEchoButton->setIcon((selected && ((MidiTrack*)selected)->recEcho()) ? QIcon(*midiThruOnIcon) : QIcon(*midiThruOffIcon)); recEchoButton->setIconSize(midiThruOnIcon->size()); // MusE-2: AlignCenter and WordBreak are set in the ui(3) file, but not supported by QLabel. Turn them on here. @@ -114,14 +118,26 @@ MidiTrackInfo::MidiTrackInfo(QWidget* parent, Track* sel_track) : QWidget(parent if(selected) { trackNameLabel->setObjectName(selected->cname()); - QPalette pal; + + /*QPalette pal; + QColor c; //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue if(selected->type() == Track::DRUM) - pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.drumTrackLabelBg); + c = MusEConfig::config.drumTrackLabelBg; else - pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); - trackNameLabel->setPalette(pal); - } + c = MusEConfig::config.midiTrackLabelBg; + + QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + pal.setBrush(trackNameLabel->backgroundRole(), gradient); + trackNameLabel->setPalette(pal); */ + } //else //{ // pal.setColor(trackNameLabel->backgroundRole(), MusEConfig::config.midiTrackLabelBg); @@ -543,6 +559,28 @@ void MidiTrackInfo::setLabelText() trackNameLabel->setText(track->name()); else trackNameLabel->setText(QString()); + + if(track) + { + QPalette pal; + QColor c; + //pal.setColor(trackNameLabel->backgroundRole(), QColor(0, 160, 255)); // Med blue + if(track->type() == Track::DRUM) + c = MusEConfig::config.drumTrackLabelBg; + else + c = MusEConfig::config.midiTrackLabelBg; + + QLinearGradient gradient(trackNameLabel->geometry().topLeft(), trackNameLabel->geometry().bottomLeft()); + //gradient.setColorAt(0, c.darker()); + //gradient.setColorAt(0, c); + //gradient.setColorAt(1, c.darker()); + gradient.setColorAt(0, c.lighter()); + gradient.setColorAt(1, c); + //palette.setBrush(QPalette::Button, gradient); + //palette.setBrush(QPalette::Window, gradient); + pal.setBrush(trackNameLabel->backgroundRole(), gradient); + trackNameLabel->setPalette(pal); + } } //--------------------------------------------------------- @@ -1340,6 +1378,8 @@ void MidiTrackInfo::updateTrackInfo(int flags) recEchoButton->setChecked(track->recEcho()); recEchoButton->blockSignals(false); } + recEchoButton->setIcon(track->recEcho() ? QIcon(*midiThruOnIcon) : QIcon(*midiThruOffIcon)); + //recEchoButton->setIconSize(midiThruOnIcon->size()); } int outChannel = track->outChannel(); @@ -1566,4 +1606,12 @@ void MidiTrackInfo::recordClicked() } } +void MidiTrackInfo::resizeEvent(QResizeEvent* ev) +{ + //printf("MidiTrackInfo::resizeEvent\n"); + QWidget::resizeEvent(ev); + setLabelText(); + setLabelFont(); +} + } // namespace MusEWidget diff --git a/muse2/muse/widgets/mtrackinfo.h b/muse2/muse/widgets/mtrackinfo.h index 42be1f58..42bcb2bf 100644 --- a/muse2/muse/widgets/mtrackinfo.h +++ b/muse2/muse/widgets/mtrackinfo.h @@ -2,6 +2,7 @@ // MusE // Linux Music Editor // (C) Copyright 2010 Werner Schweer and others (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 @@ -40,7 +41,10 @@ class MidiTrackInfo : public QWidget, public Ui::MidiTrackInfoBase int program, pan, volume; int heartBeatCounter; - private slots: + protected: + virtual void resizeEvent(QResizeEvent*); + + private slots: void iOutputChannelChanged(int); void iOutputPortChanged(int); void iProgHBankChanged(); diff --git a/muse2/muse/widgets/posedit.cpp b/muse2/muse/widgets/posedit.cpp index 0e031c38..772d434a 100644 --- a/muse2/muse/widgets/posedit.cpp +++ b/muse2/muse/widgets/posedit.cpp @@ -77,11 +77,11 @@ class PosEditor : public QLineEdit protected: void init(); - bool event(QEvent *e); - void resizeEvent(QResizeEvent*); - void paintEvent(QPaintEvent*); - void mousePressEvent(QMouseEvent *e); - void keyPressEvent(QKeyEvent * event ); + virtual bool event(QEvent *e); + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent *e); + virtual void keyPressEvent(QKeyEvent * event ); void applyFocusSelection() {} public: @@ -817,8 +817,9 @@ void PosEdit::removeLastNumber(int secNo) // resizeEvent //--------------------------------------------------------- -void PosEdit::resizeEvent(QResizeEvent *) +void PosEdit::resizeEvent(QResizeEvent* ev) { + QWidget::resizeEvent(ev); controls->resize(width(), height()); } diff --git a/muse2/muse/widgets/posedit.h b/muse2/muse/widgets/posedit.h index 3224a3a6..5f763f51 100644 --- a/muse2/muse/widgets/posedit.h +++ b/muse2/muse/widgets/posedit.h @@ -74,9 +74,9 @@ class PosEdit : public QWidget void returnPressed(); protected: - bool event(QEvent *e ); + virtual bool event(QEvent *e ); void timerEvent(QTimerEvent* e); - void resizeEvent(QResizeEvent*); + virtual void resizeEvent(QResizeEvent*); QString sectionFormattedText(int sec); void addNumber(int sec, int num); void removeLastNumber(int sec); diff --git a/muse2/muse/widgets/scrollscale.cpp b/muse2/muse/widgets/scrollscale.cpp index 21ed10b6..572a1d86 100644 --- a/muse2/muse/widgets/scrollscale.cpp +++ b/muse2/muse/widgets/scrollscale.cpp @@ -197,9 +197,10 @@ void ScrollScale::setPosNoLimit ( unsigned pos ) // resizeEvent //--------------------------------------------------------- -void ScrollScale::resizeEvent ( QResizeEvent* ) +void ScrollScale::resizeEvent ( QResizeEvent* ev) { - setScale ( scale->value() ); + QWidget::resizeEvent(ev); + setScale ( scale->value() ); } //--------------------------------------------------------- @@ -223,6 +224,7 @@ ScrollScale::ScrollScale ( int s1, int s2, int cs, int max_, Qt::Orientation o, down = 0; logbase = bas; invers = inv; + scaleVal = 0; double min, max; if ( scaleMin < 0 ) diff --git a/muse2/muse/widgets/sigedit.cpp b/muse2/muse/widgets/sigedit.cpp index c2c5a842..a952cfef 100644 --- a/muse2/muse/widgets/sigedit.cpp +++ b/muse2/muse/widgets/sigedit.cpp @@ -103,11 +103,11 @@ class SigEditor : public QLineEdit protected: void init(); - bool event(QEvent *e); - void resizeEvent(QResizeEvent*); - void paintEvent(QPaintEvent*); - void mousePressEvent(QMouseEvent *e); - void keyPressEvent(QKeyEvent * event ); + virtual bool event(QEvent *e); + virtual void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void mousePressEvent(QMouseEvent *e); + virtual void keyPressEvent(QKeyEvent * event ); void applyFocusSelection() {} public: @@ -699,9 +699,10 @@ void SigEdit::removeLastNumber(int secNo) // resizeEvent //--------------------------------------------------------- -void SigEdit::resizeEvent(QResizeEvent *) +void SigEdit::resizeEvent(QResizeEvent* ev) { - controls->resize(width(), height()); + QWidget::resizeEvent(ev); + controls->resize(width(), height()); } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/sigedit.h b/muse2/muse/widgets/sigedit.h index 3b1ca635..05684db1 100644 --- a/muse2/muse/widgets/sigedit.h +++ b/muse2/muse/widgets/sigedit.h @@ -72,9 +72,9 @@ class SigEdit : public QWidget void returnPressed(); protected: - bool event(QEvent *e ); + virtual bool event(QEvent *e ); void timerEvent(QTimerEvent* e); - void resizeEvent(QResizeEvent*); + virtual void resizeEvent(QResizeEvent*); QString sectionFormattedText(int sec); void addNumber(int sec, int num); void removeLastNumber(int sec); diff --git a/muse2/muse/widgets/siglabel.cpp b/muse2/muse/widgets/siglabel.cpp index 9916bd0a..f571c2f1 100644 --- a/muse2/muse/widgets/siglabel.cpp +++ b/muse2/muse/widgets/siglabel.cpp @@ -43,12 +43,12 @@ namespace MusEWidget { // edit Signature Values (4/4) //--------------------------------------------------------- -SigLabel::SigLabel(int z, int n, QWidget* parent) : QLabel(parent) +SigLabel::SigLabel(int zz, int nn, QWidget* parent) : QLabel(parent) { - z = n = 0; + z = n = 0; setFocusPolicy(Qt::NoFocus); setAlignment(Qt::AlignCenter); - setValue(z, n); + setValue(zz, nn); } SigLabel::SigLabel(const AL::TimeSignature& sig, QWidget* parent) : QLabel(parent) diff --git a/muse2/muse/widgets/slider.cpp b/muse2/muse/widgets/slider.cpp index 593b3df6..863933d2 100644 --- a/muse2/muse/widgets/slider.cpp +++ b/muse2/muse/widgets/slider.cpp @@ -580,7 +580,7 @@ void Slider::paintEvent(QPaintEvent* /*ev*/) void Slider::resizeEvent(QResizeEvent *e) { - + MusEWidget::SliderBase::resizeEvent(e); d_resized = TRUE; QSize s = e->size(); /* Scale is not supported diff --git a/muse2/muse/widgets/slider.h b/muse2/muse/widgets/slider.h index 5a2bff71..b1281da0 100644 --- a/muse2/muse/widgets/slider.h +++ b/muse2/muse/widgets/slider.h @@ -79,8 +79,8 @@ class Slider : public SliderBase, public ScaleIf virtual void drawSlider (QPainter *p, const QRect &r); double getValue(const QPoint &p); void getScrollMode( QPoint &p, const Qt::MouseButton &button, int &scrollMode, int &direction); - void resizeEvent(QResizeEvent *e); - void paintEvent (QPaintEvent *e); + virtual void resizeEvent(QResizeEvent *e); + virtual void paintEvent (QPaintEvent *e); void valueChange(); void rangeChange(); void scaleChange(); diff --git a/muse2/muse/widgets/swidget.cpp b/muse2/muse/widgets/swidget.cpp index f8461977..51796781 100644 --- a/muse2/muse/widgets/swidget.cpp +++ b/muse2/muse/widgets/swidget.cpp @@ -32,7 +32,8 @@ namespace MusEWidget { void SWidget::resizeEvent(QResizeEvent* ev) { - emit heightChanged(ev->size().height()); + QWidget::resizeEvent(ev); + emit heightChanged(ev->size().height()); } } // namespace MusEWidget diff --git a/muse2/muse/widgets/tools.cpp b/muse2/muse/widgets/tools.cpp index ccd0f89b..113de6c4 100644 --- a/muse2/muse/widgets/tools.cpp +++ b/muse2/muse/widgets/tools.cpp @@ -129,7 +129,7 @@ void EditToolBar::toolChanged(QAction* action) EditToolBar::~EditToolBar() { - delete actions; + delete [] actions; } //--------------------------------------------------------- diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index c900f3b6..41c5a180 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -167,7 +167,6 @@ QString bitmap2String(int bm) //--------------------------------------------------------- // u32bitmap2String //--------------------------------------------------------- -// Added by Tim. p3.3.8 QString u32bitmap2String(unsigned int bm) { @@ -274,7 +273,6 @@ int string2bitmap(const QString& str) //--------------------------------------------------------- // string2u32bitmap //--------------------------------------------------------- -// Added by Tim. p3.3.8 unsigned int string2u32bitmap(const QString& str) { @@ -343,7 +341,6 @@ unsigned int string2u32bitmap(const QString& str) // ignoreWidth: Set if dealing with a vertically constrained widget - one which is free to resize horizontally. // ignoreHeight: Set if dealing with a horizontally constrained widget - one which is free to resize vertically. //--------------------------------------------------------- -// Added by Tim. p3.3.8 bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool ignoreHeight, int max, int min) { @@ -373,12 +370,10 @@ bool autoAdjustFontSize(QFrame* w, const QString& s, bool ignoreWidth, bool igno if((ignoreWidth || (r.width() <= (cr.width() - extra))) && (ignoreHeight || (r.height() <= cr.height()))) break; } - // Added by Tim. p3.3.9 //printf("autoAdjustFontSize: ptsz:%d widget:%s before setFont x:%d y:%d w:%d h:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height()); // Here we will always have a font ranging from min to max point size. w->setFont(fnt); - // Added by Tim. p3.3.9 //printf("autoAdjustFontSize: ptsz:%d widget:%s x:%d y:%d w:%d h:%d frame w:%d rw:%d rh:%d\n", fnt.pointSize(), w->name(), w->x(), w->y(), w->width(), w->height(), w->frameWidth(), cr.width(), cr.height()); // Force minimum height. Use the expected height for the highest given point size. diff --git a/muse2/muse/widgets/verticalmeter.cpp b/muse2/muse/widgets/verticalmeter.cpp index 74b4b695..4553b156 100644 --- a/muse2/muse/widgets/verticalmeter.cpp +++ b/muse2/muse/widgets/verticalmeter.cpp @@ -333,8 +333,9 @@ void VerticalMeter::drawVU(QPainter& p, int w, int h, int xv) // resizeEvent //--------------------------------------------------------- -void VerticalMeter::resizeEvent(QResizeEvent* /*ev*/) +void VerticalMeter::resizeEvent(QResizeEvent* ev) { + MusEWidget::Meter::resizeEvent(ev); } } // namespace MusEWidget diff --git a/muse2/muse/widgets/verticalmeter.h b/muse2/muse/widgets/verticalmeter.h index d6bee245..024ecc10 100644 --- a/muse2/muse/widgets/verticalmeter.h +++ b/muse2/muse/widgets/verticalmeter.h @@ -47,8 +47,8 @@ class VerticalMeter : public Meter { void drawVU(QPainter& p, int, int, int); - void paintEvent(QPaintEvent*); - void resizeEvent(QResizeEvent*); + virtual void paintEvent(QPaintEvent*); + virtual void resizeEvent(QResizeEvent*); public slots: void resetPeaks(); diff --git a/muse2/muse/widgets/view.cpp b/muse2/muse/widgets/view.cpp index 9be66ed5..8a9d82b4 100644 --- a/muse2/muse/widgets/view.cpp +++ b/muse2/muse/widgets/view.cpp @@ -290,8 +290,9 @@ void View::setYPos(int y) // resizeEvent //--------------------------------------------------------- -void View::resizeEvent(QResizeEvent* /*ev*/) +void View::resizeEvent(QResizeEvent* ev) { + QWidget::resizeEvent(ev); #ifdef VIEW_USE_DOUBLE_BUFFERING //pm.resize(ev->size()); //printf("View::resizeEvent width:%d height:%d\n", diff --git a/muse2/muse/widgets/visibletracks.cpp b/muse2/muse/widgets/visibletracks.cpp index 1b549975..7e56bb36 100644 --- a/muse2/muse/widgets/visibletracks.cpp +++ b/muse2/muse/widgets/visibletracks.cpp @@ -139,7 +139,7 @@ void VisibleTracks::visibilityChanged(QAction* action) VisibleTracks::~VisibleTracks() { - delete actions; + delete [] actions; } } // namespace MusEWidget diff --git a/muse2/synti/deicsonze/deicsonzegui.h b/muse2/synti/deicsonze/deicsonzegui.h index f82e072b..7dec344f 100644 --- a/muse2/synti/deicsonze/deicsonzegui.h +++ b/muse2/synti/deicsonze/deicsonzegui.h @@ -526,10 +526,10 @@ class QFramePitchEnvelope:private QFrame { void env2Points(int pl1, int pl2, int pl3, int pr1, int pr2, int pr3); void updateEnv(void) {update();}; protected: - void paintEvent(QPaintEvent* e); - void mouseMoveEvent(QMouseEvent* e); - void mousePressEvent(QMouseEvent * e); - void mouseReleaseEvent(QMouseEvent * e); + virtual void paintEvent(QPaintEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void mousePressEvent(QMouseEvent * e); + virtual void mouseReleaseEvent(QMouseEvent * e); }; class QFrameEnvelope:private QFrame { diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp index a03c5da8..cc5c496a 100644 --- a/muse2/synti/fluidsynth/fluidsynti.cpp +++ b/muse2/synti/fluidsynth/fluidsynti.cpp @@ -115,6 +115,17 @@ FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) FluidSynth::~FluidSynth() { + + for (std::list<FluidSoundFont>::iterator it =stack.begin(); it !=stack.end(); it++) + { + if(it->intid == FS_UNSPECIFIED_FONT || it->intid == FS_UNSPECIFIED_ID) + continue; + //Try to unload soundfont + int err = fluid_synth_sfunload(fluidsynth, it->intid, 0); + if(err == -1) + std::cerr << DEBUG_ARGS << "Error unloading soundfont!" << fluid_synth_error(fluidsynth) << std::endl; + } + int err = delete_fluid_synth (fluidsynth); if(gui) delete gui; |