diff --git a/.gitignore b/.gitignore index 5363d447..6978a1a9 100644 --- a/.gitignore +++ b/.gitignore @@ -107,6 +107,7 @@ tests/audio_export_test tests/audio_import_test tests/audio_metadata_test tests/audio_peaks_test +tests/cmdline_parser_test tests/datedecode_test tests/dateparse_test tests/db_charset_test diff --git a/ChangeLog b/ChangeLog index f84ed1ac..c3ed041b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20000,3 +20000,52 @@ * Added '' tags to the 'Apple' RSS schema. 2020-06-04 Fred Gleason * Added an 'iTunes + Superfeed' RSS schema. +2020-05-22 Fred Gleason + * Added 'RDListView::NumericSort' to the 'RDListView::SortType' + enumeration. + * Fixed a bug in rdlibrary(1) that caused cuts to be incorrectly + sorted when scheduled 'By Specified Order'. +2020-05-23 Fred Gleason + * Added a 'cmdline_parser_test' test harness. + * Fixed a bug in 'RDCmdSwitch' that caused value-only arguments + containing '=' characters to be incorrectly parsed. +2020-05-23 Fred Gleason + * Fixed a bug in 'RDFormPost' that caused an error when processing + multipart-mime submissions containing '=' characters. +2020-05-29 Fred Gleason + * Fixed a bug in rdairplay(1) where attempting to audition an + audio cart with a disabled cue output would crash the application. +2020-06-04 Fred Gleason + * Added a 'Results Report' report in rdadmin(1). +2020-06-05 Fred Gleason + * Incremented the package version 3.4.0int0. +2020-06-08 Fred Gleason + * Fixed a regression in rdairplay(1) that caused the 'Forced Segue' + setting in rdadmin(1) to be ignored when executing an event with + a hard start attribute. +2020-06-08 Fred Gleason + * Fixed a bug in rdairplay(1) where a paused event could not be + removed by dropping the empty cart on it. +2020-06-09 Fred Gleason + * Fixed a cast overflow bug in rdairplay(1) that cause incorrect + pie timer indications after adding or deleting events to a running + log. +2020-06-09 Fred Gleason + * Fixed a bug in rdlibrary(1) that would throw a segfault when + attempting to delete a range of cuts, one of which was in the + clipboard. +2020-06-09 Fred Gleason + * Fixed a math bug in rdairplay(1) that caused the estimated + stop-down times in the post point widget to be incorrect after + adding or removing events from a running log. +2020-06-09 Fred Gleason + * Fixed a bug in rdadmin(1) that made it impossible to enter + useful strings in the 'WaveForm Caption' control on the + 'Edit RDLogEdit' dialog. +2020-06-09 Fred Gleason + * Fixed a bug in RDRenderer that caused segue transitions to + be rendered without regard to the 'No Fade on Segue Out' checkbox + in the 'Edit Audio' dialog. +2020-06-10 Fred Gleason + * Fixed a bug in ripcd(8) that caused connections to ModbusTCP + devices to fail to be properly restored by the connection watchdog. diff --git a/NEWS b/NEWS index 05bd842b..417632c9 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,22 @@ The NEWS file for the Rivendell package. ------------------------------------------------------------------------------- -v3.3.0int1 -- 2 May 2020 +v3.4.0int0 -- 5 June 2020 + +Changes: + As-played Reports. Added a 'Results Report'. + + Various Bugfixes. See 'ChangeLog' for details. + +Database Update: + This version of Rivendell uses database schema version 317, and will + automatically upgrade any earlier versions. To see the current schema + version prior to upgrade, see RDAdmin->SystemInfo. + + Be sure to run 'rddbmgr --modify' (as root) immediately after upgrading + to allow any necessary changes to the database schema to be applied. +------------------------------------------------------------------------------- +v3.4.0 -- 19 May 2020 Changes: Edit Event dialog in rdlogmanager(1) - Cleaned up the layout of the diff --git a/PACKAGE_VERSION b/PACKAGE_VERSION index 17ff2d95..59efc4bf 100644 --- a/PACKAGE_VERSION +++ b/PACKAGE_VERSION @@ -1 +1 @@ -3.3.0int1 \ No newline at end of file +3.4.0int0 \ No newline at end of file diff --git a/lib/Makefile.am b/lib/Makefile.am index 494c25f0..3ef6823a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,7 +2,7 @@ ## ## Automake.am for rivendell/lib ## -## (C) Copyright 2002-2018 Fred Gleason +## (C) Copyright 2002-2020 Fred Gleason ## ## 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 @@ -53,6 +53,7 @@ dist_librd_la_SOURCES = dbversion.h\ export_musicsummary.cpp\ export_nprsoundex.cpp\ export_radiotraffic.cpp\ + export_resultsrecon.cpp\ export_soundex.cpp\ export_spincount.cpp\ export_technical.cpp\ diff --git a/lib/export_resultsrecon.cpp b/lib/export_resultsrecon.cpp new file mode 100644 index 00000000..8cac987d --- /dev/null +++ b/lib/export_resultsrecon.cpp @@ -0,0 +1,115 @@ +// export_resultsreport.cpp +// +// Export a Rivendell Report in 'results' format +// +// (C) Copyright 2002-2020 Fred Gleason +// +// 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 +#include +#include + +#include "rdconf.h" +#include "rddatedecode.h" +#include "rddb.h" +#include "rdescape_string.h" +#include "rdreport.h" + +bool RDReport::ExportResultsReport(const QString &filename, + const QDate &startdate,const QDate &enddate, + const QString &mixtable) +{ + QString sql; + RDSqlQuery *q; + QString air_fmt; + + QFile *file=new QFile(filename); + if(!file->open(QIODevice::WriteOnly|QIODevice::Truncate)) { + report_error_code=RDReport::ErrorCantOpen; + delete file; + return false; + } + QTextStream *strm=new QTextStream(file); + strm->setEncoding(QTextStream::UnicodeUTF8); + sql=QString("select ")+ + "ELR_LINES.EVENT_DATETIME,"+ // 00 + "ELR_LINES.EVENT_TYPE,"+ // 01 + "ELR_LINES.LENGTH,"+ // 02 + "ELR_LINES.CART_NUMBER,"+ // 03 + "ELR_LINES.CUT_NUMBER,"+ // 04 + "ELR_LINES.TITLE,"+ // 05 + "ELR_LINES.ARTIST,"+ // 06 + "ELR_LINES.EXT_START_TIME "+ // 07 + "from ELR_LINES left join CART "+ + "on ELR_LINES.CART_NUMBER=CART.NUMBER where "+ + "SERVICE_NAME=\""+RDEscapeString(mixtable)+"\" "+ + "order by EVENT_DATETIME"; + q=new RDSqlQuery(sql); + + // + // Write Data Rows + // + QString cart_title; + QString play_length; + QString tfc_length; + QString tfc_time; + QString air_cartnum; + QString tfc_cartnum; + QString ext_data; + QString ext_annc_type; + int line=0; + + while(q->next()) { + // DateTime + *strm << q->value(0).toDateTime().toString("yy-MM-dd,hh:mm:dd,"); + + *strm << "on-air,"; + + // Cart Number + *strm << QString().sprintf("%06u,",q->value(3).toUInt()); + + // Cut Number + *strm << QString().sprintf("%03d,",q->value(4).toInt()); + + // Title / Artist + *strm << QString(). + sprintf("\"%-23s %-25s\",", + q->value(5).toString().left(23).toUtf8().constData(), + q->value(6).toString().left(25).toUtf8().constData()); + + // Length + *strm << RDGetTimeLength(q->value(2).toInt(),true,false).right(5)+","; + + // Scheduled Start Time + *strm << q->value(7).toTime().toString("hh:mm:ss,"); + + // Line Counts + *strm << QString().sprintf("%05d|-|%05d|00",line,line); + + // EOL + *strm << "\r\n"; + + line++; + } + + delete q; + delete strm; + delete file; + report_error_code=RDReport::ErrorOk; + + return true; +} + diff --git a/lib/lib.pro b/lib/lib.pro index a11486fa..92c0f436 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -32,6 +32,7 @@ SOURCES += export_musicplayout.cpp SOURCES += export_musicsummary.cpp SOURCES += export_nprsoundex.cpp SOURCES += export_radiotraffic.cpp +SOURCES += export_resultsrecon.cpp SOURCES += export_spincount.cpp SOURCES += export_soundex.cpp SOURCES += export_technical.cpp diff --git a/lib/librd_cs.ts b/lib/librd_cs.ts index b2f4120a..31628a95 100644 --- a/lib/librd_cs.ts +++ b/lib/librd_cs.ts @@ -805,6 +805,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_de.ts b/lib/librd_de.ts index e40a4a12..4fbc82c8 100644 --- a/lib/librd_de.ts +++ b/lib/librd_de.ts @@ -801,6 +801,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_es.ts b/lib/librd_es.ts index 8f3788ae..af679c9b 100644 --- a/lib/librd_es.ts +++ b/lib/librd_es.ts @@ -801,6 +801,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_fr.ts b/lib/librd_fr.ts index c9082bfc..b76a56ac 100644 --- a/lib/librd_fr.ts +++ b/lib/librd_fr.ts @@ -771,6 +771,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_nb.ts b/lib/librd_nb.ts index bf52f7a1..16deb7b3 100644 --- a/lib/librd_nb.ts +++ b/lib/librd_nb.ts @@ -801,6 +801,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_nn.ts b/lib/librd_nn.ts index bf52f7a1..16deb7b3 100644 --- a/lib/librd_nn.ts +++ b/lib/librd_nn.ts @@ -801,6 +801,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/librd_pt_BR.ts b/lib/librd_pt_BR.ts index 4f3b0df8..64346686 100644 --- a/lib/librd_pt_BR.ts +++ b/lib/librd_pt_BR.ts @@ -801,6 +801,10 @@ Inline Traffic, + + Results Report + + RDAddCart diff --git a/lib/rdcmd_switch.cpp b/lib/rdcmd_switch.cpp index 3bdf0ea4..c106916e 100644 --- a/lib/rdcmd_switch.cpp +++ b/lib/rdcmd_switch.cpp @@ -44,17 +44,23 @@ RDCmdSwitch::RDCmdSwitch(int argc,char *argv[],const char *modname, if(value=="-d") { switch_debug=true; } - QStringList f0=value.split("="); + QStringList f0=value.split("=",QString::KeepEmptyParts); if(f0.size()>=2) { - switch_keys.push_back(f0[0]); - for(int i=2;i +// (C) Copyright 2013-2020 Fred Gleason // // 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 @@ -26,12 +26,9 @@ #include "rdconf.h" #include "rdcueedit.h" -RDCueEdit::RDCueEdit(RDCae *cae,int card,int port,QWidget *parent) +RDCueEdit::RDCueEdit(QWidget *parent) : RDWidget(parent) { - edit_cae=cae; - edit_play_card=card; - edit_play_port=port; edit_height=325; edit_slider_pressed=false; edit_shift_pressed=false; @@ -102,7 +99,8 @@ RDCueEdit::RDCueEdit(RDCae *cae,int card,int port,QWidget *parent) edit_audition_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_audition_button->setFont(buttonFont()); - // edit_audition_button->setText(tr("&Audition")); + edit_audition_button-> + setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_audition_button,SIGNAL(clicked()), this,SLOT(auditionButtonData())); @@ -114,7 +112,8 @@ RDCueEdit::RDCueEdit(RDCae *cae,int card,int port,QWidget *parent) edit_pause_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_pause_button->setFont(buttonFont()); - // edit_pause_button->setText(tr("&Pause")); + edit_pause_button-> + setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_pause_button,SIGNAL(clicked()),this,SLOT(pauseButtonData())); // @@ -126,7 +125,8 @@ RDCueEdit::RDCueEdit(RDCae *cae,int card,int port,QWidget *parent) edit_stop_button-> setPalette(QPalette(backgroundColor(),QColor(Qt::gray))); edit_stop_button->setFont(buttonFont()); - // edit_stop_button->setText(tr("&Stop")); + edit_stop_button-> + setDisabled((rda->station()->cueCard()<0)||(rda->station()->cuePort()<0)); connect(edit_stop_button,SIGNAL(clicked()),this,SLOT(stopButtonData())); // @@ -180,7 +180,7 @@ RDCueEdit::RDCueEdit(RDCae *cae,int card,int port,QWidget *parent) // // Play Deck // - edit_play_deck=new RDPlayDeck(edit_cae,RDPLAYDECK_AUDITION_ID,this); + 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)), @@ -312,8 +312,8 @@ void RDCueEdit::auditionButtonData() if(edit_play_deck->state()==RDPlayDeck::Playing) { return; } - edit_play_deck->setCard(edit_play_card); - edit_play_deck->setPort(edit_play_port); + edit_play_deck->setCard(rda->station()->cueCard()); + edit_play_deck->setPort(rda->station()->cuePort()); if(!edit_play_deck->setCart(edit_logline,false)) { return; } @@ -621,8 +621,8 @@ void RDCueEdit::UpdateCounters() void RDCueEdit::ClearChannel() { - if(edit_cae->playPortActive(edit_play_deck->card(),edit_play_deck->port(), - edit_play_deck->stream())) { + 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)) { diff --git a/lib/rdcueedit.h b/lib/rdcueedit.h index 7844fb15..3b62bbf4 100644 --- a/lib/rdcueedit.h +++ b/lib/rdcueedit.h @@ -2,7 +2,7 @@ // // Cueing Editor for RDLogLine-based Events // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -39,7 +39,7 @@ class RDCueEdit : public RDWidget { Q_OBJECT public: - RDCueEdit(RDCae *cae,int card,int port,QWidget *parent=0); + RDCueEdit(QWidget *parent=0); ~RDCueEdit(); QSize sizeHint() const; QSizePolicy sizePolicy() const; @@ -82,9 +82,6 @@ class RDCueEdit : public RDWidget RDEventPlayer *edit_event_player; QString edit_start_rml; QString edit_stop_rml; - RDCae *edit_cae; - int edit_play_card; - int edit_play_port; RDSlider *edit_slider; QLabel *edit_up_label; QLabel *edit_down_label; diff --git a/lib/rdcueeditdialog.cpp b/lib/rdcueeditdialog.cpp index 3c5dbb27..7724cd81 100644 --- a/lib/rdcueeditdialog.cpp +++ b/lib/rdcueeditdialog.cpp @@ -2,7 +2,7 @@ // // A Dialog Box for using an RDCueEdit widget. // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License @@ -32,7 +32,7 @@ RDCueEditDialog::RDCueEditDialog(RDCae *cae,int play_card,int play_port, // // Cue Editor // - cue_edit=new RDCueEdit(cae,play_card,play_port,this); + cue_edit=new RDCueEdit(this); cue_edit->setGeometry(15,10, cue_edit->sizeHint().width(), cue_edit->sizeHint().height()); diff --git a/lib/rdformpost.cpp b/lib/rdformpost.cpp index 63553bfd..94013265 100644 --- a/lib/rdformpost.cpp +++ b/lib/rdformpost.cpp @@ -489,7 +489,13 @@ void RDFormPost::LoadUrlEncoding(char first) post_data[post_content_length]=0; lines=QString(post_data).split("&"); for(int i=0;i2) { + line.removeLast(); + } switch(line.size()) { case 1: post_values[line[0]]=""; @@ -572,14 +578,19 @@ bool RDFormPost::GetMimePart(QString *name,QString *value,bool *is_file) // Headers // do { - // line=post_text_reader->readLine(); line=QString::fromUtf8(GetLine()); QStringList f0=line.split(":"); if(f0.size()==2) { if(f0[0].lower()=="content-disposition") { QStringList f1=f0[1].split(";"); for(int i=0;i2) { + f2.removeLast(); + } if(f2.size()==2) { if(f2[0]=="name") { *name=f2[1].replace("\"",""); diff --git a/lib/rdlistview.h b/lib/rdlistview.h index c9c4ef91..e27769fb 100644 --- a/lib/rdlistview.h +++ b/lib/rdlistview.h @@ -2,7 +2,7 @@ // // A contiguous-selection only QListView widget for Rivendell // -// (C) Copyright 2002-2003,2016 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -31,7 +31,7 @@ class RDListView : public Q3ListView Q_OBJECT public: - enum SortType {NormalSort=0,TimeSort=1,LineSort=2,GpioSort=3}; + enum SortType {NormalSort=0,TimeSort=1,LineSort=2,GpioSort=3,NumericSort=4}; RDListView(QWidget *parent); int hardSortColumn() const; void setHardSortColumn(int col); diff --git a/lib/rdlistviewitem.cpp b/lib/rdlistviewitem.cpp index 45869bef..6ccf310c 100644 --- a/lib/rdlistviewitem.cpp +++ b/lib/rdlistviewitem.cpp @@ -2,7 +2,7 @@ // // A color-selectable QListViewItem class for Rivendell // -// (C) Copyright 2002-2004,2016 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -174,6 +174,8 @@ int RDListViewItem::compare(Q3ListViewItem *i,int col,bool ascending) const int length; QStringList fields; QStringList prev_fields; + int this_num; + int that_num; if((hard_column=list_parent->hardSortColumn())<0) { switch(list_parent->columnSortType(col)) { @@ -207,6 +209,17 @@ int RDListViewItem::compare(Q3ListViewItem *i,int col,bool ascending) const return -1; } return 0; + + case RDListView::NumericSort: + this_num=text(col).toInt(); + that_num=i->text(col).toInt(); + if(this_num>that_num) { + return 1; + } + if(this_num +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -1432,7 +1432,13 @@ void RDLogPlay::transTimerData() } makeNext(play_trans_line); if(logline->transType()!=RDLogLine::Stop || grace>=0) { - StartEvent(trans_line,RDLogLine::Play,0,RDLogLine::StartTime); + if(play_trans_length>0) { + StartEvent(trans_line,RDLogLine::Segue,play_trans_length, + RDLogLine::StartTime); + } + else { + StartEvent(trans_line,RDLogLine::Play,0,RDLogLine::StartTime); + } } } SetTransTimer(); @@ -2414,7 +2420,8 @@ void RDLogPlay::UpdatePostPoint(int line) if((line=0)&&(play_trans_linestartTime(RDLogLine::Logged); - offset=length(line,post_line)-QTime::currentTime().msecsTo(post_time); + offset=length(line,post_line)-QTime::currentTime().msecsTo(post_time)- + logLine(line)->playPosition(); } } if((post_time!=play_post_time)||(offset!=play_post_offset)) { diff --git a/lib/rdrenderer.cpp b/lib/rdrenderer.cpp index 0c83462f..533fe5fe 100644 --- a/lib/rdrenderer.cpp +++ b/lib/rdrenderer.cpp @@ -2,7 +2,7 @@ // // Render a Rivendell log to a single audio object. // -// (C) Copyright 2017-2019 Fred Gleason +// (C) Copyright 2017-2020 Fred Gleason // // 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 @@ -86,11 +86,13 @@ void __RDRenderLogLine::setRampRate(double lvl) } -void __RDRenderLogLine::setRamp(RDLogLine::TransType next_trans) +void __RDRenderLogLine::setRamp(RDLogLine::TransType next_trans,int segue_gain) { if((next_trans==RDLogLine::Segue)&&(segueStartPoint()>=0)) { - ll_ramp_rate=((double)RD_FADE_DEPTH)/ + ll_ramp_rate=((double)segue_gain)/ ((double)FramesFromMsec(segueEndPoint()-segueStartPoint())); + //ll_ramp_rate=((double)RD_FADE_DEPTH)/ + // ((double)FramesFromMsec(segueEndPoint()-segueStartPoint())); } } @@ -109,6 +111,7 @@ bool __RDRenderLogLine::open(const QTime &time) setEndPoint(ll_cut->endPoint(),RDLogLine::CartPointer); setSegueStartPoint(ll_cut->segueStartPoint(),RDLogLine::CartPointer); setSegueEndPoint(ll_cut->segueEndPoint(),RDLogLine::CartPointer); + setSegueGain(ll_cut->segueGain()); QString filename; if(GetCutFile(cutname,ll_cut->startPoint(),ll_cut->endPoint(), &filename)) { @@ -528,7 +531,7 @@ bool RDRenderer::Render(const QString &outfile,RDLogEvent *log,RDSettings *s, sf_writef_float(sf_out,pcm,frames); delete pcm; pcm=NULL; - lls.at(i)->setRamp(lls.at(i+1)->transType()); + lls.at(i)->setRamp(lls.at(i+1)->transType(),lls.at(i)->segueGain()); } else { if(i<(lls.size()-1)) { diff --git a/lib/rdrenderer.h b/lib/rdrenderer.h index a520bb8c..8495651b 100644 --- a/lib/rdrenderer.h +++ b/lib/rdrenderer.h @@ -42,7 +42,7 @@ class __RDRenderLogLine : public RDLogLine void setRampLevel(double lvl); double rampRate() const; void setRampRate(double lvl); - void setRamp(RDLogLine::TransType next_trans); + void setRamp(RDLogLine::TransType next_trans,int segue_gain); bool open(const QTime &time); void close(); QString summary() const; diff --git a/lib/rdreport.cpp b/lib/rdreport.cpp index ca14d1ea..abb3190e 100644 --- a/lib/rdreport.cpp +++ b/lib/rdreport.cpp @@ -654,6 +654,10 @@ bool RDReport::generateReport(const QDate &startdate,const QDate &enddate, ret=ExportCutLog(filename,startdate,enddate,mixname); break; + case RDReport::ResultsReport: + ret=ExportResultsReport(filename,startdate,enddate,mixname); + break; + default: return false; break; @@ -731,6 +735,9 @@ QString RDReport::filterText(RDReport::ExportFilter filter) case RDReport::CutLog: return QObject::tr("Cut Log"); + case RDReport::ResultsReport: + return QObject::tr("Results Report"); + case RDReport::LastFilter: break; } @@ -776,6 +783,7 @@ bool RDReport::multipleDaysAllowed(RDReport::ExportFilter filter) case RDReport::SpinCount: case RDReport::WideOrbit: case RDReport::CutLog: + case RDReport::ResultsReport: return false; case RDReport::BmiEmr: @@ -807,6 +815,7 @@ bool RDReport::multipleMonthsAllowed(RDReport::ExportFilter filter) case RDReport::NaturalLog: case RDReport::WideOrbit: case RDReport::CutLog: + case RDReport::ResultsReport: return false; case RDReport::MusicSummary: diff --git a/lib/rdreport.h b/lib/rdreport.h index 2d8d4db6..a05d700f 100644 --- a/lib/rdreport.h +++ b/lib/rdreport.h @@ -37,7 +37,7 @@ class RDReport CounterPoint=7,Music1=8,MusicSummary=9,WideOrbit=10, NprSoundExchange=11,MusicPlayout=12,NaturalLog=13, MusicClassical=14,MrMaster=15,SpinCount=16,CutLog=17, - CounterPoint2=18,LastFilter=19}; + CounterPoint2=18,ResultsReport=19,LastFilter=20}; enum ExportOs {Linux=0,Windows=1}; enum ExportType {Generic=0,Traffic=1,Music=2}; enum StationType {TypeOther=0,TypeAm=1,TypeFm=2,TypeLast=3}; @@ -124,6 +124,8 @@ class RDReport const QDate &enddate,const QString &mixtable); bool ExportCutLog(const QString &filename,const QDate &startdate, const QDate &enddate,const QString &mixtable); + bool ExportResultsReport(const QString &filename,const QDate &startdate, + const QDate &enddate,const QString &mixtable); void SetRow(const QString ¶m,const QString &value) const; void SetRow(const QString ¶m,int value) const; void SetRow(const QString ¶m,unsigned value) const; diff --git a/rdadmin/edit_rdlogedit.cpp b/rdadmin/edit_rdlogedit.cpp index e0c7f13f..99acd0cd 100644 --- a/rdadmin/edit_rdlogedit.cpp +++ b/rdadmin/edit_rdlogedit.cpp @@ -2,7 +2,7 @@ // // Edit an RDLogedit Configuration // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -185,7 +185,6 @@ EditRDLogedit::EditRDLogedit(RDStation *station,RDStation *cae_station, // lib_waveform_caption_edit=new QLineEdit(this); lib_waveform_caption_edit->setGeometry(180,268,sizeHint().width()-190,19); - lib_waveform_caption_edit->setValidator(validator); QLabel *lib_waveform_caption_label= new QLabel(lib_waveform_caption_edit,tr("WaveForm Caption:"),this); lib_waveform_caption_label->setFont(labelFont()); diff --git a/rdairplay/button_log.cpp b/rdairplay/button_log.cpp index bbb8b81f..84885afe 100644 --- a/rdairplay/button_log.cpp +++ b/rdairplay/button_log.cpp @@ -2,7 +2,7 @@ // // The button log widget for RDAirPlay // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -20,13 +20,12 @@ #include "button_log.h" -ButtonLog::ButtonLog(RDLogPlay *log,RDCae *cae,int id,RDAirPlayConf *conf, - bool allow_pause,QWidget *parent) +ButtonLog::ButtonLog(RDLogPlay *log,int id,RDAirPlayConf *conf,bool allow_pause, + QWidget *parent) : RDWidget(parent) { log_id=id; log_log=log; - log_cae=cae; log_action_mode=RDAirPlayConf::Normal; log_op_mode=RDAirPlayConf::LiveAssist; log_time_mode=RDAirPlayConf::TwentyFourHour; @@ -46,7 +45,7 @@ ButtonLog::ButtonLog(RDLogPlay *log,RDCae *cae,int id,RDAirPlayConf *conf, // // Edit Event Dialog // - log_event_edit=new EditEvent(log_log,log_cae,this); + log_event_edit=new EditEvent(log_log,this); // // Line Boxes / Start Buttons diff --git a/rdairplay/button_log.h b/rdairplay/button_log.h index 4b9f7c4c..b8bdc40e 100644 --- a/rdairplay/button_log.h +++ b/rdairplay/button_log.h @@ -2,7 +2,7 @@ // // The button play widget for RDAirPlay. // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -37,8 +37,8 @@ class ButtonLog : public RDWidget { Q_OBJECT public: - ButtonLog(RDLogPlay *log,RDCae *cae,int id,RDAirPlayConf *conf, - bool allow_pause=false,QWidget *parent=0); + ButtonLog(RDLogPlay *log,int id,RDAirPlayConf *conf,bool allow_pause=false, + QWidget *parent=0); QSize sizeHint() const; QSizePolicy sizePolicy() const; RDAirPlayConf::OpMode opMode() const; @@ -79,7 +79,6 @@ class ButtonLog : public RDWidget int log_line_counter; RDAirPlayConf::TimeMode log_time_mode; EditEvent *log_event_edit; - RDCae *log_cae; bool log_pause_enabled; }; diff --git a/rdairplay/edit_event.cpp b/rdairplay/edit_event.cpp index 194fb791..7edc2474 100644 --- a/rdairplay/edit_event.cpp +++ b/rdairplay/edit_event.cpp @@ -2,7 +2,7 @@ // // Event Editor for RDAirPlay // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -23,11 +23,10 @@ #include "edit_event.h" -EditEvent::EditEvent(RDLogPlay *log,RDCae *cae,QWidget *parent) +EditEvent::EditEvent(RDLogPlay *log,QWidget *parent) : RDDialog(parent) { edit_log=log; - edit_cae=cae; edit_height=385; setWindowTitle("RDAirPlay - "+tr("Edit Event")); @@ -112,8 +111,7 @@ EditEvent::EditEvent(RDLogPlay *log,RDCae *cae,QWidget *parent) // // Cue Editor // - edit_cue_edit=new RDCueEdit(edit_cae,rda->station()->cueCard(), - rda->station()->cuePort(),this); + edit_cue_edit=new RDCueEdit(this); // // Cart Notes diff --git a/rdairplay/edit_event.h b/rdairplay/edit_event.h index 03239653..4485fc5d 100644 --- a/rdairplay/edit_event.h +++ b/rdairplay/edit_event.h @@ -2,7 +2,7 @@ // // Event Editor for RDAirPlay // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -36,7 +36,7 @@ class EditEvent : public RDDialog { Q_OBJECT public: - EditEvent(RDLogPlay *log,RDCae *cae,QWidget *parent=0); + EditEvent(RDLogPlay *log,QWidget *parent=0); ~EditEvent(); QSize sizeHint() const; QSizePolicy sizePolicy() const; @@ -78,7 +78,6 @@ class EditEvent : public RDDialog QPushButton *edit_cancel_button; QLabel *edit_horizrule_label; int edit_height; - RDCae *edit_cae; }; diff --git a/rdairplay/list_log.cpp b/rdairplay/list_log.cpp index ab1005e5..3e9e290e 100644 --- a/rdairplay/list_log.cpp +++ b/rdairplay/list_log.cpp @@ -35,13 +35,12 @@ #include "../icons/traffic.xpm" #include "../icons/music.xpm" -ListLog::ListLog(RDLogPlay *log,RDCae *cae,int id,bool allow_pause, +ListLog::ListLog(RDLogPlay *log,int id,bool allow_pause, QWidget *parent) : RDWidget(parent) { list_id=id; list_log=log; - list_cae=cae; list_op_mode=RDAirPlayConf::LiveAssist; list_action_mode=RDAirPlayConf::Normal; list_time_mode=RDAirPlayConf::TwentyFourHour; @@ -358,7 +357,7 @@ ListLog::ListLog(RDLogPlay *log,RDCae *cae,int id,bool allow_pause, // // Edit Event Dialog // - list_event_edit=new EditEvent(list_log,list_cae,this); + list_event_edit=new EditEvent(list_log,this); // // Map Slots diff --git a/rdairplay/list_log.h b/rdairplay/list_log.h index 911eec0c..1f0bea1c 100644 --- a/rdairplay/list_log.h +++ b/rdairplay/list_log.h @@ -2,7 +2,7 @@ // // The full log list widget for RDAirPlay. // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -34,7 +34,7 @@ class ListLog : public RDWidget { Q_OBJECT public: - ListLog(RDLogPlay *log,RDCae *cae,int id,bool allow_pause=false, + ListLog(RDLogPlay *log,int id,bool allow_pause=false, QWidget *parent=0); QSize sizeHint() const; QSizePolicy sizePolicy() const; @@ -139,7 +139,6 @@ class ListLog : public RDWidget bool list_pause_allowed; bool list_audition_head_playing; bool list_audition_tail_playing; - RDCae *list_cae; }; diff --git a/rdairplay/loglinebox.cpp b/rdairplay/loglinebox.cpp index 1d8c0e67..819370ec 100644 --- a/rdairplay/loglinebox.cpp +++ b/rdairplay/loglinebox.cpp @@ -834,7 +834,9 @@ void LogLineBox::paintEvent(QPaintEvent *e) void LogLineBox::dragEnterEvent(QDragEnterEvent *e) { - e->accept(RDCartDrag::canDecode(e)&&(line_status==RDLogLine::Scheduled)); + e->accept(RDCartDrag::canDecode(e)&& + ((line_status==RDLogLine::Scheduled)|| + (line_status==RDLogLine::Paused))); } diff --git a/rdairplay/rdairplay.cpp b/rdairplay/rdairplay.cpp index 82460827..21992d32 100644 --- a/rdairplay/rdairplay.cpp +++ b/rdairplay/rdairplay.cpp @@ -623,7 +623,7 @@ MainWidget::MainWidget(RDConfig *config,QWidget *parent) // air_pause_enabled=rda->airplayConf()->pauseEnabled(); for(int i=0;icae(),i,air_pause_enabled,this); + air_log_list[i]=new ListLog(air_log[i],i,air_pause_enabled,this); air_log_list[i]->setGeometry(510,140,air_log_list[i]->sizeHint().width(), air_log_list[i]->sizeHint().height()); air_log_list[i]->hide(); @@ -690,8 +690,8 @@ MainWidget::MainWidget(RDConfig *config,QWidget *parent) // // Button Log // - air_button_list=new ButtonLog(air_log[0],rda->cae(),0,rda->airplayConf(), - air_pause_enabled,this); + air_button_list= + new ButtonLog(air_log[0],0,rda->airplayConf(),air_pause_enabled,this); air_button_list->setGeometry(10,140,air_button_list->sizeHint().width(), air_button_list->sizeHint().height()); connect(air_button_list,SIGNAL(selectClicked(int,int,RDLogLine::Status)), @@ -1724,16 +1724,18 @@ void MainWidget::transportChangedData() case RDAirPlayConf::CartTransition: if((next_logline=air_log[0]-> logLine(air_log[0]->nextLine(line)))!=NULL) { - if((unsigned)logline->startTime(RDLogLine::Actual). + // + // Are we not past the segue point? + // + if((logline->playPosition()> + (unsigned)logline->segueLength(next_logline->transType()))|| + ((unsigned)logline->startTime(RDLogLine::Actual). msecsTo(QTime::currentTime())< logline->segueLength(next_logline->transType())- - logline->playPosition()) { + logline->playPosition())) { air_pie_counter-> setTime(logline->segueLength(next_logline->transType())); } - else { - air_pie_counter->setTime(logline->effectiveLength()); - } } else { air_pie_counter->setTime(logline->effectiveLength()); diff --git a/rdlibrary/audio_cart.cpp b/rdlibrary/audio_cart.cpp index 6126b1cc..cfc76a25 100644 --- a/rdlibrary/audio_cart.cpp +++ b/rdlibrary/audio_cart.cpp @@ -2,7 +2,7 @@ // // The audio cart editor for RDLibrary. // -// (C) Copyright 2002-2019 Fred Gleason +// (C) Copyright 2002-2020 Fred Gleason // // 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 @@ -102,7 +102,7 @@ AudioCart::AudioCart(AudioControls *controls,RDCart *cart,QString *path, rdcart_cut_list->setAllColumnsShowFocus(true); rdcart_cut_list->setSelectionMode(Q3ListView::Extended); rdcart_cut_list->setItemMargin(5); - rdcart_cut_list->setSorting(11); + rdcart_cut_list->setSorting(12); connect(rdcart_cut_list, SIGNAL(doubleClicked(Q3ListViewItem *,const QPoint &,int)), this, @@ -110,7 +110,7 @@ AudioCart::AudioCart(AudioControls *controls,RDCart *cart,QString *path, rdcart_cut_list->addColumn(tr("Wt")); rdcart_cut_list->setColumnAlignment(0,Qt::AlignHCenter); - rdcart_cut_list->setColumnSortType(0,RDListView::LineSort); + rdcart_cut_list->setColumnSortType(0,RDListView::NumericSort); rdcart_cut_list->addColumn(tr("Description")); rdcart_cut_list->setColumnAlignment(1,Qt::AlignLeft); @@ -268,9 +268,11 @@ void AudioCart::changeCutScheduling(int sched) } if(sched) { rdcart_cut_list->setColumnText(0,tr("Wt")); + rdcart_cut_list->setSortColumn(12); } else { rdcart_cut_list->setColumnText(0,tr("Ord")); + rdcart_cut_list->setSortColumn(0); } rdcart_use_weighting=sched!=0; } @@ -358,15 +360,18 @@ void AudioCart::deleteCutData() // Check Clipboard // if(cut_clipboard!=NULL) { - if(item->text(12)==cut_clipboard->cutName()) { - if(QMessageBox::question(this,tr("Empty Clipboard"), - tr("Deleting this cut will also empty the clipboard.\nDo you still want to proceed?"),QMessageBox::Yes,QMessageBox::No)== - QMessageBox::No) { - return; + for(unsigned i=0;icutName()) { + if(QMessageBox::question(this,tr("Empty Clipboard"), + tr("Deleting this cut will also empty the clipboard.\nDo you still want to proceed?"),QMessageBox::Yes,QMessageBox::No)== + QMessageBox::No) { + return; + } + delete cut_clipboard; + cut_clipboard=NULL; + paste_cut_button->setDisabled(true); + break; } - delete cut_clipboard; - cut_clipboard=NULL; - paste_cut_button->setDisabled(true); } } diff --git a/ripcd/modbus.cpp b/ripcd/modbus.cpp index 9d5e4617..61040f61 100644 --- a/ripcd/modbus.cpp +++ b/ripcd/modbus.cpp @@ -179,6 +179,7 @@ void Modbus::connectedData() "connection to Modbus device at %s:%u established", (const char *)modbus_ip_address.toString(),0xffff&modbus_ip_port); modbus_watchdog_active=false; + modbus_busy=false; pollInputs(); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 445019a6..e8f08290 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -31,6 +31,7 @@ noinst_PROGRAMS = audio_convert_test\ audio_import_test\ audio_metadata_test\ audio_peaks_test\ + cmdline_parser_test\ datedecode_test\ dateparse_test\ db_charset_test\ @@ -67,6 +68,9 @@ audio_metadata_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIB dist_audio_peaks_test_SOURCES = audio_peaks_test.cpp audio_peaks_test.h audio_peaks_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIBS@ -lQt3Support +dist_cmdline_parser_test_SOURCES = cmdline_parser_test.cpp cmdline_parser_test.h +cmdline_parser_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIBS@ -lQt3Support + dist_datedecode_test_SOURCES = datedecode_test.cpp datedecode_test.h datedecode_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@ @QT4_LIBS@ @MUSICBRAINZ_LIBS@ -lQt3Support diff --git a/tests/cmdline_parser_test.cpp b/tests/cmdline_parser_test.cpp new file mode 100644 index 00000000..3dca77fa --- /dev/null +++ b/tests/cmdline_parser_test.cpp @@ -0,0 +1,52 @@ +// cmdline_parser_test.cpp +// +// Test the Rivendell command-line parser routines. +// +// (C) Copyright 2020 Fred Gleason +// +// 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 +#include + +#include + +#include + +#include "cmdline_parser_test.h" + +MainObject::MainObject(QObject *parent) + :QObject(parent) +{ + // + // Read Command Options + // + RDCmdSwitch *cmd= + new RDCmdSwitch(qApp->argc(),qApp->argv(),"cmdline_parser_test", + CMDLINE_PARSER_TEST_USAGE); + for(unsigned i=0;ikeys();i++) { + printf(" key[%d]: %s\n",i,cmd->key(i).utf8().constData()); + printf("value[%d]: %s\n",i,cmd->value(i).toUtf8().constData()); + } + exit(0); +} + + +int main(int argc,char *argv[]) +{ + QApplication a(argc,argv,false); + new MainObject(); + return a.exec(); +} diff --git a/tests/cmdline_parser_test.h b/tests/cmdline_parser_test.h new file mode 100644 index 00000000..a0fc265e --- /dev/null +++ b/tests/cmdline_parser_test.h @@ -0,0 +1,35 @@ +// cmdline_parser_test.h +// +// Test the Rivendell command-line parser routines. +// +// (C) Copyright 2020 Fred Gleason +// +// 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. +// + +#ifndef CMDLINE_PARSER_TEST_H +#define CMDLINE_PARSER_TEST_H + +#include + +#define CMDLINE_PARSER_TEST_USAGE " ...\n\n" + +class MainObject : public QObject +{ + public: + MainObject(QObject *parent=0); +}; + + +#endif // CMDLINE_PARSER_TEST_H