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

0001 /************************************************************************
0002  *                                  *
0003  *  This file is part of Kooka, a scanning/OCR application using    *
0004  *  Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>.  *
0005  *                                  *
0006  *  Copyright (C) 2000-2016 Klaas Freitag <freitag@suse.de>     *
0007  *                          Jonathan Marten <jjm@keelhaul.me.uk>    *
0008  *                                  *
0009  *  Kooka is free software; you can redistribute it and/or modify it    *
0010  *  under the terms of the GNU Library General Public License as    *
0011  *  published by the Free Software Foundation and appearing in the  *
0012  *  file COPYING included in the packaging of this file;  either    *
0013  *  version 2 of the License, or (at your option) any later version.    *
0014  *                                  *
0015  *  As a special exception, permission is given to link this program    *
0016  *  with any version of the KADMOS OCR/ICR engine (a product of     *
0017  *  reRecognition GmbH, Kreuzlingen), and distribute the resulting  *
0018  *  executable without including the source code for KADMOS in the  *
0019  *  source distribution.                        *
0020  *                                  *
0021  *  This program is distributed in the hope that it will be useful, *
0022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *
0023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *
0024  *  GNU General Public License for more details.            *
0025  *                                  *
0026  *  You should have received a copy of the GNU General Public       *
0027  *  License along with this program;  see the file COPYING.  If     *
0028  *  not, see <http://www.gnu.org/licenses/>.                *
0029  *                                  *
0030  ************************************************************************/
0031 
0032 #include "deviceselector.h"
0033 
0034 #include <qcheckbox.h>
0035 #include <qlayout.h>
0036 #include <qlabel.h>
0037 #include <qlistwidget.h>
0038 #include <qstandardpaths.h>
0039 
0040 #include <klocalizedstring.h>
0041 #include <kguiitem.h>
0042 #include <kiconloader.h>
0043 
0044 #include "scanglobal.h"
0045 #include "scandevices.h"
0046 #include "scansettings.h"
0047 #include "libkookascan_logging.h"
0048 
0049 
0050 DeviceSelector::DeviceSelector(QWidget *pnt,
0051                                const QList<QByteArray> &backends,
0052                                const KGuiItem &cancelGuiItem)
0053     : DialogBase(pnt)
0054 {
0055     setObjectName("DeviceSelector");
0056 
0057     setButtons(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0058     setButtonText(QDialogButtonBox::Ok, i18n("Select"));
0059     setWindowTitle(i18n("Select Scan Device"));
0060     if (!cancelGuiItem.text().isEmpty()) {      // special GUI item provided
0061         setButtonGuiItem(QDialogButtonBox::Cancel, cancelGuiItem);
0062     }
0063 
0064     // Layout-Boxes
0065     QWidget *vb = new QWidget(this);
0066     vb->setMinimumSize(QSize(450, 180));
0067     setMainWidget(vb);
0068 
0069     QVBoxLayout *vlay = new QVBoxLayout(vb);
0070 
0071     QLabel *l = new QLabel(i18n("Available Scanners:"), vb);
0072     vlay->addWidget(l);
0073 
0074     mListBox = new QListWidget(vb);
0075     mListBox->setSelectionMode(QAbstractItemView::SingleSelection);
0076     mListBox->setUniformItemSizes(true);
0077     vlay->addWidget(mListBox, 1);
0078     l->setBuddy(mListBox);
0079 
0080     vlay->addSpacing(verticalSpacing());
0081 
0082     mSkipCheckbox = new QCheckBox(i18n("Always use this device at startup"), vb);
0083     vlay->addWidget(mSkipCheckbox);
0084 
0085     bool skipDialog = ScanSettings::startupSkipAsk();
0086     mSkipCheckbox->setChecked(skipDialog);
0087 
0088 
0089     setScanSources(backends);
0090 }
0091 
0092 DeviceSelector::~DeviceSelector()
0093 {
0094 }
0095 
0096 QByteArray DeviceSelector::getDeviceFromConfig() const
0097 {
0098     QByteArray result = ScanSettings::startupScanDevice().toLocal8Bit();
0099     qCDebug(LIBKOOKASCAN_LOG) << "Scanner from config" << result;
0100 
0101     bool skipDialog = ScanSettings::startupSkipAsk();
0102     if (skipDialog && !result.isEmpty() && mDeviceList.contains(result)) {
0103         qCDebug(LIBKOOKASCAN_LOG) << "Using scanner from config";
0104     } else {
0105         qCDebug(LIBKOOKASCAN_LOG) << "Not using scanner from config";
0106         result = "";
0107     }
0108 
0109     return (result);
0110 }
0111 
0112 bool DeviceSelector::getShouldSkip() const
0113 {
0114     return (mSkipCheckbox->isChecked());
0115 }
0116 
0117 QByteArray DeviceSelector::getSelectedDevice() const
0118 {
0119     const QList<QListWidgetItem *> selItems = mListBox->selectedItems();
0120     if (selItems.count() < 1) {
0121         return ("");
0122     }
0123 
0124     int selIndex = mListBox->row(selItems.first()); // of selected item
0125     int dcount = mDeviceList.count();
0126     //qCDebug(LIBKOOKASCAN_LOG) << "selected index" << selIndex << "of" << dcount;
0127     if (selIndex < 0 || selIndex >= dcount) {
0128         return ("");    // can never happen?
0129     }
0130 
0131     QByteArray dev = mDeviceList.at(selIndex).toLocal8Bit();
0132     qCDebug(LIBKOOKASCAN_LOG) << "selected device" << dev;
0133 
0134     // Save both the scan device and the skip-start-dialog flag
0135     // in the global "scannerrc" file.
0136     ScanSettings::setStartupScanDevice(dev);
0137     ScanSettings::setStartupSkipAsk(getShouldSkip());
0138     ScanSettings::self()->save();
0139    
0140     return (dev);
0141 }
0142 
0143 void DeviceSelector::setScanSources(const QList<QByteArray> &backends)
0144 {
0145     const KConfig *typeConf = nullptr;
0146 
0147     QString typeFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "libkookascan/scantypes.dat");
0148     qCDebug(LIBKOOKASCAN_LOG) << "Scanner type file" << typeFile;
0149     if (!typeFile.isEmpty()) {
0150         typeConf = new KConfig(typeFile, KConfig::SimpleConfig);
0151     }
0152 
0153     QByteArray defstr = ScanSettings::startupScanDevice().toLocal8Bit();
0154     QListWidgetItem *defItem = nullptr;
0155 
0156     for (QList<QByteArray>::const_iterator it = backends.constBegin();
0157             it != backends.constEnd(); ++it) {
0158         QByteArray devName = (*it);
0159         const SANE_Device *dev = ScanDevices::self()->deviceInfo(devName);
0160         if (dev == nullptr) {
0161             qCDebug(LIBKOOKASCAN_LOG) << "no device info for" << devName;
0162             continue;
0163         }
0164 
0165         mDeviceList.append(devName);
0166 
0167         QListWidgetItem *item = new QListWidgetItem();
0168 
0169         QWidget *hbox = new QWidget(this);
0170         QHBoxLayout *hlay = new QHBoxLayout(hbox);
0171         hlay->setMargin(0);
0172 
0173         hlay->setSpacing(horizontalSpacing());
0174 
0175         QString itemIcon = "scanner";
0176         if (typeConf != nullptr) {         // type config file available
0177             QString devBase = QString(devName).section(':', 0, 0);
0178             QString ii = typeConf->group("Devices").readEntry(devBase, "");
0179             qCDebug(LIBKOOKASCAN_LOG) << "for device" << devBase << "icon" << ii;
0180             if (!ii.isEmpty()) {
0181                 itemIcon = ii;
0182             } else {
0183                 ii = typeConf->group("Types").readEntry(dev->type, "");
0184                 qCDebug(LIBKOOKASCAN_LOG) << "for type" << dev->type << "icon" << ii;
0185                 if (!ii.isEmpty()) {
0186                     itemIcon = ii;
0187                 }
0188             }
0189         }
0190 
0191         QLabel *label = new QLabel(hbox);
0192         label->setPixmap(KIconLoader::global()->loadIcon(itemIcon,
0193                          KIconLoader::NoGroup,
0194                          KIconLoader::SizeMedium));
0195         hlay->addSpacing(horizontalSpacing());
0196         hlay->addWidget(label);
0197 
0198         label = new QLabel(QString::fromLatin1("<qt><b>%1</b><br>%2")
0199                            .arg(ScanDevices::self()->deviceDescription(devName))
0200                            .arg(devName.constData()), hbox);
0201         label->setTextInteractionFlags(Qt::NoTextInteraction);
0202         hlay->addSpacing(horizontalSpacing());
0203         hlay->addWidget(label);
0204 
0205         hlay->addStretch(1);
0206 
0207         mListBox->addItem(item);
0208         mListBox->setItemWidget(item, hbox);
0209         item->setData(Qt::SizeHintRole, QSize(1, 40));  // X-size is ignored
0210 
0211         // Select this item (when finished) either if it matches the default
0212         // device, or else is the first item.
0213         if (defItem == nullptr || devName == defstr) {
0214             defItem = item;
0215         }
0216     }
0217 
0218     if (defItem != nullptr) {
0219         defItem->setSelected(true);
0220     }
0221     delete typeConf;
0222 }