📄 notationselector.cpp
字号:
} if (clefEvt) clef = Clef(*clefEvt); if (keyEvt) key = ::Rosegarden::Key(*keyEvt); int height = targetStaff->getHeightAtCanvasCoords(x, y); int pitch = clickedPitch; if (height != clickedHeight) pitch = Pitch (height, clef, key, clickedAccidental).getPerformancePitch(); if (pitch < clickedPitch) { if (height < -10) { height = -10; pitch = Pitch (height, clef, key, clickedAccidental).getPerformancePitch(); } } else if (pitch > clickedPitch) { if (height > 18) { height = 18; pitch = Pitch (height, clef, key, clickedAccidental).getPerformancePitch(); } } bool singleNonNotePreview = !m_clickedElement->isNote() && selection->getSegmentEvents().size() == 1; if (!final && !singleNonNotePreview) { if ((pitch != m_lastDragPitch || dragTime != m_lastDragTime) && m_clickedElement->isNote()) { m_nParentView->showPreviewNote(targetStaff->getId(), layoutX, pitch, height, Note::getNearestNote(duration)); m_lastDragPitch = pitch; m_lastDragTime = dragTime; } } else { m_nParentView->clearPreviewNote(); KMacroCommand *command = new KMacroCommand(MoveCommand::getGlobalName()); bool haveSomething = false; MoveCommand *mc = 0; Event *lastInsertedEvent = 0; if (pitch != clickedPitch && m_clickedElement->isNote()) { command->addCommand(new TransposeCommand(pitch - clickedPitch, *selection)); haveSomething = true; } if (targetStaff != m_selectedStaff) { command->addCommand(new MoveAcrossSegmentsCommand (m_selectedStaff->getSegment(), targetStaff->getSegment(), dragTime - clickedTime + selection->getStartTime(), true, *selection)); haveSomething = true; } else { if (dragTime != clickedTime) { mc = new MoveCommand (m_selectedStaff->getSegment(), //!!!sort dragTime - clickedTime, true, *selection); command->addCommand(mc); haveSomething = true; } } if (haveSomething) { m_nParentView->addCommandToHistory(command); if (mc && singleNonNotePreview) { lastInsertedEvent = mc->getLastInsertedEvent(); if (lastInsertedEvent) { m_nParentView->setSingleSelectedEvent(targetStaff->getId(), lastInsertedEvent); ViewElementList::iterator vli = targetStaff->findEvent(lastInsertedEvent); if (vli != targetStaff->getViewElementList()->end()) { m_clickedElement = dynamic_cast<NotationElement *>(*vli); } else { m_clickedElement = 0; } m_selectionRect->setX(x); m_selectionRect->setY(y); } } } else { delete command; } }}void NotationSelector::dragFine(int x, int y, bool final){ NOTATION_DEBUG << "NotationSelector::drag " << x << ", " << y << endl; if (!m_clickedElement || !m_selectedStaff) return ; EventSelection *selection = m_nParentView->getCurrentSelection(); if (!selection) selection = new EventSelection(m_selectedStaff->getSegment()); if (!selection->contains(m_clickedElement->event())) selection->addEvent(m_clickedElement->event()); m_nParentView->setCurrentSelection(selection); // Fine drag modifies the DISPLACED_X and DISPLACED_Y properties on // each event. The modifications have to be relative to the previous // values of these properties, not to zero, so for each event we need // to store the previous value at the time the drag starts. static PropertyName xProperty("temporary-displaced-x"); static PropertyName yProperty("temporary-displaced-y"); if (!m_startedFineDrag) { // back up original properties for (EventSelection::eventcontainer::iterator i = selection->getSegmentEvents().begin(); i != selection->getSegmentEvents().end(); ++i) { long prevX = 0, prevY = 0; (*i)->get <Int>(DISPLACED_X, prevX); (*i)->get <Int>(DISPLACED_Y, prevY); (*i)->setMaybe<Int>(xProperty, prevX); (*i)->setMaybe<Int>(yProperty, prevY); } m_startedFineDrag = true; } // We want the displacements in 1/1000ths of a staff space double dx = x - m_selectionRect->x(); double dy = y - m_selectionRect->y(); double noteBodyWidth = m_nParentView->getNotePixmapFactory()->getNoteBodyWidth(); double lineSpacing = m_nParentView->getNotePixmapFactory()->getLineSpacing(); dx = (1000.0 * dx) / noteBodyWidth; dy = (1000.0 * dy) / lineSpacing; if (final) { // reset original values (and remove backup values) before // applying command for (EventSelection::eventcontainer::iterator i = selection->getSegmentEvents().begin(); i != selection->getSegmentEvents().end(); ++i) { long prevX = 0, prevY = 0; (*i)->get <Int>(xProperty, prevX); (*i)->get <Int>(yProperty, prevY); (*i)->setMaybe<Int>(DISPLACED_X, prevX); (*i)->setMaybe<Int>(DISPLACED_Y, prevY); (*i)->unset(xProperty); (*i)->unset(yProperty); } IncrementDisplacementsCommand *command = new IncrementDisplacementsCommand (*selection, long(dx), long(dy)); m_nParentView->addCommandToHistory(command); } else { timeT startTime = 0, endTime = 0; for (EventSelection::eventcontainer::iterator i = selection->getSegmentEvents().begin(); i != selection->getSegmentEvents().end(); ++i) { long prevX = 0, prevY = 0; (*i)->get <Int>(xProperty, prevX); (*i)->get <Int>(yProperty, prevY); (*i)->setMaybe<Int>(DISPLACED_X, prevX + long(dx)); (*i)->setMaybe<Int>(DISPLACED_Y, prevY + long(dy)); if (i == selection->getSegmentEvents().begin()) { startTime = (*i)->getAbsoluteTime(); } endTime = (*i)->getAbsoluteTime() + (*i)->getDuration(); } if (startTime == endTime) ++endTime; selection->getSegment().updateRefreshStatuses(startTime, endTime); m_nParentView->update(); }}void NotationSelector::ready(){ m_selectionRect = new QCanvasRectangle(m_nParentView->canvas()); m_selectionRect->hide(); m_selectionRect->setPen(GUIPalette::getColour(GUIPalette::SelectionRectangle)); m_nParentView->setCanvasCursor(Qt::arrowCursor); m_nParentView->setHeightTracking(false);}void NotationSelector::stow(){ delete m_selectionRect; m_selectionRect = 0; m_nParentView->canvas()->update();}void NotationSelector::slotHideSelection(){ if (!m_selectionRect) return ; m_selectionRect->hide(); m_selectionRect->setSize(0, 0); m_nParentView->canvas()->update();}void NotationSelector::slotInsertSelected(){ m_nParentView->slotLastNoteAction();}void NotationSelector::slotEraseSelected(){ m_parentView->actionCollection()->action("erase")->activate();}void NotationSelector::slotCollapseRestsHard(){ m_parentView->actionCollection()->action("collapse_rests_aggressively")->activate();}void NotationSelector::slotRespellFlat(){ m_parentView->actionCollection()->action("respell_flat")->activate();}void NotationSelector::slotRespellSharp(){ m_parentView->actionCollection()->action("respell_sharp")->activate();}void NotationSelector::slotRespellNatural(){ m_parentView->actionCollection()->action("respell_natural")->activate();}void NotationSelector::slotCollapseNotes(){ m_parentView->actionCollection()->action("collapse_notes")->activate();}void NotationSelector::slotInterpret(){ m_parentView->actionCollection()->action("interpret")->activate();}void NotationSelector::slotMakeInvisible(){ m_parentView->actionCollection()->action("make_invisible")->activate();}void NotationSelector::slotMakeVisible(){ m_parentView->actionCollection()->action("make_visible")->activate();}void NotationSelector::setViewCurrentSelection(bool preview){ EventSelection *selection = getSelection(); if (m_selectionToMerge) { if (selection && m_selectionToMerge->getSegment() == selection->getSegment()) { selection->addFromSelection(m_selectionToMerge); } else { return ; } } m_nParentView->setCurrentSelection(selection, preview, true);}NotationStaff *NotationSelector::getStaffForElement(NotationElement *elt){ for (int i = 0; i < m_nParentView->getStaffCount(); ++i) { NotationStaff *staff = m_nParentView->getNotationStaff(i); if (staff->getSegment().findSingle(elt->event()) != staff->getSegment().end()) return staff; } return 0;}EventSelection* NotationSelector::getSelection(){ // If selection rect is not visible or too small, // return 0 // if (!m_selectionRect->visible()) return 0; // NOTATION_DEBUG << "Selection x,y: " << m_selectionRect->x() << "," // << m_selectionRect->y() << "; w,h: " << m_selectionRect->width() << "," << m_selectionRect->height() << endl; if (m_selectionRect->width() > -3 && m_selectionRect->width() < 3 && m_selectionRect->height() > -3 && m_selectionRect->height() < 3) return 0; QCanvasItemList itemList = m_selectionRect->collisions(false); QCanvasItemList::Iterator it; QRect rect = m_selectionRect->rect().normalize(); QCanvasNotationSprite *sprite = 0; if (!m_selectedStaff) { // Scan the list of collisions, looking for a valid notation // element; if we find one, initialise m_selectedStaff from it. // If we don't find one, we have no selection. This is a little // inefficient but we only do it for the first event in the // selection. for (it = itemList.begin(); it != itemList.end(); ++it) { if ((sprite = dynamic_cast<QCanvasNotationSprite*>(*it))) { NotationElement &el = sprite->getNotationElement(); NotationStaff *staff = getStaffForElement(&el); if (!staff) continue; int x = (int)(*it)->x(); bool shifted = false; int nbw = staff->getNotePixmapFactory(false).getNoteBodyWidth(); // #957364 (Notation: Hard to select upper note in // chords of seconds) -- adjust x-coord for shifted // note head if (el.event()->get<Rosegarden::Bool> (staff->getProperties().NOTE_HEAD_SHIFTED, shifted) && shifted) { x += nbw; } if (!rect.contains(x, int((*it)->y()), true)) { // #988217 (Notation: Special column of pixels // prevents sweep selection) -- for notes, test // again with centred x-coord if (!el.isNote() || !rect.contains(x + nbw/2, int((*it)->y()), true)) { continue; } } m_selectedStaff = staff; break; } } } if (!m_selectedStaff) return 0; Segment& originalSegment = m_selectedStaff->getSegment(); // If we selected the whole staff, force that to happen explicitly // rather than relying on collisions with the rectangle -- because // events way off the currently visible area might not even have // been drawn yet, and so will not appear in the collision list. // (We did still need the collision list to determine which staff // to use though.) if (m_wholeStaffSelectionComplete) { EventSelection *selection = new EventSelection(originalSegment, originalSegment.getStartTime(), originalSegment.getEndMarkerTime()); return selection; } EventSelection* selection = new EventSelection(originalSegment); for (it = itemList.begin(); it != itemList.end(); ++it) { if ((sprite = dynamic_cast<QCanvasNotationSprite*>(*it))) { NotationElement &el = sprite->getNotationElement(); int x = (int)(*it)->x(); bool shifted = false; int nbw = m_selectedStaff->getNotePixmapFactory(false).getNoteBodyWidth(); // #957364 (Notation: Hard to select upper note in chords // of seconds) -- adjust x-coord for shifted note head if (el.event()->get<Rosegarden::Bool> (m_selectedStaff->getProperties().NOTE_HEAD_SHIFTED, shifted) && shifted) { x += nbw; } // check if the element's rect // is actually included in the selection rect. // if (!rect.contains(x, int((*it)->y()), true)) { // #988217 (Notation: Special column of pixels // prevents sweep selection) -- for notes, test again // with centred x-coord if (!el.isNote() || !rect.contains(x + nbw/2, int((*it)->y()), true)) { continue; } } // must be in the same segment as we first started on, // we can't select events across multiple segments if (selection->getSegment().findSingle(el.event()) != selection->getSegment().end()) { selection->addEvent(el.event()); } } } if (selection->getAddedEvents() > 0) { return selection; } else { delete selection; return 0; }}const QString NotationSelector::ToolName = "notationselector";}#include "NotationSelector.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -