diff options
author | Florian Jung <flo@windfisch.org> | 2011-09-11 15:34:52 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-09-11 15:34:52 +0000 |
commit | 253b9d9f1a17b98f3f6696f456e9d83f1ac9aee3 (patch) | |
tree | 0b32703e2bee9fb8135295671f7f2b7194cd2aaa | |
parent | 5f5a8e76f19d6956f6d711979877028f07203d88 (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.pro | 3 | ||||
-rw-r--r-- | muse2/muse/dialogs.cpp | 6 | ||||
-rw-r--r-- | muse2/muse/dialogs.h | 2 | ||||
-rw-r--r-- | muse2/muse/functions.cpp | 18 | ||||
-rw-r--r-- | muse2/muse/functions.h | 1 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.h | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/drumedit.cpp | 11 | ||||
-rw-r--r-- | muse2/muse/midiedit/drumedit.h | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/pianoroll.cpp | 12 | ||||
-rw-r--r-- | muse2/muse/midiedit/pianoroll.h | 1 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.h | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 21 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 3 | ||||
-rw-r--r-- | muse2/muse/shortcuts.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/shortcuts.h | 4 | ||||
-rw-r--r-- | muse2/muse/widgets/CMakeLists.txt | 3 | ||||
-rw-r--r-- | muse2/muse/widgets/pastedialogbase.ui | 4 | ||||
-rw-r--r-- | muse2/muse/widgets/pasteeventsdialog.cpp | 171 | ||||
-rw-r--r-- | muse2/muse/widgets/pasteeventsdialog.h | 65 | ||||
-rw-r--r-- | muse2/muse/widgets/pasteeventsdialogbase.ui | 383 |
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> |