summaryrefslogtreecommitdiffstats
path: root/kdeprint/kprintdialog.cpp
blob: 3570393bbbda81dfc6eec9bea8c86c2da2fd5e54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
/*
 *  This file is part of the KDE libraries
 *  Copyright (c) 2001 Michael Goffioul <kdeprint@swing.be>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License version 2 as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 **/

/*
 *  "WhatsThis" help items added by Kurt Pfeifle, August 2003,
 *  same copyright as above.
 **/

#include "kprintdialog.h"
#include "kprinter.h"
#include "kprinterimpl.h"
#include "kmfactory.h"
#include "kmuimanager.h"
#include "kmmanager.h"
#include "kmprinter.h"
#include "kmvirtualmanager.h"
#include "kprintdialogpage.h"
#include "kprinterpropertydialog.h"
#include "plugincombobox.h"
#include "kpcopiespage.h"
#include "treecombobox.h"
#include "messagewindow.h"

#include <qgroupbox.h>
#include <qcheckbox.h>
#include <kpushbutton.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <qtabwidget.h>
#include <qvbox.h>
#include <qlayout.h>
#include <qregexp.h>
#include <kmessagebox.h>
#include <qdir.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <klocale.h>
#include <kiconloader.h>
#include <kfiledialog.h>
#include <kurlrequester.h>
#include <klineedit.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kconfig.h>
#include <kguiitem.h>
#include <kstdguiitem.h>
#include <kapplication.h>
#include <kio/renamedlg.h>

#include <time.h>

#define	SHOWHIDE(widget,on)	if (on) widget->show(); else widget->hide();

class KPrintDialog::KPrintDialogPrivate
{
public:
	QLabel	*m_type, *m_state, *m_comment, *m_location, *m_cmdlabel, *m_filelabel;
	KPushButton	*m_properties, *m_default, *m_options, *m_ok, *m_extbtn;
	QPushButton	*m_wizard, *m_filter;
	QCheckBox	*m_preview;
	QLineEdit	*m_cmd;
	TreeComboBox	*m_printers;
	QVBox		*m_dummy;
	PluginComboBox	*m_plugin;
	KURLRequester	*m_file;
	QCheckBox	*m_persistent;
	bool	m_reduced;

	QPtrList<KPrintDialogPage>	m_pages;
	KPrinter		*m_printer;
	bool b_optionsEnabled;
	bool b_propertiesEnabled;
	bool b_systemEnabled;
};

