Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / unx / generic / print / prtsetup.cxx
blobad5d0fc53553ef11bf749fe2b3a82ae8627855b9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
21 #include <svdata.hxx>
22 #include <strings.hrc>
24 #include <officecfg/Office/Common.hxx>
26 using namespace psp;
28 void RTSDialog::insertAllPPDValues(weld::ComboBox& rBox, const PPDParser* pParser, const PPDKey* pKey )
30 if( ! pKey || ! pParser )
31 return;
33 const PPDValue* pValue = nullptr;
34 OUString aOptionText;
36 for (int i = 0; i < pKey->countValues(); ++i)
38 pValue = pKey->getValue( i );
39 if (pValue->m_bCustomOption)
40 continue;
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);
50 else
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);
61 if (nPos != -1)
62 rBox.set_active(nPos);
67 * RTSDialog
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)
95 if (rPage == "paper")
96 m_xPaperPage->update();
99 IMPL_LINK( RTSDialog, ClickButton, weld::Button&, rButton, void )
101 if (&rButton == m_xOKButton.get())
103 // refresh the changed values
104 if (m_xPaperPage)
106 // orientation
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;
114 if( m_xDevicePage )
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);
128 * RTSPaperPage
131 RTSPaperPage::RTSPaperPage(weld::Widget* pPage, RTSDialog* pDialog)
132 : m_xBuilder(Application::CreateBuilder(pPage, "vcl/ui/printerpaperpage.ui"))
133 , m_pParent(pDialog)
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"))
145 //PrinterPaperPage
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 ) );
152 update();
155 RTSPaperPage::~RTSPaperPage()
159 void RTSPaperPage::update()
161 const PPDKey* pKey = nullptr;
163 // orientation
164 m_xOrientBox->set_active(m_pParent->m_aJobData.m_eOrientation == orientation::Portrait ? 0 : 1);
166 // duplex
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 );
172 else
174 m_xDuplexText->set_sensitive( false );
175 m_xDuplexBox->set_sensitive( false );
178 // paper
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 );
184 else
186 m_xPaperText->set_sensitive( false );
187 m_xPaperBox->set_sensitive( false );
190 // input slots
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 );
196 else
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
210 else
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;
242 if( pKey )
244 PPDValue* pValue = reinterpret_cast<PPDValue*>(rBox.get_active_id().toInt64());
245 m_pParent->m_aJobData.m_aContext.setValue( pKey, pValue );
246 update();
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);
263 * RTSDevicePage
266 RTSDevicePage::RTSDevicePage(weld::Widget* pPage, RTSDialog* pParent)
267 : m_xBuilder(Application::CreateBuilder(pPage, "vcl/ui/printerdevicepage.ui"))
268 , m_pCustomValue(nullptr)
269 , m_pParent(pParent)
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 )
291 case 0:
292 m_xSpaceBox->set_active(0);
293 break;
294 case 1:
295 m_xSpaceBox->set_active(1);
296 break;
297 case -1:
298 m_xSpaceBox->set_active(2);
299 break;
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
308 nLevelEntryData = 0;
309 else if (m_pParent->m_aJobData.m_nPDFDevice == -1) //explicitly PS from driver
310 nLevelEntryData = 1;
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);
328 break;
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);
337 // fill ppd boxes
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();
371 if (nSelectPos == 0)
372 return 8;
373 else
374 return 24;
377 sal_uLong RTSDevicePage::getColorDevice() const
379 sal_uInt16 nSelectPos = m_xSpaceBox->get_active();
380 switch (nSelectPos)
382 case 0:
383 return 0;
384 case 1:
385 return 1;
386 case 2:
387 return -1;
389 return 0;
392 sal_uLong RTSDevicePage::getLevel() const
394 auto nLevel = m_xLevelBox->get_active_id().toInt32();
395 if (nLevel == 0)
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();
403 if (nLevel > 9)
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)
412 if (m_pCustomValue)
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());
429 if (pKey && pValue)
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();
443 if( ! pKey )
444 return;
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 )
453 OUString aEntry;
454 if (pValue->m_bCustomOption)
455 aEntry = VclResId(SV_PRINT_CUSTOM_TXT);
456 else
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();
484 else
485 m_xCustomEdit->hide();
488 int SetupPrinterDriver(weld::Window* pParent, ::psp::PrinterInfo& rJobData)
490 int nRet = 0;
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;
501 return nRet;
504 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */