1 /*
2 SPDX-FileCopyrightText: 2010-2018 Daniel Nicoletti <dantti12@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "AddPrinterAssistant.h"
8
9 #include "PageDestinations.h"
10 #include "PageChoosePrinters.h"
11 #include "PageChoosePPD.h"
12 #include "PageAddPrinter.h"
13
14 #include <KCupsRequest.h>
15
16 #include <QHostInfo>
17 #include <QPushButton>
18
19 #include <KLocalizedString>
20 #include <KPixmapSequence>
21 #include <KIconLoader>
22 #include <KSharedConfig>
23 #include <KWindowConfig>
24
AddPrinterAssistant()25 AddPrinterAssistant::AddPrinterAssistant()
26 {
27 setWindowTitle(i18nc("@title:window", "Add a New Printer"));
28 setWindowIcon(QIcon::fromTheme(QLatin1String("printer")));
29 buttonBox()->removeButton(buttonBox()->button(QDialogButtonBox::Cancel));
30 // Needed so we have our dialog size saved
31 setAttribute(Qt::WA_DeleteOnClose);
32
33 QPushButton *helpButton = buttonBox()->addButton(QDialogButtonBox::Help);
34 // Configure the help button to be flat, disabled and empty
35 helpButton->setFlat(true);
36 helpButton->setEnabled(false);
37 helpButton->setIcon(QIcon());
38 helpButton->setText(QString());
39
40 // Setup the busy cursor
41 m_busySeq = new KPixmapSequenceOverlayPainter(this);
42 m_busySeq->setSequence(KIconLoader::global()->loadPixmapSequence(QLatin1String("process-working"), KIconLoader::SizeSmallMedium));
43 m_busySeq->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
44 m_busySeq->setWidget(helpButton);
45
46 connect(finishButton(), &QPushButton::clicked, this, &AddPrinterAssistant::slotFinishButtonClicked);
47
48 // Restore the dialog size
49 KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), "AddPrinterAssistant");
50 KWindowConfig::restoreWindowSize(windowHandle(), configGroup);
51 }
52
~AddPrinterAssistant()53 AddPrinterAssistant::~AddPrinterAssistant()
54 {
55 KConfigGroup configGroup(KSharedConfig::openConfig(QLatin1String("print-manager")), "AddPrinterAssistant");
56 KWindowConfig::saveWindowSize(windowHandle(), configGroup);
57 }
58
initAddPrinter(const QString & printer,const QString & deviceId)59 void AddPrinterAssistant::initAddPrinter(const QString &printer, const QString &deviceId)
60 {
61 // setup our hash args with the information if we are
62 // adding a new printer or a class
63 QVariantHash args({
64 {ADDING_PRINTER, true}
65 });
66
67 KPageWidgetItem *currentPage;
68 if (deviceId.isEmpty()) {
69 m_devicesPage = new KPageWidgetItem(new PageDestinations(args), i18nc("@title:window", "Select a Printer to Add"));
70 addPage(m_devicesPage);
71 currentPage = m_devicesPage;
72
73 m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD, i18nc("@title:window", "Pick a Driver"));
74 addPage(m_choosePPDPage);
75 } else {
76 args[KCUPS_DEVICE_URI] = printer;
77 args[KCUPS_DEVICE_ID] = deviceId;
78 args[KCUPS_DEVICE_LOCATION] = QHostInfo::localHostName();
79
80 m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD(args), i18nc("@title:window", "Pick a Driver"));
81 addPage(m_choosePPDPage);
82 currentPage = m_choosePPDPage;
83 }
84
85 m_addPrinterPage = new KPageWidgetItem(new PageAddPrinter, i18nc("@title:window", "Please describe your printer"));
86 addPage(m_addPrinterPage);
87
88 // Set this later so that all m_*Pages are created
89 setCurrentPage(currentPage);
90 }
91
initAddClass()92 void AddPrinterAssistant::initAddClass()
93 {
94 // setup our hash args with the information if we are
95 // adding a new printer or a class
96 const QVariantHash args({
97 {ADDING_PRINTER, false},
98 {KCUPS_DEVICE_LOCATION, QHostInfo::localHostName()}
99 });
100
101 KPageWidgetItem *currentPage;
102 m_chooseClassPage = new KPageWidgetItem(new PageChoosePrinters(args), i18nc("@title:window", "Configure your connection"));
103 addPage(m_chooseClassPage);
104 currentPage = m_chooseClassPage;
105
106 m_addPrinterPage = new KPageWidgetItem(new PageAddPrinter, i18nc("@title:window", "Please describe your printer"));
107 addPage(m_addPrinterPage);
108
109 // Set this later so that all m_*Pages are created
110 setCurrentPage(currentPage);
111 }
112
initChangePPD(const QString & printer,const QString & deviceUri,const QString & makeAndModel)113 void AddPrinterAssistant::initChangePPD(const QString &printer, const QString &deviceUri, const QString &makeAndModel)
114 {
115 // setup our hash args with the information if we are
116 // adding a new printer or a class
117 const QVariantHash args({
118 {ADDING_PRINTER, true},
119 {KCUPS_DEVICE_URI, deviceUri},
120 {KCUPS_PRINTER_NAME, printer},
121 {KCUPS_PRINTER_MAKE_AND_MODEL, makeAndModel}
122 });
123
124 m_choosePPDPage = new KPageWidgetItem(new PageChoosePPD(args), i18nc("@title:window", "Pick a Driver"));
125 addPage(m_choosePPDPage);
126 setCurrentPage(m_choosePPDPage);
127 }
128
back()129 void AddPrinterAssistant::back()
130 {
131 KAssistantDialog::back();
132 auto currPage = qobject_cast<GenericPage*>(currentPage()->widget());
133 enableNextButton(currPage->canProceed());
134 if (!qobject_cast<GenericPage*>(currentPage()->widget())->isValid()) {
135 back();
136 }
137 }
138
next()139 void AddPrinterAssistant::next()
140 {
141 next(currentPage());
142 }
143
next(KPageWidgetItem * currentPage)144 void AddPrinterAssistant::next(KPageWidgetItem *currentPage)
145 {
146 // Each page has all it's settings and previous pages
147 // settings stored, so when going backwards
148 // we don't set (or even unset values),
149 // and we only call setValues on the next page if
150 // the currentPage() has changes.
151 const QVariantHash args = qobject_cast<GenericPage*>(currentPage->widget())->values();
152 if (currentPage == m_devicesPage) {
153 qobject_cast<GenericPage*>(m_choosePPDPage->widget())->setValues(args);
154 setCurrentPage(m_choosePPDPage);
155 } else if (currentPage == m_chooseClassPage ||currentPage == m_choosePPDPage) {
156 qobject_cast<GenericPage*>(m_addPrinterPage->widget())->setValues(args);
157 setCurrentPage(m_addPrinterPage);
158 }
159 }
160
setCurrentPage(KPageWidgetItem * page)161 void AddPrinterAssistant::setCurrentPage(KPageWidgetItem *page)
162 {
163 // if after setting the values the page is still valid show
164 // it up, if not call next with it so we can find the next page
165 if (qobject_cast<GenericPage*>(page->widget())->isValid()) {
166 KAssistantDialog::setCurrentPage(page);
167 auto currPage = qobject_cast<GenericPage*>(currentPage()->widget());
168 auto nextPage = qobject_cast<GenericPage*>(page->widget());
169 // Disconnect the current page slots
170 disconnect(currPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableNextButton);
171 disconnect(currPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableFinishButton);
172 disconnect(currPage, &GenericPage::proceed, this, static_cast<void(AddPrinterAssistant::*)()>(&AddPrinterAssistant::next));
173 disconnect(currPage, &GenericPage::startWorking, m_busySeq, &KPixmapSequenceOverlayPainter::start);
174 disconnect(currPage, &GenericPage::stopWorking, m_busySeq, &KPixmapSequenceOverlayPainter::stop);
175
176 // Connect next page signals
177 connect(nextPage, &GenericPage::startWorking, m_busySeq, &KPixmapSequenceOverlayPainter::start);
178 connect(nextPage, &GenericPage::stopWorking, m_busySeq, &KPixmapSequenceOverlayPainter::stop);
179 connect(nextPage, &GenericPage::proceed, this, static_cast<void(AddPrinterAssistant::*)()>(&AddPrinterAssistant::next));
180
181 // check the working property
182 if (nextPage->isWorking()) {
183 m_busySeq->start();
184 } else {
185 m_busySeq->stop();
186 }
187
188 // When ChangePPD() is called addPrinterPage is zero
189 if (page == m_addPrinterPage || m_addPrinterPage == nullptr) {
190 connect(nextPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableFinishButton);
191 enableNextButton(false);
192 enableFinishButton(nextPage->canProceed());
193 } else {
194 connect(nextPage, &GenericPage::allowProceed, this, &AddPrinterAssistant::enableNextButton);
195 enableNextButton(nextPage->canProceed());
196 }
197 } else {
198 // In case page is not valid try the next one
199 next(page);
200 }
201 }
202
showEvent(QShowEvent * event)203 void AddPrinterAssistant::showEvent(QShowEvent *event)
204 {
205 KAssistantDialog::showEvent(event);
206 enableNextButton(false);
207 enableFinishButton(false);
208 }
209
slotFinishButtonClicked()210 void AddPrinterAssistant::slotFinishButtonClicked()
211 {
212 auto page = qobject_cast<GenericPage*>(currentPage()->widget());
213 enableFinishButton(false);
214 if (page->finishClicked()) {
215 //KAssistantDialog::slotButtonClicked(button); // FIXME next() really?
216 next();
217 } else {
218 enableFinishButton(true);
219 }
220 }
221
enableNextButton(bool enable)222 void AddPrinterAssistant::enableNextButton(bool enable)
223 {
224 nextButton()->setEnabled(enable);
225 }
226
enableFinishButton(bool enable)227 void AddPrinterAssistant::enableFinishButton(bool enable)
228 {
229 finishButton()->setEnabled(enable);
230 }
231
232 #include "moc_AddPrinterAssistant.cpp"
233