1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sdext.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "PresenterHelpView.hxx"
32*cdf0e10cSrcweir #include "PresenterButton.hxx"
33*cdf0e10cSrcweir #include "PresenterCanvasHelper.hxx"
34*cdf0e10cSrcweir #include "PresenterGeometryHelper.hxx"
35*cdf0e10cSrcweir #include "PresenterHelper.hxx"
36*cdf0e10cSrcweir #include "PresenterWindowManager.hxx"
37*cdf0e10cSrcweir #include <com/sun/star/awt/XWindowPeer.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/drawing/framework/XControllerManager.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/rendering/CompositeOperation.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/rendering/TextDirection.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/util/Color.hpp>
44*cdf0e10cSrcweir #include <algorithm>
45*cdf0e10cSrcweir #include <vector>
46*cdf0e10cSrcweir #include <boost/bind.hpp>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir using namespace ::com::sun::star;
49*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
50*cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
51*cdf0e10cSrcweir using ::rtl::OUString;
52*cdf0e10cSrcweir using ::std::vector;
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir namespace sdext { namespace presenter {
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir namespace {
60*cdf0e10cSrcweir     const static sal_Int32 gnHorizontalGap (20);
61*cdf0e10cSrcweir     const static sal_Int32 gnVerticalBorder (30);
62*cdf0e10cSrcweir     const static sal_Int32 gnVerticalButtonPadding (12);
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir     class LineDescriptor
65*cdf0e10cSrcweir     {
66*cdf0e10cSrcweir     public:
67*cdf0e10cSrcweir         LineDescriptor(void);
68*cdf0e10cSrcweir         void AddPart (
69*cdf0e10cSrcweir             const OUString& rsLine,
70*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
71*cdf0e10cSrcweir         bool IsEmpty (void) const;
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir         OUString msLine;
74*cdf0e10cSrcweir         geometry::RealSize2D maSize;
75*cdf0e10cSrcweir         double mnVerticalOffset;
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir         void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
78*cdf0e10cSrcweir     };
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir     class LineDescriptorList
81*cdf0e10cSrcweir     {
82*cdf0e10cSrcweir     public:
83*cdf0e10cSrcweir         LineDescriptorList (
84*cdf0e10cSrcweir             const OUString& rsText,
85*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
86*cdf0e10cSrcweir             const sal_Int32 nMaximalWidth);
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir         void Update (
89*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
90*cdf0e10cSrcweir             const sal_Int32 nMaximalWidth);
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir         double Paint(
93*cdf0e10cSrcweir             const Reference<rendering::XCanvas>& rxCanvas,
94*cdf0e10cSrcweir             const geometry::RealRectangle2D& rBBox,
95*cdf0e10cSrcweir             const bool bFlushLeft,
96*cdf0e10cSrcweir             const rendering::ViewState& rViewState,
97*cdf0e10cSrcweir             rendering::RenderState& rRenderState,
98*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
99*cdf0e10cSrcweir         double GetHeight (void) const;
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir     private:
102*cdf0e10cSrcweir         const OUString msText;
103*cdf0e10cSrcweir         ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir         void SplitText (const ::rtl::OUString& rsText, vector<rtl::OUString>& rTextParts);
106*cdf0e10cSrcweir         void FormatText (
107*cdf0e10cSrcweir             const vector<rtl::OUString>& rTextParts,
108*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
109*cdf0e10cSrcweir             const sal_Int32 nMaximalWidth);
110*cdf0e10cSrcweir     };
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir     class Block
113*cdf0e10cSrcweir     {
114*cdf0e10cSrcweir     public:
115*cdf0e10cSrcweir         Block (const Block& rBlock);
116*cdf0e10cSrcweir         Block (
117*cdf0e10cSrcweir             const OUString& rsLeftText,
118*cdf0e10cSrcweir             const OUString& rsRightText,
119*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
120*cdf0e10cSrcweir             const sal_Int32 nMaximalWidth);
121*cdf0e10cSrcweir         void Update (
122*cdf0e10cSrcweir             const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
123*cdf0e10cSrcweir             const sal_Int32 nMaximalWidth);
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir         LineDescriptorList maLeft;
126*cdf0e10cSrcweir         LineDescriptorList maRight;
127*cdf0e10cSrcweir     };
128*cdf0e10cSrcweir } // end of anonymous namespace
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir };
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir PresenterHelpView::PresenterHelpView (
136*cdf0e10cSrcweir     const Reference<uno::XComponentContext>& rxContext,
137*cdf0e10cSrcweir     const Reference<XResourceId>& rxViewId,
138*cdf0e10cSrcweir     const Reference<frame::XController>& rxController,
139*cdf0e10cSrcweir     const ::rtl::Reference<PresenterController>& rpPresenterController)
140*cdf0e10cSrcweir     : PresenterHelpViewInterfaceBase(m_aMutex),
141*cdf0e10cSrcweir       mxComponentContext(rxContext),
142*cdf0e10cSrcweir       mxViewId(rxViewId),
143*cdf0e10cSrcweir       mxPane(),
144*cdf0e10cSrcweir       mxWindow(),
145*cdf0e10cSrcweir       mxCanvas(),
146*cdf0e10cSrcweir       mpPresenterController(rpPresenterController),
147*cdf0e10cSrcweir       mpFont(),
148*cdf0e10cSrcweir       mpTextContainer(),
149*cdf0e10cSrcweir       mpCloseButton(),
150*cdf0e10cSrcweir       mnSeparatorY(0),
151*cdf0e10cSrcweir       mnMaximalWidth(0)
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir     try
154*cdf0e10cSrcweir     {
155*cdf0e10cSrcweir         // Get the content window via the pane anchor.
156*cdf0e10cSrcweir         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
157*cdf0e10cSrcweir         Reference<XConfigurationController> xCC (
158*cdf0e10cSrcweir             xCM->getConfigurationController(), UNO_QUERY_THROW);
159*cdf0e10cSrcweir         mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir         mxWindow = mxPane->getWindow();
162*cdf0e10cSrcweir         ProvideCanvas();
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir         mxWindow->addWindowListener(this);
165*cdf0e10cSrcweir         mxWindow->addPaintListener(this);
166*cdf0e10cSrcweir         Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
167*cdf0e10cSrcweir         if (xPeer.is())
168*cdf0e10cSrcweir             xPeer->setBackground(util::Color(0xff000000));
169*cdf0e10cSrcweir         mxWindow->setVisible(sal_True);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir         if (mpPresenterController.is())
172*cdf0e10cSrcweir         {
173*cdf0e10cSrcweir             mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
174*cdf0e10cSrcweir             if (mpFont.get() != NULL)
175*cdf0e10cSrcweir             {
176*cdf0e10cSrcweir                 mpFont->PrepareFont(mxCanvas);
177*cdf0e10cSrcweir             }
178*cdf0e10cSrcweir         }
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir         // Create the close button.
181*cdf0e10cSrcweir         mpCloseButton = PresenterButton::Create(
182*cdf0e10cSrcweir             mxComponentContext,
183*cdf0e10cSrcweir             mpPresenterController,
184*cdf0e10cSrcweir             mpPresenterController->GetTheme(),
185*cdf0e10cSrcweir             mxWindow,
186*cdf0e10cSrcweir             mxCanvas,
187*cdf0e10cSrcweir             A2S("HelpViewCloser"));
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir         ReadHelpStrings();
190*cdf0e10cSrcweir         Resize();
191*cdf0e10cSrcweir     }
192*cdf0e10cSrcweir     catch (RuntimeException&)
193*cdf0e10cSrcweir     {
194*cdf0e10cSrcweir         mxViewId = NULL;
195*cdf0e10cSrcweir         mxWindow = NULL;
196*cdf0e10cSrcweir         throw;
197*cdf0e10cSrcweir     }
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir PresenterHelpView::~PresenterHelpView (void)
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir }
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::disposing (void)
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir     mxViewId = NULL;
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir     if (mpCloseButton.is())
215*cdf0e10cSrcweir     {
216*cdf0e10cSrcweir         Reference<lang::XComponent> xComponent (
217*cdf0e10cSrcweir             static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
218*cdf0e10cSrcweir         mpCloseButton = NULL;
219*cdf0e10cSrcweir         if (xComponent.is())
220*cdf0e10cSrcweir             xComponent->dispose();
221*cdf0e10cSrcweir     }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir     if (mxWindow.is())
224*cdf0e10cSrcweir     {
225*cdf0e10cSrcweir         mxWindow->removeWindowListener(this);
226*cdf0e10cSrcweir         mxWindow->removePaintListener(this);
227*cdf0e10cSrcweir     }
228*cdf0e10cSrcweir }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir //----- lang::XEventListener --------------------------------------------------
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject)
236*cdf0e10cSrcweir     throw (RuntimeException)
237*cdf0e10cSrcweir {
238*cdf0e10cSrcweir     if (rEventObject.Source == mxCanvas)
239*cdf0e10cSrcweir     {
240*cdf0e10cSrcweir         mxCanvas = NULL;
241*cdf0e10cSrcweir     }
242*cdf0e10cSrcweir     else if (rEventObject.Source == mxWindow)
243*cdf0e10cSrcweir     {
244*cdf0e10cSrcweir         mxWindow = NULL;
245*cdf0e10cSrcweir         dispose();
246*cdf0e10cSrcweir     }
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir //----- XWindowListener -------------------------------------------------------
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent& rEvent)
255*cdf0e10cSrcweir     throw (uno::RuntimeException)
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     (void)rEvent;
258*cdf0e10cSrcweir     ThrowIfDisposed();
259*cdf0e10cSrcweir     Resize();
260*cdf0e10cSrcweir }
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 
265*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent& rEvent)
266*cdf0e10cSrcweir     throw (uno::RuntimeException)
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir     (void)rEvent;
269*cdf0e10cSrcweir     ThrowIfDisposed();
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject& rEvent)
276*cdf0e10cSrcweir     throw (uno::RuntimeException)
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir     (void)rEvent;
279*cdf0e10cSrcweir     ThrowIfDisposed();
280*cdf0e10cSrcweir     Resize();
281*cdf0e10cSrcweir }
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject& rEvent)
287*cdf0e10cSrcweir     throw (uno::RuntimeException)
288*cdf0e10cSrcweir {
289*cdf0e10cSrcweir     (void)rEvent;
290*cdf0e10cSrcweir     ThrowIfDisposed();
291*cdf0e10cSrcweir }
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir //----- XPaintListener --------------------------------------------------------
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent)
299*cdf0e10cSrcweir     throw (RuntimeException)
300*cdf0e10cSrcweir {
301*cdf0e10cSrcweir     Paint(rEvent.UpdateRect);
302*cdf0e10cSrcweir }
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
308*cdf0e10cSrcweir {
309*cdf0e10cSrcweir     ProvideCanvas();
310*cdf0e10cSrcweir     if ( ! mxCanvas.is())
311*cdf0e10cSrcweir         return;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir     // Clear background.
314*cdf0e10cSrcweir     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
315*cdf0e10cSrcweir     mpPresenterController->GetCanvasHelper()->Paint(
316*cdf0e10cSrcweir         mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
317*cdf0e10cSrcweir         Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
318*cdf0e10cSrcweir         rUpdateBox,
319*cdf0e10cSrcweir         awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
320*cdf0e10cSrcweir         awt::Rectangle());
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir     // Paint vertical divider.
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir     rendering::ViewState aViewState(
325*cdf0e10cSrcweir         geometry::AffineMatrix2D(1,0,0, 0,1,0),
326*cdf0e10cSrcweir         PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir     rendering::RenderState aRenderState (
329*cdf0e10cSrcweir         geometry::AffineMatrix2D(1,0,0, 0,1,0),
330*cdf0e10cSrcweir         NULL,
331*cdf0e10cSrcweir         Sequence<double>(4),
332*cdf0e10cSrcweir         rendering::CompositeOperation::SOURCE);
333*cdf0e10cSrcweir     PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir     mxCanvas->drawLine(
336*cdf0e10cSrcweir         geometry::RealPoint2D(aWindowBox.Width/2, gnVerticalBorder),
337*cdf0e10cSrcweir         geometry::RealPoint2D(aWindowBox.Width/2, mnSeparatorY - gnVerticalBorder),
338*cdf0e10cSrcweir         aViewState,
339*cdf0e10cSrcweir         aRenderState);
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir     // Paint the horizontal separator.
342*cdf0e10cSrcweir     mxCanvas->drawLine(
343*cdf0e10cSrcweir         geometry::RealPoint2D(0, mnSeparatorY),
344*cdf0e10cSrcweir         geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
345*cdf0e10cSrcweir         aViewState,
346*cdf0e10cSrcweir         aRenderState);
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     // Paint text.
349*cdf0e10cSrcweir     double nY (gnVerticalBorder);
350*cdf0e10cSrcweir     TextContainer::const_iterator iBlock (mpTextContainer->begin());
351*cdf0e10cSrcweir     TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
352*cdf0e10cSrcweir     for ( ; iBlock!=iBlockEnd; ++iBlock)
353*cdf0e10cSrcweir     {
354*cdf0e10cSrcweir         const double nLeftHeight (
355*cdf0e10cSrcweir             (*iBlock)->maLeft.Paint(mxCanvas,
356*cdf0e10cSrcweir                 geometry::RealRectangle2D(
357*cdf0e10cSrcweir                     gnHorizontalGap,
358*cdf0e10cSrcweir                     nY,
359*cdf0e10cSrcweir                     aWindowBox.Width/2 - gnHorizontalGap,
360*cdf0e10cSrcweir                     aWindowBox.Height - gnVerticalBorder),
361*cdf0e10cSrcweir                 false,
362*cdf0e10cSrcweir                 aViewState,
363*cdf0e10cSrcweir                 aRenderState,
364*cdf0e10cSrcweir                 mpFont->mxFont));
365*cdf0e10cSrcweir         const double nRightHeight (
366*cdf0e10cSrcweir             (*iBlock)->maRight.Paint(mxCanvas,
367*cdf0e10cSrcweir                 geometry::RealRectangle2D(
368*cdf0e10cSrcweir                     aWindowBox.Width/2 + gnHorizontalGap,
369*cdf0e10cSrcweir                     nY,
370*cdf0e10cSrcweir                     aWindowBox.Width - gnHorizontalGap,
371*cdf0e10cSrcweir                     aWindowBox.Height - gnVerticalBorder),
372*cdf0e10cSrcweir                 true,
373*cdf0e10cSrcweir                 aViewState,
374*cdf0e10cSrcweir                 aRenderState,
375*cdf0e10cSrcweir                 mpFont->mxFont));
376*cdf0e10cSrcweir         nY += ::std::max(nLeftHeight,nRightHeight);
377*cdf0e10cSrcweir     }
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
380*cdf0e10cSrcweir     if (xSpriteCanvas.is())
381*cdf0e10cSrcweir         xSpriteCanvas->updateScreen(sal_False);
382*cdf0e10cSrcweir }
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir void PresenterHelpView::ReadHelpStrings (void)
388*cdf0e10cSrcweir {
389*cdf0e10cSrcweir     mpTextContainer.reset(new TextContainer());
390*cdf0e10cSrcweir     PresenterConfigurationAccess aConfiguration (
391*cdf0e10cSrcweir         mxComponentContext,
392*cdf0e10cSrcweir         OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
393*cdf0e10cSrcweir         PresenterConfigurationAccess::READ_ONLY);
394*cdf0e10cSrcweir     Reference<container::XNameAccess> xStrings (
395*cdf0e10cSrcweir         aConfiguration.GetConfigurationNode(A2S("PresenterScreenSettings/HelpView/HelpStrings")),
396*cdf0e10cSrcweir         UNO_QUERY);
397*cdf0e10cSrcweir     PresenterConfigurationAccess::ForAll(
398*cdf0e10cSrcweir         xStrings,
399*cdf0e10cSrcweir         ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
400*cdf0e10cSrcweir }
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir void PresenterHelpView::ProcessString (
406*cdf0e10cSrcweir     const Reference<beans::XPropertySet>& rsProperties)
407*cdf0e10cSrcweir {
408*cdf0e10cSrcweir     if ( ! rsProperties.is())
409*cdf0e10cSrcweir         return;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir     OUString sLeftText;
412*cdf0e10cSrcweir     PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Left")) >>= sLeftText;
413*cdf0e10cSrcweir     OUString sRightText;
414*cdf0e10cSrcweir     PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Right")) >>= sRightText;
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
417*cdf0e10cSrcweir     mpTextContainer->push_back(
418*cdf0e10cSrcweir         ::boost::shared_ptr<Block>(
419*cdf0e10cSrcweir             new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
420*cdf0e10cSrcweir }
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 
425*cdf0e10cSrcweir void PresenterHelpView::CheckFontSize (void)
426*cdf0e10cSrcweir {
427*cdf0e10cSrcweir     if (mpFont.get() == NULL)
428*cdf0e10cSrcweir         return;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
431*cdf0e10cSrcweir     if (aWindowBox.Width<=0 || aWindowBox.Height<=0)
432*cdf0e10cSrcweir         return;
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     sal_Int32 nBestSize (6);
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir     // Scaling down and then reformatting can cause the text to be too large
437*cdf0e10cSrcweir     // still.  So do this again and again until the text size is
438*cdf0e10cSrcweir     // small enough.  Restrict the number of loops.
439*cdf0e10cSrcweir     for (int nLoopCount=0; nLoopCount<5; ++nLoopCount)
440*cdf0e10cSrcweir     {
441*cdf0e10cSrcweir         double nY (gnVerticalBorder);
442*cdf0e10cSrcweir         TextContainer::iterator iBlock (mpTextContainer->begin());
443*cdf0e10cSrcweir         TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
444*cdf0e10cSrcweir         for ( ; iBlock!=iBlockEnd; ++iBlock)
445*cdf0e10cSrcweir             nY += ::std::max(
446*cdf0e10cSrcweir                 (*iBlock)->maLeft.GetHeight(),
447*cdf0e10cSrcweir                 (*iBlock)->maRight.GetHeight());
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir         const double nHeightDifference (nY - (aWindowBox.Height-gnVerticalBorder));
450*cdf0e10cSrcweir         if (nHeightDifference <= 0 && nHeightDifference > -50)
451*cdf0e10cSrcweir         {
452*cdf0e10cSrcweir             // We have found a good font size that is large and leaves not
453*cdf0e10cSrcweir             // too much space below the help text.
454*cdf0e10cSrcweir             return;
455*cdf0e10cSrcweir         }
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir         // Font is too large.  Make it smaller.
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir         // Use a simple linear transformation to calculate initial guess of
460*cdf0e10cSrcweir         // a size that lets all help text be shown inside the window.
461*cdf0e10cSrcweir         const double nScale (double(aWindowBox.Height-gnVerticalBorder) / nY);
462*cdf0e10cSrcweir         if (nScale > 0.95 && nScale <1.05)
463*cdf0e10cSrcweir             break;
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir         sal_Int32 nFontSizeGuess (::std::max(sal_Int32(1),sal_Int32(mpFont->mnSize * nScale)));
466*cdf0e10cSrcweir         if (nHeightDifference<0 && mpFont->mnSize>nBestSize)
467*cdf0e10cSrcweir             nBestSize = mpFont->mnSize;
468*cdf0e10cSrcweir         mpFont->mnSize = nFontSizeGuess;
469*cdf0e10cSrcweir         mpFont->mxFont = NULL;
470*cdf0e10cSrcweir         mpFont->PrepareFont(mxCanvas);
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir         // Reformat blocks.
473*cdf0e10cSrcweir         for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
474*cdf0e10cSrcweir             (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
475*cdf0e10cSrcweir     }
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir     if (nBestSize != mpFont->mnSize)
478*cdf0e10cSrcweir     {
479*cdf0e10cSrcweir         mpFont->mnSize = nBestSize;
480*cdf0e10cSrcweir         mpFont->mxFont = NULL;
481*cdf0e10cSrcweir         mpFont->PrepareFont(mxCanvas);
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir         // Reformat blocks.
484*cdf0e10cSrcweir         for (TextContainer::iterator
485*cdf0e10cSrcweir                  iBlock (mpTextContainer->begin()),
486*cdf0e10cSrcweir                  iEnd (mpTextContainer->end());
487*cdf0e10cSrcweir              iBlock!=iEnd;
488*cdf0e10cSrcweir              ++iBlock)
489*cdf0e10cSrcweir         {
490*cdf0e10cSrcweir             (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
491*cdf0e10cSrcweir         }
492*cdf0e10cSrcweir     }
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir 
498*cdf0e10cSrcweir //----- XResourceId -----------------------------------------------------------
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId (void)
501*cdf0e10cSrcweir     throw (RuntimeException)
502*cdf0e10cSrcweir {
503*cdf0e10cSrcweir     ThrowIfDisposed();
504*cdf0e10cSrcweir     return mxViewId;
505*cdf0e10cSrcweir }
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly (void)
511*cdf0e10cSrcweir     throw (RuntimeException)
512*cdf0e10cSrcweir {
513*cdf0e10cSrcweir     return false;
514*cdf0e10cSrcweir }
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir //-----------------------------------------------------------------------------
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir void PresenterHelpView::ProvideCanvas (void)
522*cdf0e10cSrcweir {
523*cdf0e10cSrcweir     if ( ! mxCanvas.is() && mxPane.is())
524*cdf0e10cSrcweir     {
525*cdf0e10cSrcweir         mxCanvas = mxPane->getCanvas();
526*cdf0e10cSrcweir         if ( ! mxCanvas.is())
527*cdf0e10cSrcweir             return;
528*cdf0e10cSrcweir         Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
529*cdf0e10cSrcweir         if (xComponent.is())
530*cdf0e10cSrcweir             xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir         if (mpCloseButton.is())
533*cdf0e10cSrcweir             mpCloseButton->SetCanvas(mxCanvas, mxWindow);
534*cdf0e10cSrcweir     }
535*cdf0e10cSrcweir }
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir void PresenterHelpView::Resize (void)
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir     if (mpCloseButton.get() != NULL && mxWindow.is())
543*cdf0e10cSrcweir     {
544*cdf0e10cSrcweir         const awt::Rectangle aWindowBox (mxWindow->getPosSize());
545*cdf0e10cSrcweir         mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir         // Place vertical separator.
548*cdf0e10cSrcweir         mnSeparatorY = aWindowBox.Height
549*cdf0e10cSrcweir             - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir         mpCloseButton->SetCenter(geometry::RealPoint2D(
552*cdf0e10cSrcweir             aWindowBox.Width/2,
553*cdf0e10cSrcweir             aWindowBox.Height - mpCloseButton->GetSize().Height/2));
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir         CheckFontSize();
556*cdf0e10cSrcweir     }
557*cdf0e10cSrcweir }
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir void PresenterHelpView::ThrowIfDisposed (void)
563*cdf0e10cSrcweir     throw (lang::DisposedException)
564*cdf0e10cSrcweir {
565*cdf0e10cSrcweir 	if (rBHelper.bDisposed || rBHelper.bInDispose)
566*cdf0e10cSrcweir 	{
567*cdf0e10cSrcweir         throw lang::DisposedException (
568*cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM(
569*cdf0e10cSrcweir                 "PresenterHelpView has been already disposed")),
570*cdf0e10cSrcweir             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
571*cdf0e10cSrcweir     }
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir //===== LineDescritor =========================================================
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir namespace {
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir LineDescriptor::LineDescriptor (void)
582*cdf0e10cSrcweir     : msLine(),
583*cdf0e10cSrcweir       maSize(0,0),
584*cdf0e10cSrcweir       mnVerticalOffset(0)
585*cdf0e10cSrcweir {
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir 
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir void LineDescriptor::AddPart (
592*cdf0e10cSrcweir     const OUString& rsLine,
593*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     msLine += rsLine;
596*cdf0e10cSrcweir 
597*cdf0e10cSrcweir     CalculateSize(rxFont);
598*cdf0e10cSrcweir }
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir bool LineDescriptor::IsEmpty (void) const
604*cdf0e10cSrcweir {
605*cdf0e10cSrcweir     return msLine.getLength()==0;
606*cdf0e10cSrcweir }
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir void LineDescriptor::CalculateSize (
612*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
613*cdf0e10cSrcweir {
614*cdf0e10cSrcweir     OSL_ASSERT(rxFont.is());
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir     rendering::StringContext aContext (msLine, 0, msLine.getLength());
617*cdf0e10cSrcweir     Reference<rendering::XTextLayout> xLayout (
618*cdf0e10cSrcweir         rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
619*cdf0e10cSrcweir     const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
620*cdf0e10cSrcweir     maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
621*cdf0e10cSrcweir     mnVerticalOffset = aTextBBox.Y2;
622*cdf0e10cSrcweir }
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir } // end of anonymous namespace
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir //===== LineDescriptorList ====================================================
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir namespace {
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir LineDescriptorList::LineDescriptorList (
634*cdf0e10cSrcweir     const OUString& rsText,
635*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
636*cdf0e10cSrcweir     const sal_Int32 nMaximalWidth)
637*cdf0e10cSrcweir     : msText(rsText)
638*cdf0e10cSrcweir {
639*cdf0e10cSrcweir     Update(rxFont, nMaximalWidth);
640*cdf0e10cSrcweir }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir double LineDescriptorList::Paint(
646*cdf0e10cSrcweir     const Reference<rendering::XCanvas>& rxCanvas,
647*cdf0e10cSrcweir     const geometry::RealRectangle2D& rBBox,
648*cdf0e10cSrcweir     const bool bFlushLeft,
649*cdf0e10cSrcweir     const rendering::ViewState& rViewState,
650*cdf0e10cSrcweir     rendering::RenderState& rRenderState,
651*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
652*cdf0e10cSrcweir {
653*cdf0e10cSrcweir     if ( ! rxCanvas.is())
654*cdf0e10cSrcweir         return 0;
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir     double nY (rBBox.Y1);
657*cdf0e10cSrcweir     vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
658*cdf0e10cSrcweir     vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
659*cdf0e10cSrcweir     for ( ; iLine!=iEnd; ++iLine)
660*cdf0e10cSrcweir     {
661*cdf0e10cSrcweir         double nX (rBBox.X1);
662*cdf0e10cSrcweir         if ( ! bFlushLeft)
663*cdf0e10cSrcweir             nX = rBBox.X2 - iLine->maSize.Width;
664*cdf0e10cSrcweir         rRenderState.AffineTransform.m02 = nX;
665*cdf0e10cSrcweir         rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir         const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir         rxCanvas->drawText (
670*cdf0e10cSrcweir             aContext,
671*cdf0e10cSrcweir             rxFont,
672*cdf0e10cSrcweir             rViewState,
673*cdf0e10cSrcweir             rRenderState,
674*cdf0e10cSrcweir             rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
675*cdf0e10cSrcweir 
676*cdf0e10cSrcweir         nY += iLine->maSize.Height * 1.2;
677*cdf0e10cSrcweir     }
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir     return nY - rBBox.Y1;
680*cdf0e10cSrcweir }
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir double LineDescriptorList::GetHeight (void) const
686*cdf0e10cSrcweir {
687*cdf0e10cSrcweir     double nHeight (0);
688*cdf0e10cSrcweir     vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
689*cdf0e10cSrcweir     vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
690*cdf0e10cSrcweir     for ( ; iLine!=iEnd; ++iLine)
691*cdf0e10cSrcweir         nHeight += iLine->maSize.Height * 1.2;
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir     return nHeight;
694*cdf0e10cSrcweir }
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir void LineDescriptorList::Update (
700*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
701*cdf0e10cSrcweir     const sal_Int32 nMaximalWidth)
702*cdf0e10cSrcweir {
703*cdf0e10cSrcweir     vector<OUString> aTextParts;
704*cdf0e10cSrcweir     SplitText(msText, aTextParts);
705*cdf0e10cSrcweir     FormatText(aTextParts, rxFont, nMaximalWidth);
706*cdf0e10cSrcweir }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir 
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir void LineDescriptorList::SplitText (
712*cdf0e10cSrcweir     const OUString& rsText,
713*cdf0e10cSrcweir     vector<OUString>& rTextParts)
714*cdf0e10cSrcweir {
715*cdf0e10cSrcweir     const sal_Char cQuote ('\'');
716*cdf0e10cSrcweir     const sal_Char cSeparator (',');
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir     sal_Int32 nIndex (0);
719*cdf0e10cSrcweir     sal_Int32 nStart (0);
720*cdf0e10cSrcweir     sal_Int32 nLength (rsText.getLength());
721*cdf0e10cSrcweir     bool bIsQuoted (false);
722*cdf0e10cSrcweir     while (nIndex < nLength)
723*cdf0e10cSrcweir     {
724*cdf0e10cSrcweir         const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
725*cdf0e10cSrcweir         const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
726*cdf0e10cSrcweir         if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
727*cdf0e10cSrcweir         {
728*cdf0e10cSrcweir             bIsQuoted = !bIsQuoted;
729*cdf0e10cSrcweir             nIndex = nQuoteIndex+1;
730*cdf0e10cSrcweir             continue;
731*cdf0e10cSrcweir         }
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir         const sal_Int32 nNextIndex = nSeparatorIndex;
734*cdf0e10cSrcweir         if (nNextIndex < 0)
735*cdf0e10cSrcweir         {
736*cdf0e10cSrcweir             break;
737*cdf0e10cSrcweir         }
738*cdf0e10cSrcweir         else if ( ! bIsQuoted)
739*cdf0e10cSrcweir         {
740*cdf0e10cSrcweir             rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
741*cdf0e10cSrcweir             nStart = nNextIndex + 1;
742*cdf0e10cSrcweir         }
743*cdf0e10cSrcweir         nIndex = nNextIndex+1;
744*cdf0e10cSrcweir     }
745*cdf0e10cSrcweir     if (nStart < nLength)
746*cdf0e10cSrcweir         rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
747*cdf0e10cSrcweir }
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir 
752*cdf0e10cSrcweir void LineDescriptorList::FormatText (
753*cdf0e10cSrcweir     const vector<OUString>& rTextParts,
754*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
755*cdf0e10cSrcweir     const sal_Int32 nMaximalWidth)
756*cdf0e10cSrcweir {
757*cdf0e10cSrcweir     LineDescriptor aLineDescriptor;
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir     mpLineDescriptors.reset(new vector<LineDescriptor>());
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir     vector<OUString>::const_iterator iPart (rTextParts.begin());
762*cdf0e10cSrcweir     vector<OUString>::const_iterator iEnd (rTextParts.end());
763*cdf0e10cSrcweir     for ( ; iPart!=iEnd; ++iPart)
764*cdf0e10cSrcweir     {
765*cdf0e10cSrcweir         if (aLineDescriptor.IsEmpty())
766*cdf0e10cSrcweir         {
767*cdf0e10cSrcweir             // Avoid empty lines.
768*cdf0e10cSrcweir             aLineDescriptor.AddPart(*iPart, rxFont);
769*cdf0e10cSrcweir         }
770*cdf0e10cSrcweir         else if (PresenterCanvasHelper::GetTextSize(
771*cdf0e10cSrcweir             rxFont, aLineDescriptor.msLine+A2S(", ")+*iPart).Width > nMaximalWidth)
772*cdf0e10cSrcweir         {
773*cdf0e10cSrcweir             aLineDescriptor.AddPart(A2S(","), rxFont);
774*cdf0e10cSrcweir             mpLineDescriptors->push_back(aLineDescriptor);
775*cdf0e10cSrcweir             aLineDescriptor = LineDescriptor();
776*cdf0e10cSrcweir             aLineDescriptor.AddPart(*iPart, rxFont);
777*cdf0e10cSrcweir         }
778*cdf0e10cSrcweir         else
779*cdf0e10cSrcweir         {
780*cdf0e10cSrcweir             aLineDescriptor.AddPart(A2S(", ")+*iPart, rxFont);
781*cdf0e10cSrcweir         }
782*cdf0e10cSrcweir     }
783*cdf0e10cSrcweir     if ( ! aLineDescriptor.IsEmpty())
784*cdf0e10cSrcweir     {
785*cdf0e10cSrcweir         mpLineDescriptors->push_back(aLineDescriptor);
786*cdf0e10cSrcweir     }
787*cdf0e10cSrcweir }
788*cdf0e10cSrcweir 
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir } // end of anonymous namespace
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir 
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir //===== Block =================================================================
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir namespace {
798*cdf0e10cSrcweir 
799*cdf0e10cSrcweir Block::Block (
800*cdf0e10cSrcweir     const OUString& rsLeftText,
801*cdf0e10cSrcweir     const OUString& rsRightText,
802*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
803*cdf0e10cSrcweir     const sal_Int32 nMaximalWidth)
804*cdf0e10cSrcweir     : maLeft(rsLeftText, rxFont, nMaximalWidth),
805*cdf0e10cSrcweir       maRight(rsRightText, rxFont, nMaximalWidth)
806*cdf0e10cSrcweir {
807*cdf0e10cSrcweir }
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir void Block::Update (
812*cdf0e10cSrcweir     const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
813*cdf0e10cSrcweir     const sal_Int32 nMaximalWidth)
814*cdf0e10cSrcweir {
815*cdf0e10cSrcweir     maLeft.Update(rxFont, nMaximalWidth);
816*cdf0e10cSrcweir     maRight.Update(rxFont, nMaximalWidth);
817*cdf0e10cSrcweir }
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir } // end of anonymous namespace
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir } } // end of namespace ::sdext::presenter
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir 
824