1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sdext.hxx"
30 
31 #include "PresenterNotesView.hxx"
32 #include "PresenterButton.hxx"
33 #include "PresenterCanvasHelper.hxx"
34 #include "PresenterGeometryHelper.hxx"
35 #include "PresenterPaintManager.hxx"
36 #include "PresenterScrollBar.hxx"
37 #include "PresenterTextView.hxx"
38 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
39 #include <com/sun/star/awt/Key.hpp>
40 #include <com/sun/star/awt/KeyModifier.hpp>
41 #include <com/sun/star/awt/PosSize.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
44 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
45 #include <com/sun/star/drawing/framework/XPane.hpp>
46 #include <com/sun/star/lang/XServiceName.hpp>
47 #include <com/sun/star/presentation/XPresentationPage.hpp>
48 #include <com/sun/star/rendering/CompositeOperation.hpp>
49 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
50 #include <com/sun/star/text/XTextRange.hpp>
51 #include <com/sun/star/util/XChangesBatch.hpp>
52 #include <com/sun/star/container/XChild.hpp>
53 #include <boost/bind.hpp>
54 #include <set>
55 
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::drawing::framework;
59 using ::rtl::OUString;
60 
61 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
62 
63 static const sal_Int32 gnSpaceBelowSeparator (10);
64 static const sal_Int32 gnSpaceAboveSeparator (10);
65 static const sal_Int32 gnPartHeight (128);
66 /** Maximal size of memory used for bitmaps which show the notes text.
67 */
68 static const sal_Int32 gnMaximalCacheSize (8*1024*1024);
69 static const double gnLineScrollFactor (1.2);
70 
71 namespace sdext { namespace presenter {
72 
73 //===== PresenterNotesView ====================================================
74 
75 PresenterNotesView::PresenterNotesView (
76     const Reference<XComponentContext>& rxComponentContext,
77     const Reference<XResourceId>& rxViewId,
78     const Reference<frame::XController>& rxController,
79     const ::rtl::Reference<PresenterController>& rpPresenterController)
80     : PresenterNotesViewInterfaceBase(m_aMutex),
81       mxViewId(rxViewId),
82       mpPresenterController(rpPresenterController),
83       mxCanvas(),
84       mxCurrentNotesPage(),
85       mpScrollBar(),
86       mxToolBarWindow(),
87       mxToolBarCanvas(),
88       mpToolBar(),
89       mpCloseButton(),
90       maSeparatorColor(0xffffff),
91       mnSeparatorYLocation(0),
92       maTextBoundingBox(),
93       mpBackground(),
94       mnTop(0),
95       mpFont(),
96       mpTextView()
97 {
98     try
99     {
100         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
101         Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
102         Reference<XPane> xPane (xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
103 
104         mxParentWindow = xPane->getWindow();
105         mxCanvas = xPane->getCanvas();
106         mpTextView.reset(new PresenterTextView(
107             rxComponentContext,
108             mxCanvas,
109             mpPresenterController->GetPaintManager()->GetInvalidator(mxParentWindow)));
110 
111         const OUString sResourceURL (mxViewId->getResourceURL());
112         mpFont.reset(new PresenterTheme::FontDescriptor(
113             rpPresenterController->GetViewFont(sResourceURL)));
114         maSeparatorColor = mpFont->mnColor;
115         mpTextView->SetFont(mpFont);
116 
117         CreateToolBar(rxComponentContext, rpPresenterController);
118 
119         mpCloseButton = PresenterButton::Create(
120             rxComponentContext,
121             mpPresenterController,
122             mpPresenterController->GetTheme(),
123             mxParentWindow,
124             mxCanvas,
125             A2S("NotesViewCloser"));
126 
127         if (mxParentWindow.is())
128         {
129             mxParentWindow->addWindowListener(this);
130             mxParentWindow->addPaintListener(this);
131             mxParentWindow->addKeyListener(this);
132             mxParentWindow->setVisible(sal_True);
133         }
134 
135         mpScrollBar = new PresenterVerticalScrollBar(
136             rxComponentContext,
137             mxParentWindow,
138             mpPresenterController->GetPaintManager(),
139             ::boost::bind(&PresenterNotesView::SetTop, this, _1));
140         mpScrollBar->SetBackground(
141             mpPresenterController->GetViewBackground(mxViewId->getResourceURL()));
142 
143         mpScrollBar->SetCanvas(mxCanvas);
144 
145         Layout();
146     }
147     catch (RuntimeException&)
148     {
149         PresenterNotesView::disposing();
150         throw;
151     }
152 }
153 
154 
155 
156 
157 PresenterNotesView::~PresenterNotesView (void)
158 {
159 }
160 
161 
162 
163 
164 void SAL_CALL PresenterNotesView::disposing (void)
165 {
166     if (mxParentWindow.is())
167     {
168         mxParentWindow->removeWindowListener(this);
169         mxParentWindow->removePaintListener(this);
170         mxParentWindow->removeKeyListener(this);
171         mxParentWindow = NULL;
172     }
173 
174     // Dispose tool bar.
175     {
176         Reference<XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY);
177         mpToolBar = NULL;
178         if (xComponent.is())
179             xComponent->dispose();
180     }
181     {
182         Reference<XComponent> xComponent (mxToolBarCanvas, UNO_QUERY);
183         mxToolBarCanvas = NULL;
184         if (xComponent.is())
185             xComponent->dispose();
186     }
187     {
188         Reference<XComponent> xComponent (mxToolBarWindow, UNO_QUERY);
189         mxToolBarWindow = NULL;
190         if (xComponent.is())
191             xComponent->dispose();
192     }
193 
194     // Dispose close button
195     {
196         Reference<XComponent> xComponent (static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
197         mpCloseButton = NULL;
198         if (xComponent.is())
199             xComponent->dispose();
200     }
201 
202     // Create the tool bar.
203 
204     mpScrollBar = NULL;
205 
206     mxViewId = NULL;
207 }
208 
209 
210 
211 
212 void PresenterNotesView::CreateToolBar (
213     const css::uno::Reference<css::uno::XComponentContext>& rxContext,
214     const ::rtl::Reference<PresenterController>& rpPresenterController)
215 {
216     if (rpPresenterController.get() == NULL)
217         return;
218 
219     Reference<drawing::XPresenterHelper> xPresenterHelper (
220         rpPresenterController->GetPresenterHelper());
221     if ( ! xPresenterHelper.is())
222         return;
223 
224     // Create a new window as container of the tool bar.
225     mxToolBarWindow = xPresenterHelper->createWindow(
226         mxParentWindow,
227         sal_False,
228         sal_True,
229         sal_False,
230         sal_False);
231     mxToolBarCanvas = xPresenterHelper->createSharedCanvas (
232         Reference<rendering::XSpriteCanvas>(mxCanvas, UNO_QUERY),
233         mxParentWindow,
234         mxCanvas,
235         mxParentWindow,
236         mxToolBarWindow);
237 
238     // Create the tool bar.
239     mpToolBar = new PresenterToolBar(
240         rxContext,
241         mxToolBarWindow,
242         mxToolBarCanvas,
243         rpPresenterController,
244         PresenterToolBar::Left);
245     mpToolBar->Initialize(
246         A2S("PresenterScreenSettings/ToolBars/NotesToolBar"));
247 }
248 
249 
250 
251 
252 void PresenterNotesView::SetSlide (const Reference<drawing::XDrawPage>& rxNotesPage)
253 {
254     static const ::rtl::OUString sNotesShapeName (
255         A2S("com.sun.star.presentation.NotesShape"));
256     static const ::rtl::OUString sTextShapeName (
257         A2S("com.sun.star.drawing.TextShape"));
258 
259     Reference<container::XIndexAccess> xIndexAccess (rxNotesPage, UNO_QUERY);
260     if (xIndexAccess.is())
261     {
262         ::rtl::OUString sText;
263 
264         // Iterate over all shapes and find the one that holds the text.
265         sal_Int32 nCount (xIndexAccess->getCount());
266         for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
267         {
268 
269             Reference<lang::XServiceName> xServiceName (
270                 xIndexAccess->getByIndex(nIndex), UNO_QUERY);
271             if (xServiceName.is()
272                 && xServiceName->getServiceName().equals(sNotesShapeName))
273             {
274                 Reference<text::XTextRange> xText (xServiceName, UNO_QUERY);
275                 if (xText.is())
276                 {
277                     sText += xText->getString();
278                 }
279             }
280             else
281             {
282                 Reference<drawing::XShapeDescriptor> xShapeDescriptor (
283                     xIndexAccess->getByIndex(nIndex), UNO_QUERY);
284                 if (xShapeDescriptor.is())
285                 {
286                     ::rtl::OUString sType (xShapeDescriptor->getShapeType());
287                     if (sType.equals(sNotesShapeName) || sType.equals(sTextShapeName))
288                     {
289                         Reference<text::XTextRange> xText (
290                             xIndexAccess->getByIndex(nIndex), UNO_QUERY);
291                         if (xText.is())
292                         {
293                             sText += xText->getString();
294                             mpTextView->SetText(Reference<text::XText>(xText, UNO_QUERY));
295                         }
296                     }
297                 }
298             }
299         }
300 
301         Layout();
302 
303         if (mpScrollBar.get() != NULL)
304         {
305             mpScrollBar->SetThumbPosition(0, false);
306             UpdateScrollBar();
307         }
308 
309         Invalidate();
310     }
311 }
312 
313 
314 
315 
316 //-----  lang::XEventListener -------------------------------------------------
317 
318 void SAL_CALL PresenterNotesView::disposing (const lang::EventObject& rEventObject)
319     throw (RuntimeException)
320 {
321     if (rEventObject.Source == mxParentWindow)
322         mxParentWindow = NULL;
323 }
324 
325 
326 
327 
328 //----- XWindowListener -------------------------------------------------------
329 
330 void SAL_CALL PresenterNotesView::windowResized (const awt::WindowEvent& rEvent)
331     throw (RuntimeException)
332 {
333     (void)rEvent;
334     Layout();
335 }
336 
337 
338 
339 
340 void SAL_CALL PresenterNotesView::windowMoved (const awt::WindowEvent& rEvent)
341     throw (RuntimeException)
342 {
343     (void)rEvent;
344 }
345 
346 
347 
348 
349 void SAL_CALL PresenterNotesView::windowShown (const lang::EventObject& rEvent)
350     throw (RuntimeException)
351 {
352     (void)rEvent;
353 }
354 
355 
356 
357 
358 void SAL_CALL PresenterNotesView::windowHidden (const lang::EventObject& rEvent)
359     throw (RuntimeException)
360 {
361     (void)rEvent;
362 }
363 
364 
365 
366 
367 //----- XPaintListener --------------------------------------------------------
368 
369 void SAL_CALL PresenterNotesView::windowPaint (const awt::PaintEvent& rEvent)
370     throw (RuntimeException)
371 {
372     ThrowIfDisposed();
373 
374     if ( ! mbIsPresenterViewActive)
375         return;
376 
377     ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
378     Paint(rEvent.UpdateRect);
379 }
380 
381 
382 
383 
384 //----- XResourceId -----------------------------------------------------------
385 
386 Reference<XResourceId> SAL_CALL PresenterNotesView::getResourceId (void)
387     throw (RuntimeException)
388 {
389     return mxViewId;
390 }
391 
392 
393 
394 
395 sal_Bool SAL_CALL PresenterNotesView::isAnchorOnly (void)
396     throw (RuntimeException)
397 {
398     return false;
399 }
400 
401 
402 
403 
404 //----- XDrawView -------------------------------------------------------------
405 
406 void SAL_CALL PresenterNotesView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
407     throw (RuntimeException)
408 {
409     // Get the associated notes page.
410     mxCurrentNotesPage = NULL;
411     try
412     {
413         Reference<presentation::XPresentationPage> xPresentationPage(rxSlide, UNO_QUERY);
414         if (xPresentationPage.is())
415             mxCurrentNotesPage = xPresentationPage->getNotesPage();
416     }
417     catch (RuntimeException&)
418     {
419     }
420 
421     SetSlide(mxCurrentNotesPage);
422 }
423 
424 
425 
426 
427 Reference<drawing::XDrawPage> SAL_CALL PresenterNotesView::getCurrentPage (void)
428     throw (RuntimeException)
429 {
430     return NULL;
431 }
432 
433 
434 
435 
436 //----- XKeyListener ----------------------------------------------------------
437 
438 void SAL_CALL PresenterNotesView::keyPressed (const awt::KeyEvent& rEvent)
439     throw (RuntimeException)
440 {
441     switch (rEvent.KeyCode)
442     {
443         case awt::Key::A:
444             Scroll(-gnLineScrollFactor * mpFont->mnSize);
445             break;
446 
447         case awt::Key::Y:
448         case awt::Key::Z:
449             Scroll(+gnLineScrollFactor * mpFont->mnSize);
450             break;
451 
452         case awt::Key::S:
453             ChangeFontSize(-1);
454             break;
455 
456         case awt::Key::G:
457             ChangeFontSize(+1);
458             break;
459 
460         case awt::Key::H:
461             if (mpTextView)
462                 mpTextView->MoveCaret(
463                     -1,
464                     (rEvent.Modifiers == awt::KeyModifier::SHIFT)
465                         ? cssa::AccessibleTextType::CHARACTER
466                         : cssa::AccessibleTextType::WORD);
467             break;
468 
469         case awt::Key::L:
470             if (mpTextView)
471                 mpTextView->MoveCaret(
472                     +1,
473                     (rEvent.Modifiers == awt::KeyModifier::SHIFT)
474                         ? cssa::AccessibleTextType::CHARACTER
475                         : cssa::AccessibleTextType::WORD);
476             break;
477     }
478 }
479 
480 
481 
482 
483 void SAL_CALL PresenterNotesView::keyReleased (const awt::KeyEvent& rEvent)
484     throw (RuntimeException)
485 {
486     (void)rEvent;
487 }
488 
489 
490 
491 
492 //-----------------------------------------------------------------------------
493 
494 void PresenterNotesView::Layout (void)
495 {
496     if ( ! mxParentWindow.is())
497         return;
498 
499     awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
500     geometry::RealRectangle2D aNewTextBoundingBox (0,0,aWindowBox.Width, aWindowBox.Height);
501 
502     // Size the tool bar and the horizontal separator above it.
503     if (mxToolBarWindow.is())
504     {
505         const geometry::RealSize2D aToolBarSize (mpToolBar->GetMinimalSize());
506         const sal_Int32 nToolBarHeight = sal_Int32(aToolBarSize.Height + 0.5);
507         mxToolBarWindow->setPosSize(0, aWindowBox.Height - nToolBarHeight,
508             sal_Int32(aToolBarSize.Width + 0.5), nToolBarHeight,
509             awt::PosSize::POSSIZE);
510         aNewTextBoundingBox.Y2 -= nToolBarHeight;
511 
512         mnSeparatorYLocation = aWindowBox.Height - nToolBarHeight - gnSpaceBelowSeparator;
513         aNewTextBoundingBox.Y2 = mnSeparatorYLocation - gnSpaceAboveSeparator;
514 
515         // Place the close button.
516         if (mpCloseButton.get() != NULL)
517             mpCloseButton->SetCenter(geometry::RealPoint2D(
518                 (aWindowBox.Width +  aToolBarSize.Width) / 2,
519                 aWindowBox.Height - aToolBarSize.Height/2));
520     }
521 
522     // Check whether the vertical scroll bar is necessary.
523     if (mpScrollBar.get() != NULL)
524     {
525         bool bShowVerticalScrollbar (false);
526         try
527         {
528             const double nTextBoxHeight (aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1);
529             const double nHeight (mpTextView->GetTotalTextHeight());
530             if (nHeight > nTextBoxHeight)
531             {
532                 bShowVerticalScrollbar = true;
533                 aNewTextBoundingBox.X2 -= mpScrollBar->GetSize();
534             }
535             mpScrollBar->SetTotalSize(nHeight);
536         }
537         catch(beans::UnknownPropertyException&)
538         {
539             OSL_ASSERT(false);
540         }
541 
542         mpScrollBar->SetVisible(bShowVerticalScrollbar);
543         mpScrollBar->SetPosSize(
544             geometry::RealRectangle2D(
545                 aNewTextBoundingBox.X2,
546                 aNewTextBoundingBox.X1,
547                 aNewTextBoundingBox.X2 + mpScrollBar->GetSize(),
548                 aNewTextBoundingBox.Y2));
549         if ( ! bShowVerticalScrollbar)
550             mpScrollBar->SetThumbPosition(0, false);
551 
552         UpdateScrollBar();
553     }
554 
555     // Has the text area has changed it position or size?
556     if (aNewTextBoundingBox.X1 != maTextBoundingBox.X1
557         || aNewTextBoundingBox.Y1 != maTextBoundingBox.Y1
558         || aNewTextBoundingBox.X2 != maTextBoundingBox.X2
559         || aNewTextBoundingBox.Y2 != maTextBoundingBox.Y2)
560     {
561         maTextBoundingBox = aNewTextBoundingBox;
562 
563         mpTextView->SetLocation(
564             geometry::RealPoint2D(
565                 aNewTextBoundingBox.X1,
566                 aNewTextBoundingBox.Y1));
567         mpTextView->SetSize(
568             geometry::RealSize2D(
569                 aNewTextBoundingBox.X2 - aNewTextBoundingBox.X1,
570                 aNewTextBoundingBox.Y2 - aNewTextBoundingBox.Y1));
571     }
572 }
573 
574 
575 
576 
577 void PresenterNotesView::Paint (const awt::Rectangle& rUpdateBox)
578 {
579     if ( ! mxParentWindow.is())
580         return;
581     if ( ! mxCanvas.is())
582         return;
583 
584     if (mpBackground.get() == NULL)
585         mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
586 
587     if (rUpdateBox.Y < maTextBoundingBox.Y2
588         && rUpdateBox.X < maTextBoundingBox.X2)
589     {
590         PaintText(rUpdateBox);
591     }
592 
593     mpTextView->Paint(rUpdateBox);
594 
595     if (rUpdateBox.Y + rUpdateBox.Height > maTextBoundingBox.Y2)
596     {
597         PaintToolBar(rUpdateBox);
598     }
599 }
600 
601 
602 
603 
604 void PresenterNotesView::PaintToolBar (const awt::Rectangle& rUpdateBox)
605 {
606     awt::Rectangle aWindowBox (mxParentWindow->getPosSize());
607 
608     rendering::ViewState aViewState (
609         geometry::AffineMatrix2D(1,0,0, 0,1,0),
610         NULL);
611     rendering::RenderState aRenderState(
612         geometry::AffineMatrix2D(1,0,0, 0,1,0),
613         NULL,
614         Sequence<double>(4),
615         rendering::CompositeOperation::SOURCE);
616 
617     if (mpBackground.get() != NULL)
618     {
619         // Paint the background.
620         mpPresenterController->GetCanvasHelper()->Paint(
621             mpBackground,
622             mxCanvas,
623             rUpdateBox,
624             awt::Rectangle(0,sal_Int32(maTextBoundingBox.Y2),aWindowBox.Width,aWindowBox.Height),
625             awt::Rectangle());
626     }
627 
628     // Paint the horizontal separator.
629     OSL_ASSERT(mxViewId.is());
630     PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
631 
632     mxCanvas->drawLine(
633         geometry::RealPoint2D(0,mnSeparatorYLocation),
634         geometry::RealPoint2D(aWindowBox.Width,mnSeparatorYLocation),
635         aViewState,
636         aRenderState);
637 }
638 
639 
640 
641 
642 void PresenterNotesView::PaintText (const awt::Rectangle& rUpdateBox)
643 {
644     const awt::Rectangle aBox (PresenterGeometryHelper::Intersection(rUpdateBox,
645             PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox)));
646 
647     if (aBox.Width <= 0 || aBox.Height <= 0)
648         return;
649 
650     rendering::ViewState aViewState (
651         geometry::AffineMatrix2D(1,0,0, 0,1,0),
652         PresenterGeometryHelper::CreatePolygon(aBox, mxCanvas->getDevice()));
653     rendering::RenderState aRenderState(
654         geometry::AffineMatrix2D(1,0,0, 0,1,0),
655         NULL,
656         Sequence<double>(3),
657         rendering::CompositeOperation::SOURCE);
658 
659     if (mpBackground.get() != NULL)
660     {
661         // Paint the background.
662         mpPresenterController->GetCanvasHelper()->Paint(
663             mpBackground,
664             mxCanvas,
665             rUpdateBox,
666             aBox,
667             awt::Rectangle());
668     }
669 
670     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
671     if (xSpriteCanvas.is())
672         xSpriteCanvas->updateScreen(sal_False);
673 }
674 
675 
676 
677 
678 void PresenterNotesView::Invalidate (void)
679 {
680     mpPresenterController->GetPaintManager()->Invalidate(
681         mxParentWindow,
682         PresenterGeometryHelper::ConvertRectangle(maTextBoundingBox));
683 }
684 
685 
686 
687 
688 void PresenterNotesView::Scroll (const double rnDistance)
689 {
690     try
691     {
692         mnTop += rnDistance;
693         mpTextView->SetOffset(0, mnTop);
694 
695         UpdateScrollBar();
696         Invalidate();
697     }
698     catch (beans::UnknownPropertyException&)
699     {}
700 }
701 
702 
703 
704 
705 void PresenterNotesView::SetTop (const double nTop)
706 {
707     try
708     {
709         mnTop = nTop;
710         mpTextView->SetOffset(0, mnTop);
711 
712         UpdateScrollBar();
713         Invalidate();
714     }
715     catch (beans::UnknownPropertyException&)
716     {}
717 }
718 
719 
720 
721 
722 void PresenterNotesView::ChangeFontSize (const sal_Int32 nSizeChange)
723 {
724     const sal_Int32 nNewSize (mpFont->mnSize + nSizeChange);
725     if (nNewSize > 5)
726     {
727         mpFont->mnSize = nNewSize;
728         mpFont->mxFont = NULL;
729         mpTextView->SetFont(mpFont);
730 
731         Layout();
732         UpdateScrollBar();
733         Invalidate();
734 
735         // Write the new font size to the configuration to make it persistent.
736         try
737         {
738             const OUString sStyleName (mpPresenterController->GetTheme()->GetStyleName(
739                 mxViewId->getResourceURL()));
740             ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration (
741                 mpPresenterController->GetTheme()->GetNodeForViewStyle(
742                     sStyleName,
743                     PresenterConfigurationAccess::READ_WRITE));
744             if (pConfiguration.get()==NULL || ! pConfiguration->IsValid())
745                 return;
746 
747             pConfiguration->GoToChild(A2S("Font"));
748             pConfiguration->SetProperty(A2S("Size"), Any((sal_Int32)(nNewSize+0.5)));
749             pConfiguration->CommitChanges();
750         }
751         catch (Exception&)
752         {
753             OSL_ASSERT(false);
754         }
755     }
756 }
757 
758 
759 
760 
761 ::boost::shared_ptr<PresenterTextView> PresenterNotesView::GetTextView (void) const
762 {
763     return mpTextView;
764 }
765 
766 
767 
768 
769 void PresenterNotesView::UpdateScrollBar (void)
770 {
771     if (mpScrollBar.get() != NULL)
772     {
773         try
774         {
775             mpScrollBar->SetTotalSize(mpTextView->GetTotalTextHeight());
776         }
777         catch(beans::UnknownPropertyException&)
778         {
779             OSL_ASSERT(false);
780         }
781 
782         mpScrollBar->SetLineHeight(mpFont->mnSize*1.2);
783         mpScrollBar->SetThumbPosition(mnTop, false);
784 
785         mpScrollBar->SetThumbSize(maTextBoundingBox.Y2 - maTextBoundingBox.Y1);
786         mpScrollBar->CheckValues();
787     }
788 }
789 
790 
791 
792 
793 void PresenterNotesView::ThrowIfDisposed (void)
794     throw (::com::sun::star::lang::DisposedException)
795 {
796 	if (rBHelper.bDisposed || rBHelper.bInDispose)
797 	{
798         throw lang::DisposedException (
799             A2S("PresenterNotesView object has already been disposed"),
800             static_cast<uno::XWeak*>(this));
801     }
802 }
803 
804 
805 
806 
807 } } // end of namespace ::sdext::presenter
808