File indexing completed on 2025-04-27 03:58:22

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2012-01-05
0007  * Description : a widget to find missing binaries.
0008  *
0009  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2012-2016 by Benjamin Girault <benjamin dot girault at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "dbinarysearch.h"
0017 
0018 // Qt includes
0019 
0020 #include <QLabel>
0021 #include <QHeaderView>
0022 
0023 // KDE includes
0024 
0025 #include <klocalizedstring.h>
0026 
0027 // Local includes
0028 
0029 #include "digikam_debug.h"
0030 
0031 namespace Digikam
0032 {
0033 
0034 class Q_DECL_HIDDEN DBinarySearch::Private
0035 {
0036 public:
0037 
0038     explicit Private()
0039       : downloadLabel(nullptr)
0040     {
0041     }
0042 
0043     QVector<DBinaryIface*>    binaryIfaces;
0044     QVector<QTreeWidgetItem*> items;
0045     QLabel*                   downloadLabel;
0046 };
0047 
0048 DBinarySearch::DBinarySearch(QWidget* const parent)
0049     : QTreeWidget(parent),
0050       d          (new Private)
0051 {
0052     setIconSize(QSize(16, 16));
0053     setAlternatingRowColors(true);
0054     setSelectionMode(QAbstractItemView::NoSelection);
0055     setSortingEnabled(false);
0056     setRootIsDecorated(false);
0057     setUniformRowHeights(true);
0058     setAllColumnsShowFocus(true);
0059     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0060     setColumnCount(5);
0061     setHeaderLabels(QStringList() << QLatin1String("")
0062                                   << i18nc("@title: binary properties", "Binary")
0063                                   << i18nc("@title: binary properties", "Version")
0064                                   << QLatin1String("")
0065                                   << QLatin1String(""));
0066 
0067     header()->setSectionResizeMode(Status,    QHeaderView::ResizeToContents);
0068     header()->setSectionResizeMode(Binary,    QHeaderView::Stretch);
0069     header()->setSectionResizeMode(Version,   QHeaderView::Stretch);
0070     header()->setSectionResizeMode(Button,    QHeaderView::Stretch);
0071     header()->setSectionResizeMode(Link,      QHeaderView::Stretch);
0072 
0073     d->downloadLabel = new QLabel(parentWidget());
0074 
0075     QGridLayout* const layout = qobject_cast<QGridLayout*>(parentWidget()->layout());
0076 
0077     if (layout)
0078     {
0079         layout->addWidget(this, 0, 0);
0080     }
0081 }
0082 
0083 DBinarySearch::~DBinarySearch()
0084 {
0085     delete d;
0086 }
0087 
0088 void DBinarySearch::addBinary(DBinaryIface& binary)
0089 {
0090     delete d->downloadLabel;
0091 
0092     binary.recheckDirectories();
0093 
0094     d->binaryIfaces.append(&binary);
0095     d->items.append(new QTreeWidgetItem());
0096     QTreeWidgetItem* const item   = d->items[d->items.size() - 1];
0097     item->setIcon(Status,       QIcon::fromTheme(QLatin1String("dialog-cancel")).pixmap(16, 16));
0098     item->setText(Binary,       binary.baseName());
0099     item->setText(Version,      binary.version());
0100     item->setToolTip(Binary,    binary.description());
0101     item->setToolTip(Status,    i18n("Binary not found."));
0102     item->setToolTip(Version,   i18n("Minimal version number required for this binary is %1", binary.minimalVersion()));
0103     insertTopLevelItem(d->binaryIfaces.size() - 1, item);
0104     QPushButton* const findButton = new QPushButton(i18n("Find"));
0105     setItemWidget(item, Button, findButton);
0106     QLabel* const downloadLabel   = new QLabel(i18n(" or <a href=\"%1\">download</a>", binary.url().url()));
0107     downloadLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse);
0108     downloadLabel->setOpenExternalLinks(true);
0109     setItemWidget(item, Link, downloadLabel);
0110 
0111     // Starts a dialog to find the binary
0112 
0113     connect(findButton, SIGNAL(clicked(bool)),
0114             &binary, SLOT(slotNavigateAndCheck()));
0115 
0116     // Rechecks full validity when a binary is found and valid
0117 
0118     connect(&binary, SIGNAL(signalBinaryValid()),
0119             this, SLOT(slotAreBinariesFound()));
0120 
0121     // Scans (if no binary were found) a new directory where a binary was found
0122 
0123     connect(&binary, SIGNAL(signalSearchDirectoryAdded(QString)),
0124             this, SIGNAL(signalAddPossibleDirectory(QString)));
0125 
0126     connect(this, SIGNAL(signalAddPossibleDirectory(QString)),
0127             &binary, SLOT(slotAddPossibleSearchDirectory(QString)));
0128 
0129     // Force scan of a new directory
0130 
0131     connect(this, SIGNAL(signalAddDirectory(QString)),
0132             &binary, SLOT(slotAddSearchDirectory(QString)));
0133 
0134     d->downloadLabel = new QLabel(i18n(
0135         "<qt><p><font color=\"red\"><b>Warning:</b> Some necessary binaries have not been found on "
0136         "your system. If you have these binaries installed, please click the 'Find' button to locate them on your "
0137         "system, otherwise please download and install them to proceed.</font></p></qt>"), parentWidget());
0138 
0139     QGridLayout* const layout = qobject_cast<QGridLayout*>(parentWidget()->layout());
0140 
0141     if (layout)
0142     {
0143         layout->addWidget(d->downloadLabel, layout->rowCount(), 0);
0144     }
0145 
0146     d->downloadLabel->setContentsMargins(20, 20, 20, 20);
0147     d->downloadLabel->setWordWrap(true);
0148     d->downloadLabel->hide();
0149 }
0150 
0151 void DBinarySearch::addDirectory(const QString& dir)
0152 {
0153     Q_EMIT signalAddPossibleDirectory(dir);
0154 }
0155 
0156 bool DBinarySearch::allBinariesFound()
0157 {
0158     bool ret = true;
0159 
0160     Q_FOREACH (DBinaryIface* const binary, d->binaryIfaces)
0161     {
0162         int index = d->binaryIfaces.indexOf(binary);
0163 
0164         if (binary->isValid())
0165         {
0166             if (!binary->developmentVersion())
0167             {
0168                 d->items[index]->setIcon(Status, QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(16, 16));
0169                 d->items[index]->setToolTip(Status, QString());
0170             }
0171             else
0172             {
0173                 d->items[index]->setIcon(Status, QIcon::fromTheme(QLatin1String("dialog-warning")).pixmap(16, 16));
0174                 d->items[index]->setToolTip(Status, i18n("A development version has been detect. "
0175                                                          "There is no guarantee on the behavior of this binary."));
0176                 d->downloadLabel->show();
0177             }
0178 
0179             d->items[index]->setText(Version, binary->version());
0180             QPushButton* const btn = qobject_cast<QPushButton*>(itemWidget(d->items[index], Button));
0181 
0182             if (btn)
0183             {
0184                 btn->setText(i18n("Change"));
0185             }
0186         }
0187         else if (binary->hasError())
0188         {
0189             d->items[index]->setIcon(Status, QIcon::fromTheme(QLatin1String("data-error")).pixmap(16, 16));
0190             d->items[index]->setToolTip(Status, i18n("The binary file found does not appear to be "
0191                                                      "working as intended."));
0192 
0193             ret = false;
0194         }
0195         else
0196         {
0197             ret = false;
0198         }
0199     }
0200 
0201     if (ret)
0202     {
0203         d->downloadLabel->hide();
0204     }
0205 
0206     return ret;
0207 }
0208 
0209 void DBinarySearch::slotAreBinariesFound()
0210 {
0211     bool allFound = allBinariesFound();
0212     Q_EMIT signalBinariesFound(allFound);
0213     qCDebug(DIGIKAM_GENERAL_LOG) << "All Binaries Found : " << allFound;
0214 }
0215 
0216 } // namespace Digikam
0217 
0218 #include "moc_dbinarysearch.cpp"