File indexing completed on 2023-10-01 05:54:50
0001 /*************************************************************************** 0002 * Copyright (C) 2009-2010 by Daniel Nicoletti * 0003 * dantti12@gmail.com * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; see the file COPYING. If not, write to * 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0018 * Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 0021 #include "BrowseView.h" 0022 0023 #include "PackageDetails.h" 0024 #include "CategoryModel.h" 0025 0026 #include <ApplicationsDelegate.h> 0027 #include <ApplicationSortFilterModel.h> 0028 #include <PackageModel.h> 0029 0030 #include <Daemon> 0031 0032 #include <QFileDialog> 0033 #include <KPixmapSequence> 0034 #include <QMenu> 0035 #include <KIconLoader> 0036 #include <KConfig> 0037 #include <KConfigGroup> 0038 #include <KLocalizedString> 0039 0040 #include <QDBusConnection> 0041 #include <QDBusMessage> 0042 #include <QAbstractItemView> 0043 #include <QScrollBar> 0044 0045 #include <QLoggingCategory> 0046 0047 using namespace PackageKit; 0048 0049 BrowseView::BrowseView(QWidget *parent) 0050 : QWidget(parent) 0051 { 0052 setupUi(this); 0053 connect(categoryView, &QListView::clicked, this, &BrowseView::categoryActivated); 0054 0055 m_busySeq = new KPixmapSequenceOverlayPainter(this); 0056 m_busySeq->setSequence(KIconLoader::global()->loadPixmapSequence(QLatin1String("process-working"), KIconLoader::SizeSmallMedium)); 0057 m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 0058 m_busySeq->setWidget(packageView->viewport()); 0059 0060 m_model = new PackageModel(this); 0061 m_proxy = new ApplicationSortFilterModel(this); 0062 m_proxy->setSourceModel(m_model); 0063 0064 packageView->setModel(m_proxy); 0065 packageView->sortByColumn(PackageModel::NameCol, Qt::AscendingOrder); 0066 packageView->header()->setDefaultAlignment(Qt::AlignCenter); 0067 packageView->header()->setStretchLastSection(false); 0068 packageView->header()->setSectionResizeMode(PackageModel::NameCol, QHeaderView::Stretch); 0069 packageView->header()->setSectionResizeMode(PackageModel::VersionCol, QHeaderView::ResizeToContents); 0070 packageView->header()->setSectionResizeMode(PackageModel::ArchCol, QHeaderView::ResizeToContents); 0071 packageView->header()->setSectionResizeMode(PackageModel::OriginCol, QHeaderView::ResizeToContents); 0072 packageView->header()->setSectionResizeMode(PackageModel::SizeCol, QHeaderView::ResizeToContents); 0073 packageView->header()->setSectionResizeMode(PackageModel::ActionCol, QHeaderView::ResizeToContents); 0074 0075 // Hide current Version since it's useless for us 0076 packageView->header()->setSectionHidden(PackageModel::CurrentVersionCol, true); 0077 0078 ApplicationsDelegate *delegate = new ApplicationsDelegate(packageView); 0079 packageView->setItemDelegate(delegate); 0080 0081 exportInstalledPB->setIcon(QIcon::fromTheme(QLatin1String("document-export"))); 0082 importInstalledPB->setIcon(QIcon::fromTheme(QLatin1String("document-import"))); 0083 0084 KConfig config(QLatin1String("apper")); 0085 KConfigGroup viewGroup(&config, "BrowseView"); 0086 0087 // Version 0088 packageView->header()->setSectionHidden(PackageModel::VersionCol, true); 0089 m_showPackageVersion = new QAction(i18n("Show Versions"), this); 0090 m_showPackageVersion->setCheckable(true); 0091 connect(m_showPackageVersion, &QAction::toggled, this, &BrowseView::showVersions); 0092 m_showPackageVersion->setChecked(viewGroup.readEntry("ShowApplicationVersions", true)); 0093 0094 // Arch 0095 packageView->header()->setSectionHidden(PackageModel::ArchCol, true); 0096 m_showPackageArch = new QAction(i18n("Show Architectures"), this); 0097 m_showPackageArch->setCheckable(true); 0098 connect(m_showPackageArch, &QAction::toggled, this, &BrowseView::showArchs); 0099 m_showPackageArch->setChecked(viewGroup.readEntry("ShowApplicationArchitectures", false)); 0100 0101 // Origin 0102 packageView->header()->setSectionHidden(PackageModel::OriginCol, true); 0103 m_showPackageOrigin = new QAction(i18n("Show Origins"), this); 0104 m_showPackageOrigin->setCheckable(true); 0105 connect(m_showPackageOrigin, &QAction::toggled, this, &BrowseView::showOrigins); 0106 m_showPackageOrigin->setChecked(viewGroup.readEntry("ShowApplicationOrigins", false)); 0107 0108 // Sizes 0109 packageView->header()->setSectionHidden(PackageModel::SizeCol, true); 0110 m_showPackageSizes = new QAction(i18n("Show Sizes"), this); 0111 m_showPackageSizes->setCheckable(true); 0112 connect(m_showPackageSizes, &QAction::toggled, this, &BrowseView::showSizes); 0113 m_showPackageSizes->setChecked(viewGroup.readEntry("ShowPackageSizes", false)); 0114 0115 0116 // Ensure the index is visible when the packageDetails appears 0117 connect(packageDetails, &PackageDetails::ensureVisible, this, &BrowseView::ensureVisible); 0118 } 0119 0120 void BrowseView::init(Transaction::Roles roles) 0121 { 0122 packageDetails->init(roles); 0123 } 0124 0125 BrowseView::~BrowseView() 0126 { 0127 } 0128 0129 bool BrowseView::showPageHeader() const 0130 { 0131 return false; 0132 } 0133 0134 PackageModel* BrowseView::model() const 0135 { 0136 return m_model; 0137 } 0138 0139 void BrowseView::showVersions(bool enabled) 0140 { 0141 KConfig config(QLatin1String("apper")); 0142 KConfigGroup viewGroup(&config, "BrowseView"); 0143 viewGroup.writeEntry("ShowApplicationVersions", enabled); 0144 packageView->header()->setSectionHidden(PackageModel::VersionCol, !enabled); 0145 packageDetails->hidePackageVersion(enabled); 0146 } 0147 0148 void BrowseView::showArchs(bool enabled) 0149 { 0150 KConfig config(QLatin1String("apper")); 0151 KConfigGroup viewGroup(&config, "BrowseView"); 0152 viewGroup.writeEntry("ShowApplicationArchitectures", enabled); 0153 packageView->header()->setSectionHidden(PackageModel::ArchCol, !enabled); 0154 packageDetails->hidePackageArch(enabled); 0155 } 0156 0157 void BrowseView::showOrigins(bool enabled) 0158 { 0159 KConfig config(QLatin1String("apper")); 0160 KConfigGroup viewGroup(&config, "BrowseView"); 0161 viewGroup.writeEntry("ShowApplicationOrigins", enabled); 0162 packageView->header()->setSectionHidden(PackageModel::OriginCol, !enabled); 0163 } 0164 0165 void BrowseView::showSizes(bool enabled) 0166 { 0167 KConfig config(QLatin1String("apper")); 0168 KConfigGroup viewGroup(&config, "BrowseView"); 0169 viewGroup.writeEntry("ShowPackageSizes", enabled); 0170 packageView->header()->setSectionHidden(PackageModel::SizeCol, !enabled); 0171 packageDetails->hidePackageArch(enabled); 0172 if (enabled) { 0173 m_model->fetchSizes(); 0174 } 0175 } 0176 0177 void BrowseView::on_packageView_customContextMenuRequested(const QPoint &pos) 0178 { 0179 auto menu = new QMenu(this); 0180 menu->addAction(m_showPackageVersion); 0181 menu->addAction(m_showPackageArch); 0182 menu->addAction(m_showPackageOrigin); 0183 menu->addAction(m_showPackageSizes); 0184 menu->exec(packageView->viewport()->mapToGlobal(pos)); 0185 menu->deleteLater(); 0186 } 0187 0188 void BrowseView::on_packageView_clicked(const QModelIndex &index) 0189 { 0190 if (index.column() == PackageModel::ActionCol) { 0191 return; 0192 } 0193 0194 QModelIndex origIndex = m_proxy->mapToSource(index); 0195 packageDetails->setPackage(origIndex); 0196 } 0197 0198 void BrowseView::ensureVisible(const QModelIndex &index) 0199 { 0200 QModelIndex proxIndex = m_proxy->mapFromSource(index); 0201 packageView->scrollTo(proxIndex); 0202 } 0203 0204 void BrowseView::showInstalledPanel(bool visible) 0205 { 0206 installedF->setVisible(visible); 0207 } 0208 0209 ApplicationSortFilterModel* BrowseView::proxy() const 0210 { 0211 return m_proxy; 0212 } 0213 0214 KPixmapSequenceOverlayPainter* BrowseView::busyCursor() const 0215 { 0216 return m_busySeq; 0217 } 0218 0219 void BrowseView::setCategoryModel(QAbstractItemModel *model) 0220 { 0221 categoryView->setModel(model); 0222 } 0223 0224 void BrowseView::setParentCategory(const QModelIndex &index) 0225 { 0226 categoryView->setRootIndex(index); 0227 // Make sure the last item is not selected 0228 categoryView->selectionModel()->clearSelection(); 0229 categoryView->horizontalScrollBar()->setValue(0); 0230 0231 // Display the category view if the index has child items 0232 categoryF->setVisible(categoryView->model()->rowCount(index)); 0233 } 0234 0235 bool BrowseView::goBack() 0236 { 0237 packageDetails->hide(); 0238 QModelIndex index = categoryView->rootIndex(); 0239 if (index.parent().isValid()) { 0240 index = index.parent(); 0241 // if it's valid we need to know if it wasn't a PK root category 0242 if (index.data(CategoryModel::GroupRole).type() == QVariant::String) { 0243 QString category = index.data(CategoryModel::GroupRole).toString(); 0244 if (!category.startsWith(QLatin1Char('@'))) { 0245 return true; 0246 } 0247 } 0248 setParentCategory(index); 0249 emit categoryActivated(index); 0250 return false; 0251 } 0252 return true; 0253 } 0254 0255 void BrowseView::on_categoryMvLeft_clicked() 0256 { 0257 categoryView->horizontalScrollBar()->setValue(categoryView->horizontalScrollBar()->value() - 1); 0258 } 0259 0260 void BrowseView::on_categoryMvRight_clicked() 0261 { 0262 categoryView->horizontalScrollBar()->setValue(categoryView->horizontalScrollBar()->value() + 1); 0263 } 0264 0265 void BrowseView::cleanUi() 0266 { 0267 packageDetails->hide(); 0268 categoryF->setVisible(false); 0269 } 0270 0271 bool BrowseView::isShowingSizes() const 0272 { 0273 return m_showPackageSizes->isChecked(); 0274 } 0275 0276 void BrowseView::on_exportInstalledPB_clicked() 0277 { 0278 // We will assume the installed model 0279 // is populated since the user is seeing it. 0280 QString fileName; 0281 fileName = QFileDialog::getSaveFileName(this, 0282 i18n("Export installed packages"), 0283 QString(), 0284 QStringLiteral("*.catalog")); 0285 if (fileName.isEmpty()) { 0286 return; 0287 } 0288 0289 QFile file(fileName); 0290 file.open(QIODevice::WriteOnly); 0291 QTextStream out(&file); 0292 out << "[PackageKit Catalog]\n\n"; 0293 out << "InstallPackages(" << Daemon::global()->distroID() << ")="; 0294 QStringList packages; 0295 for (int i = 0; i < m_model->rowCount(); i++) { 0296 packages << m_model->data(m_model->index(i, 0), 0297 PackageModel::PackageName).toString(); 0298 } 0299 out << packages.join(QLatin1Char(';')); 0300 } 0301 0302 void BrowseView::on_importInstalledPB_clicked() 0303 { 0304 QString fileName; 0305 fileName = QFileDialog::getOpenFileName(this, 0306 i18n("Install packages from catalog"), 0307 QString(), 0308 QStringLiteral("*.catalog")); 0309 if (fileName.isEmpty()) { 0310 return; 0311 } 0312 0313 // send a DBus message to install this catalog 0314 QDBusMessage message; 0315 message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.PackageKit"), 0316 QLatin1String("/org/freedesktop/PackageKit"), 0317 QLatin1String("org.freedesktop.PackageKit.Modify"), 0318 QLatin1String("InstallCatalogs")); 0319 message << static_cast<uint>(effectiveWinId()); 0320 message << (QStringList() << fileName); 0321 message << QString(); 0322 0323 // This call must block otherwise this application closes before 0324 // smarticon is activated 0325 QDBusMessage reply = QDBusConnection::sessionBus().call(message, QDBus::Block); 0326 } 0327 0328 void BrowseView::disableExportInstalledPB() 0329 { 0330 exportInstalledPB->setEnabled(false); 0331 } 0332 0333 void BrowseView::enableExportInstalledPB() 0334 { 0335 exportInstalledPB->setEnabled(true); 0336 } 0337 0338 #include "moc_BrowseView.cpp"