KPrintDialog::KPrintDialog(QWidget *parent, const char *name)
: KDialog(parent,name,true)
{
	//WhatsThis strings.... (added by pfeifle@kde.org)
	QString whatsThisLocationLabel = i18n(  " <qt><b>Printer Location:</b> The <em>Location</em> may describe where the"
						" selected printer is located. The Location description is created"
						" by the administrator of the print system (or may be"
						" left empty)."
						" </qt>" );
	QString whatsThisPrinterType = i18n(    " <qt><b>Printer Type:</b>  The <em>Type</em> indicates your printer type."
						" </qt>" );
	QString whatsThisPrinterState = i18n(   " <qt><b>Printer State:</b>  The <em>State</em> indicates the state of the"
						" print queue on the print server (which could be your localhost). The"
						" state may be 'Idle', 'Processing', 'Stopped', 'Paused' or similar."
						" </qt>" );
	QString whatsThisPrinterComment = i18n( " <qt><b>Printer Comment:</b>  The <em>Comment</em> may describe the selected"
						" printer. This comment is created by the administrator"
						" of the print system (or may be left empty)."
						" </qt>" );
	QString whatsThisPrinterSelect = i18n(  " <qt><b>Printer Selection Menu:</b> "
						" <p>Use this combo box to select the printer to which you want to print."
						" Initially (if you run KDEPrint for the first time), you may only find the "
						"  <em>KDE special printers</em> (which save"
						" jobs to disk [as PostScript- or PDF-files], or deliver jobs via"
						" email (as a PDF"
						" attachment). If you are missing a real printer, you need to..."
						" <ul>"
						" <li>...either create a local printer with the help of the <em>KDE Add"
						" Printer Wizard</em>. The Wizard is available for the CUPS and RLPR printing"
						" systems (click button to the left of the <em>'Properties'</em> button),</li>"
						" <li>...or try to connect to an existing remote"
						" CUPS print server. You can connect by clicking the <em>'System Options'</em> button"
						" below. A new dialog opens: click on the <em>'CUPS server'</em>"
						" icon: Fill in the information required to use the remote"
						" server. </li> "
						" </ul>"
						" <p><b>Note:</b> It may happen that you successfully connected to a remote CUPS "
						" server and still do not get a printer list. If this happens: force KDEPrint to "
						" re-load its configuration files."
						" To reload the configuration files, either start kprinter again, or use the "
						" switch the print system away from CUPS and back again once. The print system switch "
						" can be made through a selection in the drop-down menu at bottom of this dialog when "
						" fully expanded). </p> "
						" </qt>" );
	QString whatsThisPrintJobProperties = i18n( " <qt><b>Print Job Properties:</b> "
						" <p>This button opens a dialog where you can make decisions"
						" regarding all supported print job options."
						" </qt>" );
	QString whatsThisPrinterFilter = i18n(  " <qt><b>Selective View on List of Printers:</b>"
						" <p> This button reduces the list of visible printers"
						" to a shorter, more convenient, pre-defined list.</p>"
						" <p>This is particularly useful in enterprise environments"
						" with lots of printers. The default is to show <b>all</b> printers.</p>"
						" <p>To create a personal <em>'selective view list'</em>, click on the"
						" <em>'System Options'</em> button at the bottom of this dialog."
						" Then, in the new dialog, select <em>'Filter'</em> (left column in the"
						" <em>KDE Print Configuration</em> dialog) and setup your selection..</p>"
						" <p><b>Warning:</b> Clicking this button without prior creation of a personal "
						" <em>'selective view list'</em> will make all printers dissappear from the "
						" view. (To re-enable all printers, just click this button again.) </p> "
						" </qt>" );
	QString whatsThisAddPrinterWizard = i18n( "<qt><b>KDE Add Printer Wizard</b>"
						" <p>This button starts the <em>KDE Add Printer Wizard</em>.</p>"
						" <p>Use the Wizard (with <em>\"CUPS\"</em> or <em>\"RLPR\"</em>) to add locally"
						" defined printers to your system. </p>"
						" <p><b>Note:</b> The <em>KDE Add Printer Wizard</em> does <b>not</b> work, "
						" and this button is disabled if you use "
						" <em>\"Generic LPD</em>\", <em>\"LPRng\"</em>, or <em>\"Print Through "
						" an External Program</em>\".) </p> " 
						" </qt>" );
	QString whatsThisExternalPrintCommand = i18n( " <qt><b>External Print Command</b>"
						" <p>Here you can enter any command that would also print for you in "
						" a <em>konsole</em> window. </p>"
						" <b>Example:</b> <pre>a2ps -P &lt;printername&gt; --medium=A3</pre>."
						" </qt>" );
	QString whatsThisOptions = i18n( " <qt><b>Additional Print Job Options</b>"
						" <p>This button shows or hides additional printing options.</qt>" );
	QString whatsThisSystemOptions = i18n(  " <qt><b>System Options:</b> "
						" <p>This button starts a new dialog where you can adjust various"
  						" settings of your printing system. Amongst them:"
						" <ul><li> Should KDE"
						" applications embed all fonts into the PostScript they"
 						" generate for printing?"
						" <li> Should KDE use an external PostScript viewer"
						" like <em>gv</em> for print page previews?"
						" <li> Should KDEPrint use a local or a remote CUPS server?,"
						" </ul> and many more.... "
					        " </qt>" );

	QString whatsThisHelpButton = i18n(     " <qt><b>Help:</b> This button takes you to the complete <em>KDEPrint"
						" Manual</em>."
					        " </qt>" );

	QString whatsThisCancelButton = i18n(   " <qt><b>Cancel:</b> This button cancels your print job and quits the"
						" kprinter dialog."
					        " </qt>" );

	QString whatsThisPrintButton = i18n(    " <qt><b>Print:</b> This button sends the job to the printing process."
						" If you are sending non-PostScript files, you may be"
						" asked if you want KDE to convert the files into PostScript,"
						" or if you want your print subsystem (like CUPS) to do this."
					        " </qt>" );

	QString whatsThisKeepDialogOpenCheckbox = i18n( " <qt><b>Keep Printing Dialog Open</b>"
						"<p>If you enable this checkbox, the printing dialog"
						" stays open after you hit the <em>Print</em> button.</p>"
						" <p> This is"
						" especially useful, if you need to test various"
						" print settings (like color matching for an inkjet printer)"
						" or if you want to send your job to multiple printers (one after"
						" the other) to have it finished more quickly.</p>"
					        " </qt>" );

	QString whatsThisOutputFileLabel = i18n(" <qt><b>Output File Name and Path:</b> The \"Output file:\" shows "
						" you where your file will be"
						" saved if you decide to \"Print to File\" your job, using one of the"
						" KDE <em>Special Printers</em> named \"Print to File (PostScript)\""
						" or \"Print to File (PDF)\". Choose a name and location that suits"
						" your need by using the button and/or editing the line on the right."
					        " </qt>" );

	QString whatsThisOutputFileLineedit = i18n(" <qt><b>Output File Name and Path:</b> Edit this line to create a "
						" path and filename that suits your needs." 
						" (Button and Lineedit field are only available if you \"Print to File\")"
					        " </qt>" );

	QString whatsThisOutputFileButton = i18n(" <qt><b>Browse Directories button:<b> This button calls "
						" the \"File Open / Browsed Directories\" dialog to let you"
						" choose a directory and file name where your \"Print-to-File\""
						" job should be saved."
					        " </qt>" );

	QString whatsThisAddFileButton = i18n(  " <qt><b>Add File to Job</b>"
						" <p>This button calls the \"File Open / Browse Directories\" dialog to allow you"
						" to select a file for printing. Note, that "
						" <ul><li>you can select ASCII or International Text, PDF,"
						" PostScript, JPEG, TIFF, PNG, GIF and many other graphical"
						" formats."
						" <li>you can select various files from different paths"
						" and send them as one \"multi-file job\" to the printing"
						" system."
						" </ul>"
					        " </qt>" );

	QString whatsThisPreviewCheckBox = i18n(" <qt><b>Print Preview</b>"
						" Enable this checkbox if you want to see a preview of"
						" your printout. A preview lets you check if, for instance,"
 						" your intended \"poster\" or \"pamphlet\" layout"
						" looks like you expected, without wasting paper first. It"
						" also lets you cancel the job if something looks wrong. "
						" <p><b>Note:</b> The preview feature (and therefore this checkbox) "
						" is only visible for printjobs created from inside KDE applications. "
						" If you start kprinter from the commandline, or if you use kprinter "
						" as a print command for non-KDE applications (like Acrobat Reader, "
                                                " Firefox or OpenOffice), print preview is not available here. "
					        " </qt>" );

	QString whatsThisSetDefaultPrinter = i18n(" <qt><b>Set as Default Printer</b>"
						" This button sets the current printer as the user's"
						" default. "
						" <p><b>Note:</b> (Button is only visible if the checkbox for "
						" <em>System Options</em>"
						" --> <em>General</em> --> <em>Miscellaneous</em>: <em>\"Defaults"
						" to the last printer used in the application\"</em> is disabled.)"
					        " </qt>" );
	d = new KPrintDialogPrivate;

	d->m_pages.setAutoDelete(false);
	d->m_printer = 0;
	setCaption(i18n("Print"));

	// widget creation
	QGroupBox	*m_pbox = new QGroupBox(0,Qt::Vertical,i18n("Printer"), this);
	d->m_type = new QLabel(m_pbox);
	QWhatsThis::add(d->m_type, whatsThisPrinterType);
	d->m_state = new QLabel(m_pbox);
	QWhatsThis::add(d->m_state, whatsThisPrinterState);
	d->m_comment = new QLabel(m_pbox);
	QWhatsThis::add(d->m_comment, whatsThisPrinterComment);
	d->m_location = new QLabel(m_pbox);
	QWhatsThis::add(d->m_location, whatsThisLocationLabel);

	d->m_printers = new TreeComboBox(m_pbox);
	QWhatsThis::add(d->m_printers, whatsThisPrinterSelect);
	d->m_printers->setMinimumHeight(25);
	QLabel	*m_printerlabel = new QLabel(i18n("&Name:"), m_pbox);
	QWhatsThis::add(m_printerlabel, whatsThisPrinterSelect);
	QLabel	*m_statelabel = new QLabel(i18n("Status", "State:"), m_pbox);
	QWhatsThis::add(m_statelabel, whatsThisPrinterState);
	QLabel	*m_typelabel = new QLabel(i18n("Type:"), m_pbox);
	QWhatsThis::add(m_typelabel, whatsThisPrinterType);
	QLabel	*m_locationlabel = new QLabel(i18n("Location:"), m_pbox);
	QWhatsThis::add(m_locationlabel, whatsThisLocationLabel);
	QLabel	*m_commentlabel = new QLabel(i18n("Comment:"), m_pbox);
	QWhatsThis::add(m_commentlabel, whatsThisPrinterComment);
	m_printerlabel->setBuddy(d->m_printers);
	d->m_properties = new KPushButton(KGuiItem(i18n("P&roperties"), "edit"), m_pbox);
	QWhatsThis::add( d->m_properties, whatsThisPrintJobProperties);
	d->m_options = new KPushButton(KGuiItem(i18n("System Op&tions"), "kdeprint_configmgr"), this);
	QWhatsThis::add(d->m_options,whatsThisSystemOptions);
	d->m_default = new KPushButton(KGuiItem(i18n("Set as &Default"), "kdeprint_defaultsoft"), m_pbox);
	QWhatsThis::add(d->m_default,whatsThisSetDefaultPrinter);
	d->m_filter = new QPushButton(m_pbox);
	d->m_filter->setPixmap(SmallIcon("filter"));
	d->m_filter->setMinimumSize(QSize(d->m_printers->minimumHeight(),d->m_printers->minimumHeight()));
	d->m_filter->setToggleButton(true);
	d->m_filter->setOn(KMManager::self()->isFilterEnabled());
	QToolTip::add(d->m_filter, i18n("Toggle selective view on printer list"));
	QWhatsThis::add(d->m_filter, whatsThisPrinterFilter);
	d->m_wizard = new QPushButton(m_pbox);
	d->m_wizard->setPixmap(SmallIcon("wizard"));
	d->m_wizard->setMinimumSize(QSize(d->m_printers->minimumHeight(),d->m_printers->minimumHeight()));
	QToolTip::add(d->m_wizard, i18n("Add printer..."));
	QWhatsThis::add(d->m_wizard, whatsThisAddPrinterWizard);
	d->m_ok = new KPushButton(KGuiItem(i18n("&Print"), "fileprint"), this);
        QWhatsThis::add( d->m_ok, whatsThisPrintButton);
	d->m_ok->setDefault(true);
	d->m_ok->setEnabled( false );
	QPushButton	*m_cancel = new KPushButton(KStdGuiItem::cancel(), this);
        QWhatsThis::add(m_cancel, whatsThisCancelButton);
	d->m_preview = new QCheckBox(i18n("Previe&w"), m_pbox);
	QWhatsThis::add(d->m_preview, whatsThisPreviewCheckBox);
	d->m_filelabel = new QLabel(i18n("O&utput file:"), m_pbox);
	QWhatsThis::add(d->m_filelabel,whatsThisOutputFileLabel);
	d->m_file = new KURLRequester(QDir::homeDirPath()+"/print.ps", m_pbox);
	QWhatsThis::add(d->m_file,whatsThisOutputFileLineedit);
	d->m_file->setEnabled(false);
	d->m_filelabel->setBuddy(d->m_file);
	d->m_cmdlabel = new QLabel(i18n("Print co&mmand:"), m_pbox);
        QWhatsThis::add( d->m_cmdlabel, whatsThisExternalPrintCommand);

	d->m_cmd = new QLineEdit(m_pbox);
        QWhatsThis::add( d->m_cmd, whatsThisExternalPrintCommand);
	d->m_cmdlabel->setBuddy(d->m_cmd);
	d->m_dummy = new QVBox(this);
	d->m_plugin = new PluginComboBox(this);
	d->m_extbtn = new KPushButton(this);
	QToolTip::add(d->m_extbtn, i18n("Show/hide advanced options"));
	QWhatsThis::add(d->m_extbtn, whatsThisOptions);
	d->m_persistent = new QCheckBox(i18n("&Keep this dialog open after printing"), this);
        QWhatsThis::add( d->m_persistent, whatsThisKeepDialogOpenCheckbox);
	QPushButton	*m_help = new KPushButton(KStdGuiItem::help(), this);
        QWhatsThis::add( m_help, whatsThisHelpButton);

	QWidget::setTabOrder( d->m_printers, d->m_filter );
	QWidget::setTabOrder( d->m_filter, d->m_wizard );
	QWidget::setTabOrder( d->m_wizard, d->m_properties );
	QWidget::setTabOrder( d->m_properties, d->m_preview );
	QWidget::setTabOrder( d->m_preview, d->m_file );
	QWidget::setTabOrder( d->m_file, d->m_cmd );
	QWidget::setTabOrder( d->m_plugin, d->m_persistent );
	QWidget::setTabOrder( d->m_persistent, d->m_extbtn );
	QWidget::setTabOrder( d->m_extbtn, d->m_options );
	QWidget::setTabOrder( d->m_options, m_help );
	QWidget::setTabOrder( m_help, d->m_ok );
	QWidget::setTabOrder( d->m_ok, m_cancel );

	// layout creation
	QVBoxLayout	*l1 = new QVBoxLayout(this, 10, 10);
	l1->addWidget(m_pbox,0);
	l1->addWidget(d->m_dummy,1);
	l1->addWidget(d->m_plugin,0);
	l1->addWidget(d->m_persistent);
	QHBoxLayout	*l2 = new QHBoxLayout(0, 0, 10);
	l1->addLayout(l2);
	l2->addWidget(d->m_extbtn,0);
	l2->addWidget(d->m_options,0);
	l2->addWidget(m_help,0);
	l2->addStretch(1);
	l2->addWidget(d->m_ok,0);
	l2->addWidget(m_cancel,0);
	QGridLayout	*l3 = new QGridLayout(m_pbox->layout(),3,3,7);
	l3->setColStretch(1,1);
	l3->setRowStretch(0,1);
	QGridLayout	*l4 = new QGridLayout(0, 5, 2, 0, 5);
	l3->addMultiCellLayout(l4,0,0,0,1);
	l4->addWidget(m_printerlabel,0,0);
	l4->addWidget(m_statelabel,1,0);
	l4->addWidget(m_typelabel,2,0);
	l4->addWidget(m_locationlabel,3,0);
	l4->addWidget(m_commentlabel,4,0);
	QHBoxLayout	*ll4 = new QHBoxLayout(0, 0, 3);
	l4->addLayout(ll4,0,1);
	ll4->addWidget(d->m_printers,1);
	ll4->addWidget(d->m_filter,0);
	ll4->addWidget(d->m_wizard,0);
	//l4->addWidget(d->m_printers,0,1);
	l4->addWidget(d->m_state,1,1);
	l4->addWidget(d->m_type,2,1);
	l4->addWidget(d->m_location,3,1);
	l4->addWidget(d->m_comment,4,1);
	l4->setColStretch(1,1);
	QVBoxLayout	*l5 = new QVBoxLayout(0, 0, 10);
	l3->addLayout(l5,0,2);
	l5->addWidget(d->m_properties,0);
	l5->addWidget(d->m_default,0);
	l5->addWidget(d->m_preview,0);
	l5->addStretch(1);
	//***
	l3->addWidget(d->m_filelabel,1,0);
	l3->addWidget(d->m_file,1,1);
	//***
	l3->addWidget(d->m_cmdlabel,2,0);
	l3->addMultiCellWidget(d->m_cmd,2,2,1,2);

	// connections
	connect(d->m_ok,SIGNAL(clicked()),SLOT(accept()));
	connect(m_cancel,SIGNAL(clicked()),SLOT(reject()));
	connect(d->m_properties,SIGNAL(clicked()),SLOT(slotProperties()));
	connect(d->m_default,SIGNAL(clicked()),SLOT(slotSetDefault()));
	connect(d->m_printers,SIGNAL(activated(int)),SLOT(slotPrinterSelected(int)));
	connect(d->m_options,SIGNAL(clicked()),SLOT(slotOptions()));
	connect(d->m_wizard,SIGNAL(clicked()),SLOT(slotWizard()));
	connect(d->m_extbtn, SIGNAL(clicked()), SLOT(slotExtensionClicked()));
	connect(d->m_filter, SIGNAL(toggled(bool)), SLOT(slotToggleFilter(bool)));
	connect(m_help, SIGNAL(clicked()), SLOT(slotHelp()));
	connect(d->m_file, SIGNAL(urlSelected(const QString&)), SLOT(slotOutputFileSelected(const QString&)));
	connect( d->m_file, SIGNAL( openFileDialog( KURLRequester* ) ), SLOT( slotOpenFileDialog() ) );
	connect( KMFactory::self()->manager(), SIGNAL( updatePossible( bool ) ), SLOT( slotUpdatePossible( bool ) ) );

	d->b_optionsEnabled = kapp->authorize("print/options") && kapp->authorize("print/selection");
	d->b_propertiesEnabled = kapp->authorize("print/properties") && kapp->authorize("print/selection");
	d->b_systemEnabled = kapp->authorize("print/system") && kapp->authorize("print/selection");
	                
	if (!d->b_systemEnabled)
	{
		d->m_plugin->hide();
	}

	if (!d->b_optionsEnabled)
	{
		d->m_options->hide();
	}
	
	if (!d->b_propertiesEnabled)
	{
		d->m_properties->hide();
		d->m_wizard->hide();
	}

	if (!kapp->authorize("print/selection"))
	{
		d->m_extbtn->hide();
		m_pbox->hide();

		expandDialog(true);
	}
	else
	{
		KConfig	*config = KGlobal::config();
		config->setGroup("KPrinter Settings");
		expandDialog(!config->readBoolEntry("DialogReduced", (KMFactory::self()->settings()->application != KPrinter::StandAlone)));
	}
}

