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 "Window.hxx"
21 : #include <sfx2/dispatch.hxx>
22 : #include <sfx2/request.hxx>
23 :
24 : #include <sfx2/viewfrm.hxx>
25 : #include <svx/svxids.hrc>
26 :
27 : #include <editeng/outliner.hxx>
28 : #include <editeng/editview.hxx>
29 :
30 : #include "app.hrc"
31 : #include "helpids.h"
32 : #include "ViewShell.hxx"
33 : #include "DrawViewShell.hxx"
34 : #include "View.hxx"
35 : #include "FrameView.hxx"
36 : #include "OutlineViewShell.hxx"
37 : #include "drawdoc.hxx"
38 : #include "AccessibleDrawDocumentView.hxx"
39 : #include "WindowUpdater.hxx"
40 :
41 : #include <vcl/svapp.hxx>
42 : #include <vcl/settings.hxx>
43 : #include <LibreOfficeKit/LibreOfficeKitEnums.h>
44 :
45 : namespace sd {
46 :
47 : #define SCROLL_LINE_FACT 0.05 ///< factor for line scrolling
48 : #define SCROLL_PAGE_FACT 0.5 ///< factor for page scrolling
49 : #define SCROLL_SENSITIVE 20 ///< sensitive area in pixel
50 : #define ZOOM_MULTIPLICATOR 10000 ///< multiplier to avoid rounding errors
51 : #define MIN_ZOOM 5 ///< minimal zoom factor
52 : #define MAX_ZOOM 3000 ///< maximal zoom factor
53 :
54 197 : Window::Window(vcl::Window* pParent)
55 : : vcl::Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
56 : DropTargetHelper( this ),
57 : mpShareWin(NULL),
58 : maWinPos(0, 0), // precautionary; but the values should be set
59 : maViewOrigin(0, 0), // again from the owner of the window
60 : maViewSize(1000, 1000),
61 : maPrevSize(-1,-1),
62 : mnMinZoom(MIN_ZOOM),
63 : mnMaxZoom(MAX_ZOOM),
64 : mbMinZoomAutoCalc(false),
65 : mbCalcMinZoomByMinSide(true),
66 : mbCenterAllowed(true),
67 : mnTicks (0),
68 : mbDraggedFrom(false),
69 : mpViewShell(NULL),
70 197 : mbUseDropScroll (true)
71 : {
72 197 : SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
73 :
74 197 : MapMode aMap(GetMapMode());
75 197 : aMap.SetMapUnit(MAP_100TH_MM);
76 197 : SetMapMode(aMap);
77 :
78 : // whit it, the vcl::WindowColor is used in the slide mode
79 197 : SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetWindowColor() ) );
80 :
81 : // adjust contrast mode initially
82 197 : bool bUseContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
83 : SetDrawMode( bUseContrast
84 : ? sd::OUTPUT_DRAWMODE_CONTRAST
85 197 : : sd::OUTPUT_DRAWMODE_COLOR );
86 :
87 : // set Help ID
88 : // SetHelpId(HID_SD_WIN_DOCUMENT);
89 197 : SetUniqueId(HID_SD_WIN_DOCUMENT);
90 :
91 : // #i78183# Added after discussed with AF
92 197 : EnableRTL(false);
93 197 : }
94 :
95 591 : Window::~Window()
96 : {
97 197 : disposeOnce();
98 394 : }
99 :
100 197 : void Window::dispose()
101 : {
102 197 : if (mpViewShell != NULL)
103 : {
104 0 : WindowUpdater* pWindowUpdater = mpViewShell->GetWindowUpdater();
105 0 : if (pWindowUpdater != NULL)
106 0 : pWindowUpdater->UnregisterWindow (this);
107 : }
108 197 : mpShareWin.clear();
109 197 : vcl::Window::dispose();
110 197 : }
111 :
112 458 : void Window::SetViewShell (ViewShell* pViewSh)
113 : {
114 458 : WindowUpdater* pWindowUpdater = NULL;
115 : // Unregister at device updater of old view shell.
116 458 : if (mpViewShell != NULL)
117 : {
118 261 : pWindowUpdater = mpViewShell->GetWindowUpdater();
119 261 : if (pWindowUpdater != NULL)
120 261 : pWindowUpdater->UnregisterWindow (this);
121 : }
122 :
123 458 : mpViewShell = pViewSh;
124 :
125 : // Register at device updater of new view shell
126 458 : if (mpViewShell != NULL)
127 : {
128 261 : pWindowUpdater = mpViewShell->GetWindowUpdater();
129 261 : if (pWindowUpdater != NULL)
130 261 : pWindowUpdater->RegisterWindow (this);
131 : }
132 458 : }
133 :
134 1253 : void Window::CalcMinZoom()
135 : {
136 : // Are we entitled to change the minimal zoom factor?
137 1253 : if ( mbMinZoomAutoCalc )
138 : {
139 : // Get current zoom factor.
140 0 : long nZoom = GetZoom();
141 :
142 0 : if ( mpShareWin )
143 : {
144 0 : mpShareWin->CalcMinZoom();
145 0 : mnMinZoom = mpShareWin->mnMinZoom;
146 : }
147 : else
148 : {
149 : // Get the rectangle of the output area in logical coordinates
150 : // and calculate the scaling factors that would lead to the view
151 : // area (also called application area) to completely fill the
152 : // window.
153 0 : Size aWinSize = PixelToLogic(GetOutputSizePixel());
154 0 : sal_uLong nX = (sal_uLong) ((double) aWinSize.Width()
155 0 : * (double) ZOOM_MULTIPLICATOR / (double) maViewSize.Width());
156 0 : sal_uLong nY = (sal_uLong) ((double) aWinSize.Height()
157 0 : * (double) ZOOM_MULTIPLICATOR / (double) maViewSize.Height());
158 :
159 : // Decide whether to take the larger or the smaller factor.
160 : sal_uLong nFact;
161 0 : if (mbCalcMinZoomByMinSide)
162 0 : nFact = std::min(nX, nY);
163 : else
164 0 : nFact = std::max(nX, nY);
165 :
166 : // The factor is tansfomed according to the current zoom factor.
167 0 : nFact = nFact * nZoom / ZOOM_MULTIPLICATOR;
168 0 : mnMinZoom = std::max((sal_uInt16) MIN_ZOOM, (sal_uInt16) nFact);
169 : }
170 : // If the current zoom factor is smaller than the calculated minimal
171 : // zoom factor then set the new minimal factor as the current zoom
172 : // factor.
173 0 : if ( nZoom < (long) mnMinZoom )
174 0 : SetZoomFactor(mnMinZoom);
175 : }
176 1253 : }
177 :
178 0 : void Window::SetMinZoom (long int nMin)
179 : {
180 0 : mnMinZoom = (sal_uInt16) nMin;
181 0 : }
182 :
183 0 : void Window::SetMaxZoom (long int nMax)
184 : {
185 0 : mnMaxZoom = (sal_uInt16) nMax;
186 0 : }
187 :
188 1726 : long Window::GetZoom() const
189 : {
190 1726 : if( GetMapMode().GetScaleX().GetDenominator() )
191 : {
192 1726 : return GetMapMode().GetScaleX().GetNumerator() * 100L
193 1726 : / GetMapMode().GetScaleX().GetDenominator();
194 : }
195 : else
196 : {
197 0 : return 0;
198 : }
199 : }
200 :
201 763 : void Window::Resize()
202 : {
203 763 : vcl::Window::Resize();
204 763 : CalcMinZoom();
205 :
206 763 : if( mpViewShell && mpViewShell->GetViewFrame() )
207 763 : mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
208 763 : }
209 :
210 2035 : void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
211 : {
212 2035 : if ( mpViewShell )
213 2035 : mpViewShell->PrePaint();
214 2035 : }
215 :
216 1137 : void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle& rRect)
217 : {
218 1137 : if ( mpViewShell )
219 1137 : mpViewShell->Paint(rRect, this);
220 1137 : }
221 :
222 1 : void Window::KeyInput(const KeyEvent& rKEvt)
223 : {
224 1 : if (getenv("SD_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 && mpViewShell)
225 : {
226 0 : mpViewShell->GetDoc()->dumpAsXml(0);
227 1 : return;
228 : }
229 :
230 1 : if (!(mpViewShell && mpViewShell->KeyInput(rKEvt, this)))
231 : {
232 0 : if (mpViewShell && rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
233 : {
234 0 : mpViewShell->GetViewShell()->Escape();
235 : }
236 : else
237 : {
238 0 : vcl::Window::KeyInput(rKEvt);
239 : }
240 : }
241 : }
242 :
243 0 : void Window::MouseButtonDown(const MouseEvent& rMEvt)
244 : {
245 0 : if ( mpViewShell )
246 0 : mpViewShell->MouseButtonDown(rMEvt, this);
247 0 : }
248 :
249 0 : void Window::MouseMove(const MouseEvent& rMEvt)
250 : {
251 0 : if ( mpViewShell )
252 0 : mpViewShell->MouseMove(rMEvt, this);
253 0 : }
254 :
255 0 : void Window::MouseButtonUp(const MouseEvent& rMEvt)
256 : {
257 0 : mnTicks = 0;
258 :
259 0 : if ( mpViewShell )
260 0 : mpViewShell->MouseButtonUp(rMEvt, this);
261 0 : }
262 :
263 0 : void Window::Command(const CommandEvent& rCEvt)
264 : {
265 0 : if ( mpViewShell )
266 0 : mpViewShell->Command(rCEvt, this);
267 0 : }
268 :
269 106 : bool Window::Notify( NotifyEvent& rNEvt )
270 : {
271 106 : bool nResult = false;
272 106 : if ( mpViewShell )
273 : {
274 106 : nResult = mpViewShell->Notify(rNEvt, this);
275 : }
276 106 : if( !nResult )
277 106 : nResult = vcl::Window::Notify( rNEvt );
278 :
279 106 : return nResult;
280 : }
281 :
282 0 : void Window::RequestHelp(const HelpEvent& rEvt)
283 : {
284 0 : if ( mpViewShell )
285 : {
286 0 : if( !mpViewShell->RequestHelp( rEvt, this) )
287 0 : vcl::Window::RequestHelp( rEvt );
288 : }
289 : else
290 0 : vcl::Window::RequestHelp( rEvt );
291 0 : }
292 :
293 : /**
294 : * Set the position of the upper left corner from the visible area of the
295 : * window.
296 : */
297 607 : void Window::SetWinViewPos(const Point& rPnt)
298 : {
299 607 : maWinPos = rPnt;
300 607 : }
301 :
302 : /**
303 : * Set origin of the representation in respect to the whole working area.
304 : */
305 490 : void Window::SetViewOrigin(const Point& rPnt)
306 : {
307 490 : maViewOrigin = rPnt;
308 490 : }
309 :
310 : /**
311 : * Set size of the whole working area which can be seen with the window.
312 : */
313 490 : void Window::SetViewSize(const Size& rSize)
314 : {
315 490 : maViewSize = rSize;
316 490 : CalcMinZoom();
317 490 : }
318 :
319 261 : void Window::SetCenterAllowed (bool bIsAllowed)
320 : {
321 261 : mbCenterAllowed = bIsAllowed;
322 261 : }
323 :
324 857 : long Window::SetZoomFactor(long nZoom)
325 : {
326 : // Clip the zoom factor to the valid range marked by nMinZoom as
327 : // calculated by CalcMinZoom() and the constant MAX_ZOOM.
328 857 : if ( nZoom > MAX_ZOOM )
329 0 : nZoom = MAX_ZOOM;
330 857 : if ( nZoom < (long) mnMinZoom )
331 2 : nZoom = mnMinZoom;
332 :
333 : // Set the zoom factor at the window's map mode.
334 857 : if (!mpViewShell || !mpViewShell->GetDoc()->isTiledRendering())
335 : {
336 827 : MapMode aMap(GetMapMode());
337 827 : aMap.SetScaleX(Fraction(nZoom, 100));
338 827 : aMap.SetScaleY(Fraction(nZoom, 100));
339 827 : SetMapMode(aMap);
340 : }
341 :
342 : // invalidate previous size - it was relative to the old scaling
343 857 : maPrevSize = Size(-1,-1);
344 :
345 : // Update the map mode's origin (to what effect?).
346 857 : UpdateMapOrigin();
347 :
348 : // Update the view's snapping to the new zoom factor.
349 857 : if ( mpViewShell && mpViewShell->ISA(DrawViewShell) )
350 857 : static_cast<DrawViewShell*>(mpViewShell)->GetView()->
351 1714 : RecalcLogicSnapMagnetic(*this);
352 :
353 : // Return the zoom factor just in case it has been changed above to lie
354 : // inside the valid range.
355 857 : return nZoom;
356 : }
357 :
358 430 : void Window::SetZoomIntegral(long nZoom)
359 : {
360 : // Clip the zoom factor to the valid range marked by nMinZoom as
361 : // previously calculated by <member>CalcMinZoom()</member> and the
362 : // MAX_ZOOM constant.
363 430 : if ( nZoom > MAX_ZOOM )
364 0 : nZoom = MAX_ZOOM;
365 430 : if ( nZoom < (long) mnMinZoom )
366 0 : nZoom = mnMinZoom;
367 :
368 : // Calculate the window's new origin.
369 430 : Size aSize = PixelToLogic(GetOutputSizePixel());
370 430 : long nW = aSize.Width() * GetZoom() / nZoom;
371 430 : long nH = aSize.Height() * GetZoom() / nZoom;
372 430 : maWinPos.X() += (aSize.Width() - nW) / 2;
373 430 : maWinPos.Y() += (aSize.Height() - nH) / 2;
374 430 : if ( maWinPos.X() < 0 ) maWinPos.X() = 0;
375 430 : if ( maWinPos.Y() < 0 ) maWinPos.Y() = 0;
376 :
377 : // Finally update this window's map mode to the given zoom factor that
378 : // has been clipped to the valid range.
379 430 : SetZoomFactor(nZoom);
380 430 : }
381 :
382 124 : long Window::GetZoomForRect( const Rectangle& rZoomRect )
383 : {
384 124 : long nRetZoom = 100;
385 :
386 124 : if( (rZoomRect.GetWidth() != 0) && (rZoomRect.GetHeight() != 0))
387 : {
388 : // Calculate the scale factors which will lead to the given
389 : // rectangle being fully visible (when translated accordingly) as
390 : // large as possible in the output area independently in both
391 : // coordinate directions .
392 124 : sal_uLong nX(0L);
393 124 : sal_uLong nY(0L);
394 :
395 124 : const Size aWinSize( PixelToLogic(GetOutputSizePixel()) );
396 124 : if(rZoomRect.GetHeight())
397 : {
398 124 : nX = (sal_uLong) ((double) aWinSize.Height()
399 124 : * (double) ZOOM_MULTIPLICATOR / (double) rZoomRect.GetHeight());
400 : }
401 :
402 124 : if(rZoomRect.GetWidth())
403 : {
404 124 : nY = (sal_uLong) ((double) aWinSize.Width()
405 124 : * (double) ZOOM_MULTIPLICATOR / (double) rZoomRect.GetWidth());
406 : }
407 :
408 : // Use the smaller one of both so that the zoom rectangle will be
409 : // fully visible with respect to both coordinate directions.
410 124 : sal_uLong nFact = std::min(nX, nY);
411 :
412 : // Transform the current zoom factor so that it leads to the desired
413 : // scaling.
414 124 : nRetZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR;
415 :
416 : // Calculate the new origin.
417 124 : if ( nFact == 0 )
418 : {
419 : // Don't change anything if the scale factor is degenrate.
420 61 : nRetZoom = GetZoom();
421 : }
422 : else
423 : {
424 : // Clip the zoom factor to the valid range marked by nMinZoom as
425 : // previously calculated by <member>CalcMinZoom()</member> and the
426 : // MAX_ZOOM constant.
427 63 : if ( nRetZoom > MAX_ZOOM )
428 0 : nRetZoom = MAX_ZOOM;
429 63 : if ( nRetZoom < (long) mnMinZoom )
430 1 : nRetZoom = mnMinZoom;
431 : }
432 : }
433 :
434 124 : return nRetZoom;
435 : }
436 :
437 : /** Recalculate the zoom factor and translation so that the given rectangle
438 : is displayed centered and as large as possible while still being fully
439 : visible in the window.
440 : */
441 430 : long Window::SetZoomRect (const Rectangle& rZoomRect)
442 : {
443 430 : long nNewZoom = 100;
444 :
445 430 : if (rZoomRect.GetWidth() == 0 || rZoomRect.GetHeight() == 0)
446 : {
447 : // The given rectangle is degenerate. Use the default zoom factor
448 : // (above) of 100%.
449 0 : SetZoomIntegral(nNewZoom);
450 : }
451 : else
452 : {
453 430 : Point aPos = rZoomRect.TopLeft();
454 : // Transform the output area from pixel coordinates into logical
455 : // coordinates.
456 430 : Size aWinSize = PixelToLogic(GetOutputSizePixel());
457 : // Paranoia! The degenerate case of zero width or height has been
458 : // taken care of above.
459 : DBG_ASSERT(rZoomRect.GetWidth(), "ZoomRect-Width = 0!");
460 : DBG_ASSERT(rZoomRect.GetHeight(), "ZoomRect-Height = 0!");
461 :
462 : // Calculate the scale factors which will lead to the given
463 : // rectangle being fully visible (when translated accordingly) as
464 : // large as possible in the output area independently in both
465 : // coordinate directions .
466 430 : sal_uLong nX(0L);
467 430 : sal_uLong nY(0L);
468 :
469 430 : if(rZoomRect.GetHeight())
470 : {
471 430 : nX = (sal_uLong) ((double) aWinSize.Height()
472 430 : * (double) ZOOM_MULTIPLICATOR / (double) rZoomRect.GetHeight());
473 : }
474 :
475 430 : if(rZoomRect.GetWidth())
476 : {
477 430 : nY = (sal_uLong) ((double) aWinSize.Width()
478 430 : * (double) ZOOM_MULTIPLICATOR / (double) rZoomRect.GetWidth());
479 : }
480 :
481 : // Use the smaller one of both so that the zoom rectangle will be
482 : // fully visible with respect to both coordinate directions.
483 430 : sal_uLong nFact = std::min(nX, nY);
484 :
485 : // Transform the current zoom factor so that it leads to the desired
486 : // scaling.
487 430 : long nZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR;
488 :
489 : // Calculate the new origin.
490 430 : if ( nFact == 0 )
491 : {
492 : // Don't change anything if the scale factor is degenrate.
493 3 : nNewZoom = GetZoom();
494 : }
495 : else
496 : {
497 : // Calculate the new window position that centers the given
498 : // rectangle on the screen.
499 427 : if ( nZoom > MAX_ZOOM )
500 0 : nFact = nFact * MAX_ZOOM / nZoom;
501 :
502 427 : maWinPos = maViewOrigin + aPos;
503 :
504 427 : aWinSize.Width() = (long) ((double) aWinSize.Width() * (double) ZOOM_MULTIPLICATOR / (double) nFact);
505 427 : maWinPos.X() += (rZoomRect.GetWidth() - aWinSize.Width()) / 2;
506 427 : aWinSize.Height() = (long) ((double) aWinSize.Height() * (double) ZOOM_MULTIPLICATOR / (double) nFact);
507 427 : maWinPos.Y() += (rZoomRect.GetHeight() - aWinSize.Height()) / 2;
508 :
509 427 : if ( maWinPos.X() < 0 ) maWinPos.X() = 0;
510 427 : if ( maWinPos.Y() < 0 ) maWinPos.Y() = 0;
511 :
512 : // Adapt the window's map mode to the new zoom factor.
513 427 : nNewZoom = SetZoomFactor(nZoom);
514 : }
515 : }
516 :
517 430 : return nNewZoom;
518 : }
519 :
520 0 : void Window::SetMinZoomAutoCalc (bool bAuto)
521 : {
522 0 : mbMinZoomAutoCalc = bAuto;
523 0 : }
524 :
525 : /**
526 : * Calculate and set new MapMode origin.
527 : * If aWinPos.X()/Y() == -1, then we center the corresponding position (e.g. for
528 : * initialization).
529 : */
530 1761 : void Window::UpdateMapOrigin(bool bInvalidate)
531 : {
532 1761 : bool bChanged = false;
533 1761 : const Size aWinSize = PixelToLogic(GetOutputSizePixel());
534 :
535 1761 : if ( mbCenterAllowed )
536 : {
537 1760 : if( maPrevSize != Size(-1,-1) )
538 : {
539 : // keep view centered around current pos, when window
540 : // resizes
541 770 : maWinPos.X() -= (aWinSize.Width() - maPrevSize.Width()) / 2;
542 770 : maWinPos.Y() -= (aWinSize.Height() - maPrevSize.Height()) / 2;
543 770 : bChanged = true;
544 : }
545 :
546 1760 : if ( maWinPos.X() > maViewSize.Width() - aWinSize.Width() )
547 : {
548 10 : maWinPos.X() = maViewSize.Width() - aWinSize.Width();
549 10 : bChanged = true;
550 : }
551 1760 : if ( maWinPos.Y() > maViewSize.Height() - aWinSize.Height() )
552 : {
553 99 : maWinPos.Y() = maViewSize.Height() - aWinSize.Height();
554 99 : bChanged = true;
555 : }
556 1760 : if ( aWinSize.Width() > maViewSize.Width() || maWinPos.X() < 0 )
557 : {
558 185 : maWinPos.X() = maViewSize.Width() / 2 - aWinSize.Width() / 2;
559 185 : bChanged = true;
560 : }
561 1760 : if ( aWinSize.Height() > maViewSize.Height() || maWinPos.Y() < 0 )
562 : {
563 277 : maWinPos.Y() = maViewSize.Height() / 2 - aWinSize.Height() / 2;
564 277 : bChanged = true;
565 : }
566 : }
567 :
568 1761 : UpdateMapMode ();
569 :
570 1761 : maPrevSize = aWinSize;
571 :
572 : // When tiled rendering, the above UpdateMapMode() call doesn't touch the map mode.
573 1761 : if (bChanged && bInvalidate && (!mpViewShell || !mpViewShell->GetDoc()->isTiledRendering()))
574 934 : Invalidate();
575 1761 : }
576 :
577 1761 : void Window::UpdateMapMode()
578 : {
579 1761 : maWinPos -= maViewOrigin;
580 1761 : Size aPix(maWinPos.X(), maWinPos.Y());
581 1761 : aPix = LogicToPixel(aPix);
582 : // Size has to be a multiple of BRUSH_SIZE due to the correct depiction of
583 : // pattern
584 : // #i2237#
585 : // removed old stuff here which still forced zoom to be
586 : // %BRUSH_SIZE which is outdated now
587 :
588 1761 : if (mpViewShell && mpViewShell->ISA(DrawViewShell))
589 : {
590 : // page should not "stick" to the window border
591 1760 : if (aPix.Width() == 0)
592 : {
593 : // #i2237#
594 : // Since BRUSH_SIZE alignment is outdated now, i use the
595 : // former constant here directly
596 1 : aPix.Width() -= 8;
597 : }
598 1760 : if (aPix.Height() == 0)
599 : {
600 : // #i2237#
601 : // Since BRUSH_SIZE alignment is outdated now, i use the
602 : // former constant here directly
603 0 : aPix.Height() -= 8;
604 : }
605 : }
606 :
607 1761 : aPix = PixelToLogic(aPix);
608 1761 : maWinPos.X() = aPix.Width();
609 1761 : maWinPos.Y() = aPix.Height();
610 1761 : Point aNewOrigin (-maWinPos.X(), -maWinPos.Y());
611 1761 : maWinPos += maViewOrigin;
612 :
613 1761 : if (!mpViewShell || !mpViewShell->GetDoc()->isTiledRendering())
614 : {
615 1703 : MapMode aMap(GetMapMode());
616 1703 : aMap.SetOrigin(aNewOrigin);
617 1703 : SetMapMode(aMap);
618 : }
619 1761 : }
620 :
621 : /**
622 : * @returns X position of the visible area as fraction (< 1) of the whole
623 : * working area.
624 : */
625 1061 : double Window::GetVisibleX()
626 : {
627 1061 : return ((double) maWinPos.X() / maViewSize.Width());
628 : }
629 :
630 : /**
631 : * @returns Y position of the visible area as fraction (< 1) of the whole
632 : * working area.
633 : */
634 1061 : double Window::GetVisibleY()
635 : {
636 1061 : return ((double) maWinPos.Y() / maViewSize.Height());
637 : }
638 :
639 : /**
640 : * Set x and y position of the visible area as fraction (< 1) of the whole
641 : * working area. Negative values are ignored.
642 : */
643 3 : void Window::SetVisibleXY(double fX, double fY)
644 : {
645 3 : long nOldX = maWinPos.X();
646 3 : long nOldY = maWinPos.Y();
647 :
648 3 : if ( fX >= 0 )
649 3 : maWinPos.X() = (long) (fX * maViewSize.Width());
650 3 : if ( fY >= 0 )
651 1 : maWinPos.Y() = (long) (fY * maViewSize.Height());
652 3 : UpdateMapOrigin(false);
653 3 : Scroll(nOldX - maWinPos.X(), nOldY - maWinPos.Y(), ScrollFlags::Children);
654 3 : Update();
655 3 : }
656 :
657 : /**
658 : * @returns width of the visible area in proportion to the width of the whole
659 : * working area.
660 : */
661 2703 : double Window::GetVisibleWidth()
662 : {
663 2703 : Size aWinSize = PixelToLogic(GetOutputSizePixel());
664 2703 : if ( aWinSize.Width() > maViewSize.Width() )
665 18 : aWinSize.Width() = maViewSize.Width();
666 2703 : return ((double) aWinSize.Width() / maViewSize.Width());
667 : }
668 :
669 : /**
670 : * @returns height of the visible area in proportion to the height of the whole
671 : * working area.
672 : */
673 3522 : double Window::GetVisibleHeight()
674 : {
675 3522 : Size aWinSize = PixelToLogic(GetOutputSizePixel());
676 3522 : if ( aWinSize.Height() > maViewSize.Height() )
677 82 : aWinSize.Height() = maViewSize.Height();
678 3522 : return ((double) aWinSize.Height() / maViewSize.Height());
679 : }
680 :
681 : /**
682 : * @returns width of a scroll column in proportion to the width of the whole
683 : * working area.
684 : */
685 901 : double Window::GetScrlLineWidth()
686 : {
687 901 : return (GetVisibleWidth() * SCROLL_LINE_FACT);
688 : }
689 :
690 : /**
691 : * @returns height of a scroll column in proportion to the height of the whole
692 : * working area.
693 : */
694 860 : double Window::GetScrlLineHeight()
695 : {
696 860 : return (GetVisibleHeight() * SCROLL_LINE_FACT);
697 : }
698 :
699 : /**
700 : * @returns width of a scroll page in proportion to the width of the whole
701 : * working area.
702 : */
703 901 : double Window::GetScrlPageWidth()
704 : {
705 901 : return (GetVisibleWidth() * SCROLL_PAGE_FACT);
706 : }
707 :
708 : /**
709 : * @returns height of a scroll page in proportion to the height of the whole
710 : * working area.
711 : */
712 860 : double Window::GetScrlPageHeight()
713 : {
714 860 : return (GetVisibleHeight() * SCROLL_PAGE_FACT);
715 : }
716 :
717 : /**
718 : * Deactivate window.
719 : */
720 6 : void Window::LoseFocus()
721 : {
722 6 : mnTicks = 0;
723 6 : vcl::Window::LoseFocus ();
724 6 : }
725 :
726 : /**
727 : * Activate window.
728 : */
729 202 : void Window::GrabFocus()
730 : {
731 202 : mnTicks = 0;
732 202 : vcl::Window::GrabFocus ();
733 202 : }
734 :
735 4 : void Window::DataChanged( const DataChangedEvent& rDCEvt )
736 : {
737 4 : vcl::Window::DataChanged( rDCEvt );
738 :
739 : /* Omit PRINTER by all documents which are not using a printer.
740 : Omit FONTS and FONTSUBSTITUTION if no text output is available or if the
741 : document does not allow text. */
742 :
743 16 : if ( (rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
744 8 : (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
745 8 : (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
746 20 : (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
747 12 : ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
748 16 : (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
749 : {
750 16 : if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
751 16 : (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
752 : {
753 : // When the screen zoom factor has changed then reset the zoom
754 : // factor of the frame to always display the whole page.
755 4 : const AllSettings* pOldSettings = rDCEvt.GetOldSettings ();
756 4 : const AllSettings& rNewSettings = GetSettings ();
757 4 : if (pOldSettings && mpViewShell)
758 : {
759 8 : if (pOldSettings->GetStyleSettings().GetScreenZoom()
760 4 : != rNewSettings.GetStyleSettings().GetScreenZoom())
761 : {
762 : mpViewShell->GetViewFrame()->GetDispatcher()->
763 0 : Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
764 : }
765 : }
766 :
767 : /* Rearrange or initiate Resize for scroll bars since the size of
768 : the scroll bars my have changed. Within this, inside the resize-
769 : handler, the size of the scroll bars will be asked from the
770 : Settings. */
771 4 : Resize();
772 :
773 : /* Re-set data, which are from system control or from Settings. May
774 : have to re-set more data since the resolution may also has
775 : changed. */
776 4 : if( mpViewShell )
777 : {
778 4 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
779 4 : SvtAccessibilityOptions aAccOptions;
780 : DrawModeFlags nOutputMode;
781 : sal_uInt16 nPreviewSlot;
782 :
783 4 : if( rStyleSettings.GetHighContrastMode() )
784 0 : nOutputMode = sd::OUTPUT_DRAWMODE_CONTRAST;
785 : else
786 4 : nOutputMode = sd::OUTPUT_DRAWMODE_COLOR;
787 :
788 4 : if( rStyleSettings.GetHighContrastMode() && aAccOptions.GetIsForPagePreviews() )
789 0 : nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST;
790 : else
791 4 : nPreviewSlot = SID_PREVIEW_QUALITY_COLOR;
792 :
793 4 : if( mpViewShell->ISA( DrawViewShell ) )
794 : {
795 4 : SetDrawMode( nOutputMode );
796 4 : mpViewShell->GetFrameView()->SetDrawMode( nOutputMode );
797 4 : Invalidate();
798 : }
799 :
800 : // Overwrite window color for OutlineView
801 4 : if( mpViewShell->ISA(OutlineViewShell ) )
802 : {
803 0 : svtools::ColorConfig aColorConfig;
804 0 : const Color aDocColor( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
805 0 : SetBackground( Wallpaper( aDocColor ) );
806 : }
807 :
808 8 : SfxRequest aReq( nPreviewSlot, SfxCallMode::SLOT, mpViewShell->GetDocSh()->GetDoc()->GetItemPool() );
809 4 : mpViewShell->ExecReq( aReq );
810 4 : mpViewShell->Invalidate();
811 4 : mpViewShell->ArrangeGUIElements();
812 :
813 : // re-create handles to show new outfit
814 4 : if(mpViewShell->ISA(DrawViewShell))
815 : {
816 4 : mpViewShell->GetView()->AdjustMarkHdl();
817 4 : }
818 : }
819 : }
820 :
821 12 : if ( (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
822 12 : ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
823 16 : (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
824 : {
825 : /* Virtual devices, which also depends on the resolution or the
826 : system control, should be updated. Otherwise, we should update
827 : the virtual devices at least at DataChangedEventType::DISPLAY since some
828 : systems allow to change the resolution and color depth during
829 : runtime. Or the virtual devices have to be updated when the color
830 : palette has changed since a different color matching can be used
831 : when outputting. */
832 : }
833 :
834 4 : if ( rDCEvt.GetType() == DataChangedEventType::FONTS )
835 : {
836 : /* If the document provides font choose boxes, we have to update
837 : them. I don't know how this looks like (also not really me, I
838 : only translated the comment ;). We may can handle it global. We
839 : have to discuss it with PB, but he is ill at the moment.
840 : Before we handle it here, discuss it with PB and me. */
841 : }
842 :
843 8 : if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
844 4 : (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) )
845 : {
846 : /* Do reformating since the fonts of the document may no longer
847 : exist, or exist now, or are replaced with others. */
848 0 : if( mpViewShell )
849 : {
850 0 : DrawDocShell* pDocSh = mpViewShell->GetDocSh();
851 0 : if( pDocSh )
852 0 : pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
853 : }
854 : }
855 :
856 4 : if ( rDCEvt.GetType() == DataChangedEventType::PRINTER )
857 : {
858 : /* I don't know how the handling should look like. Maybe we delete a
859 : printer and look what we have to do. Maybe I have to add
860 : something to the VCL, in case the used printer is deleted.
861 : Otherwise I may recalculate the formatting here if the current
862 : printer is destroyed. */
863 0 : if( mpViewShell )
864 : {
865 0 : DrawDocShell* pDocSh = mpViewShell->GetDocSh();
866 0 : if( pDocSh )
867 0 : pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
868 : }
869 : }
870 :
871 : // Update everything
872 4 : Invalidate();
873 : }
874 4 : }
875 :
876 0 : sal_Int8 Window::AcceptDrop( const AcceptDropEvent& rEvt )
877 : {
878 0 : sal_Int8 nRet = DND_ACTION_NONE;
879 :
880 0 : if( mpViewShell && !mpViewShell->GetDocSh()->IsReadOnly() )
881 : {
882 0 : if( mpViewShell )
883 0 : nRet = mpViewShell->AcceptDrop( rEvt, *this, this, SDRPAGE_NOTFOUND, SDRLAYER_NOTFOUND );
884 :
885 0 : if (mbUseDropScroll && ! mpViewShell->ISA(OutlineViewShell))
886 0 : DropScroll( rEvt.maPosPixel );
887 : }
888 :
889 0 : return nRet;
890 : }
891 :
892 0 : sal_Int8 Window::ExecuteDrop( const ExecuteDropEvent& rEvt )
893 : {
894 0 : sal_Int8 nRet = DND_ACTION_NONE;
895 :
896 0 : if( mpViewShell )
897 : {
898 0 : nRet = mpViewShell->ExecuteDrop( rEvt, *this, this, SDRPAGE_NOTFOUND, SDRLAYER_NOTFOUND );
899 : }
900 :
901 0 : return nRet;
902 : }
903 :
904 64 : void Window::SetUseDropScroll (bool bUseDropScroll)
905 : {
906 64 : mbUseDropScroll = bUseDropScroll;
907 64 : }
908 :
909 0 : void Window::DropScroll(const Point& rMousePos)
910 : {
911 0 : short nDx = 0;
912 0 : short nDy = 0;
913 :
914 0 : Size aSize = GetOutputSizePixel();
915 :
916 0 : if (aSize.Width() > SCROLL_SENSITIVE * 3)
917 : {
918 0 : if ( rMousePos.X() < SCROLL_SENSITIVE )
919 : {
920 0 : nDx = -1;
921 : }
922 :
923 0 : if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE )
924 : {
925 0 : nDx = 1;
926 : }
927 : }
928 :
929 0 : if (aSize.Height() > SCROLL_SENSITIVE * 3)
930 : {
931 0 : if ( rMousePos.Y() < SCROLL_SENSITIVE )
932 : {
933 0 : nDy = -1;
934 : }
935 :
936 0 : if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE )
937 : {
938 0 : nDy = 1;
939 : }
940 : }
941 :
942 0 : if ( (nDx || nDy) && (rMousePos.X()!=0 || rMousePos.Y()!=0 ) )
943 : {
944 0 : if (mnTicks > 20)
945 0 : mpViewShell->ScrollLines(nDx, nDy);
946 : else
947 0 : mnTicks ++;
948 : }
949 0 : }
950 :
951 : ::com::sun::star::uno::Reference<
952 : ::com::sun::star::accessibility::XAccessible>
953 3 : Window::CreateAccessible()
954 : {
955 : // If current viewshell is PresentationViewShell, just return empty because the correct ShowWin will be created later.
956 3 : if (mpViewShell && mpViewShell->ISA(PresentationViewShell))
957 : {
958 0 : return vcl::Window::CreateAccessible ();
959 : }
960 3 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc = GetAccessible(false);
961 3 : if (xAcc.get())
962 : {
963 0 : return xAcc;
964 : }
965 3 : if (mpViewShell != NULL)
966 : {
967 3 : xAcc = mpViewShell->CreateAccessibleDocumentView (this);
968 3 : SetAccessible(xAcc);
969 3 : return xAcc;
970 : }
971 : else
972 : {
973 : OSL_TRACE ("::sd::Window::CreateAccessible: no view shell");
974 0 : return vcl::Window::CreateAccessible ();
975 3 : }
976 : }
977 :
978 0 : OUString Window::GetSurroundingText() const
979 : {
980 0 : if ( mpViewShell->GetShellType() == ViewShell::ST_OUTLINE )
981 0 : return OUString();
982 0 : else if ( mpViewShell->GetView()->IsTextEdit() )
983 : {
984 0 : OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
985 0 : return pOLV->GetEditView().GetSurroundingText();
986 : }
987 0 : return OUString();
988 : }
989 :
990 0 : Selection Window::GetSurroundingTextSelection() const
991 : {
992 0 : if ( mpViewShell->GetShellType() == ViewShell::ST_OUTLINE )
993 : {
994 0 : return Selection( 0, 0 );
995 : }
996 0 : else if ( mpViewShell->GetView()->IsTextEdit() )
997 : {
998 0 : OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
999 0 : return pOLV->GetEditView().GetSurroundingTextSelection();
1000 : }
1001 : else
1002 : {
1003 0 : return Selection( 0, 0 );
1004 : }
1005 : }
1006 :
1007 4252 : void Window::LogicInvalidate(const Rectangle* pRectangle)
1008 : {
1009 4252 : OString sRectangle;
1010 4252 : if (!pRectangle)
1011 978 : sRectangle = "EMPTY";
1012 : else
1013 : {
1014 3274 : Rectangle aRectangle(*pRectangle);
1015 3274 : if (GetMapMode().GetMapUnit() == MAP_100TH_MM)
1016 3014 : aRectangle = OutputDevice::LogicToLogic(aRectangle, MAP_100TH_MM, MAP_TWIP);
1017 3274 : sRectangle = aRectangle.toString();
1018 : }
1019 4252 : mpViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr());
1020 4252 : }
1021 :
1022 66 : } // end of namespace sd
1023 :
1024 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|