Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "SlideSorter.hxx"
21 :
22 : #include "SlideSorterViewShell.hxx"
23 : #include "controller/SlideSorterController.hxx"
24 : #include "controller/SlsScrollBarManager.hxx"
25 : #include "controller/SlsProperties.hxx"
26 : #include "controller/SlsAnimator.hxx"
27 : #include "view/SlideSorterView.hxx"
28 : #include "view/SlsTheme.hxx"
29 : #include "model/SlideSorterModel.hxx"
30 :
31 : #include "glob.hrc"
32 : #include "DrawController.hxx"
33 : #include "ViewShellBase.hxx"
34 : #include "ViewShellManager.hxx"
35 : #include "Window.hxx"
36 :
37 : #include <vcl/scrbar.hxx>
38 : #include <vcl/svapp.hxx>
39 : #include <vcl/settings.hxx>
40 :
41 : #include <sfx2/dispatch.hxx>
42 : #include "sdresid.hxx"
43 :
44 : using namespace ::com::sun::star::uno;
45 : using namespace ::com::sun::star;
46 :
47 : namespace sd { namespace slidesorter {
48 :
49 : namespace {
50 : class ContentWindow : public ::sd::Window
51 : {
52 : public:
53 : ContentWindow(vcl::Window& rParent, SlideSorter& rSlideSorter);
54 : virtual ~ContentWindow();
55 : void SetCurrentFunction (const rtl::Reference<FuPoor>& rpFunction);
56 : virtual void Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle& rRect) SAL_OVERRIDE;
57 : virtual void KeyInput (const KeyEvent& rEvent) SAL_OVERRIDE;
58 : virtual void MouseMove (const MouseEvent& rEvent) SAL_OVERRIDE;
59 : virtual void MouseButtonUp (const MouseEvent& rEvent) SAL_OVERRIDE;
60 : virtual void MouseButtonDown (const MouseEvent& rEvent) SAL_OVERRIDE;
61 : virtual void Command (const CommandEvent& rEvent) SAL_OVERRIDE;
62 : virtual bool Notify (NotifyEvent& rEvent) SAL_OVERRIDE;
63 :
64 : private:
65 : SlideSorter& mrSlideSorter;
66 : rtl::Reference<FuPoor> mpCurrentFunction;
67 : };
68 : }
69 :
70 : //===== SlideSorter ===========================================================
71 :
72 64 : ::boost::shared_ptr<SlideSorter> SlideSorter::CreateSlideSorter(
73 : ViewShell& rViewShell,
74 : sd::Window* pContentWindow,
75 : ScrollBar* pHorizontalScrollBar,
76 : ScrollBar* pVerticalScrollBar,
77 : ScrollBarBox* pScrollBarBox)
78 : {
79 : ::boost::shared_ptr<SlideSorter> pSlideSorter(
80 : new SlideSorter(
81 : rViewShell,
82 : pContentWindow,
83 : pHorizontalScrollBar,
84 : pVerticalScrollBar,
85 64 : pScrollBarBox));
86 64 : pSlideSorter->Init();
87 64 : return pSlideSorter;
88 : }
89 :
90 0 : ::boost::shared_ptr<SlideSorter> SlideSorter::CreateSlideSorter (
91 : ViewShellBase& rBase,
92 : ViewShell* pViewShell,
93 : vcl::Window& rParentWindow)
94 : {
95 : ::boost::shared_ptr<SlideSorter> pSlideSorter(
96 : new SlideSorter(
97 : rBase,
98 : pViewShell,
99 0 : rParentWindow));
100 0 : pSlideSorter->Init();
101 0 : return pSlideSorter;
102 : }
103 :
104 64 : SlideSorter::SlideSorter (
105 : ViewShell& rViewShell,
106 : sd::Window* pContentWindow,
107 : ScrollBar* pHorizontalScrollBar,
108 : ScrollBar* pVerticalScrollBar,
109 : ScrollBarBox* pScrollBarBox)
110 : : mbIsValid(false),
111 : mpSlideSorterController(),
112 : mpSlideSorterModel(),
113 : mpSlideSorterView(),
114 : mxControllerWeak(),
115 : mpViewShell(&rViewShell),
116 64 : mpViewShellBase(&rViewShell.GetViewShellBase()),
117 : mpContentWindow(pContentWindow),
118 : mbOwnesContentWindow(false),
119 : mpHorizontalScrollBar(pHorizontalScrollBar),
120 : mpVerticalScrollBar(pVerticalScrollBar),
121 : mpScrollBarBox(pScrollBarBox),
122 : mbLayoutPending(true),
123 0 : mpProperties(new controller::Properties()),
124 128 : mpTheme(new view::Theme(mpProperties))
125 : {
126 64 : }
127 :
128 0 : SlideSorter::SlideSorter (
129 : ViewShellBase& rBase,
130 : ViewShell* pViewShell,
131 : vcl::Window& rParentWindow)
132 : : mbIsValid(false),
133 : mpSlideSorterController(),
134 : mpSlideSorterModel(),
135 : mpSlideSorterView(),
136 : mxControllerWeak(),
137 : mpViewShell(pViewShell),
138 : mpViewShellBase(&rBase),
139 : mpContentWindow(VclPtr<ContentWindow>::Create(rParentWindow,*this )),
140 : mbOwnesContentWindow(true),
141 : mpHorizontalScrollBar(VclPtr<ScrollBar>::Create(&rParentWindow,WinBits(WB_HSCROLL | WB_DRAG))),
142 : mpVerticalScrollBar(VclPtr<ScrollBar>::Create(&rParentWindow,WinBits(WB_VSCROLL | WB_DRAG))),
143 : mpScrollBarBox(VclPtr<ScrollBarBox>::Create(&rParentWindow)),
144 : mbLayoutPending(true),
145 0 : mpProperties(new controller::Properties()),
146 0 : mpTheme(new view::Theme(mpProperties))
147 : {
148 0 : }
149 :
150 64 : void SlideSorter::Init()
151 : {
152 64 : if (mpViewShellBase != NULL)
153 64 : mxControllerWeak = mpViewShellBase->GetController();
154 :
155 : // Reinitialize colors in Properties with window specific values.
156 64 : if (mpContentWindow)
157 : {
158 : mpProperties->SetBackgroundColor(
159 64 : mpContentWindow->GetSettings().GetStyleSettings().GetWindowColor());
160 : mpProperties->SetTextColor(
161 64 : mpContentWindow->GetSettings().GetStyleSettings().GetWindowTextColor());
162 : mpProperties->SetSelectionColor(
163 64 : mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
164 : mpProperties->SetHighlightColor(
165 64 : mpContentWindow->GetSettings().GetStyleSettings().GetMenuHighlightColor());
166 : }
167 :
168 64 : CreateModelViewController ();
169 :
170 64 : SetupListeners ();
171 :
172 : // Initialize the window.
173 64 : sd::Window *pContentWindow (GetContentWindow());
174 64 : if (pContentWindow)
175 : {
176 64 : vcl::Window* pParentWindow = pContentWindow->GetParent();
177 64 : if (pParentWindow != NULL)
178 64 : pParentWindow->SetBackground(Wallpaper());
179 64 : pContentWindow->SetBackground(Wallpaper());
180 64 : pContentWindow->SetViewOrigin (Point(0,0));
181 : // We do our own scrolling while dragging a page selection.
182 64 : pContentWindow->SetUseDropScroll (false);
183 : // Change the winbits so that the active window accepts the focus.
184 64 : pContentWindow->SetStyle ((pContentWindow->GetStyle() & ~WB_DIALOGCONTROL) | WB_TABSTOP);
185 64 : pContentWindow->Hide();
186 :
187 : // Set view pointer of base class.
188 64 : SetupControls(pParentWindow);
189 :
190 64 : mbIsValid = true;
191 : }
192 64 : }
193 :
194 192 : SlideSorter::~SlideSorter()
195 : {
196 64 : mbIsValid = false;
197 :
198 64 : ReleaseListeners();
199 :
200 : // Dispose model, view and controller to avoid calls between them when
201 : // they are being destructed and one or two of them are already gone.
202 64 : mpSlideSorterController->Dispose();
203 64 : mpSlideSorterView->Dispose();
204 64 : mpSlideSorterModel->Dispose();
205 :
206 : // Reset the auto pointers explicitly to control the order of destruction.
207 64 : mpSlideSorterController.reset();
208 64 : mpSlideSorterView.reset();
209 64 : mpSlideSorterModel.reset();
210 :
211 64 : mpHorizontalScrollBar.reset();
212 64 : mpVerticalScrollBar.reset();
213 64 : mpScrollBarBox.reset();
214 128 : }
215 :
216 2431 : model::SlideSorterModel& SlideSorter::GetModel() const
217 : {
218 : OSL_ASSERT(mpSlideSorterModel.get()!=NULL);
219 2431 : return *mpSlideSorterModel;
220 : }
221 :
222 3206 : view::SlideSorterView& SlideSorter::GetView() const
223 : {
224 : OSL_ASSERT(mpSlideSorterView.get()!=NULL);
225 3206 : return *mpSlideSorterView;
226 : }
227 :
228 2308 : controller::SlideSorterController& SlideSorter::GetController() const
229 : {
230 : OSL_ASSERT(mpSlideSorterController.get()!=NULL);
231 2308 : return *mpSlideSorterController;
232 : }
233 :
234 200 : Reference<frame::XController> SlideSorter::GetXController() const
235 : {
236 200 : Reference<frame::XController> xController(mxControllerWeak);
237 200 : return xController;
238 : }
239 :
240 0 : void SlideSorter::Paint (const Rectangle& rRepaintArea)
241 : {
242 0 : GetController().Paint(
243 : rRepaintArea,
244 0 : GetContentWindow());
245 0 : }
246 :
247 132 : void SlideSorter::SetupControls (vcl::Window* )
248 : {
249 132 : GetVerticalScrollBar()->Show();
250 132 : }
251 :
252 132 : void SlideSorter::SetupListeners()
253 : {
254 132 : sd::Window *pWindow (GetContentWindow());
255 132 : if (pWindow)
256 : {
257 132 : vcl::Window* pParentWindow = pWindow->GetParent();
258 132 : if (pParentWindow != NULL)
259 : pParentWindow->AddEventListener(
260 132 : LINK(
261 : mpSlideSorterController.get(),
262 : controller::SlideSorterController,
263 132 : WindowEventHandler));
264 : pWindow->AddEventListener(
265 132 : LINK(
266 : mpSlideSorterController.get(),
267 : controller::SlideSorterController,
268 132 : WindowEventHandler));
269 : }
270 : Application::AddEventListener(
271 132 : LINK(
272 : mpSlideSorterController.get(),
273 : controller::SlideSorterController,
274 132 : WindowEventHandler));
275 :
276 132 : mpSlideSorterController->GetScrollBarManager().Connect();
277 132 : }
278 :
279 132 : void SlideSorter::ReleaseListeners()
280 : {
281 132 : mpSlideSorterController->GetScrollBarManager().Disconnect();
282 :
283 132 : sd::Window *pWindow (GetContentWindow());
284 132 : if (pWindow)
285 : {
286 : pWindow->RemoveEventListener(
287 132 : LINK(mpSlideSorterController.get(),
288 : controller::SlideSorterController,
289 132 : WindowEventHandler));
290 :
291 132 : vcl::Window* pParentWindow = pWindow->GetParent();
292 132 : if (pParentWindow != NULL)
293 : pParentWindow->RemoveEventListener(
294 132 : LINK(mpSlideSorterController.get(),
295 : controller::SlideSorterController,
296 132 : WindowEventHandler));
297 : }
298 : Application::RemoveEventListener(
299 132 : LINK(mpSlideSorterController.get(),
300 : controller::SlideSorterController,
301 132 : WindowEventHandler));
302 132 : }
303 :
304 64 : void SlideSorter::CreateModelViewController()
305 : {
306 64 : mpSlideSorterModel.reset(CreateModel());
307 : DBG_ASSERT (mpSlideSorterModel.get()!=NULL,
308 : "Can not create model for slide browser");
309 :
310 64 : mpSlideSorterView.reset(CreateView());
311 : DBG_ASSERT (mpSlideSorterView.get()!=NULL,
312 : "Can not create view for slide browser");
313 :
314 64 : mpSlideSorterController.reset(CreateController());
315 : DBG_ASSERT (mpSlideSorterController.get()!=NULL,
316 : "Can not create controller for slide browser");
317 :
318 : // Now that model, view, and controller are constructed, do the
319 : // initialization that relies on all three being in place.
320 64 : mpSlideSorterController->Init();
321 64 : mpSlideSorterView->Init();
322 64 : }
323 :
324 64 : model::SlideSorterModel* SlideSorter::CreateModel()
325 : {
326 : // Get pointers to the document.
327 64 : ViewShellBase* pViewShellBase = GetViewShellBase();
328 64 : if (pViewShellBase != NULL)
329 : {
330 : OSL_ASSERT (pViewShellBase->GetDocument() != NULL);
331 :
332 64 : return new model::SlideSorterModel(*this);
333 : }
334 : else
335 0 : return NULL;
336 : }
337 :
338 64 : view::SlideSorterView* SlideSorter::CreateView()
339 : {
340 64 : return new view::SlideSorterView (*this);
341 : }
342 :
343 64 : controller::SlideSorterController* SlideSorter::CreateController()
344 : {
345 : controller::SlideSorterController* pController
346 64 : = new controller::SlideSorterController (*this);
347 64 : return pController;
348 : }
349 :
350 131 : void SlideSorter::ArrangeGUIElements (
351 : const Point& rOffset,
352 : const Size& rSize)
353 : {
354 131 : Point aOrigin (rOffset);
355 :
356 456 : if (rSize.Width()>0
357 68 : && rSize.Height()>0
358 267 : && GetContentWindow()
359 461 : && GetContentWindow()->IsVisible())
360 : {
361 : // Prevent untimely redraws while the view is not yet correctly
362 : // resized.
363 68 : view::SlideSorterView::DrawLock aLock (*this);
364 68 : GetContentWindow()->EnablePaint (false);
365 :
366 68 : mpSlideSorterController->Resize (Rectangle(aOrigin, rSize));
367 :
368 68 : GetContentWindow()->EnablePaint (true);
369 :
370 68 : mbLayoutPending = false;
371 : }
372 131 : }
373 :
374 68 : bool SlideSorter::RelocateToWindow (vcl::Window* pParentWindow)
375 : {
376 : // Stop all animations for they have been started for the old window.
377 68 : mpSlideSorterController->GetAnimator()->RemoveAllAnimations();
378 :
379 68 : ReleaseListeners();
380 :
381 68 : vcl::Window *pNewWindow = NULL;
382 68 : if (mpViewShell)
383 : {
384 68 : mpViewShell->ViewShell::RelocateToParentWindow(pParentWindow);
385 68 : pNewWindow = mpViewShell->GetParentWindow();
386 : }
387 : else
388 0 : pNewWindow = NULL;
389 :
390 68 : SetupControls(pNewWindow);
391 68 : SetupListeners();
392 :
393 : // For accessibility we have to shortly hide the content window. This
394 : // triggers the construction of a new accessibility object for the new
395 : // view shell. (One is created earlier while the construtor of the base
396 : // class is executed. But because at that time the correct
397 : // accessibility object can not be constructed we do that now.)
398 68 : if (mpContentWindow.get() !=NULL)
399 : {
400 68 : mpContentWindow->Hide();
401 68 : mpContentWindow->Show();
402 : }
403 :
404 68 : return true;
405 : }
406 :
407 64 : void SlideSorter::SetCurrentFunction (const rtl::Reference<FuPoor>& rpFunction)
408 : {
409 64 : if (GetViewShell() != NULL)
410 : {
411 64 : GetViewShell()->SetCurrentFunction(rpFunction);
412 64 : GetViewShell()->SetOldFunction(rpFunction);
413 : }
414 : else
415 : {
416 0 : ContentWindow* pWindow = dynamic_cast<ContentWindow*>(GetContentWindow().get());
417 0 : if (pWindow != NULL)
418 0 : pWindow->SetCurrentFunction(rpFunction);
419 : }
420 64 : }
421 :
422 128 : ::boost::shared_ptr<controller::Properties> SlideSorter::GetProperties() const
423 : {
424 : OSL_ASSERT(mpProperties);
425 128 : return mpProperties;
426 : }
427 :
428 256 : ::boost::shared_ptr<view::Theme> SlideSorter::GetTheme() const
429 : {
430 : OSL_ASSERT(mpTheme);
431 256 : return mpTheme;
432 : }
433 :
434 : //===== ContentWindow =========================================================
435 :
436 : namespace {
437 :
438 0 : ContentWindow::ContentWindow(
439 : vcl::Window& rParent,
440 : SlideSorter& rSlideSorter)
441 : : ::sd::Window(&rParent),
442 : mrSlideSorter(rSlideSorter),
443 0 : mpCurrentFunction()
444 : {
445 0 : SetDialogControlFlags(GetDialogControlFlags() & ~DialogControlFlags::WantFocus);
446 0 : SetStyle(GetStyle() | WB_NOPOINTERFOCUS);
447 0 : }
448 :
449 0 : ContentWindow::~ContentWindow()
450 : {
451 0 : }
452 :
453 0 : void ContentWindow::SetCurrentFunction (const rtl::Reference<FuPoor>& rpFunction)
454 : {
455 0 : mpCurrentFunction = rpFunction;
456 0 : }
457 :
458 0 : void ContentWindow::Paint (vcl::RenderContext& /*rRenderContext*/, const Rectangle& rRect)
459 : {
460 0 : mrSlideSorter.Paint(rRect);
461 0 : }
462 :
463 0 : void ContentWindow::KeyInput (const KeyEvent& rEvent)
464 : {
465 0 : if (mpCurrentFunction.is())
466 0 : mpCurrentFunction->KeyInput(rEvent);
467 0 : }
468 :
469 0 : void ContentWindow::MouseMove (const MouseEvent& rEvent)
470 : {
471 0 : if (mpCurrentFunction.is())
472 0 : mpCurrentFunction->MouseMove(rEvent);
473 0 : }
474 :
475 0 : void ContentWindow::MouseButtonUp(const MouseEvent& rEvent)
476 : {
477 0 : if (mpCurrentFunction.is())
478 0 : mpCurrentFunction->MouseButtonUp(rEvent);
479 0 : }
480 :
481 0 : void ContentWindow::MouseButtonDown(const MouseEvent& rEvent)
482 : {
483 0 : if (mpCurrentFunction.is())
484 0 : mpCurrentFunction->MouseButtonDown(rEvent);
485 0 : }
486 :
487 0 : void ContentWindow::Command(const CommandEvent& rEvent)
488 : {
489 0 : if (mpCurrentFunction.is())
490 0 : mpCurrentFunction->Command(rEvent);
491 0 : }
492 :
493 0 : bool ContentWindow::Notify (NotifyEvent&)
494 : {
495 0 : return false;
496 : }
497 :
498 : } // end of anonymous namespace
499 :
500 66 : } } // end of namespace ::sd::slidesorter
501 :
502 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|