KPrintDialog::~KPrintDialog()
{
	KConfig	*config = KGlobal::config();
	config->setGroup("KPrinter Settings");
	config->writeEntry("DialogReduced", d->m_reduced);

	delete d;
}

void KPrintDialog::setFlags(int f)
{
	SHOWHIDE(d->m_properties, (f & KMUiManager::Properties) && d->b_propertiesEnabled)
	d->m_default->hide();
	SHOWHIDE(d->m_default, ((f & KMUiManager::Default) && !KMFactory::self()->printConfig("General")->readBoolEntry("UseLast", true)))
	SHOWHIDE(d->m_preview, (f & KMUiManager::Preview))
	bool	on = (f & KMUiManager::OutputToFile);
	SHOWHIDE(d->m_filelabel, on)
	SHOWHIDE(d->m_file, on)
	on = (f & KMUiManager::PrintCommand);
	SHOWHIDE(d->m_cmdlabel, on)
	SHOWHIDE(d->m_cmd, on)
	SHOWHIDE(d->m_persistent, (f & KMUiManager::Persistent))

	// also update "wizard" button
	KMManager	*mgr = KMFactory::self()->manager();
	d->m_wizard->setEnabled((mgr->hasManagement() && (mgr->printerOperationMask() & KMManager::PrinterCreation)));
}

void KPrintDialog::setDialogPages(QPtrList<KPrintDialogPage> *pages)
{
	if (!pages) return;
	if (pages->count() + d->m_pages.count() == 1)
	{
		// only one page, reparent the page to d->m_dummy and remove any
		// QTabWidget child if any.
		if (pages->count() > 0)
			d->m_pages.append(pages->take(0));
		d->m_pages.first()->reparent(d->m_dummy, QPoint(0,0));
		d->m_pages.first()->show();
		delete d->m_dummy->child("TabWidget", "QTabWidget");
	}
	else
	{
		// more than one page.
		QTabWidget	*tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
		if (!tabs)
		{
			// QTabWidget doesn't exist. Create it and reparent all
			// already existing pages.
			tabs = new QTabWidget(d->m_dummy, "TabWidget");
			tabs->setMargin(10);
			for (d->m_pages.first(); d->m_pages.current(); d->m_pages.next())
			{
				tabs->addTab(d->m_pages.current(), d->m_pages.current()->title());
			}
		}
		while (pages->count() > 0)
		{
			KPrintDialogPage	*page = pages->take(0);
			d->m_pages.append(page);
			tabs->addTab(page, page->title());
		}
		tabs->show();
	}
	d->m_extbtn->setEnabled(d->m_pages.count() > 0);
}

