/src/libreoffice/svx/source/dialog/graphctl.cxx
Line | Count | Source |
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 <config_wasm_strip.h> |
21 | | |
22 | | #include <svl/itempool.hxx> |
23 | | #include <vcl/settings.hxx> |
24 | | #include <vcl/ptrstyle.hxx> |
25 | | #include <vcl/svapp.hxx> |
26 | | #include <vcl/weld/Dialog.hxx> |
27 | | |
28 | | #include <svx/graphctl.hxx> |
29 | | #include <svx/sdr/overlay/overlaymanager.hxx> |
30 | | #include <GraphCtlAccessibleContext.hxx> |
31 | | #include <svx/svxids.hrc> |
32 | | #include <svx/svdpage.hxx> |
33 | | #include <svx/sdrpaintwindow.hxx> |
34 | | |
35 | | void GraphCtrlUserCall::Changed( const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle& /*rOldBoundRect*/ ) |
36 | 0 | { |
37 | 0 | switch( eType ) |
38 | 0 | { |
39 | 0 | case SdrUserCallType::MoveOnly: |
40 | 0 | case SdrUserCallType::Resize: |
41 | 0 | m_rWin.SdrObjChanged( rObj ); |
42 | 0 | break; |
43 | | |
44 | 0 | case SdrUserCallType::Inserted: |
45 | 0 | m_rWin.SdrObjCreated( rObj ); |
46 | 0 | break; |
47 | | |
48 | 0 | default: |
49 | 0 | break; |
50 | 0 | } |
51 | 0 | m_rWin.QueueIdleUpdate(); |
52 | 0 | } |
53 | | |
54 | | GraphCtrl::GraphCtrl(weld::Dialog* pDialog) |
55 | 0 | : maUpdateIdle("svx GraphCtrl Update") |
56 | 0 | , maMap100(MapUnit::Map100thMM) |
57 | 0 | , meObjKind(SdrObjKind::NONE) |
58 | 0 | , mnPolyEdit(0) |
59 | 0 | , mbEditMode(false) |
60 | 0 | , mbSdrMode(false) |
61 | 0 | , mbInIdleUpdate(false) |
62 | 0 | , mpDialog(pDialog) |
63 | 0 | { |
64 | 0 | mpUserCall.reset(new GraphCtrlUserCall( *this )); |
65 | 0 | maUpdateIdle.SetPriority( TaskPriority::LOWEST ); |
66 | 0 | maUpdateIdle.SetInvokeHandler( LINK( this, GraphCtrl, UpdateHdl ) ); |
67 | 0 | maUpdateIdle.Start(); |
68 | 0 | } |
69 | | |
70 | | void GraphCtrl::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
71 | 0 | { |
72 | 0 | weld::CustomWidgetController::SetDrawingArea(pDrawingArea); |
73 | 0 | EnableRTL(false); |
74 | 0 | } |
75 | | |
76 | | GraphCtrl::~GraphCtrl() |
77 | 0 | { |
78 | 0 | maUpdateIdle.Stop(); |
79 | |
|
80 | 0 | #if !ENABLE_WASM_STRIP_ACCESSIBILITY |
81 | 0 | if( mpAccContext.is() ) |
82 | 0 | { |
83 | 0 | mpAccContext->disposing(); |
84 | 0 | mpAccContext.clear(); |
85 | 0 | } |
86 | 0 | #endif |
87 | |
|
88 | 0 | mpView.reset(); |
89 | 0 | mpModel.reset(); |
90 | 0 | mpUserCall.reset(); |
91 | 0 | } |
92 | | |
93 | | void GraphCtrl::SetSdrMode(bool bSdrMode) |
94 | 0 | { |
95 | 0 | mbSdrMode = bSdrMode; |
96 | |
|
97 | 0 | const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); |
98 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
99 | 0 | rDevice.SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) ); |
100 | 0 | mxVD->SetBackground( Wallpaper( rStyleSettings.GetWindowColor() ) ); |
101 | 0 | rDevice.SetMapMode( maMap100 ); |
102 | 0 | mxVD->SetMapMode( maMap100 ); |
103 | |
|
104 | 0 | mpView.reset(); |
105 | 0 | mpModel.reset(); |
106 | |
|
107 | 0 | if ( mbSdrMode ) |
108 | 0 | InitSdrModel(); |
109 | |
|
110 | 0 | QueueIdleUpdate(); |
111 | 0 | } |
112 | | |
113 | | void GraphCtrl::InitSdrModel() |
114 | 0 | { |
115 | 0 | SolarMutexGuard aGuard; |
116 | |
|
117 | 0 | rtl::Reference<SdrPage> pPage; |
118 | | |
119 | | // destroy old junk |
120 | 0 | mpView.reset(); |
121 | 0 | mpModel.reset(); |
122 | | |
123 | | // Creating a Model |
124 | 0 | mpModel.reset(new SdrModel(nullptr, nullptr, true)); |
125 | 0 | mpModel->SetScaleUnit(maMap100.GetMapUnit()); |
126 | 0 | mpModel->SetDefaultFontHeight( 500 ); |
127 | |
|
128 | 0 | pPage = new SdrPage( *mpModel ); |
129 | |
|
130 | 0 | pPage->SetSize( maGraphSize ); |
131 | 0 | pPage->SetBorder( 0, 0, 0, 0 ); |
132 | 0 | mpModel->InsertPage( pPage.get() ); |
133 | 0 | mpModel->SetChanged( false ); |
134 | | |
135 | | // Creating a View |
136 | 0 | mpView.reset(new GraphCtrlView(*mpModel, this)); |
137 | 0 | mpView->SetWorkArea( tools::Rectangle( Point(), maGraphSize ) ); |
138 | 0 | mpView->EnableExtendedMouseEventDispatcher( true ); |
139 | 0 | mpView->ShowSdrPage(mpView->GetModel().GetPage(0)); |
140 | 0 | mpView->SetFrameDragSingles(); |
141 | 0 | mpView->SetMarkedPointsSmooth( SdrPathSmoothKind::Symmetric ); |
142 | 0 | mpView->SetEditMode(); |
143 | | |
144 | | // #i72889# set needed flags |
145 | 0 | mpView->SetPageDecorationAllowed(false); |
146 | 0 | mpView->SetMasterPageVisualizationAllowed(false); |
147 | 0 | mpView->SetBufferedOutputAllowed(true); |
148 | 0 | mpView->SetBufferedOverlayAllowed(true); |
149 | |
|
150 | 0 | #if !ENABLE_WASM_STRIP_ACCESSIBILITY |
151 | | // Tell the accessibility object about the changes. |
152 | 0 | if (mpAccContext.is()) |
153 | 0 | mpAccContext->setModelAndView (mpModel.get(), mpView.get()); |
154 | 0 | #endif |
155 | 0 | } |
156 | | |
157 | | void GraphCtrl::SetGraphic( const Graphic& rGraphic, bool bNewModel ) |
158 | 0 | { |
159 | 0 | maGraphic = rGraphic; |
160 | 0 | mxVD->SetOutputSizePixel(Size(0, 0)); //force redraw |
161 | |
|
162 | 0 | if ( maGraphic.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel ) |
163 | 0 | maGraphSize = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), maMap100 ); |
164 | 0 | else |
165 | 0 | maGraphSize = OutputDevice::LogicToLogic( maGraphic.GetPrefSize(), maGraphic.GetPrefMapMode(), maMap100 ); |
166 | |
|
167 | 0 | if ( mbSdrMode && bNewModel ) |
168 | 0 | InitSdrModel(); |
169 | |
|
170 | 0 | maGraphSizeLink.Call( this ); |
171 | |
|
172 | 0 | Resize(); |
173 | |
|
174 | 0 | Invalidate(); |
175 | 0 | QueueIdleUpdate(); |
176 | 0 | } |
177 | | |
178 | | void GraphCtrl::GraphicToVD() |
179 | 0 | { |
180 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
181 | 0 | mxVD->SetOutputSizePixel(GetOutputSizePixel()); |
182 | 0 | mxVD->SetBackground(rDevice.GetBackground()); |
183 | 0 | mxVD->Erase(); |
184 | 0 | const bool bGraphicValid(GraphicType::NONE != maGraphic.GetType()); |
185 | 0 | if (bGraphicValid) |
186 | 0 | maGraphic.Draw(*mxVD, Point(), maGraphSize); |
187 | 0 | } |
188 | | |
189 | | void GraphCtrl::Resize() |
190 | 0 | { |
191 | 0 | weld::CustomWidgetController::Resize(); |
192 | |
|
193 | 0 | if (maGraphSize.Width() && maGraphSize.Height()) |
194 | 0 | { |
195 | 0 | MapMode aDisplayMap( maMap100 ); |
196 | 0 | Point aNewPos; |
197 | 0 | Size aNewSize; |
198 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
199 | 0 | const Size aWinSize = rDevice.PixelToLogic( GetOutputSizePixel(), aDisplayMap ); |
200 | 0 | const tools::Long nWidth = aWinSize.Width(); |
201 | 0 | const tools::Long nHeight = aWinSize.Height(); |
202 | 0 | double fGrfWH = static_cast<double>(maGraphSize.Width()) / maGraphSize.Height(); |
203 | 0 | double fWinWH = static_cast<double>(nWidth) / nHeight; |
204 | | |
205 | | // Adapt Bitmap to Thumb size |
206 | 0 | if ( fGrfWH < fWinWH) |
207 | 0 | { |
208 | 0 | aNewSize.setWidth( static_cast<tools::Long>( static_cast<double>(nHeight) * fGrfWH ) ); |
209 | 0 | aNewSize.setHeight( nHeight ); |
210 | 0 | } |
211 | 0 | else |
212 | 0 | { |
213 | 0 | aNewSize.setWidth( nWidth ); |
214 | 0 | aNewSize.setHeight( static_cast<tools::Long>( static_cast<double>(nWidth) / fGrfWH ) ); |
215 | 0 | } |
216 | |
|
217 | 0 | aNewPos.setX( ( nWidth - aNewSize.Width() ) >> 1 ); |
218 | 0 | aNewPos.setY( ( nHeight - aNewSize.Height() ) >> 1 ); |
219 | | |
220 | | // Implementing MapMode for Engine |
221 | 0 | aDisplayMap.SetScaleX( double(aNewSize.Width()) / maGraphSize.Width() ); |
222 | 0 | aDisplayMap.SetScaleY( double(aNewSize.Height()) / maGraphSize.Height() ); |
223 | |
|
224 | 0 | aDisplayMap.SetOrigin( OutputDevice::LogicToLogic( aNewPos, maMap100, aDisplayMap ) ); |
225 | 0 | rDevice.SetMapMode( aDisplayMap ); |
226 | 0 | mxVD->SetMapMode( aDisplayMap ); |
227 | 0 | } |
228 | |
|
229 | 0 | Invalidate(); |
230 | 0 | } |
231 | | |
232 | | void GraphCtrl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) |
233 | 0 | { |
234 | | // #i72889# used split repaint to be able to paint an own background |
235 | | // even to the buffered view |
236 | 0 | const bool bGraphicValid(GraphicType::NONE != maGraphic.GetType()); |
237 | |
|
238 | 0 | if (GetOutputSizePixel() != mxVD->GetOutputSizePixel()) |
239 | 0 | GraphicToVD(); |
240 | |
|
241 | 0 | if (mbSdrMode) |
242 | 0 | { |
243 | 0 | SdrPaintWindow* pPaintWindow = mpView->BeginCompleteRedraw(&rRenderContext); |
244 | 0 | pPaintWindow->SetOutputToWindow(true); |
245 | |
|
246 | 0 | if (bGraphicValid) |
247 | 0 | { |
248 | 0 | vcl::RenderContext& rTarget = pPaintWindow->GetTargetOutputDevice(); |
249 | |
|
250 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
251 | 0 | rTarget.SetBackground(rDevice.GetBackground()); |
252 | 0 | rTarget.Erase(); |
253 | |
|
254 | 0 | rTarget.DrawOutDev(Point(), mxVD->GetOutputSize(), Point(), mxVD->GetOutputSize(), *mxVD); |
255 | 0 | } |
256 | |
|
257 | 0 | const vcl::Region aRepaintRegion(rRect); |
258 | 0 | mpView->DoCompleteRedraw(*pPaintWindow, aRepaintRegion); |
259 | 0 | mpView->EndCompleteRedraw(*pPaintWindow, true); |
260 | 0 | } |
261 | 0 | else |
262 | 0 | { |
263 | | // #i73381# in non-SdrMode, paint to local directly |
264 | 0 | rRenderContext.DrawOutDev(rRect.TopLeft(), rRect.GetSize(), |
265 | 0 | rRect.TopLeft(), rRect.GetSize(), |
266 | 0 | *mxVD); |
267 | 0 | } |
268 | 0 | } |
269 | | |
270 | | void GraphCtrl::SdrObjChanged( const SdrObject& ) |
271 | 0 | { |
272 | 0 | QueueIdleUpdate(); |
273 | 0 | } |
274 | | |
275 | | void GraphCtrl::SdrObjCreated( const SdrObject& ) |
276 | 0 | { |
277 | 0 | QueueIdleUpdate(); |
278 | 0 | } |
279 | | |
280 | | void GraphCtrl::MarkListHasChanged() |
281 | 0 | { |
282 | 0 | QueueIdleUpdate(); |
283 | 0 | } |
284 | | |
285 | | bool GraphCtrl::KeyInput( const KeyEvent& rKEvt ) |
286 | 0 | { |
287 | 0 | vcl::KeyCode aCode( rKEvt.GetKeyCode() ); |
288 | 0 | bool bProc = false; |
289 | |
|
290 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
291 | |
|
292 | 0 | switch ( aCode.GetCode() ) |
293 | 0 | { |
294 | 0 | case KEY_DELETE: |
295 | 0 | case KEY_BACKSPACE: |
296 | 0 | { |
297 | 0 | if ( mbSdrMode ) |
298 | 0 | { |
299 | 0 | mpView->DeleteMarked(); |
300 | 0 | bProc = true; |
301 | 0 | } |
302 | 0 | } |
303 | 0 | break; |
304 | | |
305 | 0 | case KEY_ESCAPE: |
306 | 0 | { |
307 | 0 | if ( mbSdrMode ) |
308 | 0 | { |
309 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
310 | 0 | if ( mpView->IsAction() ) |
311 | 0 | { |
312 | 0 | mpView->BrkAction(); |
313 | 0 | bProc = true; |
314 | 0 | } |
315 | 0 | else if ( rMarkList.GetMarkCount() != 0 ) |
316 | 0 | { |
317 | 0 | mpView->UnmarkAllObj(); |
318 | 0 | bProc = true; |
319 | 0 | } |
320 | 0 | } |
321 | 0 | } |
322 | 0 | break; |
323 | | |
324 | 0 | case KEY_F11: |
325 | 0 | case KEY_TAB: |
326 | 0 | { |
327 | 0 | if( mbSdrMode ) |
328 | 0 | { |
329 | 0 | if( !aCode.IsMod1() && !aCode.IsMod2() ) |
330 | 0 | { |
331 | 0 | bool bForward = !aCode.IsShift(); |
332 | | // select next object |
333 | 0 | if ( ! mpView->MarkNextObj( bForward )) |
334 | 0 | { |
335 | | // At first or last object. Cycle to the other end |
336 | | // of the list. |
337 | 0 | mpView->UnmarkAllObj(); |
338 | 0 | mpView->MarkNextObj (bForward); |
339 | 0 | } |
340 | 0 | bProc = true; |
341 | 0 | } |
342 | 0 | else if(aCode.IsMod1()) |
343 | 0 | { |
344 | | // select next handle |
345 | 0 | const SdrHdlList& rHdlList = mpView->GetHdlList(); |
346 | 0 | bool bForward(!aCode.IsShift()); |
347 | |
|
348 | 0 | const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward); |
349 | |
|
350 | 0 | bProc = true; |
351 | 0 | } |
352 | 0 | } |
353 | 0 | } |
354 | 0 | break; |
355 | | |
356 | 0 | case KEY_END: |
357 | 0 | { |
358 | |
|
359 | 0 | if ( aCode.IsMod1() ) |
360 | 0 | { |
361 | | // mark last object |
362 | 0 | mpView->UnmarkAllObj(); |
363 | 0 | mpView->MarkNextObj(); |
364 | |
|
365 | 0 | bProc = true; |
366 | 0 | } |
367 | 0 | } |
368 | 0 | break; |
369 | | |
370 | 0 | case KEY_HOME: |
371 | 0 | { |
372 | 0 | if ( aCode.IsMod1() ) |
373 | 0 | { |
374 | 0 | mpView->UnmarkAllObj(); |
375 | 0 | mpView->MarkNextObj(true); |
376 | |
|
377 | 0 | bProc = true; |
378 | 0 | } |
379 | 0 | } |
380 | 0 | break; |
381 | | |
382 | 0 | case KEY_UP: |
383 | 0 | case KEY_DOWN: |
384 | 0 | case KEY_LEFT: |
385 | 0 | case KEY_RIGHT: |
386 | 0 | { |
387 | 0 | tools::Long nX = 0; |
388 | 0 | tools::Long nY = 0; |
389 | |
|
390 | 0 | if (aCode.GetCode() == KEY_UP) |
391 | 0 | { |
392 | | // Scroll up |
393 | 0 | nX = 0; |
394 | 0 | nY =-1; |
395 | 0 | } |
396 | 0 | else if (aCode.GetCode() == KEY_DOWN) |
397 | 0 | { |
398 | | // Scroll down |
399 | 0 | nX = 0; |
400 | 0 | nY = 1; |
401 | 0 | } |
402 | 0 | else if (aCode.GetCode() == KEY_LEFT) |
403 | 0 | { |
404 | | // Scroll left |
405 | 0 | nX =-1; |
406 | 0 | nY = 0; |
407 | 0 | } |
408 | 0 | else if (aCode.GetCode() == KEY_RIGHT) |
409 | 0 | { |
410 | | // Scroll right |
411 | 0 | nX = 1; |
412 | 0 | nY = 0; |
413 | 0 | } |
414 | |
|
415 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
416 | 0 | if (rMarkList.GetMarkCount() != 0 && !aCode.IsMod1() ) |
417 | 0 | { |
418 | 0 | if(aCode.IsMod2()) |
419 | 0 | { |
420 | | // move in 1 pixel distance |
421 | 0 | Size aLogicSizeOnePixel = rDevice.PixelToLogic(Size(1,1)); |
422 | 0 | nX *= aLogicSizeOnePixel.Width(); |
423 | 0 | nY *= aLogicSizeOnePixel.Height(); |
424 | 0 | } |
425 | 0 | else |
426 | 0 | { |
427 | | // old, fixed move distance |
428 | 0 | nX *= 100; |
429 | 0 | nY *= 100; |
430 | 0 | } |
431 | | |
432 | | // II |
433 | 0 | const SdrHdlList& rHdlList = mpView->GetHdlList(); |
434 | 0 | SdrHdl* pHdl = rHdlList.GetFocusHdl(); |
435 | |
|
436 | 0 | if(nullptr == pHdl) |
437 | 0 | { |
438 | | // restrict movement to WorkArea |
439 | 0 | const tools::Rectangle& rWorkArea = mpView->GetWorkArea(); |
440 | |
|
441 | 0 | if(!rWorkArea.IsEmpty()) |
442 | 0 | { |
443 | 0 | tools::Rectangle aMarkRect(mpView->GetMarkedObjRect()); |
444 | 0 | aMarkRect.Move(nX, nY); |
445 | |
|
446 | 0 | if(!aMarkRect.Contains(rWorkArea)) |
447 | 0 | { |
448 | 0 | if(aMarkRect.Left() < rWorkArea.Left()) |
449 | 0 | { |
450 | 0 | nX += rWorkArea.Left() - aMarkRect.Left(); |
451 | 0 | } |
452 | |
|
453 | 0 | if(aMarkRect.Right() > rWorkArea.Right()) |
454 | 0 | { |
455 | 0 | nX -= aMarkRect.Right() - rWorkArea.Right(); |
456 | 0 | } |
457 | |
|
458 | 0 | if(aMarkRect.Top() < rWorkArea.Top()) |
459 | 0 | { |
460 | 0 | nY += rWorkArea.Top() - aMarkRect.Top(); |
461 | 0 | } |
462 | |
|
463 | 0 | if(aMarkRect.Bottom() > rWorkArea.Bottom()) |
464 | 0 | { |
465 | 0 | nY -= aMarkRect.Bottom() - rWorkArea.Bottom(); |
466 | 0 | } |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | | // no handle selected |
471 | 0 | if(0 != nX || 0 != nY) |
472 | 0 | { |
473 | 0 | mpView->MoveAllMarked(Size(nX, nY)); |
474 | 0 | } |
475 | 0 | } |
476 | 0 | else |
477 | 0 | { |
478 | | // move handle with index nHandleIndex |
479 | 0 | if (nX || nY) |
480 | 0 | { |
481 | | // now move the Handle (nX, nY) |
482 | 0 | Point aStartPoint(pHdl->GetPos()); |
483 | 0 | Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); |
484 | 0 | const SdrDragStat& rDragStat = mpView->GetDragStat(); |
485 | | |
486 | | // start dragging |
487 | 0 | mpView->BegDragObj(aStartPoint, nullptr, pHdl, 0); |
488 | |
|
489 | 0 | if(mpView->IsDragObj()) |
490 | 0 | { |
491 | 0 | bool bWasNoSnap = rDragStat.IsNoSnap(); |
492 | 0 | bool bWasSnapEnabled = mpView->IsSnapEnabled(); |
493 | | |
494 | | // switch snapping off |
495 | 0 | if(!bWasNoSnap) |
496 | 0 | const_cast<SdrDragStat&>(rDragStat).SetNoSnap(); |
497 | 0 | if(bWasSnapEnabled) |
498 | 0 | mpView->SetSnapEnabled(false); |
499 | |
|
500 | 0 | mpView->MovAction(aEndPoint); |
501 | 0 | mpView->EndDragObj(); |
502 | | |
503 | | // restore snap |
504 | 0 | if(!bWasNoSnap) |
505 | 0 | const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap); |
506 | 0 | if(bWasSnapEnabled) |
507 | 0 | mpView->SetSnapEnabled(bWasSnapEnabled); |
508 | 0 | } |
509 | 0 | } |
510 | 0 | } |
511 | |
|
512 | 0 | bProc = true; |
513 | 0 | } |
514 | 0 | } |
515 | 0 | break; |
516 | | |
517 | 0 | case KEY_SPACE: |
518 | 0 | { |
519 | 0 | const SdrHdlList& rHdlList = mpView->GetHdlList(); |
520 | 0 | SdrHdl* pHdl = rHdlList.GetFocusHdl(); |
521 | |
|
522 | 0 | if(pHdl) |
523 | 0 | { |
524 | 0 | if(pHdl->GetKind() == SdrHdlKind::Poly) |
525 | 0 | { |
526 | | // rescue ID of point with focus |
527 | 0 | sal_uInt32 nPol(pHdl->GetPolyNum()); |
528 | 0 | sal_uInt32 nPnt(pHdl->GetPointNum()); |
529 | |
|
530 | 0 | if(mpView->IsPointMarked(*pHdl)) |
531 | 0 | { |
532 | 0 | if(rKEvt.GetKeyCode().IsShift()) |
533 | 0 | { |
534 | 0 | mpView->UnmarkPoint(*pHdl); |
535 | 0 | } |
536 | 0 | } |
537 | 0 | else |
538 | 0 | { |
539 | 0 | if(!rKEvt.GetKeyCode().IsShift()) |
540 | 0 | { |
541 | 0 | mpView->UnmarkAllPoints(); |
542 | 0 | } |
543 | |
|
544 | 0 | mpView->MarkPoint(*pHdl); |
545 | 0 | } |
546 | |
|
547 | 0 | if(nullptr == rHdlList.GetFocusHdl()) |
548 | 0 | { |
549 | | // restore point with focus |
550 | 0 | SdrHdl* pNewOne = nullptr; |
551 | |
|
552 | 0 | for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a) |
553 | 0 | { |
554 | 0 | SdrHdl* pAct = rHdlList.GetHdl(a); |
555 | |
|
556 | 0 | if(pAct |
557 | 0 | && pAct->GetKind() == SdrHdlKind::Poly |
558 | 0 | && pAct->GetPolyNum() == nPol |
559 | 0 | && pAct->GetPointNum() == nPnt) |
560 | 0 | { |
561 | 0 | pNewOne = pAct; |
562 | 0 | } |
563 | 0 | } |
564 | |
|
565 | 0 | if(pNewOne) |
566 | 0 | { |
567 | 0 | const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne); |
568 | 0 | } |
569 | 0 | } |
570 | |
|
571 | 0 | bProc = true; |
572 | 0 | } |
573 | 0 | } |
574 | 0 | } |
575 | 0 | break; |
576 | | |
577 | 0 | default: |
578 | 0 | break; |
579 | 0 | } |
580 | | |
581 | 0 | if (bProc) |
582 | 0 | ReleaseMouse(); |
583 | |
|
584 | 0 | QueueIdleUpdate(); |
585 | |
|
586 | 0 | return bProc; |
587 | 0 | } |
588 | | |
589 | | bool GraphCtrl::MouseButtonDown( const MouseEvent& rMEvt ) |
590 | 0 | { |
591 | 0 | if ( mbSdrMode && ( rMEvt.GetClicks() < 2 ) ) |
592 | 0 | { |
593 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
594 | |
|
595 | 0 | const Point aLogPt( rDevice.PixelToLogic( rMEvt.GetPosPixel() ) ); |
596 | |
|
597 | 0 | if ( !tools::Rectangle( Point(), maGraphSize ).Contains( aLogPt ) && !mpView->IsEditMode() ) |
598 | 0 | weld::CustomWidgetController::MouseButtonDown( rMEvt ); |
599 | 0 | else |
600 | 0 | { |
601 | | // Get Focus for key inputs |
602 | 0 | GrabFocus(); |
603 | |
|
604 | 0 | if ( mnPolyEdit ) |
605 | 0 | { |
606 | 0 | SdrViewEvent aVEvt; |
607 | 0 | SdrHitKind eHit = mpView->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt ); |
608 | |
|
609 | 0 | if ( mnPolyEdit == SID_BEZIER_INSERT && eHit == SdrHitKind::MarkedObject ) |
610 | 0 | mpView->BegInsObjPoint( aLogPt, rMEvt.IsMod1()); |
611 | 0 | else |
612 | 0 | mpView->MouseButtonDown( rMEvt, &rDevice ); |
613 | 0 | } |
614 | 0 | else |
615 | 0 | mpView->MouseButtonDown( rMEvt, &rDevice ); |
616 | 0 | } |
617 | |
|
618 | 0 | SdrObject* pCreateObj = mpView->GetCreateObj(); |
619 | | |
620 | | // We want to realize the insert |
621 | 0 | if ( pCreateObj && !pCreateObj->GetUserCall() ) |
622 | 0 | pCreateObj->SetUserCall( mpUserCall.get() ); |
623 | |
|
624 | 0 | SetPointer( mpView->GetPreferredPointer( aLogPt, &rDevice ) ); |
625 | 0 | } |
626 | 0 | else |
627 | 0 | weld::CustomWidgetController::MouseButtonDown( rMEvt ); |
628 | |
|
629 | 0 | QueueIdleUpdate(); |
630 | |
|
631 | 0 | return false; |
632 | 0 | } |
633 | | |
634 | | bool GraphCtrl::MouseMove(const MouseEvent& rMEvt) |
635 | 0 | { |
636 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
637 | 0 | const Point aLogPos( rDevice.PixelToLogic( rMEvt.GetPosPixel() ) ); |
638 | |
|
639 | 0 | if ( mbSdrMode ) |
640 | 0 | { |
641 | 0 | mpView->MouseMove( rMEvt, &rDevice ); |
642 | |
|
643 | 0 | if( ( SID_BEZIER_INSERT == mnPolyEdit ) && |
644 | 0 | !mpView->PickHandle( aLogPos ) && |
645 | 0 | !mpView->IsInsObjPoint() ) |
646 | 0 | { |
647 | 0 | SetPointer( PointerStyle::Cross ); |
648 | 0 | } |
649 | 0 | else |
650 | 0 | SetPointer( mpView->GetPreferredPointer( aLogPos, &rDevice ) ); |
651 | 0 | } |
652 | 0 | else |
653 | 0 | weld::CustomWidgetController::MouseButtonUp( rMEvt ); |
654 | |
|
655 | 0 | if ( maMousePosLink.IsSet() ) |
656 | 0 | { |
657 | 0 | if ( tools::Rectangle( Point(), maGraphSize ).Contains( aLogPos ) ) |
658 | 0 | maMousePos = aLogPos; |
659 | 0 | else |
660 | 0 | maMousePos = Point(); |
661 | |
|
662 | 0 | maMousePosLink.Call( this ); |
663 | 0 | } |
664 | |
|
665 | 0 | QueueIdleUpdate(); |
666 | |
|
667 | 0 | return false; |
668 | 0 | } |
669 | | |
670 | | bool GraphCtrl::MouseButtonUp(const MouseEvent& rMEvt) |
671 | 0 | { |
672 | 0 | if ( mbSdrMode ) |
673 | 0 | { |
674 | 0 | OutputDevice& rDevice = GetDrawingArea()->get_ref_device(); |
675 | |
|
676 | 0 | if ( mpView->IsInsObjPoint() ) |
677 | 0 | mpView->EndInsObjPoint( SdrCreateCmd::ForceEnd ); |
678 | 0 | else |
679 | 0 | mpView->MouseButtonUp( rMEvt, &rDevice ); |
680 | |
|
681 | 0 | ReleaseMouse(); |
682 | 0 | SetPointer( mpView->GetPreferredPointer( rDevice.PixelToLogic( rMEvt.GetPosPixel() ), &rDevice ) ); |
683 | 0 | } |
684 | 0 | else |
685 | 0 | weld::CustomWidgetController::MouseButtonUp( rMEvt ); |
686 | |
|
687 | 0 | QueueIdleUpdate(); |
688 | |
|
689 | 0 | return false; |
690 | 0 | } |
691 | | |
692 | | SdrObject* GraphCtrl::GetSelectedSdrObject() const |
693 | 0 | { |
694 | 0 | SdrObject* pSdrObj = nullptr; |
695 | |
|
696 | 0 | if ( mbSdrMode ) |
697 | 0 | { |
698 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
699 | |
|
700 | 0 | if ( rMarkList.GetMarkCount() == 1 ) |
701 | 0 | pSdrObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); |
702 | 0 | } |
703 | |
|
704 | 0 | return pSdrObj; |
705 | 0 | } |
706 | | |
707 | | void GraphCtrl::SetEditMode( const bool _bEditMode ) |
708 | 0 | { |
709 | 0 | if ( mbSdrMode ) |
710 | 0 | { |
711 | 0 | mbEditMode = _bEditMode; |
712 | 0 | mpView->SetEditMode( mbEditMode ); |
713 | 0 | meObjKind = SdrObjKind::NONE; |
714 | 0 | mpView->SetCurrentObj(meObjKind); |
715 | 0 | } |
716 | 0 | else |
717 | 0 | mbEditMode = false; |
718 | |
|
719 | 0 | QueueIdleUpdate(); |
720 | 0 | } |
721 | | |
722 | | void GraphCtrl::SetPolyEditMode( const sal_uInt16 _nPolyEdit ) |
723 | 0 | { |
724 | 0 | if ( mbSdrMode && ( _nPolyEdit != mnPolyEdit ) ) |
725 | 0 | { |
726 | 0 | mnPolyEdit = _nPolyEdit; |
727 | 0 | mpView->SetFrameDragSingles( mnPolyEdit == 0 ); |
728 | 0 | } |
729 | 0 | else |
730 | 0 | mnPolyEdit = 0; |
731 | |
|
732 | 0 | QueueIdleUpdate(); |
733 | 0 | } |
734 | | |
735 | | void GraphCtrl::SetObjKind( const SdrObjKind _eObjKind ) |
736 | 0 | { |
737 | 0 | if ( mbSdrMode ) |
738 | 0 | { |
739 | 0 | mbEditMode = false; |
740 | 0 | mpView->SetEditMode( mbEditMode ); |
741 | 0 | meObjKind = _eObjKind; |
742 | 0 | mpView->SetCurrentObj(meObjKind); |
743 | 0 | } |
744 | 0 | else |
745 | 0 | meObjKind = SdrObjKind::NONE; |
746 | |
|
747 | 0 | QueueIdleUpdate(); |
748 | 0 | } |
749 | | |
750 | | IMPL_LINK_NOARG(GraphCtrl, UpdateHdl, Timer *, void) |
751 | 0 | { |
752 | 0 | mbInIdleUpdate = true; |
753 | 0 | maUpdateLink.Call( this ); |
754 | 0 | mbInIdleUpdate = false; |
755 | 0 | } |
756 | | |
757 | | void GraphCtrl::QueueIdleUpdate() |
758 | 0 | { |
759 | 0 | if (!mbInIdleUpdate) |
760 | 0 | maUpdateIdle.Start(); |
761 | 0 | } |
762 | | |
763 | | namespace |
764 | | { |
765 | | class WeldOverlayManager final : public sdr::overlay::OverlayManager |
766 | | { |
767 | | weld::CustomWidgetController& m_rGraphCtrl; |
768 | | |
769 | | public: |
770 | | WeldOverlayManager(weld::CustomWidgetController& rGraphCtrl, OutputDevice& rDevice) |
771 | 0 | : OverlayManager(rDevice) |
772 | 0 | , m_rGraphCtrl(rGraphCtrl) |
773 | 0 | { |
774 | 0 | } |
775 | | |
776 | | // invalidate the given range at local OutputDevice |
777 | | virtual void invalidateRange(const basegfx::B2DRange& rRange) override |
778 | 0 | { |
779 | 0 | tools::Rectangle aInvalidateRectangle(RangeToInvalidateRectangle(rRange)); |
780 | 0 | m_rGraphCtrl.Invalidate(aInvalidateRectangle); |
781 | 0 | } |
782 | | }; |
783 | | } |
784 | | |
785 | | rtl::Reference<sdr::overlay::OverlayManager> GraphCtrlView::CreateOverlayManager(OutputDevice& rDevice) const |
786 | 0 | { |
787 | 0 | assert(&rDevice == &m_rGraphCtrl.GetDrawingArea()->get_ref_device()); |
788 | 0 | if (rDevice.GetOutDevType() == OUTDEV_VIRDEV) |
789 | 0 | { |
790 | 0 | rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager(new WeldOverlayManager(m_rGraphCtrl, rDevice)); |
791 | 0 | InitOverlayManager(xOverlayManager); |
792 | 0 | return xOverlayManager; |
793 | 0 | } |
794 | 0 | return SdrView::CreateOverlayManager(rDevice); |
795 | 0 | } |
796 | | |
797 | | void GraphCtrlView::InvalidateOneWin(OutputDevice& rDevice) |
798 | 0 | { |
799 | 0 | assert(&rDevice == &m_rGraphCtrl.GetDrawingArea()->get_ref_device()); |
800 | 0 | if (rDevice.GetOutDevType() == OUTDEV_VIRDEV) |
801 | 0 | { |
802 | 0 | m_rGraphCtrl.Invalidate(); |
803 | 0 | return; |
804 | 0 | } |
805 | 0 | SdrView::InvalidateOneWin(rDevice); |
806 | 0 | } |
807 | | |
808 | | void GraphCtrlView::InvalidateOneWin(OutputDevice& rDevice, const tools::Rectangle& rArea) |
809 | 0 | { |
810 | 0 | assert(&rDevice == &m_rGraphCtrl.GetDrawingArea()->get_ref_device()); |
811 | 0 | if (rDevice.GetOutDevType() == OUTDEV_VIRDEV) |
812 | 0 | { |
813 | 0 | m_rGraphCtrl.Invalidate(rArea); |
814 | 0 | return; |
815 | 0 | } |
816 | 0 | SdrView::InvalidateOneWin(rDevice, rArea); |
817 | 0 | } |
818 | | |
819 | | GraphCtrlView::~GraphCtrlView() |
820 | 0 | { |
821 | | // turn SetOutputToWindow back off again before |
822 | | // turning back into our baseclass during dtoring |
823 | 0 | const sal_uInt32 nWindowCount(PaintWindowCount()); |
824 | 0 | for (sal_uInt32 nWinNum(0); nWinNum < nWindowCount; nWinNum++) |
825 | 0 | { |
826 | 0 | SdrPaintWindow* pPaintWindow = GetPaintWindow(nWinNum); |
827 | 0 | pPaintWindow->SetOutputToWindow(false); |
828 | 0 | } |
829 | 0 | } |
830 | | |
831 | | Point GraphCtrl::GetPositionInDialog() const |
832 | 0 | { |
833 | 0 | int x, y, width, height; |
834 | 0 | if (GetDrawingArea()->get_extents_relative_to(*mpDialog, x, y, width, height)) |
835 | 0 | return Point(x, y); |
836 | 0 | return Point(); |
837 | 0 | } |
838 | | |
839 | | rtl::Reference<comphelper::OAccessible> GraphCtrl::CreateAccessible() |
840 | 0 | { |
841 | 0 | #if !ENABLE_WASM_STRIP_ACCESSIBILITY |
842 | 0 | if(mpAccContext == nullptr ) |
843 | 0 | { |
844 | 0 | mpAccContext = new SvxGraphCtrlAccessibleContext(*this); |
845 | 0 | } |
846 | 0 | #endif |
847 | 0 | return mpAccContext; |
848 | 0 | } |
849 | | |
850 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |