2021-01-25 Fred Gleason <fredg@paravelsystems.com>

* Added 'RDFeedListModel' class
	* Refactored the top-level window in rdcastmanager(1) to use the
	model-based API.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason
2021-01-25 09:28:43 -05:00
parent be3fcfd4ef
commit 9d5d446c2a
24 changed files with 945 additions and 278 deletions

View File

@@ -384,13 +384,13 @@ void EditCast::okData()
return;
}
done(0);
done(true);
}
void EditCast::cancelData()
{
done(-1);
done(false);
}

View File

@@ -41,11 +41,10 @@
#include "../icons/whiteball.xpm"
#include "../icons/rdcastmanager-32x32.xpm"
ListCasts::ListCasts(unsigned feed_id,bool is_super,QWidget *parent)
ListCasts::ListCasts(unsigned feed_id,QWidget *parent)
: RDDialog(parent)
{
list_feed_id=feed_id;
list_is_superfeed=is_super;
setWindowTitle("RDCastManager - "+tr("Podcast Item List")+
" [Feed ID: "+QString().sprintf("%u",feed_id)+"]");
@@ -486,7 +485,7 @@ void ListCasts::postProgressChangedData(int step)
void ListCasts::closeData()
{
done(0);
done(true);
}
@@ -566,7 +565,7 @@ void ListCasts::RefreshList()
list_casts_view->clear();
sql=QString("select ID from PODCASTS ")+
RDCastSearch(list_feed->keyName(),list_is_superfeed,
RDCastSearch(list_feed->keyName(),false,
list_filter_edit->text(),
list_active_check->isChecked())+
" order by ORIGIN_DATETIME";

View File

@@ -35,7 +35,7 @@ class ListCasts : public RDDialog
{
Q_OBJECT
public:
ListCasts(unsigned feed_id,bool is_super,QWidget *parent=0);
ListCasts(unsigned feed_id,QWidget *parent=0);
~ListCasts();
QSize sizeHint() const;
QSizePolicy sizePolicy() const;
@@ -84,7 +84,6 @@ class ListCasts : public RDDialog
QProgressDialog *list_progress_dialog;
RenderDialog *list_render_dialog;
RDFeed *list_feed;
bool list_is_superfeed;
};

View File

@@ -2,7 +2,7 @@
//
// A PodCast Management Utility for Rivendell.
//
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2021 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
@@ -18,26 +18,20 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <qapplication.h>
#include <qclipboard.h>
#include <qtranslator.h>
#include <qmessagebox.h>
#include <QApplication>
#include <QClipboard>
#include <QTranslator>
#include <QMessageBox>
#include <rdconf.h>
#include <rdescape_string.h>
#include <rdpodcast.h>
#include "edit_cast.h"
#include "globals.h"
#include "list_casts.h"
#include "rdcastmanager.h"
//
// Icons
//
#include "../icons/greencheckmark.xpm"
#include "../icons/redx.xpm"
#include "../icons/rdcastmanager-32x32.xpm"
//
// Global Resources
//
@@ -68,6 +62,8 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
QMessageBox::critical(this,"RDCastManager - "+tr("Error"),err_msg);
exit(1);
}
setWindowIcon(rda->iconEngine()->
applicationIcon(RDIconEngine::RdCastManager,22));
//
// Read Command Options
@@ -92,15 +88,6 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
rda->ripc()->
connectHost("localhost",RIPCD_TCP_PORT,rda->config()->password());
//
// Create Icons
//
setWindowIcon(rda->iconEngine()->
applicationIcon(RDIconEngine::RdCastManager,22));
cast_greencheckmark_map=new QPixmap(greencheckmark_xpm);
cast_redx_map=new QPixmap(redx_xpm);
cast_rdcastmanager_32x32_map=new QPixmap(rdcastmanager_32x32_xpm);
//
// Notifications
//
@@ -110,29 +97,24 @@ MainWidget::MainWidget(RDConfig *c,QWidget *parent)
//
// Feed List
//
cast_feed_list=new RDListView(this);
cast_feed_list->setAllColumnsShowFocus(true);
cast_feed_list->setItemMargin(5);
connect(cast_feed_list,SIGNAL(clicked(Q3ListViewItem *)),
this,SLOT(feedClickedData(Q3ListViewItem *)));
connect(cast_feed_list,
SIGNAL(doubleClicked(Q3ListViewItem *,const QPoint &,int)),
this,
SLOT(feedDoubleclickedData(Q3ListViewItem *,const QPoint &,int)));
cast_feed_list->addColumn("");
cast_feed_list->setColumnAlignment(0,Qt::AlignCenter);
cast_feed_list->addColumn(tr("Key Name"));
cast_feed_list->setColumnAlignment(1,Qt::AlignLeft);
cast_feed_list->addColumn(tr("Feed Name"));
cast_feed_list->setColumnAlignment(2,Qt::AlignLeft);
cast_feed_list->addColumn(tr("Casts"));
cast_feed_list->setColumnAlignment(3,Qt::AlignCenter);
cast_feed_list->addColumn(tr("Public URL"));
cast_feed_list->setColumnAlignment(4,Qt::AlignLeft);
cast_feed_view=new QTreeView(this);
cast_feed_view->setSelectionBehavior(QAbstractItemView::SelectRows);
cast_feed_view->setSortingEnabled(false);
cast_feed_view->setWordWrap(false);
cast_feed_model=new RDFeedListModel(this);
cast_feed_model->setFont(font());
cast_feed_model->setPalette(palette());
cast_feed_view->setModel(cast_feed_model);
connect(cast_feed_model,SIGNAL(modelReset()),this,SLOT(modelResetData()));
connect(rda->ripc(),SIGNAL(notificationReceived(RDNotification *)),
cast_feed_model,SLOT(processNotification(RDNotification *)));
connect(cast_feed_view,SIGNAL(doubleClicked(const QModelIndex &)),
this,SLOT(feedDoubleClickedData(const QModelIndex &)));
connect(cast_feed_view->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection &,const QItemSelection &)),
this,
SLOT(selectionChangedData(const QItemSelection &,
const QItemSelection &)));
//
// Open Button
@@ -183,8 +165,33 @@ void MainWidget::userChangedData()
str1=QString("RDCastManager")+" v"+VERSION+" - "+tr("Host");
str2=QString(tr("User"));
setCaption(str1+": "+rda->config()->stationName()+" "+str2+" "+rda->ripc()->user());
RefreshList();
setWindowTitle(str1+": "+rda->config()->stationName()+" "+str2+" "+rda->ripc()->user());
cast_feed_model->changeUser();
}
void MainWidget::modelResetData()
{
for(int i=0;i<cast_feed_model->columnCount();i++) {
cast_feed_view->resizeColumnToContents(i);
}
}
void MainWidget::selectionChangedData(const QItemSelection &before,
const QItemSelection &after)
{
QModelIndexList rows=cast_feed_view->selectionModel()->selectedRows();
cast_open_button->setEnabled(rows.size()==1);
cast_copy_button->setEnabled(rows.size()==1);
if(cast_feed_model->isFeed(rows.first())) {
cast_open_button->setText(tr("View\nFeed"));
}
if(cast_feed_model->isCast(rows.first())) {
cast_open_button->setText(tr("Edit"));
}
}
@@ -197,62 +204,47 @@ void MainWidget::feedClickedData(Q3ListViewItem *item)
void MainWidget::openData()
{
RDListViewItem *item=(RDListViewItem *)cast_feed_list->selectedItem();
if(item==NULL) {
QModelIndexList rows=cast_feed_view->selectionModel()->selectedRows();
if(rows.size()!=1) {
return;
}
ListCasts *casts=
new ListCasts(item->id(),item->text(3)==tr("[superfeed]"),this);
casts->exec();
RefreshItem(item);
delete casts;
if(cast_feed_model->isFeed(rows.first())) {
ListCasts *d=new ListCasts(cast_feed_model->feedId(rows.first()),this);
if(d->exec()) {
cast_feed_model->refreshRow(rows.first());
}
delete d;
}
if(cast_feed_model->isCast(rows.first())) {
EditCast *d=new EditCast(cast_feed_model->castId(rows.first()),this);
if(d->exec()) {
cast_feed_model->refreshRow(rows.first());
}
delete d;
}
}
void MainWidget::copyData()
{
RDListViewItem *item=(RDListViewItem *)cast_feed_list->selectedItem();
if(item==NULL) {
QModelIndexList rows=cast_feed_view->selectionModel()->selectedRows();
if(rows.size()!=1) {
return;
}
QApplication::clipboard()->setText(item->text(4));
QApplication::clipboard()->setText(cast_feed_model->publicUrl(rows.first()));
}
void MainWidget::feedDoubleclickedData(Q3ListViewItem *,const QPoint &,int)
void MainWidget::feedDoubleClickedData(const QModelIndex &index)
{
openData();
}
void MainWidget::notificationReceivedData(RDNotification *notify)
{
QString keyname;
RDListViewItem *item=NULL;
if(notify->type()==RDNotification::FeedType) {
keyname=notify->id().toString();
switch(notify->action()) {
case RDNotification::ModifyAction:
item=(RDListViewItem *)cast_feed_list->firstChild();
while(item!=NULL) {
if(item->text(1)==keyname) {
RefreshItem(item);
}
item=(RDListViewItem *)item->nextSibling();
}
break;
case RDNotification::NoAction:
case RDNotification::AddAction:
case RDNotification::DeleteAction:
case RDNotification::LastAction:
break;
}
}
}
void MainWidget::quitMainWidget()
{
exit(0);
@@ -262,7 +254,7 @@ void MainWidget::quitMainWidget()
void MainWidget::resizeEvent(QResizeEvent *e)
{
if(cast_resize) {
cast_feed_list->setGeometry(10,10,size().width()-20,size().height()-70);
cast_feed_view->setGeometry(10,10,size().width()-20,size().height()-70);
cast_open_button->setGeometry(10,size().height()-55,80,50);
cast_copy_button->setGeometry(120,size().height()-55,100,50);
cast_close_button->setGeometry(size().width()-90,size().height()-55,80,50);
@@ -270,103 +262,6 @@ void MainWidget::resizeEvent(QResizeEvent *e)
}
void MainWidget::RefreshItem(RDListViewItem *item)
{
RDSqlQuery *q;
RDSqlQuery *q1;
QString sql;
int active=0;
int total=0;
sql=QString("select ")+
"FEEDS.CHANNEL_TITLE,"+ // 00
"FEEDS.IS_SUPERFEED,"+ // 01
"FEEDS.ID,"+ // 02
"FEEDS.BASE_URL,"+ // 03
"FEED_IMAGES.DATA "+ // 04
"from FEEDS left join FEED_IMAGES "+
"on FEEDS.CHANNEL_IMAGE_ID=FEED_IMAGES.ID where "+
"FEEDS.KEY_NAME=\""+RDEscapeString(item->text(1))+"\"";
q=new RDSqlQuery(sql);
while(q->next()) {
sql=QString().sprintf("select STATUS from PODCASTS where FEED_ID=%u",
q->value(2).toUInt());
q1=new RDSqlQuery(sql);
while(q1->next()) {
total++;
switch((RDPodcast::Status)q1->value(0).toUInt()) {
case RDPodcast::StatusActive:
case RDPodcast::StatusExpired:
active++;
break;
case RDPodcast::StatusPending:
break;
}
}
delete q1;
if(q->value(4).isNull()) {
item->setPixmap(0,*cast_rdcastmanager_32x32_map);
}
else {
QImage img=QImage::fromData(q->value(4).toByteArray());
item->setPixmap(0,QPixmap::fromImage(img.scaled(32,32)));
}
item->setText(2,q->value(0).toString());
if(RDBool(q->value(1).toString())) {
item->setText(3,tr("[superfeed]"));
}
else {
item->setText(3,QString().sprintf("%d / %d",active,total));
}
item->setText(4,RDFeed::publicUrl(q->value(3).toString(),item->text(1)));
}
delete q;
}
void MainWidget::RefreshList()
{
RDSqlQuery *q;
QString sql;
int id=-1;
RDListViewItem *selected_item=NULL;
RDListViewItem *item=(RDListViewItem *)cast_feed_list->selectedItem();
if(item!=NULL) {
id=item->id();
}
cast_feed_list->clear();
sql=QString("select KEY_NAME from FEED_PERMS where ")+
"USER_NAME=\""+RDEscapeString(rda->user()->name())+"\"";
q=new RDSqlQuery(sql);
if(q->size()<=0) { // No valid feeds!
delete q;
return;
}
sql="select ID,KEY_NAME from FEEDS where ";
while(q->next()) {
sql+=QString("(KEY_NAME=\"")+RDEscapeString(q->value(0).toString())+"\")||";
}
delete q;
sql=sql.left(sql.length()-2);
q=new RDSqlQuery(sql);
while(q->next()) {
item=new RDListViewItem(cast_feed_list);
item->setId(q->value(0).toInt());
item->setText(1,q->value(1).toString());
RefreshItem(item);
if(item->id()==id) {
selected_item=item;
}
}
delete q;
if(selected_item!=NULL) {
cast_feed_list->setSelected(selected_item,true);
cast_feed_list->ensureItemVisible(item);
}
}
int main(int argc,char *argv[])
{
QApplication::setStyle(RD_GUI_STYLE);

View File

@@ -2,7 +2,7 @@
//
// A RSS Feed Management Utility for Rivendell.
//
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2021 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
@@ -21,9 +21,11 @@
#ifndef RDCASTMANAGER_H
#define RDCASTMANAGER_H
#include <qpushbutton.h>
#include <QPushButton>
#include <QTreeView>
#include <rdconfig.h>
#include <rdfeedlistmodel.h>
#include <rdlog_line.h>
#include <rdwidget.h>
@@ -41,21 +43,19 @@ class MainWidget : public RDWidget
void openData();
void copyData();
void userChangedData();
void modelResetData();
void selectionChangedData(const QItemSelection &before,
const QItemSelection &after);
void feedClickedData(Q3ListViewItem *item);
void feedDoubleclickedData(Q3ListViewItem *item,const QPoint &pt,int col);
void notificationReceivedData(RDNotification *notify);
void feedDoubleClickedData(const QModelIndex &index);
void quitMainWidget();
protected:
void resizeEvent(QResizeEvent *e);
private:
void RefreshItem(RDListViewItem *item);
void RefreshList();
RDListView *cast_feed_list;
QPixmap *cast_greencheckmark_map;
QPixmap *cast_redx_map;
QPixmap *cast_rdcastmanager_32x32_map;
QTreeView *cast_feed_view;
RDFeedListModel *cast_feed_model;
QPushButton *cast_open_button;
QPushButton *cast_copy_button;
QPushButton *cast_close_button;

View File

@@ -473,11 +473,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Název klíče</translation>
<translation type="obsolete">Název klíče</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Název přívodu</translation>
<translation type="obsolete">Název přívodu</translation>
</message>
<message>
<source>Description</source>
@@ -485,7 +485,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Podcasty</translation>
<translation type="obsolete">Podcasty</translation>
</message>
<message>
<source>&amp;View
@@ -499,7 +499,7 @@ přívod</translation>
</message>
<message>
<source>User</source>
<translation>Uživatel</translation>
<translation type="unfinished">Uživatel</translation>
</message>
<message>
<source>Host</source>
@@ -513,17 +513,18 @@ přívod</translation>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -458,11 +458,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Schlüsselname</translation>
<translation type="obsolete">Schlüsselname</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Feedname</translation>
<translation type="obsolete">Feedname</translation>
</message>
<message>
<source>Description</source>
@@ -470,7 +470,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Casts</translation>
<translation type="obsolete">Casts</translation>
</message>
<message>
<source>&amp;View
@@ -484,7 +484,7 @@ Feed</translation>
</message>
<message>
<source>User</source>
<translation>Benutzer</translation>
<translation type="unfinished">Benutzer</translation>
</message>
<message>
<source>Host</source>
@@ -498,17 +498,18 @@ Feed</translation>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -413,11 +413,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Nombre Clave</translation>
<translation type="obsolete">Nombre Clave</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Nombre del Feed</translation>
<translation type="obsolete">Nombre del Feed</translation>
</message>
<message>
<source>Description</source>
@@ -425,7 +425,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Podcasts</translation>
<translation type="obsolete">Podcasts</translation>
</message>
<message>
<source>&amp;Close</source>
@@ -433,7 +433,7 @@ Log</source>
</message>
<message>
<source>User</source>
<translation>Usuario</translation>
<translation type="unfinished">Usuario</translation>
</message>
<message>
<source>&amp;View
@@ -452,17 +452,18 @@ Feed</source>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -288,18 +288,6 @@ Log</source>
<source>User: [Unknown]</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Key Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Feed Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Casts</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;View
Feed</source>
@@ -309,10 +297,6 @@ Feed</source>
<source>&amp;Close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Host</source>
<translation type="unfinished"></translation>
@@ -325,17 +309,22 @@ Feed</source>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>User</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -440,11 +440,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Lykjelnamn</translation>
<translation type="obsolete">Lykjelnamn</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Straumnamn</translation>
<translation type="obsolete">Straumnamn</translation>
</message>
<message>
<source>Description</source>
@@ -452,7 +452,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Kastar</translation>
<translation type="obsolete">Kastar</translation>
</message>
<message>
<source>&amp;View
@@ -466,7 +466,7 @@ straum</translation>
</message>
<message>
<source>User</source>
<translation>Brukar</translation>
<translation type="unfinished">Brukar</translation>
</message>
<message>
<source>Host</source>
@@ -480,17 +480,18 @@ straum</translation>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -440,11 +440,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Lykjelnamn</translation>
<translation type="obsolete">Lykjelnamn</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Straumnamn</translation>
<translation type="obsolete">Straumnamn</translation>
</message>
<message>
<source>Description</source>
@@ -452,7 +452,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Kastar</translation>
<translation type="obsolete">Kastar</translation>
</message>
<message>
<source>&amp;View
@@ -466,7 +466,7 @@ straum</translation>
</message>
<message>
<source>User</source>
<translation>Brukar</translation>
<translation type="unfinished">Brukar</translation>
</message>
<message>
<source>Host</source>
@@ -480,17 +480,18 @@ straum</translation>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>

View File

@@ -418,11 +418,11 @@ Log</source>
</message>
<message>
<source>Key Name</source>
<translation>Nome chave</translation>
<translation type="obsolete">Nome chave</translation>
</message>
<message>
<source>Feed Name</source>
<translation>Nome do Feed</translation>
<translation type="obsolete">Nome do Feed</translation>
</message>
<message>
<source>Description</source>
@@ -430,7 +430,7 @@ Log</source>
</message>
<message>
<source>Casts</source>
<translation>Casts</translation>
<translation type="obsolete">Casts</translation>
</message>
<message>
<source>&amp;View
@@ -444,7 +444,7 @@ Feed</translation>
</message>
<message>
<source>User</source>
<translation>Usuário</translation>
<translation type="unfinished">Usuário</translation>
</message>
<message>
<source>Host</source>
@@ -458,17 +458,18 @@ Feed</translation>
<source>Unknown command option</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Public URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Copy URL to
Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>[superfeed]</source>
<source>View
Feed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Edit</source>
<translation type="unfinished"></translation>
</message>
</context>