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