File indexing completed on 2023-10-01 09:38:09
0001 /* 0002 SPDX-FileCopyrightText: 2010-2018 Daniel Nicoletti <dantti12@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "PageDestinations.h" 0008 #include "ui_PageDestinations.h" 0009 0010 #include "DevicesModel.h" 0011 0012 #include "ChooseLpd.h" 0013 #include "ChooseSamba.h" 0014 #include "ChooseSerial.h" 0015 #include "ChooseSocket.h" 0016 #include "ChooseUri.h" 0017 0018 #include <KCupsRequest.h> 0019 #include <KLocalizedString> 0020 #include <NoSelectionRectDelegate.h> 0021 0022 #include <QItemSelectionModel> 0023 #include <QDebug> 0024 0025 // system-config-printer --setup-printer='file:/tmp/printout' --devid='MFG:Ricoh;MDL:Aficio SP C820DN' 0026 PageDestinations::PageDestinations(const QVariantHash &args, QWidget *parent) : 0027 GenericPage(parent), 0028 ui(new Ui::PageDestinations), 0029 m_chooseLpd(new ChooseLpd(this)), 0030 m_chooseSamba(new ChooseSamba(this)), 0031 m_chooseSerial(new ChooseSerial(this)), 0032 m_chooseSocket(new ChooseSocket(this)), 0033 m_chooseUri(new ChooseUri(this)), 0034 m_chooseLabel(new QLabel(this)) 0035 { 0036 ui->setupUi(this); 0037 setAttribute(Qt::WA_DeleteOnClose); 0038 0039 ui->stackedWidget->addWidget(m_chooseLpd); 0040 connect(m_chooseLpd, &ChooseLpd::allowProceed, this, &PageDestinations::allowProceed); 0041 connect(m_chooseLpd, &ChooseLpd::startWorking, this, &PageDestinations::working); 0042 connect(m_chooseLpd, &ChooseLpd::stopWorking, this, &PageDestinations::notWorking); 0043 0044 ui->stackedWidget->addWidget(m_chooseSamba); 0045 connect(m_chooseSamba, &ChooseSamba::allowProceed, this, &PageDestinations::allowProceed); 0046 connect(m_chooseSamba, &ChooseSamba::startWorking, this, &PageDestinations::working); 0047 connect(m_chooseSamba, &ChooseSamba::stopWorking, this, &PageDestinations::notWorking); 0048 0049 ui->stackedWidget->addWidget(m_chooseSerial); 0050 connect(m_chooseSerial, &ChooseSerial::allowProceed, this, &PageDestinations::allowProceed); 0051 connect(m_chooseSerial, &ChooseSerial::startWorking, this, &PageDestinations::working); 0052 connect(m_chooseSerial, &ChooseSerial::stopWorking, this, &PageDestinations::notWorking); 0053 0054 ui->stackedWidget->addWidget(m_chooseSocket); 0055 connect(m_chooseSocket, &ChooseSocket::allowProceed, this, &PageDestinations::allowProceed); 0056 connect(m_chooseSocket, &ChooseSocket::startWorking, this, &PageDestinations::working); 0057 connect(m_chooseSocket, &ChooseSocket::stopWorking, this, &PageDestinations::notWorking); 0058 0059 ui->stackedWidget->addWidget(m_chooseUri); 0060 connect(m_chooseUri, &ChooseUri::allowProceed, this, &PageDestinations::allowProceed); 0061 connect(m_chooseUri, &ChooseUri::startWorking, this, &PageDestinations::working); 0062 connect(m_chooseUri, &ChooseUri::stopWorking, this, &PageDestinations::notWorking); 0063 ui->messageWidget->setWordWrap(true); 0064 connect(m_chooseUri, &ChooseUri::errorMessage, ui->messageWidget, &KMessageWidget::setText); 0065 connect(m_chooseUri, &ChooseUri::errorMessage, ui->messageWidget, &KMessageWidget::animatedShow); 0066 connect(m_chooseUri, &ChooseUri::insertDevice, this, &PageDestinations::insertDevice); 0067 0068 m_chooseLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 0069 ui->stackedWidget->addWidget(m_chooseLabel); 0070 0071 // Hide the message widget 0072 ui->messageWidget->setWordWrap(true); 0073 ui->messageWidget->setMessageType(KMessageWidget::Error); 0074 ui->messageWidget->hide(); 0075 0076 // setup default options 0077 setWindowTitle(i18nc("@title:window", "Select a Printer to Add")); 0078 m_model = new DevicesModel(this); 0079 ui->devicesTV->setModel(m_model); 0080 ui->devicesTV->setItemDelegate(new NoSelectionRectDelegate(this)); 0081 connect(ui->devicesTV->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PageDestinations::deviceChanged); 0082 connect(m_model, &DevicesModel::errorMessage, ui->messageWidget, &KMessageWidget::setText); 0083 connect(m_model, &DevicesModel::errorMessage, ui->messageWidget, &KMessageWidget::animatedShow); 0084 0085 // Expand when a parent is added 0086 connect(m_model, &DevicesModel::parentAdded, ui->devicesTV, &QTreeView::expand); 0087 0088 // Update the view when the device URI combo box changed 0089 connect(ui->connectionsCB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PageDestinations::deviceUriChanged); 0090 ui->connectionsGB->setVisible(false); 0091 0092 // Setup the busy cursor 0093 working(); 0094 connect(m_model, &DevicesModel::loaded, this, &PageDestinations::notWorking); 0095 0096 if (!args.isEmpty()) { 0097 // set our args 0098 setValues(args); 0099 } 0100 } 0101 0102 PageDestinations::~PageDestinations() 0103 { 0104 delete ui; 0105 } 0106 0107 void PageDestinations::setValues(const QVariantHash &args) 0108 { 0109 m_args = args; 0110 if (args[ADDING_PRINTER].toBool()) { 0111 // m_isValid = true; 0112 m_model->update(); 0113 // m_busySeq->start(); 0114 } else { 0115 // m_isValid = false; 0116 } 0117 } 0118 0119 bool PageDestinations::isValid() const 0120 { 0121 return true; 0122 } 0123 0124 QVariantHash PageDestinations::values() const 0125 { 0126 QVariantHash ret = m_args; 0127 auto page = qobject_cast<GenericPage*>(ui->stackedWidget->currentWidget()); 0128 if (page) { 0129 ret = page->values(); 0130 } else if (canProceed()) { 0131 ret = selectedItemValues(); 0132 } 0133 return ret; 0134 } 0135 0136 bool PageDestinations::canProceed() const 0137 { 0138 bool ret = ui->stackedWidget->currentIndex() != 0; 0139 0140 auto page = qobject_cast<GenericPage*>(ui->stackedWidget->currentWidget()); 0141 if (page) { 0142 ret = page->canProceed(); 0143 } 0144 0145 return ret; 0146 } 0147 0148 void PageDestinations::deviceChanged() 0149 { 0150 QItemSelectionModel *selection = ui->devicesTV->selectionModel(); 0151 if (!selection->selectedIndexes().isEmpty() && 0152 selection->selectedIndexes().size() == 1) { 0153 QModelIndex index = selection->selectedIndexes().first(); 0154 QVariant uris = index.data(DevicesModel::DeviceUris); 0155 if (uris.isNull()) { 0156 ui->connectionsGB->setVisible(false); 0157 } else if (uris.type() == QVariant::StringList) { 0158 ui->connectionsCB->clear(); 0159 for (const QString &uri : uris.toStringList()) { 0160 ui->connectionsCB->addItem(uriText(uri), uri); 0161 } 0162 ui->connectionsGB->setVisible(true); 0163 } else { 0164 ui->connectionsCB->clear(); 0165 const auto printers = uris.value<KCupsPrinters>(); 0166 for (const KCupsPrinter &printer : printers) { 0167 ui->connectionsCB->addItem(printer.name(), QVariant::fromValue(printer)); 0168 } 0169 ui->connectionsGB->setVisible(true); 0170 } 0171 } else { 0172 ui->connectionsGB->setVisible(false); 0173 setCurrentPage(nullptr, selectedItemValues()); 0174 return; 0175 } 0176 0177 deviceUriChanged(); 0178 } 0179 0180 void PageDestinations::deviceUriChanged() 0181 { 0182 // Get the selected values 0183 QVariantHash args = selectedItemValues(); 0184 0185 // "beh" is excluded from the list 0186 QString deviceUri = args[KCUPS_DEVICE_URI].toString(); 0187 qDebug() << deviceUri; 0188 if (deviceUri.startsWith(QLatin1String("parallel"))) { 0189 m_chooseLabel->setText(i18n("A printer connected to the parallel port.")); 0190 setCurrentPage(m_chooseLabel, args); 0191 } else if (deviceUri.startsWith(QLatin1String("usb"))) { 0192 m_chooseLabel->setText(i18n("A printer connected to a USB port.")); 0193 setCurrentPage(m_chooseLabel, args); 0194 } else if (deviceUri.startsWith(QLatin1String("bluetooth"))) { 0195 m_chooseLabel->setText(i18n("A printer connected via Bluetooth.")); 0196 setCurrentPage(m_chooseLabel, args); 0197 } else if (deviceUri.startsWith(QLatin1String("hal"))) { 0198 m_chooseLabel->setText(i18n("Local printer detected by the " 0199 "Hardware Abstraction Layer (HAL).")); 0200 setCurrentPage(m_chooseLabel, args); 0201 } else if (deviceUri.startsWith(QLatin1String("hp"))) { 0202 m_chooseLabel->setText(i18n("HPLIP software driving a printer, " 0203 "or the printer function of a multi-function device.")); 0204 setCurrentPage(m_chooseLabel, args); 0205 } else if (deviceUri.startsWith(QLatin1String("hpfax"))) { 0206 m_chooseLabel->setText(i18n("HPLIP software driving a fax machine, " 0207 "or the fax function of a multi-function device.")); 0208 setCurrentPage(m_chooseLabel, args); 0209 } else if (deviceUri.startsWith(QLatin1String("dnssd")) || 0210 deviceUri.startsWith(QLatin1String("mdns"))) { 0211 // TODO this needs testing... 0212 QString text; 0213 if (deviceUri.contains(QLatin1String("cups"))) { 0214 text = i18n("Remote CUPS printer via DNS-SD"); 0215 } else { 0216 QString protocol; 0217 if (deviceUri.contains(QLatin1String("._ipp"))) { 0218 protocol = QLatin1String("IPP"); 0219 } else if (deviceUri.contains(QLatin1String("._printer"))) { 0220 protocol = QLatin1String("LPD"); 0221 } else if (deviceUri.contains(QLatin1String("._pdl-datastream"))) { 0222 protocol = QLatin1String("AppSocket/JetDirect"); 0223 } 0224 0225 if (protocol.isNull()) { 0226 text = i18n("Network printer via DNS-SD"); 0227 } else { 0228 text = i18n("%1 network printer via DNS-SD", protocol); 0229 } 0230 } 0231 m_chooseLabel->setText(text); 0232 setCurrentPage(m_chooseLabel, args); 0233 } else if (deviceUri.startsWith(QLatin1String("socket"))) { 0234 qDebug() << "SOCKET"; 0235 setCurrentPage(m_chooseSocket, args); 0236 } else if (deviceUri.startsWith(QLatin1String("ipp")) || 0237 deviceUri.startsWith(QLatin1String("ipps")) || 0238 deviceUri.startsWith(QLatin1String("http")) || 0239 deviceUri.startsWith(QLatin1String("https"))) { 0240 setCurrentPage(m_chooseUri, args); 0241 } else if (deviceUri.startsWith(QLatin1String("lpd"))) { 0242 setCurrentPage(m_chooseLpd, args); 0243 } else if (deviceUri.startsWith(QLatin1String("scsi"))) { 0244 // TODO 0245 setCurrentPage(m_chooseUri, args); 0246 } else if (deviceUri.startsWith(QLatin1String("serial"))) { 0247 setCurrentPage(m_chooseSerial, args); 0248 } else if (deviceUri.startsWith(QLatin1String("smb"))) { 0249 setCurrentPage(m_chooseSamba, args); 0250 } else if (deviceUri.startsWith(QLatin1String("network"))) { 0251 setCurrentPage(m_chooseUri, args); 0252 } else { 0253 setCurrentPage(m_chooseUri, args); 0254 } 0255 0256 Q_EMIT allowProceed(canProceed()); 0257 } 0258 0259 void PageDestinations::insertDevice(const QString &device_class, const QString &device_id, const QString &device_info, const QString &device_make_and_model, const QString &device_uri, const QString &device_location, const KCupsPrinters &grouped_printers) 0260 { 0261 m_model->insertDevice(device_class, 0262 device_id, 0263 device_info, 0264 device_make_and_model, 0265 device_uri, 0266 device_location, 0267 grouped_printers); 0268 } 0269 0270 QVariantHash PageDestinations::selectedItemValues() const 0271 { 0272 QVariantHash ret = m_args; 0273 if (!ui->devicesTV->selectionModel()->selectedIndexes().isEmpty() && 0274 ui->devicesTV->selectionModel()->selectedIndexes().size() == 1) { 0275 QModelIndex index = ui->devicesTV->selectionModel()->selectedIndexes().first(); 0276 QVariant uri = index.data(DevicesModel::DeviceUri); 0277 QVariant uris = index.data(DevicesModel::DeviceUris); 0278 // if the devicesTV holds an item with grouped URIs 0279 // get the selected value from the connections combo box 0280 if (uris.isNull() || uris.type() == QVariant::StringList) { 0281 if (uris.type() == QVariant::StringList) { 0282 uri = ui->connectionsCB->itemData(ui->connectionsCB->currentIndex()); 0283 } 0284 ret[KCUPS_DEVICE_URI] = uri; 0285 ret[KCUPS_DEVICE_ID] = index.data(DevicesModel::DeviceId); 0286 ret[KCUPS_DEVICE_MAKE_AND_MODEL] = index.data(DevicesModel::DeviceMakeAndModel); 0287 ret[KCUPS_DEVICE_INFO] = index.data(DevicesModel::DeviceInfo); 0288 ret[KCUPS_DEVICE_LOCATION] = index.data(DevicesModel::DeviceLocation); 0289 } else { 0290 QVariant aux = ui->connectionsCB->itemData(ui->connectionsCB->currentIndex()); 0291 KCupsPrinter printer = aux.value<KCupsPrinter>(); 0292 QUrl url(uri.toString()); 0293 url.setPath(QLatin1String("printers/") + printer.name()); 0294 ret[KCUPS_DEVICE_URI] = url.url(); 0295 ret[KCUPS_DEVICE_ID] = index.data(DevicesModel::DeviceId); 0296 ret[KCUPS_PRINTER_INFO] = printer.info(); 0297 qDebug() << KCUPS_PRINTER_INFO << printer.info(); 0298 ret[KCUPS_PRINTER_NAME] = printer.name(); 0299 ret[KCUPS_DEVICE_LOCATION] = printer.location(); 0300 } 0301 qDebug() << uri << ret; 0302 } 0303 return ret; 0304 } 0305 0306 void PageDestinations::setCurrentPage(QWidget *widget, const QVariantHash &args) 0307 { 0308 auto page = qobject_cast<GenericPage*>(widget); 0309 if (page) { 0310 page->setValues(args); 0311 if (ui->stackedWidget->currentWidget() != page) { 0312 ui->stackedWidget->setCurrentWidget(page); 0313 } 0314 } else if (qobject_cast<QLabel*>(widget)) { 0315 if (ui->connectionsGB->isVisible() && 0316 ui->connectionsCB->currentText() == m_chooseLabel->text()) { 0317 // Don't show duplicated text for the user 0318 m_chooseLabel->clear(); 0319 } 0320 0321 if (ui->stackedWidget->currentWidget() != widget) { 0322 ui->stackedWidget->setCurrentWidget(widget); 0323 } 0324 } else { 0325 ui->stackedWidget->setCurrentIndex(0); 0326 } 0327 } 0328 0329 QString PageDestinations::uriText(const QString &uri) const 0330 { 0331 QString ret; 0332 if (uri.startsWith(QLatin1String("parallel"))) { 0333 ret = i18n("Parallel Port"); 0334 } else if (uri.startsWith(QLatin1String("serial"))) { 0335 ret = i18n("Serial Port"); 0336 } else if (uri.startsWith(QLatin1String("usb"))) { 0337 ret = i18n("USB"); 0338 } else if (uri.startsWith(QLatin1String("bluetooth")) ){ 0339 ret = i18n("Bluetooth"); 0340 } else if (uri.startsWith(QLatin1String("hpfax"))) { 0341 ret = i18n("Fax - HP Linux Imaging and Printing (HPLIP)"); 0342 } else if (uri.startsWith(QLatin1String("hp"))) { 0343 ret = i18n("HP Linux Imaging and Printing (HPLIP)"); 0344 } else if (uri.startsWith(QLatin1String("hal"))) { 0345 ret = i18n("Hardware Abstraction Layer (HAL)"); 0346 } else if (uri.startsWith(QLatin1String("socket"))) { 0347 ret = i18n("AppSocket/HP JetDirect"); 0348 } else if (uri.startsWith(QLatin1String("lpd"))) { 0349 // Check if the queue name is defined 0350 const QString queue = uri.section(QLatin1Char('/'), -1, -1); 0351 if (queue.isEmpty()) { 0352 ret = i18n("LPD/LPR queue"); 0353 } else { 0354 ret = i18n("LPD/LPR queue %1", queue); 0355 } 0356 } else if (uri.startsWith(QLatin1String("smb"))) { 0357 ret = i18n("Windows Printer via SAMBA"); 0358 } else if (uri.startsWith(QLatin1String("ipp"))) { 0359 // Check if the queue name (fileName) is defined 0360 const QString queue = uri.section(QLatin1Char('/'), -1, -1); 0361 if (queue.isEmpty()) { 0362 ret = i18n("IPP"); 0363 } else { 0364 ret = i18n("IPP %1", queue); 0365 } 0366 } else if (uri.startsWith(QLatin1String("https"))) { 0367 ret = i18n("HTTP"); 0368 } else if (uri.startsWith(QLatin1String("dnssd")) || 0369 uri.startsWith(QLatin1String("mdns"))) { 0370 // TODO this needs testing... 0371 QString text; 0372 if (uri.contains(QLatin1String("cups"))) { 0373 text = i18n("Remote CUPS printer via DNS-SD"); 0374 } else { 0375 if (uri.contains(QLatin1String("._ipp"))) { 0376 ret = i18n("IPP network printer via DNS-SD"); 0377 } else if (uri.contains(QLatin1String("._printer"))) { 0378 ret = i18n("LPD network printer via DNS-SD"); 0379 } else if (uri.contains(QLatin1String("._pdl-datastream"))) { 0380 ret = i18n("AppSocket/JetDirect network printer via DNS-SD"); 0381 } else { 0382 ret = i18n("Network printer via DNS-SD"); 0383 } 0384 } 0385 } else { 0386 ret = uri; 0387 } 0388 return ret; 0389 } 0390 0391 #include "moc_PageDestinations.cpp"