On Wednesday 11 June 2003 05:47 am, Levi Burton wrote:
> Well. I uh. Well. I sure feel stupid now.
Attached is a patch which is probably a better solution. It is a fairly large
patch, so beware.
I consolidated all the move code into the SegmentMover tool. SegmentSelector
now grabs a SegmentMover tool and dispatches events to it rather than
handling the move logic in the SegmentSelector tool.
Also, I commented out the delete m_displatchTool code in the
SegmentSelector::handleMouseButtonRelease() code which was causing problems
(segfaults) when doing things like this:
SegmentMover* mover =
dynamic_cast<SegmentResizer*>(getToolBox()->getTool(SegmentMover::ToolName));
It would actually segfault in the call to dynamic_cast. A mystery to me, but
not deleting the tool and just assigning the value 0 to it seems to have
fixed the problem, although there could be ramifications i'm not aware of.
Also, the shift drag copy stuff doesnt seem to work now and I cannot figure
out why. I am sure it is something very simple.
I still think the move guides for multiple segments is weird. Perhaps there
should be fore, aft, top and bottom guides. Also -- why are the guides
QCanvasRectangles rather than QCanvasLines?
--
Levi Burton
http://www.puresimplicity.net/~ldb/
Index: segmenttool.cpp
===================================================================
RCS file: /cvsroot/rosegarden/gui/segmenttool.cpp,v
retrieving revision 1.26
diff -u -r1.26 segmenttool.cpp
--- segmenttool.cpp 7 Jun 2003 22:48:53 -0000 1.26
+++ segmenttool.cpp 13 Jun 2003 05:03:23 -0000
@@ -135,7 +135,9 @@
m_currentItem = item;
if (!item->isSelected()) {
- SegmentSelector* selector = dynamic_cast<SegmentSelector*>(getToolBox()->getTool("segmentselector"));
+ SegmentSelector* selector =
+ dynamic_cast<SegmentSelector*>
+ (getToolBox()->getTool(SegmentSelector::ToolName));
selector->clearSelected();
selector->slotSelectSegmentItem(item);
emit selectedSegments(selector->getSelectedSegments());
@@ -260,7 +262,7 @@
// that the segment was created by this tool rather than by
// e.g. a simple file load
SegmentSelector* selector = dynamic_cast<SegmentSelector*>
- (getToolBox()->getTool("segmentselector"));
+ (getToolBox()->getTool(SegmentSelector::ToolName));
Rosegarden::Segment *segment = command->getSegment();
SegmentItem *item = m_canvas->addSegmentItem(segment);
@@ -382,9 +384,19 @@
SegmentItem *item = m_canvas->findSegmentClickedOn(e->pos());
if (item) {
+ SegmentSelection selection = m_canvas->getSelectedSegments();
+
+ // There has to be a better way.
+ for (SegmentSelection::iterator it = selection.begin();
+ it != selection.end(); it++) {
+ SegmentItem *si = m_canvas->getSegmentItem((*it));
+ m_selectedItems.push_back
+ (SegmentItemPair(QPoint(int(si->x()), int(si->y())), si));
+ }
+
m_currentItem = item;
- m_currentItemStartX = item->x();
- m_clickPoint = e->pos();
+ m_currentItemStartX = item->x();
+ m_clickPoint = e->pos();
m_currentItem->showRepeatRect(false);
m_foreGuide->setX(int(m_canvas->grid().getRulerScale()->
@@ -408,72 +420,134 @@
}
}
+
void SegmentMover::handleMouseButtonRelease(QMouseEvent*)
{
- if (m_currentItem)
- {
- Rosegarden::Composition &comp = m_doc->getComposition();
- Rosegarden::Track *track = comp.getTrackByPosition(
- m_currentItem->getTrackPosition());
- SegmentReconfigureCommand *command =
- new SegmentReconfigureCommand(i18n("Move Segment"));
+ if ( m_currentItem->isSelected() ) {
+ SegmentItemList::iterator it;
- command->addSegment(m_currentItem->getSegment(),
- m_currentItem->getStartTime(),
- m_currentItem->getEndTime(),
- track->getId());
- addCommandToHistory(command);
- m_currentItem->showRepeatRect(true);
+ SegmentReconfigureCommand::SegmentRecSet segmentRecSet;
+ bool haveChange = false;
+
+ SegmentReconfigureCommand *command =
+ new SegmentReconfigureCommand
+ (m_selectedItems.size() == 1 ? i18n("Move Segment") :
+ i18n("Move Segments"));
+
+ for (it = m_selectedItems.begin(); it != m_selectedItems.end(); it++) {
+ SegmentReconfigureCommand::SegmentRec segmentRec;
+ SegmentItem *item = it->second;
+
+ Rosegarden::Composition &comp = m_doc->getComposition();
+ Rosegarden::Track *track =
+ comp.getTrackByPosition(item->getTrackPosition());
+
+ Rosegarden::TrackId trackId = track->getId();
+
+ if (item->getStartTime() != item->getSegment()->getStartTime() ||
+ item->getEndTime() != item->getSegment()->getEndMarkerTime() ||
+ trackId != item->getSegment()->getTrack()) {
+
+ segmentRec.segment = item->getSegment();
+ segmentRec.startTime = item->getStartTime();
+ segmentRec.endTime = item->getEndTime();
+ segmentRec.track = item->getTrackPosition();
+ segmentRecSet.push_back(segmentRec);
+ item->showRepeatRect(true);
+
+ haveChange = true;
+ }
+ }
+
+ if (haveChange) {
+ command->addSegments(segmentRecSet);
+ addCommandToHistory(command);
+ }
+
m_foreGuide->hide();
m_topGuide->hide();
+ m_currentItem = 0;
+ m_selectedItems.clear();
+ m_canvas->canvas()->update();
}
-
- m_currentItem = 0;
}
int SegmentMover::handleMouseMove(QMouseEvent *e)
{
- if (m_currentItem) {
-
- m_canvas->setSnapGrain(true);
-
- int newX = e->x() - m_clickPoint.x() + int(m_currentItemStartX);
- //if (newX < 0) newX = 0;
- int newY = e->y();
- if (newY < 0) newY = 0;
-
- timeT newStartTime = m_canvas->grid().snapX(newX);
- m_currentItem->setEndTime(m_currentItem->getEndTime() + newStartTime -
- m_currentItem->getStartTime());
- m_currentItem->setStartTime(newStartTime);
-
- TrackId track = m_canvas->grid().getYBin(newY);
-
- int nbTracks = m_doc->getComposition().getNbTracks();
-
- if (track >= ((unsigned int)nbTracks)) {
- // Make sure the item isn't dragged to below the last track
- track = nbTracks - 1;
- }
-
- // Don't use proper TrackPosition yet - just visual position
- // until the release.
- //
- m_currentItem->setTrackPosition(track);
-
- m_foreGuide->setX(int(m_canvas->grid().getRulerScale()->
- getXForTime(newStartTime)) - 2);
-
- m_topGuide->setY(m_canvas->grid().getYBinCoordinate(track));
+ m_canvas->setSnapGrain(true);
+ if (m_currentItem->isSelected()) {
+ int guideX = 0;
+ int guideY = 0;
+
+ for (SegmentItemList::iterator it = m_selectedItems.begin();
+ it != m_selectedItems.end(); it++)
+ {
+ int x = e->pos().x() - m_clickPoint.x(),
+ y = e->pos().y() - m_clickPoint.y();
+
+ const int inertiaDistance = m_canvas->grid().getYSnap() / 3;
+ if (!m_passedInertiaEdge &&
+ (x < inertiaDistance && x > -inertiaDistance) &&
+ (y < inertiaDistance && y > -inertiaDistance)) {
+ return false;
+ } else {
+ m_passedInertiaEdge = true;
+ }
+
+
+ timeT newStartTime = m_canvas->grid().snapX(it->first.x() + x);
+ it->second->setEndTime(it->second->getEndTime() + newStartTime -
+ it->second->getStartTime());
+ it->second->setStartTime(newStartTime);
+
+ TrackId track;
+ int newY=it->first.y() + y;
+ // Make sure we don't set a non-existing track
+ if (newY < 0) { newY = 0; }
+ track = m_canvas->grid().getYBin(newY);
+
+ // Make sure we don't set a non-existing track (c'td)
+ // TODO: make this suck less. Either the tool should
+ // not allow it in the first place, or we automatically
+ // create new tracks - might make undo very tricky though
+ //
+ if (track >= TrackId(m_doc->getComposition().getNbTracks()))
+ track = TrackId(m_doc->getComposition().getNbTracks() - 1);
+
+ if (it == m_selectedItems.begin()) {
+ guideX = int(m_canvas->grid().getRulerScale()->
+ getXForTime(newStartTime));
+
+ guideY = m_canvas->grid().getYBinCoordinate(track);
+ }
+ else
+ {
+ if (x < guideX)
+ guideX = int(m_canvas->grid().getRulerScale()->
+ getXForTime(newStartTime));
+
+ if (y < guideY)
+ guideY = m_canvas->grid().getYBinCoordinate(track);
+ }
+
+ // This is during a "mover" so don't use the normalised (i.e.
+ // proper) TrackPosition value yet.
+ //
+ it->second->setTrackPosition(track);
+ }
+
+ m_foreGuide->setX(guideX - 2);
+ m_topGuide->setY(guideY - 2);
+
m_canvas->canvas()->update();
-
- return FollowHorizontal | FollowVertical;
}
-
- return NoFollow;
+
+ m_passedInertiaEdge = false;
+
+ return FollowHorizontal | FollowVertical;
}
//////////////////////////////
@@ -692,57 +766,42 @@
if (threshold == 0) threshold = 1;
if (threshold > 10) threshold = 10;
- if (!m_segmentAddMode &&
- SegmentResizer::cursorIsCloseEnoughToEdge(item, e, threshold)) {
- SegmentResizer* resizer = dynamic_cast<SegmentResizer*>(getToolBox()->getTool(SegmentResizer::ToolName));
- resizer->setEdgeThreshold(threshold);
-
- m_dispatchTool = resizer;
-
- m_dispatchTool->handleMouseButtonPress(e);
- return;
- }
-
+ if (!m_segmentAddMode &&
+ SegmentResizer::cursorIsCloseEnoughToEdge(item, e, threshold)) {
+ SegmentResizer* resizer =
+ dynamic_cast<SegmentResizer*>(getToolBox()->getTool(SegmentResizer::ToolName));
+ if (resizer) {
+ resizer->setEdgeThreshold(threshold);
+ resizer->handleMouseButtonPress(e);
+ m_dispatchTool = resizer;
+ return;
+ }
+ }
// Moving
- //
- m_currentItem = item;
- m_clickPoint = e->pos();
- slotSelectSegmentItem(m_currentItem);
-
- m_foreGuide->setX(int(m_canvas->grid().getRulerScale()->
- getXForTime(item->getSegment()->getStartTime())) -2);
- m_foreGuide->setY(0);
- m_foreGuide->setZ(10);
- m_foreGuide->setSize(2, m_canvas->canvas()->height());
-
- m_topGuide->setX(0);
- m_topGuide->setY(int(m_canvas->grid().getYBinCoordinate(
- item->getSegment()->getTrack())));
- m_topGuide->setZ(10);
- m_topGuide->setSize(m_canvas->canvas()->width(), 2);
-
- m_foreGuide->show();
- m_topGuide->show();
-
- // Don't update until the move - lazy way of making sure the
- // guides don't flash on while we're double clicking
- //
- //m_canvas->canvas()->update();
+ // dispatch to SegmentMover
+ m_dispatchTool = getToolBox()->getTool(SegmentMover::ToolName);
+ if (m_dispatchTool) {
+ m_currentItem = item;
+ m_clickPoint = e->pos();
+ slotSelectSegmentItem(m_currentItem);
+ m_dispatchTool->handleMouseButtonPress(e);
+ return;
+ }
+
} else {
-
// Add on middle button - bounding box on rest
//
- if (e->button() == MidButton) {
- m_dispatchTool = getToolBox()->getTool(SegmentPencil::ToolName);
+ if (e->button() == MidButton) {
+ m_dispatchTool = getToolBox()->getTool(SegmentPencil::ToolName);
if (m_dispatchTool)
m_dispatchTool->handleMouseButtonPress(e);
- return;
- }
+ return;
+ }
else {
// do a bounding box
QCanvasRectangle *rect = m_canvas->getSelectionRectangle();
@@ -760,8 +819,6 @@
// when the list is empty we're just unselecting.
//
emit selectedSegments(getSelectedSegments());
-
- m_passedInertiaEdge = false;
}
SegmentSelection
@@ -825,11 +882,11 @@
m_canvas->canvas()->update();
if (m_dispatchTool) {
- m_dispatchTool->handleMouseButtonRelease(e);
- delete m_dispatchTool;
- m_dispatchTool = 0;
- m_canvas->setCursor(Qt::arrowCursor);
- return;
+ m_dispatchTool->handleMouseButtonRelease(e);
+ // delete m_dispatchTool;
+ m_dispatchTool = 0;
+ m_canvas->setCursor(Qt::arrowCursor);
+ return;
}
if (!m_currentItem) {
@@ -837,61 +894,20 @@
if (rect) {
rect->hide();
- m_canvas->canvas()->update();
+ m_canvas->canvas()->update();
}
return;
}
m_canvas->setCursor(Qt::arrowCursor);
- if (m_currentItem->isSelected())
- {
- SegmentItemList::iterator it;
-
- bool haveChange = false;
-
- SegmentReconfigureCommand *command =
- new SegmentReconfigureCommand
- (m_selectedItems.size() == 1 ? i18n("Move Segment") :
- i18n("Move Segments"));
-
- for (it = m_selectedItems.begin();
- it != m_selectedItems.end();
- it++)
- {
-
- SegmentItem *item = it->second;
-
- Rosegarden::Composition &comp = m_doc->getComposition();
- Rosegarden::Track *track =
- comp.getTrackByPosition(item->getTrackPosition());
-
- Rosegarden::TrackId trackId = track->getId();
-
- if (item->getStartTime() != item->getSegment()->getStartTime() ||
- item->getEndTime() != item->getSegment()->getEndMarkerTime() ||
- trackId != item->getSegment()->getTrack()) {
-
- command->addSegment(item->getSegment(),
- item->getStartTime(),
- item->getEndTime(),
- trackId);
-
- haveChange = true;
- }
- }
-
- if (haveChange) addCommandToHistory(command);
-
- m_canvas->canvas()->update();
- }
// if we've just finished a quick copy then drop the Z level back
if (m_segmentQuickCopyDone)
- {
- m_segmentQuickCopyDone = false;
-// m_currentItem->setZ(2); // see SegmentItem::setSelected --??
- }
+ {
+ m_segmentQuickCopyDone = false;
+ // m_currentItem->setZ(2); // see SegmentItem::setSelected --??
+ }
m_currentItem = 0;
}
@@ -903,7 +919,7 @@
SegmentSelector::handleMouseMove(QMouseEvent *e)
{
if (m_dispatchTool) {
- return m_dispatchTool->handleMouseMove(e);
+ return m_dispatchTool->handleMouseMove(e);
}
if (!m_currentItem) {
@@ -922,7 +938,7 @@
if (h > 0) ++h; else --h;
selectionRect->setSize(w, h);
- m_canvas->canvas()->update();
+ m_canvas->canvas()->update();
// Get collisions and do selection
//
@@ -936,14 +952,14 @@
if (l.count()) {
for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
- {
- if (SegmentItem *item = dynamic_cast<SegmentItem*>(*it))
{
- segCount++;
- slotSelectSegmentItem(item);
- newSelection.insert(item->getSegment());
+ if (SegmentItem *item = dynamic_cast<SegmentItem*>(*it))
+ {
+ segCount++;
+ slotSelectSegmentItem(item);
+ newSelection.insert(item->getSegment());
+ }
}
- }
}
// Check for unselected items with this piece of crap
@@ -951,30 +967,30 @@
bool found = false;
for (SegmentSelection::const_iterator oIt = oldSelection.begin();
- oIt != oldSelection.end(); oIt++)
- {
- found = false;
- for (SegmentSelection::const_iterator nIt = newSelection.begin();
- nIt != newSelection.end(); nIt++)
+ oIt != oldSelection.end(); oIt++)
{
- if (*oIt == *nIt)
- {
- found = true;
- break;
- }
- }
- if (found == false)
- {
- removeFromSelection(*oIt);
- m_canvas->getSegmentItem(*oIt)->
- setSelected(false, m_canvas->getSegmentBrush());
+ found = false;
+ for (SegmentSelection::const_iterator nIt = newSelection.begin();
+ nIt != newSelection.end(); nIt++)
+ {
+ if (*oIt == *nIt)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found == false)
+ {
+ removeFromSelection(*oIt);
+ m_canvas->getSegmentItem(*oIt)->
+ setSelected(false, m_canvas->getSegmentBrush());
+ }
}
- }
if (segCount)
- {
- emit selectedSegments(getSelectedSegments());
- }
+ {
+ emit selectedSegments(getSelectedSegments());
+ }
}
return FollowHorizontal | FollowVertical;
}
@@ -982,112 +998,39 @@
m_canvas->setCursor(Qt::sizeAllCursor);
if (m_segmentCopyMode && !m_segmentQuickCopyDone)
- {
- KMacroCommand *mcommand = new KMacroCommand
- (SegmentQuickCopyCommand::getGlobalName());
-
- SegmentItemList::iterator it;
- for (it = m_selectedItems.begin();
- it != m_selectedItems.end();
- it++)
- {
- SegmentQuickCopyCommand *command =
- new SegmentQuickCopyCommand(it->second->getSegment());
-
- mcommand->addCommand(command);
- }
-
- addCommandToHistory(mcommand);
-
-// Rosegarden::Segment *newSegment = command->getCopy();
+ {
+ KMacroCommand *mcommand = new KMacroCommand
+ (SegmentQuickCopyCommand::getGlobalName());
+
+ SegmentItemList::iterator it;
+ for (it = m_selectedItems.begin();
+ it != m_selectedItems.end();
+ it++)
+ {
+ SegmentQuickCopyCommand *command =
+ new SegmentQuickCopyCommand(it->second->getSegment());
- // generate SegmentItem
- //
- m_canvas->updateAllSegmentItems();
- m_segmentQuickCopyDone = true;
+ mcommand->addCommand(command);
+ }
- // Don't understand why swapping selected item is causing
- // problem hereafter - so leaving this commented out.
- //
- //SegmentItem *newItem = m_canvas->getSegmentItem(newSegment);
- //clearSelected();
- //m_currentItem = newItem;
- //m_currentItem->setZ(3); // bring it to the top
- //slotSelectSegmentItem(newItem);
- }
+ addCommandToHistory(mcommand);
- m_canvas->setSnapGrain(true);
+ // Rosegarden::Segment *newSegment = command->getCopy();
- if (m_currentItem->isSelected())
- {
- SegmentItemList::iterator it;
- int guideX = 0;
- int guideY = 0;
-
- for (it = m_selectedItems.begin();
- it != m_selectedItems.end();
- it++)
- {
- int x = e->pos().x() - m_clickPoint.x(),
- y = e->pos().y() - m_clickPoint.y();
-
- const int inertiaDistance = m_canvas->grid().getYSnap() / 3;
- if (!m_passedInertiaEdge &&
- (x < inertiaDistance && x > -inertiaDistance) &&
- (y < inertiaDistance && y > -inertiaDistance)) {
- return false;
- } else {
- m_passedInertiaEdge = true;
- }
-
-
- timeT newStartTime = m_canvas->grid().snapX(it->first.x() + x);
- it->second->setEndTime(it->second->getEndTime() + newStartTime -
- it->second->getStartTime());
- it->second->setStartTime(newStartTime);
-
- TrackId track;
- int newY=it->first.y() + y;
- // Make sure we don't set a non-existing track
- if (newY < 0) { newY = 0; }
- track = m_canvas->grid().getYBin(newY);
-
- // Make sure we don't set a non-existing track (c'td)
- // TODO: make this suck less. Either the tool should
- // not allow it in the first place, or we automatically
- // create new tracks - might make undo very tricky though
+ // generate SegmentItem
//
- if (track >= TrackId(m_doc->getComposition().getNbTracks()))
- track = TrackId(m_doc->getComposition().getNbTracks() - 1);
-
- if (it == m_selectedItems.begin())
- {
- guideX = int(m_canvas->grid().getRulerScale()->
- getXForTime(newStartTime));
-
- guideY = m_canvas->grid().getYBinCoordinate(track);
- }
- else
- {
- if (x < guideX)
- guideX = int(m_canvas->grid().getRulerScale()->
- getXForTime(newStartTime));
+ m_canvas->updateAllSegmentItems();
+ m_segmentQuickCopyDone = true;
- if (y < guideY)
- guideY = m_canvas->grid().getYBinCoordinate(track);
- }
-
- // This is during a "mover" so don't use the normalised (i.e.
- // proper) TrackPosition value yet.
+ // Don't understand why swapping selected item is causing
+ // problem hereafter - so leaving this commented out.
//
- it->second->setTrackPosition(track);
- }
-
- m_foreGuide->setX(guideX - 2);
- m_topGuide->setY(guideY - 2);
-
- m_canvas->canvas()->update();
- }
+ //SegmentItem *newItem = m_canvas->getSegmentItem(newSegment);
+ //clearSelected();
+ //m_currentItem = newItem;
+ //m_currentItem->setZ(3); // bring it to the top
+ //slotSelectSegmentItem(newItem);
+ }
return FollowHorizontal | FollowVertical;
}
Index: segmenttool.h
===================================================================
RCS file: /cvsroot/rosegarden/gui/segmenttool.h,v
retrieving revision 1.9
diff -u -r1.9 segmenttool.h
--- segmenttool.h 27 Apr 2003 15:47:45 -0000 1.9
+++ segmenttool.h 13 Jun 2003 05:03:23 -0000
@@ -170,11 +170,15 @@
protected:
SegmentMover(SegmentCanvas*, RosegardenGUIDoc*);
+ typedef std::pair<QPoint, SegmentItem *> SegmentItemPair;
+ typedef std::vector<SegmentItemPair> SegmentItemList;
+
//--------------- Data members ---------------------------------
QPoint m_clickPoint;
double m_currentItemStartX;
-
+ SegmentItemList m_selectedItems;
+ bool m_passedInertiaEdge;
QCanvasRectangle *m_foreGuide;
QCanvasRectangle *m_topGuide;
@@ -285,7 +289,7 @@
bool m_segmentCopyMode;
QPoint m_clickPoint;
bool m_segmentQuickCopyDone;
- bool m_passedInertiaEdge;
+
SegmentTool *m_dispatchTool;