File indexing completed on 2025-01-19 05:06:21

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 "AddPrinterAssistant.h"
0008 
0009 #include "PageAddPrinter.h"
0010 #include "PageChoosePPD.h"
0011 #include "PageChoosePrinters.h"
0012 #include "PageDestinations.h"
0013 
0014 #include <KCupsRequest.h>
0015 
0016 #include <QHostInfo>
0017 #include <QPushButton>
0018 
0019 #include <KIconLoader>
0020 #include <KLocalizedString>
0021 #include <KPixmapSequence>
0022 #include <KPixmapSequenceLoader>
0023 #include <KSharedConfig>
0024 #include <KWindowConfig>
0025 
0026 AddPrinterAssistant::AddPrinterAssistant()
0027 {
0028     setWindowTitle(i18nc("@title:window", "Add a New Printer"));
0029     setWindowIcon(QIcon::fromTheme(QLatin1String("printer")));
0030     buttonBox()->removeButton(buttonBox()->button(QDialogButtonBox::Cancel));
0031     // Needed so we have our dialog size saved
0032     setAttribute(Qt::WA_DeleteOnClose);
0033 
0034     QPushButton *helpButton = buttonBox()->addButton(QDialogButtonBox::Help);
0035     // Configure the help button to be flat, disabled and empty
0036     helpButton->setFlat(true);
0037     helpButton->setEnabled(false);
0038     helpButton->setIcon(QIcon());
0039     helpButton->setText(QString());
0040 
0041     // Setup the busy cursor
0042     m_busySeq = new KPixmapSequenceOverlayPainter(this);
0043     m_busySeq->setSequence(KPixmapSequenceLoader::load(QLatin1String("process-working"), KIconLoader::SizeSmallMedium));
0044     m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
0045     m_busySeq->setWidget(helpButton);
0046 
0047     connect(finishButton(), &QPushButton::clicked, this, &AddPrinterAssistant::slotFinishButtonClicked);
0048 
0049     // Restore the dialog size
0050     KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), QStringLiteral("AddPrinterAssistant"));
0051     KWindowConfig::restoreWindowSize(windowHandle(), configGroup);
0052 }
0053 
0054 AddPrinterAssistant::~AddPrinterAssistant()
0055 {
0056     KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), QStringLiteral("AddPrinterAssistant"));
0057     KWindowConfig::saveWindowSize(windowHandle(), configGroup);
0058 }
0059 
0060 void AddPrinterAssistant::initAddPrinter(const QString &printer, const QString &deviceId)
0061 {
0062     // setup our hash args with the information if we are
0063     // adding a new printer or a class
0064     QVariantMap args({
0065         {ADDING_PRINTER, true},
0066     });
0067 
0068     KPageWidgetItem *currentPage;
0069     if (deviceId.isEmpty()) {
0070         m_devicesPage = new KPageWidgetItem(new PageDestinations(args), i18nc("@title:window", "Select a Printer to Add"));
0071         addPage(m_devicesPage);
0072         currentPage = m_devicesPage;
0073 
0074         m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD);
0075         addPage(m_choosePPDPage);
0076     } else {
0077         args[KCUPS_DEVICE_URI] = printer;
0078         args[KCUPS_DEVICE_ID] = deviceId;
0079         args[KCUPS_DEVICE_LOCATION] = QHostInfo::localHostName();
0080 
0081         m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD(args));
0082         addPage(m_choosePPDPage);
0083         currentPage = m_choosePPDPage;
0084     }
0085 
0086     m_addPrinterPage = new KPageWidgetItem(new PageAddPrinter, i18nc("@title:window", "Please describe your printer"));
0087     addPage(m_addPrinterPage);
0088 
0089     // Set this later so that all m_*Pages are created
0090     setCurrentPage(currentPage);
0091 }
0092 
0093 void AddPrinterAssistant::initAddClass()
0094 {
0095     // setup our hash args with the information if we are
0096     // adding a new printer or a class
0097     const QVariantMap args({
0098         {ADDING_PRINTER, false},
0099         {KCUPS_DEVICE_LOCATION, QHostInfo::localHostName()},
0100     });
0101 
0102     KPageWidgetItem *currentPage;
0103     m_chooseClassPage = new KPageWidgetItem(new PageChoosePrinters(args), i18nc("@title:window", "Configure your connection"));
0104     addPage(m_chooseClassPage);
0105     currentPage = m_chooseClassPage;
0106 
0107     m_addPrinterPage = new KPageWidgetItem(new PageAddPrinter, i18nc("@title:window", "Please describe your printer"));
0108     addPage(m_addPrinterPage);
0109 
0110     // Set this later so that all m_*Pages are created
0111     setCurrentPage(currentPage);
0112 }
0113 
0114 void AddPrinterAssistant::initChangePPD(const QString &printer, const QString &deviceUri, const QString &makeAndModel)
0115 {
0116     // setup our hash args with the information if we are
0117     // adding a new printer or a class
0118     const QVariantMap args({
0119         {ADDING_PRINTER, true},
0120         {KCUPS_DEVICE_URI, deviceUri},
0121         {KCUPS_PRINTER_NAME, printer},
0122         {KCUPS_PRINTER_MAKE_AND_MODEL, makeAndModel},
0123     });
0124 
0125     m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD(args));
0126     addPage(m_choosePPDPage);
0127     setCurrentPage(m_choosePPDPage);
0128 }
0129 
0130 void AddPrinterAssistant::back()
0131 {
0132     KAssistantDialog::back();
0133     auto currPage = qobject_cast<GenericPage *>(currentPage()->widget());
0134     enableNextButton(currPage->canProceed());
0135     if (!qobject_cast<GenericPage *>(currentPage()->widget())->isValid()) {
0136         back();
0137     }
0138 }
0139 
0140 void AddPrinterAssistant::next()
0141 {
0142     next(currentPage());
0143 }
0144 
0145 void AddPrinterAssistant::next(KPageWidgetItem *currentPage)
0146 {
0147     // Each page has all it's settings and previous pages
0148     // settings stored, so when going backwards
0149     // we don't set (or even unset values),
0150     // and we only call setValues on the next page if
0151     // the currentPage() has changes.
0152     const QVariantMap args = qobject_cast<GenericPage *>(currentPage->widget())->values();
0153     if (currentPage == m_devicesPage) {
0154         qobject_cast<GenericPage *>(m_choosePPDPage->widget())->setValues(args);
0155         setCurrentPage(m_choosePPDPage);
0156     } else if (currentPage == m_chooseClassPage || currentPage == m_choosePPDPage) {
0157         qobject_cast<GenericPage *>(m_addPrinterPage->widget())->setValues(args);
0158         setCurrentPage(m_addPrinterPage);
0159     }
0160 }
0161 
0162 void AddPrinterAssistant::setCurrentPage(KPageWidgetItem *page)
0163 {
0164     // if after setting the values the page is still valid show
0165     // it up, if not call next with it so we can find the next page
0166     if (qobject_cast<GenericPage *>(page->widget())->isValid()) {
0167         KAssistantDialog::setCurrentPage(page);
0168         auto currPage = qobject_cast<GenericPage *>(currentPage()->widget());
0169         auto nextPage = qobject_cast<GenericPage *>(page->widget());
0170         // Disconnect the current page slots
0171         disconnect(currPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableNextButton);
0172         disconnect(currPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableFinishButton);
0173         disconnect(currPage, &GenericPage::proceed, this, static_cast<void (AddPrinterAssistant::*)()>(&AddPrinterAssistant::next));
0174         disconnect(currPage, &GenericPage::startWorking, m_busySeq, &KPixmapSequenceOverlayPainter::start);
0175         disconnect(currPage, &GenericPage::stopWorking, m_busySeq, &KPixmapSequenceOverlayPainter::stop);
0176 
0177         // Connect next page signals
0178         connect(nextPage, &GenericPage::startWorking, m_busySeq, &KPixmapSequenceOverlayPainter::start);
0179         connect(nextPage, &GenericPage::stopWorking, m_busySeq, &KPixmapSequenceOverlayPainter::stop);
0180         connect(nextPage, &GenericPage::proceed, this, static_cast<void (AddPrinterAssistant::*)()>(&AddPrinterAssistant::next));
0181 
0182         // check the working property
0183         if (nextPage->isWorking()) {
0184             m_busySeq->start();
0185         } else {
0186             m_busySeq->stop();
0187         }
0188 
0189         if (page == m_choosePPDPage) {
0190             QVariantMap args = qobject_cast<GenericPage *>(page->widget())->values();
0191             m_choosePPDPage->setName(i18nc("@title:window", "Pick a Driver for %1", args[KCUPS_DEVICE_MAKE_AND_MODEL].toString()));
0192         }
0193 
0194         // When ChangePPD() is called addPrinterPage is zero
0195         if (page == m_addPrinterPage || m_addPrinterPage == nullptr) {
0196             connect(nextPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableFinishButton);
0197             enableNextButton(false);
0198             enableFinishButton(nextPage->canProceed());
0199         } else {
0200             connect(nextPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableNextButton);
0201             enableNextButton(nextPage->canProceed());
0202         }
0203     } else {
0204         // In case page is not valid try the next one
0205         next(page);
0206     }
0207 }
0208 
0209 void AddPrinterAssistant::showEvent(QShowEvent *event)
0210 {
0211     KAssistantDialog::showEvent(event);
0212     enableNextButton(false);
0213     enableFinishButton(false);
0214 }
0215 
0216 void AddPrinterAssistant::slotFinishButtonClicked()
0217 {
0218     auto page = qobject_cast<GenericPage *>(currentPage()->widget());
0219     enableFinishButton(false);
0220     if (page->finishClicked()) {
0221         // KAssistantDialog::slotButtonClicked(button); // FIXME next() really?
0222         next();
0223     } else {
0224         enableFinishButton(true);
0225     }
0226 }
0227 
0228 void AddPrinterAssistant::enableNextButton(bool enable)
0229 {
0230     nextButton()->setEnabled(enable);
0231 }
0232 
0233 void AddPrinterAssistant::enableFinishButton(bool enable)
0234 {
0235     finishButton()->setEnabled(enable);
0236 }
0237 
0238 #include "moc_AddPrinterAssistant.cpp"