1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "basicrenderable.hxx"
21 #include <bastypes.hxx>
22 #include <iderid.hxx>
23 #include <strings.hrc>
24 
25 #include <toolkit/awt/vclxdevice.hxx>
26 #include <tools/multisel.hxx>
27 #include <cppuhelper/compbase.hxx>
28 #include <comphelper/propertysequence.hxx>
29 
30 namespace basctl
31 {
32 
33 using namespace com::sun::star;
34 using namespace com::sun::star::uno;
35 
Renderable(BaseWindow * pWin)36 Renderable::Renderable (BaseWindow* pWin)
37 : cppu::WeakComponentImplHelper< css::view::XRenderable >( maMutex )
38 , mpWindow( pWin )
39 {
40     m_aUIProperties.resize( 4 );
41 
42     // show Subgroup for print range
43     vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
44     aPrintRangeOpt.maGroupHint = "PrintRange" ;
45     aPrintRangeOpt.mbInternalOnly = true;
46 
47     m_aUIProperties[0].Value = setSubgroupControlOpt("printrange",
48         IDEResId( RID_STR_PRINTDLG_PAGES ), OUString(), aPrintRangeOpt);
49 
50     // create a choice for the range to print
51     OUString aPrintContentName( "PrintContent" );
52     const Sequence<OUString> aChoices{IDEResId(RID_STR_PRINTDLG_PRINTALLPAGES),
53                                       IDEResId(RID_STR_PRINTDLG_PRINTPAGES)};
54     const Sequence<OUString> aHelpIds{".HelpID:vcl:PrintDialog:PrintContent:RadioButton:0",
55                                       ".HelpID:vcl:PrintDialog:PrintContent:RadioButton:1"};
56     const Sequence<OUString> aWidgetIds{"rbAllPages",
57                                         "rbRangePages"};
58     m_aUIProperties[1].Value = setChoiceRadiosControlOpt(aWidgetIds, OUString(),
59                                                    aHelpIds, aPrintContentName,
60                                                    aChoices, 0);
61 
62     // create an Edit dependent on "Pages" selected
63     vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt(aPrintContentName, 1, true);
64     m_aUIProperties[2].Value = setEditControlOpt("pagerange", OUString(),
65                                                  OUString(), "PageRange",
66                                                  OUString(), aPageRangeOpt);
67 
68     vcl::PrinterOptionsHelper::UIControlOptions aEvenOddOpt(aPrintContentName, 0, true);
69     m_aUIProperties[3].Value = setChoiceListControlOpt("evenoddbox",
70                                                         OUString(),
71                                                         uno::Sequence<OUString>(),
72                                                         "EvenOdd",
73                                                         uno::Sequence<OUString>(),
74                                                         0,
75                                                         uno::Sequence< sal_Bool >(),
76                                                         aEvenOddOpt);
77 }
78 
~Renderable()79 Renderable::~Renderable()
80 {
81 }
82 
getPrinter() const83 VclPtr< Printer > Renderable::getPrinter() const
84 {
85     VclPtr< Printer > pPrinter;
86     Any aValue( getValue( "RenderDevice" ) );
87     Reference<awt::XDevice> xRenderDevice;
88 
89     if( aValue >>= xRenderDevice )
90     {
91         VCLXDevice* pDevice = comphelper::getUnoTunnelImplementation<VCLXDevice>(xRenderDevice);
92         VclPtr< OutputDevice > pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
93         pPrinter = dynamic_cast<Printer*>(pOut.get());
94     }
95     return pPrinter;
96 }
97 
isPrintOddPages() const98 bool Renderable::isPrintOddPages() const
99 {
100     sal_Int64 nContent = getIntValue( "PrintContent", -1 );
101     return nContent != 2;
102 }
103 
isPrintEvenPages() const104 bool Renderable::isPrintEvenPages() const
105 {
106     sal_Int64 nContent = getIntValue( "PrintContent", -1 );
107     return nContent != 3;
108 }
109 
getRendererCount(const Any &,const Sequence<beans::PropertyValue> & i_xOptions)110 sal_Int32 SAL_CALL Renderable::getRendererCount (
111         const Any&, const Sequence<beans::PropertyValue >& i_xOptions
112         )
113 {
114     processProperties( i_xOptions );
115 
116     maValidPages.clear();
117 
118     sal_Int32 nCount = 0;
119     if( mpWindow )
120     {
121         VclPtr<Printer> pPrinter = getPrinter();
122         if (!pPrinter)
123             throw lang::IllegalArgumentException("no printer", static_cast<cppu::OWeakObject*>(this), -1);
124 
125         nCount = mpWindow->countPages( pPrinter );
126 
127         for (sal_Int32 nPage = 1; nPage <= nCount; nPage++)
128         {
129             if ( (isPrintEvenPages() && isOnEvenPage( nPage ))
130                 || (isPrintOddPages() && !isOnEvenPage( nPage )) )
131             {
132                 maValidPages.push_back( nPage-1 );
133             }
134         }
135 
136         sal_Int64 nContent = getIntValue( "PrintContent", -1 );
137         sal_Int64 nEOContent = getIntValue ("EvenOdd", -1);
138         if( nContent == 1 )
139         {
140             OUString aPageRange( getStringValue( "PageRange" ) );
141             if( !aPageRange.isEmpty() )
142             {
143                 StringRangeEnumerator aRangeEnum( aPageRange, 0, nCount-1 );
144                 sal_Int32 nSelCount = aRangeEnum.size();
145                 if( nSelCount >= 0 )
146                     nCount = nSelCount;
147             }
148         }
149         else if ( nEOContent == 1 || nEOContent == 2 ) // even/odd pages
150             return static_cast<sal_Int32>( maValidPages.size() );
151     }
152 
153     return nCount;
154 }
155 
getRenderer(sal_Int32,const Any &,const Sequence<beans::PropertyValue> & i_xOptions)156 Sequence<beans::PropertyValue> SAL_CALL Renderable::getRenderer (
157         sal_Int32, const Any&, const Sequence<beans::PropertyValue>& i_xOptions
158         )
159 {
160     processProperties( i_xOptions );
161 
162     Sequence< beans::PropertyValue > aVals;
163     // insert page size here
164     VclPtr<Printer> pPrinter = getPrinter();
165     // no renderdevice is legal; the first call is to get our print ui options
166     if( pPrinter )
167     {
168         Size aPageSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), MapMode( MapUnit::Map100thMM ) ) );
169 
170         awt::Size aSize;
171         aSize.Width  = aPageSize.Width();
172         aSize.Height = aPageSize.Height();
173         aVals = ::comphelper::InitPropertySequence({
174             { "PageSize", Any(aSize) }
175         });
176     }
177 
178     appendPrintUIOptions( aVals );
179 
180     return aVals;
181 }
182 
render(sal_Int32 nRenderer,const Any &,const Sequence<beans::PropertyValue> & i_xOptions)183 void SAL_CALL Renderable::render (
184         sal_Int32 nRenderer, const Any&,
185         const Sequence<beans::PropertyValue>& i_xOptions
186         )
187 {
188     processProperties( i_xOptions );
189 
190     if( !mpWindow )
191         return;
192 
193     VclPtr<Printer> pPrinter = getPrinter();
194     if (!pPrinter)
195         throw lang::IllegalArgumentException("no printer", static_cast<cppu::OWeakObject*>(this), -1);
196 
197     sal_Int64 nContent = getIntValue( "PrintContent", -1 );
198     if( nContent == 1 )
199     {
200         OUString aPageRange( getStringValue( "PageRange" ) );
201         if( !aPageRange.isEmpty() )
202         {
203             sal_Int32 nPageCount = mpWindow->countPages( pPrinter );
204             StringRangeEnumerator aRangeEnum( aPageRange, 0, nPageCount-1 );
205             StringRangeEnumerator::Iterator it = aRangeEnum.begin();
206             for( ; it != aRangeEnum.end() && nRenderer; --nRenderer )
207                 ++it;
208 
209             sal_Int32 nPage = ( it != aRangeEnum.end() ) ? *it : nRenderer;
210             mpWindow->printPage( nPage, pPrinter );
211         }
212         else
213             mpWindow->printPage( nRenderer, pPrinter );
214     }
215     else
216         mpWindow->printPage( maValidPages.at( nRenderer ), pPrinter );
217 }
218 
219 } // namespace basctl
220 
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
222