diff --git a/ChangeLog b/ChangeLog index 85e8de67..51e8d829 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22833,6 +22833,11 @@ * Removed the 'RDAirPlayConf::soundPanelChannelName()' method. 2021-12-21 David Klann * Add missing files to EXTRA_DIST in versions. +2021-12-22 Fred Gleason + * Added the ability to filter the library by two scheduler codes. +2021-12-22 Fred Gleason + * Added '%z', '%:z' and '%::z' patterns to the set of filepath + wildcards. 2021-12-23 Fred Gleason * Refactored the build of the 'python3-rivwebpyapi' deb package so as to include proper PyPI package metadata. diff --git a/docs/opsguide/filepath_wildcards.xml b/docs/opsguide/filepath_wildcards.xml index 3be63e70..3c056762 100644 --- a/docs/opsguide/filepath_wildcards.xml +++ b/docs/opsguide/filepath_wildcards.xml @@ -1,8 +1,8 @@ Filepath Wildcards - Filepath wildcards can be used in most places in RDAdmin where a filename - is required. + Filepath wildcards can be used in most places in RDAdmin and RDCatch + where a filename or URL is required. Definition @@ -473,7 +473,23 @@ z - [unassigned] + -HHMM numeric timezone (e.g. -0400) + + + + + :z + + + -HH:MM numeric timezone (e.g. -04:00) + + + + + ::z + + + -HH:MM:SS numeric timezone (e.g. -04:00:00) @@ -501,7 +517,8 @@ Examples - For the date time of February 3rd, 2017 at 2:34:26 PM: + For the date time of February 3rd, 2017 at 2:34:26 PM, in the + America/New_York timezone: @@ -640,6 +657,22 @@ + + %Y-%m-%dT%H:%M:%S + + + 2017-02-03T14:34:26 + + + + + %Y-%m-%dT%H:%M:%S%:z + + + 2017-02-03T14:34:26-05:00 + + + diff --git a/lib/rdcartfilter.cpp b/lib/rdcartfilter.cpp index 606c04d2..643434a2 100644 --- a/lib/rdcartfilter.cpp +++ b/lib/rdcartfilter.cpp @@ -88,11 +88,20 @@ RDCartFilter::RDCartFilter(bool show_drag_box,bool user_is_admin, // Scheduler Codes Filter // d_codes_box=new QComboBox(this); - d_codes_label=new QLabel(tr("Scheduler Code:"),this); + d_codes_label=new QLabel(tr("Scheduler Codes:"),this); d_codes_label->setFont(labelFont()); d_codes_label->setAlignment(Qt::AlignVCenter|Qt::AlignRight); connect(d_codes_box,SIGNAL(activated(const QString &)), this,SLOT(schedulerCodeChangedData(const QString &))); + d_and_codes_box=new QComboBox(this); + d_and_codes_box->setDisabled(true); + d_and_codes_label=new QLabel(" "+tr("and")+" ",this); + d_and_codes_label->setFont(labelFont()); + d_and_codes_label->setAlignment(Qt::AlignVCenter|Qt::AlignRight); + d_and_codes_box->insertItem(0,tr("[none]")); + d_and_codes_label->setDisabled(true); + connect(d_and_codes_box,SIGNAL(activated(const QString &)), + this,SLOT(andSchedulerCodeChangedData(const QString &))); // // Results Counter @@ -239,13 +248,30 @@ QString RDCartFilter::filterSql(const QStringList &and_fields) const // // Schedule Code Filter // - if(d_codes_box->currentText()!=tr("ALL")) { + if(d_codes_box->currentIndex()>0) { sql+="&&(`CART_SCHED_CODES`.`SCHED_CODE`='"+ RDEscapeString(d_codes_box->currentText())+"') "; + if(d_and_codes_box->currentIndex()>0) { + // + // Generate a list of carts with the second scheduler code + // + QString sub_sql; + QString cart_sql=QString("select ")+ + "`CART_NUMBER` "+ // 00 + "from `CART_SCHED_CODES` where "+ + "`SCHED_CODE`='"+RDEscapeString(d_and_codes_box->currentText())+"'"; + RDSqlQuery *q=new RDSqlQuery(cart_sql); + while(q->next()) { + sub_sql+= + QString::asprintf("(`CART`.`NUMBER`=%u)||",q->value(0).toUInt()); + } + delete q; + if(!sub_sql.isEmpty()) { + sql+="&&("+sub_sql.left(sub_sql.length()-2)+")"; + } + } } - // sql+="order by `CART`.`NUMBER` "; - return sql; } @@ -481,6 +507,31 @@ void RDCartFilter::groupChangedData(const QString &str) void RDCartFilter::schedulerCodeChangedData(const QString &str) +{ + QString sql; + RDSqlQuery *q=NULL; + + d_and_codes_label->setEnabled(d_codes_box->currentIndex()>0); + d_and_codes_box->setEnabled(d_codes_box->currentIndex()>0); + d_and_codes_box->clear(); + d_and_codes_box->insertItem(0,tr("[none]")); + if(d_codes_box->currentIndex()>0) { + sql=QString("select ")+ + "`CODE` "+ // 00 + "from `SCHED_CODES` where "+ + "`CODE`!='"+RDEscapeString(d_codes_box->currentText())+"' "+ + "order by `CODE`"; + q=new RDSqlQuery(sql); + while(q->next()) { + d_and_codes_box->insertItem(d_codes_box->count(),q->value(0).toString()); + } + delete q; + } + filterChangedData(""); +} + + +void RDCartFilter::andSchedulerCodeChangedData(const QString &str) { filterChangedData(""); } @@ -523,6 +574,8 @@ void RDCartFilter::resizeEvent(QResizeEvent *e) d_group_box->setGeometry(70,38,140,24); d_codes_label->setGeometry(215,40,115,20); d_codes_box->setGeometry(335,38,120,24); + d_and_codes_label->setGeometry(455,40,labelFontMetrics()->width(d_and_codes_label->text()),20); + d_and_codes_box->setGeometry(d_and_codes_label->x()+d_and_codes_label->width(),38,120,24); d_matches_label->setGeometry(660,40,100,20); d_matches_edit->setGeometry(765,40,55,20); d_showmatches_label->setGeometry(760,66,200,20); diff --git a/lib/rdcartfilter.h b/lib/rdcartfilter.h index 42a185bb..7d5ec78c 100644 --- a/lib/rdcartfilter.h +++ b/lib/rdcartfilter.h @@ -81,6 +81,7 @@ class RDCartFilter : public RDWidget void clearClickedData(); void groupChangedData(const QString &str); void schedulerCodeChangedData(const QString &str); + void andSchedulerCodeChangedData(const QString &str); void checkChangedData(int n); void dragsChangedData(int n); void searchLimitChangedData(int state); @@ -99,6 +100,10 @@ class RDCartFilter : public RDWidget QLabel *d_group_label; QComboBox *d_codes_box; QLabel *d_codes_label; + + QComboBox *d_and_codes_box; + QLabel *d_and_codes_label; + QLineEdit *d_matches_edit; QLabel *d_matches_label; QPushButton *d_search_button; diff --git a/lib/rdconf.h b/lib/rdconf.h index 4a5eb0a1..d8e3aaf4 100644 --- a/lib/rdconf.h +++ b/lib/rdconf.h @@ -101,7 +101,6 @@ QDateTime RDLocalToUtc(const QDateTime &localdatetime); QTime RDLocalToUtc(const QTime &localtime); QDateTime RDUtcToLocal(const QDateTime &gmtdatetime); QTime RDUtcToLocal(const QTime &gmttime); -//int RDTimeZoneOffset(); QColor RDGetTextColor(const QColor &background_color); bool RDProcessActive(const QString &cmd); bool RDProcessActive(const QStringList &cmds); diff --git a/lib/rddatedecode.cpp b/lib/rddatedecode.cpp index d22acd06..70d7fb31 100644 --- a/lib/rddatedecode.cpp +++ b/lib/rddatedecode.cpp @@ -20,7 +20,44 @@ #include -#include +#include "rdconf.h" +#include "rddatedecode.h" +#include "rddatetime.h" + +QString __RDDateCode_TZFormat(int level) +{ + int offset=RDTimeZoneOffset(); + int hours=abs(offset/3600); + int minutes=(abs(offset)-3600*hours)/60; + int seconds=abs(offset)-3600*hours-60*minutes; + QString ret; + + switch(level) { + case 0: + ret=QString::asprintf("%02d",hours).left(2)+ + QString::asprintf("%02d",minutes).left(2); + break; + + case 1: + ret=QString::asprintf("%02d",hours).left(2)+":"+ + QString::asprintf("%02d",minutes).left(2); + break; + + case 2: + ret=QString::asprintf("%02d",hours).left(2)+":"+ + QString::asprintf("%02d",minutes).left(2)+":"+ + QString::asprintf("%02d",seconds).left(2); + break; + } + if(offset<0) { + ret="+"+ret; + } + else { + ret="-"+ret; + } + + return ret; +} QString RDDateDecode(QString str,const QDate &date,RDStation *station, RDConfig *config,const QString &svcname) @@ -453,6 +490,24 @@ QString RDDateTimeDecode(QString str,const QDateTime &datetime, field=QString::asprintf("%04d",dt.date().year()); break; + case 'z': // +hhmm numeric time zone (e.g., -0400) + field=__RDDateCode_TZFormat(0); + break; + + case ':': // Extended numeric timezones + if((str.length()>(i+1))&&(str.at(i+1)==QChar('z'))) { + field=__RDDateCode_TZFormat(1); + i++; + } + else { + if((str.length()>(i+2))&&(str.at(i+1)==QChar(':'))&& + (str.at(i+2)==QChar('z'))) { + field=__RDDateCode_TZFormat(2); + i+=2; + } + } + break; + case '%': // Literal '%' field=QString("%"); break;