summaryrefslogtreecommitdiff
path: root/sdext/source/presenter/PresenterHelpView.cxx
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2008-05-13 13:31:10 +0000
committerVladimir Glazounov <vg@openoffice.org>2008-05-13 13:31:10 +0000
commit44db83d4af80da1dc96b25b5d9b0b79bbc68bc32 (patch)
tree2abda29c59b8a454fbbe019265843458c0a3f63a /sdext/source/presenter/PresenterHelpView.cxx
parentf6bf1062196b7d6493bcc372f3eca1571c6aa94e (diff)
INTEGRATION: CWS presenterscreen (1.2.4); FILE MERGED
2008/04/30 09:22:41 af 1.2.4.5: #i18486# Made TextContainer use shared_ptrs of Block. 2008/04/30 08:17:36 af 1.2.4.4: #i88850# Make sure that all help text can be displayed. 2008/04/22 08:27:14 af 1.2.4.3: RESYNC: (1.2-1.3); FILE MERGED 2008/04/16 16:59:13 af 1.2.4.2: #i18486# Fixed some Linux build problems. 2008/04/16 15:35:25 af 1.2.4.1: #i18486# Help view now displays supported keyboard keys.
Diffstat (limited to 'sdext/source/presenter/PresenterHelpView.cxx')
-rw-r--r--sdext/source/presenter/PresenterHelpView.cxx617
1 files changed, 510 insertions, 107 deletions
diff --git a/sdext/source/presenter/PresenterHelpView.cxx b/sdext/source/presenter/PresenterHelpView.cxx
index 4044b0f67950..f6078f706202 100644
--- a/sdext/source/presenter/PresenterHelpView.cxx
+++ b/sdext/source/presenter/PresenterHelpView.cxx
@@ -8,7 +8,7 @@
*
* $RCSfile: PresenterHelpView.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
* This file is part of OpenOffice.org.
*
@@ -30,10 +30,11 @@
************************************************************************/
#include "PresenterHelpView.hxx"
+#include "PresenterButton.hxx"
+#include "PresenterCanvasHelper.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterHelper.hxx"
#include "PresenterWindowManager.hxx"
-#include <com/sun/star/awt/InvalidateStyle.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
@@ -42,14 +43,96 @@
#include <com/sun/star/rendering/TextDirection.hpp>
#include <com/sun/star/util/Color.hpp>
#include <algorithm>
+#include <vector>
+#include <boost/bind.hpp>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::rtl::OUString;
+using ::std::vector;
+
+#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
+
namespace sdext { namespace presenter {
+namespace {
+ const static sal_Int32 gnHorizontalGap (20);
+ const static sal_Int32 gnVerticalBorder (30);
+ const static sal_Int32 gnVerticalButtonPadding (12);
+
+ class LineDescriptor
+ {
+ public:
+ LineDescriptor(void);
+ void AddPart (
+ const OUString& rsLine,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
+ bool IsEmpty (void) const;
+
+ OUString msLine;
+ geometry::RealSize2D maSize;
+ double mnVerticalOffset;
+
+ void CalculateSize (const css::uno::Reference<css::rendering::XCanvasFont>& rxFont);
+ };
+
+ class LineDescriptorList
+ {
+ public:
+ LineDescriptorList (
+ const OUString& rsText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ void Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ double Paint(
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rBBox,
+ const bool bFlushLeft,
+ const rendering::ViewState& rViewState,
+ rendering::RenderState& rRenderState,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const;
+ double GetHeight (void) const;
+
+ private:
+ const OUString msText;
+ ::boost::shared_ptr<vector<LineDescriptor> > mpLineDescriptors;
+
+ void SplitText (const ::rtl::OUString& rsText, vector<rtl::OUString>& rTextParts);
+ void FormatText (
+ const vector<rtl::OUString>& rTextParts,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+ };
+
+ class Block
+ {
+ public:
+ Block (const Block& rBlock);
+ Block (
+ const OUString& rsLeftText,
+ const OUString& rsRightText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+ void Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth);
+
+ LineDescriptorList maLeft;
+ LineDescriptorList maRight;
+ };
+} // end of anonymous namespace
+
+class PresenterHelpView::TextContainer : public vector<boost::shared_ptr<Block> >
+{
+};
+
+
PresenterHelpView::PresenterHelpView (
const Reference<uno::XComponentContext>& rxContext,
const Reference<XResourceId>& rxViewId,
@@ -60,9 +143,13 @@ PresenterHelpView::PresenterHelpView (
mxViewId(rxViewId),
mxPane(),
mxWindow(),
- mpPresenterController(rpPresenterController),
mxCanvas(),
- mxFont()
+ mpPresenterController(rpPresenterController),
+ mpFont(),
+ mpTextContainer(),
+ mpCloseButton(),
+ mnSeparatorY(0),
+ mnMaximalWidth(0)
{
try
{
@@ -73,6 +160,7 @@ PresenterHelpView::PresenterHelpView (
mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
mxWindow = mxPane->getWindow();
+ ProvideCanvas();
mxWindow->addWindowListener(this);
mxWindow->addPaintListener(this);
@@ -83,13 +171,25 @@ PresenterHelpView::PresenterHelpView (
if (mpPresenterController.is())
{
- ::rtl::Reference<PresenterWindowManager> pWindowManager(
- mpPresenterController->GetWindowManager());
- if (pWindowManager.is())
- pWindowManager->SetPanePosSizeRelative(rxViewId->getAnchor(),
- 0.1,0.2, 0.8,0.6);
+ mpFont = mpPresenterController->GetViewFont(mxViewId->getResourceURL());
+ if (mpFont.get() != NULL)
+ {
+ mpFont->PrepareFont(mxCanvas);
+ }
}
+ // Create the close button.
+ mpCloseButton = PresenterButton::Create(
+ mxComponentContext,
+ mpPresenterController,
+ mpPresenterController->GetTheme(),
+ mxWindow,
+ mxCanvas,
+ A2S("HelpViewCloser"));
+
+ mnMaximalWidth = (mxWindow->getPosSize().Width - 4*gnHorizontalGap) / 2;
+ ReadHelpStrings();
+ CheckFontSize();
Resize();
}
catch (RuntimeException&)
@@ -114,6 +214,15 @@ void SAL_CALL PresenterHelpView::disposing (void)
{
mxViewId = NULL;
+ if (mpCloseButton.is())
+ {
+ Reference<lang::XComponent> xComponent (
+ static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
+ mpCloseButton = NULL;
+ if (xComponent.is())
+ xComponent->dispose();
+ }
+
if (mxWindow.is())
{
mxWindow->removeWindowListener(this);
@@ -201,12 +310,19 @@ void SAL_CALL PresenterHelpView::windowPaint (const css::awt::PaintEvent& rEvent
void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
{
ProvideCanvas();
+ if ( ! mxCanvas.is())
+ return;
+
+ // Clear background.
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpPresenterController->GetCanvasHelper()->Paint(
+ mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
+ Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY),
+ rUpdateBox,
+ awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
+ awt::Rectangle());
- Sequence<double> aBackgroundColor(4);
- aBackgroundColor[0] = 0.9;
- aBackgroundColor[1] = 0.6;
- aBackgroundColor[2] = 0.4;
- aBackgroundColor[3] = 0;
+ // Paint vertical divider.
rendering::ViewState aViewState(
geometry::AffineMatrix2D(1,0,0, 0,1,0),
@@ -215,105 +331,134 @@ void PresenterHelpView::Paint (const awt::Rectangle& rUpdateBox)
rendering::RenderState aRenderState (
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL,
- aBackgroundColor,
- rendering::CompositeOperation::ADD);
+ Sequence<double>(3),
+ rendering::CompositeOperation::SOURCE);
+ PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
- const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(aWindowBox.Width/2, gnVerticalBorder),
+ geometry::RealPoint2D(aWindowBox.Width/2, mnSeparatorY - gnVerticalBorder),
+ aViewState,
+ aRenderState);
- mxCanvas->fillPolyPolygon(
- PresenterGeometryHelper::CreatePolygon(
- awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
- mxCanvas->getDevice()),
+ // Paint the horizontal separator.
+ mxCanvas->drawLine(
+ geometry::RealPoint2D(0, mnSeparatorY),
+ geometry::RealPoint2D(aWindowBox.Width, mnSeparatorY),
aViewState,
aRenderState);
- aRenderState.DeviceColor[0] = 0.4;
- aRenderState.DeviceColor[1] = 0.4;
- aRenderState.DeviceColor[2] = 0.4;
- aRenderState.DeviceColor[3] = 0.8;
-
- // Create a polygon for a rectangle with rounded corners.
- Sequence<Sequence<geometry::RealBezierSegment2D> > aPolygon(1);
- aPolygon[0] = Sequence<geometry::RealBezierSegment2D>(8);
- const double nLeft = 0.2 * aWindowBox.Width;
- const double nTop = 0.2 * aWindowBox.Height;
- const double nRight = 0.8 * aWindowBox.Width;
- const double nBottom = 0.8 * aWindowBox.Height;
- const double nRadius = ::std::min(30.0,::std::min(aWindowBox.Width/2.0,aWindowBox.Height/2.0));
-
-#define SetCurve(aPolygon, x,y, dx1,dy1, dx2,dy2) \
- aPolygon.Px=(x); aPolygon.Py=(y); \
- aPolygon.C1x=(x)+(dx1); aPolygon.C1y=(y)+(dy1); \
- aPolygon.C2x=(x)+(dx1)+(dx2); aPolygon.C2y=(y)+(dy1)+(dy2);
-#define SetLine(aPolygon, x1,y1, x2,y2) \
- aPolygon.Px=(x1); aPolygon.Py=(y1); \
- aPolygon.C1x=0.666*(x1)+0.334*(x2); aPolygon.C1y=0.666*(y1)+0.334*(y2); \
- aPolygon.C2x=0.333*(x1)+0.667*(x2); aPolygon.C2y=0.333*(y1)+0.667*(y2);
-
- SetCurve(aPolygon[0][0], nLeft + nRadius, nTop, -nRadius, 0, 0,0);
- SetLine(aPolygon[0][1], nLeft, nTop+nRadius, nLeft, nBottom-nRadius);
-
- SetCurve(aPolygon[0][2], nLeft, nBottom-nRadius, 0,nRadius, 0,0);
- SetLine(aPolygon[0][3], nLeft+nRadius, nBottom, nRight-nRadius, nBottom);
-
- SetCurve(aPolygon[0][4], nRight-nRadius, nBottom, nRadius,0, 0,0);
- SetLine(aPolygon[0][5], nRight, nBottom-nRadius, nRight, nTop+nRadius);
-
- SetCurve(aPolygon[0][6], nRight, nTop+nRadius, 0,-nRadius, 0,0);
- SetLine(aPolygon[0][7], nRight-nRadius, nTop, nLeft+nRadius, nTop);
-
- Reference<rendering::XPolyPolygon2D> xPolygon (
- mxCanvas->getDevice()->createCompatibleBezierPolyPolygon(aPolygon),
- UNO_QUERY_THROW);
- if (xPolygon.is())
+ // Paint text.
+ double nY (gnVerticalBorder);
+ TextContainer::const_iterator iBlock (mpTextContainer->begin());
+ TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
+ for ( ; iBlock!=iBlockEnd; ++iBlock)
{
- xPolygon->setClosed(0, sal_True);
- mxCanvas->fillPolyPolygon(
- xPolygon,
- aViewState,
- aRenderState);
+ const double nLeftHeight (
+ (*iBlock)->maLeft.Paint(mxCanvas,
+ geometry::RealRectangle2D(
+ gnHorizontalGap,
+ nY,
+ aWindowBox.Width/2 - gnHorizontalGap,
+ aWindowBox.Height - gnVerticalBorder),
+ false,
+ aViewState,
+ aRenderState,
+ mpFont->mxFont));
+ const double nRightHeight (
+ (*iBlock)->maRight.Paint(mxCanvas,
+ geometry::RealRectangle2D(
+ aWindowBox.Width/2 + gnHorizontalGap,
+ nY,
+ aWindowBox.Width - gnHorizontalGap,
+ aWindowBox.Height - gnVerticalBorder),
+ true,
+ aViewState,
+ aRenderState,
+ mpFont->mxFont));
+ nY += ::std::max(nLeftHeight,nRightHeight);
}
- if ( ! mxFont.is())
- mxFont = mxCanvas->createFont(
- mpPresenterController->GetViewFontRequest(mxViewId->getResourceURL()),
- Sequence<beans::PropertyValue>(),
- geometry::Matrix2D(1,0,0,1));
+ Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
+ if (xSpriteCanvas.is())
+ xSpriteCanvas->updateScreen(sal_False);
+}
+
+
+
+
+void PresenterHelpView::ReadHelpStrings (void)
+{
+ mpTextContainer.reset(new TextContainer());
+ PresenterConfigurationAccess aConfiguration (
+ mxComponentContext,
+ OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"),
+ PresenterConfigurationAccess::READ_ONLY);
+ Reference<container::XNameAccess> xStrings (
+ aConfiguration.GetConfigurationNode(A2S("PresenterScreenSettings/HelpView/HelpStrings")),
+ UNO_QUERY);
+ PresenterConfigurationAccess::ForAll(
+ xStrings,
+ ::boost::bind(&PresenterHelpView::ProcessString, this, _2));
+}
+
+
+
+
+void PresenterHelpView::ProcessString (
+ const Reference<beans::XPropertySet>& rsProperties)
+{
+ if ( ! rsProperties.is())
+ return;
+
+ OUString sLeftText;
+ PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Left")) >>= sLeftText;
+ OUString sRightText;
+ PresenterConfigurationAccess::GetProperty(rsProperties, A2S("Right")) >>= sRightText;
+
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+ mpTextContainer->push_back(
+ ::boost::shared_ptr<Block>(
+ new Block(sLeftText, sRightText, mpFont->mxFont, mnMaximalWidth)));
+}
+
+
+
+
+void PresenterHelpView::CheckFontSize (void)
+{
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+
+ double nY (gnVerticalBorder);
+ TextContainer::iterator iBlock (mpTextContainer->begin());
+ TextContainer::const_iterator iBlockEnd (mpTextContainer->end());
+ for ( ; iBlock!=iBlockEnd; ++iBlock)
+ nY += ::std::max(
+ (*iBlock)->maLeft.GetHeight(),
+ (*iBlock)->maRight.GetHeight());
- if (mxFont.is())
+ if (nY > aWindowBox.Height-gnVerticalBorder)
{
- OUString sText (OUString::createFromAscii("Help View\nSecond Line of Text"));
- rendering::StringContext aContext (sText, 0, sText.getLength());
-
- Reference<rendering::XTextLayout> xLayout (
- mxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
-
- geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
- // const double nTextWidth = aBox.X2 - aBox.X1;
- // const double nTextHeight = aBox.Y2 - aBox.Y1;
- const double nX = nTop + 2*nRadius;
- const double nY = nLeft + 2*nRadius;
-
- rendering::RenderState aFontRenderState(
- geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
- NULL,
- Sequence<double>(3),
- rendering::CompositeOperation::SOURCE);
- const util::Color aFontColor (
- mpPresenterController->GetViewFontColor(mxViewId->getResourceURL()));
- aRenderState.DeviceColor[0] = ((aFontColor & 0x00ff0000)>>16) / 255.0;
- aRenderState.DeviceColor[1] = ((aFontColor & 0x0000ff00)>>8) / 255.0;
- aRenderState.DeviceColor[2] = (aFontColor & 0x000000ff) / 255.0;
-
- mxCanvas->drawText(
- aContext,
- mxFont,
- aViewState,
- aFontRenderState,
- rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
- }
+ // Font is too large. Make it smaller.
- mxCanvas->updateScreen(sal_False);
+ if (mpFont.get() == NULL)
+ {
+ // No font to work with.
+ return;
+ }
+
+ // Use a simple linear transformation to calculate initial guess of
+ // a size that lets all help text be shown inside the window.
+ sal_Int32 nFontSizeGuess (
+ sal_Int32(mpFont->mnSize * (aWindowBox.Height-gnVerticalBorder) / nY));
+ mpFont->mnSize = nFontSizeGuess;
+ mpFont->mxFont = NULL;
+ mpFont->PrepareFont(mxCanvas);
+
+ // Reformat blocks.
+ for (iBlock=mpTextContainer->begin(); iBlock!=iBlockEnd; ++iBlock)
+ (*iBlock)->Update(mpFont->mxFont, mnMaximalWidth);
+ }
}
@@ -346,12 +491,15 @@ void PresenterHelpView::ProvideCanvas (void)
{
if ( ! mxCanvas.is() && mxPane.is())
{
- mxCanvas = Reference<rendering::XSpriteCanvas>(mxPane->getCanvas(), UNO_QUERY);
+ mxCanvas = mxPane->getCanvas();
if ( ! mxCanvas.is())
return;
Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
if (xComponent.is())
xComponent->addEventListener(static_cast<awt::XPaintListener*>(this));
+
+ if (mpCloseButton.is())
+ mpCloseButton->SetCanvas(mxCanvas, mxWindow);
}
}
@@ -360,10 +508,18 @@ void PresenterHelpView::ProvideCanvas (void)
void PresenterHelpView::Resize (void)
{
- // The whole window has to be repainted.
- Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
- if (xPeer.is())
- xPeer->invalidate(awt::InvalidateStyle::CHILDREN);
+ if (mpCloseButton.get() != NULL && mxWindow.is())
+ {
+ const awt::Rectangle aWindowBox (mxWindow->getPosSize());
+
+ // Place vertical separator.
+ mnSeparatorY = aWindowBox.Height
+ - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
+
+ mpCloseButton->SetCenter(geometry::RealPoint2D(
+ aWindowBox.Width/2,
+ aWindowBox.Height - mpCloseButton->GetSize().Height/2));
+ }
}
@@ -381,4 +537,251 @@ void PresenterHelpView::ThrowIfDisposed (void)
}
}
+
+
+
+//===== LineDescritor =========================================================
+
+namespace {
+
+LineDescriptor::LineDescriptor (void)
+ : msLine(),
+ maSize(0,0),
+ mnVerticalOffset(0)
+{
+}
+
+
+
+
+void LineDescriptor::AddPart (
+ const OUString& rsLine,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
+{
+ msLine += rsLine;
+
+ CalculateSize(rxFont);
+}
+
+
+
+
+bool LineDescriptor::IsEmpty (void) const
+{
+ return msLine.getLength()==0;
+}
+
+
+
+
+void LineDescriptor::CalculateSize (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont)
+{
+ OSL_ASSERT(rxFont.is());
+
+ rendering::StringContext aContext (msLine, 0, msLine.getLength());
+ Reference<rendering::XTextLayout> xLayout (
+ rxFont->createTextLayout(aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 0));
+ const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
+ maSize = css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1);
+ mnVerticalOffset = aTextBBox.Y2;
+}
+
+} // end of anonymous namespace
+
+
+
+
+//===== LineDescriptorList ====================================================
+
+namespace {
+
+LineDescriptorList::LineDescriptorList (
+ const OUString& rsText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+ : msText(rsText)
+{
+ Update(rxFont, nMaximalWidth);
+}
+
+
+
+
+double LineDescriptorList::Paint(
+ const Reference<rendering::XCanvas>& rxCanvas,
+ const geometry::RealRectangle2D& rBBox,
+ const bool bFlushLeft,
+ const rendering::ViewState& rViewState,
+ rendering::RenderState& rRenderState,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont) const
+{
+ if ( ! rxCanvas.is())
+ return 0;
+
+ double nY (rBBox.Y1);
+ vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
+ vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
+ for ( ; iLine!=iEnd; ++iLine)
+ {
+ double nX (rBBox.X1);
+ if ( ! bFlushLeft)
+ nX = rBBox.X2 - iLine->maSize.Width;
+ rRenderState.AffineTransform.m02 = nX;
+ rRenderState.AffineTransform.m12 = nY + iLine->maSize.Height - iLine->mnVerticalOffset;
+
+ const rendering::StringContext aContext (iLine->msLine, 0, iLine->msLine.getLength());
+
+ rxCanvas->drawText (
+ aContext,
+ rxFont,
+ rViewState,
+ rRenderState,
+ rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
+
+ nY += iLine->maSize.Height * 1.2;
+ }
+
+ return nY - rBBox.Y1;
+}
+
+
+
+
+double LineDescriptorList::GetHeight (void) const
+{
+ double nHeight (0);
+ vector<LineDescriptor>::const_iterator iLine (mpLineDescriptors->begin());
+ vector<LineDescriptor>::const_iterator iEnd (mpLineDescriptors->end());
+ for ( ; iLine!=iEnd; ++iLine)
+ nHeight += iLine->maSize.Height * 1.2;
+
+ return nHeight;
+}
+
+
+
+
+void LineDescriptorList::Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ vector<OUString> aTextParts;
+ SplitText(msText, aTextParts);
+ FormatText(aTextParts, rxFont, nMaximalWidth);
+}
+
+
+
+
+void LineDescriptorList::SplitText (
+ const OUString& rsText,
+ vector<OUString>& rTextParts)
+{
+ const sal_Char cQuote ('\'');
+ const sal_Char cSeparator (',');
+
+ sal_Int32 nIndex (0);
+ sal_Int32 nStart (0);
+ sal_Int32 nLength (rsText.getLength());
+ bool bIsQuoted (false);
+ while (nIndex < nLength)
+ {
+ const sal_Int32 nQuoteIndex (rsText.indexOf(cQuote, nIndex));
+ const sal_Int32 nSeparatorIndex (rsText.indexOf(cSeparator, nIndex));
+ if (nQuoteIndex>=0 && (nSeparatorIndex==-1 || nQuoteIndex<nSeparatorIndex))
+ {
+ bIsQuoted = !bIsQuoted;
+ nIndex = nQuoteIndex+1;
+ continue;
+ }
+
+ const sal_Int32 nNextIndex = nSeparatorIndex;
+ if (nNextIndex < 0)
+ {
+ break;
+ }
+ else if ( ! bIsQuoted)
+ {
+ rTextParts.push_back(rsText.copy(nStart, nNextIndex-nStart));
+ nStart = nNextIndex + 1;
+ }
+ nIndex = nNextIndex+1;
+ }
+ if (nStart < nLength)
+ rTextParts.push_back(rsText.copy(nStart, nLength-nStart));
+}
+
+
+
+
+void LineDescriptorList::FormatText (
+ const vector<OUString>& rTextParts,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ LineDescriptor aLineDescriptor;
+
+ mpLineDescriptors.reset(new vector<LineDescriptor>());
+
+ vector<OUString>::const_iterator iPart (rTextParts.begin());
+ vector<OUString>::const_iterator iEnd (rTextParts.end());
+ for ( ; iPart!=iEnd; ++iPart)
+ {
+ if (aLineDescriptor.IsEmpty())
+ {
+ // Avoid empty lines.
+ aLineDescriptor.AddPart(*iPart, rxFont);
+ }
+ else if (PresenterCanvasHelper::GetTextSize(
+ rxFont, aLineDescriptor.msLine+A2S(", ")+*iPart).Width > nMaximalWidth)
+ {
+ aLineDescriptor.AddPart(A2S(","), rxFont);
+ mpLineDescriptors->push_back(aLineDescriptor);
+ aLineDescriptor = LineDescriptor();
+ aLineDescriptor.AddPart(*iPart, rxFont);
+ }
+ else
+ {
+ aLineDescriptor.AddPart(A2S(", ")+*iPart, rxFont);
+ }
+ }
+ if ( ! aLineDescriptor.IsEmpty())
+ mpLineDescriptors->push_back(aLineDescriptor);
+}
+
+
+} // end of anonymous namespace
+
+
+
+
+//===== Block =================================================================
+
+namespace {
+
+Block::Block (
+ const OUString& rsLeftText,
+ const OUString& rsRightText,
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+ : maLeft(rsLeftText, rxFont, nMaximalWidth),
+ maRight(rsRightText, rxFont, nMaximalWidth)
+{
+}
+
+
+
+void Block::Update (
+ const css::uno::Reference<css::rendering::XCanvasFont>& rxFont,
+ const sal_Int32 nMaximalWidth)
+{
+ maLeft.Update(rxFont, nMaximalWidth);
+ maRight.Update(rxFont, nMaximalWidth);
+}
+
+} // end of anonymous namespace
+
} } // end of namespace ::sdext::presenter
+
+