KPrintDialog* KPrintDialog::printerDialog(KPrinter *printer, QWidget *parent, const QString& caption, bool forceExpand)
{
	if (printer)
	{
		KPrintDialog	*dlg = new KPrintDialog(parent);
		// needs to set the printer before setting up the
		// print dialog as some additional pages may need it.
		// Real initialization comes after.
		dlg->d->m_printer = printer;
		KMFactory::self()->uiManager()->setupPrintDialog(dlg);
		dlg->init();
		if (!caption.isEmpty())
			dlg->setCaption(caption);
		if (forceExpand)
		{
			// we force the dialog to be expanded:
			//	- expand the dialog
			//	- hide the show/hide button
			dlg->expandDialog(true);
			dlg->d->m_extbtn->hide();
		}
		return dlg;
	}
	return NULL;
}

void KPrintDialog::initialize(KPrinter *printer)
{
	d->m_printer = printer;

	// first retrieve printer list and update combo box (get default or last used printer also)
	QPtrList<KMPrinter>	*plist = KMFactory::self()->manager()->printerList();
	if (!KMManager::self()->errorMsg().isEmpty())
	{
		KMessageBox::error(parentWidget(),
			"<qt><nobr>"+
			i18n("An error occurred while retrieving the printer list:")
			+"</nobr><br><br>"+KMManager::self()->errorMsg()+"</qt>");
	}

	if (plist)
	{
		QString	oldP = d->m_printers->currentText();
		d->m_printers->clear();
		QPtrListIterator<KMPrinter>	it(*plist);
		int 	defsoft(-1), defhard(-1), defsearch(-1);
		bool	sep(false);
		for (;it.current();++it)
		{
			// skip invalid printers
			if ( !it.current()->isValid() )
				continue;

			if (!sep && it.current()->isSpecial())
			{
				sep = true;
				d->m_printers->insertItem(QPixmap(), QString::fromLatin1("--------"));
			}
			d->m_printers->insertItem(SmallIcon(it.current()->pixmap(),0,(it.current()->isValid() ? (int)KIcon::DefaultState : (int)KIcon::LockOverlay)),it.current()->name(),false/*sep*/);
			if (it.current()->isSoftDefault())
				defsoft = d->m_printers->count()-1;
			if (it.current()->isHardDefault())
				defhard = d->m_printers->count()-1;
			if (!oldP.isEmpty() && oldP == it.current()->name())
				defsearch = d->m_printers->count()-1;
			else if (defsearch == -1 && it.current()->name() == printer->searchName())
				defsearch = d->m_printers->count()-1;
		}
		int	defindex = (defsearch != -1 ? defsearch : (defsoft != -1 ? defsoft : QMAX(defhard,0)));
		d->m_printers->setCurrentItem(defindex);
		//slotPrinterSelected(defindex);
	}

	// Initialize output filename
	if (!d->m_printer->outputFileName().isEmpty())
		d->m_file->setURL( d->m_printer->outputFileName() );
	else if (!d->m_printer->docFileName().isEmpty())
		d->m_file->setURL( d->m_printer->docDirectory()+"/"+d->m_printer->docFileName()+".ps" );

	if ( d->m_printers->count() > 0 )
		slotPrinterSelected( d->m_printers->currentItem() );

	// update with KPrinter options
	if (d->m_printer->option("kde-preview") == "1" || d->m_printer->previewOnly())
		d->m_preview->setChecked(true);
	d->m_preview->setEnabled(!d->m_printer->previewOnly());
	d->m_cmd->setText(d->m_printer->option("kde-printcommand"));
	QPtrListIterator<KPrintDialogPage>	it(d->m_pages);
	for (;it.current();++it)
		it.current()->setOptions(d->m_printer->options());
}

