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 "PrinterBehavior.h"
8 #include "ui_PrinterBehavior.h"
9 
10 #include "Debug.h"
11 
12 #include <QPointer>
13 
PrinterBehavior(const QString & destName,bool isClass,QWidget * parent)14 PrinterBehavior::PrinterBehavior(const QString &destName, bool isClass, QWidget *parent) :
15     PrinterPage(parent),
16     ui(new Ui::PrinterBehavior),
17     m_destName(destName),
18     m_isClass(isClass)
19 {
20     ui->setupUi(this);
21 
22     connect(ui->errorPolicyCB, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
23             this, &PrinterBehavior::currentIndexChangedCB);
24     connect(ui->operationPolicyCB, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
25             this, &PrinterBehavior::currentIndexChangedCB);
26 
27     connect(ui->startingBannerCB, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
28             this, &PrinterBehavior::currentIndexChangedCB);
29     connect(ui->endingBannerCB, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
30             this, &PrinterBehavior::currentIndexChangedCB);
31 
32     connect(ui->usersELB, &KEditListWidget::changed, this, &PrinterBehavior::userListChanged);
33     connect(ui->allowRB, &QRadioButton::toggled, this, &PrinterBehavior::userListChanged);
34 }
35 
~PrinterBehavior()36 PrinterBehavior::~PrinterBehavior()
37 {
38     delete ui;
39 }
40 
setValues(const KCupsPrinter & printer)41 void PrinterBehavior::setValues(const KCupsPrinter &printer)
42 {
43     int defaultChoice;
44     ui->errorPolicyCB->clear();
45     const QStringList errorPolicySupported = printer.errorPolicySupported();
46     for (const QString &value : errorPolicySupported) {
47         ui->errorPolicyCB->addItem(errorPolicyString(value), value);
48     }
49     const QStringList errorPolicy = printer.errorPolicy();
50     if (!errorPolicy.isEmpty()) {
51         defaultChoice = ui->errorPolicyCB->findData(errorPolicy.first());
52         ui->errorPolicyCB->setCurrentIndex(defaultChoice);
53         ui->errorPolicyCB->setProperty("defaultChoice", defaultChoice);
54     }
55 
56     ui->operationPolicyCB->clear();
57     const QStringList opPolicySupported = printer.opPolicySupported();
58     for (const QString &value : opPolicySupported) {
59         ui->operationPolicyCB->addItem(operationPolicyString(value), value);
60     }
61     const QStringList operationPolicy = printer.opPolicy();
62     if (!errorPolicy.isEmpty()) {
63         defaultChoice = ui->operationPolicyCB->findData(operationPolicy.first());
64         ui->operationPolicyCB->setCurrentIndex(defaultChoice);
65         ui->operationPolicyCB->setProperty("defaultChoice", defaultChoice);
66     }
67 
68     ui->startingBannerCB->clear();
69     ui->endingBannerCB->clear();
70     const QStringList jobSheetsSupported = printer.jobSheetsSupported();
71     for (const QString &value : jobSheetsSupported) {
72         ui->startingBannerCB->addItem(jobSheetsString(value), value);
73         ui->endingBannerCB->addItem(jobSheetsString(value), value);
74     }
75     const QStringList bannerPolicy = printer.jobSheetsDefault();
76     if (bannerPolicy.size() == 2) {
77         defaultChoice = ui->startingBannerCB->findData(bannerPolicy.at(0));
78         ui->startingBannerCB->setCurrentIndex(defaultChoice);
79         ui->startingBannerCB->setProperty("defaultChoice", defaultChoice);
80         defaultChoice = ui->endingBannerCB->findData(bannerPolicy.at(1));
81         ui->endingBannerCB->setCurrentIndex(defaultChoice);
82         ui->endingBannerCB->setProperty("defaultChoice", defaultChoice);
83     }
84 
85     if (!printer.requestingUserNameAllowed().isEmpty()) {
86         QStringList list = printer.requestingUserNameAllowed();
87         list.sort(); // sort the list here to be able to compare it later
88         ui->usersELB->setEnabled(true);
89         if (list != ui->usersELB->items()) {
90             ui->usersELB->clear();
91             ui->usersELB->insertStringList(list);
92         }
93         ui->usersELB->setProperty("defaultList", list);
94         ui->allowRB->setProperty("defaultChoice", true);
95         // Set checked AFTER the default choice was set
96         // otherwise the signal will be emitted
97         // which sets that we have a change
98         ui->allowRB->setChecked(true);
99 
100     } else if (!printer.requestingUserNameDenied().isEmpty()) {
101         QStringList list = printer.requestingUserNameDenied();
102         list.sort(); // sort the list here to be able to compare it later
103         ui->usersELB->setEnabled(true);
104         if (list != ui->usersELB->items()) {
105             ui->usersELB->clear();
106             ui->usersELB->insertStringList(list);
107         }
108         ui->usersELB->setProperty("defaultList", list);
109         ui->allowRB->setProperty("defaultChoice", false);
110         // Set checked AFTER the default choice was set
111         // otherwise the signal will be emitted
112         // which sets that we have a change
113         ui->preventRB->setChecked(true);
114     }
115 
116     // Clear previous changes
117     m_changes = 0;
118     emit changed(false);
119     m_changedValues.clear();
120     ui->errorPolicyCB->setProperty("different", false);
121     ui->operationPolicyCB->setProperty("different", false);
122     ui->startingBannerCB->setProperty("different", false);
123     ui->endingBannerCB->setProperty("different", false);
124     ui->usersELB->setProperty("different", false);
125 }
126 
userListChanged()127 void PrinterBehavior::userListChanged()
128 {
129     if (ui->usersELB->isEnabled() == false &&
130         (ui->allowRB->isChecked() ||
131          ui->preventRB->isChecked())) {
132         // this only happen when the list was empty
133        ui-> usersELB->setEnabled(true);
134     }
135 
136     QStringList currentList = ui->usersELB->items();
137     // sort the list so we can be sure it's different
138     currentList.sort();
139     const QStringList defaultList = ui->usersELB->property("defaultList").toStringList();
140 
141     bool isDifferent = currentList != defaultList;
142     if (isDifferent == false && currentList.isEmpty() == false) {
143         // if the lists are equal and not empty the user might have
144         // changed the Radio Button...
145         if (ui->allowRB->isChecked() != ui->allowRB->property("defaultChoice").toBool()) {
146             isDifferent = true;
147         }
148     }
149 
150     if (isDifferent != ui->usersELB->property("different").toBool()) {
151         // it's different from the last time so add or remove changes
152         isDifferent ? m_changes++ : m_changes--;
153 
154         ui->usersELB->setProperty("different", isDifferent);
155         emit changed(m_changes);
156     }
157 }
158 
currentIndexChangedCB(int index)159 void PrinterBehavior::currentIndexChangedCB(int index)
160 {
161     auto comboBox = qobject_cast<QComboBox*>(sender());
162     bool isDifferent = comboBox->property("defaultChoice").toInt() != index;
163     qCDebug(PM_CONFIGURE_PRINTER) << Q_FUNC_INFO << "isDifferent" << isDifferent << this;
164 
165     if (isDifferent != comboBox->property("different").toBool()) {
166         // it's different from the last time so add or remove changes
167         isDifferent ? m_changes++ : m_changes--;
168 
169         comboBox->setProperty("different", isDifferent);
170         qCDebug(PM_CONFIGURE_PRINTER) << Q_FUNC_INFO << m_changes << this;
171 
172         emit changed(m_changes);
173     }
174 
175     const QString attribute = comboBox->property("AttributeName").toString();
176     QVariant value;
177     // job-sheets-default has always two values
178     if (attribute == QLatin1String("job-sheets-default")) {
179         value = QStringList({
180                                ui->startingBannerCB->itemData(ui->startingBannerCB->currentIndex()).toString(),
181                                 ui->endingBannerCB->itemData(ui->endingBannerCB->currentIndex()).toString()
182                             });
183     } else {
184         value = comboBox->itemData(index).toString();
185     }
186 
187     // store the new values
188     if (isDifferent) {
189         m_changedValues[attribute] = value;
190     } else {
191         m_changedValues.remove(attribute);
192     }
193 }
194 
errorPolicyString(const QString & policy) const195 QString PrinterBehavior::errorPolicyString(const QString &policy) const
196 {
197     // TODO search for others policies of printer-error-policy-supported
198     if (policy == QLatin1String("abort-job")) {
199         return i18n("Abort job");
200     } else if (policy == QLatin1String("retry-current-job")) {
201         return i18n("Retry current job");
202     } else if (policy == QLatin1String("retry-job")) {
203         return i18n("Retry job");
204     } else if (policy == QLatin1String("stop-printer")) {
205         return i18n("Stop printer");
206     }
207     return policy;
208 }
209 
operationPolicyString(const QString & policy) const210 QString PrinterBehavior::operationPolicyString(const QString &policy) const
211 {
212     // TODO search for others policies of printer-error-policy-supported
213     if (policy == QLatin1String("authenticated")) {
214         return i18n("Authenticated");
215     } else if (policy == QLatin1String("default")) {
216         return i18n("Default");
217     }
218     return policy;
219 }
220 
jobSheetsString(const QString & policy) const221 QString PrinterBehavior::jobSheetsString(const QString &policy) const
222 {
223     // TODO search for others policies of printer-error-policy-supported
224     if (policy == QLatin1String("none")) {
225         return i18n("None");
226     } else if (policy == QLatin1String("classified")) {
227         return i18n("Classified");
228     } else if (policy == QLatin1String("confidential")) {
229         return i18n("Confidential");
230     } else if (policy == QLatin1String("secret")) {
231         return i18n("Secret");
232     } else if (policy == QLatin1String("standard")) {
233         return i18n("Standard");
234     } else if (policy == QLatin1String("topsecret")) {
235         return i18n("Topsecret");
236     } else if (policy == QLatin1String("unclassified")) {
237         return i18n("Unclassified");
238     }
239     return policy;
240 }
241 
save()242 void PrinterBehavior::save()
243 {
244     if (m_changes) {
245         QVariantHash changedValues = m_changedValues;
246         // since a QStringList might be big we get it here instead
247         // of adding it at edit time.
248         if (ui->usersELB->property("different").toBool()) {
249             QStringList list = ui->usersELB->items();
250             if (list.isEmpty()) {
251                 list << QLatin1String("all");
252                 changedValues[KCUPS_REQUESTING_USER_NAME_ALLOWED] = list;
253             } else {
254                 if (ui->allowRB->isChecked()) {
255                     changedValues[KCUPS_REQUESTING_USER_NAME_ALLOWED] = list;
256                 } else {
257                     changedValues[KCUPS_REQUESTING_USER_NAME_DENIED] = list;
258                 }
259             }
260         }
261         QPointer<KCupsRequest> request = new KCupsRequest;
262         if (m_isClass) {
263             request->addOrModifyClass(m_destName, changedValues);
264         } else {
265             request->addOrModifyPrinter(m_destName, changedValues);
266         }
267         request->waitTillFinished();
268         if (request) {
269             if (!request->hasError()) {
270                 request->getPrinterAttributes(m_destName, m_isClass, neededValues());
271                 request->waitTillFinished();
272                 if (request && !request->hasError() && !request->printers().isEmpty()){
273                     KCupsPrinter printer = request->printers().first();
274                     setValues(printer);
275                 }
276             }
277             request->deleteLater();
278         }
279     }
280 }
281 
setRemote(bool remote)282 void PrinterBehavior::setRemote(bool remote)
283 {
284     ui->errorPolicyCB->setEnabled(!remote);
285     ui->operationPolicyCB->setEnabled(!remote);
286     ui->startingBannerCB->setEnabled(!remote);
287     ui->endingBannerCB->setEnabled(!remote);
288     ui->allowRB->setEnabled(!remote);
289     ui->preventRB->setEnabled(!remote);
290     ui->usersELB->setEnabled(!remote);
291 }
292 
hasChanges()293 bool PrinterBehavior::hasChanges()
294 {
295     return m_changes;
296 }
297 
neededValues() const298 QStringList PrinterBehavior::neededValues() const
299 {
300     return QStringList({
301                            KCUPS_JOB_SHEETS_DEFAULT,
302                            KCUPS_JOB_SHEETS_SUPPORTED,
303 
304                            KCUPS_PRINTER_ERROR_POLICY,
305                            KCUPS_PRINTER_ERROR_POLICY_SUPPORTED,
306 
307                            KCUPS_PRINTER_OP_POLICY,
308                            KCUPS_PRINTER_OP_POLICY_SUPPORTED,
309 
310                            KCUPS_REQUESTING_USER_NAME_ALLOWED,
311                            KCUPS_REQUESTING_USER_NAME_DENIED
312                        });
313 }
314 
315 #include "moc_PrinterBehavior.cpp"
316