1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "prtsetup.hxx"
22 #include <strings.hrc>
24 #include <officecfg/Office/Common.hxx>
28 void RTSDialog::insertAllPPDValues(weld::ComboBox
& rBox
, const PPDParser
* pParser
, const PPDKey
* pKey
)
30 if( ! pKey
|| ! pParser
)
33 const PPDValue
* pValue
= nullptr;
36 for (int i
= 0; i
< pKey
->countValues(); ++i
)
38 pValue
= pKey
->getValue( i
);
39 if (pValue
->m_bCustomOption
)
41 aOptionText
= pParser
->translateOption( pKey
->getKey(), pValue
->m_aOption
) ;
43 OUString
sId(OUString::number(reinterpret_cast<sal_Int64
>(pValue
)));
44 int nCurrentPos
= rBox
.find_id(sId
);
45 if( m_aJobData
.m_aContext
.checkConstraints( pKey
, pValue
) )
47 if (nCurrentPos
== -1)
48 rBox
.append(sId
, aOptionText
);
52 if (nCurrentPos
!= -1)
53 rBox
.remove(nCurrentPos
);
56 pValue
= m_aJobData
.m_aContext
.getValue( pKey
);
57 if (pValue
&& !pValue
->m_bCustomOption
)
59 OUString
sId(OUString::number(reinterpret_cast<sal_IntPtr
>(pValue
)));
60 int nPos
= rBox
.find_id(sId
);
62 rBox
.set_active(nPos
);
70 RTSDialog::RTSDialog(const PrinterInfo
& rJobData
, weld::Window
* pParent
)
71 : GenericDialogController(pParent
, "vcl/ui/printerpropertiesdialog.ui", "PrinterPropertiesDialog")
72 , m_aJobData(rJobData
)
73 , m_bDataModified(false)
74 , m_xTabControl(m_xBuilder
->weld_notebook("tabcontrol"))
75 , m_xOKButton(m_xBuilder
->weld_button("ok"))
76 , m_xCancelButton(m_xBuilder
->weld_button("cancel"))
77 , m_xPaperPage(new RTSPaperPage(m_xTabControl
->get_page("paper"), this))
78 , m_xDevicePage(new RTSDevicePage(m_xTabControl
->get_page("device"), this))
80 OUString
aTitle(m_xDialog
->get_title());
81 m_xDialog
->set_title(aTitle
.replaceAll("%s", m_aJobData
.m_aPrinterName
));
83 m_xTabControl
->connect_enter_page( LINK( this, RTSDialog
, ActivatePage
) );
84 m_xOKButton
->connect_clicked( LINK( this, RTSDialog
, ClickButton
) );
85 m_xCancelButton
->connect_clicked( LINK( this, RTSDialog
, ClickButton
) );
86 ActivatePage(m_xTabControl
->get_current_page_ident());
89 RTSDialog::~RTSDialog()
93 IMPL_LINK(RTSDialog
, ActivatePage
, const OString
&, rPage
, void)
96 m_xPaperPage
->update();
99 IMPL_LINK( RTSDialog
, ClickButton
, weld::Button
&, rButton
, void )
101 if (&rButton
== m_xOKButton
.get())
103 // refresh the changed values
107 m_aJobData
.m_eOrientation
= m_xPaperPage
->getOrientation() == 0 ?
108 orientation::Portrait
: orientation::Landscape
;
109 // assume use of paper size from printer setup if the user
110 // got here via File > Printer Settings ...
111 if ( m_aJobData
.meSetupMode
== PrinterSetupMode::DocumentGlobal
)
112 m_aJobData
.m_bPapersizeFromSetup
= true;
116 m_aJobData
.m_nColorDepth
= m_xDevicePage
->getDepth();
117 m_aJobData
.m_nColorDevice
= m_xDevicePage
->getColorDevice();
118 m_aJobData
.m_nPSLevel
= m_xDevicePage
->getLevel();
119 m_aJobData
.m_nPDFDevice
= m_xDevicePage
->getPDFDevice();
121 m_xDialog
->response(RET_OK
);
123 else if (&rButton
== m_xCancelButton
.get())
124 m_xDialog
->response(RET_CANCEL
);
131 RTSPaperPage::RTSPaperPage(weld::Widget
* pPage
, RTSDialog
* pDialog
)
132 : m_xBuilder(Application::CreateBuilder(pPage
, "vcl/ui/printerpaperpage.ui"))
134 , m_xContainer(m_xBuilder
->weld_widget("PrinterPaperPage"))
135 , m_xCbFromSetup(m_xBuilder
->weld_check_button("papersizefromsetup"))
136 , m_xPaperText(m_xBuilder
->weld_label("paperft"))
137 , m_xPaperBox(m_xBuilder
->weld_combo_box("paperlb"))
138 , m_xOrientText(m_xBuilder
->weld_label("orientft"))
139 , m_xOrientBox(m_xBuilder
->weld_combo_box("orientlb"))
140 , m_xDuplexText(m_xBuilder
->weld_label("duplexft"))
141 , m_xDuplexBox(m_xBuilder
->weld_combo_box("duplexlb"))
142 , m_xSlotText(m_xBuilder
->weld_label("slotft"))
143 , m_xSlotBox(m_xBuilder
->weld_combo_box("slotlb"))
146 m_xPaperBox
->connect_changed( LINK( this, RTSPaperPage
, SelectHdl
) );
147 m_xOrientBox
->connect_changed( LINK( this, RTSPaperPage
, SelectHdl
) );
148 m_xDuplexBox
->connect_changed( LINK( this, RTSPaperPage
, SelectHdl
) );
149 m_xSlotBox
->connect_changed( LINK( this, RTSPaperPage
, SelectHdl
) );
150 m_xCbFromSetup
->connect_toggled( LINK( this, RTSPaperPage
, CheckBoxHdl
) );
155 RTSPaperPage::~RTSPaperPage()
159 void RTSPaperPage::update()
161 const PPDKey
* pKey
= nullptr;
164 m_xOrientBox
->set_active(m_pParent
->m_aJobData
.m_eOrientation
== orientation::Portrait
? 0 : 1);
167 if( m_pParent
->m_aJobData
.m_pParser
&&
168 (pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "Duplex" )) )
170 m_pParent
->insertAllPPDValues( *m_xDuplexBox
, m_pParent
->m_aJobData
.m_pParser
, pKey
);
174 m_xDuplexText
->set_sensitive( false );
175 m_xDuplexBox
->set_sensitive( false );
179 if( m_pParent
->m_aJobData
.m_pParser
&&
180 (pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "PageSize" )) )
182 m_pParent
->insertAllPPDValues( *m_xPaperBox
, m_pParent
->m_aJobData
.m_pParser
, pKey
);
186 m_xPaperText
->set_sensitive( false );
187 m_xPaperBox
->set_sensitive( false );
191 if( m_pParent
->m_aJobData
.m_pParser
&&
192 (pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "InputSlot" )) )
194 m_pParent
->insertAllPPDValues( *m_xSlotBox
, m_pParent
->m_aJobData
.m_pParser
, pKey
);
198 m_xSlotText
->set_sensitive( false );
199 m_xSlotBox
->set_sensitive( false );
202 if ( m_pParent
->m_aJobData
.meSetupMode
== PrinterSetupMode::SingleJob
)
204 m_xCbFromSetup
->show();
206 if ( m_pParent
->m_aJobData
.m_bPapersizeFromSetup
)
207 m_xCbFromSetup
->set_active(m_pParent
->m_aJobData
.m_bPapersizeFromSetup
);
208 // disable those, unless user wants to use papersize from printer prefs
209 // as they have no influence on what's going to be printed anyway
212 m_xPaperText
->set_sensitive( false );
213 m_xPaperBox
->set_sensitive( false );
214 m_xOrientText
->set_sensitive( false );
215 m_xOrientBox
->set_sensitive( false );
220 IMPL_LINK( RTSPaperPage
, SelectHdl
, weld::ComboBox
&, rBox
, void )
222 const PPDKey
* pKey
= nullptr;
223 if( &rBox
== m_xPaperBox
.get() )
225 if( m_pParent
->m_aJobData
.m_pParser
)
226 pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "PageSize" );
228 else if( &rBox
== m_xDuplexBox
.get() )
230 if( m_pParent
->m_aJobData
.m_pParser
)
231 pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "Duplex" );
233 else if( &rBox
== m_xSlotBox
.get() )
235 if( m_pParent
->m_aJobData
.m_pParser
)
236 pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( "InputSlot" );
238 else if( &rBox
== m_xOrientBox
.get() )
240 m_pParent
->m_aJobData
.m_eOrientation
= m_xOrientBox
->get_active() == 0 ? orientation::Portrait
: orientation::Landscape
;
244 PPDValue
* pValue
= reinterpret_cast<PPDValue
*>(rBox
.get_active_id().toInt64());
245 m_pParent
->m_aJobData
.m_aContext
.setValue( pKey
, pValue
);
249 m_pParent
->SetDataModified( true );
252 IMPL_LINK( RTSPaperPage
, CheckBoxHdl
, weld::ToggleButton
&, /*cBox*/, void )
254 bool bFromSetup
= m_xCbFromSetup
->get_active();
255 m_pParent
->m_aJobData
.m_bPapersizeFromSetup
= bFromSetup
;
256 m_xPaperText
->set_sensitive(bFromSetup
);
257 m_xPaperBox
->set_sensitive(bFromSetup
);
258 m_xOrientText
->set_sensitive(bFromSetup
);
259 m_xOrientBox
->set_sensitive(bFromSetup
);
260 m_pParent
->SetDataModified(true);
266 RTSDevicePage::RTSDevicePage(weld::Widget
* pPage
, RTSDialog
* pParent
)
267 : m_xBuilder(Application::CreateBuilder(pPage
, "vcl/ui/printerdevicepage.ui"))
268 , m_pCustomValue(nullptr)
270 , m_xContainer(m_xBuilder
->weld_widget("PrinterDevicePage"))
271 , m_xPPDKeyBox(m_xBuilder
->weld_tree_view("options"))
272 , m_xPPDValueBox(m_xBuilder
->weld_tree_view("values"))
273 , m_xCustomEdit(m_xBuilder
->weld_entry("custom"))
274 , m_xLevelBox(m_xBuilder
->weld_combo_box("level"))
275 , m_xSpaceBox(m_xBuilder
->weld_combo_box("colorspace"))
276 , m_xDepthBox(m_xBuilder
->weld_combo_box("colordepth"))
278 m_aReselectCustomIdle
.SetInvokeHandler(LINK(this, RTSDevicePage
, ImplHandleReselectHdl
));
279 m_aReselectCustomIdle
.SetDebugName("RTSDevicePage m_aReselectCustomIdle");
281 m_xPPDKeyBox
->set_size_request(m_xPPDKeyBox
->get_approximate_digit_width() * 32,
282 m_xPPDKeyBox
->get_height_rows(12));
284 m_xCustomEdit
->connect_changed(LINK(this, RTSDevicePage
, ModifyHdl
));
286 m_xPPDKeyBox
->connect_changed( LINK( this, RTSDevicePage
, SelectHdl
) );
287 m_xPPDValueBox
->connect_changed( LINK( this, RTSDevicePage
, SelectHdl
) );
289 switch( m_pParent
->m_aJobData
.m_nColorDevice
)
292 m_xSpaceBox
->set_active(0);
295 m_xSpaceBox
->set_active(1);
298 m_xSpaceBox
->set_active(2);
302 sal_Int32 nLevelEntryData
= 0; //automatic
303 if( m_pParent
->m_aJobData
.m_nPDFDevice
== 2 ) //explicit PDF
304 nLevelEntryData
= 10;
305 else if (m_pParent
->m_aJobData
.m_nPSLevel
> 0) //explicit PS Level
306 nLevelEntryData
= m_pParent
->m_aJobData
.m_nPSLevel
+1;
307 else if (m_pParent
->m_aJobData
.m_nPDFDevice
== 1) //automatically PDF
309 else if (m_pParent
->m_aJobData
.m_nPDFDevice
== -1) //explicitly PS from driver
312 bool bAutoIsPDF
= officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get();
314 assert(nLevelEntryData
!= 0
315 || "Generic Printer" == m_pParent
->m_aJobData
.m_aPrinterName
316 || int(bAutoIsPDF
) == m_pParent
->m_aJobData
.m_nPDFDevice
);
318 OUString sStr
= m_xLevelBox
->get_text(0);
319 OUString sId
= m_xLevelBox
->get_id(0);
320 m_xLevelBox
->insert(0, sStr
.replaceAll("%s", bAutoIsPDF
? m_xLevelBox
->get_text(5) : m_xLevelBox
->get_text(1)), &sId
, nullptr, nullptr);
321 m_xLevelBox
->remove(1);
323 for (int i
= 0; i
< m_xLevelBox
->get_count(); ++i
)
325 if (m_xLevelBox
->get_id(i
).toInt32() == nLevelEntryData
)
327 m_xLevelBox
->set_active(i
);
332 if (m_pParent
->m_aJobData
.m_nColorDepth
== 8)
333 m_xDepthBox
->set_active(0);
334 else if (m_pParent
->m_aJobData
.m_nColorDepth
== 24)
335 m_xDepthBox
->set_active(1);
338 if( m_pParent
->m_aJobData
.m_pParser
)
340 for( int i
= 0; i
< m_pParent
->m_aJobData
.m_pParser
->getKeys(); i
++ )
342 const PPDKey
* pKey
= m_pParent
->m_aJobData
.m_pParser
->getKey( i
);
344 // skip options already shown somewhere else
345 // also skip options from the "InstallableOptions" PPD group
346 // Options in that group define hardware features that are not
347 // job-specific and should better be handled in the system-wide
348 // printer configuration. Keyword is defined in PPD specification
349 // (version 4.3), section 5.4.
350 if( pKey
->isUIKey() &&
351 pKey
->getKey() != "PageSize" &&
352 pKey
->getKey() != "InputSlot" &&
353 pKey
->getKey() != "PageRegion" &&
354 pKey
->getKey() != "Duplex" &&
355 pKey
->getGroup() != "InstallableOptions")
357 OUString
aEntry( m_pParent
->m_aJobData
.m_pParser
->translateKey( pKey
->getKey() ) );
358 m_xPPDKeyBox
->append(OUString::number(reinterpret_cast<sal_Int64
>(pKey
)), aEntry
);
364 RTSDevicePage::~RTSDevicePage()
368 sal_uLong
RTSDevicePage::getDepth() const
370 sal_uInt16 nSelectPos
= m_xDepthBox
->get_active();
377 sal_uLong
RTSDevicePage::getColorDevice() const
379 sal_uInt16 nSelectPos
= m_xSpaceBox
->get_active();
392 sal_uLong
RTSDevicePage::getLevel() const
394 auto nLevel
= m_xLevelBox
->get_active_id().toInt32();
396 return 0; //automatic
397 return nLevel
< 10 ? nLevel
-1 : 0;
400 sal_uLong
RTSDevicePage::getPDFDevice() const
402 auto nLevel
= m_xLevelBox
->get_active_id().toInt32();
404 return 2; //explicitly PDF
405 else if (nLevel
== 0)
406 return 0; //automatic
407 return -1; //explicitly PS
410 IMPL_LINK(RTSDevicePage
, ModifyHdl
, weld::Entry
&, rEdit
, void)
414 m_pCustomValue
->m_aCustomOption
= rEdit
.get_text();
418 IMPL_LINK( RTSDevicePage
, SelectHdl
, weld::TreeView
&, rBox
, void )
420 if (&rBox
== m_xPPDKeyBox
.get())
422 const PPDKey
* pKey
= reinterpret_cast<PPDKey
*>(m_xPPDKeyBox
->get_selected_id().toInt64());
423 FillValueBox( pKey
);
425 else if (&rBox
== m_xPPDValueBox
.get())
427 const PPDKey
* pKey
= reinterpret_cast<PPDKey
*>(m_xPPDKeyBox
->get_selected_id().toInt64());
428 const PPDValue
* pValue
= reinterpret_cast<PPDValue
*>(m_xPPDValueBox
->get_selected_id().toInt64());
431 m_pParent
->m_aJobData
.m_aContext
.setValue( pKey
, pValue
);
432 ValueBoxChanged(pKey
);
435 m_pParent
->SetDataModified( true );
438 void RTSDevicePage::FillValueBox( const PPDKey
* pKey
)
440 m_xPPDValueBox
->clear();
441 m_xCustomEdit
->hide();
446 const PPDValue
* pValue
= nullptr;
447 for( int i
= 0; i
< pKey
->countValues(); i
++ )
449 pValue
= pKey
->getValue( i
);
450 if( m_pParent
->m_aJobData
.m_aContext
.checkConstraints( pKey
, pValue
) &&
451 m_pParent
->m_aJobData
.m_pParser
)
454 if (pValue
->m_bCustomOption
)
455 aEntry
= VclResId(SV_PRINT_CUSTOM_TXT
);
457 aEntry
= m_pParent
->m_aJobData
.m_pParser
->translateOption( pKey
->getKey(), pValue
->m_aOption
);
458 m_xPPDValueBox
->append(OUString::number(reinterpret_cast<sal_Int64
>(pValue
)), aEntry
);
461 pValue
= m_pParent
->m_aJobData
.m_aContext
.getValue( pKey
);
462 m_xPPDValueBox
->select_id(OUString::number(reinterpret_cast<sal_Int64
>(pValue
)));
464 ValueBoxChanged(pKey
);
467 IMPL_LINK_NOARG(RTSDevicePage
, ImplHandleReselectHdl
, Timer
*, void)
469 //in case selected entry is now not visible select it again to scroll it into view
470 m_xPPDValueBox
->select(m_xPPDValueBox
->get_selected_index());
473 void RTSDevicePage::ValueBoxChanged( const PPDKey
* pKey
)
475 const PPDValue
* pValue
= m_pParent
->m_aJobData
.m_aContext
.getValue(pKey
);
476 if (pValue
->m_bCustomOption
)
478 m_pCustomValue
= pValue
;
479 m_pParent
->m_aJobData
.m_aContext
.setValue(pKey
, pValue
);
480 m_xCustomEdit
->set_text(m_pCustomValue
->m_aCustomOption
);
481 m_xCustomEdit
->show();
482 m_aReselectCustomIdle
.Start();
485 m_xCustomEdit
->hide();
488 int SetupPrinterDriver(weld::Window
* pParent
, ::psp::PrinterInfo
& rJobData
)
491 RTSDialog
aDialog(rJobData
, pParent
);
493 // return 0 if cancel was pressed or if the data
494 // weren't modified, 1 otherwise
495 if (aDialog
.run() != RET_CANCEL
)
497 rJobData
= aDialog
.getSetup();
498 nRet
= aDialog
.GetDataModified() ? 1 : 0;
504 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */