diff options
Diffstat (limited to 'src/gui/editors/parameters/SegmentParameterBox.cpp')
-rw-r--r-- | src/gui/editors/parameters/SegmentParameterBox.cpp | 1214 |
1 files changed, 1214 insertions, 0 deletions
diff --git a/src/gui/editors/parameters/SegmentParameterBox.cpp b/src/gui/editors/parameters/SegmentParameterBox.cpp new file mode 100644 index 0000000..c17cbe2 --- /dev/null +++ b/src/gui/editors/parameters/SegmentParameterBox.cpp @@ -0,0 +1,1214 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Rosegarden + A MIDI and audio sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <glaurent@telegraph-road.org>, + Chris Cannam <cannam@all-day-breakfast.com>, + Richard Bown <richard.bown@ferventsoftware.com> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + 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; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "SegmentParameterBox.h" +#include <qlayout.h> +#include <kapplication.h> + +#include <klocale.h> +#include "misc/Debug.h" +#include "misc/Strings.h" +#include "document/ConfigGroups.h" +#include "base/Colour.h" +#include "base/ColourMap.h" +#include "base/Composition.h" +#include "base/MidiProgram.h" +#include "base/NotationTypes.h" +#include "base/BasicQuantizer.h" +#include "base/RealTime.h" +#include "base/Segment.h" +#include "base/Selection.h" +#include "commands/segment/SegmentChangeQuantizationCommand.h" +#include "commands/segment/SegmentColourCommand.h" +#include "commands/segment/SegmentColourMapCommand.h" +#include "commands/segment/SegmentCommandRepeat.h" +#include "commands/segment/SegmentLabelCommand.h" +#include "document/MultiViewCommandHistory.h" +#include "document/RosegardenGUIDoc.h" +#include "gui/dialogs/PitchPickerDialog.h" +#include "gui/editors/notation/NotationStrings.h" +#include "gui/editors/notation/NotePixmapFactory.h" +#include "gui/general/GUIPalette.h" +#include "gui/widgets/ColourTable.h" +#include "gui/widgets/TristateCheckBox.h" +#include "RosegardenParameterArea.h" +#include "RosegardenParameterBox.h" +#include <kcolordialog.h> +#include <kcombobox.h> +#include <kcommand.h> +#include <kconfig.h> +#include <klineeditdlg.h> +#include <ktabwidget.h> +#include <qbutton.h> +#include <qcheckbox.h> +#include <qcolor.h> +#include <qdialog.h> +#include <qfont.h> +#include <qfontmetrics.h> +#include <qframe.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qpushbutton.h> +#include <qscrollview.h> +#include <qspinbox.h> +#include <qstring.h> +#include <qtooltip.h> +#include <qvbox.h> +#include <qwidget.h> +#include <qwidgetstack.h> + + +namespace Rosegarden +{ + +SegmentParameterBox::SegmentParameterBox(RosegardenGUIDoc* doc, + QWidget *parent) + : RosegardenParameterBox(i18n("Segment"), + i18n("Segment Parameters"), + parent), + m_highestPlayable(127), + m_lowestPlayable(0), + m_standardQuantizations(BasicQuantizer::getStandardQuantizations()), + m_doc(doc), + m_transposeRange(48) +{ + initBox(); + + m_doc->getComposition().addObserver(this); + + connect(getCommandHistory(), SIGNAL(commandExecuted()), + this, SLOT(update())); +} + +SegmentParameterBox::~SegmentParameterBox() +{ + if (!isCompositionDeleted()) { + m_doc->getComposition().removeObserver(this); + } +} + +void +SegmentParameterBox::initBox() +{ + QFont font(m_font); + + QFontMetrics fontMetrics(font); + // magic numbers: 13 is the height of the menu pixmaps, 10 is just 10 + //int comboHeight = std::max(fontMetrics.height(), 13) + 10; + int width = fontMetrics.width("12345678901234567890"); + + // QFrame *frame = new QFrame(this); + QGridLayout *gridLayout = new QGridLayout(this, 8, 6, 4, 2); + + QLabel *label = new QLabel(i18n("Label"), this); + QLabel *repeatLabel = new QLabel(i18n("Repeat"), this); + QLabel *quantizeLabel = new QLabel(i18n("Quantize"), this); + QLabel *transposeLabel = new QLabel(i18n("Transpose"), this); + QLabel *delayLabel = new QLabel(i18n("Delay"), this); + QLabel *colourLabel = new QLabel(i18n("Color"), this); +// m_autoFadeLabel = new QLabel(i18n("Audio auto-fade"), this); +// m_fadeInLabel = new QLabel(i18n("Fade in"), this); +// m_fadeOutLabel = new QLabel(i18n("Fade out"), this); +// m_rangeLabel = new QLabel(i18n("Range"), this); + + // Label .. + m_label = new QLabel(this); + m_label->setFont(font); + m_label->setFixedWidth(width); + //m_label->setFixedHeight(comboHeight); + m_label->setFrameStyle(QFrame::Panel | QFrame::Sunken); + + // .. and edit button + m_labelButton = new QPushButton(i18n("Edit"), this); + m_labelButton->setFont(font); + // m_labelButton->setFixedWidth(50); + + connect(m_labelButton, SIGNAL(released()), + SLOT(slotEditSegmentLabel())); + + m_repeatValue = new TristateCheckBox(this); + m_repeatValue->setFont(font); + //m_repeatValue->setFixedHeight(comboHeight); + + // handle state changes + connect(m_repeatValue, SIGNAL(pressed()), SLOT(slotRepeatPressed())); + + // non-reversing motif style read-only combo + m_quantizeValue = new KComboBox(this); + m_quantizeValue->setFont(font); + //m_quantizeValue->setFixedHeight(comboHeight); + + // handle quantize changes from drop down + connect(m_quantizeValue, SIGNAL(activated(int)), + SLOT(slotQuantizeSelected(int))); + + // reversing motif style read-write combo + m_transposeValue = new KComboBox(this); + m_transposeValue->setFont(font); + //m_transposeValue->setFixedHeight(comboHeight); + + // handle transpose combo changes + connect(m_transposeValue, SIGNAL(activated(int)), + SLOT(slotTransposeSelected(int))); + + // and text changes + connect(m_transposeValue, SIGNAL(textChanged(const QString&)), + SLOT(slotTransposeTextChanged(const QString&))); + + // reversing motif style read-write combo + m_delayValue = new KComboBox(this); + m_delayValue->setFont(font); + //m_delayValue->setFixedHeight(comboHeight); + + // handle delay combo changes + connect(m_delayValue, SIGNAL(activated(int)), + SLOT(slotDelaySelected(int))); + + // Detect when the document colours are updated + connect(m_doc, SIGNAL(docColoursChanged()), + this, SLOT(slotDocColoursChanged())); + + // handle text changes for delay + connect(m_delayValue, SIGNAL(textChanged(const QString&)), + SLOT(slotDelayTextChanged(const QString &))); + + // set up combo box for colours + m_colourValue = new KComboBox(false, this); + m_colourValue->setFont(font); + //m_colourValue->setFixedHeight(comboHeight); + // m_colourValue->setMaximumWidth(width); + m_colourValue->setSizeLimit(20); + + // handle colour combo changes + connect(m_colourValue, SIGNAL(activated(int)), + SLOT(slotColourSelected(int))); + + // pre-set width of buttons so they don't grow later +// width = fontMetrics.width(i18n("used internally for spacing", "High: ----")); + + // highest playable note + // +// m_highButton = new QPushButton(i18n("High: ---"), this); +// QToolTip::add +// (m_highButton, i18n("Choose the highest suggested playable note, using a staff")); +// m_highButton->setFont(font); +// m_highButton->setMinimumWidth(width); + +// connect(m_highButton, SIGNAL(released()), +// SLOT(slotHighestPressed())); + + // lowest playable note + // +// m_lowButton = new QPushButton(i18n("Low: ----"), this); +// QToolTip::add +// (m_lowButton, i18n("Choose the lowest suggested playable note, using a staff")); +// m_lowButton->setFont(font); +// m_lowButton->setMinimumWidth(width); + +// connect(m_lowButton, SIGNAL(released()), +// SLOT(slotLowestPressed())); + + // Audio autofade enabled + // +// m_autoFadeBox = new QCheckBox(this); +// connect(m_autoFadeBox, SIGNAL(stateChanged(int)), +// this, SLOT(slotAudioFadeChanged(int))); + + // Fade in and out times + // +// m_fadeInSpin = new QSpinBox(this); +// m_fadeInSpin->setMinValue(0); +// m_fadeInSpin->setMaxValue(5000); +// m_fadeInSpin->setSuffix(i18n(" ms")); +// connect(m_fadeInSpin, SIGNAL(valueChanged(int)), +// this, SLOT(slotFadeInChanged(int))); + +// m_fadeOutSpin = new QSpinBox(this); +// m_fadeOutSpin->setMinValue(0); +// m_fadeOutSpin->setMaxValue(5000); +// m_fadeOutSpin->setSuffix(i18n(" ms")); +// connect(m_fadeOutSpin, SIGNAL(valueChanged(int)), +// this, SLOT(slotFadeOutChanged(int))); + + label->setFont(font); + repeatLabel->setFont(font); + quantizeLabel->setFont(font); + transposeLabel->setFont(font); + delayLabel->setFont(font); + colourLabel->setFont(font); +// m_autoFadeLabel->setFont(font); +// m_fadeInLabel->setFont(font); +// m_fadeOutLabel->setFont(font); +// m_rangeLabel->setFont(font); + + int row = 0; + +// gridLayout->addRowSpacing(0, 12); // why?? + + gridLayout->addWidget(label, row, 0); //, AlignRight); + gridLayout->addMultiCellWidget(m_label, row, row, 1, 4); //, AlignLeft); + gridLayout->addWidget(m_labelButton, row, 5); //, AlignLeft); + ++row; + + gridLayout->addWidget(repeatLabel, row, 0); //, AlignRight); + gridLayout->addWidget(m_repeatValue, row, 1); //, AlignLeft); + + gridLayout->addMultiCellWidget(transposeLabel, row, row, 2, 3, AlignRight); + gridLayout->addMultiCellWidget(m_transposeValue, row, row, 4, 5); + ++row; + + gridLayout->addWidget(quantizeLabel, row, 0); //, AlignRight); + gridLayout->addMultiCellWidget(m_quantizeValue, row, row, 1, 2); //, AlignLeft); + + gridLayout->addWidget(delayLabel, row, 3, AlignRight); + gridLayout->addMultiCellWidget(m_delayValue, row, row, 4, 5); + ++row; + + gridLayout->addWidget(colourLabel, row, 0); //, AlignRight); + gridLayout->addMultiCellWidget(m_colourValue, row, row, 1, 5); + ++row; + +// gridLayout->addWidget(m_rangeLabel, row, 0); //, AlignRight); +// gridLayout->addMultiCellWidget(m_lowButton, row, row, 1, 2); +// gridLayout->addMultiCellWidget(m_highButton, row, row, 3, 4); +// ++row; + +// m_autoFadeLabel->hide(); +// m_autoFadeBox->hide(); + /* + gridLayout->addWidget(m_fadeInLabel, 5, 0, AlignRight); + gridLayout->addWidget(m_fadeInSpin, 5, 1); + + gridLayout->addWidget(m_fadeOutLabel, 5, 2, AlignRight); + gridLayout->addWidget(m_fadeOutSpin, 5, 3); + */ + // Configure the empty final row to accomodate any extra vertical space. + + gridLayout->setRowStretch(gridLayout->numRows() - 1, 1); + + // Configure the empty final column to accomodate any extra horizontal + // space. + +// gridLayout->setColStretch(gridLayout->numCols() - 1, 1); + + // populate the quantize combo + // + QPixmap noMap = NotePixmapFactory::toQPixmap(NotePixmapFactory::makeToolbarPixmap("menu-no-note")); + + for (unsigned int i = 0; i < m_standardQuantizations.size(); ++i) { + + timeT time = m_standardQuantizations[i]; + timeT error = 0; + QString label = NotationStrings::makeNoteMenuLabel(time, true, error); + QPixmap pmap = NotePixmapFactory::toQPixmap(NotePixmapFactory::makeNoteMenuPixmap(time, error)); + m_quantizeValue->insertItem(error ? noMap : pmap, label); + } + m_quantizeValue->insertItem(noMap, i18n("Off")); + + // default to last item + m_quantizeValue->setCurrentItem(m_quantizeValue->count() - 1); + + // populate the transpose combo + // + for (int i = -m_transposeRange; i < m_transposeRange + 1; i++) { + m_transposeValue->insertItem(noMap, QString("%1").arg(i)); + if (i == 0) + m_transposeValue->setCurrentItem(m_transposeValue->count() - 1); + } + + m_delays.clear(); + + for (int i = 0; i < 6; i++) { + timeT time = 0; + if (i > 0 && i < 6) { + time = Note(Note::Hemidemisemiquaver).getDuration() << (i - 1); + } else if (i > 5) { + time = Note(Note::Crotchet).getDuration() * (i - 4); + } + + m_delays.push_back(time); + + // check if it's a valid note duration (it will be for the + // time defn above, but if we were basing it on the sequencer + // resolution it might not be) & include a note pixmap if so + // + timeT error = 0; + QString label = NotationStrings::makeNoteMenuLabel(time, true, error); + QPixmap pmap = NotePixmapFactory::toQPixmap(NotePixmapFactory::makeNoteMenuPixmap(time, error)); + m_delayValue->insertItem((error ? noMap : pmap), label); + } + + for (int i = 0; i < 10; i++) { + int rtd = (i < 5 ? ((i + 1) * 10) : ((i - 3) * 50)); + m_realTimeDelays.push_back(rtd); + m_delayValue->insertItem(i18n("%1 ms").arg(rtd)); + } + + // set delay blank initially + m_delayValue->setCurrentItem( -1); + + // populate m_colourValue + slotDocColoursChanged(); + + //!!! disabled until after 1.3 +// m_highButton->hide(); +// m_lowButton->hide(); +// m_rangeLabel->hide(); + ////////////////////////////// + +} + +void +SegmentParameterBox::setDocument(RosegardenGUIDoc* doc) +{ + if (m_doc != 0) + disconnect(m_doc, SIGNAL(docColoursChanged()), + this, SLOT(slotDocColoursChanged())); + + m_doc = doc; + + // Detect when the document colours are updated + connect (m_doc, SIGNAL(docColoursChanged()), + this, SLOT(slotDocColoursChanged())); + + slotDocColoursChanged(); // repopulate combo +} + +void +SegmentParameterBox::useSegment(Segment *segment) +{ + m_segments.clear(); + m_segments.push_back(segment); + populateBoxFromSegments(); +} + +void +SegmentParameterBox::useSegments(const SegmentSelection &segments) +{ + m_segments.clear(); + + m_segments.resize(segments.size()); + std::copy(segments.begin(), segments.end(), m_segments.begin()); + + populateBoxFromSegments(); +} + +void +SegmentParameterBox::slotDocColoursChanged() +{ + RG_DEBUG << "SegmentParameterBox::slotDocColoursChanged()" << endl; + + m_colourValue->clear(); + m_colourList.clear(); + // Populate it from composition.m_segmentColourMap + ColourMap temp = m_doc->getComposition().getSegmentColourMap(); + + unsigned int i = 0; + + for (RCMap::const_iterator it = temp.begin(); it != temp.end(); ++it) { + QString qtrunc(strtoqstr(it->second.second)); + QPixmap colour(15, 15); + colour.fill(GUIPalette::convertColour(it->second.first)); + if (qtrunc == "") { + m_colourValue->insertItem(colour, i18n("Default"), i); + } else { + // truncate name to 15 characters to avoid the combo forcing the + // whole kit and kaboodle too wide + if (qtrunc.length() > 15) + qtrunc = qtrunc.left(12) + "..."; + m_colourValue->insertItem(colour, qtrunc, i); + } + m_colourList[it->first] = i; // maps colour number to menu index + ++i; + } + + m_addColourPos = i; + m_colourValue->insertItem(i18n("Add New Color"), m_addColourPos); + + m_colourValue->setCurrentItem(0); +} + +void SegmentParameterBox::update() +{ + RG_DEBUG << "SegmentParameterBox::update()" << endl; + + populateBoxFromSegments(); +} + +void +SegmentParameterBox::segmentRemoved(const Composition *composition, + Segment *segment) +{ + if (composition == &m_doc->getComposition()) { + + for (std::vector<Segment*>::iterator it = + m_segments.begin(); it != m_segments.end(); ++it) { + + if (*it == segment) { + m_segments.erase(it); + return ; + } + } + } +} + +void +SegmentParameterBox::populateBoxFromSegments() +{ + std::vector<Segment*>::iterator it; + Tristate repeated = NotApplicable; + Tristate quantized = NotApplicable; + Tristate transposed = NotApplicable; + Tristate delayed = NotApplicable; + Tristate diffcolours = NotApplicable; + Tristate highlow = NotApplicable; + unsigned int myCol = 0; + unsigned int myHigh = 127; + unsigned int myLow = 0; + + timeT qntzLevel = 0; + // At the moment we have no negative delay, so we use negative + // values to represent real-time delay in ms + timeT delayLevel = 0; + int transposeLevel = 0; + + if (m_segments.size() == 0) + m_label->setText(""); + else + m_label->setText(strtoqstr(m_segments[0]->getLabel())); + + for (it = m_segments.begin(); it != m_segments.end(); it++) { + // ok, first thing is we know we have at least one segment + if (repeated == NotApplicable) + repeated = None; + if (quantized == NotApplicable) + quantized = None; + if (transposed == NotApplicable) + transposed = None; + if (delayed == NotApplicable) + delayed = None; + if (diffcolours == NotApplicable) + diffcolours = None; + if (highlow == NotApplicable) + highlow = None; + + // Set label to "*" when multiple labels don't match + // + if (strtoqstr((*it)->getLabel()) != m_label->text()) + m_label->setText("*"); + + // Are all, some or none of the Segments repeating? + if ((*it)->isRepeating()) { + if (it == m_segments.begin()) + repeated = All; + else { + if (repeated == None) + repeated = Some; + } + } else { + if (repeated == All) + repeated = Some; + } + + // Quantization + // + if ((*it)->hasQuantization()) { + if (it == m_segments.begin()) { + quantized = All; + qntzLevel = (*it)->getQuantizer()->getUnit(); + } else { + // If quantize levels don't match + if (quantized == None || + (quantized == All && + qntzLevel != + (*it)->getQuantizer()->getUnit())) + quantized = Some; + } + } else { + if (quantized == All) + quantized = Some; + } + + // Transpose + // + if ((*it)->getTranspose() != 0) { + if (it == m_segments.begin()) { + transposed = All; + transposeLevel = (*it)->getTranspose(); + } else { + if (transposed == None || + (transposed == All && + transposeLevel != (*it)->getTranspose())) + transposed = Some; + } + + } else { + if (transposed == All) + transposed = Some; + } + + // Delay + // + timeT myDelay = (*it)->getDelay(); + if (myDelay == 0) { + myDelay = -((*it)->getRealTimeDelay().sec * 1000 + + (*it)->getRealTimeDelay().msec()); + } + + if (myDelay != 0) { + if (it == m_segments.begin()) { + delayed = All; + delayLevel = myDelay; + } else { + if (delayed == None || + (delayed == All && + delayLevel != myDelay)) + delayed = Some; + } + } else { + if (delayed == All) + delayed = Some; + } + + // Colour + + if (it == m_segments.begin()) { + myCol = (*it)->getColourIndex(); + } else { + if (myCol != (*it)->getColourIndex()) + ; + diffcolours = All; + } + + // Highest/Lowest playable + // + if (it == m_segments.begin()) { + myHigh = (*it)->getHighestPlayable(); + myLow = (*it)->getLowestPlayable(); + } else { + if (myHigh != (*it)->getHighestPlayable() || + myLow != (*it)->getLowestPlayable()) { + highlow = All; + } + } + + } + + switch (repeated) { + case All: + m_repeatValue->setChecked(true); + break; + + case Some: + m_repeatValue->setNoChange(); + break; + + case None: + case NotApplicable: + default: + m_repeatValue->setChecked(false); + break; + } + + m_repeatValue->setEnabled(repeated != NotApplicable); + + switch (quantized) { + case All: { + for (unsigned int i = 0; + i < m_standardQuantizations.size(); ++i) { + if (m_standardQuantizations[i] == qntzLevel) { + m_quantizeValue->setCurrentItem(i); + break; + } + } + } + break; + + case Some: + // Set the edit text to an unfeasible blank value meaning "Some" + // + m_quantizeValue->setCurrentItem( -1); + break; + + // Assuming "Off" is always the last field + case None: + default: + m_quantizeValue->setCurrentItem(m_quantizeValue->count() - 1); + break; + } + + m_quantizeValue->setEnabled(quantized != NotApplicable); + + switch (transposed) { + // setCurrentItem works with QStrings + // 2nd arg of "true" means "add if necessary" + case All: + m_transposeValue-> + setCurrentItem(QString("%1").arg(transposeLevel), true); + break; + + case Some: + m_transposeValue->setCurrentItem(QString(""), true); + break; + + case None: + default: + m_transposeValue->setCurrentItem("0"); + break; + } + + m_transposeValue->setEnabled(transposed != NotApplicable); + + m_delayValue->blockSignals(true); + + switch (delayed) { + case All: + if (delayLevel >= 0) { + timeT error = 0; + QString label = NotationStrings::makeNoteMenuLabel(delayLevel, + true, + error); + m_delayValue->setCurrentItem(label, true); + + } else if (delayLevel < 0) { + + m_delayValue->setCurrentItem(i18n("%1 ms").arg( -delayLevel), + true); + } + + break; + + case Some: + m_delayValue->setCurrentItem("", true); + break; + + case None: + default: + m_delayValue->setCurrentItem(0); + break; + } + + m_delayValue->setEnabled(delayed != NotApplicable); + + m_delayValue->blockSignals(false); + + switch (diffcolours) { + case None: + if (m_colourList.find(myCol) != m_colourList.end()) + m_colourValue->setCurrentItem(m_colourList[myCol]); + else + m_colourValue->setCurrentItem(0); + break; + + + case All: + case NotApplicable: + default: + m_colourValue->setCurrentItem(0); + break; + + } + + m_colourValue->setEnabled(diffcolours != NotApplicable); + + //!!! this is all borked up and useless; sort out after 1.3 +/* + switch (highlow) { + case All: + updateHighLow(); + break; + + case Some: + case None: + default: + m_highButton->setText(i18n("High: ---")); + m_lowButton->setText(i18n("Low: ----")); + highlow = NotApplicable; + break; + } + + m_highButton->setEnabled(highlow != NotApplicable); + m_lowButton->setEnabled(highlow != NotApplicable); +*/ + + // Enable or disable the fade in/out params +/* + if (m_segments.size() == 1 && + (*(m_segments.begin()))->getType() == Segment::Audio) { + m_autoFadeBox->blockSignals(true); + m_fadeInSpin->blockSignals(true); + m_fadeOutSpin->blockSignals(true); + + ... !!! No, not setting up autofade widgets. The implementation's too + incomplete to finish for this release. + + (Or for the next one after the one the previous comment referred to.) + + (Or for the one after the one after that. Will we ever get those + working, or should Rich's final legacy simply be quietly disappeared?) + + m_fadeInLabel->show(); + m_fadeInSpin->show(); + m_fadeOutLabel->show(); + m_fadeOutSpin->show(); + + instead: + + m_fadeInLabel->hide(); + m_fadeInSpin->hide(); + m_fadeOutLabel->hide(); + m_fadeOutSpin->hide(); + + m_autoFadeLabel->setEnabled(true); + m_autoFadeBox->setEnabled(true); + m_fadeInLabel->setEnabled(true); + m_fadeInSpin->setEnabled(true); + m_fadeOutLabel->setEnabled(true); + m_fadeOutSpin->setEnabled(true); + + Segment *seg = *(m_segments.begin()); + + int fadeInTime = seg->getFadeInTime().sec * 1000 + + seg->getFadeInTime().msec(); + m_fadeInSpin->setValue(fadeInTime); + + int fadeOutTime = seg->getFadeOutTime().sec * 1000 + + seg->getFadeOutTime().msec(); + m_fadeOutSpin->setValue(fadeOutTime); + + m_autoFadeBox->setChecked(seg->isAutoFading()); + + m_autoFadeBox->blockSignals(false); + m_fadeInSpin->blockSignals(false); + m_fadeOutSpin->blockSignals(false); + } else { + m_autoFadeLabel->setEnabled(false); + m_autoFadeBox->setEnabled(false); + m_fadeInLabel->setEnabled(false); + m_fadeInSpin->setEnabled(false); + m_fadeOutLabel->setEnabled(false); + m_fadeOutSpin->setEnabled(false); + + m_autoFadeLabel->hide(); + m_autoFadeBox->hide(); + m_fadeInLabel->hide(); + m_fadeInSpin->hide(); + m_fadeOutLabel->hide(); + m_fadeOutSpin->hide(); + + m_autoFadeBox->setChecked(false); + m_fadeInSpin->setValue(0); + m_fadeOutSpin->setValue(0); + } +*/ + +} + +void SegmentParameterBox::slotRepeatPressed() +{ + if (m_segments.size() == 0) + return ; + + bool state = false; + + switch (m_repeatValue->state()) { + case QButton::Off: + state = true; + break; + + case QButton::NoChange: + case QButton::On: + default: + state = false; + break; + } + + // update the check box and all current Segments + m_repeatValue->setChecked(state); + + addCommandToHistory(new SegmentCommandRepeat(m_segments, state)); + + // std::vector<Segment*>::iterator it; + + // for (it = m_segments.begin(); it != m_segments.end(); it++) + // (*it)->setRepeating(state); +} + +void +SegmentParameterBox::slotQuantizeSelected(int qLevel) +{ + bool off = (qLevel == m_quantizeValue->count() - 1); + + SegmentChangeQuantizationCommand *command = + new SegmentChangeQuantizationCommand + (off ? 0 : m_standardQuantizations[qLevel]); + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + command->addSegment(*it); + } + + addCommandToHistory(command); +} + +void +SegmentParameterBox::slotTransposeTextChanged(const QString &text) +{ + if (text.isEmpty() || m_segments.size() == 0) + return ; + + int transposeValue = text.toInt(); + + // addCommandToHistory(new SegmentCommandChangeTransposeValue(m_segments, + // transposeValue)); + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setTranspose(transposeValue); + } + + emit documentModified(); +} + +void +SegmentParameterBox::slotTransposeSelected(int value) +{ + slotTransposeTextChanged(m_transposeValue->text(value)); +} + +void +SegmentParameterBox::slotDelayTimeChanged(timeT delayValue) +{ + // by convention and as a nasty hack, we use negative timeT here + // to represent positive RealTime in ms + + if (delayValue > 0) { + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setDelay(delayValue); + (*it)->setRealTimeDelay(RealTime::zeroTime); + } + + } else if (delayValue < 0) { + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setDelay(0); + int sec = ( -delayValue) / 1000; + int nsec = (( -delayValue) - 1000 * sec) * 1000000; + (*it)->setRealTimeDelay(RealTime(sec, nsec)); + } + } else { + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setDelay(0); + (*it)->setRealTimeDelay(RealTime::zeroTime); + } + } + + emit documentModified(); +} + +void +SegmentParameterBox::slotDelayTextChanged(const QString &text) +{ + if (text.isEmpty() || m_segments.size() == 0) + return ; + + slotDelayTimeChanged( -(text.toInt())); +} + +void +SegmentParameterBox::slotDelaySelected(int value) +{ + if (value < int(m_delays.size())) { + slotDelayTimeChanged(m_delays[value]); + } else { + slotDelayTimeChanged( -(m_realTimeDelays[value - m_delays.size()])); + } +} + +void +SegmentParameterBox::slotColourSelected(int value) +{ + if (value != m_addColourPos) { + unsigned int temp = 0; + + ColourTable::ColourList::const_iterator pos; + for (pos = m_colourList.begin(); pos != m_colourList.end(); ++pos) { + if (pos->second == value) { + temp = pos->first; + break; + } + } + + SegmentSelection segments; + std::vector<Segment*>::iterator it; + + for (it = m_segments.begin(); it != m_segments.end(); ++it) { + segments.insert(*it); + } + + SegmentColourCommand *command = new SegmentColourCommand(segments, temp); + + addCommandToHistory(command); + } else { + ColourMap newMap = m_doc->getComposition().getSegmentColourMap(); + QColor newColour; + bool ok = false; + QString newName = KLineEditDlg::getText(i18n("New Color Name"), i18n("Enter new name"), + i18n("New"), &ok); + if ((ok == true) && (!newName.isEmpty())) { + KColorDialog box(this, "", true); + + int result = box.getColor(newColour); + + if (result == KColorDialog::Accepted) { + Colour newRColour = GUIPalette::convertColour(newColour); + newMap.addItem(newRColour, qstrtostr(newName)); + SegmentColourMapCommand *command = new SegmentColourMapCommand(m_doc, newMap); + addCommandToHistory(command); + slotDocColoursChanged(); + } + } + // Else we don't do anything as they either didn't give a name· + // or didn't give a colour + } + + +} + +void +SegmentParameterBox::updateHighLow() +{ + // Key of C major and NoAccidental means any "black key" notes will be + // written as sharps. + Accidental accidental = Accidentals::NoAccidental; + Rosegarden::Key key = Rosegarden::Key("C major"); + + Pitch highest(m_highestPlayable, accidental); + Pitch lowest(m_lowestPlayable, accidental); + + KConfig *config = kapp->config(); + config->setGroup(GeneralOptionsConfigGroup); + int base = config->readNumEntry("midipitchoctave", -2); + //!!! FIXME this code is broken, and needs to be fixed after the fashion of + //the TPB, but I'm not bothering with that at this time, because they are + //going to be hidden for 1.3 anyway +// m_highButton->setText(QString("&High: %1%2").arg(highest.getNoteName(key)).arg(highest.getOctave(base))); +// m_lowButton->setText(QString("&Low: %1%2").arg(lowest.getNoteName(key)).arg(lowest.getOctave(base))); +} + +void +SegmentParameterBox::slotHighestPressed() +{ + RG_DEBUG << "SegmentParameterBox::slotHighestPressed()" << endl; + + PitchPickerDialog dialog(0, m_highestPlayable, i18n("Highest playable note")); + std::vector<Segment*>::iterator it; + + if (dialog.exec() == QDialog::Accepted) { + m_highestPlayable = dialog.getPitch(); + updateHighLow(); + + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setHighestPlayable(m_highestPlayable); + } + + emit documentModified(); + } +} + +void +SegmentParameterBox::slotLowestPressed() +{ + RG_DEBUG << "SegmentParameterBox::slotLowestPressed()" << endl; + + PitchPickerDialog dialog(0, m_lowestPlayable, i18n("Lowest playable note")); + std::vector<Segment*>::iterator it; + + if (dialog.exec() == QDialog::Accepted) { + m_lowestPlayable = dialog.getPitch(); + updateHighLow(); + + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setLowestPlayable(m_lowestPlayable); + } + + emit documentModified(); + } +} + +MultiViewCommandHistory* +SegmentParameterBox::getCommandHistory() +{ + return m_doc->getCommandHistory(); +} + +void +SegmentParameterBox::addCommandToHistory(KCommand *command) +{ + m_doc->getCommandHistory()->addCommand(command); +} + +void +SegmentParameterBox::slotEditSegmentLabel() +{ + QString editLabel; + + if (m_segments.size() == 0) + return ; + else if (m_segments.size() == 1) + editLabel = i18n("Modify Segment label"); + else + editLabel = i18n("Modify Segments label"); + + bool ok = false; + + // Remove the asterisk if we're using it + // + QString label = m_label->text(); + if (label == "*") + label = ""; + + QString newLabel = KLineEditDlg::getText(editLabel, + i18n("Enter new label"), + m_label->text(), + &ok, + this); + + if (ok) { + SegmentSelection segments; + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); ++it) + segments.insert(*it); + + SegmentLabelCommand *command = new + SegmentLabelCommand(segments, newLabel); + + addCommandToHistory(command); + + // fix #1776915, maybe? + update(); + } +} + +void +SegmentParameterBox::slotAudioFadeChanged(int value) +{ + RG_DEBUG << "SegmentParameterBox::slotAudioFadeChanged - value = " + << value << endl; +/* + if (m_segments.size() == 0) + return ; + + bool state = false; + if (value == QButton::On) + state = true; + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setAutoFade(state); + } +*/ +} + +void +SegmentParameterBox::slotFadeInChanged(int value) +{ + RG_DEBUG << "SegmentParameterBox::slotFadeInChanged - value = " + << value << endl; +/* + if (m_segments.size() == 0) + return ; + + if (value == 0 && m_fadeOutSpin->value() == 0) + slotAudioFadeChanged(QButton::Off); + else + slotAudioFadeChanged(QButton::On); + + // Convert from ms + // + RealTime fadeInTime(value / 1000, (value % 1000) * 1000000); + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setFadeInTime(fadeInTime); + } + + emit documentModified(); +*/ +} + +void +SegmentParameterBox::slotFadeOutChanged(int value) +{ + RG_DEBUG << "SegmentParameterBox::slotFadeOutChanged - value = " + << value << endl; +/* + if (m_segments.size() == 0) + return ; + + if (value == 0 && m_fadeInSpin->value() == 0) + slotAudioFadeChanged(QButton::Off); + else + slotAudioFadeChanged(QButton::On); + + // Convert from ms + // + RealTime fadeOutTime(value / 1000000, (value % 1000) * 10000000); + + std::vector<Segment*>::iterator it; + for (it = m_segments.begin(); it != m_segments.end(); it++) { + (*it)->setFadeOutTime(fadeOutTime); + } + + emit documentModified(); +*/ +} + +void +SegmentParameterBox::showAdditionalControls(bool showThem) +{ + //!!! disabled until after 1.3 + /* m_highButton->setShown(showThem); + m_lowButton->setShown(showThem); + m_rangeLabel->setShown(showThem); */ +} + +QString +SegmentParameterBox::getPreviousBox(RosegardenParameterArea::Arrangement arrangement) const +{ + if (arrangement == RosegardenParameterArea::CLASSIC_STYLE) { + return ""; + } else { + return i18n("Instrument"); + } +} + +} +#include "SegmentParameterBox.moc" |