/* * Cantata * * Copyright (c) 2011-2022 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "cachesettings.h" #include "context/artistview.h" #include "context/albumview.h" #include "context/songview.h" #include "context/contextwidget.h" #include "context/wikipediasettings.h" #include "covers.h" #include "support/utils.h" #include "support/messagebox.h" #include "config.h" #include "support/thread.h" #include "settings.h" #include "widgets/basicitemdelegate.h" #include "models/streamsmodel.h" #include "online/podcastsearchdialog.h" #include "support/squeezedtextlabel.h" #ifdef ENABLE_SCROBBLING #include "scrobbling/scrobbler.h" #endif #include #include #include #include #include #include #include #include static const int constMaxRecurseLevel=4; static void calculate(const QString &d, const QStringList &types, int &items, quint64 &space, int level=0) { if (!d.isEmpty() && levelstart(); } CacheItemCounter::~CacheItemCounter() { if (thread) { thread->stop(); } } void CacheItemCounter::getCount() { int items=0; quint64 space=0; calculate(dir, types, items, space); emit count(items, space); } void CacheItemCounter::deleteAll() { ::deleteAll(dir, types); getCount(); } CacheItem::CacheItem(const QString &title, const QString &d, const QStringList &t, QTreeWidget *p, Type ty) : QTreeWidgetItem(p, QStringList() << title) , counter(new CacheItemCounter(title, d, t)) , empty(true) , usedSpace(0) , type(ty) { connect(this, SIGNAL(getCount()), counter, SLOT(getCount()), Qt::QueuedConnection); connect(this, SIGNAL(deleteAll()), counter, SLOT(deleteAll()), Qt::QueuedConnection); connect(counter, SIGNAL(count(int, quint64)), this, SLOT(update(int, quint64)), Qt::QueuedConnection); connect(this, SIGNAL(updated()), p, SIGNAL(itemSelectionChanged())); } CacheItem::~CacheItem() { delete counter; } void CacheItem::update(int itemCount, quint64 space) { setText(1, QString::number(itemCount)); setText(2, Utils::formatByteSize(space)); empty=0==itemCount; usedSpace=space; setStatus(); emit updated(); } void CacheItem::setStatus(const QString &str) { QFont f(font(0)); if (!str.isEmpty()) { f.setItalic(true); setText(1, str); setText(2, str); } setFont(1, f); setFont(2, f); } void CacheItem::clean() { setStatus(tr("Deleting...")); emit deleteAll(); switch (type) { case Type_Covers: Covers::self()->clearNameCache(); break; case Type_ScaledCovers: Covers::self()->clearScaleCache(); break; default: break; } } void CacheItem::calculate() { setStatus(tr("Calculating...")); emit getCount(); } static inline void setResizeMode(QHeaderView *hdr, int idx, QHeaderView::ResizeMode mode) { hdr->setSectionResizeMode(idx, mode); } CacheTree::CacheTree(QWidget *parent) : QTreeWidget(parent) , calculated(false) { setHeaderLabels(QStringList() << tr("Name") << tr("Item Count") << tr("Space Used")); setAllColumnsShowFocus(true); setSelectionMode(QAbstractItemView::ExtendedSelection); setRootIsDecorated(false); setSortingEnabled(false); //setSortingEnabled(true); //sortByColumn(0, Qt::AscendingOrder); setResizeMode(header(), 0, QHeaderView::Stretch); setResizeMode(header(), 1, QHeaderView::Stretch); setResizeMode(header(), 2, QHeaderView::Stretch); header()->setStretchLastSection(true); setAlternatingRowColors(false); setItemDelegate(new BasicItemDelegate(this)); } CacheTree::~CacheTree() { } void CacheTree::showEvent(QShowEvent *e) { if (!calculated) { for (int i=0; i(topLevelItem(i))->calculate(); } calculated=true; } QTreeWidget::showEvent(e); } SpaceLabel::SpaceLabel(QWidget *p) : SqueezedTextLabel(p) { QFont f=font(); f.setItalic(true); setFont(f); update(tr("Calculating...")); } void SpaceLabel::update(int space) { update(Utils::formatByteSize(space)); } void SpaceLabel::update(const QString &text) { setText(tr("Total space used: %1").arg(text)); } CacheSettings::CacheSettings(QWidget *parent) : QWidget(parent) { int spacing=Utils::layoutSpacing(this); QGridLayout *layout=new QGridLayout(this); layout->setMargin(0); int row=0; int col=0; QLabel *label=new QLabel(tr("Cantata caches various pieces of information (covers, lyrics, etc). Below is a summary of Cantata's " "current cache usage."), this); QFont f(Utils::smallFont(label->font())); f.setItalic(true); label->setFont(f); label->setWordWrap(true); layout->addWidget(label, row++, col, 1, 2); layout->addItem(new QSpacerItem(spacing, spacing, QSizePolicy::Fixed, QSizePolicy::Fixed), row++, 0); tree=new CacheTree(this); layout->addWidget(tree, row++, col, 1, 2); new CacheItem(tr("Covers"), Utils::cacheDir(Covers::constCoverDir, false), QStringList() << "*.jpg" << "*.png", tree, CacheItem::Type_Covers); new CacheItem(tr("Scaled Covers"), Utils::cacheDir(Covers::constScaledCoverDir, false), QStringList() << "*.jpg" << "*.png", tree, CacheItem::Type_ScaledCovers); new CacheItem(tr("Backdrops"), Utils::cacheDir(ContextWidget::constCacheDir, false), QStringList() << "*.jpg" << "*.png", tree); new CacheItem(tr("Lyrics"), Utils::cacheDir(SongView::constLyricsDir, false), QStringList() << "*"+SongView::constExtension, tree); new CacheItem(tr("Artist Information"), Utils::cacheDir(ArtistView::constCacheDir, false), QStringList() << "*"+ArtistView::constInfoExt << "*"+ArtistView::constSimilarInfoExt << "*.json.gz" << "*.jpg" << "*.png", tree); new CacheItem(tr("Album Information"), Utils::cacheDir(AlbumView::constCacheDir, false), QStringList() << "*"+AlbumView::constInfoExt << "*.jpg" << "*.png", tree); new CacheItem(tr("Track Information"), Utils::cacheDir(SongView::constCacheDir, false), QStringList() << "*"+AlbumView::constInfoExt, tree); new CacheItem(tr("Stream Listings"), Utils::cacheDir(StreamsModel::constSubDir, false), QStringList() << "*"+StreamsModel::constCacheExt, tree); new CacheItem(tr("Podcast Directories"), Utils::cacheDir(PodcastSearchDialog::constCacheDir, false), QStringList() << "*"+PodcastSearchDialog::constExt, tree); new CacheItem(tr("Wikipedia Languages"), Utils::cacheDir(WikipediaSettings::constSubDir, false), QStringList() << "*.xml.gz", tree); #ifdef ENABLE_SCROBBLING new CacheItem(tr("Scrobble Tracks"), Utils::cacheDir(Scrobbler::constCacheDir, false), QStringList() << "*.xml.gz", tree); #endif for (int i=0; itopLevelItemCount(); ++i) { connect(static_cast(tree->topLevelItem(i)), SIGNAL(updated()), this, SLOT(updateSpace())); } spaceLabel=new SpaceLabel(this); button=new QPushButton(tr("Delete All"), this); layout->addWidget(spaceLabel, row, 0, 1, 1); layout->addWidget(button, row++, 1, 1, 1); button->setEnabled(false); connect(tree, SIGNAL(itemSelectionChanged()), this, SLOT(controlButton())); connect(button, SIGNAL(clicked()), this, SLOT(deleteAll())); } CacheSettings::~CacheSettings() { } void CacheSettings::controlButton() { button->setEnabled(false); for (int i=0; itopLevelItemCount(); ++i) { CacheItem *item=static_cast(tree->topLevelItem(i)); if (item->isSelected() && !item->isEmpty()) { button->setEnabled(true); break; } } } void CacheSettings::deleteAll() { QList toDelete; for (int i=0; itopLevelItemCount(); ++i) { CacheItem *item=static_cast(tree->topLevelItem(i)); if (item->isSelected() && !item->isEmpty()) { toDelete.append(item); } } if (!toDelete.isEmpty()) { if (1==toDelete.count()) { if (MessageBox::Yes==MessageBox::warningYesNo(this, tr("Delete all '%1' items?").arg(toDelete.at(0)->name()), tr("Delete Cache Items"), StdGuiItem::del(), StdGuiItem::cancel())) { toDelete.first()->clean(); } } else if (toDelete.count()>1) { static const QChar constBullet(0x2022); QString items; for (CacheItem *i: toDelete) { items+=constBullet+QLatin1Char(' ')+i->name()+QLatin1Char('\n'); } if (MessageBox::No==MessageBox::warningYesNo(this, tr("Delete items from all selected categories?")+QLatin1String("\n\n")+items, tr("Delete Cache Items"), StdGuiItem::del(), StdGuiItem::cancel())) { return; } for (CacheItem *i: toDelete) { i->clean(); } } } } void CacheSettings::updateSpace() { quint64 space=0; for (int i=0; itopLevelItemCount(); ++i) { space+=static_cast(tree->topLevelItem(i))->spaceUsed(); } spaceLabel->update(space); } #include "moc_cachesettings.cpp"