1 /**************************************************************************
2 *   Copyright (C) 2005-2020 by Oleksandr Shneyder                         *
3 *                              <o.shneyder@phoca-gmbh.de>                 *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *   This program is distributed in the hope that it will be useful,       *
10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12 *   GNU General Public License for more details.                          *
13 *                                                                         *
14 *   You should have received a copy of the GNU General Public License     *
15 *   along with this program.  If not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17 
18 #include "cupsprintersettingsdialog.h"
19 #include "cupsprint.h"
20 #include "x2goutils.h"
21 #ifndef Q_OS_WIN
22 #include <QHeaderView>
23 #include <QMessageBox>
24 #include <QTimer>
25 
CUPSPrinterSettingsDialog(QString prnName,CUPSPrint * cupsObject,QWidget * parent,Qt::WindowFlags flags)26 CUPSPrinterSettingsDialog::CUPSPrinterSettingsDialog (
27     QString prnName,
28     CUPSPrint*  cupsObject,
29     QWidget * parent,
30     Qt::WindowFlags flags
31 ) :QDialog ( parent, flags )
32 {
33 	m_cups=cupsObject;
34 	printer=prnName;
35 	ui.setupUi ( this );
36 	setWindowTitle ( prnName );
37 	QList<int> sz;
38 	sz<<250<<100;
39 	ui.splitter->setSizes ( sz );
40 	if ( !m_cups->setCurrentPrinter ( printer ) )
41 	{
42 		//message here
43 		close();
44 	}
45 	setGeneralTab();
46 	setPPDTab();
47 	connect ( ( QObject* ) ( ui.buttonBox->button (
48 	                             QDialogButtonBox::RestoreDefaults ) ),
49 	          SIGNAL ( clicked() ),this,SLOT ( slot_restoreDefaults() ) );
50 	connect ( ( QObject* ) ( ui.buttonBox->button (
51 	                             QDialogButtonBox::Save ) ),
52 	          SIGNAL ( clicked() ),this,SLOT ( slot_saveOptions() ) );
53 	connect ( ( QObject* ) ( ui.buttonBox->button (
54 	                             QDialogButtonBox::Cancel ) ),
55 	          SIGNAL ( clicked() ),this,SLOT ( reject() ) );
56 	connect ( ( QObject* ) ( ui.buttonBox->button (
57 	                             QDialogButtonBox::Ok ) ),
58 	          SIGNAL ( clicked() ),this,SLOT ( slot_ok() ) );
59 }
60 
61 
62 
~CUPSPrinterSettingsDialog()63 CUPSPrinterSettingsDialog::~CUPSPrinterSettingsDialog()
64 {
65 }
66 
67 
68 
setCbBox(QComboBox * cb,QString optionKeyword)69 void CUPSPrinterSettingsDialog::setCbBox ( QComboBox* cb,
70         QString optionKeyword )
71 {
72 	QStringList values;
73 	QStringList descriptions;
74 	int cur_val=m_cups->getOptionValues ( optionKeyword,
75 	                                      values,descriptions );
76 	if ( cur_val==-1 )
77 		cb->setEnabled ( false );
78 	else
79 	{
80 		cb->addItems ( descriptions );
81 		cb->setCurrentIndex ( cur_val );
82 	}
83 }
84 
slot_optionSelected(QTreeWidgetItem * current,QTreeWidgetItem *)85 void CUPSPrinterSettingsDialog::slot_optionSelected ( QTreeWidgetItem * current,
86         QTreeWidgetItem * )
87 {
88 	ui.optionsTree->clear();
89 	if ( current )
90 		if ( current->childCount() ==0 )
91 		{
92 			ui.gbOptions->setTitle ( current->text ( 0 ) );
93 			QStringList valueNames, valueTexts;
94 			int selectedValue=m_cups->
95 			                  getOptionValues (
96 			                      current->text ( 2 ),
97 			                      valueNames,valueTexts );
98 			for ( int i=0;i<valueNames.size();++i )
99 			{
100 				QTreeWidgetItem* ritem=new QTreeWidgetItem (
101 				    ui.optionsTree,
102 				    QTreeWidgetItem::Type ) ;
103 				ritem->setText ( 0,valueTexts[i] );
104 				ritem->setText ( 1,valueNames[i] );
105 				if ( i==selectedValue )
106 					ui.optionsTree->setCurrentItem (
107 					    ritem );
108 			}
109 			return;
110 		}
111 	ui.gbOptions->setTitle ( tr ( "No option selected" ) );
112 }
113 
slot_valueSelected(QTreeWidgetItem * current,QTreeWidgetItem *)114 void CUPSPrinterSettingsDialog::slot_valueSelected ( QTreeWidgetItem * current,
115         QTreeWidgetItem * )
116 {
117 	if ( !current )
118 		return;
119 	QTreeWidgetItem* optionItem=ui.ppdTree->currentItem();
120 	QString option=optionItem->text ( 2 );
121 	QString newVal=current->text ( 1 );
122 	QString prevVal,prevText;
123 	m_cups->getOptionValue ( option,prevVal,prevText );
124 	if ( prevVal==newVal )
125 		return;
126 
127 	//we need change current item
128 	//do it outside this function
129 	setNewValue ( option,newVal ) ;
130 	QTimer::singleShot ( 1, this, SLOT ( slot_reloadValues() ) );
131 
132 	m_cups->getOptionValue ( option,prevVal,prevText );
133 	optionItem->setText ( 1,prevText );
134 	optionItem->setText ( 3,prevVal );
135 	setGeneralTab();
136 }
137 
138 
setGeneralTab()139 void CUPSPrinterSettingsDialog::setGeneralTab()
140 {
141 	disconnect ( ui.cbPageSize,SIGNAL ( currentIndexChanged ( int ) ),
142 	             this,SLOT ( slot_changePSize ( int ) ) );
143 	disconnect ( ui.cbMediaType,SIGNAL ( currentIndexChanged ( int ) ),
144 	             this,SLOT ( slot_changePType ( int ) ) );
145 	disconnect ( ui.cbInputSlot,SIGNAL ( currentIndexChanged ( int ) ),
146 	             this,SLOT ( slot_changeISlot ( int ) ) );
147 	disconnect ( ui.rbNone,SIGNAL ( clicked ( ) ),
148 	             this,SLOT ( slot_changeDuplex() ) );
149 	disconnect ( ui.rbShort,SIGNAL ( clicked ( ) ),
150 	             this,SLOT ( slot_changeDuplex() ) );
151 	disconnect ( ui.rbLong,SIGNAL ( clicked ( ) ),
152 	             this,SLOT ( slot_changeDuplex() ) );
153 	ui.cbPageSize->clear();
154 	ui.cbMediaType->clear();
155 	ui.cbInputSlot->clear();
156 	setCbBox ( ui.cbPageSize,"PageSize" );
157 	setCbBox ( ui.cbMediaType,"MediaType" );
158 	setCbBox ( ui.cbInputSlot,"InputSlot" );
159 	QString valueName, valueText;
160 	ui.rbNone->setChecked ( true );
161 	if ( m_cups->getOptionValue ( "Duplex",valueName,valueText ) )
162 	{
163 		if ( valueName=="DuplexTumble" )
164 			ui.rbShort->setChecked ( true );
165 		if ( valueName=="DuplexNoTumble" )
166 			ui.rbLong->setChecked ( true );
167 
168 	}
169 	else
170 		ui.gbDuplex->setEnabled ( false );
171 	connect ( ui.cbPageSize,SIGNAL ( currentIndexChanged ( int ) ),
172 	          this,SLOT ( slot_changePSize ( int ) ) );
173 	connect ( ui.cbMediaType,SIGNAL ( currentIndexChanged ( int ) ),
174 	          this,SLOT ( slot_changePType ( int ) ) );
175 	connect ( ui.cbInputSlot,SIGNAL ( currentIndexChanged ( int ) ),
176 	          this,SLOT ( slot_changeISlot ( int ) ) );
177 	connect ( ui.rbNone,SIGNAL ( clicked ( ) ),
178 	          this,SLOT ( slot_changeDuplex() ) );
179 	connect ( ui.rbShort,SIGNAL ( clicked ( ) ),
180 	          this,SLOT ( slot_changeDuplex() ) );
181 	connect ( ui.rbLong,SIGNAL ( clicked ( ) ),
182 	          this,SLOT ( slot_changeDuplex() ) );
183 
184 }
185 
186 
setPPDTab()187 void CUPSPrinterSettingsDialog::setPPDTab()
188 {
189 	disconnect ( ui.ppdTree,
190 	             SIGNAL ( currentItemChanged ( QTreeWidgetItem*,
191 	                                           QTreeWidgetItem* ) ),
192 	             this,
193 	             SLOT ( slot_optionSelected ( QTreeWidgetItem*,
194 	                                          QTreeWidgetItem* ) ) );
195 
196 	disconnect ( ui.optionsTree,
197 	             SIGNAL ( currentItemChanged ( QTreeWidgetItem*,
198 	                                           QTreeWidgetItem* ) ),
199 	             this,
200 	             SLOT ( slot_valueSelected ( QTreeWidgetItem*,
201 	                                         QTreeWidgetItem* ) ) );
202 
203 	QString info;
204 	bool acceptJobs;
205 	QString location;
206 	QString model;
207 	CUPSPrint::printState state;
208 	QString stateReason;
209 	QString valueName,valueText;
210 	UNUSED (m_cups->getPrinterInfo (printer,
211 	                                info, acceptJobs,
212 	                                location, model, state, stateReason));
213 
214 
215 	ui.ppdTree->clear();
216 	QTreeWidgetItem* ritem=new QTreeWidgetItem ( ( QTreeWidgetItem* ) 0,
217 	        QTreeWidgetItem::Type ) ;
218 
219 	ritem->setText ( 0,model );
220 	ui.ppdTree->addTopLevelItem ( ritem );
221 	QStringList grName, grText;
222 	m_cups->getOptionGroups ( grName,grText );
223 	for ( int i=0;i<grName.size();++i )
224 	{
225 		QTreeWidgetItem* gritem=new QTreeWidgetItem ( ritem,
226 		        QTreeWidgetItem::Type ) ;
227 		gritem->setText ( 0,grText[i] );
228 		gritem->setText ( 2,grName[i] );
229 		QStringList optName, optText;
230 		m_cups->getOptionsList ( grName[i],optName,optText );
231 		for ( int j=0;j<optName.size();++j )
232 		{
233 			QTreeWidgetItem* optitem=new QTreeWidgetItem ( gritem,
234 			        QTreeWidgetItem::Type ) ;
235 			optitem->setText ( 0,optText[j] );
236 			optitem->setText ( 2,optName[j] );
237 			m_cups->getOptionValue ( optName[j],valueName,
238 			                         valueText );
239 			optitem->setText ( 1,valueText );
240 			optitem->setText ( 3,valueName );
241 		}
242 
243 	}
244 	ui.ppdTree->expandAll();
245 	ui.ppdTree->header()->resizeSections ( QHeaderView::ResizeToContents );
246 	slot_optionSelected ( ritem,0l );
247 	connect ( ui.ppdTree,
248 	          SIGNAL ( currentItemChanged ( QTreeWidgetItem*,
249 	                                        QTreeWidgetItem* ) ),
250 	          this,
251 	          SLOT ( slot_optionSelected ( QTreeWidgetItem*,
252 	                                       QTreeWidgetItem* ) ) );
253 
254 	connect ( ui.optionsTree,
255 	          SIGNAL ( currentItemChanged ( QTreeWidgetItem*,
256 	                                        QTreeWidgetItem* ) ),
257 	          this,
258 	          SLOT ( slot_valueSelected ( QTreeWidgetItem*,
259 	                                      QTreeWidgetItem* ) ) );
260 
261 }
262 
263 
setNewValue(const QString & option,const QString & value)264 bool CUPSPrinterSettingsDialog::setNewValue ( const QString& option,
265         const QString& value )
266 {
267 	QString confVal,confOpt;
268 	bool res=m_cups->setValue ( option,value,confOpt,confVal );
269 	if ( !res )
270 	{
271 		QString textMessage=
272 		    tr ( "This value is in conflict with another option." );
273 		QString txt;
274 		m_cups->getOptionText ( confOpt,txt );
275 		QString val,valt;
276 		m_cups->getOptionValue ( confOpt,val,valt );
277 		if ( confOpt.length() >0 &&confVal.length() >0 )
278 		{
279 			textMessage+="\n("+txt+" : "+valt+")";
280 
281 		}
282 		QMessageBox::critical ( this,tr ( "Options conflict." ),
283 		                        textMessage );
284 	}
285 	return res;
286 }
287 
288 
slot_reloadValues()289 void CUPSPrinterSettingsDialog::slot_reloadValues()
290 {
291 	if ( ui.ppdTree->currentItem() )
292 		slot_optionSelected ( ui.ppdTree->currentItem(),0l );
293 	QTreeWidgetItemIterator it ( ui.ppdTree );
294 	while ( *it )
295 	{
296 		if ( ( *it )->childCount() ==0 )
297 		{
298 			QString opt= ( *it )->text ( 2 );
299 			QString nval,ntext;
300 			m_cups->getOptionValue ( opt,nval,ntext );
301 			if ( ( *it )->text ( 3 ) != nval )
302 				( *it )->setText ( 1,ntext );
303 			( *it )->setText ( 3,nval );
304 		}
305 		++it;
306 	}
307 }
308 
309 
slot_changePSize(int ind)310 void CUPSPrinterSettingsDialog::slot_changePSize ( int ind )
311 {
312 	changeFromCbBox ( "PageSize",ind );
313 
314 }
315 
slot_changePType(int ind)316 void CUPSPrinterSettingsDialog::slot_changePType ( int ind )
317 {
318 	changeFromCbBox ( "MediaType",ind );
319 }
320 
slot_changeISlot(int ind)321 void CUPSPrinterSettingsDialog::slot_changeISlot ( int ind )
322 {
323 	changeFromCbBox ( "InputSlot",ind );
324 }
325 
changeFromCbBox(const QString & opt,int id)326 void CUPSPrinterSettingsDialog::changeFromCbBox ( const QString& opt, int id )
327 {
328 	QStringList vals,texts;
329 	m_cups->getOptionValues ( opt,vals,texts );
330 	if ( vals.size() <id )
331 		return;
332 	changeGeneralOption ( opt,vals[id] );
333 }
334 
slot_changeDuplex()335 void CUPSPrinterSettingsDialog::slot_changeDuplex()
336 {
337 	if ( ui.rbShort->isChecked() )
338 	{
339 		changeGeneralOption ( "Duplex","DuplexTumble" );
340 	}
341 	if ( ui.rbLong->isChecked() )
342 	{
343 		changeGeneralOption ( "Duplex","DuplexNoTumble" );
344 	}
345 	if ( ui.rbNone->isChecked() )
346 	{
347 		changeGeneralOption ( "Duplex","None" );
348 	}
349 }
350 
changeGeneralOption(const QString & option,const QString & val)351 void CUPSPrinterSettingsDialog::changeGeneralOption ( const QString&  option,
352         const QString& val )
353 {
354 	if ( !setNewValue ( option,val ) )
355 		QTimer::singleShot ( 1, this, SLOT ( setGeneralTab() ) );
356 	slot_reloadValues();
357 }
358 
slot_restoreDefaults()359 void CUPSPrinterSettingsDialog::slot_restoreDefaults()
360 {
361 	m_cups->setDefaults();
362 	setGeneralTab();
363 	slot_reloadValues();
364 }
365 
slot_saveOptions()366 void CUPSPrinterSettingsDialog::slot_saveOptions()
367 {
368 	m_cups->saveOptions();
369 }
370 
slot_ok()371 void CUPSPrinterSettingsDialog::slot_ok()
372 {
373 	m_cups->saveOptions();
374 	accept();
375 }
376 
377 #endif
378