Rivendellaudio/lib/rdcut_dialog.cpp
Fred Gleason 42691d70aa 2020-02-25 Fred Gleason <fredg@paravelsystems.com>
* Removed the 'Q3ProgressDialog' dependency from the 'Select Cut'
	dialog.
2020-02-25 17:20:35 -05:00

672 lines
16 KiB
C++

// rdcut_dialog.cpp
//
// A widget to select a Rivendell Cut.
//
// (C) Copyright 2002-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 <stdlib.h>
#include <stdio.h>
#include <qpushbutton.h>
#include <qapplication.h>
#include "rdadd_cart.h"
#include "rdapplication.h"
#include "rdcart_search_text.h"
#include "rdconf.h"
#include "rdcut_dialog.h"
#include "rddb.h"
#include "rdescape_string.h"
#include "rdprofile.h"
#include "rdtextvalidator.h"
//
// Icons
//
#include "../icons/play.xpm"
#include "../icons/rml5.xpm"
RDCutDialog::RDCutDialog(QString *cutname,const QString &caption,
QString *filter,QString *group,
QString *schedcode,bool show_clear,bool allow_add,
bool exclude_tracks,QWidget *parent)
: RDDialog(parent)
{
cut_cutname=cutname;
cut_caption=caption;
cut_exclude_tracks=exclude_tracks;
cut_group=group;
cut_schedcode=schedcode;
cut_allow_clear=show_clear;
if(filter==NULL) {
cut_filter=new QString();
local_filter=true;
}
else {
cut_filter=filter;
local_filter=false;
}
setWindowTitle(caption+" - "+tr("Select Cut"));
//
// Create Icons
//
cut_playout_map=new QPixmap(play_xpm);
cut_macro_map=new QPixmap(rml5_xpm);
//
// Fix the Window Size
//
setMinimumWidth(sizeHint().width());
setMaximumWidth(sizeHint().width());
setMinimumHeight(sizeHint().height());
setMaximumHeight(sizeHint().height());
//
// Progress Dialog
//
cut_progress_dialog=
new QProgressDialog(tr("Please Wait..."),"Cancel",0,10,this,
Qt::WStyle_Customize|Qt::WStyle_NormalBorder);
cut_progress_dialog->setCaption(" ");
QLabel *label=new QLabel(tr("Please Wait..."),cut_progress_dialog);
label->setAlignment(Qt::AlignCenter);
label->setFont(progressFont());
cut_progress_dialog->setLabel(label);
cut_progress_dialog->setCancelButton(NULL);
cut_progress_dialog->setMinimumDuration(2000);
//
// Filter Selector
//
cut_filter_edit=new QLineEdit(this);
label=new QLabel(cut_filter_edit,tr("Cart Filter:"),this);
label->setGeometry(10,10,85,20);
label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
label->setFont(labelFont());
connect(cut_filter_edit,SIGNAL(textChanged(const QString &)),
this,SLOT(filterChangedData(const QString &)));
//
// Filter Search Button
//
cut_search_button=new QPushButton(this);
cut_search_button->setGeometry(sizeHint().width()-140,8,60,24);
cut_search_button->setText(tr("&Search"));
cut_search_button->setFont(buttonFont());
connect(cut_search_button,SIGNAL(clicked()),this,SLOT(searchButtonData()));
//
// Filter Clear Button
//
cut_clear_button=new QPushButton(this);
cut_clear_button->setGeometry(sizeHint().width()-70,8,60,24);
cut_clear_button->setFont(buttonFont());
cut_clear_button->setText(tr("C&lear"));
connect(cut_clear_button,SIGNAL(clicked()),this,SLOT(clearData()));
//
// Group Selector
//
cut_group_box=new QComboBox(this);
cut_group_box->setGeometry(100,40,140,20);
label=new QLabel(cut_filter_edit,tr("Group:"),this);
label->setGeometry(10,40,85,20);
label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
label->setFont(labelFont());
connect(cut_group_box,SIGNAL(activated(const QString &)),
this,SLOT(groupActivatedData(const QString &)));
//
// Scheduler Code Selector
//
cut_schedcode_box=new QComboBox(this);
cut_schedcode_box->setGeometry(380,40,sizeHint().width()-390,20);
cut_schedcode_label=new QLabel(cut_schedcode_box,tr("Scheduler Code:"),this);
cut_schedcode_label->setGeometry(260,40,115,20);
cut_schedcode_label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
cut_schedcode_label->setFont(labelFont());
connect(cut_schedcode_box,SIGNAL(activated(const QString &)),
this,SLOT(groupActivatedData(const QString &)));
//
// Search Limit Checkbox
//
cart_limit_box=new QCheckBox(this);
cart_limit_box->setGeometry(100,72,15,15);
cart_limit_box->setChecked(true);
label=new QLabel(cart_limit_box,tr("Show Only First")+
QString().sprintf(" %d ",
RD_LIMITED_CART_SEARCH_QUANTITY)+tr("Matches"),this);
label->setGeometry(120,70,300,20);
label->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
label->setFont(labelFont());
connect(cart_limit_box,SIGNAL(stateChanged(int)),
this,SLOT(limitChangedData(int)));
//
// Cart List
//
cut_cart_list=new RDListView(this);
cut_cart_list->setGeometry(10,120,300,200);
cut_cart_list->setAllColumnsShowFocus(true);
cut_cart_list->setItemMargin(5);
connect(cut_cart_list,SIGNAL(selectionChanged()),
this,SLOT(selectionChangedData()));
connect(cut_cart_list,SIGNAL(clicked(Q3ListViewItem *)),
this,SLOT(cartClickedData(Q3ListViewItem *)));
label=new QLabel(cut_cart_list,tr("Carts"),this);
label->setGeometry(15,100,100,20);
label->setFont(labelFont());
cut_cart_list->addColumn("");
cut_cart_list->setColumnAlignment(0,Qt::AlignHCenter);
cut_cart_list->addColumn(tr("Number"));
cut_cart_list->setColumnAlignment(1,Qt::AlignHCenter);
cut_cart_list->addColumn(tr("Title"));
cut_cart_list->setColumnAlignment(2,Qt::AlignLeft);
cut_cart_list->addColumn(tr("Group"));
cut_cart_list->setColumnAlignment(3,Qt::AlignCenter);
//
// Cut List
//
cut_cut_list=new Q3ListView(this);
cut_cut_list->setGeometry(320,120,sizeHint().width()-330,200);
cut_cut_list->setAllColumnsShowFocus(true);
cut_cut_list->setItemMargin(5);
label=new QLabel(cut_cut_list,tr("Cuts"),this);
label->setGeometry(325,100,100,20);
label->setFont(labelFont());
cut_cut_list->addColumn(tr("Description"));
cut_cut_list->setColumnAlignment(0,Qt::AlignLeft);
cut_cut_list->addColumn(tr("Number"));
cut_cut_list->setColumnAlignment(1,Qt::AlignLeft);
QPushButton *button=NULL;
//
// Add Button
//
button=new QPushButton(tr("&Add New\nCart"),this);
button->setGeometry(10,sizeHint().height()-60,80,50);
button->setFont(buttonFont());
connect(button,SIGNAL(clicked()),this,SLOT(addButtonData()));
if(!allow_add) {
button->hide();
}
//
// Clear Button
//
button=new QPushButton(tr("&Clear"),this);
button->setFont(buttonFont());
connect(button,SIGNAL(clicked()),this,SLOT(clearButtonData()));
if(!show_clear) {
button->hide();
}
if(allow_add) {
button->setGeometry(100,sizeHint().height()-60,80,50);
}
else {
button->setGeometry(10,sizeHint().height()-60,80,50);
}
//
// OK Button
//
cut_ok_button=new QPushButton(tr("&OK"),this);
cut_ok_button->
setGeometry(sizeHint().width()-180,sizeHint().height()-60,80,50);
cut_ok_button->setFont(buttonFont());
cut_ok_button->setDefault(true);
connect(cut_ok_button,SIGNAL(clicked()),this,SLOT(okData()));
//
// Cancel Button
//
cut_cancel_button=new QPushButton(tr("&Cancel"),this);
cut_cancel_button->
setGeometry(sizeHint().width()-90,sizeHint().height()-60,80,50);
cut_cancel_button->setFont(buttonFont());
connect(cut_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData()));
//
// Populate Data
//
if(cut_cutname->isEmpty()) {
cut_ok_button->setDisabled(true);
}
switch(rda->station()->filterMode()) {
case RDStation::FilterAsynchronous:
cut_search_button->setDefault(true);
cut_filter_edit->setGeometry(100,10,sizeHint().width()-250,20);
break;
case RDStation::FilterSynchronous:
cut_ok_button->setDefault(true);
cut_search_button->hide();
cut_filter_edit->setGeometry(100,10,sizeHint().width()-180,20);
}
BuildGroupList();
cut_filter_edit->setText(*cut_filter);
RefreshCarts();
RefreshCuts();
SelectCut(*cut_cutname);
}
RDCutDialog::~RDCutDialog()
{
if(local_filter) {
delete cut_filter;
}
}
QSize RDCutDialog::sizeHint() const
{
return QSize(550,400);
}
QSizePolicy RDCutDialog::sizePolicy() const
{
return QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
}
int RDCutDialog::exec()
{
LoadState();
return QDialog::exec();
}
void RDCutDialog::filterChangedData(const QString &str)
{
cut_search_button->setEnabled(true);
switch(rda->station()->filterMode()) {
case RDStation::FilterSynchronous:
searchButtonData();
break;
case RDStation::FilterAsynchronous:
break;
}
}
void RDCutDialog::clearData()
{
cut_filter_edit->clear();
filterChangedData("");
}
void RDCutDialog::groupActivatedData(const QString &str)
{
filterChangedData("");
}
void RDCutDialog::limitChangedData(int state)
{
filterChangedData("");
}
void RDCutDialog::cartClickedData(Q3ListViewItem *)
{
cut_ok_button->setEnabled(true);
}
void RDCutDialog::selectionChangedData()
{
RefreshCuts();
if(cut_cut_list->firstChild()!=NULL) {
cut_cut_list->setSelected(cut_cut_list->firstChild(),true);
}
}
void RDCutDialog::searchButtonData()
{
if(cut_filter_edit->text().isEmpty()) {
cut_clear_button->setDisabled(true);
}
else {
cut_clear_button->setEnabled(true);
}
RefreshCarts();
RefreshCuts();
}
void RDCutDialog::clearButtonData()
{
RDListViewItem *item=(RDListViewItem *)cut_cart_list->selectedItem();
if(item!=NULL) {
cut_cart_list->setSelected(item,false);
}
cut_cut_list->clear();
}
void RDCutDialog::addButtonData()
{
QString cart_group=cut_group_box->currentText();
RDCart::Type cart_type=RDCart::Audio;
QString cart_title;
QString sql;
RDSqlQuery *q;
int cart_num=-1;
RDAddCart *add_cart=new RDAddCart(&cart_group,&cart_type,&cart_title,
rda->user()->name(),cut_caption,
rda->system(),this);
if((cart_num=add_cart->exec())<0) {
delete add_cart;
return;
}
sql=QString().sprintf("insert into CART set \
NUMBER=%d,TYPE=%d,GROUP_NAME=\"%s\",TITLE=\"%s\"",
cart_num,cart_type,
(const char *)cart_group,
(const char *)cart_title);
q=new RDSqlQuery(sql);
delete q;
RDCut::create(cart_num,1);
RDListViewItem *item=new RDListViewItem(cut_cart_list);
item->setPixmap(0,*cut_playout_map);
item->setText(1,QString().sprintf("%06d",cart_num));
item->setText(2,cart_title);
cut_cart_list->setSelected(item,true);
cut_cart_list->ensureItemVisible(item);
cut_ok_button->setEnabled(true);
delete add_cart;
}
void RDCutDialog::okData()
{
RDListViewItem *cart_item=(RDListViewItem *)cut_cart_list->selectedItem();
Q3ListViewItem *cut_item=cut_cut_list->selectedItem();
if((cart_item==NULL)||(cut_item==NULL)) {
if(cut_allow_clear) {
*cut_cutname="";
if(!local_filter) {
*cut_filter=cut_filter_edit->text();
}
if(cut_group!=NULL) {
*cut_group=cut_group_box->currentText();
}
if(cut_schedcode!=NULL) {
*cut_schedcode=cut_schedcode_box->currentText();
}
SaveState();
done(0);
}
return;
}
*cut_cutname=cart_item->text(1)+QString("_")+cut_item->text(1);
if(!local_filter) {
*cut_filter=cut_filter_edit->text();
}
if(cut_group!=NULL) {
*cut_group=cut_group_box->currentText();
}
SaveState();
done(0);
}
void RDCutDialog::cancelData()
{
SaveState();
done(1);
}
void RDCutDialog::closeEvent(QCloseEvent *e)
{
cancelData();
}
void RDCutDialog::RefreshCarts()
{
QString sql;
RDSqlQuery *q;
RDListViewItem *l;
QString group=cut_group_box->currentText();
if(!cut_cutname->isEmpty()) {
}
cut_cart_list->clear();
if(group==QString(tr("ALL"))) {
group="";
}
QString schedcode="";
if(cut_schedcode_box->currentText()!=tr("ALL")) {
schedcode=cut_schedcode_box->currentText();
}
sql=QString().sprintf("select CART.NUMBER,CART.TITLE,CART.GROUP_NAME,\
GROUPS.COLOR,CART.TYPE from CART left join GROUPS \
on CART.GROUP_NAME=GROUPS.NAME \
%s&&(CART.TYPE=%u)",
(const char *)RDCartSearchText(cut_filter_edit->text(),
group,schedcode.utf8(),
false),
RDCart::Audio);
if(cut_exclude_tracks) {
sql+="&&(CART.OWNER is null)";
}
if(cart_limit_box->isChecked()) {
sql+=QString().sprintf(" limit %d",RD_LIMITED_CART_SEARCH_QUANTITY);
}
q=new RDSqlQuery(sql);
int step=0;
int count=0;
cut_progress_dialog->setMaximum(q->size()/RDCUT_DIALOG_STEP_SIZE);
cut_progress_dialog->setValue(0);
while(q->next()) {
l=new RDListViewItem(cut_cart_list);
switch((RDCart::Type)q->value(4).toUInt()) {
case RDCart::Audio:
l->setPixmap(0,*cut_playout_map);
break;
case RDCart::All:
case RDCart::Macro:
break;
}
l->setText(1,QString().sprintf("%06u",q->value(0).toUInt())); // Number
l->setText(2,q->value(1).toString()); // Title
l->setText(3,q->value(2).toString()); // Group
l->setTextColor(3,q->value(3).toString(),QFont::Bold);
if(count++>RDCUT_DIALOG_STEP_SIZE) {
cut_progress_dialog->setValue(++step);
count=0;
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
}
}
cut_progress_dialog->reset();
delete q;
cut_search_button->setDisabled(true);
}
void RDCutDialog::RefreshCuts()
{
QString sql;
RDSqlQuery *q;
Q3ListViewItem *l;
Q3ListViewItem *cart_item=cut_cart_list->selectedItem();
cut_cut_list->clear();
if(cart_item==NULL) {
return;
}
sql=QString().sprintf("select DESCRIPTION,CUT_NAME from CUTS where \
CART_NUMBER=%s",(const char *)cart_item->text(1));
q=new RDSqlQuery(sql);
while(q->next()) {
l=new Q3ListViewItem(cut_cut_list);
l->setText(0,q->value(0).toString()); // Description
l->setText(1,QString().sprintf("%03u", // Cut Number
q->value(1).toString().right(3).toUInt()));
}
delete q;
}
void RDCutDialog::SelectCut(QString cutname)
{
QString cart=cutname.left(6);
QString cut=cutname.right(3);
Q3ListViewItem *item=cut_cart_list->findItem(cart,1);
if(item!=NULL) {
cut_cart_list->setSelected(item,true);
cut_cart_list->ensureItemVisible(item);
}
RefreshCuts();
item=cut_cut_list->findItem(cut,1);
if(item!=NULL) {
cut_cut_list->setSelected(item,true);
}
}
void RDCutDialog::BuildGroupList()
{
QString sql;
RDSqlQuery *q;
cut_group_box->clear();
cut_group_box->insertItem(tr("ALL"));
if(rda->user()->name().isEmpty()) {
sql="select NAME from GROUPS order by NAME desc";
}
else {
sql=QString("select GROUP_NAME from USER_PERMS where ")+
"USER_NAME=\""+RDEscapeString(rda->user()->name())+"\" "+
"order by GROUP_NAME desc";
}
q=new RDSqlQuery(sql);
while(q->next()) {
cut_group_box->insertItem(q->value(0).toString(),true);
}
delete q;
//
// Preselect Group
//
if(cut_group!=NULL) {
for(int i=0;i<cut_group_box->count();i++) {
if(*cut_group==cut_group_box->text(i)) {
cut_group_box->setCurrentItem(i);
return;
}
}
}
//
// Scheduler Codes
//
cut_schedcode_box->clear();
cut_schedcode_box->insertItem(tr("ALL"));
sql="select CODE from SCHED_CODES";
q=new RDSqlQuery(sql);
while(q->next()) {
cut_schedcode_box->insertItem(q->value(0).toString());
}
delete q;
//
// Preselect Scheduler Code
//
if(cut_schedcode!=NULL) {
for(int i=0;i<cut_schedcode_box->count();i++) {
if(*cut_schedcode==cut_schedcode_box->text(i)) {
cut_schedcode_box->setCurrentItem(i);
return;
}
}
}
}
QString RDCutDialog::StateFile() {
bool home_found = false;
QString home = RDGetHomeDir(&home_found);
if(home_found) {
return QString().sprintf("%s/.rdcartdialog",(const char *)home);
}
return QString();
}
void RDCutDialog::LoadState()
{
QString state_file = StateFile();
if(state_file.isEmpty()) {
return;
}
RDProfile *p=new RDProfile();
p->setSource(state_file);
bool value_read = false;
cart_limit_box->setChecked(p->boolValue("RDCartDialog", "LimitSearch", true, &value_read));
delete p;
}
void RDCutDialog::SaveState()
{
FILE *f=NULL;
QString state_file = StateFile();
if(state_file.isEmpty()) {
return;
}
if((f=fopen(state_file,"w"))==NULL) {
return;
}
fprintf(f,"[RDCartDialog]\n");
if(cart_limit_box->isChecked()) {
fprintf(f,"LimitSearch=Yes\n");
}
else {
fprintf(f,"LimitSearch=No\n");
}
fclose(f);
}