update dev300-m58
[ooovba.git] / sdext / source / presenter / PresenterNotesView.cxx
bloba423f1846309e2225709261417354507b3fa6eb5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterNotesView.cxx,v $
11 * $Revision: 1.8 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 #include "PresenterNotesView.hxx"
36 #include "PresenterButton.hxx"
37 #include "PresenterCanvasHelper.hxx"
38 #include "PresenterGeometryHelper.hxx"
39 #include "PresenterPaintManager.hxx"
40 #include "PresenterScrollBar.hxx"
41 #include <com/sun/star/awt/Key.hpp>
42 #include <com/sun/star/awt/PosSize.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
45 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
46 #include <com/sun/star/drawing/framework/XPane.hpp>
47 #include <com/sun/star/lang/XServiceName.hpp>
48 #include <com/sun/star/presentation/XPresentationPage.hpp>
49 #include <com/sun/star/rendering/CompositeOperation.hpp>
50 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
51 #include <com/sun/star/text/XTextRange.hpp>
52 #include <com/sun/star/util/XChangesBatch.hpp>
53 #include <com/sun/star/container/XChild.hpp>
54 #include <boost/bind.hpp>
55 #include <set>
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::drawing::framework;
60 using ::rtl::OUString;
62 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
64 static const sal_Int32 gnSpaceBelowSeparator (10);
65 static const sal_Int32 gnSpaceAboveSeparator (10);
66 static const sal_Int32 gnPartHeight (128);
67 /** Maximal size of memory used for bitmaps which show the notes text.
69 static const sal_Int32 gnMaximalCacheSize (8*1024*1024);
70 static const double gnLineScrollFactor (1.2);
72 namespace sdext { namespace presenter {
74 //===== PresenterNotesView::BitmapContainer ===================================
76 namespace {
77 class NotesBitmapDescriptor
79 public:
80 NotesBitmapDescriptor (const sal_Int32 nTop, const sal_Int32 nBottom,
81 const Reference<rendering::XBitmap> xBitmap)
82 : Top(nTop), Bottom(nBottom), Bitmap(xBitmap)
83 { }
84 sal_Int32 Top;
85 sal_Int32 Bottom;
86 Reference<rendering::XBitmap> Bitmap;
88 typedef ::boost::shared_ptr<NotesBitmapDescriptor> SharedNotesBitmapDescriptor;
90 typedef ::std::vector<SharedNotesBitmapDescriptor> BitmapDescriptorSet;
93 /** Container of bitmaps that show parts of the notes text. If the bitmaps
94 use more than a specified amount of memory then some bitmaps that are
95 currently not on the screen are discarded.
97 class PresenterNotesView::BitmapContainer
98 : public BitmapDescriptorSet
100 public:
101 BitmapContainer (const ::boost::shared_ptr<BitmapFactory>& rpFactory);
103 /** Call this when for instance the font size has changed and all
104 bitmaps have to be created anew or the slide has changed.
106 void Clear (void);
107 void Prune (const sal_Int32 nTop, const sal_Int32 nBottom);
108 sal_Int32 GetMemorySize (const Reference<rendering::XBitmap>& rxBitmap) const;
109 sal_Int32 GetMemorySize (void) const;
110 const_iterator GetBegin (const double nTop, const double nBottom);
111 const_iterator GetEnd (const double nTop, const double nBottom);
113 private:
114 ::boost::shared_ptr<BitmapFactory> mpFactory;
115 sal_Int32 mnMaximalCacheSize;
116 const sal_Int32 mnPartHeight;
117 sal_Int32 mnTotalHeight;
119 sal_Int32 GetTopIndex (const double nValue) const;
120 sal_Int32 GetBottomIndex (const double nValue) const;
121 void ProvideBitmaps (
122 const sal_Int32 nTopIndex,
123 const sal_Int32 nBottomIndex);
129 //===== PresenterNotesView::BitmapFactory =====================================
131 class PresenterNotesView::BitmapFactory
133 public:
134 BitmapFactory (
135 const Reference<XComponentContext>& rxComponentContext,
136 const PresenterTheme::SharedFontDescriptor& rpFont,
137 const Reference<rendering::XCanvas>& rxCanvas,
138 const SharedBitmapDescriptor& rpBackground);
139 ~BitmapFactory (void);
140 void SetText (const OUString& rsText);
141 void SetWidth (const sal_Int32 nWidth);
142 void SetFontHeight (const sal_Int32 nHeight);
143 sal_Int32 GetHeightForWidth (const sal_Int32 nWidth);
144 sal_Int32 GetTotalHeight (void);
145 Reference<rendering::XBitmap> CreateBitmap (const sal_Int32 nTop, const sal_Int32 nBottom);
147 private:
148 Reference<rendering::XCanvas> mxCanvas;
149 OUString msText;
150 PresenterTheme::SharedFontDescriptor mpFont;
151 css::awt::FontDescriptor maFontDescriptor;
152 sal_Int32 mnWidth;
153 sal_Int32 mnTotalHeight;
154 css::uno::Reference<css::beans::XPropertySet> mxTextView;
155 SharedBitmapDescriptor mpBackground;
161 //===== PresenterNotesView ====================================================
163 PresenterNotesView::PresenterNotesView (
164 const Reference<XComponentContext>& rxComponentContext,
165 const Reference<XResourceId>& rxViewId,
166 const Reference<frame::XController>& rxController,
167 const ::rtl::Reference<PresenterController>& rpPresenterController)
168 : PresenterNotesViewInterfaceBase(m_aMutex),
169 mxViewId(rxViewId),
170 mpPresenterController(rpPresenterController),
171 mxCanvas(),
172 mpBitmapContainer(),
173 mpBitmapFactory(),
174 mxCurrentNotesPage(),
175 mpScrollBar(),
176 mxToolBarWindow(),
177 mxToolBarCanvas(),
178 mpToolBar(),
179 mpCloseButton(),
180 maSeparatorColor(0xffffff),
181 mnSeparatorYLocation(0),
182 maTextBoundingBox(),
183 mpBackground(),
184 mnTop(0),
185 mnFontSize(12)
189 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
190 Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
191 Reference<XPane> xPane (xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
193 mxParentWindow = xPane->getWindow();
194 mxCanvas = xPane->getCanvas();
196 const OUString sResourceURL (mxViewId->getResourceURL());
197 PresenterTheme::SharedFontDescriptor pFont(
198 rpPresenterController->GetViewFont(sResourceURL));
199 mpBitmapFactory.reset(new BitmapFactory(
200 rxComponentContext,
201 pFont,
202 mxCanvas,
203 mpPresenterController->GetViewBackground(mxViewId->getResourceURL())));
204 mpBitmapContainer.reset(new BitmapContainer(mpBitmapFactory));
206 maSeparatorColor = pFont->mnColor;
207 mnFontSize = pFont->mnSize;
209 CreateToolBar(rxComponentContext, rpPresenterController);
211 mpCloseButton = PresenterButton::Create(
212 rxComponentContext,
213 mpPresenterController,
214 mpPresenterController->GetTheme(),
215 mxParentWindow,
216 mxCanvas,
217 A2S("NotesViewCloser"));
219 if (mxParentWindow.is())
221 mxParentWindow->addWindowListener(this);
222 mxParentWindow->addPaintListener(this);
223 mxParentWindow->addKeyListener(this);
224 mxParentWindow->setVisible(sal_True);
227 mpScrollBar = new PresenterVerticalScrollBar(
228 rxComponentContext,
229 mxParentWindow,
230 mpPresenterController->GetPaintManager(),
231 ::boost::bind(&PresenterNotesView::SetTop, this, _1));
232 mpScrollBar->SetBackground(
233 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()));
235 mpScrollBar->SetCanvas(mxCanvas);
237 Layout();
239 catch (RuntimeException&)
241 PresenterNotesView::disposing();
242 throw;
249 PresenterNotesView::~PresenterNotesView (void)
256 void SAL_CALL PresenterNotesView::disposing (void)
258 if (mxParentWindow.is())
260 mxParentWindow->removeWindowListener(this);
261 mxParentWindow->removePaintListener(this);
262 mxParentWindow->removeKeyListener(this);
263 mxParentWindow = NULL;
266 // Dispose tool bar.
268 Reference<XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
269 mpToolBar = NULL;
270 if (xComponent.is())
271 xComponent->dispose();
274 Reference<XComponent> xComponent (mxToolBarCanvas, UNO_QUERY);
275 mxToolBarCanvas = NULL;
276 if (xComponent.is())
277 xComponent->dispose();
280 Reference<XComponent> xComponent (mxToolBarWindow, UNO_QUERY);
281 mxToolBarWindow = NULL;
282 if (xComponent.is())
283 xComponent->dispose();
286 // Dispose close button
288 Reference<XComponent> xComponent (static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
289 mpCloseButton = NULL;
290 if (xComponent.is())
291 xComponent->dispose();
294 // Create the tool bar.
296 mpScrollBar = NULL;
298 mxViewId = NULL;
304 void PresenterNotesView::CreateToolBar (
305 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
306 const ::rtl::Reference<PresenterController>& rpPresenterController)
308 if (rpPresenterController.get() == NULL)
309 return;
311 Reference<drawing::XPresenterHelper> xPresenterHelper (
312 rpPresenterController->GetPresenterHelper());
313 if ( ! xPresenterHelper.is())
314 return;
316 // Create a new window as container of the tool bar.
317 mxToolBarWindow = xPresenterHelper->createWindow(
318 mxParentWindow,
319 sal_False,
320 sal_True,
321 sal_False,
322 sal_False);
323 mxToolBarCanvas = xPresenterHelper->createSharedCanvas (
324 Reference<rendering::XSpriteCanvas>(mxCanvas, UNO_QUERY),
325 mxParentWindow,
326 mxCanvas,
327 mxParentWindow,
328 mxToolBarWindow);
330 // Create the tool bar.
331 mpToolBar = new PresenterToolBar(
332 rxContext,
333 mxToolBarWindow,
334 mxToolBarCanvas,
335 rpPresenterController,
336 PresenterToolBar::Left);
337 mpToolBar->Initialize(
338 A2S("PresenterScreenSettings/ToolBars/NotesToolBar"));
344 void PresenterNotesView::SetSlide (const Reference<drawing::XDrawPage>& rxNotesPage)
346 static const ::rtl::OUString sNotesShapeName (
347 A2S("com.sun.star.presentation.NotesShape"));
348 static const ::rtl::OUString sTextShapeName (
349 A2S("com.sun.star.drawing.TextShape"));
351 Reference<container::XIndexAccess> xIndexAccess (rxNotesPage, UNO_QUERY);
352 if (xIndexAccess.is())
354 ::rtl::OUString sText;
356 // Iterate over all shapes and find the one that holds the text.
357 sal_Int32 nCount (xIndexAccess->getCount());
358 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
361 Reference<lang::XServiceName> xServiceName (
362 xIndexAccess->getByIndex(nIndex), UNO_QUERY);
363 if (xServiceName.is()
364 && xServiceName->getServiceName().equals(sNotesShapeName))
366 Reference<text::XTextRange> xText (xServiceName, UNO_QUERY);
367 if (xText.is())
369 sText += xText->getString();
372 else
374 Reference<drawing::XShapeDescriptor> xShapeDescriptor (
375 xIndexAccess->getByIndex(nIndex), UNO_QUERY);
376 if (xShapeDescriptor.is())
378 ::rtl::OUString sType (xShapeDescriptor->getShapeType());
379 if (sType.equals(sNotesShapeName) || sType.equals(sTextShapeName))
381 Reference<text::XTextRange> xText (
382 xIndexAccess->getByIndex(nIndex), UNO_QUERY);
383 if (xText.is())
385 sText += xText->getString();
392 mpBitmapFactory->SetText(sText);
394 Layout();
395 mpBitmapContainer->Clear();
397 if (mpScrollBar.get() != NULL)
399 mpScrollBar->SetThumbPosition(0, false);
400 UpdateScrollBar();
403 Invalidate();
410 //----- lang::XEventListener -------------------------------------------------
412 void SAL_CALL PresenterNotesView::disposing (const lang::EventObject& rEventObject)
413 throw (RuntimeException)
415 if (rEventObject.Source == mxParentWindow)
416 mxParentWindow = NULL;
422 //----- XWindowListener -------------------------------------------------------
424 void SAL_CALL PresenterNotesView::windowResized (const awt::WindowEvent& rEvent)
425 throw (RuntimeException)
427 (void)rEvent;
428 Layout();
434 void SAL_CALL PresenterNotesView::windowMoved (const awt::WindowEvent& rEvent)
435 throw (RuntimeException)
437 (void)rEvent;
443 void SAL_CALL PresenterNotesView::windowShown (const lang::EventObject& rEvent)
444 throw (RuntimeException)
446 (void)rEvent;
452 void SAL_CALL PresenterNotesView::windowHidden (const lang::EventObject& rEvent)
453 throw (RuntimeException)
455 (void)rEvent;
461 //----- XPaintListener --------------------------------------------------------
463 void SAL_CALL PresenterNotesView::windowPaint (const awt::PaintEvent& rEvent)
464 throw (RuntimeException)
466 ThrowIfDisposed();
468 if ( ! mbIsPresenterViewActive)
469 return;
471 ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
472 Paint(rEvent.UpdateRect);
478 //----- XResourceId -----------------------------------------------------------
480 Reference<XResourceId> SAL_CALL PresenterNotesView::getResourceId (void)
481 throw (RuntimeException)
483 return mxViewId;
489 sal_Bool SAL_CALL PresenterNotesView::isAnchorOnly (void)
490 throw (RuntimeException)
492 return false;
498 //----- XDrawView -------------------------------------------------------------
500 void SAL_CALL PresenterNotesView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
501 throw (RuntimeException)
503 // Get the associated notes page.
504 mxCurrentNotesPage = NULL;
507 Reference<presentation::XPresentationPage> xPresentationPage(rxSlide, UNO_QUERY);
508 if (xPresentationPage.is())
509 mxCurrentNotesPage = xPresentationPage->getNotesPage();
511 catch (RuntimeException&)
515 SetSlide(mxCurrentNotesPage);
521 Reference<drawing::XDrawPage> SAL_CALL PresenterNotesView::getCurrentPage (void)
522 throw (RuntimeException)
524 return NULL;
530 //----- XKeyListener ----------------------------------------------------------
532 void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent)
533 throw (RuntimeException)
535 switch (rEvent.KeyCode)
537 case awt::Key::A:
538 Scroll(-gnLineScrollFactor * mnFontSize);
539 break;
541 case awt::Key::Y:
542 case awt::Key::Z:
543 Scroll(+gnLineScrollFactor * mnFontSize);
544 break;
546 case awt::Key::S:
547 ChangeFontSize(-1);
548 break;
550 case awt::Key::G:
551 ChangeFontSize(+1);
552 break;
559 void SAL_CALL PresenterNotesView::keyReleased (const awt::KeyEvent& rEvent)
560 throw (RuntimeException)
562 (void)rEvent;
568 //-----------------------------------------------------------------------------
570 void PresenterNotesView::Layout (void)
572 if ( ! mxParentWindow.is())
573 return;
575 awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
576 geometry::RealRectangle2D aNewTextBoundingBox (0,0,aWindowBox.Width, aWindowBox.Height);
578 // Size the tool bar and the horizontal separator above it.
579 if (mxToolBarWindow.is())
581 const geometry::RealSize2D aToolBarSize (mpToolBar->GetMinimalSize());
582 const sal_Int32 nToolBarHeight = sal_Int32(aToolBarSize.Height + 0.5);
583 mxToolBarWindow->setPosSize(0, aWindowBox.Height - nToolBarHeight,
584 sal_Int32(aToolBarSize.Width + 0.5), nToolBarHeight,
585 awt::PosSize::POSSIZE);
586 aNewTextBoundingBox.Y2 -= nToolBarHeight;
588 mnSeparatorYLocation = aWindowBox.Height - nToolBarHeight - gnSpaceBelowSeparator;
589 aNewTextBoundingBox.Y2 = mnSeparatorYLocation - gnSpaceAboveSeparator;
591 // Place the close button.
592 if (mpCloseButton.get() != NULL)
593 mpCloseButton->SetCenter(geometry::RealPoint2D(
594 (aWindowBox.Width + aToolBarSize.Width) / 2,
595 aWindowBox.Height - aToolBarSize.Height/2));
598 // Check whether the vertical scroll bar is necessary.
599 if (mpScrollBar.get() != NULL)
601 bool bShowVerticalScrollbar (false);
604 const double nTextBoxHeight (aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1);
605 const sal_Int32 nHeight (mpBitmapFactory->GetHeightForWidth(
606 sal_Int32(aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1)));
607 if (nHeight > nTextBoxHeight)
609 bShowVerticalScrollbar = true;
610 aNewTextBoundingBox.X2 -= mpScrollBar->GetSize();
612 mpScrollBar->SetTotalSize(nHeight);
614 catch(beans::UnknownPropertyException&)
616 OSL_ASSERT(false);
619 mpScrollBar->SetVisible(bShowVerticalScrollbar);
620 mpBitmapFactory->SetWidth(sal_Int32(aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1));
621 mpScrollBar->SetPosSize(
622 geometry::RealRectangle2D(
623 aNewTextBoundingBox.X2,
624 aNewTextBoundingBox.X1,
625 aNewTextBoundingBox.X2 + mpScrollBar->GetSize(),
626 aNewTextBoundingBox.Y2));
627 if ( ! bShowVerticalScrollbar)
628 mpScrollBar->SetThumbPosition(0, false);
630 UpdateScrollBar();
633 // Has the text area has changed it position or size?
634 if (aNewTextBoundingBox.X1 != maTextBoundingBox.X1
635 || aNewTextBoundingBox.Y1 != maTextBoundingBox.Y1
636 || aNewTextBoundingBox.X2 != maTextBoundingBox.X2
637 || aNewTextBoundingBox.Y2 != maTextBoundingBox.Y2)
639 maTextBoundingBox = aNewTextBoundingBox;
641 // When the size has changed then we need a new text bitmap.
642 if (aNewTextBoundingBox.X2-aNewTextBoundingBox.X1
643 != maTextBoundingBox.X2-maTextBoundingBox.X1
644 || aNewTextBoundingBox.Y2-aNewTextBoundingBox.Y1
645 != maTextBoundingBox.Y2-maTextBoundingBox.Y1)
647 mpBitmapContainer->Clear();
655 void PresenterNotesView::Paint (const awt::Rectangle& rUpdateBox)
657 if ( ! mxParentWindow.is())
658 return;
659 if ( ! mxCanvas.is())
660 return;
662 if (mpBackground.get() == NULL)
663 mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
665 if (rUpdateBox.Y < maTextBoundingBox.Y2
666 && rUpdateBox.X < maTextBoundingBox.X2)
668 PaintText(rUpdateBox);
671 if (rUpdateBox.Y + rUpdateBox.Height > maTextBoundingBox.Y2)
673 PaintToolBar(rUpdateBox);
680 void PresenterNotesView::PaintToolBar (const awt::Rectangle& rUpdateBox)
682 awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
684 rendering::ViewState aViewState (
685 geometry::AffineMatrix2D(1,0,0, 0,1,0),
686 NULL);
687 rendering::RenderState aRenderState(
688 geometry::AffineMatrix2D(1,0,0, 0,1,0),
689 NULL,
690 Sequence<double>(4),
691 rendering::CompositeOperation::SOURCE);
693 if (mpBackground.get() != NULL)
695 // Paint the background.
696 mpPresenterController->GetCanvasHelper()->Paint(
697 mpBackground,
698 mxCanvas,
699 rUpdateBox,
700 awt::Rectangle(0,sal_Int32(maTextBoundingBox.Y2),aWindowBox.Width,aWindowBox.Height),
701 awt::Rectangle());
704 // Paint the horizontal separator.
705 OSL_ASSERT(mxViewId.is());
706 PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
708 mxCanvas->drawLine(
709 geometry::RealPoint2D(0,mnSeparatorYLocation),
710 geometry::RealPoint2D(aWindowBox.Width,mnSeparatorYLocation),
711 aViewState,
712 aRenderState);
718 void PresenterNotesView::PaintText (const awt::Rectangle& rUpdateBox)
720 const awt::Rectangle aBox (PresenterGeometryHelper::Intersection(rUpdateBox,
721 PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox)));
723 if (aBox.Width <= 0 || aBox.Height <= 0)
724 return;
726 rendering::ViewState aViewState (
727 geometry::AffineMatrix2D(1,0,0, 0,1,0),
728 PresenterGeometryHelper::CreatePolygon(aBox, mxCanvas->getDevice()));
729 rendering::RenderState aRenderState(
730 geometry::AffineMatrix2D(1,0,0, 0,1,0),
731 NULL,
732 Sequence<double>(3),
733 rendering::CompositeOperation::SOURCE);
735 if (mpBackground.get() != NULL)
737 // Paint the background.
738 mpPresenterController->GetCanvasHelper()->Paint(
739 mpBackground,
740 mxCanvas,
741 rUpdateBox,
742 aBox,
743 awt::Rectangle());
746 // Iterator over all bitmaps that are (partially) visible and paint
747 // them.
748 const double nBottom (mnTop + maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
749 BitmapContainer::const_iterator iBitmap (mpBitmapContainer->GetBegin(mnTop, nBottom));
750 BitmapContainer::const_iterator iEnd (mpBitmapContainer->GetEnd(mnTop, nBottom));
751 for ( ; iBitmap!=iEnd; ++iBitmap)
753 if (iBitmap->get() != NULL && (*iBitmap)->Bitmap.is())
755 aRenderState.AffineTransform.m02 = maTextBoundingBox.X1;
756 aRenderState.AffineTransform.m12 = (*iBitmap)->Top + maTextBoundingBox.Y1 - mnTop;
757 mxCanvas->drawBitmap((*iBitmap)->Bitmap, aViewState, aRenderState);
761 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
762 if (xSpriteCanvas.is())
763 xSpriteCanvas->updateScreen(sal_False);
769 void PresenterNotesView::Invalidate (void)
771 mpPresenterController->GetPaintManager()->Invalidate(
772 mxParentWindow,
773 PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox));
779 void PresenterNotesView::Scroll (const double rnDistance)
783 mnTop += rnDistance;
785 UpdateScrollBar();
786 Invalidate();
788 catch (beans::UnknownPropertyException&)
795 void PresenterNotesView::SetTop (const double nTop)
799 mnTop = nTop;
801 UpdateScrollBar();
802 Invalidate();
804 catch (beans::UnknownPropertyException&)
811 void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange)
813 const sal_Int32 nNewSize (mnFontSize + nSizeChange);
814 if (nNewSize > 5)
816 mnFontSize = nNewSize;
817 mpBitmapFactory->SetFontHeight(mnFontSize);
818 mpBitmapContainer->Clear();
820 Layout();
821 UpdateScrollBar();
822 Invalidate();
824 // Write the new font size to the configuration to make it persistent.
827 const OUString sStyleName (mpPresenterController->GetTheme()->GetStyleName(
828 mxViewId->getResourceURL()));
829 ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration (
830 mpPresenterController->GetTheme()->GetNodeForViewStyle(
831 sStyleName,
832 PresenterConfigurationAccess::READ_WRITE));
833 if (pConfiguration.get()==NULL || ! pConfiguration->IsValid())
834 return;
836 pConfiguration->GoToChild(A2S("Font"));
837 pConfiguration->SetProperty(A2S("Size"), Any((sal_Int32)(nNewSize+0.5)));
838 pConfiguration->CommitChanges();
840 catch (Exception&)
842 OSL_ASSERT(false);
850 void PresenterNotesView::UpdateScrollBar (void)
852 if (mpScrollBar.get() != NULL)
856 double nHeight = mpBitmapFactory->GetTotalHeight();
857 mpScrollBar->SetTotalSize(nHeight);
859 catch(beans::UnknownPropertyException&)
861 OSL_ASSERT(false);
864 mpScrollBar->SetLineHeight(mnFontSize*1.2);
865 mpScrollBar->SetThumbPosition(mnTop, false);
867 mpScrollBar->SetThumbSize(maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
868 mpScrollBar->CheckValues();
875 void PresenterNotesView::ThrowIfDisposed (void)
876 throw (::com::sun::star::lang::DisposedException)
878 if (rBHelper.bDisposed || rBHelper.bInDispose)
880 throw lang::DisposedException (
881 A2S("PresenterNotesView object has already been disposed"),
882 static_cast<uno::XWeak*>(this));
889 //===== PresenterNotesView::BitmapContainer ===================================
891 PresenterNotesView::BitmapContainer::BitmapContainer (
892 const ::boost::shared_ptr<BitmapFactory>& rpFactory)
893 : mpFactory(rpFactory),
894 mnMaximalCacheSize(gnMaximalCacheSize),
895 mnPartHeight(gnPartHeight),
896 mnTotalHeight(0)
903 void PresenterNotesView::BitmapContainer::Clear (void)
905 clear();
906 mnTotalHeight = mpFactory->GetTotalHeight();
907 const sal_Int32 nSize ((mnTotalHeight+mnPartHeight-1) / mnPartHeight);
908 if (nSize > 0)
909 resize(nSize, SharedNotesBitmapDescriptor());
915 void PresenterNotesView::BitmapContainer::Prune (
916 const sal_Int32 nTopIndex,
917 const sal_Int32 nBottomIndex)
919 sal_Int32 nDistance (::std::max(nTopIndex-0, sal_Int32(size())-nBottomIndex));
920 sal_Int32 nIndex;
921 sal_Int32 nTotalSize (GetMemorySize());
922 iterator iPart;
924 while (nDistance > 0
925 && nTotalSize > mnMaximalCacheSize)
927 // Remove bitmap that is nDistance places before nTopIndex.
928 nIndex = nTopIndex - nDistance;
929 if (nIndex >= 0)
931 iPart = begin() + nIndex;
932 nTotalSize -= GetMemorySize((*iPart)->Bitmap);
933 (*iPart)->Bitmap = NULL;
936 if (nTotalSize <= mnMaximalCacheSize)
937 break;
939 // Remove bitmap that is nDistance places behind nBottomIndex.
940 nIndex = nBottomIndex + nDistance;
941 if (nIndex < sal_Int32(size()))
943 iPart = begin() + nIndex;
944 nTotalSize -= GetMemorySize((*iPart)->Bitmap);
945 (*iPart)->Bitmap = NULL;
953 sal_Int32 PresenterNotesView::BitmapContainer::GetMemorySize (
954 const Reference<rendering::XBitmap>& rxBitmap) const
956 if (rxBitmap.is())
958 const geometry::IntegerSize2D aSize (rxBitmap->getSize());
959 return aSize.Width * aSize.Height * 3;
961 return 0;
967 sal_Int32 PresenterNotesView::BitmapContainer::GetMemorySize (void) const
969 sal_Int32 nSize (0);
970 for (const_iterator iBitmap=begin(); iBitmap!=end(); ++iBitmap)
971 if (iBitmap->get() != NULL)
972 if ((*iBitmap)->Bitmap.is())
973 nSize += GetMemorySize((*iBitmap)->Bitmap);
974 return nSize;
980 sal_Int32 PresenterNotesView::BitmapContainer::GetTopIndex (const double nValue) const
982 const sal_Int32 nIndex (sal::static_int_cast<sal_Int32>(nValue) / mnPartHeight);
983 if (nIndex < 0)
984 return 0;
985 else if (nIndex >= sal_Int32(size()))
986 return sal_Int32(size())-1;
987 else
988 return nIndex;
994 sal_Int32 PresenterNotesView::BitmapContainer::GetBottomIndex (const double nValue) const
996 const sal_Int32 nIndex ((sal::static_int_cast<sal_Int32>(nValue)+mnPartHeight-1) / mnPartHeight);
997 if (nIndex >= sal_Int32(size()))
998 return size()-1;
999 else if (nIndex < 0)
1000 return -1;
1001 else return nIndex;
1007 PresenterNotesView::BitmapContainer::const_iterator PresenterNotesView::BitmapContainer::GetBegin (
1008 const double nTop,
1009 const double nBottom)
1011 const sal_Int32 nTopIndex (GetTopIndex(nTop));
1012 const sal_Int32 nBottomIndex(GetBottomIndex(nBottom));
1013 ProvideBitmaps(nTopIndex, nBottomIndex);
1014 if (nTopIndex >= 0)
1015 return begin()+nTopIndex;
1016 else
1017 return end();
1023 PresenterNotesView::BitmapContainer::const_iterator PresenterNotesView::BitmapContainer::GetEnd (
1024 const double nTop,
1025 const double nBottom)
1027 (void)nTop;
1028 const sal_Int32 nIndex (GetBottomIndex(nBottom));
1029 if (nIndex >= 0)
1030 return (begin() + nIndex)+1;
1031 else
1032 return end();
1038 void PresenterNotesView::BitmapContainer::ProvideBitmaps (
1039 const sal_Int32 nTopIndex,
1040 const sal_Int32 nBottomIndex)
1042 BitmapDescriptorSet aNewBitmaps;
1044 if (nTopIndex < 0 || nBottomIndex<0)
1045 return;
1047 if (nTopIndex > nBottomIndex)
1048 return;
1050 for (sal_Int32 nIndex=nTopIndex; nIndex<=nBottomIndex; ++nIndex)
1052 iterator iPart (begin() + nIndex);
1053 const sal_Int32 nTop (nIndex * mnPartHeight);
1054 const sal_Int32 nBottom (nTop + mnPartHeight - 1);
1055 if (iPart->get() == NULL)
1057 iPart->reset(new NotesBitmapDescriptor(nTop, nBottom, NULL));
1059 if ( ! (*iPart)->Bitmap.is())
1061 (*iPart)->Bitmap = mpFactory->CreateBitmap(nTop, nBottom);
1062 (*iPart)->Top = nTop;
1063 (*iPart)->Bottom = nTop + (*iPart)->Bitmap->getSize().Height;
1067 // Calculate memory size used by all bitmaps.
1068 if (GetMemorySize() > mnMaximalCacheSize)
1069 Prune(nTopIndex,nBottomIndex);
1075 //===== PresenterNotesView::BitmapFactory =====================================
1077 PresenterNotesView::BitmapFactory::BitmapFactory (
1078 const Reference<XComponentContext>& rxComponentContext,
1079 const PresenterTheme::SharedFontDescriptor& rpFont,
1080 const Reference<rendering::XCanvas>& rxCanvas,
1081 const SharedBitmapDescriptor& rpBackground)
1082 : mxCanvas(rxCanvas),
1083 msText(),
1084 mpFont(rpFont),
1085 maFontDescriptor(),
1086 mnWidth(100),
1087 mnTotalHeight(0),
1088 mxTextView(),
1089 mpBackground(rpBackground)
1091 Reference<lang::XMultiComponentFactory> xFactory (
1092 rxComponentContext->getServiceManager(), UNO_QUERY_THROW);
1093 Sequence<Any> aArguments(1);
1094 aArguments[0] <<= rxCanvas;
1095 mxTextView = Reference<beans::XPropertySet>(
1096 xFactory->createInstanceWithArgumentsAndContext(
1097 A2S("com.sun.star.drawing.PresenterTextView"),
1098 aArguments,
1099 rxComponentContext),
1100 UNO_QUERY_THROW);
1101 mxTextView->setPropertyValue(A2S("BackgroundColor"), Any(sal_uInt32(0x00ff0000)));
1102 if (mpFont.get() != NULL)
1104 maFontDescriptor.Name = mpFont->msFamilyName;
1105 maFontDescriptor.Height = sal::static_int_cast<sal_Int16>(mpFont->mnSize);
1106 maFontDescriptor.StyleName = mpFont->msStyleName;
1107 mxTextView->setPropertyValue(A2S("FontDescriptor"), Any(maFontDescriptor));
1108 mxTextView->setPropertyValue(A2S("TextColor"), Any(mpFont->mnColor));
1115 PresenterNotesView::BitmapFactory::~BitmapFactory (void)
1118 Reference<XComponent> xComponent (mxTextView, UNO_QUERY);
1119 mxTextView = NULL;
1120 if (xComponent.is())
1121 xComponent->dispose();
1128 void PresenterNotesView::BitmapFactory::SetText (const OUString& rsText)
1130 if (mxTextView.is())
1131 mxTextView->setPropertyValue(A2S("Text"), Any(rsText));
1132 mnTotalHeight = 0;
1138 void PresenterNotesView::BitmapFactory::SetWidth (const sal_Int32 nWidth)
1140 mnWidth = nWidth;
1146 void PresenterNotesView::BitmapFactory::SetFontHeight (const sal_Int32 nHeight)
1148 maFontDescriptor.Height = sal::static_int_cast<sal_Int16>(nHeight);
1149 mxTextView->setPropertyValue(A2S("FontDescriptor"), Any(maFontDescriptor));
1150 if (mpFont.get() != NULL)
1151 mpFont->mnSize = nHeight;
1152 mnTotalHeight = 0;
1158 sal_Int32 PresenterNotesView::BitmapFactory::GetHeightForWidth (const sal_Int32 nWidth)
1160 mxTextView->setPropertyValue(
1161 A2S("Size"),
1162 Any(awt::Size(nWidth, 100)));
1163 sal_Int32 nHeight (0);
1164 if (mxTextView->getPropertyValue(A2S("TotalHeight")) >>= nHeight)
1165 return nHeight;
1166 else
1167 return -1;
1173 sal_Int32 PresenterNotesView::BitmapFactory::GetTotalHeight (void)
1175 if (mnTotalHeight == 0)
1177 sal_Int32 nHeight (0);
1178 if (mxTextView->getPropertyValue(A2S("TotalHeight")) >>= nHeight)
1179 mnTotalHeight = nHeight;
1181 return mnTotalHeight;
1187 Reference<rendering::XBitmap> PresenterNotesView::BitmapFactory::CreateBitmap (
1188 const sal_Int32 nTop,
1189 const sal_Int32 nBottom)
1191 // Get text bitmap.
1192 sal_Int32 nHeight;
1193 if (nBottom > GetTotalHeight())
1194 nHeight = GetTotalHeight() - nTop + 1;
1195 else
1196 nHeight = nBottom - nTop + 1;
1197 mxTextView->setPropertyValue(A2S("Size"), Any(awt::Size(mnWidth,nHeight)));
1198 mxTextView->setPropertyValue(A2S("Top"), Any(sal_Int32(nTop)));
1199 Reference<rendering::XBitmap> xTextBitmap (
1200 mxTextView->getPropertyValue(A2S("Bitmap")), UNO_QUERY);
1202 return xTextBitmap;
1208 } } // end of namespace ::sdext::presenter