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