void KPrintDialog::slotPrinterSelected(int index)
{
	bool 	ok(false);
	d->m_location->setText(QString::null);
	d->m_state->setText(QString::null);
	d->m_comment->setText(QString::null);
	d->m_type->setText(QString::null);
	if (index >= 0 && index < d->m_printers->count())
	{
		KMManager	*mgr = KMFactory::self()->manager();
		KMPrinter	*p = mgr->findPrinter(d->m_printers->text(index));
		if (p)
		{
			if (!p->isSpecial()) mgr->completePrinterShort(p);
			d->m_location->setText(p->location());
			d->m_comment->setText(p->driverInfo());
			d->m_type->setText(p->description());
			d->m_state->setText(p->stateString());
			ok = p->isValid();
			enableSpecial(p->isSpecial());
			enableOutputFile(p->option("kde-special-file") == "1");
			setOutputFileExtension(p->option("kde-special-extension"));
		}
                else
                    enableOutputFile( ok );
	}
	d->m_properties->setEnabled(ok);
	d->m_ok->setEnabled(ok);
}

void KPrintDialog::slotProperties()
{
	if (!d->m_printer) return;

	KMPrinter	*prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
	if (prt)
		KPrinterPropertyDialog::setupPrinter(prt, this);
}

void KPrintDialog::slotSetDefault()
{
	KMPrinter	*p = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
	if (p)
		KMFactory::self()->virtualManager()->setDefault(p);
}

void KPrintDialog::done(int result)
{
	if (result == Accepted && d->m_printer)
	{
		QMap<QString,QString>	opts;
		KMPrinter		*prt(0);

		// get options from global pages
		QString	msg;
		QPtrListIterator<KPrintDialogPage>	it(d->m_pages);
		for (;it.current();++it)
			if (it.current()->isEnabled())
			{
				if (it.current()->isValid(msg))
					it.current()->getOptions(opts);
				else
				{
					KMessageBox::error(this, msg.prepend("<qt>").append("</qt>"));
					return;
				}
			}

		// add options from the dialog itself
		// TODO: ADD PRINTER CHECK MECHANISM !!!
		prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
		if (prt->isSpecial() && prt->option("kde-special-file") == "1")
		{
			if (!checkOutputFile()) return;
			d->m_printer->setOutputToFile(true);
			/* be sure to decode the output filename */
			d->m_printer->setOutputFileName( KURL::decode_string( d->m_file->url() ) );
		}
		else
			d->m_printer->setOutputToFile(false);
		d->m_printer->setPrinterName(prt->printerName());
		d->m_printer->setSearchName(prt->name());
		opts["kde-printcommand"] = d->m_cmd->text();
		opts["kde-preview"] = (d->m_preview->isChecked() ? "1" : "0");
		opts["kde-isspecial"] = (prt->isSpecial() ? "1" : "0");
		opts["kde-special-command"] = prt->option("kde-special-command");

		// merge options with KMPrinter object options
		QMap<QString,QString>	popts = (prt->isEdited() ? prt->editedOptions() : prt->defaultOptions());
		for (QMap<QString,QString>::ConstIterator it=popts.begin(); it!=popts.end(); ++it)
			opts[it.key()] = it.data();

		// update KPrinter object
		d->m_printer->setOptions(opts);

		emit printRequested(d->m_printer);
		// close dialog if not persistent
		if (!d->m_persistent->isChecked() || !d->m_persistent->isVisible())
			KDialog::done(result);
	}
	else
		KDialog::done(result);
}

bool KPrintDialog::checkOutputFile()
{
	bool	value(false);
	if (d->m_file->url().isEmpty())
		KMessageBox::error(this,i18n("The output filename is empty."));
	else
	{
		KURL url( d->m_file->url() );
		if ( !url.isLocalFile() )
			return true;

		bool	anotherCheck;
		do
		{
		anotherCheck = false;
		QFileInfo	f(url.path());
		if (f.exists())
		{
			if (f.isWritable())
			{
				//value = (KMessageBox::warningYesNo(this,i18n("File \"%1\" already exists. Overwrite?").arg(f.absFilePath())) == KMessageBox::Yes);
				time_t mtimeDest = f.lastModified().toTime_t();
				KIO::RenameDlg dlg( this, i18n( "Print" ), QString::null, d->m_file->url(),
						KIO::M_OVERWRITE, ( time_t ) -1, f.size(), ( time_t ) -1, f.created().toTime_t() , mtimeDest+1, mtimeDest, true );
				int result = dlg.exec();
				switch ( result )
				{
					case KIO::R_OVERWRITE:
						value = true;
						break;
					default:
					case KIO::R_CANCEL:
						value = false;
						break;
					case KIO::R_RENAME:
						url = dlg.newDestURL();
						d->m_file->setURL( url.path() );
						value = true;
						anotherCheck = true;
						break;
				}
			}
			else
				KMessageBox::error(this,i18n("You don't have write permissions to this file."));
		}
		else
		{
			QFileInfo d( f.dirPath( true ) );
			if ( !d.exists() )
				KMessageBox::error( this, i18n( "The output directory does not exist." ) );
			else if ( !d.isWritable() )
				KMessageBox::error(this,i18n("You don't have write permissions in that directory."));
			else
				value = true;
		}
		} while( anotherCheck );
	}
	return value;
}

void KPrintDialog::slotOptions()
{
	if (KMManager::self()->invokeOptionsDialog(this))
		init();
}

void KPrintDialog::enableOutputFile(bool on)
{
	d->m_filelabel->setEnabled(on);
	d->m_file->setEnabled(on);
}

void KPrintDialog::enableSpecial(bool on)
{
	d->m_default->setDisabled(on);
	d->m_cmdlabel->setDisabled(on);
	d->m_cmd->setDisabled(on);
	KPCopiesPage	*copypage = (KPCopiesPage*)child("CopiesPage","KPCopiesPage");
	if (copypage)
		copypage->initialize(!on);
	// disable/enable all other pages (if needed)
	for (d->m_pages.first(); d->m_pages.current(); d->m_pages.next())
		if (d->m_pages.current()->onlyRealPrinters())
			d->m_pages.current()->setEnabled(!on);
}

void KPrintDialog::setOutputFileExtension(const QString& ext)
{
	if (!ext.isEmpty())
	{
		KURL url( d->m_file->url() );
		QString f( url.fileName() );
		int p = f.findRev( '.' );
		// change "file.ext"; don't change "file", "file." or ".file" but do change ".file.ext"
		if ( p > 0 && p != int (f.length () - 1) )
		{
			url.setFileName( f.left( p ) + "." + ext );
			d->m_file->setURL( KURL::decode_string( url.url() ) );
		}
	}
}

void KPrintDialog::slotWizard()
{
	int	result = KMFactory::self()->manager()->addPrinterWizard(this);
	if (result == -1)
		KMessageBox::error(this, KMFactory::self()->manager()->errorMsg().prepend("<qt>").append("</qt>"));
	else if (result == 1)
		initialize(d->m_printer);
}

void KPrintDialog::reload()
{
	// remove printer dependent pages (usually from plugin)
	QTabWidget	*tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
	for (uint i=0; i<d->m_pages.count(); i++)
		if (d->m_pages.at(i)->onlyRealPrinters())
		{
			KPrintDialogPage	*page = d->m_pages.take(i--);
			if (tabs)
				tabs->removePage(page);
			delete page;
		}
	// reload printer dependent pages from plugin
	QPtrList<KPrintDialogPage>	pages;
	pages.setAutoDelete(false);
	KMFactory::self()->uiManager()->setupPrintDialogPages(&pages);
	// add those pages to the dialog
	setDialogPages(&pages);
	if (!d->m_reduced)
		d->m_dummy->show();
	// other initializations
	setFlags(KMFactory::self()->uiManager()->dialogFlags());
	connect( KMFactory::self()->manager(), SIGNAL( updatePossible( bool ) ), SLOT( slotUpdatePossible( bool ) ) );
	init();
}

void KPrintDialog::configChanged()
{
	// simply update the printer list: do it all the time
	// as changing settings may influence the way printer
	// are listed.
	init();

	// update the GUI
	setFlags(KMFactory::self()->uiManager()->dialogFlags());
}

void KPrintDialog::expandDialog(bool on)
{
	QSize	sz(size());
	bool	needResize(isVisible());

	if (on)
	{
		sz.setHeight(sz.height()+d->m_dummy->minimumSize().height()+d->m_plugin->minimumSize().height()+2*layout()->spacing());
		if (isVisible() || !d->m_dummy->isVisible() || !d->m_plugin->isVisible())
		{
			d->m_dummy->show();
			if (d->b_systemEnabled)
				d->m_plugin->show();
		}
		d->m_extbtn->setIconSet(SmallIconSet("up"));
		d->m_extbtn->setText(i18n("&Options <<"));
		d->m_reduced = false;
	}
	else
	{
		sz.setHeight(sz.height()-d->m_dummy->height()-d->m_plugin->height()-2*layout()->spacing());
		if (!isVisible() || d->m_dummy->isVisible() || d->m_plugin->isVisible())
		{
			d->m_dummy->hide();
			if (d->b_systemEnabled)
				d->m_plugin->hide();
		}
		d->m_extbtn->setIconSet(SmallIconSet("down"));
		d->m_extbtn->setText(i18n("&Options >>"));
		d->m_reduced = true;
	}

	if (needResize)
	{
		layout()->activate();
		resize(sz);
	}
}

void KPrintDialog::slotExtensionClicked()
{
	// As all pages are children of d->m_dummy, I simply have to hide/show it
	expandDialog(!(d->m_dummy->isVisible()));
}

KPrinter* KPrintDialog::printer() const
{
	return d->m_printer;
}

void KPrintDialog::slotToggleFilter(bool on)
{
	KMManager::self()->enableFilter(on);
	initialize(d->m_printer);
}

void KPrintDialog::slotHelp()
{
	kapp->invokeHelp(QString::null, "kdeprint");
}

void KPrintDialog::slotOutputFileSelected(const QString& txt)
{
	d->m_file->setURL( txt );
}

void KPrintDialog::init()
{
	d->m_ok->setEnabled( false );
	MessageWindow::remove( this );
	MessageWindow::add( this, i18n( "Initializing printing system..." ), 500 );
	KMFactory::self()->manager()->checkUpdatePossible();
}

void KPrintDialog::slotUpdatePossible( bool flag )
{
	MessageWindow::remove( this );
	if ( !flag )
		KMessageBox::error(parentWidget(),
			"<qt><nobr>"+
			i18n("An error occurred while retrieving the printer list:")
			+"</nobr><br><br>"+KMManager::self()->errorMsg()+"</qt>");
	initialize( d->m_printer );
}

void KPrintDialog::enableDialogPage( int index, bool flag )
{
	if ( index < 0 || index >= ( int )d->m_pages.count() )
	{
		kdWarning() << "KPrintDialog: page index out of bound" << endl;
		return;
	}

	if ( d->m_pages.count() > 1 )
	{
		QTabWidget	*tabs = static_cast<QTabWidget*>(d->m_dummy->child("TabWidget", "QTabWidget"));
		tabs->setTabEnabled( d->m_pages.at( index ), flag );
	}
	else
		d->m_pages.at( 0 )->setEnabled( flag );
}

void KPrintDialog::slotOpenFileDialog()
{
	KFileDialog *dialog = d->m_file->fileDialog();

	dialog->setCaption(i18n("Print to File"));
	dialog->setMode(d->m_file->fileDialog()->mode() & ~KFile::LocalOnly);
	dialog->setOperationMode( KFileDialog::Saving );

	KMPrinter *prt = KMFactory::self()->manager()->findPrinter(d->m_printers->currentText());
	if (prt)
	{
		QString	mimetype(prt->option("kde-special-mimetype"));
		QString	ext(prt->option("kde-special-extension"));

		if (!mimetype.isEmpty())
		{
			QStringList filter;
			filter << mimetype;
			filter << "all/allfiles";
			dialog->setMimeFilter (filter, mimetype);
		}
		else if (!ext.isEmpty())
			dialog->setFilter ("*." + ext + "\n*|" + i18n ("All Files"));
	}
}

#include "kprintdialog.moc"