summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-11-28 11:38:56 +0000
committerWerner Schweer <ws.seh.de>2006-11-28 11:38:56 +0000
commitcc3f817f58d4c9d33e03b2aafd9e53b352041028 (patch)
tree1aa42e77599c71865a1443707a4daf466bf3e38e
parent776dc95b628074122e7a71d493e2993e9c8686fd (diff)
part drag& drop
-rw-r--r--muse/ChangeLog2
-rw-r--r--muse/muse/arranger/canvas.cpp165
-rw-r--r--muse/muse/arranger/canvas.h2
-rw-r--r--muse/muse/arranger/partdrag.cpp50
-rw-r--r--muse/muse/miditrack.cpp2
-rw-r--r--muse/muse/part.cpp8
-rw-r--r--muse/muse/part.h2
-rw-r--r--muse/muse/songfile.cpp1
-rw-r--r--muse/muse/songpart.cpp2
-rw-r--r--muse/muse/wavetrack.cpp2
10 files changed, 151 insertions, 85 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index 08f9772c..f7abcbf7 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,5 @@
+28.11 (ws)
+ - application spanning drag&drop of parts
24.11 (ws)
- added new make target: "doxy" to generate doxygen source
documentation
diff --git a/muse/muse/arranger/canvas.cpp b/muse/muse/arranger/canvas.cpp
index cd871963..1bcc3d71 100644
--- a/muse/muse/arranger/canvas.cpp
+++ b/muse/muse/arranger/canvas.cpp
@@ -760,14 +760,20 @@ void PartCanvas::mouseMove(QPoint pos)
//
// drag whole part
//
+ srcPart = part;
QDrag* d = 0;
if (track->type() == Track::MIDI)
- d = new MidiPartDrag(part, this);
+ d = new MidiPartDrag(srcPart, this);
else if (track->type() == Track::WAVE)
- d = new AudioPartDrag(part, this);
+ d = new AudioPartDrag(srcPart, this);
if (d) {
+ Qt::KeyboardModifiers kb = QApplication::keyboardModifiers();
+ Qt::DropActions da = kb ? (Qt::MoveAction | Qt::CopyAction | Qt::LinkAction) : Qt::MoveAction;
+ song->startUndo();
_dragOffset = startDrag.x() - rCanvasA.x() - ppos;
- /* Qt::DropAction da =*/ d->start(Qt::CopyAction | Qt::LinkAction | Qt::MoveAction);
+ if (d->start(da) == Qt::MoveAction)
+ song->removePart(srcPart);
+ song->endUndo(0);
update = true;
}
state = S_NORMAL;
@@ -951,7 +957,13 @@ void PartCanvas::dragEnter(QDragEnterEvent* event)
if (MidiPartDrag::canDecode(md)
|| AudioPartDrag::canDecode(md)
|| WavUriDrag::canDecode(md)) {
- event->acceptProposedAction();
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions())) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ else
+ event->acceptProposedAction();
}
else {
QStringList formats = md->formats();
@@ -966,37 +978,32 @@ void PartCanvas::dragEnter(QDragEnterEvent* event)
void PartCanvas::dragMove(QDragMoveEvent* event)
{
+ QPoint p(event->pos() - rCanvasA.topLeft());
+ searchPart(p);
+ if (!track) {
+ if (state != S_NORMAL) {
+ state = S_NORMAL;
+ widget()->update();
+ }
+ event->ignore();
+ return;
+ }
+
Part* srcPart = 0;
QString filename;
+ bool srcIsMidi;
const QMimeData* md = event->mimeData();
if (MidiPartDrag::canDecode(md)) {
MidiPartDrag::decode(md, srcPart);
+ srcIsMidi = true;
}
else if (AudioPartDrag::canDecode(md)) {
AudioPartDrag::decode(md, srcPart);
+ srcIsMidi = false;
}
else if (WavUriDrag::canDecode(md)) {
WavUriDrag::decode(md, &filename);
- }
- else {
- state = S_NORMAL;
- event->ignore();
- return;
- }
- Track* srcTrack = srcPart ? srcPart->track() : 0;
-
- QPoint p(event->pos() - rCanvasA.topLeft());
- searchPart(p);
- if (!track) {
- if (state != S_NORMAL) {
- state = S_NORMAL;
- widget()->update();
- }
- event->ignore();
- return;
- }
- if (srcTrack == 0) { // drag uri
if (state != S_NORMAL) {
state = S_NORMAL;
widget()->update();
@@ -1007,7 +1014,14 @@ void PartCanvas::dragMove(QDragMoveEvent* event)
event->ignore();
return;
}
- if (track->type() != srcTrack->type()) {
+ else {
+ state = S_NORMAL;
+ event->ignore();
+ return;
+ }
+
+ bool dstIsMidi = track->type() == Track::MIDI;
+ if (dstIsMidi != srcIsMidi) {
if (state != S_NORMAL) {
state = S_NORMAL;
widget()->update();
@@ -1015,20 +1029,31 @@ void PartCanvas::dragMove(QDragMoveEvent* event)
event->ignore();
return;
}
- event->acceptProposedAction();
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions())) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ else
+ event->acceptProposedAction();
state = S_DRAG4;
ArrangerTrack* at = &(track->arrangerTrack);
PartCanvas* cw = (PartCanvas*)event->source();
QRect updateRect(drag);
- Pos pos(pix2pos(p.x() - cw->dragOffset()).snaped(raster()));
+ Pos pos;
+ if (cw)
+ pos = pix2pos(p.x() - cw->dragOffset()).snaped(raster());
+ else
+ pos = pix2pos(p.x()).snaped(raster());
drag.setRect(
pos2pix(pos),
at->tw->y(),
rmapx(srcPart->lenTick()),
at->tw->height() - 1 - partBorderWidth
);
+ delete srcPart;
updateRect |= drag;
updateRect.adjust(-1, -1 + rCanvasA.y(), 1, 1 + rCanvasA.y());
widget()->update(updateRect);
@@ -1041,54 +1066,66 @@ void PartCanvas::dragMove(QDragMoveEvent* event)
void PartCanvas::drop(QDropEvent* event)
{
state = S_NORMAL;
- Part* srcPart = 0;
+ Part* dstPart = 0;
QString filename;
+ QPoint pos(event->pos() - rCanvasA.topLeft());
const QMimeData* md = event->mimeData();
- if (MidiPartDrag::canDecode(md)) {
- MidiPartDrag::decode(md, srcPart);
- }
- else if (AudioPartDrag::canDecode(md)) {
- AudioPartDrag::decode(md, srcPart);
- }
- else if (WavUriDrag::canDecode(md)) {
+ if (WavUriDrag::canDecode(md)) {
WavUriDrag::decode(md, &filename);
- }
- else
+ int tick = AL::sigmap.raster(mapxDev(pos.x()), raster());
+ Pos pos(tick);
+ muse->importWaveToTrack(filename, track, pos);
+ widget()->update();
return;
+ }
+
+ bool isMidi = false;
+ if (MidiPartDrag::canDecode(md)) {
+ MidiPartDrag::decode(md, dstPart);
+ isMidi = true;
+ }
+ else if (AudioPartDrag::canDecode(md))
+ AudioPartDrag::decode(md, dstPart);
- QPoint pos(event->pos() - rCanvasA.topLeft());
searchPart(pos);
- Track* srcTrack = srcPart ? srcPart->track() : 0;
- if (track == 0 || (srcTrack && (track->type() != srcTrack->type())))
+ if (!track || !dstPart || isMidi != track->isMidiTrack())
return;
- if (srcPart == 0) {
- int tick = AL::sigmap.raster(mapxDev(pos.x()), raster());
- Pos pos(tick);
- muse->importWaveToTrack(filename, track, pos);
- }
- else {
- PartCanvas* cw = (PartCanvas*)event->source();
- unsigned tick = AL::sigmap.raster(mapxDev(pos.x() - cw->dragOffset()), raster());
- if (srcPart->tick() != tick || srcTrack != track) {
- Qt::KeyboardModifiers keyState = event->keyboardModifiers();
-
- if (keyState & Qt::ShiftModifier) {
- song->cmdCopyPart(srcPart, tick, track);
- event->setDropAction(Qt::CopyAction);
- }
- else if (keyState & Qt::ControlModifier) {
- song->cmdLinkPart(srcPart, tick, track);
- event->setDropAction(Qt::LinkAction);
- }
- else {
- song->cmdMovePart(srcPart, tick, track);
- event->setDropAction(Qt::MoveAction);
- }
- }
+ dstPart->setTrack(track);
+ PartCanvas* cw = (PartCanvas*)event->source();
+
+ //
+ // cw == 0 means that we are dropping to
+ // another application
+
+ unsigned tick;
+ if (cw)
+ tick = AL::sigmap.raster(mapxDev(pos.x() - cw->dragOffset()), raster());
+ else
+ tick = AL::sigmap.raster(mapxDev(pos.x()), raster());
+
+ dstPart->setTick(tick);
+
+ Qt::DropAction da = event->proposedAction();
+ Qt::KeyboardModifiers kb = event->keyboardModifiers();
+ if (kb == 0 && (Qt::MoveAction & event->possibleActions()))
+ da = Qt::MoveAction;
+
+ if ((da == Qt::LinkAction) && (event->source() == this)) {
+ delete dstPart->events();
+ dstPart->clone(srcPart->events());
+ event->setDropAction(Qt::LinkAction);
}
- event->acceptProposedAction();
+ else if (da == Qt::MoveAction)
+ event->setDropAction(Qt::MoveAction);
+ else
+ event->setDropAction(Qt::CopyAction);
+ event->accept();
+ if (cw)
+ song->addPart(dstPart);
+ else
+ song->cmdAddPart(dstPart);
widget()->update();
}
diff --git a/muse/muse/arranger/canvas.h b/muse/muse/arranger/canvas.h
index 8ecd3abe..032292af 100644
--- a/muse/muse/arranger/canvas.h
+++ b/muse/muse/arranger/canvas.h
@@ -63,6 +63,8 @@ class PartCanvas : public TimeCanvas {
Part* part;
ArrangerTrack* at;
+ Part* srcPart; // src part of a drag/drop operation
+
bool _drawBackground;
int selected;
int lselected; // in local coordinates
diff --git a/muse/muse/arranger/partdrag.cpp b/muse/muse/arranger/partdrag.cpp
index a09d9d3b..e497b613 100644
--- a/muse/muse/arranger/partdrag.cpp
+++ b/muse/muse/arranger/partdrag.cpp
@@ -19,8 +19,8 @@
//=============================================================================
#include "partdrag.h"
-
-class Part;
+#include "al/xml.h"
+#include "part.h"
const char MidiPartDrag::type[] = "application/muse/part/midi";
const char AudioPartDrag::type[] = "application/muse/part/audio";
@@ -36,9 +36,13 @@ const char WavUriDrag::type[] = "text/uri-list";
MidiPartDrag::MidiPartDrag(Part* part, QWidget* src)
: QDrag(src)
{
- QByteArray a((const char*)&part, sizeof(part));
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ AL::Xml xml(&buffer);
+ part->write(xml);
+ buffer.close();
QMimeData* mimeData = new QMimeData;
- mimeData->setData(type, a);
+ mimeData->setData(type, buffer.buffer());
setMimeData(mimeData);
}
@@ -57,11 +61,31 @@ bool MidiPartDrag::canDecode(const QMimeData* s)
bool MidiPartDrag::decode(const QMimeData* s, Part*& p)
{
- QByteArray a = s->data(type);
- char* cp = (char*)(&p);
- for (unsigned i = 0; i < sizeof(p); ++i)
- *cp++ = a[i];
- return true;
+ p = 0;
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(s->data(type), false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + "\n at line: " + ln + " col: " + col;
+ printf("error parsing part: %s\n", error.toLatin1().data());
+ return false;
+ }
+ for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "part") {
+ p = new Part(0);
+ p->ref();
+ p->read(node, true);
+ }
+ else
+ printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
+ }
+ return (p != 0);
}
//---------------------------------------------------------
@@ -74,10 +98,14 @@ bool MidiPartDrag::decode(const QMimeData* s, Part*& p)
AudioPartDrag::AudioPartDrag(Part* part, QWidget* src)
: QDrag(src)
{
- QByteArray a((char*)&part, sizeof(part));
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ Xml xml(&buffer);
+ part->write(xml);
+ buffer.close();
QMimeData* mimeData = new QMimeData;
- mimeData->setData(type, a);
+ mimeData->setData(type, buffer.buffer());
setMimeData(mimeData);
}
diff --git a/muse/muse/miditrack.cpp b/muse/muse/miditrack.cpp
index 742e24e1..e96f53ef 100644
--- a/muse/muse/miditrack.cpp
+++ b/muse/muse/miditrack.cpp
@@ -131,7 +131,7 @@ void MidiTrack::read(QDomNode node)
_compression = i;
else if (tag == "part") {
Part* p = newPart();
- p->read(node);
+ p->read(node, true);
parts()->add(p);
}
else if (tag == "locked")
diff --git a/muse/muse/part.cpp b/muse/muse/part.cpp
index e52b1309..30daed4f 100644
--- a/muse/muse/part.cpp
+++ b/muse/muse/part.cpp
@@ -63,7 +63,7 @@ Part::Part(Track* t)
_fillLen = 0;
_track = t;
_events = 0;
- if (_track->type() == Track::WAVE)
+ if (_track && _track->type() == Track::WAVE)
setType(AL::FRAMES);
}
@@ -244,7 +244,7 @@ void Part::write(Xml& xml)
// Part::read
//---------------------------------------------------------
-void Part::read(QDomNode node)
+void Part::read(QDomNode node, bool isMidiPart)
{
QDomElement e = node.toElement();
int id = e.attribute("cloneId", "-1").toInt();
@@ -280,9 +280,7 @@ void Part::read(QDomNode node)
else if (tag == "fillLen")
_fillLen = i;
else if (tag == "event") {
- EventType type = Wave;
- if (_track->isMidiTrack())
- type = Note;
+ EventType type = isMidiPart ? Note : Wave;
Event e(type);
e.read(node);
// tickpos is relative to start of part
diff --git a/muse/muse/part.h b/muse/muse/part.h
index 8a7c80f0..fd5fdd52 100644
--- a/muse/muse/part.h
+++ b/muse/muse/part.h
@@ -120,7 +120,7 @@ class Part : public AL::PosLen {
int fillLen() const { return _fillLen; }
void setFillLen(int val) { _fillLen = val; }
- void read(QDomNode);
+ void read(QDomNode, bool isMidiPart);
void write(Xml&);
void dump(int n = 0) const;
diff --git a/muse/muse/songfile.cpp b/muse/muse/songfile.cpp
index 187132e3..fa62d4f2 100644
--- a/muse/muse/songfile.cpp
+++ b/muse/muse/songfile.cpp
@@ -26,7 +26,6 @@
#include "midiedit/drummap.h"
#include "al/marker.h"
#include "midictrl.h"
-// #include "mixer/mixer.h"
#include "conf.h"
#include "midiseq.h"
#include "al/tempo.h"
diff --git a/muse/muse/songpart.cpp b/muse/muse/songpart.cpp
index 6ad52f47..e561476b 100644
--- a/muse/muse/songpart.cpp
+++ b/muse/muse/songpart.cpp
@@ -117,7 +117,7 @@ void Song::removePart(Part* part)
audio->sendMessage(&msg, false);
undoOp(UndoOp::DeletePart, part);
updateFlags |= SC_PART_REMOVED;
-// part->deref();
+ part->deref();
part->track()->partListChanged();
}
diff --git a/muse/muse/wavetrack.cpp b/muse/muse/wavetrack.cpp
index 47187364..750c805a 100644
--- a/muse/muse/wavetrack.cpp
+++ b/muse/muse/wavetrack.cpp
@@ -157,7 +157,7 @@ void WaveTrack::read(QDomNode node)
if (e.tagName() == "part") {
Part* p = newPart();
p->ref();
- p->read(node);
+ p->read(node, false);
parts()->add(p);
}
else if (AudioTrack::readProperties(node))