File indexing completed on 2024-04-21 15:12:04

0001 /***************************************************************************
0002  *                                                                         *
0003  *  This file is part of Kooka, a KDE scanning/OCR application.            *
0004  *                                                                         *
0005  *  This file may be distributed and/or modified under the terms of the    *
0006  *  GNU General Public License version 2 as published by the Free Software *
0007  *  Foundation and appearing in the file COPYING included in the           *
0008  *  packaging of this file.                                                *
0009  *                                                                         *
0010  *  As a special exception, permission is given to link this program       *
0011  *  with any version of the KADMOS ocr/icr engine of reRecognition GmbH,   *
0012  *  Kreuzlingen and distribute the resulting executable without            *
0013  *  including the source code for KADMOS in the source distribution.       *
0014  *                                                                         *
0015  *  As a special exception, permission is given to link this program       *
0016  *  with any edition of Qt, and distribute the resulting executable,       *
0017  *  without including the source code for Qt in the source distribution.   *
0018  *                                                                         *
0019  *  Author:  Jonathan Marten <jjm AT keelhaul DOT me DOT uk>               *
0020  *                                                                         *
0021  ***************************************************************************/
0022 
0023 #include "kookascanparams.h"
0024 
0025 #include <qicon.h>
0026 #include <qcombobox.h>
0027 #include <qlabel.h>
0028 
0029 #include <kmessagewidget.h>
0030 #include <klocalizedstring.h>
0031 
0032 #include "abstractplugin.h"
0033 #include "abstractdestination.h"
0034 #include "pluginmanager.h"
0035 #include "scanparamspage.h"
0036 #include "kookasettings.h"
0037 #include "kooka_logging.h"
0038 
0039 
0040 #define ROWS_TO_RESERVE     5           // rows to reserve for plugin GUI
0041 
0042 
0043 KookaScanParams::KookaScanParams(QWidget *parent)
0044     : ScanParams(parent)
0045 {
0046     mNoScannerMessage = nullptr;
0047     mDestinationPlugin = nullptr;
0048 }
0049 
0050 
0051 static KMessageWidget *createErrorWidget(const QString &text)
0052 {
0053     KMessageWidget *msg = new KMessageWidget(text);
0054     msg->setMessageType(KMessageWidget::Error);
0055     msg->setIcon(QIcon::fromTheme("dialog-error"));
0056     msg->setWordWrap(true);
0057     msg->setCloseButtonVisible(false);
0058     return (msg);
0059 }
0060 
0061 
0062 QWidget *KookaScanParams::messageScannerNotSelected()
0063 {
0064     if (mNoScannerMessage==nullptr)
0065     {
0066         mNoScannerMessage = createErrorWidget(
0067             xi18nc("@info",
0068                    "<title>Gallery Mode - No scanner selected</title>"
0069                    "<nl/><nl/>"
0070                    "In this mode you can browse, manipulate and OCR images already in the gallery."
0071                    "<nl/><nl/>"
0072                    "<link url=\"a:1\">Select a scanner device</link> "
0073                    "to perform scanning, or "
0074                    "<link url=\"a:2\">add a device</link> "
0075                    "if a scanner is not automatically detected."));
0076 
0077         mNoScannerMessage->setMessageType(KMessageWidget::Information);
0078         mNoScannerMessage->setIcon(QIcon::fromTheme("dialog-information"));
0079         connect(mNoScannerMessage, &KMessageWidget::linkActivated, this, &KookaScanParams::slotLinkActivated);
0080     }
0081 
0082     return (mNoScannerMessage);
0083 }
0084 
0085 
0086 void KookaScanParams::slotLinkActivated(const QString &link)
0087 {
0088     if (link == QLatin1String("a:1")) {
0089         emit actionSelectScanner();
0090     } else if (link == QLatin1String("a:2")) {
0091         emit actionAddScanner();
0092     }
0093 }
0094 
0095 
0096 void KookaScanParams::createScanDestinationGUI(ScanParamsPage *frame)
0097 {
0098     const QMap<QString,AbstractPluginInfo> plugins = PluginManager::self()->allPlugins(PluginManager::DestinationPlugin);
0099     qCDebug(KOOKA_LOG) << "have" << plugins.count() << "destination plugins";
0100 
0101     const QString configuredPlugin = KookaSettings::destinationPlugin();
0102     int configuredIndex = -1;
0103 
0104     mDestinationCombo = new QComboBox(frame);
0105     for (QMap<QString,AbstractPluginInfo>::const_iterator it = plugins.constBegin(); it!=plugins.constEnd(); ++it)
0106     {
0107         const AbstractPluginInfo &info = it.value();
0108         if (info.key==configuredPlugin) configuredIndex = mDestinationCombo->count();
0109         mDestinationCombo->addItem(QIcon::fromTheme(info.icon), info.name, info.key);
0110     }
0111 
0112     if (configuredIndex!=-1) mDestinationCombo->setCurrentIndex(configuredIndex);
0113     connect(mDestinationCombo, QOverload<int>::of(&QComboBox::activated), this, &KookaScanParams::slotDestinationSelected);
0114     frame->addRow(i18n("Scan &destination:"), mDestinationCombo);
0115 
0116     mParamsPage = frame;
0117     mParamsRow = frame->currentRow();
0118 
0119     slotDestinationSelected(mDestinationCombo->currentIndex());
0120     frame->setCurrentRow(mParamsRow+ROWS_TO_RESERVE);
0121 }
0122 
0123 
0124 void KookaScanParams::slotDestinationSelected(int idx)
0125 {
0126     const QString destName = mDestinationCombo->itemData(idx).toString();
0127     qCDebug(KOOKA_LOG) << idx << destName;
0128 
0129     // Check the plugin that is currently loaded.  If it is the same as is
0130     // required then nothing needs to be done.
0131     AbstractDestination *currentPlugin = qobject_cast<AbstractDestination *>(PluginManager::self()->currentPlugin(PluginManager::DestinationPlugin));
0132     if (currentPlugin!=nullptr && currentPlugin->pluginInfo()->key==destName)
0133     {
0134         // But ensure that this is not the initialisation of scan parameters
0135         // for a new scanner, after the same plugin has previously been
0136         // loaded for the previous scanner.  In this case, the GUI setup
0137         // still needs to be done.
0138         if (mDestinationPlugin!=nullptr) return;
0139     }
0140 
0141     qCDebug(KOOKA_LOG) << "params at row" << mParamsRow;
0142     for (int i = ROWS_TO_RESERVE-1; i>=0; --i)      // clear any existing GUI rows,
0143     {                           // backwards to leave first row as current
0144         mParamsPage->setCurrentRow(mParamsRow+i);
0145         mParamsPage->clearRow();
0146     }
0147 
0148     if (destName.isEmpty())
0149     {
0150         mParamsPage->addRow(createErrorWidget(xi18nc("@info", "No destination selected")));
0151         return;
0152     }
0153 
0154     // Save the settings for the current plugin before it gets unloaded.
0155     if (currentPlugin!=nullptr) currentPlugin->saveSettings();
0156 
0157     mDestinationPlugin = qobject_cast<AbstractDestination *>(PluginManager::self()->loadPlugin(PluginManager::DestinationPlugin, destName));
0158     if (mDestinationPlugin==nullptr)
0159     {
0160         mParamsPage->addRow(createErrorWidget(xi18nc("@info", "Unable to load plugin '%1'", destName)));
0161         return;
0162     }
0163 
0164     mDestinationPlugin->setParentWidget(this);      // give it a widget for reference
0165     mDestinationPlugin->createGUI(mParamsPage);     // create the plugin's GUI
0166 }
0167 
0168 
0169 void KookaScanParams::saveDestinationSettings()
0170 {
0171     qCDebug(KOOKA_LOG);
0172 
0173     if (!hasScanDevice()) return;           // no scanner configured
0174 
0175     AbstractDestination *currentPlugin = qobject_cast<AbstractDestination *>(PluginManager::self()->currentPlugin(PluginManager::DestinationPlugin));
0176     if (currentPlugin==nullptr) return;         // nothing to save
0177 
0178     KookaSettings::setDestinationPlugin(currentPlugin->pluginInfo()->key);
0179     currentPlugin->saveSettings();
0180 
0181     KookaSettings::self()->save();
0182 }