File indexing completed on 2025-01-19 05:06:22
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 <QDebug> 0023 #include <QItemSelectionModel> 0024 0025 // system-config-printer --setup-printer='file:/tmp/printout' --devid='MFG:Ricoh;MDL:Aficio SP C820DN' 0026 PageDestinations::PageDestinations(const QVariantMap &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 QVariantMap &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 QVariantMap PageDestinations::values() const 0125 { 0126 QVariantMap 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() && selection->selectedIndexes().size() == 1) { 0152 QModelIndex index = selection->selectedIndexes().first(); 0153 QVariant uris = index.data(DevicesModel::DeviceUris); 0154 if (uris.isNull()) { 0155 ui->connectionsGB->setVisible(false); 0156 } else if (uris.type() == QVariant::StringList) { 0157 ui->connectionsCB->clear(); 0158 for (const QString &uri : uris.toStringList()) { 0159 ui->connectionsCB->addItem(m_model->uriDevice(uri), uri); 0160 } 0161 ui->connectionsGB->setVisible(true); 0162 } else { 0163 ui->connectionsCB->clear(); 0164 const auto printers = uris.value<KCupsPrinters>(); 0165 for (const KCupsPrinter &printer : printers) { 0166 ui->connectionsCB->addItem(printer.name(), QVariant::fromValue(printer)); 0167 } 0168 ui->connectionsGB->setVisible(true); 0169 } 0170 } else { 0171 ui->connectionsGB->setVisible(false); 0172 setCurrentPage(nullptr, selectedItemValues()); 0173 return; 0174 } 0175 0176 deviceUriChanged(); 0177 } 0178 0179 void PageDestinations::deviceUriChanged() 0180 { 0181 // Get the selected values 0182 QVariantMap args = selectedItemValues(); 0183 0184 // "beh" is excluded from the list 0185 QString deviceUri = args[KCUPS_DEVICE_URI].toString(); 0186 qDebug() << deviceUri; 0187 if (deviceUri.startsWith(QLatin1String("parallel"))) { 0188 m_chooseLabel->setText(i18n("A printer connected to the parallel port.")); 0189 setCurrentPage(m_chooseLabel, args); 0190 } else if (deviceUri.startsWith(QLatin1String("usb"))) { 0191 m_chooseLabel->setText(i18n("A printer connected to a USB port.")); 0192 setCurrentPage(m_chooseLabel, args); 0193 } else if (deviceUri.startsWith(QLatin1String("bluetooth"))) { 0194 m_chooseLabel->setText(i18n("A printer connected via Bluetooth.")); 0195 setCurrentPage(m_chooseLabel, args); 0196 } else if (deviceUri.startsWith(QLatin1String("hal"))) { 0197 m_chooseLabel->setText( 0198 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( 0203 i18n("HPLIP software driving a printer, " 0204 "or the printer function of a multi-function device.")); 0205 setCurrentPage(m_chooseLabel, args); 0206 } else if (deviceUri.startsWith(QLatin1String("hpfax"))) { 0207 m_chooseLabel->setText( 0208 i18n("HPLIP software driving a fax machine, " 0209 "or the fax function of a multi-function device.")); 0210 setCurrentPage(m_chooseLabel, args); 0211 } else if (deviceUri.startsWith(QLatin1String("dnssd")) || deviceUri.startsWith(QLatin1String("mdns"))) { 0212 // TODO this needs testing... 0213 QString text; 0214 if (deviceUri.contains(QLatin1String("cups"))) { 0215 text = i18n("Remote CUPS printer via DNS-SD"); 0216 } else { 0217 QString protocol; 0218 if (deviceUri.contains(QLatin1String("._ipp"))) { 0219 protocol = QLatin1String("IPP"); 0220 } else if (deviceUri.contains(QLatin1String("._printer"))) { 0221 protocol = QLatin1String("LPD"); 0222 } else if (deviceUri.contains(QLatin1String("._pdl-datastream"))) { 0223 protocol = QLatin1String("AppSocket/JetDirect"); 0224 } 0225 0226 if (protocol.isNull()) { 0227 text = i18n("Network printer via DNS-SD"); 0228 } else { 0229 text = i18n("%1 network printer via DNS-SD", protocol); 0230 } 0231 } 0232 m_chooseLabel->setText(text); 0233 setCurrentPage(m_chooseLabel, args); 0234 } else if (deviceUri.startsWith(QLatin1String("socket"))) { 0235 qDebug() << "SOCKET"; 0236 setCurrentPage(m_chooseSocket, args); 0237 } else if (deviceUri.startsWith(QLatin1String("ipp")) || deviceUri.startsWith(QLatin1String("ipps")) || deviceUri.startsWith(QLatin1String("http")) 0238 || deviceUri.startsWith(QLatin1String("https"))) { 0239 setCurrentPage(m_chooseUri, args); 0240 } else if (deviceUri.startsWith(QLatin1String("lpd"))) { 0241 setCurrentPage(m_chooseLpd, args); 0242 } else if (deviceUri.startsWith(QLatin1String("scsi"))) { 0243 // TODO 0244 setCurrentPage(m_chooseUri, args); 0245 } else if (deviceUri.startsWith(QLatin1String("serial"))) { 0246 setCurrentPage(m_chooseSerial, args); 0247 } else if (deviceUri.startsWith(QLatin1String("smb"))) { 0248 setCurrentPage(m_chooseSamba, args); 0249 } else if (deviceUri.startsWith(QLatin1String("network"))) { 0250 setCurrentPage(m_chooseUri, args); 0251 } else { 0252 setCurrentPage(m_chooseUri, args); 0253 } 0254 0255 Q_EMIT allowProceed(canProceed()); 0256 } 0257 0258 void PageDestinations::insertDevice(const QString &device_class, 0259 const QString &device_id, 0260 const QString &device_info, 0261 const QString &device_make_and_model, 0262 const QString &device_uri, 0263 const QString &device_location, 0264 const KCupsPrinters &grouped_printers) 0265 { 0266 m_model->insertDevice(device_class, device_id, device_info, device_make_and_model, device_uri, device_location, grouped_printers); 0267 } 0268 0269 QVariantMap PageDestinations::selectedItemValues() const 0270 { 0271 QVariantMap ret = m_args; 0272 if (!ui->devicesTV->selectionModel()->selectedIndexes().isEmpty() && ui->devicesTV->selectionModel()->selectedIndexes().size() == 1) { 0273 QModelIndex index = ui->devicesTV->selectionModel()->selectedIndexes().first(); 0274 QVariant uri = index.data(DevicesModel::DeviceUri); 0275 QVariant uris = index.data(DevicesModel::DeviceUris); 0276 // if the devicesTV holds an item with grouped URIs 0277 // get the selected value from the connections combo box 0278 if (uris.isNull() || uris.type() == QVariant::StringList) { 0279 if (uris.type() == QVariant::StringList) { 0280 uri = ui->connectionsCB->itemData(ui->connectionsCB->currentIndex()); 0281 } 0282 ret[KCUPS_DEVICE_URI] = uri; 0283 ret[KCUPS_DEVICE_ID] = index.data(DevicesModel::DeviceId); 0284 ret[KCUPS_DEVICE_MAKE_AND_MODEL] = index.data(DevicesModel::DeviceMakeAndModel); 0285 ret[KCUPS_DEVICE_INFO] = index.data(DevicesModel::DeviceInfo); 0286 ret[KCUPS_DEVICE_LOCATION] = index.data(DevicesModel::DeviceLocation); 0287 } else { 0288 QVariant aux = ui->connectionsCB->itemData(ui->connectionsCB->currentIndex()); 0289 KCupsPrinter printer = aux.value<KCupsPrinter>(); 0290 QUrl url(uri.toString()); 0291 url.setPath(QLatin1String("printers/") + printer.name()); 0292 ret[KCUPS_DEVICE_URI] = url.url(); 0293 ret[KCUPS_DEVICE_ID] = index.data(DevicesModel::DeviceId); 0294 ret[KCUPS_PRINTER_INFO] = printer.info(); 0295 qDebug() << KCUPS_PRINTER_INFO << printer.info(); 0296 ret[KCUPS_PRINTER_NAME] = printer.name(); 0297 ret[KCUPS_DEVICE_LOCATION] = printer.location(); 0298 } 0299 qDebug() << uri << ret; 0300 } 0301 return ret; 0302 } 0303 0304 void PageDestinations::setCurrentPage(QWidget *widget, const QVariantMap &args) 0305 { 0306 auto page = qobject_cast<GenericPage *>(widget); 0307 if (page) { 0308 page->setValues(args); 0309 if (ui->stackedWidget->currentWidget() != page) { 0310 ui->stackedWidget->setCurrentWidget(page); 0311 } 0312 } else if (qobject_cast<QLabel *>(widget)) { 0313 if (ui->connectionsGB->isVisible() && ui->connectionsCB->currentText() == m_chooseLabel->text()) { 0314 // Don't show duplicated text for the user 0315 m_chooseLabel->clear(); 0316 } 0317 0318 if (ui->stackedWidget->currentWidget() != widget) { 0319 ui->stackedWidget->setCurrentWidget(widget); 0320 } 0321 } else { 0322 ui->stackedWidget->setCurrentIndex(0); 0323 } 0324 } 0325 0326 #include "moc_PageDestinations.cpp"