summaryrefslogtreecommitdiff
path: root/muse2/muse/arranger
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-09-14 19:33:40 +0000
committerFlorian Jung <flo@windfisch.org>2011-09-14 19:33:40 +0000
commit58033553a3e7d529a27a2b3d9ccc721d1e2dcc17 (patch)
tree160bd9993bca91b68475d4ad4249cc07b89692dd /muse2/muse/arranger
parent42269af2e0cc7a8c7b70d89ffa270184acde3dec (diff)
parent2529ef06d1227b457af051a494ddb579ef590fe3 (diff)
merged experimental into trunk
new features: - MDI user interface - improved pasting (dialogs etc) - some fixes
Diffstat (limited to 'muse2/muse/arranger')
-rw-r--r--muse2/muse/arranger/CMakeLists.txt2
-rw-r--r--muse2/muse/arranger/arranger.cpp22
-rw-r--r--muse2/muse/arranger/arranger.h10
-rw-r--r--muse2/muse/arranger/arrangerview.cpp726
-rw-r--r--muse2/muse/arranger/arrangerview.h156
-rw-r--r--muse2/muse/arranger/pcanvas.cpp354
-rw-r--r--muse2/muse/arranger/pcanvas.h14
-rw-r--r--muse2/muse/arranger/tlist.cpp171
8 files changed, 1234 insertions, 221 deletions
diff --git a/muse2/muse/arranger/CMakeLists.txt b/muse2/muse/arranger/CMakeLists.txt
index af6a30b5..d81d92c6 100644
--- a/muse2/muse/arranger/CMakeLists.txt
+++ b/muse2/muse/arranger/CMakeLists.txt
@@ -27,6 +27,7 @@
QT4_WRAP_CPP (arranger_mocs
alayout.h
arranger.h
+ arrangerview.h
pcanvas.h
tlist.h
)
@@ -37,6 +38,7 @@ QT4_WRAP_CPP (arranger_mocs
file (GLOB arranger_source_files
alayout.cpp
arranger.cpp
+ arrangerview.cpp
pcanvas.cpp
tlist.cpp
)
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp
index 3052d7d4..09e67151 100644
--- a/muse2/muse/arranger/arranger.cpp
+++ b/muse2/muse/arranger/arranger.cpp
@@ -38,6 +38,7 @@
#include <QWheelEvent>
#include <QPainter>
//#include <QStackedWidget>
+#include "arrangerview.h"
#include "arranger.h"
#include "song.h"
@@ -111,7 +112,7 @@ void Arranger::setHeaderWhatsThis()
// is the central widget in app
//---------------------------------------------------------
-Arranger::Arranger(QMainWindow* parent, const char* name)
+Arranger::Arranger(ArrangerView* parent, const char* name)
: QWidget(parent)
{
setObjectName(name);
@@ -122,11 +123,12 @@ Arranger::Arranger(QMainWindow* parent, const char* name)
///program = CTRL_VAL_UNKNOWN;
///pan = -65;
///volume = -1;
- setMinimumSize(600, 50);
showTrackinfoFlag = true;
cursVal = MAXINT;
+ parentWin=parent;
+
//setFocusPolicy(Qt::StrongFocus);
//---------------------------------------------------
@@ -396,7 +398,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name)
canvas->setCanvasTools(MusEWidget::arrangerTools);
canvas->setOrigin(-offset, 0);
canvas->setFocus();
- //parent->setFocusProxy(canvas); // Tim.
+ setFocusProxy(canvas); // once removed by Tim (r735), added by flo again
connect(canvas, SIGNAL(setUsedTool(int)), this, SIGNAL(setUsedTool(int)));
connect(canvas, SIGNAL(trackChanged(Track*)), list, SLOT(selectTrack(Track*)));
@@ -761,20 +763,20 @@ void Arranger::cmd(int cmd)
case CMD_COPY_PART:
ncmd = PartCanvas::CMD_COPY_PART;
break;
+ case CMD_COPY_PART_IN_RANGE:
+ ncmd = PartCanvas::CMD_COPY_PART_IN_RANGE;
+ break;
case CMD_PASTE_PART:
ncmd = PartCanvas::CMD_PASTE_PART;
break;
case CMD_PASTE_CLONE_PART:
ncmd = PartCanvas::CMD_PASTE_CLONE_PART;
break;
- case CMD_PASTE_PART_TO_TRACK:
- ncmd = PartCanvas::CMD_PASTE_PART_TO_TRACK;
- break;
- case CMD_PASTE_CLONE_PART_TO_TRACK:
- ncmd = PartCanvas::CMD_PASTE_CLONE_PART_TO_TRACK;
+ case CMD_PASTE_DIALOG:
+ ncmd = PartCanvas::CMD_PASTE_DIALOG;
break;
- case CMD_INSERT_PART:
- ncmd = PartCanvas::CMD_INSERT_PART;
+ case CMD_PASTE_CLONE_DIALOG:
+ ncmd = PartCanvas::CMD_PASTE_CLONE_DIALOG;
break;
case CMD_INSERT_EMPTYMEAS:
ncmd = PartCanvas::CMD_INSERT_EMPTYMEAS;
diff --git a/muse2/muse/arranger/arranger.h b/muse2/muse/arranger/arranger.h
index 77299ef6..1e3943be 100644
--- a/muse2/muse/arranger/arranger.h
+++ b/muse2/muse/arranger/arranger.h
@@ -57,6 +57,8 @@ class Splitter;
class SpinBox;
}
+class ArrangerView;
+
//---------------------------------------------------------
// WidgetStack
//---------------------------------------------------------
@@ -167,10 +169,10 @@ class Arranger : public QWidget {
void controllerChanged(Track *t);
public:
- enum { CMD_CUT_PART, CMD_COPY_PART, CMD_PASTE_PART, CMD_PASTE_CLONE_PART, CMD_PASTE_PART_TO_TRACK, CMD_PASTE_CLONE_PART_TO_TRACK,
- CMD_INSERT_PART, CMD_INSERT_EMPTYMEAS };
+ enum { CMD_CUT_PART, CMD_COPY_PART, CMD_COPY_PART_IN_RANGE, CMD_PASTE_PART, CMD_PASTE_CLONE_PART,
+ CMD_PASTE_DIALOG, CMD_PASTE_CLONE_DIALOG, CMD_INSERT_EMPTYMEAS };
- Arranger(QMainWindow* parent, const char* name = 0);
+ Arranger(ArrangerView* parent, const char* name = 0);
PartCanvas* getCanvas() { return canvas; }
void setMode(int);
@@ -187,6 +189,8 @@ class Arranger : public QWidget {
void clear();
unsigned cursorValue() { return cursVal; }
+
+ ArrangerView* parentWin;
};
#endif
diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp
new file mode 100644
index 00000000..0cc75db9
--- /dev/null
+++ b/muse2/muse/arranger/arrangerview.cpp
@@ -0,0 +1,726 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// arrangerview.cpp
+// (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)
+//
+// 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; 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 <QApplication>
+#include <QClipboard>
+#include <QCloseEvent>
+#include <QDir>
+#include <QGridLayout>
+#include <QImage>
+#include <QInputDialog>
+#include <QKeyEvent>
+#include <QKeySequence>
+#include <QLabel>
+#include <QLayout>
+#include <QMenu>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QMimeData>
+#include <QPushButton>
+#include <QResizeEvent>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QSettings>
+#include <QShortcut>
+#include <QSignalMapper>
+#include <QSizeGrip>
+#include <QToolButton>
+#include <QToolTip>
+
+#include "al/sig.h"
+#include "app.h"
+#include "arrangerview.h"
+#include "audio.h"
+#include "functions.h"
+#include "gconfig.h"
+#include "globals.h"
+#include "helper.h"
+#include "icons.h"
+#include "mtscale.h"
+#include "scoreedit.h"
+#include "shortcuts.h"
+#include "sig.h"
+#include "song.h"
+#include "structure.h"
+#include "tb1.h"
+#include "tools.h"
+#include "ttoolbar.h"
+#include "visibletracks.h"
+#include "xml.h"
+
+
+//---------------------------------------------------------
+// ArrangerView
+//---------------------------------------------------------
+
+ArrangerView::ArrangerView(QWidget* parent)
+ : TopWin(TopWin::ARRANGER, parent, "arrangerview", Qt::Window)
+{
+ using MusEGlobal::muse;
+
+ //setAttribute(Qt::WA_DeleteOnClose);
+ setWindowTitle(tr("MusE: Arranger"));
+ setFocusPolicy(Qt::StrongFocus);
+
+ arranger = new Arranger(this, "arranger");
+ setCentralWidget(arranger);
+ setFocusProxy(arranger);
+
+ scoreOneStaffPerTrackMapper = new QSignalMapper(this);
+ scoreAllInOneMapper = new QSignalMapper(this);
+
+ editSignalMapper = new QSignalMapper(this);
+ QShortcut* sc = new QShortcut(shortcuts[SHRT_DELETE].key, this);
+ sc->setContext(Qt::WindowShortcut);
+ connect(sc, SIGNAL(activated()), editSignalMapper, SLOT(map()));
+ editSignalMapper->setMapping(sc, CMD_DELETE);
+
+ // Toolbars ---------------------------------------------------------
+ QToolBar* undo_tools=addToolBar(tr("Undo/Redo tools"));
+ undo_tools->setObjectName("Undo/Redo tools");
+ undo_tools->addActions(MusEGlobal::undoRedo->actions());
+
+
+ QToolBar* panic_toolbar = addToolBar(tr("panic"));
+ panic_toolbar->setObjectName("panic");
+ panic_toolbar->addAction(MusEGlobal::panicAction);
+
+ QToolBar* transport_toolbar = addToolBar(tr("transport"));
+ transport_toolbar->setObjectName("transport");
+ transport_toolbar->addActions(MusEGlobal::transportAction->actions());
+
+ editTools = new MusEWidget::EditToolBar(this, MusEWidget::arrangerTools);
+ addToolBar(editTools);
+ editTools->setObjectName("arrangerTools");
+
+ visTracks = new MusEWidget::VisibleTracks(this);
+ addToolBar(visTracks);
+
+
+
+ connect(editTools, SIGNAL(toolChanged(int)), arranger, SLOT(setTool(int)));
+ connect(visTracks, SIGNAL(visibilityChanged()), song, SLOT(update()) );
+ connect(arranger, SIGNAL(editPart(Track*)), muse, SLOT(startEditor(Track*)));
+ connect(arranger, SIGNAL(dropSongFile(const QString&)), muse, SLOT(loadProjectFile(const QString&)));
+ connect(arranger, SIGNAL(dropMidiFile(const QString&)), muse, SLOT(importMidi(const QString&)));
+ connect(arranger, SIGNAL(startEditor(PartList*,int)), muse, SLOT(startEditor(PartList*,int)));
+ connect(arranger, SIGNAL(toolChanged(int)), editTools, SLOT(set(int)));
+ connect(muse, SIGNAL(configChanged()), arranger, SLOT(configChanged()));
+ connect(arranger, SIGNAL(setUsedTool(int)), editTools, SLOT(set(int)));
+ connect(arranger, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+
+
+
+
+
+
+ //-------- Edit Actions
+ editCutAction = new QAction(QIcon(*editcutIconSet), tr("C&ut"), this);
+ editCopyAction = new QAction(QIcon(*editcopyIconSet), tr("&Copy"), this);
+ editCopyRangeAction = new QAction(QIcon(*editcopyIconSet), tr("&Copy in range"), this);
+ editPasteAction = new QAction(QIcon(*editpasteIconSet), tr("&Paste"), this);
+ editPasteDialogAction = new QAction(QIcon(*editpasteIconSet), tr("Paste (show dialog)"), this);
+ editPasteCloneAction = new QAction(QIcon(*editpasteCloneIconSet), tr("Paste c&lone"), this);
+ editPasteCloneDialogAction = new QAction(QIcon(*editpasteCloneIconSet), tr("Paste clone (show dialog)"), this);
+ editInsertEMAction = new QAction(QIcon(*editpasteIconSet), tr("&Insert Empty Measure"), this);
+ editDeleteSelectedAction = new QAction(QIcon(*edit_track_delIcon), tr("Delete Selected Tracks"), this);
+
+ editShrinkPartsAction = new QAction(tr("Shrink selected parts"), this); //FINDMICH TODO tooltips!
+ editExpandPartsAction = new QAction(tr("Expand selected parts"), this);
+ editCleanPartsAction = new QAction(tr("Clean selected parts"), this);
+
+
+ addTrack = new QMenu(tr("Add Track"), this);
+ addTrack->setIcon(QIcon(*edit_track_addIcon));
+ select = new QMenu(tr("Select"), this);
+ select->setIcon(QIcon(*selectIcon));
+
+ editSelectAllAction = new QAction(QIcon(*select_allIcon), tr("Select &All"), this);
+ editDeselectAllAction = new QAction(QIcon(*select_deselect_allIcon), tr("&Deselect All"), this);
+ editInvertSelectionAction = new QAction(QIcon(*select_invert_selectionIcon), tr("Invert &Selection"), this);
+ editInsideLoopAction = new QAction(QIcon(*select_inside_loopIcon), tr("&Inside Loop"), this);
+ editOutsideLoopAction = new QAction(QIcon(*select_outside_loopIcon), tr("&Outside Loop"), this);
+ editAllPartsAction = new QAction( QIcon(*select_all_parts_on_trackIcon), tr("All &Parts on Track"), this);
+
+
+ scoreSubmenu = new QMenu(tr("Score"), this);
+ scoreSubmenu->setIcon(QIcon(*scoreIconSet));
+
+ scoreAllInOneSubsubmenu = new QMenu(tr("all parts in one staff"), this);
+ scoreOneStaffPerTrackSubsubmenu = new QMenu(tr("one staff per part"), this);
+
+ scoreSubmenu->addMenu(scoreAllInOneSubsubmenu);
+ scoreSubmenu->addMenu(scoreOneStaffPerTrackSubsubmenu);
+ updateScoreMenus();
+
+ startScoreEditAction = new QAction(*scoreIconSet, tr("New score window"), this);
+ startPianoEditAction = new QAction(*pianoIconSet, tr("Pianoroll"), this);
+ startDrumEditAction = new QAction(QIcon(*edit_drummsIcon), tr("Drums"), this);
+ startListEditAction = new QAction(QIcon(*edit_listIcon), tr("List"), this);
+ startWaveEditAction = new QAction(QIcon(*edit_waveIcon), tr("Wave"), this);
+
+ master = new QMenu(tr("Mastertrack"), this);
+ master->setIcon(QIcon(*edit_mastertrackIcon));
+ masterGraphicAction = new QAction(QIcon(*mastertrack_graphicIcon),tr("Graphic"), this);
+ masterListAction = new QAction(QIcon(*mastertrack_listIcon),tr("List"), this);
+
+ midiTransformerAction = new QAction(QIcon(*midi_transformIcon), tr("Midi &Transform"), this);
+
+
+ //-------- Structure Actions
+ strGlobalCutAction = new QAction(tr("Global Cut"), this);
+ strGlobalInsertAction = new QAction(tr("Global Insert"), this);
+ strGlobalSplitAction = new QAction(tr("Global Split"), this);
+
+
+
+ //-------------------------------------------------------------
+ // popup Edit
+ //-------------------------------------------------------------
+
+ QMenu* menuEdit = menuBar()->addMenu(tr("&Edit"));
+ menuEdit->addActions(MusEGlobal::undoRedo->actions());
+ menuEdit->addSeparator();
+
+ menuEdit->addAction(editCutAction);
+ menuEdit->addAction(editCopyAction);
+ menuEdit->addAction(editCopyRangeAction);
+ menuEdit->addAction(editPasteAction);
+ menuEdit->addAction(editPasteDialogAction);
+ menuEdit->addAction(editPasteCloneAction);
+ menuEdit->addAction(editPasteCloneDialogAction);
+ menuEdit->addAction(editInsertEMAction);
+ menuEdit->addSeparator();
+ menuEdit->addAction(editShrinkPartsAction);
+ menuEdit->addAction(editExpandPartsAction);
+ menuEdit->addAction(editCleanPartsAction);
+ menuEdit->addSeparator();
+ menuEdit->addAction(editDeleteSelectedAction);
+
+ menuEdit->addMenu(addTrack);
+ menuEdit->addMenu(select);
+ select->addAction(editSelectAllAction);
+ select->addAction(editDeselectAllAction);
+ select->addAction(editInvertSelectionAction);
+ select->addAction(editInsideLoopAction);
+ select->addAction(editOutsideLoopAction);
+ select->addAction(editAllPartsAction);
+ menuEdit->addSeparator();
+
+ menuEdit->addAction(startPianoEditAction);
+ menuEdit->addMenu(scoreSubmenu);
+ menuEdit->addAction(startScoreEditAction);
+ menuEdit->addAction(startDrumEditAction);
+ menuEdit->addAction(startListEditAction);
+ menuEdit->addAction(startWaveEditAction);
+
+ menuEdit->addMenu(master);
+ master->addAction(masterGraphicAction);
+ master->addAction(masterListAction);
+ menuEdit->addSeparator();
+
+ menuEdit->addAction(midiTransformerAction);
+
+ QMenu* menuStructure = menuEdit->addMenu(tr("&Structure"));
+ menuStructure->addAction(strGlobalCutAction);
+ menuStructure->addAction(strGlobalInsertAction);
+ menuStructure->addAction(strGlobalSplitAction);
+
+
+
+ QMenu* functions_menu = menuBar()->addMenu(tr("Functions"));
+ QAction* func_quantize_action = functions_menu->addAction(tr("&Quantize Notes"), editSignalMapper, SLOT(map()));
+ QAction* func_notelen_action = functions_menu->addAction(tr("Change note &length"), editSignalMapper, SLOT(map()));
+ QAction* func_velocity_action = functions_menu->addAction(tr("Change note &velocity"), editSignalMapper, SLOT(map()));
+ QAction* func_cresc_action = functions_menu->addAction(tr("Crescendo/Decrescendo"), editSignalMapper, SLOT(map()));
+ QAction* func_transpose_action = functions_menu->addAction(tr("Transpose"), editSignalMapper, SLOT(map()));
+ QAction* func_erase_action = functions_menu->addAction(tr("Erase Events (Not Parts)"), editSignalMapper, SLOT(map()));
+ QAction* func_move_action = functions_menu->addAction(tr("Move Events (Not Parts)"), editSignalMapper, SLOT(map()));
+ QAction* func_fixed_len_action = functions_menu->addAction(tr("Set Fixed Note Length"), editSignalMapper, SLOT(map()));
+ QAction* func_del_overlaps_action = functions_menu->addAction(tr("Delete Overlapping Notes"), editSignalMapper, SLOT(map()));
+ QAction* func_legato_action = functions_menu->addAction(tr("Legato"), editSignalMapper, SLOT(map()));
+ editSignalMapper->setMapping(func_quantize_action, CMD_QUANTIZE);
+ editSignalMapper->setMapping(func_notelen_action, CMD_NOTELEN);
+ editSignalMapper->setMapping(func_velocity_action, CMD_VELOCITY);
+ editSignalMapper->setMapping(func_cresc_action, CMD_CRESCENDO);
+ editSignalMapper->setMapping(func_transpose_action, CMD_TRANSPOSE);
+ editSignalMapper->setMapping(func_erase_action, CMD_ERASE);
+ editSignalMapper->setMapping(func_move_action, CMD_MOVE);
+ editSignalMapper->setMapping(func_fixed_len_action, CMD_FIXED_LEN);
+ editSignalMapper->setMapping(func_del_overlaps_action, CMD_DELETE_OVERLAPS);
+ editSignalMapper->setMapping(func_legato_action, CMD_LEGATO);
+
+
+
+ QMenu* menuSettings = menuBar()->addMenu(tr("Window &Config"));
+ menuSettings->addAction(subwinAction);
+ menuSettings->addAction(shareAction);
+ menuSettings->addAction(fullscreenAction);
+
+
+ //-------- Edit connections
+ connect(editCutAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editCopyAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editCopyRangeAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editPasteAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editPasteCloneAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editPasteDialogAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editPasteCloneDialogAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editInsertEMAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editDeleteSelectedAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+
+ connect(editShrinkPartsAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editExpandPartsAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editCleanPartsAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+
+ connect(editSelectAllAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editDeselectAllAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editInvertSelectionAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editInsideLoopAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editOutsideLoopAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editAllPartsAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+
+ editSignalMapper->setMapping(editCutAction, CMD_CUT);
+ editSignalMapper->setMapping(editCopyAction, CMD_COPY);
+ editSignalMapper->setMapping(editCopyRangeAction, CMD_COPY_RANGE);
+ editSignalMapper->setMapping(editPasteAction, CMD_PASTE);
+ editSignalMapper->setMapping(editPasteCloneAction, CMD_PASTE_CLONE);
+ editSignalMapper->setMapping(editPasteDialogAction, CMD_PASTE_DIALOG);
+ editSignalMapper->setMapping(editPasteCloneDialogAction, CMD_PASTE_CLONE_DIALOG);
+ editSignalMapper->setMapping(editInsertEMAction, CMD_INSERTMEAS);
+ editSignalMapper->setMapping(editDeleteSelectedAction, CMD_DELETE_TRACK);
+ editSignalMapper->setMapping(editShrinkPartsAction, CMD_SHRINK_PART);
+ editSignalMapper->setMapping(editExpandPartsAction, CMD_EXPAND_PART);
+ editSignalMapper->setMapping(editCleanPartsAction, CMD_CLEAN_PART);
+ editSignalMapper->setMapping(editSelectAllAction, CMD_SELECT_ALL);
+ editSignalMapper->setMapping(editDeselectAllAction, CMD_SELECT_NONE);
+ editSignalMapper->setMapping(editInvertSelectionAction, CMD_SELECT_INVERT);
+ editSignalMapper->setMapping(editInsideLoopAction, CMD_SELECT_ILOOP);
+ editSignalMapper->setMapping(editOutsideLoopAction, CMD_SELECT_OLOOP);
+ editSignalMapper->setMapping(editAllPartsAction, CMD_SELECT_PARTS);
+
+ connect(editSignalMapper, SIGNAL(mapped(int)), this, SLOT(cmd(int)));
+
+ connect(startPianoEditAction, SIGNAL(activated()), muse, SLOT(startPianoroll()));
+ connect(startScoreEditAction, SIGNAL(activated()), muse, SLOT(startScoreQuickly()));
+ connect(startDrumEditAction, SIGNAL(activated()), muse, SLOT(startDrumEditor()));
+ connect(startListEditAction, SIGNAL(activated()), muse, SLOT(startListEditor()));
+ connect(startWaveEditAction, SIGNAL(activated()), muse, SLOT(startWaveEditor()));
+ connect(scoreOneStaffPerTrackMapper, SIGNAL(mapped(QWidget*)), muse, SLOT(openInScoreEdit_oneStaffPerTrack(QWidget*)));
+ connect(scoreAllInOneMapper, SIGNAL(mapped(QWidget*)), muse, SLOT(openInScoreEdit_allInOne(QWidget*)));
+
+
+ connect(masterGraphicAction, SIGNAL(activated()), muse, SLOT(startMasterEditor()));
+ connect(masterListAction, SIGNAL(activated()), muse, SLOT(startLMasterEditor()));
+
+ connect(midiTransformerAction, SIGNAL(activated()), muse, SLOT(startMidiTransformer()));
+
+
+ //-------- Structure connections
+ connect(strGlobalCutAction, SIGNAL(activated()), SLOT(globalCut()));
+ connect(strGlobalInsertAction, SIGNAL(activated()), SLOT(globalInsert()));
+ connect(strGlobalSplitAction, SIGNAL(activated()), SLOT(globalSplit()));
+
+
+
+ connect(muse, SIGNAL(configChanged()), SLOT(updateShortcuts()));
+
+
+ QClipboard* cb = QApplication::clipboard();
+ connect(cb, SIGNAL(dataChanged()), SLOT(clipboardChanged()));
+ connect(cb, SIGNAL(selectionChanged()), SLOT(clipboardChanged()));
+
+
+
+ // work around for probable QT/WM interaction bug.
+ // for certain window managers, e.g xfce, this window is
+ // is displayed although not specifically set to show();
+ // bug: 2811156 Softsynth GUI unclosable with XFCE4 (and a few others)
+ show();
+ hide();
+}
+
+ArrangerView::~ArrangerView()
+{
+
+}
+
+void ArrangerView::closeEvent(QCloseEvent* e)
+{
+ emit deleted(static_cast<TopWin*>(this));
+ emit closed();
+ e->accept();
+}
+
+
+
+void ArrangerView::writeStatus(int level, Xml& xml) const
+{
+ xml.tag(level++, "arrangerview");
+ TopWin::writeStatus(level, xml);
+ xml.intTag(level, "tool", editTools->curTool());
+ xml.tag(level, "/arrangerview");
+}
+
+void ArrangerView::readStatus(Xml& xml)
+{
+ for (;;)
+ {
+ Xml::Token token = xml.parse();
+ if (token == Xml::Error || token == Xml::End)
+ break;
+
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::TagStart:
+ if (tag == "tool")
+ editTools->set(xml.parseInt());
+ else if (tag == "topwin")
+ TopWin::readStatus(xml);
+ else
+ xml.unknown("ArrangerView");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "arrangerview")
+ return;
+
+ default:
+ break;
+ }
+ }
+}
+
+//---------------------------------------------------------
+// readConfiguration
+//---------------------------------------------------------
+
+void ArrangerView::readConfiguration(Xml& xml)
+ {
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "topwin")
+ TopWin::readConfiguration(ARRANGER, xml);
+ else
+ xml.unknown("ArrangerView");
+ break;
+ case Xml::TagEnd:
+ if (tag == "arrangerview")
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// writeConfiguration
+//---------------------------------------------------------
+
+void ArrangerView::writeConfiguration(int level, Xml& xml)
+ {
+ xml.tag(level++, "arrangerview");
+ TopWin::writeConfiguration(ARRANGER, level, xml);
+ xml.tag(level, "/arrangerview");
+ }
+
+
+void ArrangerView::cmd(int cmd)
+ {
+ TrackList* tracks = song->tracks();
+ int l = song->lpos();
+ int r = song->rpos();
+
+ switch(cmd) {
+ case CMD_CUT:
+ arranger->cmd(Arranger::CMD_CUT_PART);
+ break;
+ case CMD_COPY:
+ arranger->cmd(Arranger::CMD_COPY_PART);
+ break;
+ case CMD_COPY_RANGE:
+ arranger->cmd(Arranger::CMD_COPY_PART_IN_RANGE);
+ break;
+ case CMD_PASTE:
+ arranger->cmd(Arranger::CMD_PASTE_PART);
+ break;
+ case CMD_PASTE_CLONE:
+ arranger->cmd(Arranger::CMD_PASTE_CLONE_PART);
+ break;
+ case CMD_PASTE_DIALOG:
+ arranger->cmd(Arranger::CMD_PASTE_DIALOG);
+ break;
+ case CMD_PASTE_CLONE_DIALOG:
+ arranger->cmd(Arranger::CMD_PASTE_CLONE_DIALOG);
+ break;
+ case CMD_INSERTMEAS:
+ arranger->cmd(Arranger::CMD_INSERT_EMPTYMEAS);
+ break;
+ case CMD_DELETE:
+ if (!song->msgRemoveParts()) //automatically does undo if neccessary and returns true then
+ {
+ //msgRemoveParts() returned false -> no parts to remove?
+ song->startUndo();
+ audio->msgRemoveTracks(); //TODO FINDME this could still be speeded up!
+ song->endUndo(SC_TRACK_REMOVED);
+ }
+ break;
+ case CMD_DELETE_TRACK:
+ song->startUndo();
+ audio->msgRemoveTracks();
+ song->endUndo(SC_TRACK_REMOVED);
+ audio->msgUpdateSoloStates();
+ break;
+
+ case CMD_SELECT_ALL:
+ case CMD_SELECT_NONE:
+ case CMD_SELECT_INVERT:
+ case CMD_SELECT_ILOOP:
+ case CMD_SELECT_OLOOP:
+ for (iTrack i = tracks->begin(); i != tracks->end(); ++i) {
+ PartList* parts = (*i)->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p) {
+ bool f = false;
+ int t1 = p->second->tick();
+ int t2 = t1 + p->second->lenTick();
+ bool inside =
+ ((t1 >= l) && (t1 < r))
+ || ((t2 > l) && (t2 < r))
+ || ((t1 <= l) && (t2 > r));
+ switch(cmd) {
+ case CMD_SELECT_INVERT:
+ f = !p->second->selected();
+ break;
+ case CMD_SELECT_NONE:
+ f = false;
+ break;
+ case CMD_SELECT_ALL:
+ f = true;
+ break;
+ case CMD_SELECT_ILOOP:
+ f = inside;
+ break;
+ case CMD_SELECT_OLOOP:
+ f = !inside;
+ break;
+ }
+ p->second->setSelected(f);
+ }
+ }
+ song->update();
+ break;
+
+ case CMD_SELECT_PARTS:
+ for (iTrack i = tracks->begin(); i != tracks->end(); ++i) {
+ if (!(*i)->selected())
+ continue;
+ PartList* parts = (*i)->parts();
+ for (iPart p = parts->begin(); p != parts->end(); ++p)
+ p->second->setSelected(true);
+ }
+ song->update();
+ break;
+
+ case CMD_SHRINK_PART: shrink_parts(); break;
+ case CMD_EXPAND_PART: expand_parts(); break;
+ case CMD_CLEAN_PART: clean_parts(); break;
+
+ case CMD_QUANTIZE: quantize_notes(); break;
+ case CMD_VELOCITY: modify_velocity(); break;
+ case CMD_CRESCENDO: crescendo(); break;
+ case CMD_NOTELEN: modify_notelen(); break;
+ case CMD_TRANSPOSE: transpose_notes(); break;
+ case CMD_ERASE: erase_notes(); break;
+ case CMD_MOVE: move_notes(); break;
+ case CMD_FIXED_LEN: set_notelen(); break;
+ case CMD_DELETE_OVERLAPS: delete_overlaps(); break;
+ case CMD_LEGATO: legato(); break;
+
+ }
+ }
+
+void ArrangerView::scoreNamingChanged()
+{
+ updateScoreMenus();
+}
+
+void ArrangerView::updateScoreMenus()
+{
+ QAction* action;
+
+
+ scoreOneStaffPerTrackSubsubmenu->clear();
+ scoreAllInOneSubsubmenu->clear();
+
+
+ action=new QAction(tr("New"), this);
+ connect(action, SIGNAL(activated()), scoreOneStaffPerTrackMapper, SLOT(map()));
+ scoreOneStaffPerTrackMapper->setMapping(action, (QWidget*)NULL);
+ scoreOneStaffPerTrackSubsubmenu->addAction(action);
+
+
+ action=new QAction(tr("New"), this); //the above action may NOT be reused!
+ connect(action, SIGNAL(activated()), scoreAllInOneMapper, SLOT(map()));
+ scoreAllInOneMapper->setMapping(action, (QWidget*)NULL);
+ scoreAllInOneSubsubmenu->addAction(action);
+
+ const ToplevelList* toplevels=MusEGlobal::muse->getToplevels();
+
+ for (ToplevelList::const_iterator it=toplevels->begin(); it!=toplevels->end(); it++)
+ if ((*it)->type()==TopWin::SCORE)
+ {
+ ScoreEdit* score = dynamic_cast<ScoreEdit*>(*it);
+
+ action=new QAction(score->get_name(), this);
+ connect(action, SIGNAL(activated()), scoreOneStaffPerTrackMapper, SLOT(map()));
+ scoreOneStaffPerTrackMapper->setMapping(action, (QWidget*)score);
+ scoreOneStaffPerTrackSubsubmenu->addAction(action);
+
+
+ action=new QAction(score->get_name(), this); //the above action may NOT be reused!
+ connect(action, SIGNAL(activated()), scoreAllInOneMapper, SLOT(map()));
+ scoreAllInOneMapper->setMapping(action, (QWidget*)score);
+ scoreAllInOneSubsubmenu->addAction(action);
+ }
+}
+
+void ArrangerView::clearScoreMenuMappers()
+{
+ delete scoreOneStaffPerTrackMapper;
+ delete scoreAllInOneMapper;
+
+ scoreOneStaffPerTrackMapper = new QSignalMapper(this);
+ scoreAllInOneMapper = new QSignalMapper(this);
+
+ connect(scoreOneStaffPerTrackMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_oneStaffPerTrack(QWidget*)));
+ connect(scoreAllInOneMapper, SIGNAL(mapped(QWidget*)), this, SLOT(openInScoreEdit_allInOne(QWidget*)));
+}
+
+void ArrangerView::populateAddTrack()
+{
+ QActionGroup *grp = MusEUtil::populateAddTrack(addTrack);
+ connect(addTrack, SIGNAL(triggered(QAction *)), SLOT(addNewTrack(QAction *)));
+
+ trackMidiAction = grp->actions()[0];
+ trackDrumAction = grp->actions()[1];
+ trackWaveAction = grp->actions()[2];
+ trackAOutputAction = grp->actions()[3];
+ trackAGroupAction = grp->actions()[4];
+ trackAInputAction = grp->actions()[5];
+ trackAAuxAction = grp->actions()[6];
+}
+
+void ArrangerView::addNewTrack(QAction* action)
+{
+ song->addNewTrack(action, MusEGlobal::muse->arranger()->curTrack()); // Insert at current selected track.
+ //song->addNewTrack(action); // Add at end.
+}
+
+void ArrangerView::updateShortcuts()
+{
+ editCutAction->setShortcut(shortcuts[SHRT_CUT].key);
+ editCopyAction->setShortcut(shortcuts[SHRT_COPY].key);
+ editCopyRangeAction->setShortcut(shortcuts[SHRT_COPY_RANGE].key);
+ editPasteAction->setShortcut(shortcuts[SHRT_PASTE].key);
+ editPasteCloneAction->setShortcut(shortcuts[SHRT_PASTE_CLONE].key);
+ editPasteDialogAction->setShortcut(shortcuts[SHRT_PASTE_DIALOG].key);
+ editPasteCloneDialogAction->setShortcut(shortcuts[SHRT_PASTE_CLONE_DIALOG].key);
+ editInsertEMAction->setShortcut(shortcuts[SHRT_INSERTMEAS].key);
+
+ //editDeleteSelectedAction has no acceleration
+
+ trackMidiAction->setShortcut(shortcuts[SHRT_ADD_MIDI_TRACK].key);
+ trackDrumAction->setShortcut(shortcuts[SHRT_ADD_DRUM_TRACK].key);
+ trackWaveAction->setShortcut(shortcuts[SHRT_ADD_WAVE_TRACK].key);
+ trackAOutputAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_OUTPUT].key);
+ trackAGroupAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_GROUP].key);
+ trackAInputAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_INPUT].key);
+ trackAAuxAction->setShortcut(shortcuts[SHRT_ADD_AUDIO_AUX].key);
+
+ editSelectAllAction->setShortcut(shortcuts[SHRT_SELECT_ALL].key);
+ editDeselectAllAction->setShortcut(shortcuts[SHRT_SELECT_NONE].key);
+ editInvertSelectionAction->setShortcut(shortcuts[SHRT_SELECT_INVERT].key);
+ editInsideLoopAction->setShortcut(shortcuts[SHRT_SELECT_OLOOP].key);
+ editOutsideLoopAction->setShortcut(shortcuts[SHRT_SELECT_OLOOP].key);
+ editAllPartsAction->setShortcut(shortcuts[SHRT_SELECT_PRTSTRACK].key);
+
+ startPianoEditAction->setShortcut(shortcuts[SHRT_OPEN_PIANO].key);
+ startDrumEditAction->setShortcut(shortcuts[SHRT_OPEN_DRUMS].key);
+ startListEditAction->setShortcut(shortcuts[SHRT_OPEN_LIST].key);
+ startWaveEditAction->setShortcut(shortcuts[SHRT_OPEN_WAVE].key);
+
+ masterGraphicAction->setShortcut(shortcuts[SHRT_OPEN_GRAPHIC_MASTER].key);
+ masterListAction->setShortcut(shortcuts[SHRT_OPEN_LIST_MASTER].key);
+
+ midiTransformerAction->setShortcut(shortcuts[SHRT_OPEN_MIDI_TRANSFORM].key);
+ strGlobalCutAction->setShortcut(shortcuts[SHRT_GLOBAL_CUT].key);
+ strGlobalInsertAction->setShortcut(shortcuts[SHRT_GLOBAL_INSERT].key);
+ strGlobalSplitAction->setShortcut(shortcuts[SHRT_GLOBAL_SPLIT].key);
+}
+
+//---------------------------------------------------------
+// clipboardChanged
+//---------------------------------------------------------
+
+void ArrangerView::clipboardChanged()
+ {
+ bool flag = false;
+ if(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-midipartlist")) ||
+ QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-wavepartlist")) ||
+ QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-mixedpartlist")))
+ flag = true;
+
+ editPasteAction->setEnabled(flag);
+ editPasteCloneAction->setEnabled(flag);
+ editPasteDialogAction->setEnabled(flag);
+ editPasteCloneDialogAction->setEnabled(flag);
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void ArrangerView::selectionChanged()
+ {
+ //bool flag = arranger->isSingleSelection(); // -- Hmm, why only single?
+ bool flag = arranger->selectionSize() > 0; // -- Test OK cut and copy. For muse2. Tim.
+ editCutAction->setEnabled(flag);
+ editCopyAction->setEnabled(flag);
+ }
+
+
+void ArrangerView::updateVisibleTracksButtons()
+{
+ visTracks->updateVisibleTracksButtons();
+}
+
+void ArrangerView::globalCut() { ::globalCut(); }
+void ArrangerView::globalInsert() { ::globalInsert(); }
+void ArrangerView::globalSplit() { ::globalSplit(); }
diff --git a/muse2/muse/arranger/arrangerview.h b/muse2/muse/arranger/arrangerview.h
new file mode 100644
index 00000000..bdb450ae
--- /dev/null
+++ b/muse2/muse/arranger/arrangerview.h
@@ -0,0 +1,156 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// arrangerview.h
+// (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)
+//
+// 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; 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 __ARRANGERVIEW_H__
+#define __ARRANGERVIEW_H__
+
+#include <QCloseEvent>
+#include <QResizeEvent>
+#include <QLabel>
+#include <QKeyEvent>
+#include <QPainter>
+#include <QPixmap>
+#include <QTimer>
+#include <QScrollBar>
+#include <QComboBox>
+#include <QSignalMapper>
+#include <QAction>
+#include <QActionGroup>
+#include <QGridLayout>
+#include <QByteArray>
+#include <QToolButton>
+
+#include <values.h>
+#include "noteinfo.h"
+#include "cobject.h"
+#include "event.h"
+#include "view.h"
+#include "gconfig.h"
+#include "part.h"
+#include "keyevent.h"
+#include "mtscale_flo.h"
+#include "steprec.h"
+#include "cleftypes.h"
+#include "helper.h"
+#include "arranger.h"
+
+namespace MusEWidget { class VisibleTracks; }
+
+
+class ArrangerView : public TopWin
+{
+ Q_OBJECT
+
+ private:
+
+ enum cmd_enum
+ {CMD_CUT, CMD_COPY, CMD_COPY_RANGE, CMD_PASTE, CMD_INSERTMEAS, CMD_PASTE_CLONE,
+ CMD_PASTE_DIALOG, CMD_PASTE_CLONE_DIALOG, CMD_DELETE,
+ CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,
+ CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PARTS,
+ CMD_DELETE_TRACK, CMD_EXPAND_PART, CMD_SHRINK_PART, CMD_CLEAN_PART,
+ CMD_QUANTIZE, CMD_VELOCITY, CMD_CRESCENDO, CMD_NOTELEN, CMD_TRANSPOSE,
+ CMD_ERASE, CMD_MOVE, CMD_FIXED_LEN, CMD_DELETE_OVERLAPS, CMD_LEGATO };
+
+ virtual void closeEvent(QCloseEvent*);
+
+ QGridLayout* mainGrid;
+ QWidget* mainw;
+
+ MusEWidget::EditToolBar* editTools;
+ MusEWidget::VisibleTracks* visTracks;
+
+ Arranger* arranger;
+
+ // Edit Menu actions
+ QMenu* select;
+ QMenu* addTrack;
+ QMenu* master;
+
+ QAction *strGlobalCutAction, *strGlobalInsertAction, *strGlobalSplitAction;
+ QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction;
+ QAction *trackAInputAction, *trackAAuxAction;
+ QAction *editCutAction, *editCopyAction, *editCopyRangeAction;
+ QAction *editPasteAction, *editPasteCloneAction, *editPasteDialogAction, *editPasteCloneDialogAction;
+ QAction *editInsertEMAction, *editPasteC2TAction, *editDeleteSelectedAction, *editSelectAllAction, *editDeselectAllAction;
+ QAction *editInvertSelectionAction, *editInsideLoopAction, *editOutsideLoopAction, *editAllPartsAction;
+ QAction *masterGraphicAction, *masterListAction;
+ QAction *midiTransformerAction;
+ QAction *editCleanPartsAction, *editShrinkPartsAction, *editExpandPartsAction;
+
+ QAction* func_quantize_action;
+ QAction* func_notelen_action;
+ QAction* func_velocity_action;
+ QAction* func_cresc_action;
+ QAction* func_transpose_action;
+ QAction* func_erase_action;
+ QAction* func_move_action;
+ QAction* func_fixed_len_action;
+ QAction* func_del_overlaps_action;
+ QAction* func_legato_action;
+
+ QSignalMapper *editSignalMapper;
+ QSignalMapper *scoreOneStaffPerTrackMapper;
+ QSignalMapper *scoreAllInOneMapper;
+
+ private slots:
+ void clearScoreMenuMappers();
+ void globalCut();
+ void globalInsert();
+ void globalSplit();
+ void cmd(int);
+ void addNewTrack(QAction* action);
+
+ signals:
+ void deleted(TopWin*);
+ void closed();
+
+ public slots:
+ void scoreNamingChanged();
+ void updateScoreMenus();
+ void clipboardChanged();
+ void selectionChanged();
+ void updateShortcuts();
+ void updateVisibleTracksButtons();
+
+ public:
+ ArrangerView(QWidget* parent = 0);
+ ~ArrangerView();
+
+ QAction *startScoreEditAction, *startPianoEditAction, *startDrumEditAction, *startListEditAction, *startWaveEditAction;
+ QMenu *scoreSubmenu, *scoreOneStaffPerTrackSubsubmenu, *scoreAllInOneSubsubmenu;
+
+ void populateAddTrack();
+
+ Arranger* getArranger() {return arranger;}
+
+ void writeStatus(int level, Xml& xml) const;
+ void readStatus(Xml& xml);
+ static void readConfiguration(Xml&);
+ static void writeConfiguration(int, Xml&);
+};
+
+
+
+
+#endif
+
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index 0d73ace6..056dcce7 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -40,6 +40,9 @@
#include "fastlog.h"
#include "widgets/tools.h"
+#include "arranger.h"
+#include "arrangerview.h"
+#include "structure.h"
#include "pcanvas.h"
#include "midieditor.h"
#include "globals.h"
@@ -58,11 +61,17 @@
#include "midi.h"
#include "midictrl.h"
#include "utils.h"
+#include "dialogs.h"
+#include "widgets/pastedialog.h"
//#define ABS(x) ((x) < 0) ? -(x) : (x))
//#define ABS(x) (x>=0?x:-x)
#define ABS(x) (abs(x))
+using std::set;
+
+int get_paste_len();
+
//---------------------------------------------------------
// colorRect
// paints a rectangular icon with a given color
@@ -172,15 +181,19 @@ void PartCanvas::leaveEvent(QEvent*)
void PartCanvas::returnPressed()
{
lineEditor->hide();
- Part* oldPart = editPart->part();
- Part* newPart = oldPart->clone();
- //printf("PartCanvas::returnPressed before msgChangePart oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oldPart->events()->refCount(), oldPart->events()->arefCount(), newPart->events()->refCount(), newPart->events()->arefCount());
-
- newPart->setName(lineEditor->text());
- // Indicate do undo, and do port controller values but not clone parts.
- audio->msgChangePart(oldPart, newPart, true, true, false);
-
- editMode = false;
+ if (editMode) {
+ //this check is neccessary, because it returnPressed may be called
+ //twice. the second call would cause a crash, however!
+ Part* oldPart = editPart->part();
+ Part* newPart = oldPart->clone();
+ //printf("PartCanvas::returnPressed before msgChangePart oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oldPart->events()->refCount(), oldPart->events()->arefCount(), newPart->events()->refCount(), newPart->events()->arefCount());
+
+ newPart->setName(lineEditor->text());
+ // Indicate do undo, and do port controller values but not clone parts.
+ audio->msgChangePart(oldPart, newPart, true, true, false);
+
+ editMode = false;
+ }
}
//---------------------------------------------------------
@@ -203,6 +216,7 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event)
if (lineEditor == 0) {
lineEditor = new QLineEdit(this);
lineEditor->setFrame(true);
+ connect(lineEditor, SIGNAL(editingFinished()),SLOT(returnPressed()));
}
editMode = true;
lineEditor->setGeometry(r);
@@ -335,7 +349,7 @@ UndoOp PartCanvas::moveItem(MusEWidget::CItem* item, const QPoint& newpos, DragT
ntrack = tracks->size();
if (MusEGlobal::debugMsg)
printf("PartCanvas::moveItem - add new track\n");
- Track* newTrack = song->addTrack(int(type));
+ Track* newTrack = song->addTrack(type, false); // Add at end of list.
if (type == Track::WAVE) {
WaveTrack* st = (WaveTrack*) track;
WaveTrack* dt = (WaveTrack*) newTrack;
@@ -648,17 +662,17 @@ QMenu* PartCanvas::genItemPopup(MusEWidget::CItem* item)
partPopup->addSeparator();
switch(trackType) {
case Track::MIDI: {
- partPopup->addAction(MusEGlobal::muse->startPianoEditAction);
- partPopup->addMenu(MusEGlobal::muse->scoreSubmenu);
- partPopup->addAction(MusEGlobal::muse->startScoreEditAction);
- partPopup->addAction(MusEGlobal::muse->startListEditAction);
+ partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startPianoEditAction);
+ partPopup->addMenu(MusEGlobal::muse->arranger()->parentWin->scoreSubmenu);
+ partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startScoreEditAction);
+ partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startListEditAction);
QAction *act_mexport = partPopup->addAction(tr("save part to disk"));
act_mexport->setData(16);
}
break;
case Track::DRUM: {
- partPopup->addAction(MusEGlobal::muse->startDrumEditAction);
- partPopup->addAction(MusEGlobal::muse->startListEditAction);
+ partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startDrumEditAction);
+ partPopup->addAction(MusEGlobal::muse->arranger()->parentWin->startListEditAction);
QAction *act_dexport = partPopup->addAction(tr("save part to disk"));
act_dexport->setData(16);
}
@@ -705,6 +719,7 @@ void PartCanvas::itemPopup(MusEWidget::CItem* item, int n, const QPoint& pt)
if (lineEditor == 0) {
lineEditor = new QLineEdit(this);
lineEditor->setFrame(true);
+ connect(lineEditor, SIGNAL(editingFinished()),SLOT(returnPressed()));
}
lineEditor->setText(editPart->name());
lineEditor->setFocus();
@@ -846,25 +861,32 @@ void PartCanvas::mousePress(QMouseEvent* event)
}
QPoint pt = event->pos();
MusEWidget::CItem* item = items.find(pt);
- if (item == 0 && _tool!=MusEWidget::AutomationTool)
- return;
+
+ //if (item == 0 && _tool!=MusEWidget::AutomationTool) // FINDMICHJETZT. neccessary? (flo93)
+ // return;
+
switch (_tool) {
default:
- emit trackChanged(item->part()->track());
+ if (item)
+ emit trackChanged(item->part()->track());
+ else
+ emit trackChanged(NULL);
break;
case MusEWidget::CutTool:
- splitItem(item, pt);
+ if (item) splitItem(item, pt);
break;
case MusEWidget::GlueTool:
- glueItem(item);
+ if (item) glueItem(item);
break;
case MusEWidget::MuteTool:
{
- NPart* np = (NPart*) item;
- Part* p = np->part();
- p->setMute(!p->mute());
- redraw();
- break;
+ if (item) {
+ NPart* np = (NPart*) item;
+ Part* p = np->part();
+ p->setMute(!p->mute());
+ redraw();
+ break;
+ }
}
case MusEWidget::AutomationTool:
if (automation.controllerState != doNothing)
@@ -943,7 +965,7 @@ void PartCanvas::keyPress(QKeyEvent* event)
{
if ( key == Qt::Key_Return || key == Qt::Key_Enter )
{
- returnPressed();
+ //returnPressed(); commented out by flo
return;
}
else if ( key == Qt::Key_Escape )
@@ -2588,21 +2610,39 @@ void PartCanvas::cmd(int cmd)
case CMD_COPY_PART:
copy(&pl);
break;
- case CMD_PASTE_PART:
- paste(false, false);
- break;
- case CMD_PASTE_CLONE_PART:
- paste(true, false);
+ case CMD_COPY_PART_IN_RANGE:
+ copy_in_range(&pl);
break;
- case CMD_PASTE_PART_TO_TRACK:
+ case CMD_PASTE_PART:
paste();
break;
- case CMD_PASTE_CLONE_PART_TO_TRACK:
+ case CMD_PASTE_CLONE_PART:
paste(true);
break;
- case CMD_INSERT_PART:
- paste(false, false, true);
+ case CMD_PASTE_DIALOG:
+ case CMD_PASTE_CLONE_DIALOG:
+ {
+ unsigned temp_begin = AL::sigmap.raster1(song->vcpos(),0);
+ unsigned temp_end = AL::sigmap.raster2(temp_begin + get_paste_len(), 0);
+ paste_dialog->raster = temp_end - temp_begin;
+ paste_dialog->clone = (cmd == CMD_PASTE_CLONE_DIALOG);
+
+ if (paste_dialog->exec())
+ {
+ paste_mode_t paste_mode;
+ switch (paste_dialog->insert_method)
+ {
+ case 0: paste_mode=PASTEMODE_MIX; break;
+ case 1: paste_mode=PASTEMODE_MOVEALL; break;
+ case 2: paste_mode=PASTEMODE_MOVESOME; break;
+ }
+
+ paste(paste_dialog->clone, paste_mode, paste_dialog->all_in_one_track,
+ paste_dialog->number, paste_dialog->raster);
+ }
+
break;
+ }
case CMD_INSERT_EMPTYMEAS:
int startPos=song->vcpos();
int oneMeas=AL::sigmap.ticksMeasure(startPos);
@@ -2617,6 +2657,70 @@ void PartCanvas::cmd(int cmd)
// cut copy paste
//---------------------------------------------------------
+void PartCanvas::copy_in_range(PartList* pl_)
+{
+ PartList pl;
+ PartList result_pl;
+ unsigned int lpos = song->lpos();
+ unsigned int rpos = song->rpos();
+
+ if (pl_->empty())
+ {
+ for (MusEWidget::iCItem i = items.begin(); i != items.end(); ++i)
+ {
+ Part* part=static_cast<NPart*>(i->second)->part();
+ if ( (part->track()->isMidiTrack()) || (part->track()->type() == Track::WAVE) )
+ pl.add(part);
+ }
+ }
+ else
+ {
+ for(ciPart p = pl_->begin(); p != pl_->end(); ++p)
+ if ( (p->second->track()->isMidiTrack()) || (p->second->track()->type() == Track::WAVE) )
+ pl.add(p->second);
+ }
+
+ if (!pl.empty() && (rpos>lpos))
+ {
+ for(ciPart p = pl.begin(); p != pl.end(); ++p)
+ {
+ Part* part=p->second;
+ Track* track=part->track();
+
+ if ((part->tick() < rpos) && (part->endTick() > lpos)) //is the part in the range?
+ {
+ if ((lpos > part->tick()) && (lpos < part->endTick()))
+ {
+ Part* p1;
+ Part* p2;
+
+ track->splitPart(part, lpos, p1, p2);
+ p1->events()->incARef(-1);
+ p2->events()->incARef(-1);
+
+ part=p2;
+ }
+
+ if ((rpos > part->tick()) && (rpos < part->endTick()))
+ {
+ Part* p1;
+ Part* p2;
+
+ track->splitPart(part, rpos, p1, p2);
+ p1->events()->incARef(-1);
+ p2->events()->incARef(-1);
+
+ part=p1;
+ }
+
+ result_pl.add(part);
+ }
+ }
+
+ copy(&result_pl);
+ }
+}
+
void PartCanvas::copy(PartList* pl)
{
if (pl->empty())
@@ -2700,11 +2804,88 @@ void PartCanvas::copy(PartList* pl)
fclose(tmp);
}
-//---------------------------------------------------------
-// pasteAt
-//---------------------------------------------------------
-Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack, int* finalPosPtr)
+
+int get_paste_len()
+{
+ QClipboard* cb = QApplication::clipboard();
+ const QMimeData* md = cb->mimeData(QClipboard::Clipboard);
+
+ QString pfx("text/");
+ QString mdpl("x-muse-midipartlist");
+ QString wvpl("x-muse-wavepartlist");
+ QString mxpl("x-muse-mixedpartlist");
+ QString txt;
+
+ if(md->hasFormat(pfx + mdpl))
+ txt = cb->text(mdpl, QClipboard::Clipboard);
+ else if(md->hasFormat(pfx + wvpl))
+ txt = cb->text(wvpl, QClipboard::Clipboard);
+ else if(md->hasFormat(pfx + mxpl))
+ txt = cb->text(mxpl, QClipboard::Clipboard);
+ else
+ return 0;
+
+
+ QByteArray ba = txt.toLatin1();
+ const char* ptxt = ba.constData();
+ Xml xml(ptxt);
+ bool end = false;
+
+ unsigned begin_tick=-1; //this uses the greatest possible begin_tick
+ unsigned end_tick=0;
+
+ for (;;)
+ {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::Error:
+ case Xml::End:
+ end = true;
+ break;
+
+ case Xml::TagStart:
+ if (tag == "part")
+ {
+ Part* p = 0;
+ p = readXmlPart(xml, NULL, false, false);
+
+ if (p)
+ {
+ if (p->tick() < begin_tick)
+ begin_tick=p->tick();
+
+ if (p->endTick() > end_tick)
+ end_tick=p->endTick();
+
+ delete p;
+ }
+ }
+ else
+ xml.unknown("PartCanvas::get_paste_len");
+ break;
+
+ case Xml::TagEnd:
+ break;
+
+ default:
+ end = true;
+ break;
+ }
+ if(end)
+ break;
+ }
+
+ if (begin_tick > end_tick)
+ return 0;
+ else
+ return end_tick - begin_tick;
+}
+
+
+Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack, int* finalPosPtr, set<Track*>* affected_tracks)
{
Undo operations;
@@ -2754,7 +2935,10 @@ Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
if (p->tick()+p->lenTick()>finalPos) {
finalPos=p->tick()+p->lenTick();
}
+ p->setSelected(true);
operations.push_back(UndoOp(UndoOp::AddPart,p));
+ if (affected_tracks)
+ affected_tracks->insert(p->track());
}
else
xml.unknown("PartCanvas::pasteAt");
@@ -2789,16 +2973,12 @@ Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool
// paste part to current selected track at cpos
//---------------------------------------------------------
-void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
+void PartCanvas::paste(bool clone, paste_mode_t paste_mode, bool to_single_track, int amount, int raster)
{
Track* track = 0;
-
- if (doInsert) // logic depends on keeping track of newly selected tracks
- deselectAll();
-
-
+
// If we want to paste to a selected track...
- if(toTrack)
+ if (to_single_track)
{
TrackList* tl = song->tracks();
for (iTrack i = tl->begin(); i != tl->end(); ++i) {
@@ -2831,7 +3011,7 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
if(md->hasFormat(pfx + mdpl))
{
// If we want to paste to a selected track...
- if(toTrack && !track->isMidiTrack())
+ if(to_single_track && !track->isMidiTrack())
{
QMessageBox::critical(this, QString("MusE"),
tr("Can only paste to midi/drum track"));
@@ -2839,11 +3019,10 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
}
txt = cb->text(mdpl, QClipboard::Clipboard);
}
- else
- if(md->hasFormat(pfx + wvpl))
+ else if(md->hasFormat(pfx + wvpl))
{
// If we want to paste to a selected track...
- if(toTrack && track->type() != Track::WAVE)
+ if(to_single_track && track->type() != Track::WAVE)
{
QMessageBox::critical(this, QString("MusE"),
tr("Can only paste to wave track"));
@@ -2851,11 +3030,10 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
}
txt = cb->text(wvpl, QClipboard::Clipboard);
}
- else
- if(md->hasFormat(pfx + mxpl))
+ else if(md->hasFormat(pfx + mxpl))
{
// If we want to paste to a selected track...
- if(toTrack && !track->isMidiTrack() && track->type() != Track::WAVE)
+ if(to_single_track && !track->isMidiTrack() && track->type() != Track::WAVE)
{
QMessageBox::critical(this, QString("MusE"),
tr("Can only paste to midi or wave track"));
@@ -2874,54 +3052,41 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert)
{
int endPos=0;
unsigned int startPos=song->vcpos();
- Undo operations=pasteAt(txt, track, startPos, clone, toTrack, &endPos);
+ set<Track*> affected_tracks;
+
+ deselectAll();
+
+ Undo operations;
+ for (int i=0;i<amount;i++)
+ {
+ Undo temp = pasteAt(txt, track, startPos + i*raster, clone, to_single_track, &endPos, &affected_tracks);
+ operations.insert(operations.end(), temp.begin(), temp.end());
+ }
+
Pos p(endPos, true);
song->setPos(0, p);
- if (doInsert) {
- int offset = endPos-startPos;
- Undo temp=movePartsTotheRight(startPos, offset);
+
+ if (paste_mode != PASTEMODE_MIX)
+ {
+ int offset;
+ if (amount==1) offset = endPos-startPos;
+ else offset = amount*raster;
+
+ Undo temp;
+ if (paste_mode==PASTEMODE_MOVESOME)
+ temp=movePartsTotheRight(startPos, offset, false, &affected_tracks);
+ else
+ temp=movePartsTotheRight(startPos, offset);
+
operations.insert(operations.end(), temp.begin(), temp.end());
}
+
song->applyOperationGroup(operations);
}
}
//---------------------------------------------------------
-// movePartsToTheRight
-//---------------------------------------------------------
-Undo PartCanvas::movePartsTotheRight(unsigned int startTicks, int length)
-{
- Undo operations;
-
- // all parts that start after the pasted parts will be moved the entire length of the pasted parts
- for (MusEWidget::iCItem i = items.begin(); i != items.end(); ++i) {
- if (!i->second->isSelected()) {
- Part* part = i->second->part();
- if (part->tick() >= startTicks) {
- Part *newPart = part->clone();
- newPart->setTick(newPart->tick()+length);
-
- operations.push_back(UndoOp(UndoOp::ModifyPart,part,newPart,false,false));
- }
- }
- }
- // perhaps ask if markers should be moved?
- MarkerList *markerlist = song->marker();
- for(iMarker i = markerlist->begin(); i != markerlist->end(); ++i)
- {
- Marker* m = &i->second;
- if (m->tick() >= startTicks) {
- Marker *oldMarker = new Marker();
- *oldMarker = *m;
- m->setTick(m->tick()+length);
- operations.push_back(UndoOp(UndoOp::ModifyMarker,oldMarker, m));
- }
- }
-
- return operations;
-}
-//---------------------------------------------------------
// startDrag
//---------------------------------------------------------
@@ -3044,6 +3209,7 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
track = tracks->index(trackNo);
if (track)
{
+ deselectAll();
Undo temp=pasteAt(text, track, x);
song->applyOperationGroup(temp);
}
@@ -3070,9 +3236,9 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
if (!track) { // we need to create a track for this drop
if (text.endsWith(".mpt", Qt::CaseInsensitive)) {
- track = song->addTrack((Track::MIDI));
+ track = song->addTrack(Track::MIDI, false); // Add at end of list.
} else {
- track = song->addTrack((Track::WAVE));
+ track = song->addTrack(Track::WAVE, false); // Add at end of list.
}
}
if (track->type() == Track::WAVE &&
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index 927a64e1..2bce9035 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -25,6 +25,7 @@
#define __PCANVAS_H__
#include <QVector>
+#include <set>
#include "song.h"
#include "canvas.h"
@@ -124,9 +125,10 @@ class PartCanvas : public MusEWidget::Canvas {
void splitItem(MusEWidget::CItem* item, const QPoint&);
void copy(PartList*);
- void paste(bool clone = false, bool toTrack = true, bool doInsert=false);
- Undo pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true, int* finalPosPtr = NULL);
- Undo movePartsTotheRight(unsigned int startTick, int length);
+ void copy_in_range(PartList*);
+ enum paste_mode_t { PASTEMODE_MIX, PASTEMODE_MOVEALL, PASTEMODE_MOVESOME };
+ void paste(bool clone = false, paste_mode_t paste_mode = PASTEMODE_MIX, bool to_single_track=false, int amount=1, int raster=1536);
+ Undo pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true, int* finalPosPtr = NULL, std::set<Track*>* affected_tracks = NULL);
//Part* readClone(Xml&, Track*, bool toTrack = true);
void drawWavePart(QPainter&, const QRect&, WavePart*, const QRect&);
//void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack*mt, const QRect& r, int pTick, int from, int to);
@@ -141,8 +143,6 @@ class PartCanvas : public MusEWidget::Canvas {
double dbToVal(double inDb);
double valToDb(double inV);
-
-
protected:
virtual void drawCanvas(QPainter&, const QRect&);
virtual void endMoveItems(const QPoint&, DragType, int dir);
@@ -165,8 +165,8 @@ class PartCanvas : public MusEWidget::Canvas {
void returnPressed();
public:
- enum { CMD_CUT_PART, CMD_COPY_PART, CMD_PASTE_PART, CMD_PASTE_CLONE_PART, CMD_PASTE_PART_TO_TRACK, CMD_PASTE_CLONE_PART_TO_TRACK,
- CMD_INSERT_PART, CMD_INSERT_EMPTYMEAS };
+ enum { CMD_CUT_PART, CMD_COPY_PART, CMD_COPY_PART_IN_RANGE, CMD_PASTE_PART, CMD_PASTE_CLONE_PART,
+ CMD_PASTE_DIALOG, CMD_PASTE_CLONE_DIALOG, CMD_INSERT_EMPTYMEAS };
PartCanvas(int* raster, QWidget* parent, int, int);
void partsChanged();
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index 87f5acde..28b12fdc 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -55,6 +55,7 @@
#include "audio.h"
#include "instruments/minstrument.h"
#include "app.h"
+#include "helper.h"
#include "gconfig.h"
#include "event.h"
#include "midiedit/drummap.h"
@@ -66,10 +67,6 @@
#include "dssihost.h"
#endif
-namespace MusEApp {
-extern QMenu* populateAddSynth(QWidget* parent);
-}
-
static const int MIN_TRACKHEIGHT = 20;
static const int WHEEL_DELTA = 120;
QColor collist[] = { Qt::red, Qt::yellow, Qt::blue , Qt::black, Qt::white, Qt::green };
@@ -993,105 +990,44 @@ void TList::mousePressEvent(QMouseEvent* ev)
Track* t = y2Track(y + ypos);
+ // FIXME Observed: Ancient bug: Track Info doesn't change if selecting multiple tracks in reverse order.
+ // Will need to be fixed if/when adding 'multiple track global editing'.
+
TrackColumn col = TrackColumn(header->logicalIndexAt(x));
if (t == 0) {
if (button == Qt::RightButton) {
QMenu* p = new QMenu;
- //p->clear();
- QAction* midi = p->addAction(*addtrack_addmiditrackIcon,
- tr("Add Midi Track"));
- midi->setData(Track::MIDI);
- QAction* drum = p->addAction(*addtrack_drumtrackIcon,
- tr("Add Drum Track"));
- drum->setData(Track::DRUM);
- QAction* wave = p->addAction(*addtrack_wavetrackIcon,
- tr("Add Wave Track"));
- wave->setData(Track::WAVE);
- QAction* aoutput = p->addAction(*addtrack_audiooutputIcon,
- tr("Add Output"));
- aoutput->setData(Track::AUDIO_OUTPUT);
- QAction* agroup = p->addAction(*addtrack_audiogroupIcon,
- tr("Add Group"));
- agroup->setData(Track::AUDIO_GROUP);
- QAction* ainput = p->addAction(*addtrack_audioinputIcon,
- tr("Add Input"));
- ainput->setData(Track::AUDIO_INPUT);
- QAction* aaux = p->addAction(*addtrack_auxsendIcon,
- tr("Add Aux Send"));
- aaux->setData(Track::AUDIO_AUX);
+ MusEUtil::populateAddTrack(p);
- // Create a sub-menu and fill it with found synth types. Make p the owner.
- QMenu* synp = MusEApp::populateAddSynth(p);
- synp->setIcon(*synthIcon);
- synp->setTitle(QT_TRANSLATE_NOOP("@default", "Add Synth"));
-
- // Add the 'Add Synth' sub-menu to the menu.
- p->addMenu(synp);
-
// Show the menu
QAction* act = p->exec(ev->globalPos(), 0);
// Valid click?
if(act)
{
- int n = act->data().toInt();
- // Valid item?
- if((n >= 0) && ((Track::TrackType)n != Track::AUDIO_SOFTSYNTH))
+ t = song->addNewTrack(act); // Add at end of list.
+ if(t)
{
- // Synth sub-menu id?
- if(n >= MENU_ADD_SYNTH_ID_BASE)
- {
- n -= MENU_ADD_SYNTH_ID_BASE;
- //if(n < synthis.size())
- // t = song->createSynthI(synthis[n]->baseName());
- //if((n - MENU_ADD_SYNTH_ID_BASE) < (int)synthis.size())
- if(n < (int)synthis.size())
- {
- //t = song->createSynthI(synp->text(n));
- //t = song->createSynthI(synthis[n]->name());
- t = song->createSynthI(synthis[n]->baseName(), synthis[n]->name());
-
- if(t)
- {
- // Add instance last in midi device list.
- for (int i = 0; i < MIDI_PORTS; ++i)
- {
- MidiPort* port = &midiPorts[i];
- MidiDevice* dev = port->device();
- if (dev==0)
- {
- midiSeq->msgSetMidiDevice(port, (SynthI*)t);
- MusEGlobal::muse->changeConfig(true); // save configuration file
- song->update();
- break;
- }
- }
- }
- }
- }
- // Normal track.
- else
- t = song->addTrack((Track::TrackType)n);
-
- if(t)
- {
- song->deselectTracks();
- t->setSelected(true);
-
- ///emit selectionChanged();
- emit selectionChanged(t);
- adjustScrollbar();
- }
- }
+ song->deselectTracks();
+ t->setSelected(true);
+
+ ///emit selectionChanged();
+ emit selectionChanged(t);
+ adjustScrollbar();
+ }
}
// Just delete p, and all its children will go too, right?
//delete synp;
delete p;
- }
+ }
else if (button == Qt::LeftButton) {
- if (!ctrl) song->deselectTracks();
- }
+ if (!ctrl)
+ {
+ song->deselectTracks();
+ emit selectionChanged(0);
+ }
+ }
return;
}
@@ -1297,18 +1233,28 @@ void TList::mousePressEvent(QMouseEvent* ev)
mode = NORMAL;
QMenu* p = new QMenu;
//p->clear();
- p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(0);
- p->addAction(QIcon(*track_commentIcon), tr("Track Comment"))->setData(1);
+ // Leave room for normal track IDs - base these at AUDIO_SOFTSYNTH.
+ p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(Track::AUDIO_SOFTSYNTH + 1);
+ p->addAction(QIcon(*track_commentIcon), tr("Track Comment"))->setData(Track::AUDIO_SOFTSYNTH + 2);
+ p->addSeparator();
+ QMenu* pnew = new QMenu(p);
+ pnew->setTitle(tr("Insert Track"));
+ pnew->setIcon(QIcon(*edit_track_addIcon));
+ MusEUtil::populateAddTrack(pnew);
+ p->addMenu(pnew);
QAction* act = p->exec(ev->globalPos(), 0);
if (act) {
int n = act->data().toInt();
- switch (n) {
- case 0: // delete track
+ if(n >= Track::AUDIO_SOFTSYNTH && n < MENU_ADD_SYNTH_ID_BASE)
+ {
+ n -= Track::AUDIO_SOFTSYNTH;
+ switch (n) {
+ case 1: // delete track
song->removeTrack0(t);
audio->msgUpdateSoloStates();
break;
- case 1: // show track comment
+ case 2: // show track comment
{
MusEWidget::TrackComment* tc = new MusEWidget::TrackComment(t, 0);
tc->show();
@@ -1320,8 +1266,19 @@ void TList::mousePressEvent(QMouseEvent* ev)
printf("action %d\n", n);
break;
}
-
}
+ else
+ {
+ t = song->addNewTrack(act, t); // Let addNewTrack handle it. Insert before clicked-on track 't'.
+ if(t)
+ {
+ song->deselectTracks();
+ t->setSelected(true);
+ emit selectionChanged(t);
+ adjustScrollbar();
+ }
+ }
+ }
delete p;
}
break;
@@ -1405,24 +1362,24 @@ void TList::mousePressEvent(QMouseEvent* ev)
// selectTrack
//---------------------------------------------------------
void TList::selectTrack(Track* tr)
- {
- song->deselectTracks();
- tr->setSelected(true);
-
+{
+ song->deselectTracks();
- // rec enable track if expected
- TrackList recd = getRecEnabledTracks();
- if (recd.size() == 1 && MusEConfig::config.moveArmedCheckBox) { // one rec enabled track, move rec enabled with selection
- song->setRecordFlag((Track*)recd.front(),false);
- song->setRecordFlag(tr,true);
- }
+ if (tr) {
+ tr->setSelected(true);
- // By T356. Force a redraw for wave tracks, since it does not seem to happen.
- //if(!tr->isMidiTrack())
- redraw();
- ///emit selectionChanged();
- emit selectionChanged(tr);
- }
+
+ // rec enable track if expected
+ TrackList recd = getRecEnabledTracks();
+ if (recd.size() == 1 && MusEConfig::config.moveArmedCheckBox) { // one rec enabled track, move rec enabled with selection
+ song->setRecordFlag((Track*)recd.front(),false);
+ song->setRecordFlag(tr,true);
+ }
+ }
+
+ redraw();
+ emit selectionChanged(tr);
+}
//---------------------------------------------------------
// selectTrackAbove