summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-09-11 15:34:52 +0000
committerFlorian Jung <flo@windfisch.org>2011-09-11 15:34:52 +0000
commit253b9d9f1a17b98f3f6696f456e9d83f1ac9aee3 (patch)
tree0b32703e2bee9fb8135295671f7f2b7194cd2aaa
parent5f5a8e76f19d6956f6d711979877028f07203d88 (diff)
began with implementing the improved paste for midi editors
TODO: sane values for raster, and respect raster and amount values support ctrl+shift+c
-rw-r--r--muse2/muse.pro3
-rw-r--r--muse2/muse/dialogs.cpp6
-rw-r--r--muse2/muse/dialogs.h2
-rw-r--r--muse2/muse/functions.cpp18
-rw-r--r--muse2/muse/functions.h1
-rw-r--r--muse2/muse/midiedit/dcanvas.h2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp11
-rw-r--r--muse2/muse/midiedit/drumedit.h2
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp12
-rw-r--r--muse2/muse/midiedit/pianoroll.h1
-rw-r--r--muse2/muse/midiedit/prcanvas.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp21
-rw-r--r--muse2/muse/midiedit/scoreedit.h3
-rw-r--r--muse2/muse/shortcuts.cpp4
-rw-r--r--muse2/muse/shortcuts.h4
-rw-r--r--muse2/muse/widgets/CMakeLists.txt3
-rw-r--r--muse2/muse/widgets/pastedialogbase.ui4
-rw-r--r--muse2/muse/widgets/pasteeventsdialog.cpp171
-rw-r--r--muse2/muse/widgets/pasteeventsdialog.h65
-rw-r--r--muse2/muse/widgets/pasteeventsdialogbase.ui383
20 files changed, 704 insertions, 14 deletions
diff --git a/muse2/muse.pro b/muse2/muse.pro
index 03f31e71..82649d96 100644
--- a/muse2/muse.pro
+++ b/muse2/muse.pro
@@ -190,6 +190,7 @@ HEADERS = \
./muse/widgets/tempolabel.h \
./muse/widgets/mixdowndialog.h \
./muse/widgets/pastedialog.h \
+ ./muse/widgets/pasteeventsdialog.h \
./muse/widgets/sigedit.h \
./muse/widgets/songinfo.h \
./muse/widgets/scldraw.h \
@@ -412,6 +413,7 @@ SOURCES = \
./muse/widgets/unusedwavefiles.cpp \
./muse/widgets/splitter.cpp \
./muse/widgets/pastedialog.cpp \
+ ./muse/widgets/pasteeventsdialog.cpp \
./muse/widgets/ctrlcombo.cpp \
./muse/widgets/siglabel.cpp \
./muse/widgets/projectcreateimpl.cpp \
@@ -597,6 +599,7 @@ FORMS = \
./muse/widgets/editsysexdialogbase.ui \
./muse/widgets/projectcreate.ui \
./muse/widgets/pastedialogbase.ui \
+ ./muse/widgets/pasteeventsdialogbase.ui \
./muse/widgets/didyouknow.ui \
./muse/widgets/itransformbase.ui \
./muse/widgets/aboutbox.ui \
diff --git a/muse2/muse/dialogs.cpp b/muse2/muse/dialogs.cpp
index a0bf265f..18db2352 100644
--- a/muse2/muse/dialogs.cpp
+++ b/muse2/muse/dialogs.cpp
@@ -32,6 +32,7 @@
#include "widgets/function_dialogs/deloverlaps.h"
#include "widgets/function_dialogs/legato.h"
#include "widgets/pastedialog.h"
+#include "widgets/pasteeventsdialog.h"
#include "xml.h"
@@ -50,6 +51,7 @@ MusEDialog::Transpose* transpose_dialog=NULL;
MusEDialog::Crescendo* crescendo_dialog=NULL;
MusEDialog::Legato* legato_dialog=NULL;
PasteDialog* paste_dialog=NULL; // FINDMICHJETZT
+PasteEventsDialog* paste_events_dialog=NULL; // FINDMICHJETZT
void init_function_dialogs(QWidget* parent)
{
@@ -64,6 +66,7 @@ void init_function_dialogs(QWidget* parent)
crescendo_dialog = new MusEDialog::Crescendo(parent);
legato_dialog = new MusEDialog::Legato(parent);
paste_dialog = new PasteDialog(parent); // FINDMICHJETZT
+ paste_events_dialog = new PasteEventsDialog(parent); // FINDMICHJETZT
}
void read_function_dialog_config(Xml& xml)
@@ -107,6 +110,8 @@ void read_function_dialog_config(Xml& xml)
legato_dialog->read_configuration(xml);
else if (tag == "pastedialog")
paste_dialog->read_configuration(xml);
+ else if (tag == "pasteeventsdialog")
+ paste_events_dialog->read_configuration(xml);
else
xml.unknown("dialogs");
break;
@@ -136,6 +141,7 @@ void write_function_dialog_config(int level, Xml& xml)
crescendo_dialog->write_configuration(level, xml);
legato_dialog->write_configuration(level, xml);
paste_dialog->write_configuration(level, xml);
+ paste_events_dialog->write_configuration(level, xml);
xml.tag(level, "/dialogs");
}
diff --git a/muse2/muse/dialogs.h b/muse2/muse/dialogs.h
index b8e85b91..3f966efd 100644
--- a/muse2/muse/dialogs.h
+++ b/muse2/muse/dialogs.h
@@ -38,6 +38,7 @@ namespace MusEDialog
class Legato;
}
class PasteDialog; //FINDMICHJETZT put into namespace
+class PasteEventsDialog; //FINDMICHJETZT put into namespace
class Xml;
@@ -52,6 +53,7 @@ extern MusEDialog::Transpose* transpose_dialog;
extern MusEDialog::Crescendo* crescendo_dialog;
extern MusEDialog::Legato* legato_dialog;
extern PasteDialog* paste_dialog; //FINDMICHJETZT
+extern PasteEventsDialog* paste_events_dialog; //FINDMICHJETZT
void init_function_dialogs(QWidget* parent);
void read_function_dialog_config(Xml& xml);
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index 2584caa3..a8b7ea1d 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -39,6 +39,7 @@
#include "widgets/function_dialogs/move.h"
#include "widgets/function_dialogs/deloverlaps.h"
#include "widgets/function_dialogs/legato.h"
+#include "widgets/pasteeventsdialog.h"
#include <values.h>
#include <iostream>
@@ -865,6 +866,20 @@ void copy_notes(const set<Part*>& parts, int range)
QApplication::clipboard()->setMimeData(drag, QClipboard::Clipboard);
}
+bool paste_notes(Part* paste_into_part)
+{
+ // TODO FINDMICHJETZT sane defaults for raster!
+ paste_events_dialog->into_single_part_allowed = (paste_into_part!=NULL);
+
+ if (!paste_events_dialog->exec())
+ return false;
+
+ paste_notes(paste_events_dialog->max_distance, paste_events_dialog->always_new_part,
+ paste_events_dialog->never_new_part, paste_events_dialog->into_single_part ? paste_into_part : NULL);
+
+ return true;
+}
+
void paste_notes(int max_distance, bool always_new_part, bool never_new_part, Part* paste_into_part)
{
QString tmp="x-muse-groupedeventlists"; // QClipboard::text() expects a QString&, not a QString :(
@@ -1027,6 +1042,9 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part
always_new_part ) && !never_new_part ) )
{
dest_part = dest_track->newPart();
+ dest_part->events()->incARef(-1); // the later song->applyOperationGroup() will increment it
+ // so we must decrement it first :/
+
dest_part->setTick(AL::sigmap.raster1(first_paste_tick, config.division));
operations.push_back(UndoOp(UndoOp::AddPart, dest_part));
}
diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h
index 650b986e..98376896 100644
--- a/muse2/muse/functions.h
+++ b/muse2/muse/functions.h
@@ -84,6 +84,7 @@ bool legato();
//functions for copy'n'paste
void copy_notes(const std::set<Part*>& parts, int range);
+bool paste_notes(Part* paste_into_part=NULL); // shows a dialog
void paste_notes(int max_distance=3072, bool always_new_part=false, bool never_new_part=false, Part* paste_into_part=NULL);
QMimeData* selected_events_to_mime(const std::set<Part*>& parts, int range);
void paste_at(const QString& pt, int pos, int max_distance=3072, bool always_new_part=false, bool never_new_part=false, Part* paste_into_part=NULL);
diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h
index 0256de01..110ecfb7 100644
--- a/muse2/muse/midiedit/dcanvas.h
+++ b/muse2/muse/midiedit/dcanvas.h
@@ -106,7 +106,7 @@ class DrumCanvas : public EventCanvas {
public:
enum {
- CMD_CUT, CMD_COPY, CMD_PASTE, CMD_SAVE, CMD_LOAD, CMD_RESET,
+ CMD_CUT, CMD_COPY, CMD_PASTE, CMD_PASTE_DIALOG, CMD_SAVE, CMD_LOAD, CMD_RESET,
CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,
CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART,
CMD_DEL, CMD_FIXED_LEN, CMD_RIGHT, CMD_LEFT, CMD_RIGHT_NOSNAP, CMD_LEFT_NOSNAP, CMD_MODIFY_VELOCITY, CMD_CRESCENDO,
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index a0dd6782..182a2db3 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -198,17 +198,20 @@ DrumEdit::DrumEdit(PartList* pl, QWidget* parent, const char* name, unsigned ini
cutAction = menuEdit->addAction(QIcon(*editcutIconSet), tr("Cut"));
copyAction = menuEdit->addAction(QIcon(*editcopyIconSet), tr("Copy"));
pasteAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("Paste"));
+ pasteDialogAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("Paste (with Dialog)"));
menuEdit->addSeparator();
deleteAction = menuEdit->addAction(tr("Delete Events"));
connect(cutAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(copyAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(pasteAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
+ connect(pasteDialogAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
connect(deleteAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
signalMapper->setMapping(cutAction, DrumCanvas::CMD_CUT);
signalMapper->setMapping(copyAction, DrumCanvas::CMD_COPY);
signalMapper->setMapping(pasteAction, DrumCanvas::CMD_PASTE);
+ signalMapper->setMapping(pasteDialogAction, DrumCanvas::CMD_PASTE_DIALOG);
signalMapper->setMapping(deleteAction, DrumCanvas::CMD_DEL);
menuSelect = menuEdit->addMenu(QIcon(*selectIcon), tr("&Select"));
@@ -919,7 +922,11 @@ void DrumEdit::cmd(int cmd)
case DrumCanvas::CMD_COPY: copy_notes(partlist_to_set(parts()), 1); break;
case DrumCanvas::CMD_PASTE:
((DrumCanvas*)canvas)->cmd(DrumCanvas::CMD_SELECT_NONE);
- paste_notes(); // (canvas->part()); TODO FINDMICHJETZT
+ paste_notes(3072);
+ break;
+ case DrumCanvas::CMD_PASTE_DIALOG:
+ ((DrumCanvas*)canvas)->cmd(DrumCanvas::CMD_SELECT_NONE);
+ paste_notes((canvas->part()));
break;
case DrumCanvas::CMD_LOAD: load(); break;
case DrumCanvas::CMD_SAVE: save(); break;
@@ -952,6 +959,7 @@ void DrumEdit::cmd(int cmd)
void DrumEdit::clipboardChanged()
{
pasteAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
+ pasteDialogAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
}
//---------------------------------------------------------
@@ -1268,6 +1276,7 @@ void DrumEdit::initShortcuts()
cutAction->setShortcut(shortcuts[SHRT_CUT].key);
copyAction->setShortcut(shortcuts[SHRT_COPY].key);
pasteAction->setShortcut(shortcuts[SHRT_PASTE].key);
+ pasteDialogAction->setShortcut(shortcuts[SHRT_PASTE_DIALOG].key);
deleteAction->setShortcut(shortcuts[SHRT_DELETE].key);
fixedAction->setShortcut(shortcuts[SHRT_FIXED_LEN].key);
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 5169dfcd..be9481c9 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -91,7 +91,7 @@ class DrumEdit : public MidiEditor {
static int _dlistWidthInit, _dcanvasWidthInit;
QAction *loadAction, *saveAction, *resetAction;
- QAction *cutAction, *copyAction, *pasteAction, *deleteAction;
+ QAction *cutAction, *copyAction, *pasteAction, *pasteDialogAction, *deleteAction;
QAction *fixedAction, *veloAction, *crescAction, *quantizeAction;
QAction *sallAction, *snoneAction, *invAction, *inAction , *outAction;
QAction *prevAction, *nextAction;
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index cfebb493..771bd3dd 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -111,6 +111,10 @@ PianoRoll::PianoRoll(PartList* pl, QWidget* parent, const char* name, unsigned i
mapper->setMapping(editPasteAction, PianoCanvas::CMD_PASTE);
connect(editPasteAction, SIGNAL(triggered()), mapper, SLOT(map()));
+ editPasteDialogAction = menuEdit->addAction(QIcon(*editpasteIconSet), tr("&Paste (with dialog)"));
+ mapper->setMapping(editPasteDialogAction, PianoCanvas::CMD_PASTE_DIALOG);
+ connect(editPasteDialogAction, SIGNAL(triggered()), mapper, SLOT(map()));
+
menuEdit->addSeparator();
editDelEventsAction = menuEdit->addAction(tr("Delete &Events"));
@@ -632,7 +636,11 @@ void PianoRoll::cmd(int cmd)
case PianoCanvas::CMD_COPY: copy_notes(partlist_to_set(parts()), 1); break;
case PianoCanvas::CMD_PASTE:
((PianoCanvas*)canvas)->cmd(PianoCanvas::CMD_SELECT_NONE);
- paste_notes(); //(canvas->part()); TODO FINDMICHJETZT
+ paste_notes(3072);
+ break;
+ case PianoCanvas::CMD_PASTE_DIALOG:
+ ((PianoCanvas*)canvas)->cmd(PianoCanvas::CMD_SELECT_NONE);
+ paste_notes((canvas->part()));
break;
case PianoCanvas::CMD_MODIFY_GATE_TIME: modify_notelen(partlist_to_set(parts())); break;
case PianoCanvas::CMD_MODIFY_VELOCITY: modify_velocity(partlist_to_set(parts())); break;
@@ -1196,6 +1204,7 @@ void PianoRoll::setEventColorMode(int mode)
void PianoRoll::clipboardChanged()
{
editPasteAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
+ editPasteDialogAction->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
}
//---------------------------------------------------------
@@ -1243,6 +1252,7 @@ void PianoRoll::initShortcuts()
editCutAction->setShortcut(shortcuts[SHRT_CUT].key);
editCopyAction->setShortcut(shortcuts[SHRT_COPY].key);
editPasteAction->setShortcut(shortcuts[SHRT_PASTE].key);
+ editPasteDialogAction->setShortcut(shortcuts[SHRT_PASTE_DIALOG].key);
editDelEventsAction->setShortcut(shortcuts[SHRT_DELETE].key);
selectAllAction->setShortcut(shortcuts[SHRT_SELECT_ALL].key);
diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h
index b1a5010b..5a8d17bc 100644
--- a/muse2/muse/midiedit/pianoroll.h
+++ b/muse2/muse/midiedit/pianoroll.h
@@ -86,6 +86,7 @@ class PianoRoll : public MidiEditor {
QAction* editCutAction;
QAction* editCopyAction;
QAction* editPasteAction;
+ QAction* editPasteDialogAction;
QAction* editDelEventsAction;
QAction* selectAllAction;
diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h
index d239994e..d45b5551 100644
--- a/muse2/muse/midiedit/prcanvas.h
+++ b/muse2/muse/midiedit/prcanvas.h
@@ -105,7 +105,7 @@ class PianoCanvas : public EventCanvas {
public:
enum {
- CMD_CUT, CMD_COPY, CMD_PASTE, CMD_DEL,
+ CMD_CUT, CMD_COPY, CMD_PASTE, CMD_PASTE_DIALOG, CMD_DEL,
CMD_QUANTIZE,
CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,
CMD_SELECT_ILOOP, CMD_SELECT_OLOOP, CMD_SELECT_PREV_PART, CMD_SELECT_NEXT_PART,
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 3c8f2afe..e4a3994a 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -367,6 +367,10 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)
menu_mapper->setMapping(paste_action, CMD_PASTE);
connect(paste_action, SIGNAL(triggered()), menu_mapper, SLOT(map()));
+ paste_dialog_action = edit_menu->addAction(QIcon(*editpasteIconSet), tr("Paste (with dialog)"));
+ menu_mapper->setMapping(paste_dialog_action, CMD_PASTE_DIALOG);
+ connect(paste_dialog_action, SIGNAL(triggered()), menu_mapper, SLOT(map()));
+
edit_menu->addSeparator();
del_action = edit_menu->addAction(tr("Delete &Events"));
@@ -497,6 +501,7 @@ void ScoreEdit::init_shortcuts()
cut_action->setShortcut(shortcuts[SHRT_CUT].key);
copy_action->setShortcut(shortcuts[SHRT_COPY].key);
paste_action->setShortcut(shortcuts[SHRT_PASTE].key);
+ paste_dialog_action->setShortcut(shortcuts[SHRT_PASTE_DIALOG].key);
del_action->setShortcut(shortcuts[SHRT_DELETE].key);
select_all_action->setShortcut(shortcuts[SHRT_SELECT_ALL].key);
@@ -694,7 +699,11 @@ void ScoreEdit::menu_command(int cmd)
case CMD_COPY: copy_notes(score_canvas->get_all_parts(), 1); break;
case CMD_PASTE:
menu_command(CMD_SELECT_NONE);
- paste_notes(); //(score_canvas->get_selected_part()); TODO FINDMICHJETZT
+ paste_notes(3072);
+ break;
+ case CMD_PASTE_DIALOG:
+ menu_command(CMD_SELECT_NONE);
+ paste_notes(score_canvas->get_selected_part());
break;
case CMD_QUANTIZE: quantize_notes(score_canvas->get_all_parts()); break;
case CMD_VELOCITY: modify_velocity(score_canvas->get_all_parts()); break;
@@ -716,6 +725,7 @@ void ScoreEdit::menu_command(int cmd)
void ScoreEdit::clipboard_changed()
{
paste_action->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
+ paste_dialog_action->setEnabled(QApplication::clipboard()->mimeData()->hasFormat(QString("text/x-muse-groupedeventlists")));
}
void ScoreEdit::selection_changed()
@@ -4501,9 +4511,16 @@ void ScoreEdit::keyPressEvent(QKeyEvent* event)
* changing "share" status, the changed state isn't stored
*
* CURRENT TODO
+ * o pasting in editors sometimes fails oO? ( ERROR: reading eventlist from clipboard failed. ignoring this one... )
+ * o ctrl+shift+c for editors
* o when pasting and creating new parts, inform the editors about that!
* o TEST pasting in editors!
- * o pasting in editors: add dialogs
+ * o sane default for raster
+ * o use raster and amount in paste_notes!
+ * x clone-bug
+ * x pasting in editors: add dialogs
+ *
+ * o ticks-to-quarter spinboxes
*
* ! o fix sigedit boxes
* M o remove that ugly "bool initalizing" stuff. it's probably unneeded (watch out for the FINDMICH message)
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index a2a89938..b436f85a 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -79,7 +79,7 @@ enum {CMD_COLOR_BLACK, CMD_COLOR_VELO, CMD_COLOR_PART,
CMD_QUANTIZE, CMD_VELOCITY, CMD_CRESCENDO, CMD_NOTELEN, CMD_TRANSPOSE,
CMD_ERASE, CMD_MOVE, CMD_FIXED_LEN, CMD_DELETE_OVERLAPS, CMD_LEGATO,
- CMD_CUT, CMD_COPY, CMD_PASTE, CMD_DEL,
+ CMD_CUT, CMD_COPY, CMD_PASTE, CMD_PASTE_DIALOG, CMD_DEL,
CMD_SELECT_ALL, CMD_SELECT_NONE, CMD_SELECT_INVERT,
CMD_SELECT_ILOOP, CMD_SELECT_OLOOP};
@@ -134,6 +134,7 @@ class ScoreEdit : public TopWin
QAction* cut_action;
QAction* copy_action;
QAction* paste_action;
+ QAction* paste_dialog_action;
QAction* del_action;
QAction* select_all_action;
diff --git a/muse2/muse/shortcuts.cpp b/muse2/muse/shortcuts.cpp
index 285bf8bc..2270befa 100644
--- a/muse2/muse/shortcuts.cpp
+++ b/muse2/muse/shortcuts.cpp
@@ -63,10 +63,12 @@ void initShortCuts()
defShrt(SHRT_FULLSCREEN, Qt::CTRL + Qt::Key_F, "Toggle fullscreen", GLOBAL_SHRT, "fullscreen");
defShrt(SHRT_COPY, Qt::CTRL + Qt::Key_C, "Edit: Copy", INVIS_SHRT, "copy");
+ defShrt(SHRT_COPY_RANGE, Qt::CTRL + Qt::SHIFT + Qt::Key_C, "Edit: Copy in range", GLOBAL_SHRT, "copy_range");
defShrt(SHRT_UNDO, Qt::CTRL + Qt::Key_Z, "Edit: Undo", INVIS_SHRT, "undo");
defShrt(SHRT_REDO, Qt::CTRL + Qt::Key_Y, "Edit: Redo", INVIS_SHRT, "redo");
defShrt(SHRT_CUT, Qt::CTRL + Qt::Key_X, "Edit: Cut", INVIS_SHRT, "cut");
defShrt(SHRT_PASTE, Qt::CTRL + Qt::Key_V, "Edit: Paste", INVIS_SHRT, "paste");
+ defShrt(SHRT_PASTE_DIALOG, Qt::CTRL + Qt::SHIFT + Qt::Key_V, "Edit: Paste (with dialog)", GLOBAL_SHRT, "paste_dialog");
defShrt(SHRT_DELETE, Qt::Key_Delete, "Edit: Delete", INVIS_SHRT, "delete");
//-----------------------------------------------------------
@@ -104,7 +106,6 @@ void initShortCuts()
defShrt(SHRT_GLOBAL_CUT, 0, "Structure: Global cut", ARRANG_SHRT, "global_cut");
defShrt(SHRT_GLOBAL_INSERT, 0, "Structure: Global insert", ARRANG_SHRT, "global_insert");
defShrt(SHRT_GLOBAL_SPLIT, 0, "Structure: Global split", ARRANG_SHRT, "global_split");
- defShrt(SHRT_COPY_RANGE, 0, "Edit: Copy in range", ARRANG_SHRT, "copy_range");
defShrt(SHRT_CUT_EVENTS, 0, "Structure: Cut events", ARRANG_SHRT, "cut_events");
//defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, "View: Open mixer window", ARRANG_SHRT, "toggle_mixer");
defShrt(SHRT_OPEN_MIXER, Qt::Key_F10, "View: Open mixer #1 window", ARRANG_SHRT, "toggle_mixer");
@@ -159,7 +160,6 @@ void initShortCuts()
defShrt(SHRT_INSERTMEAS, Qt::CTRL+Qt::SHIFT+ Qt::Key_O, "Edit: Insert empty measure", ARRANG_SHRT, "insert_measure");
- defShrt(SHRT_PASTE_DIALOG, Qt::CTRL+Qt::SHIFT+Qt::Key_V, "Edit: Paste (with dialog)", ARRANG_SHRT, "paste_dialog");
defShrt(SHRT_PASTE_CLONE, Qt::CTRL+Qt::Key_B, "Edit: Paste as clones", ARRANG_SHRT, "paste_as_clone"); // i changed "paste_clone" to "paste_as_clone" intendedly. otherwise muse would keep its old, conflicting definition (ctrl+shift+v instead of ctrl+b) (flo)
defShrt(SHRT_PASTE_CLONE_DIALOG, Qt::CTRL+Qt::SHIFT+Qt::Key_B, "Edit: Paste as clones (with dialog)", ARRANG_SHRT, "paste_as_clone_dialog");
diff --git a/muse2/muse/shortcuts.h b/muse2/muse/shortcuts.h
index ededa796..451c4ec3 100644
--- a/muse2/muse/shortcuts.h
+++ b/muse2/muse/shortcuts.h
@@ -97,8 +97,10 @@ enum {
SHRT_UNDO, //Ctrl+Z
SHRT_REDO, //Ctrl+Y
SHRT_COPY, //Ctrl+C
+ SHRT_COPY_RANGE, //Ctrl+Shift+C
SHRT_CUT, //Ctrl+X
SHRT_PASTE, //Ctrl+V
+ SHRT_PASTE_DIALOG, //Ctrl+Shift+V
SHRT_DELETE,//Delete
@@ -127,7 +129,6 @@ enum {
SHRT_GLOBAL_CUT, //Default: undefined
SHRT_GLOBAL_INSERT, //Default: undefined
SHRT_GLOBAL_SPLIT, //Default: undefined
- SHRT_COPY_RANGE, //Default: Ctrl+Shift+C
SHRT_CUT_EVENTS, //Default: undefined
SHRT_OPEN_TRANSPORT, //F11
@@ -190,7 +191,6 @@ enum {
SHRT_INSERTMEAS, //Ctrl+Shift+M - insert measures
- SHRT_PASTE_DIALOG, //CTRL+SHIFT+_V
SHRT_PASTE_CLONE, //CTRL+B
SHRT_PASTE_CLONE_DIALOG, //CTRL+SHIFT+B
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index 4e934ad0..e5353465 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -63,6 +63,7 @@ QT4_WRAP_CPP (widget_mocs
nentry.h
noteinfo.h
pastedialog.h
+ pasteeventsdialog.h
pitchedit.h
pitchlabel.h
popupmenu.h
@@ -117,6 +118,7 @@ file (GLOB widgets_ui_files
mixdowndialogbase.ui
mtrackinfobase.ui
pastedialogbase.ui
+ pasteeventsdialogbase.ui
projectcreate.ui
shortcutcapturedialogbase.ui
shortcutconfigbase.ui
@@ -165,6 +167,7 @@ file (GLOB widgets_source_files
nentry.cpp
noteinfo.cpp
pastedialog.cpp
+ pasteeventsdialog.cpp
pitchedit.cpp
pitchlabel.cpp
popupmenu.cpp
diff --git a/muse2/muse/widgets/pastedialogbase.ui b/muse2/muse/widgets/pastedialogbase.ui
index a9c7bced..e47f5d2b 100644
--- a/muse2/muse/widgets/pastedialogbase.ui
+++ b/muse2/muse/widgets/pastedialogbase.ui
@@ -77,14 +77,14 @@
<item row="0" column="3">
<widget class="QLabel" name="insert_quarters">
<property name="text">
- <string>1 quarter</string>
+ <string notr="true">1 quarter</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="raster_quarters">
<property name="text">
- <string>1 quarter</string>
+ <string notr="true">1 quarter</string>
</property>
</widget>
</item>
diff --git a/muse2/muse/widgets/pasteeventsdialog.cpp b/muse2/muse/widgets/pasteeventsdialog.cpp
new file mode 100644
index 00000000..be53ef13
--- /dev/null
+++ b/muse2/muse/widgets/pasteeventsdialog.cpp
@@ -0,0 +1,171 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: pasteeventsdialog.cpp,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $
+// (C) Copyright 2011 Florian Jung (flo93@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 <QButtonGroup>
+#include "pasteeventsdialog.h"
+#include "xml.h"
+#include "gconfig.h"
+
+using MusEConfig::config;
+
+PasteEventsDialog::PasteEventsDialog(QWidget* parent)
+ : QDialog(parent)
+{
+ setupUi(this);
+
+ raster_spinbox->setSingleStep(config.division);
+
+ connect(raster_spinbox, SIGNAL(valueChanged(int)), this, SLOT(raster_changed(int)));
+ connect(n_spinbox, SIGNAL(valueChanged(int)), this, SLOT(number_changed(int)));
+ connect(max_distance_spinbox, SIGNAL(valueChanged(int)), this, SLOT(max_distance_changed(int)));
+
+ into_single_part_allowed=true;
+
+ pull_values();
+}
+
+void PasteEventsDialog::pull_values()
+{
+ into_single_part = all_into_selected_part_checkbox->isChecked();
+ always_new_part = always_new_button->isChecked();
+ never_new_part = never_new_button->isChecked();
+
+ int temp = max_distance_spinbox->value();
+ if (temp < 0)
+ max_distance = 0;
+ else
+ max_distance = unsigned(temp);
+
+ number = n_spinbox->value();
+ raster = raster_spinbox->value();
+}
+
+void PasteEventsDialog::accept()
+{
+ pull_values();
+ QDialog::accept();
+}
+
+int PasteEventsDialog::exec()
+{
+ all_into_selected_part_checkbox->setChecked(into_single_part && into_single_part_allowed);
+ all_into_selected_part_checkbox->setEnabled(into_single_part_allowed);
+ into_single_part_allowed=true;
+
+ if (always_new_part)
+ always_new_button->setChecked(true);
+ else if (never_new_part)
+ never_new_button->setChecked(true);
+ else
+ sometimes_into_new_button->setChecked(true);
+
+ max_distance_spinbox->setValue(max_distance);
+
+ n_spinbox->setValue(number);
+ raster_spinbox->setValue(raster);
+
+ return QDialog::exec();
+}
+
+QString PasteEventsDialog::ticks_to_quarter_string(int ticks)
+{
+ if (ticks % config.division == 0)
+ {
+ return tr("%n quarter(s)", "", ticks/config.division);
+ }
+ else
+ {
+ double quarters = (double) ticks/config.division;
+ bool one = ( quarters > 0.995 && quarters < 1.005 );
+ if (one)
+ return QString::number(quarters, 'f', 2) + " " + tr("quarter");
+ else
+ return QString::number(quarters, 'f', 2) + " " + tr("quarters");
+ }
+}
+
+void PasteEventsDialog::max_distance_changed(int d)
+{
+ max_distance_quarters->setText(ticks_to_quarter_string(d));
+}
+
+void PasteEventsDialog::raster_changed(int r)
+{
+ raster_quarters->setText(ticks_to_quarter_string(r));
+ insert_quarters->setText(ticks_to_quarter_string(r*n_spinbox->value()));
+}
+
+void PasteEventsDialog::number_changed(int n)
+{
+ insert_quarters->setText(ticks_to_quarter_string(n*raster_spinbox->value()));
+}
+
+
+void PasteEventsDialog::read_configuration(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 == "number")
+ number=xml.parseInt();
+ else if (tag == "raster")
+ raster=xml.parseInt();
+ else if (tag == "always_new_part")
+ always_new_part=xml.parseInt();
+ else if (tag == "never_new_part")
+ never_new_part=xml.parseInt();
+ else if (tag == "max_distance")
+ max_distance=xml.parseInt();
+ else if (tag == "into_single_part")
+ into_single_part=xml.parseInt();
+ else
+ xml.unknown("PasteEventsDialog");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "pasteeventsdialog")
+ return;
+
+ default:
+ break;
+ }
+ }
+}
+
+void PasteEventsDialog::write_configuration(int level, Xml& xml)
+{
+ xml.tag(level++, "pasteeventsdialog");
+ xml.intTag(level, "number", number);
+ xml.intTag(level, "raster", raster);
+ xml.intTag(level, "always_new_part", always_new_part);
+ xml.intTag(level, "never_new_part", never_new_part);
+ xml.intTag(level, "max_distance", max_distance);
+ xml.intTag(level, "into_single_part", into_single_part);
+ xml.tag(level, "/pasteeventsdialog");
+}
diff --git a/muse2/muse/widgets/pasteeventsdialog.h b/muse2/muse/widgets/pasteeventsdialog.h
new file mode 100644
index 00000000..88971a84
--- /dev/null
+++ b/muse2/muse/widgets/pasteeventsdialog.h
@@ -0,0 +1,65 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: pasteeventsdialog.h,v 1.1.1.1 2011/05/05 18:51:04 flo93 Exp $
+// (C) Copyright 2011 Florian Jung (flo93@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 __PASTEEVENTSDIALOG_H__
+#define __PASTEEVENTSDIALOG_H__
+
+#include "ui_pasteeventsdialogbase.h"
+#include <QString>
+
+class Xml;
+
+class PasteEventsDialog : public QDialog, public Ui::PasteEventsDialogBase
+{
+ Q_OBJECT
+ protected:
+ QString ticks_to_quarter_string(int ticks);
+
+ protected slots:
+ void accept();
+ void pull_values();
+
+ void max_distance_changed(int);
+ void raster_changed(int);
+ void number_changed(int);
+
+ public:
+ PasteEventsDialog(QWidget* parent = 0);
+
+ int number;
+ int raster;
+ bool always_new_part;
+ bool never_new_part;
+ unsigned max_distance;
+ bool into_single_part;
+ bool into_single_part_allowed;
+
+ void read_configuration(Xml& xml);
+ void write_configuration(int level, Xml& xml);
+
+
+ public slots:
+ int exec();
+};
+
+#endif
+
diff --git a/muse2/muse/widgets/pasteeventsdialogbase.ui b/muse2/muse/widgets/pasteeventsdialogbase.ui
new file mode 100644
index 00000000..d1436ded
--- /dev/null
+++ b/muse2/muse/widgets/pasteeventsdialogbase.ui
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasteEventsDialogBase</class>
+ <widget class="QDialog" name="PasteEventsDialogBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>315</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MusE: Paste Events</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="rangeBox">
+ <property name="title">
+ <string>Number and raster</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>insert</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="n_spinbox">
+ <property name="suffix">
+ <string> times</string>
+ </property>
+ <property name="prefix">
+ <string/>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>raster</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="raster_spinbox">
+ <property name="suffix">
+ <string> ticks</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>999999</number>
+ </property>
+ <property name="singleStep">
+ <number>384</number>
+ </property>
+ <property name="value">
+ <number>384</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="insert_quarters">
+ <property name="text">
+ <string notr="true">1 quarter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QLabel" name="raster_quarters">
+ <property name="text">
+ <string notr="true">1 quarter</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Paste options</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QRadioButton" name="never_new_button">
+ <property name="text">
+ <string>Always into existing parts</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="always_new_button">
+ <property name="text">
+ <string>Never into existing parts</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="sometimes_into_new_button">
+ <property name="text">
+ <string>Into existing parts if part has not
+to be expanded by more than </string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="max_distance_spinbox">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="suffix">
+ <string> ticks</string>
+ </property>
+ <property name="maximum">
+ <number>999999</number>
+ </property>
+ <property name="singleStep">
+ <number>384</number>
+ </property>
+ <property name="value">
+ <number>3072</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="max_distance_quarters">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string notr="true"> 1 quarter</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="all_into_selected_part_checkbox">
+ <property name="text">
+ <string>Put everything into the (selected) part</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item>
+ <spacer name="Spacer1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>PasteEventsDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>PasteEventsDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sometimes_into_new_button</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>max_distance_quarters</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>161</x>
+ <y>201</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>260</x>
+ <y>231</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sometimes_into_new_button</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>max_distance_spinbox</receiver>
+ <slot>setEnabled(bool)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>161</x>
+ <y>201</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>107</x>
+ <y>231</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>