// rdcueedit.cpp // // Cueing Editor for RDLogLine-based Events // // (C) Copyright 2013-2020 Fred Gleason <fredg@paravelsystems.com> // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // 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., 675 Mass Ave, Cambridge, MA 02139, USA. // #include <qpainter.h> #include <qmessagebox.h> #include <q3frame.h> #include "rdconf.h" #include "rdcueedit.h" RDCueEdit::RDCueEdit(QWidget *parent) : RDWidget(parent) { edit_height=325; edit_slider_pressed=false; edit_shift_pressed=false; edit_right_click_stop=false; edit_event_player=NULL; edit_start_rml=""; edit_stop_rml=""; // // Create Palettes // edit_play_color= QPalette(QColor(BUTTON_PLAY_BACKGROUND_COLOR),backgroundColor()); edit_start_color=palette(); edit_start_color.setColor(QColorGroup::Foreground,RD_CUEEDITOR_START_MARKER); edit_position_label=new QLabel(this); edit_position_label->setGeometry(0,0,sizeHint().width()-30,30); edit_position_label->setBackgroundColor(QColor(Qt::white)); edit_position_label->setLineWidth(1); edit_position_label->setMidLineWidth(0); edit_position_label->setFrameStyle(Q3Frame::Box|Q3Frame::Plain); edit_position_bar=new RDMarkerBar(this); edit_position_bar->setGeometry(85,8,sizeHint().width()-200,14); edit_up_label=new QLabel("00:00:00",this); edit_up_label->setGeometry(5,8,70,14); edit_up_label->setBackgroundColor(Qt::white); edit_up_label->setFont(labelFont()); edit_up_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); edit_down_label=new QLabel("00:00:00",this); edit_down_label->setGeometry(sizeHint().width()-110,8,70,14); edit_down_label->setBackgroundColor(Qt::white); edit_down_label->setFont(labelFont()); edit_down_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); // // Position Slider // edit_slider=new RDSlider(RDSlider::Right,this); edit_slider->setGeometry(60,30,sizeHint().width()-150,50); edit_slider->setKnobSize(50,50); edit_slider->setKnobColor(QColor(RD_CUEEDITOR_KNOB_COLOR)); connect(edit_slider,SIGNAL(sliderMoved(int)), this,SLOT(sliderChangedData(int))); connect(edit_slider,SIGNAL(sliderPressed()),this,SLOT(sliderPressedData())); connect(edit_slider,SIGNAL(sliderReleased()), this,SLOT(sliderReleasedData())); // // Button Area // QLabel *label=new QLabel(this); label->setGeometry(0,85,sizeHint().width()-30,60); label->setBackgroundColor(QColor(Qt::gray)); label->setLineWidth(1); label->setMidLineWidth(0); label->setFrameStyle(Q3Frame::Box|Q3Frame::Plain); // // Audition Button // edit_audition_button= new RDTransportButton(RDTransportButton::PlayBetween,this); edit_audition_button->setGeometry(sizeHint().width()/2-130,90,80,50); edit_audition_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_audition_button->setFont(buttonFont()); edit_audition_button-> setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_audition_button,SIGNAL(clicked()), this,SLOT(auditionButtonData())); // // Pause Button // edit_pause_button=new RDTransportButton(RDTransportButton::Pause,this); edit_pause_button->setGeometry(sizeHint().width()/2-40,90,80,50); edit_pause_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_pause_button->setFont(buttonFont()); edit_pause_button-> setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_pause_button,SIGNAL(clicked()),this,SLOT(pauseButtonData())); // // Stop Button // edit_stop_button=new RDTransportButton(RDTransportButton::Stop,this); edit_stop_button->setGeometry(sizeHint().width()/2+50,90,80,50); edit_stop_button->setOnColor(QColor(Qt::red)); edit_stop_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_stop_button->setFont(buttonFont()); edit_stop_button-> setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_stop_button,SIGNAL(clicked()),this,SLOT(stopButtonData())); // // Start Marker Control // edit_start_button=new RDPushButton(this); edit_start_button->setToggleButton(true); edit_start_button->setGeometry(0,155,66,45); edit_start_button->setFlashColor(backgroundColor()); edit_start_button->setFlashPeriod(RD_CUEEDITOR_BUTTON_FLASH_PERIOD); edit_start_button->setPalette(QPalette(QColor(RD_CUEEDITOR_START_MARKER), backgroundColor())); edit_start_button->setFont(buttonFont()); edit_start_button->setText(tr("Start")); connect(edit_start_button,SIGNAL(clicked()),this,SLOT(startClickedData())); // // End Marker Control // edit_end_button=new RDPushButton(this); edit_end_button->setToggleButton(true); edit_end_button->setGeometry(90,155,66,45); edit_end_button->setFlashColor(backgroundColor()); edit_end_button->setFlashPeriod(RD_CUEEDITOR_BUTTON_FLASH_PERIOD); edit_end_button->setPalette(QPalette(QColor(RD_CUEEDITOR_START_MARKER), backgroundColor())); edit_end_button->setFont(buttonFont()); edit_end_button->setText(tr("End")); connect(edit_end_button,SIGNAL(clicked()),this,SLOT(endClickedData())); // // Recue Marker Control // edit_recue_button=new RDPushButton(this); edit_recue_button->setToggleButton(true); edit_recue_button->setGeometry(180,155,66,45); edit_recue_button->setFlashColor(backgroundColor()); edit_recue_button->setFlashPeriod(RD_CUEEDITOR_BUTTON_FLASH_PERIOD); edit_recue_button->setPalette(QPalette(QColor(RD_CUEEDITOR_START_MARKER), backgroundColor())); edit_recue_button->setFont(buttonFont()); edit_recue_button->setText(tr("&Recue")); connect(edit_recue_button,SIGNAL(clicked()),this,SLOT(recue())); // // Audition Stop Timer // edit_audition_timer=new QTimer(this); connect(edit_audition_timer,SIGNAL(timeout()),this,SLOT(auditionTimerData())); // // Play Deck // edit_play_deck=new RDPlayDeck(rda->cae(),RDPLAYDECK_AUDITION_ID,this); connect(edit_play_deck,SIGNAL(stateChanged(int,RDPlayDeck::State)),this, SLOT(stateChangedData(int,RDPlayDeck::State))); connect(edit_play_deck,SIGNAL(position(int,int)), this,SLOT(positionData(int,int))); } RDCueEdit::~RDCueEdit() { } QSize RDCueEdit::sizeHint() const { return QSize(610,215); } QSizePolicy RDCueEdit::sizePolicy() const { return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); } void RDCueEdit::setRml(RDEventPlayer *player,const QString &start_rml, const QString &stop_rml) { edit_event_player=player; edit_start_rml=start_rml; edit_stop_rml=stop_rml; } bool RDCueEdit::initialize(RDLogLine *logline) { edit_logline=logline; edit_position_bar->setLength(edit_logline->forcedLength()); edit_start_button->setOn(false); if(!(edit_logline->status()==RDLogLine::Scheduled) && !(edit_logline->status()==RDLogLine::Paused)) { edit_start_button->hide(); edit_end_button->hide(); } else { edit_start_button->show(); edit_end_button->show(); } edit_slider->setRange(0,edit_logline->forcedLength()); edit_slider->setValue(edit_logline->playPosition()); sliderChangedData(edit_logline->playPosition()); startClickedData(); edit_stop_button->on(); edit_position_bar-> setMarker(RDMarkerBar::Play,edit_logline->playPosition()); edit_position_bar-> setMarker(RDMarkerBar::Start,edit_logline->playPosition()); edit_position_bar-> setMarker(RDMarkerBar::End,edit_logline->endPoint()); edit_slider->setValue(edit_logline->playPosition()); UpdateCounters(); return true; } unsigned RDCueEdit::playPosition(RDMarkerBar::Marker marker) const { return edit_position_bar->marker(marker); } void RDCueEdit::stop() { if(edit_play_deck->state()==RDPlayDeck::Playing) { edit_play_deck->stop(); } } void RDCueEdit::recue() { edit_position_bar->setMarker(RDMarkerBar::Start,0); if(edit_start_button->isOn()) { edit_slider->setValue(0); } UpdateCounters(); } void RDCueEdit::sliderChangedData(int pos) { if(edit_start_button->isOn()) { edit_position_bar->setMarker(RDMarkerBar::Start,pos); } else { if(edit_end_button->isOn()) { edit_position_bar->setMarker(RDMarkerBar::End,pos); } else { edit_position_bar->setMarker(RDMarkerBar::Play,pos); } } UpdateCounters(); } void RDCueEdit::sliderPressedData() { if(edit_play_deck->state()==RDPlayDeck::Playing) { edit_play_deck->stop(); edit_slider_pressed=true; } } void RDCueEdit::sliderReleasedData() { if(edit_slider_pressed) { auditionButtonData(); edit_slider_pressed=false; } } void RDCueEdit::auditionButtonData() { int start_pos=edit_slider->value(); int play_len=-1; if(edit_play_deck->state()==RDPlayDeck::Playing) { return; } edit_play_deck->setCard(rda->station()->cueCard()); edit_play_deck->setPort(rda->station()->cuePort()); if(!edit_play_deck->setCart(edit_logline,false)) { return; } if(edit_start_button->isOn()) { if(edit_play_deck->state()==RDPlayDeck::Stopped) { start_pos=edit_position_bar->marker(RDMarkerBar::Start); } if(edit_play_deck->state()==RDPlayDeck::Paused) { start_pos=edit_play_deck->currentPosition(); } play_len=edit_position_bar->marker(RDMarkerBar::End)-start_pos; } else { if(edit_end_button->isOn()) { if(edit_play_deck->state()==RDPlayDeck::Stopped) { play_len=RD_CUEEDITOR_AUDITION_PREROLL; if(play_len>(edit_position_bar->marker(RDMarkerBar::End)- edit_position_bar->marker(RDMarkerBar::Start))) { play_len=edit_position_bar->marker(RDMarkerBar::End)- edit_position_bar->marker(RDMarkerBar::Start); } start_pos=edit_position_bar->marker(RDMarkerBar::End)-play_len; } } else { if((edit_play_deck->state()==RDPlayDeck::Stopped)&& (!edit_slider_pressed)) { edit_start_pos=edit_slider->value(); } } } edit_play_deck->play(start_pos); if(play_len>=0) { edit_audition_timer->start(play_len,true); } if((!edit_start_rml.isEmpty())&&(edit_event_player!=NULL)) { edit_event_player->exec(edit_logline->resolveWildcards(edit_start_rml)); } } void RDCueEdit::pauseButtonData() { if(edit_play_deck->state()==RDPlayDeck::Playing) { edit_play_deck->pause(); } } void RDCueEdit::stopButtonData() { switch(edit_play_deck->state()) { case RDPlayDeck::Playing: case RDPlayDeck::Paused: edit_play_deck->stop(); break; default: break; } } void RDCueEdit::stateChangedData(int id,RDPlayDeck::State state) { if(id!=RDPLAYDECK_AUDITION_ID) { return; } switch(state) { case RDPlayDeck::Playing: Playing(id); break; case RDPlayDeck::Stopping: break; case RDPlayDeck::Paused: Paused(id); break; case RDPlayDeck::Stopped: Stopped(id); break; case RDPlayDeck::Finished: Stopped(id); break; } } void RDCueEdit::positionData(int id,int msecs) { if(id!=RDPLAYDECK_AUDITION_ID) { return; } edit_position_bar->setMarker(RDMarkerBar::Play,msecs); if((!edit_start_button->isOn())&&(!edit_end_button->isOn())) { edit_slider->setValue(msecs); } UpdateCounters(); } void RDCueEdit::auditionTimerData() { edit_play_deck->stop(); } void RDCueEdit::startClickedData() { if(edit_end_button->isOn()) { edit_end_button->toggle(); SetEndMode(false); } SetStartMode(edit_start_button->isOn()); } void RDCueEdit::endClickedData() { if(edit_start_button->isOn()) { edit_start_button->toggle(); SetStartMode(false); } SetEndMode(edit_end_button->isOn()); } void RDCueEdit::SetStartMode(bool state) { if(state) { edit_slider->setRange(0,edit_position_bar->marker(RDMarkerBar::End)); edit_slider->setGeometry(60,30, (int)(50.0+((double)(sizeHint().width()-200)* (double)edit_position_bar-> marker(RDMarkerBar::End)/ (double)edit_logline-> forcedLength())),50); edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::Start)); edit_slider->setKnobColor(RD_CUEEDITOR_START_MARKER); edit_audition_button->setAccentColor(RD_CUEEDITOR_START_MARKER); edit_start_button->setFlashingEnabled(true); edit_up_label->setPalette(edit_start_color); edit_down_label->setPalette(edit_start_color); UpdateCounters(); } else { edit_slider->setRange(0,edit_logline->forcedLength()); edit_slider->setGeometry(60,30,sizeHint().width()-150,50); edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::Play)); edit_slider->setKnobColor(RD_CUEEDITOR_PLAY_MARKER); edit_audition_button->setAccentColor(RD_CUEEDITOR_PLAY_MARKER); edit_start_button->setFlashingEnabled(false); edit_up_label->setPalette(palette()); edit_down_label->setPalette(palette()); UpdateCounters(); } } void RDCueEdit::SetEndMode(bool state) { if(state) { edit_slider->setRange(edit_position_bar->marker(RDMarkerBar::Start), edit_logline->forcedLength()); edit_slider->setGeometry((int)(60.0+(double)(sizeHint().width()-200)* (double)edit_position_bar-> marker(RDMarkerBar::Start)/ (double)edit_logline->forcedLength()), 30,(int)(50.0+((double)(sizeHint().width()-200)* ((double)edit_logline-> forcedLength()- (double)edit_position_bar-> marker(RDMarkerBar::Start))/ (double)edit_logline-> forcedLength())),50); edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::End)); edit_slider->setKnobColor(RD_CUEEDITOR_START_MARKER); edit_audition_button->setAccentColor(RD_CUEEDITOR_START_MARKER); edit_end_button->setFlashingEnabled(true); edit_up_label->setPalette(edit_start_color); edit_down_label->setPalette(edit_start_color); UpdateCounters(); } else { edit_slider->setRange(0,edit_logline->forcedLength()); edit_slider->setGeometry(60,30,sizeHint().width()-150,50); edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::Play)); edit_slider->setKnobColor(RD_CUEEDITOR_PLAY_MARKER); edit_audition_button->setAccentColor(RD_CUEEDITOR_PLAY_MARKER); edit_end_button->setFlashingEnabled(false); edit_up_label->setPalette(palette()); edit_down_label->setPalette(palette()); UpdateCounters(); } } /* void RDCueEdit::ShowAudioControls(bool state) { if(state) { edit_height=325; edit_slider->show(); edit_up_label->show(); edit_down_label->show(); edit_audition_button->show(); edit_pause_button->show(); edit_position_bar->show(); edit_position_label->show(); } else { edit_height=170; edit_slider->hide(); edit_up_label->hide(); edit_down_label->hide(); edit_audition_button->hide(); edit_pause_button->hide(); edit_position_bar->hide(); edit_position_label->hide(); } } */ void RDCueEdit::Playing(int id) { edit_audition_button->on(); edit_pause_button->off(); edit_stop_button->off(); edit_right_click_stop=true; } void RDCueEdit::Paused(int id) { if(!edit_slider_pressed) { edit_audition_button->off(); edit_pause_button->on(); edit_stop_button->off(); ClearChannel(); edit_right_click_stop=false; } } void RDCueEdit::Stopped(int id) { if(!edit_slider_pressed) { edit_audition_button->off(); edit_pause_button->off(); edit_stop_button->on(); ClearChannel(); edit_right_click_stop=false; } if(edit_start_button->isOn()) { edit_position_bar-> setMarker(RDMarkerBar::Play,edit_position_bar->marker(RDMarkerBar::Start)); edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::Start)); } else { if(edit_end_button->isOn()) { edit_slider->setValue(edit_position_bar->marker(RDMarkerBar::End)); } else { edit_position_bar->setMarker(RDMarkerBar::Play,edit_start_pos); edit_slider->setValue(edit_start_pos); } } } void RDCueEdit::UpdateCounters() { if(edit_start_button->isOn()) { edit_up_label-> setText(RDGetTimeLength(edit_position_bar->marker(RDMarkerBar::Start),true)); edit_down_label-> setText(RDGetTimeLength(edit_logline-> forcedLength()-edit_position_bar-> marker(RDMarkerBar::Start),true)); } else { if(edit_end_button->isOn()) { edit_up_label-> setText(RDGetTimeLength(edit_position_bar->marker(RDMarkerBar::End), true)); edit_down_label-> setText(RDGetTimeLength(edit_logline-> forcedLength()-edit_position_bar-> marker(RDMarkerBar::End),true)); } else { edit_up_label-> setText(RDGetTimeLength(edit_position_bar->marker(RDMarkerBar::Play), true)); edit_down_label-> setText(RDGetTimeLength(edit_logline-> forcedLength()-edit_position_bar-> marker(RDMarkerBar::Play),true)); } } } void RDCueEdit::ClearChannel() { if(rda->cae()->playPortActive(edit_play_deck->card(),edit_play_deck->port(), edit_play_deck->stream())) { return; } if((!edit_stop_rml.isEmpty())&&(edit_event_player!=NULL)) { edit_event_player->exec(edit_stop_rml); } } void RDCueEdit::wheelEvent(QWheelEvent *e) { if(edit_audition_button->isShown()) { if(edit_play_deck->state()==RDPlayDeck::Playing) { edit_play_deck->pause(); } if(edit_shift_pressed) { edit_slider->setValue(edit_slider->value()+(e->delta()*10)/12); } else { edit_slider->setValue(edit_slider->value()+(e->delta()*100)/12); } sliderChangedData(edit_slider->value()); } } void RDCueEdit::mousePressEvent(QMouseEvent *e) { switch(e->button()) { case Qt::RightButton: if(edit_audition_button->isShown()) { if(edit_right_click_stop) { stopButtonData(); } else { auditionButtonData(); } } break; case Qt::MidButton: if(edit_audition_button->isShown()) { if(edit_logline->forcedLength()>10000) { if(edit_play_deck->state()==RDPlayDeck::Playing) { edit_play_deck->pause(); } edit_slider->setValue((edit_logline->forcedLength())-10000); sliderChangedData(edit_slider->value()); } auditionButtonData(); } break; default: QWidget::mousePressEvent(e); break; } } void RDCueEdit::keyPressEvent(QKeyEvent *e) { switch(e->key()) { case Qt::Key_Shift: edit_shift_pressed=true; break; default: e->ignore(); break; } } void RDCueEdit::keyReleaseEvent(QKeyEvent *e) { switch(e->key()) { case Qt::Key_Shift: edit_shift_pressed=false; QWidget::keyPressEvent(e); break; default: QWidget::keyPressEvent(e); break; } }