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 #include "precompiled_sd.hxx"
25 
26 #include "SlideSorter.hxx"
27 
28 #include "SlideSorterChildWindow.hrc"
29 #include "SlideSorterViewShell.hxx"
30 #include "controller/SlideSorterController.hxx"
31 #include "controller/SlsScrollBarManager.hxx"
32 #include "controller/SlsProperties.hxx"
33 #include "controller/SlsAnimator.hxx"
34 #include "view/SlideSorterView.hxx"
35 #include "view/SlsTheme.hxx"
36 #include "model/SlideSorterModel.hxx"
37 
38 #include "glob.hrc"
39 #include "DrawController.hxx"
40 #include "ViewShellBase.hxx"
41 #include "ViewShellManager.hxx"
42 #include "Window.hxx"
43 
44 #include <vcl/scrbar.hxx>
45 #include <vcl/svapp.hxx>
46 
47 #include <sfx2/dispatch.hxx>
48 #include "sdresid.hxx"
49 
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star;
52 
53 
54 namespace sd { namespace slidesorter {
55 
56 namespace {
57 class ContentWindow : public ::sd::Window
58 {
59 public:
60     ContentWindow(::Window& rParent, SlideSorter& rSlideSorter);
61     ~ContentWindow (void);
62     void SetCurrentFunction (const FunctionReference& rpFunction);
63     virtual void Paint(const Rectangle& rRect);
64 	virtual void KeyInput (const KeyEvent& rEvent);
65 	virtual void MouseMove (const MouseEvent& rEvent);
66 	virtual void MouseButtonUp (const MouseEvent& rEvent);
67 	virtual void MouseButtonDown (const MouseEvent& rEvent);
68 	virtual void Command (const CommandEvent& rEvent);
69     virtual long Notify (NotifyEvent& rEvent);
70 
71 private:
72     SlideSorter& mrSlideSorter;
73     FunctionReference mpCurrentFunction;
74 };
75 }
76 
77 
78 
79 
80 //===== SlideSorter ===========================================================
81 
CreateSlideSorter(ViewShell & rViewShell,const::boost::shared_ptr<sd::Window> & rpContentWindow,const::boost::shared_ptr<ScrollBar> & rpHorizontalScrollBar,const::boost::shared_ptr<ScrollBar> & rpVerticalScrollBar,const::boost::shared_ptr<ScrollBarBox> & rpScrollBarBox)82 ::boost::shared_ptr<SlideSorter> SlideSorter::CreateSlideSorter(
83     ViewShell& rViewShell,
84     const ::boost::shared_ptr<sd::Window>& rpContentWindow,
85 	const ::boost::shared_ptr<ScrollBar>& rpHorizontalScrollBar,
86 	const ::boost::shared_ptr<ScrollBar>& rpVerticalScrollBar,
87     const ::boost::shared_ptr<ScrollBarBox>& rpScrollBarBox)
88 {
89     ::boost::shared_ptr<SlideSorter> pSlideSorter(
90         new SlideSorter(
91             rViewShell,
92             rpContentWindow,
93             rpHorizontalScrollBar,
94             rpVerticalScrollBar,
95             rpScrollBarBox));
96     pSlideSorter->Init();
97     return pSlideSorter;
98 }
99 
100 
101 
102 
CreateSlideSorter(ViewShellBase & rBase,ViewShell * pViewShell,::Window & rParentWindow)103 ::boost::shared_ptr<SlideSorter> SlideSorter::CreateSlideSorter (
104     ViewShellBase& rBase,
105     ViewShell* pViewShell,
106     ::Window& rParentWindow)
107 {
108     ::boost::shared_ptr<SlideSorter> pSlideSorter(
109         new SlideSorter(
110             rBase,
111             pViewShell,
112             rParentWindow));
113     pSlideSorter->Init();
114     return pSlideSorter;
115 }
116 
117 
118 
119 
SlideSorter(ViewShell & rViewShell,const::boost::shared_ptr<sd::Window> & rpContentWindow,const::boost::shared_ptr<ScrollBar> & rpHorizontalScrollBar,const::boost::shared_ptr<ScrollBar> & rpVerticalScrollBar,const::boost::shared_ptr<ScrollBarBox> & rpScrollBarBox)120 SlideSorter::SlideSorter (
121     ViewShell& rViewShell,
122 	const ::boost::shared_ptr<sd::Window>& rpContentWindow,
123 	const ::boost::shared_ptr<ScrollBar>& rpHorizontalScrollBar,
124 	const ::boost::shared_ptr<ScrollBar>& rpVerticalScrollBar,
125     const ::boost::shared_ptr<ScrollBarBox>& rpScrollBarBox)
126     : mbIsValid(false),
127       mpSlideSorterController(),
128       mpSlideSorterModel(),
129       mpSlideSorterView(),
130       mxControllerWeak(),
131       mpViewShell(&rViewShell),
132       mpViewShellBase(&rViewShell.GetViewShellBase()),
133       mpContentWindow(rpContentWindow),
134       mbOwnesContentWindow(false),
135       mpHorizontalScrollBar(rpHorizontalScrollBar),
136       mpVerticalScrollBar(rpVerticalScrollBar),
137       mpScrollBarBox(rpScrollBarBox),
138       mbLayoutPending(true),
139       mpProperties(new controller::Properties()),
140       mpTheme(new view::Theme(mpProperties))
141 {
142 }
143 
144 
145 
146 
SlideSorter(ViewShellBase & rBase,ViewShell * pViewShell,::Window & rParentWindow)147 SlideSorter::SlideSorter (
148     ViewShellBase& rBase,
149     ViewShell* pViewShell,
150     ::Window& rParentWindow)
151     : mbIsValid(false),
152       mpSlideSorterController(),
153       mpSlideSorterModel(),
154       mpSlideSorterView(),
155       mxControllerWeak(),
156       mpViewShell(pViewShell),
157       mpViewShellBase(&rBase),
158       mpContentWindow(new ContentWindow(rParentWindow,*this )),
159       mbOwnesContentWindow(true),
160       mpHorizontalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_HSCROLL | WB_DRAG))),
161       mpVerticalScrollBar(new ScrollBar(&rParentWindow,WinBits(WB_VSCROLL | WB_DRAG))),
162       mpScrollBarBox(new ScrollBarBox(&rParentWindow)),
163       mbLayoutPending(true),
164       mpProperties(new controller::Properties()),
165       mpTheme(new view::Theme(mpProperties))
166 {
167 }
168 
169 
170 
171 
Init(void)172 void SlideSorter::Init (void)
173 {
174     if (mpViewShellBase != NULL)
175         mxControllerWeak = mpViewShellBase->GetController();
176 
177     // Reinitialize colors in Properties with window specific values.
178     if (mpContentWindow)
179     {
180         mpProperties->SetBackgroundColor(
181             mpContentWindow->GetSettings().GetStyleSettings().GetWindowColor());
182         mpProperties->SetTextColor(
183             mpContentWindow->GetSettings().GetStyleSettings().GetWindowTextColor());
184         mpProperties->SetSelectionColor(
185             mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
186         mpProperties->SetHighlightColor(
187             mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
188     }
189 
190     CreateModelViewController ();
191 
192     SetupListeners ();
193 
194     // Initialize the window.
195     SharedSdWindow pContentWindow (GetContentWindow());
196     if (pContentWindow)
197     {
198         ::Window* pParentWindow = pContentWindow->GetParent();
199         if (pParentWindow != NULL)
200             pParentWindow->SetBackground(Wallpaper());
201         pContentWindow->SetBackground(Wallpaper());
202         pContentWindow->SetViewOrigin (Point(0,0));
203         // We do our own scrolling while dragging a page selection.
204         pContentWindow->SetUseDropScroll (false);
205         // Change the winbits so that the active window accepts the focus.
206         pContentWindow->SetStyle ((pContentWindow->GetStyle() & ~WB_DIALOGCONTROL) | WB_TABSTOP);
207         pContentWindow->Hide();
208 
209         // Set view pointer of base class.
210         SetupControls(pParentWindow);
211 
212         mbIsValid = true;
213     }
214 }
215 
216 
217 
218 
~SlideSorter(void)219 SlideSorter::~SlideSorter (void)
220 {
221     mbIsValid = false;
222 
223     ReleaseListeners();
224 
225     // Dispose model, view and controller to avoid calls between them when
226     // they are being destructed and one or two of them are already gone.
227     mpSlideSorterController->Dispose();
228     mpSlideSorterView->Dispose();
229     mpSlideSorterModel->Dispose();
230 
231     // Reset the auto pointers explicitly to control the order of destruction.
232     mpSlideSorterController.reset();
233     mpSlideSorterView.reset();
234     mpSlideSorterModel.reset();
235 
236     mpHorizontalScrollBar.reset();
237     mpVerticalScrollBar.reset();
238     mpScrollBarBox.reset();
239 
240     if (mbOwnesContentWindow)
241     {
242         OSL_ASSERT(mpContentWindow.unique());
243     }
244     else
245     {
246         // Assume that outside this class only the owner holds a reference
247         // to the content window.
248         OSL_ASSERT(mpContentWindow.use_count()==2);
249     }
250     mpContentWindow.reset();
251 }
252 
253 
254 
255 
IsValid(void) const256 bool SlideSorter::IsValid (void) const
257 {
258     return mbIsValid;
259 }
260 
261 
262 
263 
GetVerticalScrollBar(void) const264 ::boost::shared_ptr<ScrollBar> SlideSorter::GetVerticalScrollBar (void) const
265 {
266     return mpVerticalScrollBar;
267 }
268 
269 
270 
271 
272 
GetHorizontalScrollBar(void) const273 ::boost::shared_ptr<ScrollBar> SlideSorter::GetHorizontalScrollBar (void) const
274 {
275     return mpHorizontalScrollBar;
276 }
277 
278 
279 
280 
GetScrollBarFiller(void) const281 ::boost::shared_ptr<ScrollBarBox> SlideSorter::GetScrollBarFiller (void) const
282 {
283     return mpScrollBarBox;
284 }
285 
286 
287 
288 
GetModel(void) const289 model::SlideSorterModel& SlideSorter::GetModel (void) const
290 {
291     OSL_ASSERT(mpSlideSorterModel.get()!=NULL);
292     return *mpSlideSorterModel;
293 }
294 
295 
296 
297 
GetView(void) const298 view::SlideSorterView& SlideSorter::GetView (void) const
299 {
300     OSL_ASSERT(mpSlideSorterView.get()!=NULL);
301     return *mpSlideSorterView;
302 }
303 
304 
305 
306 
GetController(void) const307 controller::SlideSorterController& SlideSorter::GetController (void) const
308 {
309     OSL_ASSERT(mpSlideSorterController.get()!=NULL);
310     return *mpSlideSorterController;
311 }
312 
313 
314 
315 
GetXController(void) const316 Reference<frame::XController> SlideSorter::GetXController (void) const
317 {
318     Reference<frame::XController> xController(mxControllerWeak);
319     return xController;
320 }
321 
322 
323 
324 
Paint(const Rectangle & rRepaintArea)325 void SlideSorter::Paint (const Rectangle& rRepaintArea)
326 {
327     GetController().Paint(
328         rRepaintArea,
329         GetContentWindow().get());
330 }
331 
332 
333 
334 
GetContentWindow(void) const335 ::SharedSdWindow SlideSorter::GetContentWindow (void) const
336 {
337     return mpContentWindow;
338 }
339 
340 
341 
342 
GetViewShellBase(void) const343 ViewShellBase* SlideSorter::GetViewShellBase (void) const
344 {
345     return mpViewShellBase;
346 }
347 
348 
349 
350 
GetViewShell(void) const351 ViewShell* SlideSorter::GetViewShell (void) const
352 {
353     return mpViewShell;
354 }
355 
356 
357 
358 
SetupControls(::Window *)359 void SlideSorter::SetupControls (::Window* )
360 {
361     GetVerticalScrollBar()->Show();
362     mpSlideSorterController->GetScrollBarManager().LateInitialization();
363 }
364 
365 
366 
367 
SetupListeners(void)368 void SlideSorter::SetupListeners (void)
369 {
370     SharedSdWindow pWindow (GetContentWindow());
371     if (pWindow)
372     {
373         ::Window* pParentWindow = pWindow->GetParent();
374         if (pParentWindow != NULL)
375             pParentWindow->AddEventListener(
376                 LINK(
377                     mpSlideSorterController.get(),
378                     controller::SlideSorterController,
379                     WindowEventHandler));
380         pWindow->AddEventListener(
381             LINK(
382                 mpSlideSorterController.get(),
383                 controller::SlideSorterController,
384                 WindowEventHandler));
385     }
386     Application::AddEventListener(
387         LINK(
388             mpSlideSorterController.get(),
389             controller::SlideSorterController,
390             WindowEventHandler));
391 
392     mpSlideSorterController->GetScrollBarManager().Connect();
393 }
394 
395 
396 
397 
ReleaseListeners(void)398 void SlideSorter::ReleaseListeners (void)
399 {
400     mpSlideSorterController->GetScrollBarManager().Disconnect();
401 
402     SharedSdWindow pWindow (GetContentWindow());
403     if (pWindow)
404     {
405         pWindow->RemoveEventListener(
406             LINK(mpSlideSorterController.get(),
407                 controller::SlideSorterController,
408                 WindowEventHandler));
409 
410         ::Window* pParentWindow = pWindow->GetParent();
411         if (pParentWindow != NULL)
412             pParentWindow->RemoveEventListener(
413                 LINK(mpSlideSorterController.get(),
414                     controller::SlideSorterController,
415                     WindowEventHandler));
416     }
417     Application::RemoveEventListener(
418         LINK(mpSlideSorterController.get(),
419             controller::SlideSorterController,
420             WindowEventHandler));
421 }
422 
423 
424 
425 
CreateModelViewController(void)426 void SlideSorter::CreateModelViewController (void)
427 {
428     mpSlideSorterModel.reset(CreateModel());
429     DBG_ASSERT (mpSlideSorterModel.get()!=NULL,
430         "Can not create model for slide browser");
431 
432     mpSlideSorterView.reset(CreateView());
433     DBG_ASSERT (mpSlideSorterView.get()!=NULL,
434         "Can not create view for slide browser");
435 
436     mpSlideSorterController.reset(CreateController());
437     DBG_ASSERT (mpSlideSorterController.get()!=NULL,
438         "Can not create controller for slide browser");
439 
440     // Now that model, view, and controller are constructed, do the
441     // initialization that relies on all three being in place.
442     mpSlideSorterModel->Init();
443     mpSlideSorterController->Init();
444     mpSlideSorterView->Init();
445 }
446 
447 
448 
449 
CreateModel(void)450 model::SlideSorterModel* SlideSorter::CreateModel (void)
451 {
452     // Get pointers to the document.
453     ViewShellBase* pViewShellBase = GetViewShellBase();
454     if (pViewShellBase != NULL)
455     {
456         OSL_ASSERT (pViewShellBase->GetDocument() != NULL);
457 
458         return new model::SlideSorterModel(*this);
459     }
460     else
461         return NULL;
462 }
463 
464 
465 
466 
CreateView(void)467 view::SlideSorterView* SlideSorter::CreateView (void)
468 {
469     return new view::SlideSorterView (*this);
470 }
471 
472 
473 
474 
CreateController(void)475 controller::SlideSorterController* SlideSorter::CreateController (void)
476 {
477     controller::SlideSorterController* pController
478         = new controller::SlideSorterController (*this);
479     return pController;
480 }
481 
482 
483 
484 
ArrangeGUIElements(const Point & rOffset,const Size & rSize)485 void SlideSorter::ArrangeGUIElements (
486     const Point& rOffset,
487     const Size& rSize)
488 {
489     Point aOrigin (rOffset);
490 
491     if (rSize.Width()>0
492         && rSize.Height()>0
493         && GetContentWindow()
494         && GetContentWindow()->IsVisible())
495     {
496         // Prevent untimely redraws while the view is not yet correctly
497         // resized.
498         view::SlideSorterView::DrawLock aLock (*this);
499         GetContentWindow()->EnablePaint (sal_False);
500 
501         mpSlideSorterController->Resize (Rectangle(aOrigin, rSize));
502 
503         GetContentWindow()->EnablePaint (sal_True);
504 
505         mbLayoutPending = false;
506     }
507 }
508 
509 
510 
511 
GetBorder(void)512 SvBorder SlideSorter::GetBorder (void)
513 {
514     SvBorder aBorder;
515 
516     ::boost::shared_ptr<ScrollBar> pScrollBar = GetVerticalScrollBar();
517     if (pScrollBar.get() != NULL && pScrollBar->IsVisible())
518         aBorder.Right() = pScrollBar->GetOutputSizePixel().Width();
519 
520     pScrollBar = GetHorizontalScrollBar();
521     if (pScrollBar.get() != NULL && pScrollBar->IsVisible())
522         aBorder.Bottom() = pScrollBar->GetOutputSizePixel().Height();
523 
524     return aBorder;
525 }
526 
527 
528 
529 
RelocateToWindow(::Window * pParentWindow)530 bool SlideSorter::RelocateToWindow (::Window* pParentWindow)
531 {
532    // Stop all animations for they have been started for the old window.
533     mpSlideSorterController->GetAnimator()->RemoveAllAnimations();
534 
535     ReleaseListeners();
536 
537     if (mpViewShell != NULL)
538         mpViewShell->ViewShell::RelocateToParentWindow(pParentWindow);
539 
540     SetupControls(mpViewShell->GetParentWindow());
541     SetupListeners();
542 
543     // For accessibility we have to shortly hide the content window.  This
544     // triggers the construction of a new accessibility object for the new
545     // view shell.  (One is created earlier while the construtor of the base
546     // class is executed.  But because at that time the correct
547     // accessibility object can not be constructed we do that now.)
548     if (mpContentWindow.get() !=NULL)
549     {
550         mpContentWindow->Hide();
551         mpContentWindow->Show();
552     }
553 
554     return true;
555 }
556 
557 
558 
559 
SetCurrentFunction(const FunctionReference & rpFunction)560 void SlideSorter::SetCurrentFunction (const FunctionReference& rpFunction)
561 {
562     if (GetViewShell() != NULL)
563     {
564         GetViewShell()->SetCurrentFunction(rpFunction);
565         GetViewShell()->SetOldFunction(rpFunction);
566     }
567     else
568     {
569         ContentWindow* pWindow = dynamic_cast<ContentWindow*>(GetContentWindow().get());
570         if (pWindow != NULL)
571             pWindow->SetCurrentFunction(rpFunction);
572     }
573 }
574 
575 
576 
577 
GetProperties(void) const578 ::boost::shared_ptr<controller::Properties> SlideSorter::GetProperties (void) const
579 {
580     OSL_ASSERT(mpProperties);
581     return mpProperties;
582 }
583 
584 
585 
586 
GetTheme(void) const587 ::boost::shared_ptr<view::Theme> SlideSorter::GetTheme (void) const
588 {
589     OSL_ASSERT(mpTheme);
590     return mpTheme;
591 }
592 
593 
594 
595 
596 //===== ContentWindow =========================================================
597 
598 namespace {
599 
ContentWindow(::Window & rParent,SlideSorter & rSlideSorter)600 ContentWindow::ContentWindow(
601     ::Window& rParent,
602     SlideSorter& rSlideSorter)
603     : ::sd::Window(&rParent),
604     mrSlideSorter(rSlideSorter),
605     mpCurrentFunction()
606 {
607     SetDialogControlFlags(GetDialogControlFlags() & ~WINDOW_DLGCTRL_WANTFOCUS);
608     SetStyle(GetStyle() | WB_NOPOINTERFOCUS);
609 }
610 
611 
612 
613 
~ContentWindow(void)614 ContentWindow::~ContentWindow (void)
615 {
616 }
617 
618 
619 
620 
SetCurrentFunction(const FunctionReference & rpFunction)621 void ContentWindow::SetCurrentFunction (const FunctionReference& rpFunction)
622 {
623     mpCurrentFunction = rpFunction;
624 }
625 
626 
627 
628 
Paint(const Rectangle & rRect)629 void ContentWindow::Paint (const Rectangle& rRect)
630 {
631     mrSlideSorter.Paint(rRect);
632 }
633 
634 
635 
636 
KeyInput(const KeyEvent & rEvent)637 void ContentWindow::KeyInput (const KeyEvent& rEvent)
638 {
639     if (mpCurrentFunction.is())
640         mpCurrentFunction->KeyInput(rEvent);
641 }
642 
643 
644 
645 
MouseMove(const MouseEvent & rEvent)646 void ContentWindow::MouseMove (const MouseEvent& rEvent)
647 {
648     if (mpCurrentFunction.is())
649         mpCurrentFunction->MouseMove(rEvent);
650 }
651 
652 
653 
654 
MouseButtonUp(const MouseEvent & rEvent)655 void ContentWindow::MouseButtonUp(const MouseEvent& rEvent)
656 {
657     if (mpCurrentFunction.is())
658         mpCurrentFunction->MouseButtonUp(rEvent);
659 }
660 
661 
662 
663 
MouseButtonDown(const MouseEvent & rEvent)664 void ContentWindow::MouseButtonDown(const MouseEvent& rEvent)
665 {
666     if (mpCurrentFunction.is())
667         mpCurrentFunction->MouseButtonDown(rEvent);
668 }
669 
670 
671 
672 
Command(const CommandEvent & rEvent)673 void ContentWindow::Command(const CommandEvent& rEvent)
674 {
675     if (mpCurrentFunction.is())
676         mpCurrentFunction->Command(rEvent);
677 }
678 
679 
680 
681 
Notify(NotifyEvent & rEvent)682 long ContentWindow::Notify (NotifyEvent& rEvent)
683 {
684     (void)rEvent;
685     return 0;
686 }
687 
688 
689 
690 } // end of anonymous namespace
691 
692 
693 
694 
695 
696 } } // end of namespace ::sd::slidesorter
697