File indexing completed on 2025-03-09 05:06:37
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 "PrintQueueUi.h" 0008 #include "ui_PrintQueueUi.h" 0009 0010 #include <JobModel.h> 0011 #include <JobSortFilterModel.h> 0012 #include <ProcessRunner.h> 0013 0014 #include <KCupsPrinter.h> 0015 #include <KCupsRequest.h> 0016 #include <NoSelectionRectDelegate.h> 0017 0018 #include <QByteArray> 0019 #include <QDebug> 0020 #include <QMenu> 0021 #include <QPointer> 0022 #include <QShortcut> 0023 #include <QToolBar> 0024 0025 #include <KConfigGroup> 0026 #include <KIO/AuthInfo> 0027 #include <KJob> 0028 #include <KMessageBox> 0029 #include <KPasswdServerClient> 0030 #include <KSharedConfig> 0031 #include <KUserTimestamp> 0032 #include <KWindowConfig> 0033 0034 static constexpr uint PRINTER_ICON_SIZE = 92; 0035 0036 PrintQueueUi::PrintQueueUi(const KCupsPrinter &printer, QWidget *parent) 0037 : QDialog(parent) 0038 , ui(new Ui::PrintQueueUi) 0039 , m_destName(printer.name()) 0040 { 0041 ui->setupUi(this); 0042 0043 // since setupUi needs to setup on the mainWidget() 0044 // we need to manually connect the buttons 0045 connect(ui->cancelJobPB, &QPushButton::clicked, this, &PrintQueueUi::cancelJob); 0046 connect(ui->holdJobPB, &QPushButton::clicked, this, &PrintQueueUi::holdJob); 0047 connect(ui->resumeJobPB, &QPushButton::clicked, this, &PrintQueueUi::resumeJob); 0048 connect(ui->reprintPB, &QPushButton::clicked, this, &PrintQueueUi::reprintJob); 0049 0050 connect(ui->pausePrinterPB, &QPushButton::clicked, this, &PrintQueueUi::pausePrinter); 0051 connect(ui->configurePrinterPB, &QPushButton::clicked, this, &PrintQueueUi::configurePrinter); 0052 0053 connect(ui->whichJobsCB, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PrintQueueUi::whichJobsIndexChanged); 0054 0055 // Needed so we have our dialog size saved 0056 setAttribute(Qt::WA_DeleteOnClose); 0057 0058 if (printer.info().isEmpty()) { 0059 m_title = printer.name(); 0060 } else { 0061 m_title = printer.info(); 0062 } 0063 setWindowTitle(m_title); 0064 setSizeGripEnabled(true); 0065 (void)minimumSizeHint(); // Force the dialog to be laid out now 0066 layout()->setContentsMargins(0, 0, 0, 0); 0067 0068 m_isClass = printer.isClass(); 0069 0070 // setup default options 0071 ui->jobsView->setCornerWidget(new QWidget); 0072 0073 setupButtons(); 0074 0075 // loads the standard key icon 0076 m_printerIcon = printer.icon().pixmap(PRINTER_ICON_SIZE, PRINTER_ICON_SIZE); 0077 ui->iconL->setPixmap(m_printerIcon); 0078 ui->printerStatusMsgL->setText(QString()); 0079 0080 // setup the jobs model 0081 m_model = new JobModel(this); 0082 m_model->setParentWId(winId()); 0083 m_model->init(printer.name()); 0084 connect(m_model, &JobModel::dataChanged, this, &PrintQueueUi::updateButtons); 0085 connect(m_model, &JobModel::dataChanged, this, &PrintQueueUi::update); 0086 m_proxyModel = new JobSortFilterModel(this); 0087 m_proxyModel->setSourceModel(m_model); 0088 m_proxyModel->setDynamicSortFilter(true); 0089 0090 ui->jobsView->setModel(m_proxyModel); 0091 ui->jobsView->setItemDelegate(new NoSelectionRectDelegate(this)); 0092 // sort by status column means the jobs will be sorted by the queue order 0093 ui->jobsView->sortByColumn(JobModel::ColStatus, Qt::AscendingOrder); 0094 connect(ui->jobsView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PrintQueueUi::updateButtons); 0095 connect(ui->jobsView, &QTreeView::customContextMenuRequested, this, &PrintQueueUi::showContextMenu); 0096 ui->jobsView->header()->setContextMenuPolicy(Qt::CustomContextMenu); 0097 connect(ui->jobsView->header(), &QHeaderView::customContextMenuRequested, this, &PrintQueueUi::showHeaderContextMenu); 0098 0099 QHeaderView *header = ui->jobsView->header(); 0100 header->setSectionResizeMode(QHeaderView::Interactive); 0101 header->setStretchLastSection(false); 0102 header->setSectionResizeMode(JobModel::ColStatus, QHeaderView::ResizeToContents); 0103 header->setSectionResizeMode(JobModel::ColName, QHeaderView::Stretch); 0104 header->setSectionResizeMode(JobModel::ColUser, QHeaderView::ResizeToContents); 0105 header->setSectionResizeMode(JobModel::ColCreated, QHeaderView::ResizeToContents); 0106 header->setSectionResizeMode(JobModel::ColCompleted, QHeaderView::ResizeToContents); 0107 header->setSectionResizeMode(JobModel::ColPages, QHeaderView::ResizeToContents); 0108 header->setSectionResizeMode(JobModel::ColProcessed, QHeaderView::ResizeToContents); 0109 header->setSectionResizeMode(JobModel::ColSize, QHeaderView::ResizeToContents); 0110 header->setSectionResizeMode(JobModel::ColStatusMessage, QHeaderView::ResizeToContents); 0111 header->setSectionResizeMode(JobModel::ColPrinter, QHeaderView::ResizeToContents); 0112 0113 KConfigGroup printQueue(KSharedConfig::openConfig(QLatin1String("print-manager")), QStringLiteral("PrintQueue")); 0114 if (printQueue.hasKey("ColumnState")) { 0115 // restore the header state order 0116 header->restoreState(printQueue.readEntry("ColumnState", QByteArray())); 0117 } else { 0118 // Hide some columns ColPrinter 0119 header->hideSection(JobModel::ColPrinter); 0120 header->hideSection(JobModel::ColUser); 0121 header->hideSection(JobModel::ColCompleted); 0122 header->hideSection(JobModel::ColSize); 0123 header->hideSection(JobModel::ColFromHost); 0124 } 0125 0126 // This is emitted when a printer is modified 0127 connect(KCupsConnection::global(), &KCupsConnection::printerModified, this, &PrintQueueUi::updatePrinter); 0128 0129 // This is emitted when a printer has it's state changed 0130 connect(KCupsConnection::global(), &KCupsConnection::printerStateChanged, this, &PrintQueueUi::updatePrinter); 0131 0132 // This is emitted when a printer is stopped 0133 connect(KCupsConnection::global(), &KCupsConnection::printerStopped, this, &PrintQueueUi::updatePrinter); 0134 0135 // This is emitted when a printer is restarted 0136 connect(KCupsConnection::global(), &KCupsConnection::printerRestarted, this, &PrintQueueUi::updatePrinter); 0137 0138 // This is emitted when a printer is shutdown 0139 connect(KCupsConnection::global(), &KCupsConnection::printerShutdown, this, &PrintQueueUi::updatePrinter); 0140 0141 // This is emitted when a printer is removed 0142 connect(KCupsConnection::global(), &KCupsConnection::printerDeleted, this, &PrintQueueUi::updatePrinter); 0143 0144 // This is emitted when a printer/queue is changed 0145 // Deprecated stuff that works better than the above 0146 connect(KCupsConnection::global(), &KCupsConnection::rhPrinterAdded, this, &PrintQueueUi::updatePrinterByName); 0147 connect(KCupsConnection::global(), &KCupsConnection::rhPrinterRemoved, this, &PrintQueueUi::updatePrinterByName); 0148 connect(KCupsConnection::global(), &KCupsConnection::rhQueueChanged, this, &PrintQueueUi::updatePrinterByName); 0149 0150 updatePrinterByName(m_destName); 0151 0152 // Restore the dialog size 0153 KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), QStringLiteral("PrintQueue")); 0154 KWindowConfig::restoreWindowSize(windowHandle(), configGroup); 0155 0156 auto delJobShortcut = new QShortcut(QKeySequence::Delete, ui->jobsView); 0157 delJobShortcut->setContext(Qt::WidgetShortcut); 0158 connect(delJobShortcut, &QShortcut::activated, this, &PrintQueueUi::cancelJob); 0159 } 0160 0161 PrintQueueUi::~PrintQueueUi() 0162 { 0163 KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), QStringLiteral("PrintQueue")); 0164 // save the header state order 0165 configGroup.writeEntry("ColumnState", ui->jobsView->header()->saveState()); 0166 0167 // Save the dialog size 0168 KWindowConfig::saveWindowSize(windowHandle(), configGroup); 0169 0170 delete ui; 0171 } 0172 0173 int PrintQueueUi::columnCount(const QModelIndex &parent) const 0174 { 0175 if (!parent.isValid()) { 0176 return JobModel::LastColumn; 0177 } 0178 return 0; 0179 } 0180 0181 void PrintQueueUi::setState(int state, const QString &message) 0182 { 0183 qDebug() << state << message; 0184 if (state != m_lastState || ui->printerStatusMsgL->text() != message) { 0185 // save the last state so the ui doesn't need to keep updating 0186 if (ui->printerStatusMsgL->text() != message) { 0187 ui->printerStatusMsgL->setText(message); 0188 } 0189 m_lastState = state; 0190 0191 m_printerPaused = false; 0192 switch (state) { 0193 case KCupsPrinter::Idle: 0194 ui->statusL->setText(i18n("Printer ready")); 0195 ui->pausePrinterPB->setText(i18n("Pause Printer")); 0196 ui->pausePrinterPB->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause"))); 0197 break; 0198 case KCupsPrinter::Printing: 0199 if (!m_title.isNull()) { 0200 QString jobTitle = m_model->processingJob(); 0201 if (jobTitle.isEmpty()) { 0202 ui->statusL->setText(i18n("Printing...")); 0203 } else { 0204 ui->statusL->setText(i18n("Printing '%1'", jobTitle)); 0205 } 0206 ui->pausePrinterPB->setText(i18n("Pause Printer")); 0207 ui->pausePrinterPB->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause"))); 0208 } 0209 break; 0210 case KCupsPrinter::Stopped: 0211 m_printerPaused = true; 0212 ui->statusL->setText(i18n("Printer paused")); 0213 ui->pausePrinterPB->setText(i18n("Resume Printer")); 0214 ui->pausePrinterPB->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); 0215 break; 0216 default: 0217 ui->statusL->setText(i18n("Printer state unknown")); 0218 break; 0219 } 0220 } 0221 } 0222 0223 void PrintQueueUi::showContextMenu(const QPoint &point) 0224 { 0225 // check if the click was actually over a job 0226 if (!ui->jobsView->indexAt(point).isValid() || m_preparingMenu) { 0227 return; 0228 } 0229 0230 // we need to map the selection to source to get the real indexes 0231 QItemSelection selection = m_proxyModel->mapSelectionToSource(ui->jobsView->selectionModel()->selection()); 0232 // if the selection is empty the user clicked on an empty space 0233 if (selection.indexes().isEmpty()) { 0234 return; 0235 } 0236 0237 m_preparingMenu = true; 0238 0239 // context menu 0240 auto menu = new QMenu(this); 0241 menu->setAttribute(Qt::WA_DeleteOnClose); 0242 0243 bool moveTo = false; 0244 bool authenticate = false; 0245 const QModelIndexList indexes = selection.indexes(); 0246 for (const QModelIndex &index : indexes) { 0247 if (index.column() == JobModel::Columns::ColStatus) { 0248 if (index.flags() & Qt::ItemIsDragEnabled) { 0249 // Found a move to item 0250 moveTo = true; 0251 } 0252 if (index.data(JobModel::Role::RoleJobAuthenticationRequired).toBool()) { 0253 // Found an item which requires authentication 0254 authenticate = true; 0255 } 0256 } 0257 } 0258 0259 // if we can move a job create the menu 0260 if (moveTo) { 0261 // move to menu 0262 auto moveToMenu = new QMenu(i18n("Move to"), menu); 0263 0264 // get printers we can move to 0265 QPointer<KCupsRequest> request = new KCupsRequest; 0266 request->getPrinters({KCUPS_PRINTER_NAME, KCUPS_PRINTER_INFO}); 0267 request->waitTillFinished(); 0268 if (!request) { 0269 return; 0270 } 0271 const KCupsPrinters printers = request->printers(); 0272 request->deleteLater(); 0273 0274 for (const KCupsPrinter &printer : printers) { 0275 // If there is a printer and it's not the current one add it 0276 // as a new destination 0277 if (printer.name() != m_destName) { 0278 QAction *action = moveToMenu->addAction(printer.info()); 0279 action->setData(printer.name()); 0280 connect(action, &QAction::triggered, this, [=]() { 0281 this->modifyJob(JobModel::Move, action->data().toString()); 0282 }); 0283 } 0284 } 0285 0286 if (!moveToMenu->isEmpty()) { 0287 menu->addMenu(moveToMenu); 0288 } 0289 } 0290 0291 // Authenticate 0292 if (authenticate) { 0293 QAction *action = menu->addAction(i18n("Authenticate")); 0294 connect(action, &QAction::triggered, this, &PrintQueueUi::authenticateJob); 0295 } 0296 0297 if (menu->isEmpty()) { 0298 delete menu; 0299 } else { 0300 // show the menu on the right point 0301 menu->popup(ui->jobsView->mapToGlobal(point)); 0302 } 0303 0304 m_preparingMenu = false; 0305 } 0306 0307 void PrintQueueUi::showHeaderContextMenu(const QPoint &point) 0308 { 0309 // Displays a menu containing the header name, and 0310 // a check box to indicate if it's being shown 0311 auto menu = new QMenu(this); 0312 for (int i = 0; i < m_proxyModel->columnCount(); i++) { 0313 auto name = m_proxyModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); 0314 QAction *action = menu->addAction(name); 0315 action->setCheckable(true); 0316 action->setChecked(!ui->jobsView->header()->isSectionHidden(i)); 0317 action->setData(i); 0318 } 0319 0320 QAction *action = menu->exec(ui->jobsView->header()->mapToGlobal(point)); 0321 if (action) { 0322 int section = action->data().toInt(); 0323 if (action->isChecked()) { 0324 ui->jobsView->header()->showSection(section); 0325 } else { 0326 ui->jobsView->header()->hideSection(section); 0327 } 0328 } 0329 } 0330 0331 void PrintQueueUi::updatePrinterByName(const QString &printer) 0332 { 0333 qDebug() << printer << m_destName; 0334 if (printer != m_destName) { 0335 // It was another printer that changed 0336 return; 0337 } 0338 0339 const QStringList attr({ 0340 KCUPS_PRINTER_INFO, 0341 KCUPS_PRINTER_TYPE, 0342 KCUPS_PRINTER_STATE, 0343 KCUPS_PRINTER_STATE_MESSAGE, 0344 }); 0345 0346 auto request = new KCupsRequest; 0347 connect(request, &KCupsRequest::finished, this, &PrintQueueUi::getAttributesFinished); 0348 request->getPrinterAttributes(printer, m_isClass, attr); 0349 } 0350 0351 void PrintQueueUi::updatePrinter(const QString &text, 0352 const QString &printerUri, 0353 const QString &printerName, 0354 uint printerState, 0355 const QString &printerStateReasons, 0356 bool printerIsAcceptingJobs) 0357 { 0358 // REALLY? all these parameters just to say foo was added?? 0359 Q_UNUSED(text) 0360 Q_UNUSED(printerUri) 0361 Q_UNUSED(printerState) 0362 Q_UNUSED(printerStateReasons) 0363 Q_UNUSED(printerIsAcceptingJobs) 0364 qDebug() << printerName << printerStateReasons; 0365 0366 updatePrinterByName(printerName); 0367 } 0368 0369 void PrintQueueUi::getAttributesFinished(KCupsRequest *request) 0370 { 0371 qDebug() << request->hasError() << request->printers().isEmpty(); 0372 0373 if (request->hasError() || request->printers().isEmpty()) { 0374 // if cups stops we disable our queue 0375 setEnabled(false); 0376 request->deleteLater(); // DO not delete before using as the request is in another thread 0377 return; 0378 } else if (isEnabled() == false) { 0379 // if cups starts again we enable our queue 0380 setEnabled(true); 0381 } 0382 0383 KCupsPrinter printer = request->printers().first(); 0384 0385 // get printer-info 0386 if (printer.info().isEmpty()) { 0387 m_title = printer.name(); 0388 } else { 0389 m_title = printer.info(); 0390 } 0391 0392 // get printer-state 0393 setState(printer.state(), printer.stateMsg()); 0394 0395 // store if the printer is a class 0396 m_isClass = printer.isClass(); 0397 0398 request->deleteLater(); 0399 0400 update(); 0401 } 0402 0403 void PrintQueueUi::update() 0404 { 0405 // Set window title 0406 if (m_model->rowCount()) { 0407 if (m_destName.isNull()) { 0408 setWindowTitle(i18np("All Printers (%1 Job)", "All Printers (%1 Jobs)", m_model->rowCount())); 0409 } else { 0410 setWindowTitle(i18np("%2 (%1 Job)", "%2 (%1 Jobs)", m_model->rowCount(), m_title)); 0411 } 0412 } else { 0413 setWindowTitle(m_destName.isNull() ? i18n("All Printers") : m_title); 0414 } 0415 } 0416 0417 void PrintQueueUi::updateButtons() 0418 { 0419 bool cancel, hold, release, reprint; 0420 // Set all options to false 0421 cancel = hold = release = reprint = false; 0422 0423 QItemSelection selection; 0424 // we need to map the selection to source to get the real indexes 0425 selection = m_proxyModel->mapSelectionToSource(ui->jobsView->selectionModel()->selection()); 0426 // enable or disable the job action buttons if something is selected 0427 if (!selection.indexes().isEmpty()) { 0428 const QModelIndexList indexes = selection.indexes(); 0429 for (const QModelIndex &index : indexes) { 0430 if (index.column() == 0) { 0431 switch (static_cast<ipp_jstate_t>(index.data(JobModel::RoleJobState).toInt())) { 0432 case IPP_JOB_CANCELED: 0433 case IPP_JOB_COMPLETED: 0434 case IPP_JOB_ABORTED: 0435 break; 0436 case IPP_JOB_HELD: 0437 case IPP_JOB_STOPPED: 0438 release = true; 0439 cancel = true; 0440 break; 0441 default: 0442 cancel = hold = true; 0443 break; 0444 } 0445 if (index.data(JobModel::RoleJobRestartEnabled).toBool()) { 0446 reprint = true; 0447 } 0448 } 0449 } 0450 } 0451 0452 ui->cancelJobPB->setEnabled(cancel); 0453 ui->holdJobPB->setVisible(hold); 0454 ui->resumeJobPB->setVisible(release); 0455 ui->reprintPB->setEnabled(reprint); 0456 } 0457 0458 void PrintQueueUi::modifyJob(int action, const QString &destName) 0459 { 0460 // get all selected indexes 0461 QItemSelection selection; 0462 // we need to map the selection to source to get the real indexes 0463 selection = m_proxyModel->mapSelectionToSource(ui->jobsView->selectionModel()->selection()); 0464 const QModelIndexList indexes = selection.indexes(); 0465 for (const QModelIndex &index : indexes) { 0466 if (index.column() == 0) { 0467 KCupsRequest *request; 0468 request = m_model->modifyJob(index.row(), static_cast<JobModel::JobAction>(action), destName); 0469 if (!request) { 0470 // probably the job already has this state 0471 // or this is an unknown action 0472 continue; 0473 } 0474 request->waitTillFinished(); 0475 if (request->hasError()) { 0476 QString msg, jobName; 0477 jobName = m_model->item(index.row(), static_cast<int>(JobModel::ColName))->text(); 0478 switch (action) { 0479 case JobModel::Cancel: 0480 msg = i18n("Failed to cancel '%1'", jobName); 0481 break; 0482 case JobModel::Hold: 0483 msg = i18n("Failed to hold '%1'", jobName); 0484 break; 0485 case JobModel::Release: 0486 msg = i18n("Failed to release '%1'", jobName); 0487 break; 0488 case JobModel::Reprint: 0489 msg = i18n("Failed to reprint '%1'", jobName); 0490 break; 0491 case JobModel::Move: 0492 msg = i18n("Failed to move '%1' to '%2'", jobName, destName); 0493 break; 0494 } 0495 KMessageBox::detailedError(this, msg, request->errorMsg(), i18n("Failed")); 0496 } 0497 request->deleteLater(); 0498 } 0499 } 0500 } 0501 0502 void PrintQueueUi::pausePrinter() 0503 { 0504 // STOP and RESUME printer 0505 QPointer<KCupsRequest> request = new KCupsRequest; 0506 if (m_printerPaused) { 0507 qDebug() << m_destName << "m_printerPaused"; 0508 request->resumePrinter(m_destName); 0509 } else { 0510 qDebug() << m_destName << "NOT m_printerPaused"; 0511 request->pausePrinter(m_destName); 0512 } 0513 request->waitTillFinished(); 0514 if (request) { 0515 request->deleteLater(); 0516 } 0517 } 0518 0519 void PrintQueueUi::configurePrinter() 0520 { 0521 ProcessRunner::configurePrinter(m_destName); 0522 } 0523 0524 void PrintQueueUi::cancelJob() 0525 { 0526 // CANCEL a job 0527 modifyJob(JobModel::Cancel); 0528 } 0529 0530 void PrintQueueUi::holdJob() 0531 { 0532 // HOLD a job 0533 modifyJob(JobModel::Hold); 0534 } 0535 0536 void PrintQueueUi::resumeJob() 0537 { 0538 // RESUME a job 0539 modifyJob(JobModel::Release); 0540 } 0541 0542 void PrintQueueUi::reprintJob() 0543 { 0544 modifyJob(JobModel::Reprint); 0545 } 0546 0547 void PrintQueueUi::authenticateJob() 0548 { 0549 QScopedPointer<KCupsRequest> request(new KCupsRequest); 0550 request->getPrinterAttributes(m_destName, m_isClass, {KCUPS_PRINTER_URI_SUPPORTED, KCUPS_AUTH_INFO_REQUIRED}); 0551 request->waitTillFinished(); 0552 if (request->hasError() || request->printers().size() != 1) { 0553 qWarning() << "Ignoring request, printer not found or error" << m_destName << request->errorMsg(); 0554 } 0555 0556 const KCupsPrinter printer = request->printers().first(); 0557 0558 KIO::AuthInfo info; 0559 info.keepPassword = true; 0560 info.prompt = i18n("Enter credentials to print from <b>%1</b>", m_destName); 0561 info.url = QUrl(printer.uriSupported()); 0562 if (printer.authInfoRequired().contains(QStringLiteral("domain"))) { 0563 info.setExtraField(QStringLiteral("domain"), QStringLiteral("")); 0564 } 0565 0566 QScopedPointer<KPasswdServerClient> passwdServerClient(new KPasswdServerClient()); 0567 0568 auto winId = static_cast<qlonglong>(this->winId()); 0569 auto usertime = static_cast<qlonglong>(KUserTimestamp::userTimestamp()); 0570 if (passwdServerClient->checkAuthInfo(&info, winId, usertime)) { 0571 // at this stage we don't know if stored credentials are correct 0572 // trying blindly is risky, it may block this user's account 0573 passwdServerClient->removeAuthInfo(info.url.host(), info.url.scheme(), info.username); 0574 } 0575 const int passwordDialogErrorCode = passwdServerClient->queryAuthInfo(&info, QString(), winId, usertime); 0576 if (passwordDialogErrorCode != KJob::NoError) { 0577 // user cancelled or kiod_kpasswdserver not running 0578 qDebug() << "queryAuthInfo error code" << passwordDialogErrorCode; 0579 return; 0580 } 0581 0582 QStringList authInfo; 0583 for (QString &authInfoRequired : printer.authInfoRequired()) { 0584 if (authInfoRequired == QStringLiteral("domain")) { 0585 authInfo << info.getExtraField(QStringLiteral("domain")).toString(); 0586 } else if (authInfoRequired == QStringLiteral("username")) { 0587 authInfo << info.username; 0588 } else if (authInfoRequired == QStringLiteral("password")) { 0589 authInfo << info.password; 0590 } else { 0591 qWarning() << "No auth info for: " << authInfoRequired; 0592 authInfo << QString(); 0593 } 0594 } 0595 0596 // we need to map the selection to source to get the real indexes 0597 QItemSelection selection = m_proxyModel->mapSelectionToSource(ui->jobsView->selectionModel()->selection()); 0598 const QModelIndexList indexes = selection.indexes(); 0599 for (const QModelIndex &index : indexes) { 0600 if (index.column() == JobModel::Columns::ColStatus) { 0601 QScopedPointer<KCupsRequest> authRequest(new KCupsRequest); 0602 authRequest->authenticateJob(m_destName, authInfo, index.data(JobModel::Role::RoleJobId).toInt()); 0603 authRequest->waitTillFinished(); 0604 if (authRequest->hasError()) { 0605 qWarning() << "Error authenticating jobs" << authRequest->error() << authRequest->errorMsg(); 0606 // remove cache on fail 0607 passwdServerClient->removeAuthInfo(info.url.host(), info.url.scheme(), info.username); 0608 return; 0609 } 0610 } 0611 } 0612 } 0613 0614 void PrintQueueUi::whichJobsIndexChanged(int index) 0615 { 0616 switch (index) { 0617 case 1: 0618 m_model->setWhichJobs(JobModel::WhichCompleted); 0619 break; 0620 case 2: 0621 m_model->setWhichJobs(JobModel::WhichAll); 0622 break; 0623 default: 0624 m_model->setWhichJobs(JobModel::WhichActive); 0625 break; 0626 } 0627 } 0628 0629 void PrintQueueUi::setupButtons() 0630 { 0631 // setup jobs buttons 0632 0633 // cancel action 0634 ui->cancelJobPB->setIcon(QIcon::fromTheme(QLatin1String("dialog-cancel"))); 0635 0636 // hold job action 0637 ui->holdJobPB->setIcon(QIcon::fromTheme(QLatin1String("document-open-recent"))); 0638 0639 // resume job action 0640 // TODO we need a new icon 0641 ui->resumeJobPB->setIcon(QIcon::fromTheme(QLatin1String("media-playback-start"))); 0642 0643 ui->reprintPB->setIcon(QIcon::fromTheme(QLatin1String("view-refresh"))); 0644 0645 const QIcon viewFilterIcon = QIcon::fromTheme(QLatin1String("view-filter")); 0646 ui->whichJobsCB->setItemIcon(0, viewFilterIcon); 0647 ui->whichJobsCB->setItemIcon(1, viewFilterIcon); 0648 ui->whichJobsCB->setItemIcon(2, viewFilterIcon); 0649 0650 // stop start printer 0651 ui->pausePrinterPB->setIcon(QIcon::fromTheme(QLatin1String("media-playback-pause"))); 0652 0653 // configure printer 0654 ui->configurePrinterPB->setIcon(QIcon::fromTheme(QLatin1String("configure"))); 0655 } 0656 0657 void PrintQueueUi::closeEvent(QCloseEvent *event) 0658 { 0659 // emits finished signal to be removed the cache 0660 Q_EMIT finished(); 0661 QWidget::closeEvent(event); 0662 } 0663 0664 #include "moc_PrintQueueUi.cpp"