qtractor: rework patches to what was submitted

Signed-off-by: Andreas Müller <schnitzeltony@gmail.com>
This commit is contained in:
Andreas Müller
2017-11-06 19:28:45 +01:00
parent e18b6869be
commit 2e9013a5b2
6 changed files with 2667 additions and 332 deletions

View File

@@ -1,330 +0,0 @@
From fff172e17a9b718403948fac449c877cdeb046b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@googlemail.com>
Date: Wed, 18 Oct 2017 23:39:57 +0200
Subject: [PATCH] MIDI import: give tracks more informational names
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Name is created by the following sequence - if name is not empty stop:
* If supplied, set track name found in MIDI file
* Try General MIDI names
* Set name of clip imported (usually shortened MIDI file name)
Upstream-Status: Submitted [1]
https://github.com/rncbc/qtractor/pull/86
Signed-off-by: Andreas Müller <schnitzeltony@googlemail.com>
---
src/qtractorMainForm.cpp | 2 +-
src/qtractorMidiClip.cpp | 11 +++
src/qtractorMidiClip.h | 6 ++
src/qtractorTracks.cpp | 181 +++++++++++++++++++++++++++++++++++++++++++++--
src/qtractorTracks.h | 6 +-
5 files changed, 200 insertions(+), 6 deletions(-)
diff --git a/src/qtractorMainForm.cpp b/src/qtractorMainForm.cpp
index 0fbb649..b3c0f76 100644
--- a/src/qtractorMainForm.cpp
+++ b/src/qtractorMainForm.cpp
@@ -3787,7 +3787,7 @@ void qtractorMainForm::trackImportMidi (void)
const unsigned long iClipStart = m_pSession->editHead();
qtractorTrack *pTrack = m_pTracks->currentTrack();
m_pTracks->addMidiTracks(
- m_pFiles->midiListView()->openFileNames(), iClipStart, pTrack);
+ m_pFiles->midiListView()->openFileNames(), iClipStart, pTrack, true);
m_pTracks->trackView()->ensureVisibleFrame(iClipStart);
}
}
diff --git a/src/qtractorMidiClip.cpp b/src/qtractorMidiClip.cpp
index 5928846..8af1d73 100644
--- a/src/qtractorMidiClip.cpp
+++ b/src/qtractorMidiClip.cpp
@@ -346,6 +346,7 @@ bool qtractorMidiClip::openMidiFile (
// Set local properties...
setFilename(sFilename);
setDirty(false);
+ m_sTrackNameRead.clear();
// Register file path...
pSession->files()->addClipItem(qtractorFileList::Midi, this, bWrite);
@@ -476,6 +477,10 @@ bool qtractorMidiClip::openMidiFile (
// We should have events, otherwise this clip is of no use...
//if (m_pSeq->events().count() < 1)
// return false;
+
+ // If MIDI file sets track name: keep it
+ m_sTrackNameRead = pSeq->name();
+
// And initial clip name...
pSeq->setName(shortClipName(QFileInfo(m_pFile->filename()).baseName()));
}
@@ -514,6 +519,12 @@ bool qtractorMidiClip::openMidiFile (
}
+QString qtractorMidiClip::getTrackName (void)
+{
+ return m_sTrackNameRead;
+}
+
+
// Private cleanup.
void qtractorMidiClip::closeMidiFile (void)
{
diff --git a/src/qtractorMidiClip.h b/src/qtractorMidiClip.h
index f47528f..f45d1cc 100644
--- a/src/qtractorMidiClip.h
+++ b/src/qtractorMidiClip.h
@@ -60,6 +60,9 @@ public:
bool openMidiFile(const QString& sFilename, int iTrackChannel = 0,
int iMode = qtractorMidiFile::Read);
+ // Track name a read MIDI file has set
+ QString getTrackName();
+
// MIDI file properties accessors.
void setTrackChannel(unsigned short iTrackChannel)
{ m_iTrackChannel = iTrackChannel; }
@@ -306,6 +309,9 @@ private:
QPoint m_posEditor;
QSize m_sizeEditor;
+ // Track name read from MIDI
+ QString m_sTrackNameRead;
+
// Default MIDI file format (for capture/record)
static unsigned short g_iDefaultFormat;
};
diff --git a/src/qtractorTracks.cpp b/src/qtractorTracks.cpp
index 9b9c4c4..7cac92e 100644
--- a/src/qtractorTracks.cpp
+++ b/src/qtractorTracks.cpp
@@ -2803,7 +2803,7 @@ bool qtractorTracks::addAudioTracks ( const QStringList& files,
// Import MIDI files into new tracks...
bool qtractorTracks::addMidiTracks ( const QStringList& files,
- unsigned long iClipStart, qtractorTrack *pAfterTrack )
+ unsigned long iClipStart, qtractorTrack *pAfterTrack, bool bEnhancedTrackNames )
{
// Have we some?
if (files.isEmpty())
@@ -2877,10 +2877,27 @@ bool qtractorTracks::addMidiTracks ( const QStringList& files,
}
// Time to check whether there is actual data on track...
if (pMidiClip->clipLength() > 0) {
+ int iChannel = pMidiClip->channel();
+ // create track name
+ QString sTrackName;
+ if (bEnhancedTrackNames) {
+ // try track name from MIDI import
+ sTrackName = pMidiClip->getTrackName();
+ // no track name set try GM names
+ if (sTrackName.isEmpty()) {
+ QString sGMName = getGMName(iChannel, pMidiClip->prog());
+ if (!sGMName.isEmpty())
+ sTrackName = sGMName;
+ }
+ }
+ // default: shortened clip name
+ if (sTrackName.isEmpty())
+ sTrackName = pSession->uniqueTrackName(pMidiClip->clipName());
+
// Add the new track to composite command...
- pTrack->setTrackName(
- pSession->uniqueTrackName(pMidiClip->clipName()));
- pTrack->setMidiChannel(pMidiClip->channel());
+ pTrack->setTrackName(sTrackName);
+ pTrack->setMidiChannel(iChannel);
+
pImportTrackCommand->addTrack(pTrack);
++iUpdate;
// Don't forget to add this one to local repository.
@@ -2984,6 +3001,162 @@ bool qtractorTracks::addMidiTrackChannel ( const QString& sPath,
}
+// MIDI specific: Get a GM name for channel/prog
+QString qtractorTracks::getGMName( int iChannel, int iProg )
+{
+ QString sName;
+ // static GM prog names
+ // no need to use numbers for multiple insstuments with same name
+ static const QStringList instrumentNamesGM = (
+ QStringList()
+ // 0-31
+ << QObject::tr("Acoustic Grand Piano")
+ << QObject::tr("Bright Acoustic Piano")
+ << QObject::tr("Electric Grand Piano")
+ << QObject::tr("Honky-tonk Piano")
+ << QObject::tr("Electric Piano")
+ << QObject::tr("Electric Piano")
+ << QObject::tr("Harpsichord")
+ << QObject::tr("Clavi")
+ << QObject::tr("Celesta")
+ << QObject::tr("Glockenspiel")
+ << QObject::tr("Music Box")
+ << QObject::tr("Vibraphone")
+ << QObject::tr("Marimba")
+ << QObject::tr("Xylophone")
+ << QObject::tr("Tubular Bells")
+ << QObject::tr("Dulcimer")
+ << QObject::tr("Organ")
+ << QObject::tr("Organ")
+ << QObject::tr("Rock Organ")
+ << QObject::tr("Church Organ")
+ << QObject::tr("Reed Organ")
+ << QObject::tr("Accordion")
+ << QObject::tr("Harmonica")
+ << QObject::tr("Tango Accordion")
+ << QObject::tr("Nylon Guitar")
+ << QObject::tr("Steel Guitar")
+ << QObject::tr("Jazz E-Guitar")
+ << QObject::tr("Clean E-Guitar")
+ << QObject::tr("Muted E-Guitar")
+ << QObject::tr("Overdrive Guitar")
+ << QObject::tr("Distorted Guitar")
+ << QObject::tr("Harmonic Guitar")
+ // 32-63
+ << QObject::tr("Acoustic Bass")
+ << QObject::tr("Fingered E-Bass")
+ << QObject::tr("Picked E-Bass")
+ << QObject::tr("Fretless Bass")
+ << QObject::tr("Slap Bass")
+ << QObject::tr("Slap Bass")
+ << QObject::tr("Synth Bass")
+ << QObject::tr("Synth Bass")
+ << QObject::tr("Violin")
+ << QObject::tr("Viola")
+ << QObject::tr("Cello")
+ << QObject::tr("Contrabass")
+ << QObject::tr("Tremolo")
+ << QObject::tr("Pizicato")
+ << QObject::tr("Harp")
+ << QObject::tr("Timpani")
+ << QObject::tr("Strings")
+ << QObject::tr("Strings")
+ << QObject::tr("Synth Strings")
+ << QObject::tr("Synth Strings")
+ << QObject::tr("Choir Aah")
+ << QObject::tr("Voice Ooh")
+ << QObject::tr("Synth Voice")
+ << QObject::tr("Hit Orchestra")
+ << QObject::tr("Trumpet")
+ << QObject::tr("Trombone")
+ << QObject::tr("Tuba")
+ << QObject::tr("Trumpet Muted")
+ << QObject::tr("French Horn")
+ << QObject::tr("Brass")
+ << QObject::tr("Synth Brass")
+ << QObject::tr("SynthBrass")
+ // 64-95
+ << QObject::tr("Soprano Sax")
+ << QObject::tr("Alto Sax")
+ << QObject::tr("Tenor Sax")
+ << QObject::tr("Baritone Sax")
+ << QObject::tr("Oboe")
+ << QObject::tr("Horn")
+ << QObject::tr("Bassoon")
+ << QObject::tr("Clarinet")
+ << QObject::tr("Piccolo")
+ << QObject::tr("Flute")
+ << QObject::tr("Recorder")
+ << QObject::tr("Pan Flute")
+ << QObject::tr("Smashing Bottle")
+ << QObject::tr("Shakuhachi")
+ << QObject::tr("Whistle")
+ << QObject::tr("Ocarina")
+ << QObject::tr("Square Lead")
+ << QObject::tr("Saw Lead")
+ << QObject::tr("Callilope Lead")
+ << QObject::tr("Chiffer Lead")
+ << QObject::tr("Charang Lead")
+ << QObject::tr("Voice Lead")
+ << QObject::tr("5th Lead")
+ << QObject::tr("Lead And Bass")
+ << QObject::tr("New Age Pad")
+ << QObject::tr("Warm Pad")
+ << QObject::tr("Polysynth Pad")
+ << QObject::tr("Choir Pad")
+ << QObject::tr("Bowed Pad")
+ << QObject::tr("Metallic Pad")
+ << QObject::tr("Halo Pad")
+ << QObject::tr("Sweep Pad")
+ // 96-127
+ << QObject::tr("Rain")
+ << QObject::tr("Soundtrack")
+ << QObject::tr("Crystal")
+ << QObject::tr("Atmosphere")
+ << QObject::tr("Brightness")
+ << QObject::tr("Goblins")
+ << QObject::tr("Echoes")
+ << QObject::tr("Sci-Fi")
+ << QObject::tr("Sitar")
+ << QObject::tr("Banjo")
+ << QObject::tr("Shamisen")
+ << QObject::tr("Koto")
+ << QObject::tr("Kalimba")
+ << QObject::tr("Bagpipe")
+ << QObject::tr("Fiddle")
+ << QObject::tr("Shanai")
+ << QObject::tr("Tinkle Bell")
+ << QObject::tr("Agogo")
+ << QObject::tr("Steel Drums")
+ << QObject::tr("Wood Block")
+ << QObject::tr("Taiko Drum")
+ << QObject::tr("Melodic Drum")
+ << QObject::tr("Synth Drum")
+ << QObject::tr("Reverse Cymbal")
+ << QObject::tr("Fretless Noise")
+ << QObject::tr("Breath Noise")
+ << QObject::tr("Seashore")
+ << QObject::tr("Birds")
+ << QObject::tr("Oldschool Telephone")
+ << QObject::tr("Helicopter")
+ << QObject::tr("Applause")
+ << QObject::tr("Gun Shot")
+ );
+
+ int iNameCount = instrumentNamesGM.size();
+ Q_ASSERT(iNameCount == 128);
+
+ // Drums (channel 10 - we keep data zero based)
+ if (iChannel == 9)
+ sName = QObject::tr("Drums");
+ // Instruments program name
+ else if (iProg >= 0 && iProg < iNameCount)
+ sName = instrumentNamesGM[iProg];
+
+ return sName;
+}
+
+
// Track-list active maintenance update.
void qtractorTracks::updateTrack ( qtractorTrack *pTrack )
{
diff --git a/src/qtractorTracks.h b/src/qtractorTracks.h
index 2d9fa48..c45b12a 100644
--- a/src/qtractorTracks.h
+++ b/src/qtractorTracks.h
@@ -71,10 +71,14 @@ public:
bool addAudioTracks(const QStringList& files,
unsigned long iClipStart, qtractorTrack *pAfterTrack = NULL);
bool addMidiTracks(const QStringList& files,
- unsigned long iClipStart, qtractorTrack *pAfterTrack = NULL);
+ unsigned long iClipStart, qtractorTrack *pAfterTrack = NULL,
+ bool bEnhancedTrackNames = false);
bool addMidiTrackChannel(const QString& sPath, int iTrackChannel,
unsigned long iClipStart, qtractorTrack *pAfterTrack = NULL);
+ // MIDI specific: GM instrument names
+ static QString getGMName(int iChannel, int iProg);
+
// Track-list active maintenance update.
void updateTrack(qtractorTrack *pTrack = NULL);
--
2.9.5

View File

@@ -0,0 +1,248 @@
From dad78145c4c427d44ad63caaa15966e8fe5693bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@googlemail.com>
Date: Sat, 4 Nov 2017 11:59:47 +0100
Subject: [PATCH 1/4] Make plugin-lists and MIDI-manager-list thread-safe
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
During debugging (PC) and testing (RaspberryPi) the MIDI import dialog, qtractor
crashed several times with segfaults due to inconsistent list state (the MIDI-
manager case was mentioned in [1]). Since adding plugins to MIDI import the
probabilty of these crashes increases because of performing 'dangerous'
operations multiple times.
To avoid this, lock/unlock guards were added under the following consideration:
Keep the locking time as short as possible to reduce the probability of
blocking audio-engine. For the implemetation qtractorSession::lock got a
parameter 'bStabilize' set true by default. If set to false, no events are
performed to avoid plugin-list-view updates with inconsistent data.
Worth to mention: With this modification no more crashes happend.
[1] https://github.com/rncbc/qtractor/issues/91
Upstream-Status: Submitted [2]
[2] https://github.com/rncbc/qtractor/pull/94
Signed-off-by: Andreas Müller <schnitzeltony@googlemail.com>
---
src/qtractorPlugin.cpp | 40 +++++++++++++++++++++++++++++++++-------
src/qtractorPluginCommand.cpp | 16 ----------------
src/qtractorSession.cpp | 14 +++++++++++---
src/qtractorSession.h | 2 +-
4 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/src/qtractorPlugin.cpp b/src/qtractorPlugin.cpp
index e547381..651f603 100644
--- a/src/qtractorPlugin.cpp
+++ b/src/qtractorPlugin.cpp
@@ -1620,10 +1620,17 @@ void qtractorPluginList::insertPlugin (
// We'll get prepared before plugging it in...
pPlugin->setChannels(m_iChannels);
+ qtractorSession *pSession = qtractorSession::getInstance();
+ if (pSession == NULL)
+ return;
+
+ // Do not perform events while locking - list views are not yet updated.
+ pSession->lock(false);
if (pNextPlugin)
insertBefore(pPlugin, pNextPlugin);
else
append(pPlugin);
+ pSession->unlock();
// Now update each observer list-view...
QListIterator<qtractorPluginListView *> iter(m_views);
@@ -1654,13 +1661,15 @@ void qtractorPluginList::movePlugin (
if (pPluginList == NULL)
return;
- // Remove and insert back again...
+ qtractorSession *pSession = qtractorSession::getInstance();
+ if (pSession == NULL)
+ return;
+
+ // Do not perform events while locking - list views are not yet updated.
+ pSession->lock(false);
+ // Remove it -> it is no more processed by worker thread.
pPluginList->unlink(pPlugin);
- if (pNextPlugin) {
- insertBefore(pPlugin, pNextPlugin);
- } else {
- append(pPlugin);
- }
+ pSession->unlock();
// DANGER: Gasp, we might be not the same...
if (pPluginList != this) {
@@ -1713,6 +1722,16 @@ void qtractorPluginList::movePlugin (
pListView->setCurrentItem(pNextItem);
}
+ // Views are updated so perform events during lock.
+ pSession->lock();
+ // Insert back again -> processing continues.
+ if (pNextPlugin) {
+ insertBefore(pPlugin, pNextPlugin);
+ } else {
+ append(pPlugin);
+ }
+ pSession->unlock();
+
// update (both) lists for Auto-plugin-deactivation
autoDeactivatePlugins(m_bAutoDeactivated, true);
if (pPluginList != this)
@@ -1723,8 +1742,15 @@ void qtractorPluginList::movePlugin (
// Remove-guarded plugin method.
void qtractorPluginList::removePlugin ( qtractorPlugin *pPlugin )
{
- // Just unlink the plugin from the list...
+ qtractorSession *pSession = qtractorSession::getInstance();
+ if (pSession == NULL)
+ return;
+
+ // Views are not touched here so perform events.
+ pSession->lock();
+ // Remove it -> it is no more processed by worker thread.
unlink(pPlugin);
+ pSession->unlock();
if (pPlugin->isActivated())
updateActivated(false);
diff --git a/src/qtractorPluginCommand.cpp b/src/qtractorPluginCommand.cpp
index 10bd717..c4321ca 100644
--- a/src/qtractorPluginCommand.cpp
+++ b/src/qtractorPluginCommand.cpp
@@ -65,8 +65,6 @@ bool qtractorPluginCommand::addPlugins (void)
if (pSession == NULL)
return false;
-// pSession->lock();
-
// Add all listed plugins, in order...
QListIterator<qtractorPlugin *> iter(m_plugins);
while (iter.hasNext()) {
@@ -78,8 +76,6 @@ bool qtractorPluginCommand::addPlugins (void)
// Avoid the disposal of the plugin reference(s).
setAutoDelete(false);
-// pSession->unlock();
-
return true;
}
@@ -91,8 +87,6 @@ bool qtractorPluginCommand::removePlugins (void)
if (pSession == NULL)
return false;
-// pSession->lock();
-
// Unlink all listed plugins, in order...
QListIterator<qtractorPlugin *> iter(m_plugins);
iter.toBack();
@@ -105,8 +99,6 @@ bool qtractorPluginCommand::removePlugins (void)
// Allow the disposal of the plugin reference(s).
setAutoDelete(true);
-// pSession->unlock();
-
return true;
}
@@ -284,8 +276,6 @@ bool qtractorInsertPluginCommand::redo (void)
if (pPluginList == NULL)
return false;
-// pSession->lock();
-
qtractorPlugin *pNextPlugin = pPlugin->next();
// Insert it...
@@ -297,8 +287,6 @@ bool qtractorInsertPluginCommand::redo (void)
// Whether to allow the disposal of the plugin reference.
setAutoDelete(false);
-// pSession->unlock();
-
return true;
}
@@ -317,8 +305,6 @@ bool qtractorInsertPluginCommand::undo (void)
if (pPluginList == NULL)
return false;
-// pSession->lock();
-
qtractorPlugin *pNextPlugin = pPlugin->next();
// Insert it...
@@ -330,8 +316,6 @@ bool qtractorInsertPluginCommand::undo (void)
// Whether to allow the disposal of the plugin reference.
setAutoDelete(true);
-// pSession->unlock();
-
return true;
}
diff --git a/src/qtractorSession.cpp b/src/qtractorSession.cpp
index bc901d6..19e72b3 100644
--- a/src/qtractorSession.cpp
+++ b/src/qtractorSession.cpp
@@ -1250,13 +1250,17 @@ void qtractorSession::release (void)
}
-void qtractorSession::lock (void)
+void qtractorSession::lock (bool bStabilize)
{
// Wind up as pending lock...
if (ATOMIC_INC(&m_locks) == 1) {
// Get lost for a while...
- while (!acquire())
- stabilize();
+ while (!acquire()) {
+ if (bStabilize)
+ stabilize();
+ else
+ QThread::yieldCurrentThread();
+ }
}
}
@@ -1901,12 +1905,16 @@ void qtractorSession::resetAllMidiControllers ( bool bForceImmediate )
// MIDI manager list accessors.
void qtractorSession::addMidiManager ( qtractorMidiManager *pMidiManager )
{
+ lock();
m_midiManagers.append(pMidiManager);
+ unlock();
}
void qtractorSession::removeMidiManager ( qtractorMidiManager *pMidiManager )
{
+ lock();
m_midiManagers.remove(pMidiManager);
+ unlock();
}
diff --git a/src/qtractorSession.h b/src/qtractorSession.h
index 151096e..821fa5b 100644
--- a/src/qtractorSession.h
+++ b/src/qtractorSession.h
@@ -229,7 +229,7 @@ public:
// Session RT-safe pseudo-locking primitives.
bool acquire();
void release();
- void lock();
+ void lock(bool bStabilize = false);
void unlock();
// Re-entrancy check.
--
2.9.5

View File

@@ -0,0 +1,164 @@
From b8ef1130bee18e5a28340c21941d67bd14949b2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@googlemail.com>
Date: Sat, 4 Nov 2017 20:41:50 +0100
Subject: [PATCH 2/4] Add qtractorPluginListDocument to save/load plugin-lists
to XML
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For MIDI Import dialog it is necessary to save/load plugin-lists. The easiest
way to do is to reuse the code used when saving/loading sessions. To perform
save/load only on plugin-lists an own document class has to be created.
Upstream-Status: Submitted [1]
[1] https://github.com/rncbc/qtractor/pull/94
Signed-off-by: Andreas Müller <schnitzeltony@googlemail.com>
---
src/qtractorPluginListDocument.cpp | 54 ++++++++++++++++++++++++++++++++++++++
src/qtractorPluginListDocument.h | 49 ++++++++++++++++++++++++++++++++++
src/src.pro | 2 ++
3 files changed, 105 insertions(+)
create mode 100644 src/qtractorPluginListDocument.cpp
create mode 100644 src/qtractorPluginListDocument.h
diff --git a/src/qtractorPluginListDocument.cpp b/src/qtractorPluginListDocument.cpp
new file mode 100644
index 0000000..4b895ed
--- /dev/null
+++ b/src/qtractorPluginListDocument.cpp
@@ -0,0 +1,54 @@
+// qtractorPluginListDocument.cpp
+//
+/****************************************************************************
+ Copyright (C) 2005-2017, rncbc aka Rui Nuno Capela. All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*****************************************************************************/
+
+#include "qtractorPluginListDocument.h"
+#include "qtractorPlugin.h"
+
+
+// Constructor.
+qtractorPluginListDocument::qtractorPluginListDocument(
+ QDomDocument *pDocument, qtractorPluginList *pPluginList)
+ : qtractorDocument(pDocument, "qtractorPluginList"),
+ m_pPluginList(pPluginList)
+
+{
+
+}
+
+
+// Destructor.
+qtractorPluginListDocument::~qtractorPluginListDocument()
+{
+}
+
+
+bool qtractorPluginListDocument::loadElement(QDomElement *pElement)
+{
+ return m_pPluginList->loadElement(this, pElement);
+}
+
+
+bool qtractorPluginListDocument::saveElement(QDomElement *pElement)
+{
+ return m_pPluginList->saveElement(this, pElement);
+}
+
+// end of qtractorPluginListDocument.cpp
diff --git a/src/qtractorPluginListDocument.h b/src/qtractorPluginListDocument.h
new file mode 100644
index 0000000..57464d7
--- /dev/null
+++ b/src/qtractorPluginListDocument.h
@@ -0,0 +1,49 @@
+// qtractorPluginListDocument.h
+//
+/****************************************************************************
+ Copyright (C) 2005-2017, rncbc aka Rui Nuno Capela. All rights reserved.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+*****************************************************************************/
+
+#ifndef __qtractorPluginListDocument_h
+#define __qtractorPluginListDocument_h
+
+#include "qtractorDocument.h"
+
+// Forward declarations.
+class qtractorPluginList;
+
+class qtractorPluginListDocument : public qtractorDocument
+{
+public:
+
+ // Constructor.
+ qtractorPluginListDocument(QDomDocument *pDocument, qtractorPluginList *pPluginList);
+ // Destructor.
+ ~qtractorPluginListDocument();
+
+ // External storage element overrides.
+ virtual bool loadElement (QDomElement *pElement);
+ virtual bool saveElement (QDomElement *pElement);
+
+private:
+ qtractorPluginList *m_pPluginList;
+};
+
+#endif // __qtractorPluginListDocument_h
+
+// end of qtractorPluginListDocument.h
diff --git a/src/src.pro b/src/src.pro
index 5e43fa7..92c0bd8 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -94,6 +94,7 @@ HEADERS += config.h \
qtractorPlugin.h \
qtractorPluginFactory.h \
qtractorPluginCommand.h \
+ qtractorPluginListDocument.h \
qtractorPluginListView.h \
qtractorPropertyCommand.h \
qtractorRingBuffer.h \
@@ -218,6 +219,7 @@ SOURCES += \
qtractorPlugin.cpp \
qtractorPluginFactory.cpp \
qtractorPluginCommand.cpp \
+ qtractorPluginListDocument.cpp \
qtractorPluginListView.cpp \
qtractorRubberBand.cpp \
qtractorScrollView.cpp \
--
2.9.5

View File

@@ -0,0 +1,167 @@
From e509eef8b5653796acb44bdd187db6574ed39da8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@googlemail.com>
Date: Sun, 5 Nov 2017 00:58:28 +0100
Subject: [PATCH 3/4] qtractorImportTrackCommand: extend to accept
qtractorEditTrackCommand
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is neccessary to align tracks during import the way track modifications
are performed.
* m_trackCommands is now a list of qtractorCommand. This is necessary because
qtractorEditTrackCommand is not inheriting qtractorTrackCommand.
* qtractorImportTrackCommand::addTrackEditCommand is added
* declaration of qtractorEditTrackCommand is moved before
qtractorImportTrackCommand to avoid useless forward declarations. This makes
the diff a bit human-unreadable.
Upstream-Status: Submitted [1]
[1] https://github.com/rncbc/qtractor/pull/94
Signed-off-by: Andreas Müller <schnitzeltony@googlemail.com>
---
src/qtractorTrackCommand.cpp | 15 +++++++++----
src/qtractorTrackCommand.h | 51 ++++++++++++++++++++++----------------------
2 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/src/qtractorTrackCommand.cpp b/src/qtractorTrackCommand.cpp
index b1a720e..959b566 100644
--- a/src/qtractorTrackCommand.cpp
+++ b/src/qtractorTrackCommand.cpp
@@ -653,6 +653,13 @@ void qtractorImportTrackCommand::addTrack ( qtractorTrack *pTrack )
m_pAfterTrack = pTrack;
}
+void qtractorImportTrackCommand::addTrackEditCommand(
+ qtractorEditTrackCommand *pEditTrackCommand)
+{
+ if (pEditTrackCommand)
+ m_trackCommands.append(pEditTrackCommand);
+}
+
// Track-import command methods.
bool qtractorImportTrackCommand::redo (void)
@@ -665,9 +672,9 @@ bool qtractorImportTrackCommand::redo (void)
}
++m_iSaveCount;
- QListIterator<qtractorAddTrackCommand *> iter(m_trackCommands);
+ QListIterator<qtractorCommand *> iter(m_trackCommands);
while (iter.hasNext()) {
- qtractorAddTrackCommand *pTrackCommand = iter.next();
+ qtractorCommand *pTrackCommand = iter.next();
if (!pTrackCommand->redo())
bResult = false;
}
@@ -679,10 +686,10 @@ bool qtractorImportTrackCommand::undo (void)
{
bool bResult = true;
- QListIterator<qtractorAddTrackCommand *> iter(m_trackCommands);
+ QListIterator<qtractorCommand *> iter(m_trackCommands);
iter.toBack();
while (iter.hasPrevious()) {
- qtractorAddTrackCommand *pTrackCommand = iter.previous();
+ qtractorCommand *pTrackCommand = iter.previous();
if (!pTrackCommand->undo())
bResult = false;
}
diff --git a/src/qtractorTrackCommand.h b/src/qtractorTrackCommand.h
index 0746fba..ab15218 100644
--- a/src/qtractorTrackCommand.h
+++ b/src/qtractorTrackCommand.h
@@ -191,61 +191,62 @@ private:
//----------------------------------------------------------------------
-// class qtractorInportTracksCommand - declaration.
+// class qtractorEditTrackCommand - declaration.
//
-class qtractorImportTrackCommand : public qtractorCommand
+class qtractorEditTrackCommand
+ : public qtractorPropertyCommand<qtractorTrack::Properties>
{
public:
// Constructor.
- qtractorImportTrackCommand(qtractorTrack *pAfterTrack);
-
- // Destructor.
- ~qtractorImportTrackCommand();
-
- // Add track to command list.
- void addTrack(qtractorTrack *pTrack);
+ qtractorEditTrackCommand(qtractorTrack *pTrack,
+ const qtractorTrack::Properties& props);
- // Track-import command methods.
+ // Overridden track-edit command methods.
bool redo();
bool undo();
private:
// Instance variables.
- qtractorTrack *m_pAfterTrack;
-
- QList<qtractorAddTrackCommand *> m_trackCommands;
-
- // Session properties backup stuff.
- qtractorSession::Properties m_sessionProps;
- qtractorPropertyCommand<qtractorSession::Properties> *m_pSaveCommand;
- int m_iSaveCount;
+ qtractorTrack *m_pTrack;
};
//----------------------------------------------------------------------
-// class qtractorEditTrackCommand - declaration.
+// class qtractorInportTracksCommand - declaration.
//
-class qtractorEditTrackCommand
- : public qtractorPropertyCommand<qtractorTrack::Properties>
+class qtractorImportTrackCommand : public qtractorCommand
{
public:
// Constructor.
- qtractorEditTrackCommand(qtractorTrack *pTrack,
- const qtractorTrack::Properties& props);
+ qtractorImportTrackCommand(qtractorTrack *pAfterTrack);
- // Overridden track-edit command methods.
+ // Destructor.
+ ~qtractorImportTrackCommand();
+
+ // Add track to command list.
+ void addTrack(qtractorTrack *pTrack);
+ // Add track edit command to command list.
+ void addTrackEditCommand(qtractorEditTrackCommand* pEditTrackCommand);
+
+ // Track-import command methods.
bool redo();
bool undo();
private:
// Instance variables.
- qtractorTrack *m_pTrack;
+ qtractorTrack *m_pAfterTrack;
+ QList<qtractorCommand *> m_trackCommands;
+
+ // Session properties backup stuff.
+ qtractorSession::Properties m_sessionProps;
+ qtractorPropertyCommand<qtractorSession::Properties> *m_pSaveCommand;
+ int m_iSaveCount;
};
--
2.9.5

View File

@@ -23,9 +23,12 @@ SRC_URI = " \
file://0002-do-nor-try-run-for-float-sse-detection.patch \
file://0003-do-nor-try-run-for-suil-libs-detection.patch \
file://0004-Add-ARM-NEON-acceleration-for-time-stretch-not-yet-t.patch \
file://0005-MIDI-import-give-tracks-more-informational-names.patch \
file://0005-Make-plugin-lists-and-MIDI-manager-list-thread-safe.patch \
file://0006-Add-qtractorPluginListDocument-to-save-load-plugin-l.patch \
file://0007-qtractorImportTrackCommand-extend-to-accept-qtractor.patch \
file://0008-Optionally-enhance-MIDI-import.patch \
"
SRCREV = "4af19b298679e4d80ee2496ecf0175526f894919"
SRCREV = "1152ce6c8e64c76e5fadff59ca9e84aa6a647a9a"
PV = "0.8.4+git${SRCPV}"
S = "${WORKDIR}/git"