Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / generic / print / prtsetup.cxx
blob6aadc0a7f0132d6d2a47748461b2cffd72a55ae6
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 "svids.hrc"
24 #include "osl/thread.h"
26 #include <officecfg/Office/Common.hxx>
28 using namespace psp;
30 void RTSDialog::insertAllPPDValues( ListBox& rBox, const PPDParser* pParser, const PPDKey* pKey )
32 if( ! pKey || ! pParser )
33 return;
35 const PPDValue* pValue = NULL;
36 sal_Int32 nPos = 0;
37 OUString aOptionText;
39 for( int i = 0; i < pKey->countValues(); i++ )
41 pValue = pKey->getValue( i );
42 if (pValue->m_bCustomOption)
43 continue;
44 aOptionText = pParser->translateOption( pKey->getKey(), pValue->m_aOption) ;
46 if( m_aJobData.m_aContext.checkConstraints( pKey, pValue ) )
48 if( rBox.GetEntryPos( (void*)pValue ) == LISTBOX_ENTRY_NOTFOUND )
50 nPos = rBox.InsertEntry( aOptionText, LISTBOX_APPEND );
51 rBox.SetEntryData( nPos, (void*)pValue );
54 else
56 if( ( nPos = rBox.GetEntryPos( (void*)pValue ) ) != LISTBOX_ENTRY_NOTFOUND )
57 rBox.RemoveEntry( nPos );
60 pValue = m_aJobData.m_aContext.getValue( pKey );
61 if (pValue && !pValue->m_bCustomOption)
63 if( ( nPos = rBox.GetEntryPos( (void*)pValue ) ) != LISTBOX_ENTRY_NOTFOUND )
64 rBox.SelectEntryPos( nPos );
66 else
67 rBox.SelectEntry( m_aInvalidString );
71 * RTSDialog
74 RTSDialog::RTSDialog(const PrinterInfo& rJobData, vcl::Window* pParent)
75 : TabDialog(pParent, "PrinterPropertiesDialog", "vcl/ui/printerpropertiesdialog.ui")
76 , m_aJobData(rJobData)
77 , m_pPaperPage(NULL)
78 , m_pDevicePage(NULL)
79 , m_aInvalidString(VclResId(SV_PRINT_INVALID_TXT))
80 , mbDataModified(false)
82 get(m_pOKButton, "ok");
83 get(m_pCancelButton, "cancel");
84 get(m_pTabControl, "notebook");
86 OUString aTitle(GetText());
87 SetText(aTitle.replaceAll("%s", m_aJobData.m_aPrinterName));
89 m_pTabControl->SetActivatePageHdl( LINK( this, RTSDialog, ActivatePage ) );
90 m_pOKButton->SetClickHdl( LINK( this, RTSDialog, ClickButton ) );
91 m_pCancelButton->SetClickHdl( LINK( this, RTSDialog, ClickButton ) );
92 ActivatePage(m_pTabControl);
95 RTSDialog::~RTSDialog()
97 disposeOnce();
100 void RTSDialog::dispose()
102 m_pTabControl.clear();
103 m_pOKButton.clear();
104 m_pCancelButton.clear();
105 m_pPaperPage.disposeAndClear();
106 m_pDevicePage.disposeAndClear();
107 TabDialog::dispose();
110 IMPL_LINK( RTSDialog, ActivatePage, TabControl*, pTabCtrl )
112 if( pTabCtrl != m_pTabControl )
113 return 0;
115 sal_uInt16 nId = m_pTabControl->GetCurPageId();
116 OString sPage = m_pTabControl->GetPageName(nId);
117 if ( ! m_pTabControl->GetTabPage( nId ) )
119 TabPage *pPage = NULL;
120 if (sPage == "paper")
121 pPage = m_pPaperPage = VclPtr<RTSPaperPage>::Create( this );
122 else if (sPage == "device")
123 pPage = m_pDevicePage = VclPtr<RTSDevicePage>::Create( this );
124 if( pPage )
125 m_pTabControl->SetTabPage( nId, pPage );
127 else
129 if (sPage == "paper")
130 m_pPaperPage->update();
133 return 0;
136 IMPL_LINK( RTSDialog, ClickButton, Button*, pButton )
138 if( pButton == m_pOKButton )
140 // refresh the changed values
141 if( m_pPaperPage )
143 // orientation
144 m_aJobData.m_eOrientation = m_pPaperPage->getOrientation() == 0 ?
145 orientation::Portrait : orientation::Landscape;
147 if( m_pDevicePage )
149 m_aJobData.m_nColorDepth = m_pDevicePage->getDepth();
150 m_aJobData.m_nColorDevice = m_pDevicePage->getColorDevice();
151 m_aJobData.m_nPSLevel = m_pDevicePage->getLevel();
152 m_aJobData.m_nPDFDevice = m_pDevicePage->getPDFDevice();
154 EndDialog( 1 );
156 else if( pButton == m_pCancelButton )
157 EndDialog( 0 );
159 return 0;
163 * RTSPaperPage
166 RTSPaperPage::RTSPaperPage(RTSDialog* pParent)
167 : TabPage(pParent->m_pTabControl, "PrinterPaperPage", "vcl/ui/printerpaperpage.ui")
168 , m_pParent( pParent )
170 get(m_pPaperText, "paperft");
171 get(m_pPaperBox, "paperlb");
172 get(m_pOrientBox, "orientlb");
173 get(m_pDuplexText, "duplexft");
174 get(m_pDuplexBox, "duplexlb");
175 get(m_pSlotText, "slotft");
176 get(m_pSlotBox, "slotlb");
178 m_pPaperBox->SetSelectHdl( LINK( this, RTSPaperPage, SelectHdl ) );
179 m_pOrientBox->SetSelectHdl( LINK( this, RTSPaperPage, SelectHdl ) );
180 m_pDuplexBox->SetSelectHdl( LINK( this, RTSPaperPage, SelectHdl ) );
181 m_pSlotBox->SetSelectHdl( LINK( this, RTSPaperPage, SelectHdl ) );
183 sal_Int32 nPos = 0;
185 // duplex
186 nPos = m_pDuplexBox->InsertEntry( m_pParent->m_aInvalidString );
187 m_pDuplexBox->SetEntryData( nPos, NULL );
189 // paper does not have an invalid entry
191 // input slots
192 nPos = m_pSlotBox->InsertEntry( m_pParent->m_aInvalidString );
193 m_pSlotBox->SetEntryData( nPos, NULL );
195 update();
198 RTSPaperPage::~RTSPaperPage()
200 disposeOnce();
203 void RTSPaperPage::dispose()
205 m_pParent.clear();
206 m_pPaperText.clear();
207 m_pPaperBox.clear();
208 m_pOrientBox.clear();
209 m_pDuplexText.clear();
210 m_pDuplexBox.clear();
211 m_pSlotText.clear();
212 m_pSlotBox.clear();
213 TabPage::dispose();
216 void RTSPaperPage::update()
218 const PPDKey* pKey = NULL;
220 // orientation
221 m_pOrientBox->SelectEntryPos(
222 m_pParent->m_aJobData.m_eOrientation == orientation::Portrait ? 0 : 1);
224 // duplex
225 if( m_pParent->m_aJobData.m_pParser &&
226 (pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString( "Duplex" ) )) )
228 m_pParent->insertAllPPDValues( *m_pDuplexBox, m_pParent->m_aJobData.m_pParser, pKey );
230 else
232 m_pDuplexText->Enable( false );
233 m_pDuplexBox->Enable( false );
236 // paper
237 if( m_pParent->m_aJobData.m_pParser &&
238 (pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString( "PageSize" ) )) )
240 m_pParent->insertAllPPDValues( *m_pPaperBox, m_pParent->m_aJobData.m_pParser, pKey );
242 else
244 m_pPaperText->Enable( false );
245 m_pPaperBox->Enable( false );
248 // input slots
249 if( m_pParent->m_aJobData.m_pParser &&
250 (pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString("InputSlot") )) )
252 m_pParent->insertAllPPDValues( *m_pSlotBox, m_pParent->m_aJobData.m_pParser, pKey );
254 else
256 m_pSlotText->Enable( false );
257 m_pSlotBox->Enable( false );
260 // disable those, unless user wants to use papersize from printer prefs
261 // as they have no influence on what's going to be printed anyway
262 if (!m_pParent->m_aJobData.m_bPapersizeFromSetup)
264 m_pPaperBox->Enable( false );
265 m_pOrientBox->Enable( false );
269 IMPL_LINK( RTSPaperPage, SelectHdl, ListBox*, pBox )
271 const PPDKey* pKey = NULL;
272 if( pBox == m_pPaperBox )
274 if( m_pParent->m_aJobData.m_pParser )
275 pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString( "PageSize" ) );
277 else if( pBox == m_pDuplexBox )
279 if( m_pParent->m_aJobData.m_pParser )
280 pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString( "Duplex" ) );
282 else if( pBox == m_pSlotBox )
284 if( m_pParent->m_aJobData.m_pParser )
285 pKey = m_pParent->m_aJobData.m_pParser->getKey( OUString( "InputSlot" ) );
287 else if( pBox == m_pOrientBox )
289 m_pParent->m_aJobData.m_eOrientation = m_pOrientBox->GetSelectEntryPos() == 0 ? orientation::Portrait : orientation::Landscape;
291 if( pKey )
293 PPDValue* pValue = static_cast<PPDValue*>(pBox->GetSelectEntryData());
294 m_pParent->m_aJobData.m_aContext.setValue( pKey, pValue );
295 update();
297 m_pParent->SetDataModified( true );
298 return 0;
302 * RTSDevicePage
305 RTSDevicePage::RTSDevicePage( RTSDialog* pParent )
306 : TabPage(pParent->m_pTabControl, "PrinterDevicePage", "vcl/ui/printerdevicepage.ui")
307 , m_pParent(pParent)
308 , m_pCustomValue(NULL)
310 get(m_pPPDKeyBox, "options");
311 get(m_pPPDValueBox, "values");
313 m_pPPDKeyBox->SetDropDownLineCount(12);
314 m_pPPDValueBox->SetDropDownLineCount(12);
316 get(m_pCustomEdit, "custom");
317 m_pCustomEdit->SetModifyHdl(LINK(this, RTSDevicePage, ModifyHdl));
319 get(m_pLevelBox, "level");
320 get(m_pSpaceBox, "colorspace");
321 get(m_pDepthBox, "colordepth");
323 m_pPPDKeyBox->SetSelectHdl( LINK( this, RTSDevicePage, SelectHdl ) );
324 m_pPPDValueBox->SetSelectHdl( LINK( this, RTSDevicePage, SelectHdl ) );
326 switch( m_pParent->m_aJobData.m_nColorDevice )
328 case 0: m_pSpaceBox->SelectEntryPos(0);break;
329 case 1: m_pSpaceBox->SelectEntryPos(1);break;
330 case -1: m_pSpaceBox->SelectEntryPos(2);break;
333 sal_uLong nLevelEntryData = 0; //automatic
334 if( m_pParent->m_aJobData.m_nPDFDevice == 2 ) //explicit PDF
335 nLevelEntryData = 10;
336 else if (m_pParent->m_aJobData.m_nPSLevel > 0) //explicit PS Level
337 nLevelEntryData = m_pParent->m_aJobData.m_nPSLevel+1;
338 else if (m_pParent->m_aJobData.m_nPDFDevice == 1) //automatically PDF
339 nLevelEntryData = 0;
340 else if (m_pParent->m_aJobData.m_nPDFDevice == -1) //explicitly PS from driver
341 nLevelEntryData = 1;
343 bool bAutoIsPDF = officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get();
345 assert(nLevelEntryData != 0
346 || "Generic Printer" == m_pParent->m_aJobData.m_aPrinterName
347 || int(bAutoIsPDF) == m_pParent->m_aJobData.m_nPDFDevice);
349 OUString sStr = m_pLevelBox->GetEntry(0);
350 m_pLevelBox->InsertEntry(sStr.replaceAll("%s", bAutoIsPDF ? m_pLevelBox->GetEntry(5) : m_pLevelBox->GetEntry(1)), 0);
351 m_pLevelBox->SetEntryData(0, m_pLevelBox->GetEntryData(1));
352 m_pLevelBox->RemoveEntry(1);
354 for( sal_uInt16 i = 0; i < m_pLevelBox->GetEntryCount(); i++ )
356 if( reinterpret_cast<sal_uLong>(m_pLevelBox->GetEntryData( i )) == nLevelEntryData )
358 m_pLevelBox->SelectEntryPos( i );
359 break;
363 if (m_pParent->m_aJobData.m_nColorDepth == 8)
364 m_pDepthBox->SelectEntryPos(0);
365 else if (m_pParent->m_aJobData.m_nColorDepth == 24)
366 m_pDepthBox->SelectEntryPos(1);
368 // fill ppd boxes
369 if( m_pParent->m_aJobData.m_pParser )
371 for( int i = 0; i < m_pParent->m_aJobData.m_pParser->getKeys(); i++ )
373 const PPDKey* pKey = m_pParent->m_aJobData.m_pParser->getKey( i );
375 // skip options already shown somewhere else
376 // also skip options from the "InstallableOptions" PPD group
377 // Options in that group define hardware features that are not
378 // job-specific and should better be handled in the system-wide
379 // printer configuration. Keyword is defined in PPD specification
380 // (version 4.3), section 5.4.
381 if( pKey->isUIKey() &&
382 pKey->getKey() != "PageSize" &&
383 pKey->getKey() != "InputSlot" &&
384 pKey->getKey() != "PageRegion" &&
385 pKey->getKey() != "Duplex" &&
386 pKey->getGroup() != "InstallableOptions")
388 OUString aEntry( m_pParent->m_aJobData.m_pParser->translateKey( pKey->getKey() ) );
389 sal_uInt16 nPos = m_pPPDKeyBox->InsertEntry( aEntry );
390 m_pPPDKeyBox->SetEntryData( nPos, (void*)pKey );
396 RTSDevicePage::~RTSDevicePage()
398 disposeOnce();
401 void RTSDevicePage::dispose()
403 m_pParent.clear();
404 m_pPPDKeyBox.clear();
405 m_pPPDValueBox.clear();
406 m_pCustomEdit.clear();
407 m_pLevelBox.clear();
408 m_pSpaceBox.clear();
409 m_pDepthBox.clear();
410 TabPage::dispose();
413 sal_uLong RTSDevicePage::getDepth()
415 sal_uInt16 nSelectPos = m_pDepthBox->GetSelectEntryPos();
416 if (nSelectPos == 0)
417 return 8;
418 else
419 return 24;
422 sal_uLong RTSDevicePage::getColorDevice()
424 sal_uInt16 nSelectPos = m_pSpaceBox->GetSelectEntryPos();
425 switch (nSelectPos)
427 case 0:
428 return 0;
429 case 1:
430 return 1;
431 case 2:
432 return -1;
434 return 0;
437 sal_uLong RTSDevicePage::getLevel()
439 sal_uLong nLevel = reinterpret_cast<sal_uLong>(m_pLevelBox->GetSelectEntryData());
440 if (nLevel == 0)
441 return 0; //automatic
442 return nLevel < 10 ? nLevel-1 : 0;
445 sal_uLong RTSDevicePage::getPDFDevice()
447 sal_uLong nLevel = reinterpret_cast<sal_uLong>(m_pLevelBox->GetSelectEntryData());
448 if (nLevel > 9)
449 return 2; //explicitly PDF
450 else if (nLevel == 0)
451 return 0; //automatic
452 return -1; //explicitly PS
455 IMPL_LINK(RTSDevicePage, ModifyHdl, Edit*, pEdit)
457 if (m_pCustomValue)
459 m_pCustomValue->m_aCustomOption = pEdit->GetText();
461 return 0;
464 IMPL_LINK( RTSDevicePage, SelectHdl, ListBox*, pBox )
466 if( pBox == m_pPPDKeyBox )
468 const PPDKey* pKey = static_cast<PPDKey*>(m_pPPDKeyBox->GetSelectEntryData());
469 FillValueBox( pKey );
471 else if( pBox == m_pPPDValueBox )
473 const PPDKey* pKey = static_cast<PPDKey*>(m_pPPDKeyBox->GetSelectEntryData());
474 const PPDValue* pValue = static_cast<PPDValue*>(m_pPPDValueBox->GetSelectEntryData());
475 if (pKey && pValue)
477 m_pParent->m_aJobData.m_aContext.setValue( pKey, pValue );
478 FillValueBox( pKey );
481 m_pParent->SetDataModified( true );
482 return 0;
485 void RTSDevicePage::FillValueBox( const PPDKey* pKey )
487 m_pPPDValueBox->Clear();
488 m_pCustomEdit->Hide();
490 if( ! pKey )
491 return;
493 const PPDValue* pValue = NULL;
494 for( int i = 0; i < pKey->countValues(); i++ )
496 pValue = pKey->getValue( i );
497 if( m_pParent->m_aJobData.m_aContext.checkConstraints( pKey, pValue ) &&
498 m_pParent->m_aJobData.m_pParser )
500 OUString aEntry;
501 if (pValue->m_bCustomOption)
502 aEntry = VclResId(SV_PRINT_CUSTOM_TXT);
503 else
504 aEntry = OUString(m_pParent->m_aJobData.m_pParser->translateOption( pKey->getKey(), pValue->m_aOption));
505 sal_uInt16 nPos = m_pPPDValueBox->InsertEntry( aEntry );
506 m_pPPDValueBox->SetEntryData( nPos, (void*)pValue );
509 pValue = m_pParent->m_aJobData.m_aContext.getValue( pKey );
510 m_pPPDValueBox->SelectEntryPos( m_pPPDValueBox->GetEntryPos( (void*)pValue ) );
511 if (pValue->m_bCustomOption)
513 m_pCustomValue = pValue;
514 m_pParent->m_aJobData.m_aContext.setValue(pKey, pValue);
515 m_pCustomEdit->SetText(m_pCustomValue->m_aCustomOption);
516 m_pCustomEdit->Show();
520 int SetupPrinterDriver(::psp::PrinterInfo& rJobData)
522 int nRet = 0;
523 ScopedVclPtrInstance< RTSDialog > aDialog( rJobData, nullptr );
525 // return 0 if cancel was pressed or if the data
526 // weren't modified, 1 otherwise
527 if( aDialog->Execute() )
529 rJobData = aDialog->getSetup();
530 nRet = aDialog->GetDataModified() ? 1 : 0;
533 return nRet;
536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */