loplugin:constmethod in vcl
[LibreOffice.git] / vcl / unx / generic / print / prtsetup.cxx
blob72d550f11844d5f856f10230361e8591083d2577
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 <osl/thread.h>
26 #include <officecfg/Office/Common.hxx>
28 using namespace psp;
30 void RTSDialog::insertAllPPDValues(weld::ComboBox& rBox, const PPDParser* pParser, const PPDKey* pKey )
32 if( ! pKey || ! pParser )
33 return;
35 const PPDValue* pValue = nullptr;
36 OUString aOptionText;
38 for (int i = 0; i < pKey->countValues(); ++i)
40 pValue = pKey->getValue( i );
41 if (pValue->m_bCustomOption)
42 continue;
43 aOptionText = pParser->translateOption( pKey->getKey(), pValue->m_aOption) ;
45 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pValue)));
46 int nCurrentPos = rBox.find_id(sId);
47 if( m_aJobData.m_aContext.checkConstraints( pKey, pValue ) )
49 if (nCurrentPos == -1)
50 rBox.append(sId, aOptionText);
52 else
54 if (nCurrentPos != -1)
55 rBox.remove(nCurrentPos);
58 pValue = m_aJobData.m_aContext.getValue( pKey );
59 if (pValue && !pValue->m_bCustomOption)
61 OUString sId(OUString::number(reinterpret_cast<sal_IntPtr>(pValue)));
62 int nPos = rBox.find_id(sId);
63 if (nPos != -1)
64 rBox.set_active(nPos);
66 else
67 rBox.set_active_text(m_aInvalidString);
71 * RTSDialog
74 RTSDialog::RTSDialog(const PrinterInfo& rJobData, weld::Window* pParent)
75 : GenericDialogController(pParent, "vcl/ui/printerpropertiesdialog.ui", "PrinterPropertiesDialog")
76 , m_aJobData(rJobData)
77 , m_aInvalidString(VclResId(SV_PRINT_INVALID_TXT))
78 , m_bDataModified(false)
79 , m_xTabControl(m_xBuilder->weld_notebook("notebook"))
80 , m_xOKButton(m_xBuilder->weld_button("ok"))
81 , m_xCancelButton(m_xBuilder->weld_button("cancel"))
82 , m_xPaperPage(new RTSPaperPage(m_xTabControl->get_page("paper"), this))
83 , m_xDevicePage(new RTSDevicePage(m_xTabControl->get_page("device"), this))
85 OUString aTitle(m_xDialog->get_title());
86 m_xDialog->set_title(aTitle.replaceAll("%s", m_aJobData.m_aPrinterName));
88 m_xTabControl->connect_enter_page( LINK( this, RTSDialog, ActivatePage ) );
89 m_xOKButton->connect_clicked( LINK( this, RTSDialog, ClickButton ) );
90 m_xCancelButton->connect_clicked( LINK( this, RTSDialog, ClickButton ) );
91 ActivatePage(m_xTabControl->get_current_page_ident());
94 RTSDialog::~RTSDialog()
98 IMPL_LINK(RTSDialog, ActivatePage, const OString&, rPage, void)
100 if (rPage == "paper")
101 m_xPaperPage->update();
104 IMPL_LINK( RTSDialog, ClickButton, weld::Button&, rButton, void )
106 if (&rButton == m_xOKButton.get())
108 // refresh the changed values
109 if (m_xPaperPage)
111 // orientation
112 m_aJobData.m_eOrientation = m_xPaperPage->getOrientation() == 0 ?
113 orientation::Portrait : orientation::Landscape;
114 // assume use of paper size from printer setup if the user
115 // got here via File > Printer Settings ...
116 if ( m_aJobData.meSetupMode == PrinterSetupMode::DocumentGlobal )
117 m_aJobData.m_bPapersizeFromSetup = true;
119 if( m_xDevicePage )
121 m_aJobData.m_nColorDepth = m_xDevicePage->getDepth();
122 m_aJobData.m_nColorDevice = m_xDevicePage->getColorDevice();
123 m_aJobData.m_nPSLevel = m_xDevicePage->getLevel();
124 m_aJobData.m_nPDFDevice = m_xDevicePage->getPDFDevice();
126 m_xDialog->response(RET_OK);
128 else if (&rButton == m_xCancelButton.get())
129 m_xDialog->response(RET_CANCEL);
133 * RTSPaperPage
136 RTSPaperPage::RTSPaperPage(weld::Widget* pPage, RTSDialog* pDialog)
137 : m_xBuilder(Application::CreateBuilder(pPage, "vcl/ui/printerpaperpage.ui"))
138 , m_pParent(pDialog)
139 , m_xContainer(m_xBuilder->weld_widget("PrinterPaperPage"))
140 , m_xCbFromSetup(m_xBuilder->weld_check_button("papersizefromsetup"))
141 , m_xPaperText(m_xBuilder->weld_label("paperft"))
142 , m_xPaperBox(m_xBuilder->weld_combo_box("paperlb"))
143 , m_xOrientText(m_xBuilder->weld_label("orientft"))
144 , m_xOrientBox(m_xBuilder->weld_combo_box("orientlb"))
145 , m_xDuplexText(m_xBuilder->weld_label("duplexft"))
146 , m_xDuplexBox(m_xBuilder->weld_combo_box("duplexlb"))
147 , m_xSlotText(m_xBuilder->weld_label("slotft"))
148 , m_xSlotBox(m_xBuilder->weld_combo_box("slotlb"))
150 //PrinterPaperPage
151 m_xPaperBox->connect_changed( LINK( this, RTSPaperPage, SelectHdl ) );
152 m_xOrientBox->connect_changed( LINK( this, RTSPaperPage, SelectHdl ) );
153 m_xDuplexBox->connect_changed( LINK( this, RTSPaperPage, SelectHdl ) );
154 m_xSlotBox->connect_changed( LINK( this, RTSPaperPage, SelectHdl ) );
155 m_xCbFromSetup->connect_toggled( LINK( this, RTSPaperPage, CheckBoxHdl ) );
157 // duplex
158 m_xDuplexBox->append_text(m_pParent->m_aInvalidString);
160 // paper does not have an invalid entry
162 // input slots
163 m_xSlotBox->append_text(m_pParent->m_aInvalidString);
165 update();
168 RTSPaperPage::~RTSPaperPage()
172 void RTSPaperPage::update()
174 const PPDKey* pKey = nullptr;
176 // orientation
177 m_xOrientBox->set_active(m_pParent->m_aJobData.m_eOrientation == orientation::Portrait ? 0 : 1);
179 // duplex
180 if( m_pParent->m_aJobData.m_pParser &&
181 (pKey = m_pParent->m_aJobData.m_pParser->getKey( "Duplex" )) )
183 m_pParent->insertAllPPDValues( *m_xDuplexBox, m_pParent->m_aJobData.m_pParser, pKey );
185 else
187 m_xDuplexText->set_sensitive( false );
188 m_xDuplexBox->set_sensitive( false );
191 // paper
192 if( m_pParent->m_aJobData.m_pParser &&
193 (pKey = m_pParent->m_aJobData.m_pParser->getKey( "PageSize" )) )
195 m_pParent->insertAllPPDValues( *m_xPaperBox, m_pParent->m_aJobData.m_pParser, pKey );
197 else
199 m_xPaperText->set_sensitive( false );
200 m_xPaperBox->set_sensitive( false );
203 // input slots
204 if( m_pParent->m_aJobData.m_pParser &&
205 (pKey = m_pParent->m_aJobData.m_pParser->getKey( "InputSlot" )) )
207 m_pParent->insertAllPPDValues( *m_xSlotBox, m_pParent->m_aJobData.m_pParser, pKey );
209 else
211 m_xSlotText->set_sensitive( false );
212 m_xSlotBox->set_sensitive( false );
215 if ( m_pParent->m_aJobData.meSetupMode == PrinterSetupMode::SingleJob )
217 m_xCbFromSetup->show();
219 if ( m_pParent->m_aJobData.m_bPapersizeFromSetup )
220 m_xCbFromSetup->set_active(m_pParent->m_aJobData.m_bPapersizeFromSetup);
221 // disable those, unless user wants to use papersize from printer prefs
222 // as they have no influence on what's going to be printed anyway
223 else
225 m_xPaperText->set_sensitive( false );
226 m_xPaperBox->set_sensitive( false );
227 m_xOrientText->set_sensitive( false );
228 m_xOrientBox->set_sensitive( false );
233 IMPL_LINK( RTSPaperPage, SelectHdl, weld::ComboBox&, rBox, void )
235 const PPDKey* pKey = nullptr;
236 if( &rBox == m_xPaperBox.get() )
238 if( m_pParent->m_aJobData.m_pParser )
239 pKey = m_pParent->m_aJobData.m_pParser->getKey( "PageSize" );
241 else if( &rBox == m_xDuplexBox.get() )
243 if( m_pParent->m_aJobData.m_pParser )
244 pKey = m_pParent->m_aJobData.m_pParser->getKey( "Duplex" );
246 else if( &rBox == m_xSlotBox.get() )
248 if( m_pParent->m_aJobData.m_pParser )
249 pKey = m_pParent->m_aJobData.m_pParser->getKey( "InputSlot" );
251 else if( &rBox == m_xOrientBox.get() )
253 m_pParent->m_aJobData.m_eOrientation = m_xOrientBox->get_active() == 0 ? orientation::Portrait : orientation::Landscape;
255 if( pKey )
257 PPDValue* pValue = reinterpret_cast<PPDValue*>(rBox.get_active_id().toInt64());
258 m_pParent->m_aJobData.m_aContext.setValue( pKey, pValue );
259 update();
262 m_pParent->SetDataModified( true );
265 IMPL_LINK( RTSPaperPage, CheckBoxHdl, weld::ToggleButton&, /*cBox*/, void )
267 bool bFromSetup = m_xCbFromSetup->get_active();
268 m_pParent->m_aJobData.m_bPapersizeFromSetup = bFromSetup;
269 m_xPaperText->set_sensitive(bFromSetup);
270 m_xPaperBox->set_sensitive(bFromSetup);
271 m_xOrientText->set_sensitive(bFromSetup);
272 m_xOrientBox->set_sensitive(bFromSetup);
273 m_pParent->SetDataModified(true);
276 * RTSDevicePage
279 RTSDevicePage::RTSDevicePage(weld::Widget* pPage, RTSDialog* pParent)
280 : m_xBuilder(Application::CreateBuilder(pPage, "vcl/ui/printerdevicepage.ui"))
281 , m_pCustomValue(nullptr)
282 , m_pParent(pParent)
283 , m_xContainer(m_xBuilder->weld_widget("PrinterDevicePage"))
284 , m_xPPDKeyBox(m_xBuilder->weld_tree_view("options"))
285 , m_xPPDValueBox(m_xBuilder->weld_tree_view("values"))
286 , m_xCustomEdit(m_xBuilder->weld_entry("custom"))
287 , m_xLevelBox(m_xBuilder->weld_combo_box("level"))
288 , m_xSpaceBox(m_xBuilder->weld_combo_box("colorspace"))
289 , m_xDepthBox(m_xBuilder->weld_combo_box("colordepth"))
291 m_aReselectCustomIdle.SetInvokeHandler(LINK(this, RTSDevicePage, ImplHandleReselectHdl));
292 m_aReselectCustomIdle.SetDebugName("RTSDevicePage m_aReselectCustomIdle");
294 m_xPPDKeyBox->set_size_request(m_xPPDKeyBox->get_approximate_digit_width() * 32,
295 m_xPPDKeyBox->get_height_rows(12));
297 m_xCustomEdit->connect_changed(LINK(this, RTSDevicePage, ModifyHdl));
299 m_xPPDKeyBox->connect_changed( LINK( this, RTSDevicePage, SelectHdl ) );
300 m_xPPDValueBox->connect_changed( LINK( this, RTSDevicePage, SelectHdl ) );
302 switch( m_pParent->m_aJobData.m_nColorDevice )
304 case 0:
305 m_xSpaceBox->set_active(0);
306 break;
307 case 1:
308 m_xSpaceBox->set_active(1);
309 break;
310 case -1:
311 m_xSpaceBox->set_active(2);
312 break;
315 sal_Int32 nLevelEntryData = 0; //automatic
316 if( m_pParent->m_aJobData.m_nPDFDevice == 2 ) //explicit PDF
317 nLevelEntryData = 10;
318 else if (m_pParent->m_aJobData.m_nPSLevel > 0) //explicit PS Level
319 nLevelEntryData = m_pParent->m_aJobData.m_nPSLevel+1;
320 else if (m_pParent->m_aJobData.m_nPDFDevice == 1) //automatically PDF
321 nLevelEntryData = 0;
322 else if (m_pParent->m_aJobData.m_nPDFDevice == -1) //explicitly PS from driver
323 nLevelEntryData = 1;
325 bool bAutoIsPDF = officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get();
327 assert(nLevelEntryData != 0
328 || "Generic Printer" == m_pParent->m_aJobData.m_aPrinterName
329 || int(bAutoIsPDF) == m_pParent->m_aJobData.m_nPDFDevice);
331 OUString sStr = m_xLevelBox->get_text(0);
332 OUString sId = m_xLevelBox->get_id(0);
333 m_xLevelBox->insert(0, sStr.replaceAll("%s", bAutoIsPDF ? m_xLevelBox->get_text(5) : m_xLevelBox->get_text(1)), &sId, nullptr, nullptr);
334 m_xLevelBox->remove(1);
336 for (int i = 0; i < m_xLevelBox->get_count(); ++i)
338 if (m_xLevelBox->get_id(i).toInt32() == nLevelEntryData)
340 m_xLevelBox->set_active(i);
341 break;
345 if (m_pParent->m_aJobData.m_nColorDepth == 8)
346 m_xDepthBox->set_active(0);
347 else if (m_pParent->m_aJobData.m_nColorDepth == 24)
348 m_xDepthBox->set_active(1);
350 // fill ppd boxes
351 if( m_pParent->m_aJobData.m_pParser )
353 for( int i = 0; i < m_pParent->m_aJobData.m_pParser->getKeys(); i++ )
355 const PPDKey* pKey = m_pParent->m_aJobData.m_pParser->getKey( i );
357 // skip options already shown somewhere else
358 // also skip options from the "InstallableOptions" PPD group
359 // Options in that group define hardware features that are not
360 // job-specific and should better be handled in the system-wide
361 // printer configuration. Keyword is defined in PPD specification
362 // (version 4.3), section 5.4.
363 if( pKey->isUIKey() &&
364 pKey->getKey() != "PageSize" &&
365 pKey->getKey() != "InputSlot" &&
366 pKey->getKey() != "PageRegion" &&
367 pKey->getKey() != "Duplex" &&
368 pKey->getGroup() != "InstallableOptions")
370 OUString aEntry( m_pParent->m_aJobData.m_pParser->translateKey( pKey->getKey() ) );
371 m_xPPDKeyBox->append(OUString::number(reinterpret_cast<sal_Int64>(pKey)), aEntry);
377 RTSDevicePage::~RTSDevicePage()
381 sal_uLong RTSDevicePage::getDepth() const
383 sal_uInt16 nSelectPos = m_xDepthBox->get_active();
384 if (nSelectPos == 0)
385 return 8;
386 else
387 return 24;
390 sal_uLong RTSDevicePage::getColorDevice() const
392 sal_uInt16 nSelectPos = m_xSpaceBox->get_active();
393 switch (nSelectPos)
395 case 0:
396 return 0;
397 case 1:
398 return 1;
399 case 2:
400 return -1;
402 return 0;
405 sal_uLong RTSDevicePage::getLevel() const
407 auto nLevel = m_xLevelBox->get_active_id().toInt32();
408 if (nLevel == 0)
409 return 0; //automatic
410 return nLevel < 10 ? nLevel-1 : 0;
413 sal_uLong RTSDevicePage::getPDFDevice() const
415 auto nLevel = m_xLevelBox->get_active_id().toInt32();
416 if (nLevel > 9)
417 return 2; //explicitly PDF
418 else if (nLevel == 0)
419 return 0; //automatic
420 return -1; //explicitly PS
423 IMPL_LINK(RTSDevicePage, ModifyHdl, weld::Entry&, rEdit, void)
425 if (m_pCustomValue)
427 m_pCustomValue->m_aCustomOption = rEdit.get_text();
431 IMPL_LINK( RTSDevicePage, SelectHdl, weld::TreeView&, rBox, void )
433 if (&rBox == m_xPPDKeyBox.get())
435 const PPDKey* pKey = reinterpret_cast<PPDKey*>(m_xPPDKeyBox->get_selected_id().toInt64());
436 FillValueBox( pKey );
438 else if (&rBox == m_xPPDValueBox.get())
440 const PPDKey* pKey = reinterpret_cast<PPDKey*>(m_xPPDKeyBox->get_selected_id().toInt64());
441 const PPDValue* pValue = reinterpret_cast<PPDValue*>(m_xPPDValueBox->get_selected_id().toInt64());
442 if (pKey && pValue)
444 m_pParent->m_aJobData.m_aContext.setValue( pKey, pValue );
445 ValueBoxChanged(pKey);
448 m_pParent->SetDataModified( true );
451 void RTSDevicePage::FillValueBox( const PPDKey* pKey )
453 m_xPPDValueBox->clear();
454 m_xCustomEdit->hide();
456 if( ! pKey )
457 return;
459 const PPDValue* pValue = nullptr;
460 for( int i = 0; i < pKey->countValues(); i++ )
462 pValue = pKey->getValue( i );
463 if( m_pParent->m_aJobData.m_aContext.checkConstraints( pKey, pValue ) &&
464 m_pParent->m_aJobData.m_pParser )
466 OUString aEntry;
467 if (pValue->m_bCustomOption)
468 aEntry = VclResId(SV_PRINT_CUSTOM_TXT);
469 else
470 aEntry = m_pParent->m_aJobData.m_pParser->translateOption( pKey->getKey(), pValue->m_aOption);
471 m_xPPDValueBox->append(OUString::number(reinterpret_cast<sal_Int64>(pValue)), aEntry);
474 pValue = m_pParent->m_aJobData.m_aContext.getValue( pKey );
475 m_xPPDValueBox->select_id(OUString::number(reinterpret_cast<sal_Int64>(pValue)));
477 ValueBoxChanged(pKey);
480 IMPL_LINK_NOARG(RTSDevicePage, ImplHandleReselectHdl, Timer*, void)
482 //in case selected entry is now not visible select it again to scroll it into view
483 m_xPPDValueBox->select(m_xPPDValueBox->get_selected_index());
486 void RTSDevicePage::ValueBoxChanged( const PPDKey* pKey )
488 const PPDValue* pValue = m_pParent->m_aJobData.m_aContext.getValue(pKey);
489 if (pValue->m_bCustomOption)
491 m_pCustomValue = pValue;
492 m_pParent->m_aJobData.m_aContext.setValue(pKey, pValue);
493 m_xCustomEdit->set_text(m_pCustomValue->m_aCustomOption);
494 m_xCustomEdit->show();
495 m_aReselectCustomIdle.Start();
497 else
498 m_xCustomEdit->hide();
501 int SetupPrinterDriver(weld::Window* pParent, ::psp::PrinterInfo& rJobData)
503 int nRet = 0;
504 RTSDialog aDialog(rJobData, pParent);
506 // return 0 if cancel was pressed or if the data
507 // weren't modified, 1 otherwise
508 if (aDialog.run() != RET_CANCEL)
510 rJobData = aDialog.getSetup();
511 nRet = aDialog.GetDataModified() ? 1 : 0;
514 return nRet;
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */