Bump version to 5.0-14
[LibreOffice.git] / sdext / source / presenter / PresenterHelpView.cxx
blobc2cb2e0e0864edf9959cc70d880794e60f3fe2fb
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 .
19 #include "vcl/svapp.hxx"
20 #include "vcl/settings.hxx"
21 #include "PresenterHelpView.hxx"
22 #include "PresenterButton.hxx"
23 #include "PresenterCanvasHelper.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterHelper.hxx"
26 #include "PresenterWindowManager.hxx"
27 #include <com/sun/star/awt/XWindowPeer.hpp>
28 #include <com/sun/star/container/XNameAccess.hpp>
29 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
30 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
31 #include <com/sun/star/rendering/CompositeOperation.hpp>
32 #include <com/sun/star/rendering/TextDirection.hpp>
33 #include <com/sun/star/util/Color.hpp>
34 #include <algorithm>
35 #include <vector>
36 #include <boost/bind.hpp>
37 #include <boost/noncopyable.hpp>
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::uno;
41 using namespace ::com::sun::star::drawing::framework;
42 using ::std::vector;
44 namespace sdext { namespace presenter {
46 namespace {
47 const static sal_Int32 gnHorizontalGap (20);
48 const static sal_Int32 gnVerticalBorder (30);
49 const static sal_Int32 gnVerticalButtonPadding (12);
51 class LineDescriptor
53 public:
54 LineDescriptor();
55 void AddPart (
56 const OUString& rsLine,
57 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
58 bool IsEmpty() const;
60 OUString msLine;
61 geometry::RealSize2D maSize;
62 double mnVerticalOffset;
64 void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
67 class LineDescriptorList
69 public:
70 LineDescriptorList (
71 const OUString& rsText,
72 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
73 const sal_Int32 nMaximalWidth);
75 void Update (
76 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
77 const sal_Int32 nMaximalWidth);
79 double Paint(
80 const Reference<rendering::XCanvas>& rxCanvas,
81 const geometry::RealRectangle2D& rBBox,
82 const bool bFlushLeft,
83 const rendering::ViewState& rViewState,
84 rendering::RenderState& rRenderState,
85 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
86 double GetHeight() const;
88 private:
89 const OUString msText;
90 ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
92 static void SplitText (const OUString& rsText, vector<OUString>& rTextParts);
93 void FormatText (
94 const vector<OUString>& rTextParts,
95 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
96 const sal_Int32 nMaximalWidth);
99 class Block: private boost::noncopyable
101 public:
102 Block (
103 const OUString& rsLeftText,
104 const OUString& rsRightText,
105 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
106 const sal_Int32 nMaximalWidth);
107 void Update (
108 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
109 const sal_Int32 nMaximalWidth);
111 LineDescriptorList maLeft;
112 LineDescriptorList maRight;
114 } // end of anonymous namespace
116 class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
120 PresenterHelpView::PresenterHelpView (
121 const Reference<uno::XComponentContext>& rxContext,
122 const Reference<XResourceId>& rxViewId,
123 const Reference<frame::XController>& rxController,
124 const ::rtl::Reference<PresenterController>& rpPresenterController)
125 : PresenterHelpViewInterfaceBase(m_aMutex),
126 mxComponentContext(rxContext),
127 mxViewId(rxViewId),
128 mxPane(),
129 mxWindow(),
130 mxCanvas(),
131 mpPresenterController(rpPresenterController),
132 mpFont(),
133 mpTextContainer(),
134 mpCloseButton(),
135 mnSeparatorY(0),
136 mnMaximalWidth(0)
140 // Get the content window via the pane anchor.
141 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
142 Reference<XConfigurationController> xCC (
143 xCM->getConfigurationController(), UNO_QUERY_THROW);
144 mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
146 mxWindow = mxPane->getWindow();
147 ProvideCanvas();
149 mxWindow->addWindowListener(this);
150 mxWindow->addPaintListener(this);
151 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
152 if (xPeer.is())
153 xPeer->setBackground(util::Color(0xff000000));
154 mxWindow->setVisible(sal_True);
156 if (mpPresenterController.is())
158 mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
159 if (mpFont.get() != NULL)
161 mpFont->PrepareFont(mxCanvas);
165 // Create the close button.
166 mpCloseButton = PresenterButton::Create(
167 mxComponentContext,
168 mpPresenterController,
169 mpPresenterController->GetTheme(),
170 mxWindow,
171 mxCanvas,
172 "HelpViewCloser");
174 ReadHelpStrings();
175 Resize();
177 catch (RuntimeException&)
179 mxViewId = NULL;
180 mxWindow = NULL;
181 throw;
185 PresenterHelpView::~PresenterHelpView()
189 void SAL_CALL PresenterHelpView::disposing()
191 mxViewId = NULL;
193 if (mpCloseButton.is())
195 Reference<lang::XComponent> xComponent (
196 static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
197 mpCloseButton = NULL;
198 if (xComponent.is())
199 xComponent->dispose();
202 if (mxWindow.is())
204 mxWindow->removeWindowListener(this);
205 mxWindow->removePaintListener(this);
209 //----- lang::XEventListener --------------------------------------------------
211 void SAL_CALL PresenterHelpView::disposing (const lang::EventObject& rEventObject)
212 throw (RuntimeException, std::exception)
214 if (rEventObject.Source == mxCanvas)
216 mxCanvas = NULL;
218 else if (rEventObject.Source == mxWindow)
220 mxWindow = NULL;
221 dispose();
225 //----- XWindowListener -------------------------------------------------------
227 void SAL_CALL PresenterHelpView::windowResized (const awt::WindowEvent& rEvent)
228 throw (uno::RuntimeException, std::exception)
230 (void)rEvent;
231 ThrowIfDisposed();
232 Resize();
235 void SAL_CALL PresenterHelpView::windowMoved (const awt::WindowEvent& rEvent)
236 throw (uno::RuntimeException, std::exception)
238 (void)rEvent;
239 ThrowIfDisposed();
242 void SAL_CALL PresenterHelpView::windowShown (const lang::EventObject& rEvent)
243 throw (uno::RuntimeException, std::exception)
245 (void)rEvent;
246 ThrowIfDisposed();
247 Resize();
250 void SAL_CALL PresenterHelpView::windowHidden (const lang::EventObject& rEvent)
251 throw (uno::RuntimeException, std::exception)
253 (void)rEvent;
254 ThrowIfDisposed();
257 //----- XPaintListener --------------------------------------------------------
259 void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent)
260 throw (RuntimeException, std::exception)
262 Paint(rEvent.UpdateRect);
265 void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
267 ProvideCanvas();
268 if ( ! mxCanvas.is())
269 return;
271 // Clear background.
272 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
273 mpPresenterController->GetCanvasHelper()->Paint(
274 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
275 Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
276 rUpdateBox,
277 awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
278 awt::Rectangle());
280 // Paint vertical divider.
282 rendering::ViewState aViewState(
283 geometry::AffineMatrix2D(1,0,0, 0,1,0),
284 PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));
286 rendering::RenderState aRenderState (
287 geometry::AffineMatrix2D(1,0,0, 0,1,0),
288 NULL,
289 Sequence<double>(4),
290 rendering::CompositeOperation::SOURCE);
291 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
293 mxCanvas->drawLine(
294 geometry::RealPoint2D((aWindowBox.Width/2.0), gnVerticalBorder),
295 geometry::RealPoint2D((aWindowBox.Width/2.0), mnSeparatorY - gnVerticalBorder),
296 aViewState,
297 aRenderState);
299 // Paint the horizontal separator.
300 mxCanvas->drawLine(
301 geometry::RealPoint2D(0, mnSeparatorY),
302 geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
303 aViewState,
304 aRenderState);
306 // Paint text.
307 double nY (gnVerticalBorder);
308 TextContainer::const_iterator iBlock (mpTextContainer->begin());
309 TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
310 for ( ; iBlock!=iBlockEnd; ++iBlock)
312 sal_Int32 LeftX1 = gnHorizontalGap;
313 sal_Int32 LeftX2 = aWindowBox.Width/2 - gnHorizontalGap;
314 sal_Int32 RightX1 = aWindowBox.Width/2 + gnHorizontalGap;
315 sal_Int32 RightX2 = aWindowBox.Width - gnHorizontalGap;
316 /* check whether RTL interface or not
317 then replace the windowbox position */
318 if(AllSettings::GetLayoutRTL())
320 LeftX1 = aWindowBox.Width/2 + gnHorizontalGap;
321 LeftX2 = aWindowBox.Width - gnHorizontalGap;
322 RightX1 = gnHorizontalGap;
323 RightX2 = aWindowBox.Width/2 - gnHorizontalGap;
325 const double nLeftHeight (
326 (*iBlock)->maLeft.Paint(mxCanvas,
327 geometry::RealRectangle2D(
328 LeftX1,
330 LeftX2,
331 aWindowBox.Height - gnVerticalBorder),
332 false,
333 aViewState,
334 aRenderState,
335 mpFont->mxFont));
336 const double nRightHeight (
337 (*iBlock)->maRight.Paint(mxCanvas,
338 geometry::RealRectangle2D(
339 RightX1,
341 RightX2,
342 aWindowBox.Height - gnVerticalBorder),
343 true,
344 aViewState,
345 aRenderState,
346 mpFont->mxFont));
348 nY += ::std::max(nLeftHeight,nRightHeight);
351 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
352 if (xSpriteCanvas.is())
353 xSpriteCanvas->updateScreen(sal_False);
356 void PresenterHelpView::ReadHelpStrings()
358 mpTextContainer.reset(new TextContainer());
359 PresenterConfigurationAccess aConfiguration (
360 mxComponentContext,
361 OUString("/org.openoffice.Office.PresenterScreen/"),
362 PresenterConfigurationAccess::READ_ONLY);
363 Reference<container::XNameAccess> xStrings (
364 aConfiguration.GetConfigurationNode("PresenterScreenSettings/HelpView/HelpStrings"),
365 UNO_QUERY);
366 PresenterConfigurationAccess::ForAll(
367 xStrings,
368 ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
371 void PresenterHelpView::ProcessString (
372 const Reference<beans::XPropertySet>& rsProperties)
374 if ( ! rsProperties.is())
375 return;
377 OUString sLeftText;
378 PresenterConfigurationAccess::GetProperty(rsProperties, "Left") >>= sLeftText;
379 OUString sRightText;
380 PresenterConfigurationAccess::GetProperty(rsProperties, "Right") >>= sRightText;
381 mpTextContainer->push_back(
382 ::boost::shared_ptr<Block>(
383 new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
386 void PresenterHelpView::CheckFontSize()
388 if (mpFont.get() == NULL)
389 return;
391 sal_Int32 nBestSize (6);
393 // Scaling down and then reformatting can cause the text to be too large
394 // still. So do this again and again until the text size is
395 // small enough. Restrict the number of loops.
396 for (int nLoopCount=0; nLoopCount<5; ++nLoopCount)
398 double nY (0.0);
399 TextContainer::iterator iBlock (mpTextContainer->begin());
400 TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
401 for ( ; iBlock!=iBlockEnd; ++iBlock)
402 nY += ::std::max(
403 (*iBlock)->maLeft.GetHeight(),
404 (*iBlock)->maRight.GetHeight());
406 const double nHeightDifference (nY - (mnSeparatorY-gnVerticalBorder));
407 if (nHeightDifference <= 0 && nHeightDifference > -50)
409 // We have found a good font size that is large and leaves not
410 // too much space below the help text.
411 return;
414 // Use a simple linear transformation to calculate initial guess of
415 // a size that lets all help text be shown inside the window.
416 const double nScale (double(mnSeparatorY-gnVerticalBorder) / nY);
417 if (nScale > 1.0 && nScale < 1.05)
418 break;
420 sal_Int32 nFontSizeGuess (sal_Int32(mpFont->mnSize * nScale));
421 if (nHeightDifference<=0 && mpFont->mnSize>nBestSize)
422 nBestSize = mpFont->mnSize;
423 mpFont->mnSize = nFontSizeGuess;
424 mpFont->mxFont = NULL;
425 mpFont->PrepareFont(mxCanvas);
427 // Reformat blocks.
428 for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
429 (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
432 if (nBestSize != mpFont->mnSize)
434 mpFont->mnSize = nBestSize;
435 mpFont->mxFont = NULL;
436 mpFont->PrepareFont(mxCanvas);
438 // Reformat blocks.
439 for (TextContainer::iterator
440 iBlock (mpTextContainer->begin()),
441 iEnd (mpTextContainer->end());
442 iBlock!=iEnd;
443 ++iBlock)
445 (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
450 //----- XResourceId -----------------------------------------------------------
452 Reference<XResourceId> SAL_CALL PresenterHelpView::getResourceId()
453 throw (RuntimeException, std::exception)
455 ThrowIfDisposed();
456 return mxViewId;
459 sal_Bool SAL_CALL PresenterHelpView::isAnchorOnly()
460 throw (RuntimeException, std::exception)
462 return false;
467 void PresenterHelpView::ProvideCanvas()
469 if ( ! mxCanvas.is() && mxPane.is())
471 mxCanvas = mxPane->getCanvas();
472 if ( ! mxCanvas.is())
473 return;
474 Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
475 if (xComponent.is())
476 xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
478 if (mpCloseButton.is())
479 mpCloseButton->SetCanvas(mxCanvas, mxWindow);
483 void PresenterHelpView::Resize()
485 if (mpCloseButton.get() != NULL && mxWindow.is())
487 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
488 mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
490 // Place vertical separator.
491 mnSeparatorY = aWindowBox.Height
492 - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
494 mpCloseButton->SetCenter(geometry::RealPoint2D(
495 aWindowBox.Width/2.0,
496 aWindowBox.Height - mpCloseButton->GetSize().Height/2.0));
498 CheckFontSize();
502 void PresenterHelpView::ThrowIfDisposed()
503 throw (lang::DisposedException)
505 if (rBHelper.bDisposed || rBHelper.bInDispose)
507 throw lang::DisposedException (
508 OUString( "PresenterHelpView has been already disposed"),
509 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
513 //===== LineDescritor =========================================================
515 namespace {
517 LineDescriptor::LineDescriptor()
518 : msLine(),
519 maSize(0,0),
520 mnVerticalOffset(0)
524 void LineDescriptor::AddPart (
525 const OUString& rsLine,
526 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
528 msLine += rsLine;
530 CalculateSize(rxFont);
533 bool LineDescriptor::IsEmpty() const
535 return msLine.isEmpty();
538 void LineDescriptor::CalculateSize (
539 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
541 OSL_ASSERT(rxFont.is());
543 rendering::StringContext aContext (msLine, 0, msLine.getLength());
544 Reference<rendering::XTextLayout> xLayout (
545 rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
546 const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
547 maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
548 mnVerticalOffset = aTextBBox.Y2;
551 } // end of anonymous namespace
553 //===== LineDescriptorList ====================================================
555 namespace {
557 LineDescriptorList::LineDescriptorList (
558 const OUString& rsText,
559 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
560 const sal_Int32 nMaximalWidth)
561 : msText(rsText)
563 Update(rxFont, nMaximalWidth);
566 double LineDescriptorList::Paint(
567 const Reference<rendering::XCanvas>& rxCanvas,
568 const geometry::RealRectangle2D& rBBox,
569 const bool bFlushLeft,
570 const rendering::ViewState& rViewState,
571 rendering::RenderState& rRenderState,
572 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
574 if ( ! rxCanvas.is())
575 return 0;
577 double nY (rBBox.Y1);
578 vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
579 vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
580 for ( ; iLine!=iEnd; ++iLine)
582 double nX;
583 /// check whether RTL interface or not
584 if(!AllSettings::GetLayoutRTL())
586 nX = rBBox.X1;
587 if ( ! bFlushLeft)
588 nX = rBBox.X2 - iLine->maSize.Width;
590 else
592 nX=rBBox.X2 - iLine->maSize.Width;
593 if ( ! bFlushLeft)
594 nX = rBBox.X1;
596 rRenderState.AffineTransform.m02 = nX;
597 rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
599 const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
600 Reference<rendering::XTextLayout> xLayout (
601 rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
602 rxCanvas->drawTextLayout (
603 xLayout,
604 rViewState,
605 rRenderState);
607 nY += iLine->maSize.Height * 1.2;
610 return nY - rBBox.Y1;
613 double LineDescriptorList::GetHeight() const
615 double nHeight (0);
616 vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
617 vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
618 for ( ; iLine!=iEnd; ++iLine)
619 nHeight += iLine->maSize.Height * 1.2;
621 return nHeight;
624 void LineDescriptorList::Update (
625 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
626 const sal_Int32 nMaximalWidth)
628 vector<OUString> aTextParts;
629 SplitText(msText, aTextParts);
630 FormatText(aTextParts, rxFont, nMaximalWidth);
633 void LineDescriptorList::SplitText (
634 const OUString& rsText,
635 vector<OUString>& rTextParts)
637 const sal_Char cQuote ('\'');
638 const sal_Char cSeparator (',');
640 sal_Int32 nIndex (0);
641 sal_Int32 nStart (0);
642 sal_Int32 nLength (rsText.getLength());
643 bool bIsQuoted (false);
644 while (nIndex < nLength)
646 const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
647 const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
648 if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
650 bIsQuoted = !bIsQuoted;
651 nIndex = nQuoteIndex+1;
652 continue;
655 const sal_Int32 nNextIndex = nSeparatorIndex;
656 if (nNextIndex < 0)
658 break;
660 else if ( ! bIsQuoted)
662 rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
663 nStart = nNextIndex + 1;
665 nIndex = nNextIndex+1;
667 if (nStart < nLength)
668 rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
671 void LineDescriptorList::FormatText (
672 const vector<OUString>& rTextParts,
673 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
674 const sal_Int32 nMaximalWidth)
676 LineDescriptor aLineDescriptor;
678 mpLineDescriptors.reset(new vector<LineDescriptor>());
680 vector<OUString>::const_iterator iPart (rTextParts.begin());
681 vector<OUString>::const_iterator iEnd (rTextParts.end());
682 while (iPart!=iEnd)
684 if (aLineDescriptor.IsEmpty())
686 // Avoid empty lines.
687 if (PresenterCanvasHelper::GetTextSize(
688 rxFont, *iPart).Width > nMaximalWidth)
690 const sal_Char cSpace (' ');
692 sal_Int32 nIndex (0);
693 sal_Int32 nStart (0);
694 sal_Int32 nLength (iPart->getLength());
695 while (nIndex < nLength)
697 sal_Int32 nSpaceIndex (iPart->indexOf(cSpace, nIndex));
698 while (nSpaceIndex >= 0 && PresenterCanvasHelper::GetTextSize(
699 rxFont, iPart->copy(nStart, nSpaceIndex-nStart)).Width <= nMaximalWidth)
701 nIndex = nSpaceIndex;
702 nSpaceIndex = iPart->indexOf(cSpace, nIndex+1);
705 if (nSpaceIndex < 0 && PresenterCanvasHelper::GetTextSize(
706 rxFont, iPart->copy(nStart, nLength-nStart)).Width <= nMaximalWidth)
708 nIndex = nLength;
711 if (nIndex == nStart)
713 nIndex = nLength;
716 aLineDescriptor.AddPart(iPart->copy(nStart, nIndex-nStart), rxFont);
717 if (nIndex != nLength)
719 mpLineDescriptors->push_back(aLineDescriptor);
720 aLineDescriptor = LineDescriptor();
722 nStart = nIndex;
725 else
727 aLineDescriptor.AddPart(*iPart, rxFont);
730 else if (PresenterCanvasHelper::GetTextSize(
731 rxFont, aLineDescriptor.msLine+", "+*iPart).Width > nMaximalWidth)
733 aLineDescriptor.AddPart(",", rxFont);
734 mpLineDescriptors->push_back(aLineDescriptor);
735 aLineDescriptor = LineDescriptor();
736 continue;
738 else
740 aLineDescriptor.AddPart(", "+*iPart, rxFont);
742 ++iPart;
744 if ( ! aLineDescriptor.IsEmpty())
746 mpLineDescriptors->push_back(aLineDescriptor);
750 } // end of anonymous namespace
752 //===== Block =================================================================
754 namespace {
756 Block::Block (
757 const OUString& rsLeftText,
758 const OUString& rsRightText,
759 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
760 const sal_Int32 nMaximalWidth)
761 : maLeft(rsLeftText, rxFont, nMaximalWidth),
762 maRight(rsRightText, rxFont, nMaximalWidth)
766 void Block::Update (
767 const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
768 const sal_Int32 nMaximalWidth)
770 maLeft.Update(rxFont, nMaximalWidth);
771 maRight.Update(rxFont, nMaximalWidth);
774 } // end of anonymous namespace
776 } } // end of namespace ::sdext::presenter
778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */