File indexing completed on 2025-01-19 12:59:17
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 }