diff --git a/ChangeLog b/ChangeLog index 0c7d2b50..f8379bff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23973,3 +23973,6 @@ 2023-01-30 Fred Gleason * Refactored splash screen code so as not to hide the splash screen until after the event loop is started. +2023-02-03 Fred Gleason + * Optimized image loading in the 'Podcast Item List' dialog in + rdcastmanager(1). diff --git a/lib/rdpodcastlistmodel.cpp b/lib/rdpodcastlistmodel.cpp index 66b32fdf..f328668d 100644 --- a/lib/rdpodcastlistmodel.cpp +++ b/lib/rdpodcastlistmodel.cpp @@ -2,7 +2,7 @@ // // Data model for Rivendell podcast episodes // -// (C) Copyright 2021-2022 Fred Gleason +// (C) Copyright 2021-2023 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 @@ -75,8 +75,6 @@ RDPodcastListModel::RDPodcastListModel(unsigned feed_id,QObject *parent) d_headers.push_back(tr("SHA1")); // 08 d_alignments.push_back(left); d_column_fields.push_back("`PODCASTS`.`SHA1_HASH`"); - - updateModel(); } @@ -148,7 +146,13 @@ QVariant RDPodcastListModel::data(const QModelIndex &index,int role) const return d_texts.at(row).at(col); case Qt::DecorationRole: - return d_icons.at(row).at(col); + if(col==0) { + return d_item_images. + value(d_item_image_ids.at(row), + rda->iconEngine()-> + applicationIcon(RDIconEngine::RdCastManager,32)); + } + break; case Qt::TextAlignmentRole: return d_alignments.at(col); @@ -169,13 +173,11 @@ QVariant RDPodcastListModel::data(const QModelIndex &index,int role) const case Qt::SizeHintRole: if(col==0) { - return QSize(RD_LISTWIDGET_ITEM_WIDTH_PADDING+ - (d_icons.at(row).at(col).value().width())+ + return QSize(RD_LISTWIDGET_ITEM_WIDTH_PADDING+32+ d_bold_font_metrics-> width(d_texts.at(row).at(col).toString()),40); } return QSize(RD_LISTWIDGET_ITEM_WIDTH_PADDING+ - (d_icons.at(row).at(col).value().width())+ d_font_metrics-> width(d_texts.at(row).at(col).toString()),40); @@ -216,7 +218,7 @@ QModelIndex RDPodcastListModel::addCast(unsigned cast_id) } d_cast_ids.insert(0,cast_id); d_texts.insert(0,list); - d_icons.insert(0,list); + d_item_image_ids.insert(0,-1); updateRowLine(0); endInsertRows(); ret=createIndex(0,0); @@ -232,7 +234,7 @@ void RDPodcastListModel::removeCast(const QModelIndex &row) d_cast_ids.removeAt(row.row()); d_texts.removeAt(row.row()); - d_icons.removeAt(row.row()); + d_item_image_ids.removeAt(row.row()); endRemoveRows(); } @@ -258,6 +260,7 @@ void RDPodcastListModel::refresh(const QModelIndex &row) RDSqlQuery *q=new RDSqlQuery(sql); if(q->first()) { updateRow(row.row(),q); + loadItemImage(q->value(13).toInt()); emit dataChanged(createIndex(row.row(),0), createIndex(row.row(),columnCount())); } @@ -321,6 +324,7 @@ void RDPodcastListModel::processNotification(RDNotification *notify) void RDPodcastListModel::updateModel() { QList texts; + QList image_ids; RDSqlQuery *q=NULL; QString sql=sqlFields()+ @@ -335,15 +339,41 @@ void RDPodcastListModel::updateModel() beginResetModel(); d_cast_ids.clear(); d_texts.clear(); - d_icons.clear(); + d_item_image_ids.clear(); q=new RDSqlQuery(sql); while(q->next()) { d_cast_ids.push_back(0); d_texts.push_back(texts); - d_icons.push_back(texts); + d_item_image_ids.push_back(-1); updateRow(d_texts.size()-1,q); + if(!image_ids.contains(q->value(13).toInt())) { + image_ids.push_back(q->value(13).toInt()); + } } delete q; + + // + // Load item thumbnail images + // + d_item_images.clear(); + for(int i=0;ifirst()) { + d_item_images[image_ids.at(i)]= + QImage::fromData(q->value(0).toByteArray()). + scaled(32,32,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); + } + else { + d_item_images[image_ids.at(i)]= + rda->iconEngine()->applicationIcon(RDIconEngine::RdCastManager,32); + } + delete q; + } + endResetModel(); } @@ -357,6 +387,7 @@ void RDPodcastListModel::updateRowLine(int line) RDSqlQuery *q=new RDSqlQuery(sql); if(q->first()) { updateRow(line,q); + loadItemImage(q->value(13).toInt()); } delete q; } @@ -370,14 +401,9 @@ void RDPodcastListModel::updateRow(int row,RDSqlQuery *q) // Title texts.push_back(q->value(2)); - if(q->value(13).isNull()) { - icons.push_back(rda->iconEngine()-> - applicationIcon(RDIconEngine::RdCastManager,32)); - } - else { - icons.push_back(QImage::fromData(q->value(13).toByteArray()). - scaled(32,32,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); - } + + // Item Image ID + d_item_image_ids[row]=q->value(13).toInt(); // Status texts.push_back(QVariant()); @@ -448,7 +474,6 @@ void RDPodcastListModel::updateRow(int row,RDSqlQuery *q) d_cast_ids[row]=q->value(0).toUInt(); d_texts[row]=texts; - d_icons[row]=icons; } @@ -468,10 +493,43 @@ QString RDPodcastListModel::sqlFields() const "`PODCASTS`.`ORIGIN_STATION`,"+ // 10 "`PODCASTS`.`ORIGIN_DATETIME`,"+ // 11 "`PODCASTS`.`SHA1_HASH`,"+ // 12 - "`FEED_IMAGES`.`DATA` "+ // 13 + "`PODCASTS`.`ITEM_IMAGE_ID` "+ // 13 "from `PODCASTS` left join `FEEDS` "+ - "on `PODCASTS`.`FEED_ID`=`FEEDS`.`ID` left join `FEED_IMAGES` "+ - "on `PODCASTS`.`ITEM_IMAGE_ID`=`FEED_IMAGES`.`ID` "; + "on `PODCASTS`.`FEED_ID`=`FEEDS`.`ID` "; - return sql; + return sql; +} + + +void RDPodcastListModel::loadItemImage(int image_id) +{ + if(!d_item_images.contains(image_id)) { + QString sql=QString("select ")+ + "`DATA_MID_THUMB` "+ // 00 + "from `FEED_IMAGES` where "+ + QString::asprintf("`ID`=%d",image_id); + RDSqlQuery *q=new RDSqlQuery(sql); + if(q->first()) { + d_item_images[image_id]= + QImage::fromData(q->value(0).toByteArray()). + scaled(32,32,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); + } + else { + d_item_images[image_id]= + rda->iconEngine()->applicationIcon(RDIconEngine::RdCastManager,32); + } + delete q; + } +} + + +QString RDPodcastListModel::imageFP(const QByteArray &img) +{ + uint32_t sum=0; + + for(int i=0;i +// (C) Copyright 2021-2023 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 @@ -61,6 +61,8 @@ class RDPodcastListModel : public QAbstractTableModel void updateRowLine(int line); void updateRow(int row,RDSqlQuery *q); QString sqlFields() const; + void loadItemImage(int image_id); + QString imageFP(const QByteArray &img); private: QPalette d_palette; @@ -73,12 +75,13 @@ class RDPodcastListModel : public QAbstractTableModel QList d_alignments; QList d_cast_ids; QList > d_texts; - QList > d_icons; + QList d_item_image_ids; unsigned d_feed_id; QString d_filter_sql; QStringList d_column_fields; int d_sort_column; Qt::SortOrder d_sort_order; + QMap d_item_images; }; diff --git a/rdcastmanager/list_casts.cpp b/rdcastmanager/list_casts.cpp index 59d5f42d..eabab2bf 100644 --- a/rdcastmanager/list_casts.cpp +++ b/rdcastmanager/list_casts.cpp @@ -2,7 +2,7 @@ // // List Rivendell Casts // -// (C) Copyright 2002-2022 Fred Gleason +// (C) Copyright 2002-2023 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 @@ -56,7 +56,6 @@ ListCasts::ListCasts(unsigned feed_id,QWidget *parent) list_cut_dialog=new RDCutDialog(&cast_filter,&cast_group,&cast_schedcode, false,false,false,"RDCastManager",false,this); - list_progress_dialog= new QProgressDialog(tr("Uploading Audio..."),tr("Cancel"),0,1,this); list_progress_dialog->setValue(1); @@ -150,10 +149,7 @@ ListCasts::ListCasts(unsigned feed_id,QWidget *parent) list_close_button->setText(tr("Close")); connect(list_close_button,SIGNAL(clicked()),this,SLOT(closeData())); - // RefreshList(); - connect(rda->ripc(),SIGNAL(userChanged()),this,SLOT(userChangedData())); - modelResetData(); userChangedData(); }