/src/libreoffice/chart2/source/controller/main/ChartController_Window.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 <sal/config.h> |
21 | | |
22 | | #include <string_view> |
23 | | |
24 | | #include <ChartController.hxx> |
25 | | #include <ChartView.hxx> |
26 | | #include <PositionAndSizeHelper.hxx> |
27 | | #include <ObjectIdentifier.hxx> |
28 | | #include <ChartWindow.hxx> |
29 | | #include <ResId.hxx> |
30 | | #include <ChartModel.hxx> |
31 | | #include <ChartType.hxx> |
32 | | #include <DiagramHelper.hxx> |
33 | | #include <Diagram.hxx> |
34 | | #include <TitleHelper.hxx> |
35 | | #include "UndoGuard.hxx" |
36 | | #include <ControllerLockGuard.hxx> |
37 | | #include <ObjectNameProvider.hxx> |
38 | | #include <strings.hrc> |
39 | | #include "DragMethod_PieSegment.hxx" |
40 | | #include "DragMethod_RotateDiagram.hxx" |
41 | | #include <ObjectHierarchy.hxx> |
42 | | #include <RelativePositionHelper.hxx> |
43 | | #include <chartview/DrawModelWrapper.hxx> |
44 | | #include <RegressionCurveHelper.hxx> |
45 | | #include <RegressionCurveModel.hxx> |
46 | | #include <StatisticsHelper.hxx> |
47 | | #include <DataSeries.hxx> |
48 | | #include <DataSeriesProperties.hxx> |
49 | | #include <Axis.hxx> |
50 | | #include <AxisHelper.hxx> |
51 | | #include <LegendHelper.hxx> |
52 | | #include <servicenames_charttypes.hxx> |
53 | | #include "DrawCommandDispatch.hxx" |
54 | | #include <PopupRequest.hxx> |
55 | | #include <ControllerCommandDispatch.hxx> |
56 | | |
57 | | #include <com/sun/star/chart2/RelativePosition.hpp> |
58 | | #include <com/sun/star/chart2/RelativeSize.hpp> |
59 | | |
60 | | #include <com/sun/star/awt/PopupMenuDirection.hpp> |
61 | | #include <com/sun/star/frame/DispatchHelper.hpp> |
62 | | #include <com/sun/star/frame/FrameSearchFlag.hpp> |
63 | | #include <com/sun/star/frame/XPopupMenuController.hpp> |
64 | | #include <com/sun/star/awt/Rectangle.hpp> |
65 | | |
66 | | #include <chart2/AbstractPivotTableDataProvider.hxx> |
67 | | #include <comphelper/lok.hxx> |
68 | | #include <comphelper/propertysequence.hxx> |
69 | | #include <comphelper/propertyvalue.hxx> |
70 | | |
71 | | #include <sfx2/viewsh.hxx> |
72 | | #include <svx/ActionDescriptionProvider.hxx> |
73 | | #include <svx/obj3d.hxx> |
74 | | #include <svx/scene3d.hxx> |
75 | | #include <svx/svddrgmt.hxx> |
76 | | #include <vcl/commandevent.hxx> |
77 | | #include <vcl/event.hxx> |
78 | | #include <vcl/svapp.hxx> |
79 | | #include <vcl/settings.hxx> |
80 | | #include <vcl/weld/MessageDialog.hxx> |
81 | | #include <vcl/weld/weld.hxx> |
82 | | #include <vcl/ptrstyle.hxx> |
83 | | #include <svtools/acceleratorexecute.hxx> |
84 | | #include <comphelper/diagnose_ex.hxx> |
85 | | #include <toolkit/awt/vclxmenu.hxx> |
86 | | #include <sal/log.hxx> |
87 | | #include <o3tl/string_view.hxx> |
88 | | |
89 | | #include <boost/property_tree/json_parser.hpp> |
90 | | #include <sfx2/dispatch.hxx> |
91 | | #include <LibreOfficeKit/LibreOfficeKitEnums.h> |
92 | | |
93 | 0 | #define DRGPIX 2 // Drag MinMove in Pixel |
94 | | |
95 | | using namespace ::com::sun::star; |
96 | | using namespace ::com::sun::star::chart2; |
97 | | using namespace ::chart::DataSeriesProperties; |
98 | | using ::com::sun::star::uno::Reference; |
99 | | |
100 | | namespace chart |
101 | | { |
102 | | |
103 | | namespace |
104 | | { |
105 | | bool lcl_GrowAndShiftLogic( |
106 | | RelativePosition & rInOutRelPos, |
107 | | RelativeSize & rInOutRelSize, |
108 | | const awt::Size & rRefSize, |
109 | | double fGrowLogicX, |
110 | | double fGrowLogicY ) |
111 | 0 | { |
112 | 0 | if( rRefSize.Width == 0 || |
113 | 0 | rRefSize.Height == 0 ) |
114 | 0 | return false; |
115 | | |
116 | 0 | double fRelativeGrowX = fGrowLogicX / rRefSize.Width; |
117 | 0 | double fRelativeGrowY = fGrowLogicY / rRefSize.Height; |
118 | |
|
119 | 0 | return ::chart::RelativePositionHelper::centerGrow( |
120 | 0 | rInOutRelPos, rInOutRelSize, |
121 | 0 | fRelativeGrowX, fRelativeGrowY ); |
122 | 0 | } |
123 | | |
124 | | bool lcl_MoveObjectLogic( |
125 | | RelativePosition & rInOutRelPos, |
126 | | RelativeSize const & rObjectSize, |
127 | | const awt::Size & rRefSize, |
128 | | double fShiftLogicX, |
129 | | double fShiftLogicY ) |
130 | 0 | { |
131 | 0 | if( rRefSize.Width == 0 || |
132 | 0 | rRefSize.Height == 0 ) |
133 | 0 | return false; |
134 | | |
135 | 0 | double fRelativeShiftX = fShiftLogicX / rRefSize.Width; |
136 | 0 | double fRelativeShiftY = fShiftLogicY / rRefSize.Height; |
137 | |
|
138 | 0 | return ::chart::RelativePositionHelper::moveObject( |
139 | 0 | rInOutRelPos, rObjectSize, |
140 | 0 | fRelativeShiftX, fRelativeShiftY ); |
141 | 0 | } |
142 | | |
143 | | void lcl_insertMenuCommand( |
144 | | const uno::Reference< awt::XPopupMenu > & xMenu, |
145 | | sal_Int16 nId, const OUString & rCommand ) |
146 | 0 | { |
147 | 0 | xMenu->insertItem( nId, u""_ustr, 0, -1 ); |
148 | 0 | xMenu->setCommand( nId, rCommand ); |
149 | 0 | } |
150 | | |
151 | | OUString lcl_getFormatCommandForObjectCID( std::u16string_view rCID ) |
152 | 0 | { |
153 | 0 | OUString aDispatchCommand( u".uno:FormatSelection"_ustr ); |
154 | |
|
155 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID ); |
156 | |
|
157 | 0 | switch(eObjectType) |
158 | 0 | { |
159 | 0 | case OBJECTTYPE_DIAGRAM: |
160 | 0 | case OBJECTTYPE_DIAGRAM_WALL: |
161 | 0 | aDispatchCommand = ".uno:FormatWall"; |
162 | 0 | break; |
163 | 0 | case OBJECTTYPE_DIAGRAM_FLOOR: |
164 | 0 | aDispatchCommand = ".uno:FormatFloor"; |
165 | 0 | break; |
166 | 0 | case OBJECTTYPE_PAGE: |
167 | 0 | aDispatchCommand = ".uno:FormatChartArea"; |
168 | 0 | break; |
169 | 0 | case OBJECTTYPE_LEGEND: |
170 | 0 | aDispatchCommand = ".uno:FormatLegend"; |
171 | 0 | break; |
172 | 0 | case OBJECTTYPE_TITLE: |
173 | 0 | aDispatchCommand = ".uno:FormatTitle"; |
174 | 0 | break; |
175 | 0 | case OBJECTTYPE_LEGEND_ENTRY: |
176 | 0 | case OBJECTTYPE_DATA_SERIES: |
177 | 0 | aDispatchCommand = ".uno:FormatDataSeries"; |
178 | 0 | break; |
179 | 0 | case OBJECTTYPE_AXIS: |
180 | 0 | case OBJECTTYPE_AXIS_UNITLABEL: |
181 | 0 | aDispatchCommand = ".uno:FormatAxis"; |
182 | 0 | break; |
183 | 0 | case OBJECTTYPE_GRID: |
184 | 0 | aDispatchCommand = ".uno:FormatMajorGrid"; |
185 | 0 | break; |
186 | 0 | case OBJECTTYPE_SUBGRID: |
187 | 0 | aDispatchCommand = ".uno:FormatMinorGrid"; |
188 | 0 | break; |
189 | 0 | case OBJECTTYPE_DATA_LABELS: |
190 | 0 | aDispatchCommand = ".uno:FormatDataLabels"; |
191 | 0 | break; |
192 | 0 | case OBJECTTYPE_DATA_LABEL: |
193 | 0 | aDispatchCommand = ".uno:FormatDataLabel"; |
194 | 0 | break; |
195 | 0 | case OBJECTTYPE_DATA_POINT: |
196 | 0 | aDispatchCommand = ".uno:FormatDataPoint"; |
197 | 0 | break; |
198 | 0 | case OBJECTTYPE_DATA_AVERAGE_LINE: |
199 | 0 | aDispatchCommand = ".uno:FormatMeanValue"; |
200 | 0 | break; |
201 | 0 | case OBJECTTYPE_DATA_ERRORS_X: |
202 | 0 | aDispatchCommand = ".uno:FormatXErrorBars"; |
203 | 0 | break; |
204 | 0 | case OBJECTTYPE_DATA_ERRORS_Y: |
205 | 0 | aDispatchCommand = ".uno:FormatYErrorBars"; |
206 | 0 | break; |
207 | 0 | case OBJECTTYPE_DATA_ERRORS_Z: |
208 | 0 | aDispatchCommand = ".uno:FormatZErrorBars"; |
209 | 0 | break; |
210 | 0 | case OBJECTTYPE_DATA_CURVE: |
211 | 0 | aDispatchCommand = ".uno:FormatTrendline"; |
212 | 0 | break; |
213 | 0 | case OBJECTTYPE_DATA_CURVE_EQUATION: |
214 | 0 | aDispatchCommand = ".uno:FormatTrendlineEquation"; |
215 | 0 | break; |
216 | 0 | case OBJECTTYPE_DATA_STOCK_RANGE: |
217 | 0 | aDispatchCommand = ".uno:FormatSelection"; |
218 | 0 | break; |
219 | 0 | case OBJECTTYPE_DATA_STOCK_LOSS: |
220 | 0 | aDispatchCommand = ".uno:FormatStockLoss"; |
221 | 0 | break; |
222 | 0 | case OBJECTTYPE_DATA_STOCK_GAIN: |
223 | 0 | aDispatchCommand = ".uno:FormatStockGain"; |
224 | 0 | break; |
225 | 0 | default: //OBJECTTYPE_UNKNOWN |
226 | 0 | break; |
227 | 0 | } |
228 | 0 | return aDispatchCommand; |
229 | 0 | } |
230 | | |
231 | | } // anonymous namespace |
232 | | |
233 | | // awt::XWindow |
234 | | void SAL_CALL ChartController::setPosSize( |
235 | | sal_Int32 X, |
236 | | sal_Int32 Y, |
237 | | sal_Int32 Width, |
238 | | sal_Int32 Height, |
239 | | sal_Int16 Flags ) |
240 | 0 | { |
241 | 0 | SolarMutexGuard aGuard; |
242 | 0 | auto pChartWindow(GetChartWindow()); |
243 | |
|
244 | 0 | if(!(m_xViewWindow.is() && pChartWindow)) |
245 | 0 | return; |
246 | | |
247 | 0 | Size aLogicSize = pChartWindow->PixelToLogic( Size( Width, Height ), MapMode( MapUnit::Map100thMM ) ); |
248 | | |
249 | | //todo: for standalone chart: detect whether we are standalone |
250 | | //change map mode to fit new size |
251 | 0 | awt::Size aModelPageSize = getChartModel()->getPageSize(); |
252 | 0 | double fScaleX = double(aLogicSize.Width()) / aModelPageSize.Width; |
253 | 0 | double fScaleY = double(aLogicSize.Height()) / aModelPageSize.Height; |
254 | 0 | MapMode aNewMapMode( |
255 | 0 | MapUnit::Map100thMM, |
256 | 0 | Point(0,0), |
257 | 0 | fScaleX, |
258 | 0 | fScaleY ); |
259 | 0 | pChartWindow->SetMapMode(aNewMapMode); |
260 | 0 | pChartWindow->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) ); |
261 | | |
262 | | //#i75867# poor quality of ole's alternative view with 3D scenes and zoomfactors besides 100% |
263 | 0 | if( m_xChartView.is() ) |
264 | 0 | { |
265 | 0 | Fraction aScaleXFrac(fScaleX); |
266 | 0 | Fraction aScaleYFrac(fScaleY); |
267 | 0 | auto aZoomFactors(::comphelper::InitPropertySequence({ |
268 | 0 | { "ScaleXNumerator", uno::Any( aScaleXFrac.GetNumerator() ) }, |
269 | 0 | { "ScaleXDenominator", uno::Any( aScaleXFrac.GetDenominator() ) }, |
270 | 0 | { "ScaleYNumerator", uno::Any( aScaleYFrac.GetNumerator() ) }, |
271 | 0 | { "ScaleYDenominator", uno::Any( aScaleYFrac.GetDenominator() ) } |
272 | 0 | })); |
273 | 0 | m_xChartView->setPropertyValue( u"ZoomFactors"_ustr, uno::Any( aZoomFactors )); |
274 | 0 | } |
275 | | |
276 | | //a correct work area is at least necessary for correct values in the position and size dialog and for dragging area |
277 | 0 | if(m_pDrawViewWrapper) |
278 | 0 | { |
279 | 0 | tools::Rectangle aRect(Point(0,0), pChartWindow->GetOutDev()->GetOutputSize()); |
280 | 0 | m_pDrawViewWrapper->SetWorkArea( aRect ); |
281 | 0 | } |
282 | 0 | pChartWindow->Invalidate(); |
283 | 0 | } |
284 | | |
285 | | awt::Rectangle SAL_CALL ChartController::getPosSize() |
286 | 0 | { |
287 | 0 | awt::Rectangle aRet(0, 0, 0, 0); |
288 | |
|
289 | 0 | if (m_xViewWindow.is()) |
290 | 0 | aRet = m_xViewWindow->getPosSize(); |
291 | |
|
292 | 0 | return aRet; |
293 | 0 | } |
294 | | |
295 | | void SAL_CALL ChartController::setVisible( sal_Bool Visible ) |
296 | 0 | { |
297 | 0 | if (m_xViewWindow.is()) |
298 | 0 | m_xViewWindow->setVisible(Visible); |
299 | 0 | } |
300 | | |
301 | | void SAL_CALL ChartController::setEnable( sal_Bool Enable ) |
302 | 0 | { |
303 | 0 | if (m_xViewWindow.is()) |
304 | 0 | m_xViewWindow->setEnable(Enable); |
305 | 0 | } |
306 | | |
307 | | void SAL_CALL ChartController::setFocus() |
308 | 0 | { |
309 | 0 | if (m_xViewWindow.is()) |
310 | 0 | m_xViewWindow->setFocus(); |
311 | 0 | } |
312 | | |
313 | | void SAL_CALL ChartController::addWindowListener( |
314 | | const uno::Reference< awt::XWindowListener >& xListener ) |
315 | 0 | { |
316 | 0 | if (m_xViewWindow.is()) |
317 | 0 | m_xViewWindow->addWindowListener(xListener); |
318 | 0 | } |
319 | | |
320 | | void SAL_CALL ChartController::removeWindowListener( |
321 | | const uno::Reference< awt::XWindowListener >& xListener ) |
322 | 0 | { |
323 | 0 | if (m_xViewWindow.is()) |
324 | 0 | m_xViewWindow->removeWindowListener(xListener); |
325 | 0 | } |
326 | | |
327 | | void SAL_CALL ChartController::addFocusListener( |
328 | | const uno::Reference< awt::XFocusListener >& xListener ) |
329 | 0 | { |
330 | 0 | if (m_xViewWindow.is()) |
331 | 0 | m_xViewWindow->addFocusListener(xListener); |
332 | 0 | } |
333 | | |
334 | | void SAL_CALL ChartController::removeFocusListener( |
335 | | const uno::Reference< awt::XFocusListener >& xListener ) |
336 | 0 | { |
337 | 0 | if (m_xViewWindow.is()) |
338 | 0 | m_xViewWindow->removeFocusListener(xListener); |
339 | 0 | } |
340 | | |
341 | | void SAL_CALL ChartController::addKeyListener( |
342 | | const uno::Reference< awt::XKeyListener >& xListener ) |
343 | 0 | { |
344 | 0 | if (m_xViewWindow.is()) |
345 | 0 | m_xViewWindow->addKeyListener(xListener); |
346 | 0 | } |
347 | | |
348 | | void SAL_CALL ChartController::removeKeyListener( |
349 | | const uno::Reference< awt::XKeyListener >& xListener ) |
350 | 0 | { |
351 | 0 | if (m_xViewWindow.is()) |
352 | 0 | m_xViewWindow->removeKeyListener(xListener); |
353 | 0 | } |
354 | | |
355 | | void SAL_CALL ChartController::addMouseListener( |
356 | | const uno::Reference< awt::XMouseListener >& xListener ) |
357 | 0 | { |
358 | 0 | if (m_xViewWindow.is()) |
359 | 0 | m_xViewWindow->addMouseListener(xListener); |
360 | 0 | } |
361 | | |
362 | | void SAL_CALL ChartController::removeMouseListener( |
363 | | const uno::Reference< awt::XMouseListener >& xListener ) |
364 | 0 | { |
365 | 0 | if (m_xViewWindow.is()) |
366 | 0 | m_xViewWindow->removeMouseListener(xListener); |
367 | 0 | } |
368 | | |
369 | | void SAL_CALL ChartController::addMouseMotionListener( |
370 | | const uno::Reference< awt::XMouseMotionListener >& xListener ) |
371 | 0 | { |
372 | 0 | if (m_xViewWindow.is()) |
373 | 0 | m_xViewWindow->addMouseMotionListener(xListener); |
374 | 0 | } |
375 | | |
376 | | void SAL_CALL ChartController::removeMouseMotionListener( |
377 | | const uno::Reference< awt::XMouseMotionListener >& xListener ) |
378 | 0 | { |
379 | 0 | if (m_xViewWindow.is()) |
380 | 0 | m_xViewWindow->removeMouseMotionListener(xListener); |
381 | 0 | } |
382 | | |
383 | | void SAL_CALL ChartController::addPaintListener( |
384 | | const uno::Reference< awt::XPaintListener >& xListener ) |
385 | 0 | { |
386 | 0 | if (m_xViewWindow.is()) |
387 | 0 | m_xViewWindow->addPaintListener(xListener); |
388 | 0 | } |
389 | | |
390 | | void SAL_CALL ChartController::removePaintListener( |
391 | | const uno::Reference< awt::XPaintListener >& xListener ) |
392 | 0 | { |
393 | 0 | if (m_xViewWindow.is()) |
394 | 0 | m_xViewWindow->removePaintListener(xListener); |
395 | 0 | } |
396 | | |
397 | | // impl vcl window controller methods |
398 | | void ChartController::PrePaint() |
399 | 0 | { |
400 | | // forward VCLs PrePaint window event to DrawingLayer |
401 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
402 | |
|
403 | 0 | if (pDrawViewWrapper) |
404 | 0 | { |
405 | 0 | pDrawViewWrapper->PrePaint(); |
406 | 0 | } |
407 | 0 | } |
408 | | |
409 | | void ChartController::execute_Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) |
410 | 0 | { |
411 | 0 | try |
412 | 0 | { |
413 | 0 | rtl::Reference<ChartModel> xModel(getChartModel()); |
414 | | //OSL_ENSURE( xModel.is(), "ChartController::execute_Paint: have no model to paint"); |
415 | 0 | if (!xModel.is()) |
416 | 0 | return; |
417 | | |
418 | | //better performance for big data |
419 | 0 | if (m_xChartView.is()) |
420 | 0 | { |
421 | 0 | awt::Size aResolution(1000, 1000); |
422 | 0 | { |
423 | 0 | SolarMutexGuard aGuard; |
424 | 0 | auto pChartWindow(GetChartWindow()); |
425 | 0 | if (pChartWindow) |
426 | 0 | { |
427 | 0 | aResolution.Width = pChartWindow->GetSizePixel().Width(); |
428 | 0 | aResolution.Height = pChartWindow->GetSizePixel().Height(); |
429 | 0 | } |
430 | 0 | } |
431 | 0 | m_xChartView->setPropertyValue( u"Resolution"_ustr, uno::Any( aResolution )); |
432 | 0 | } |
433 | |
|
434 | 0 | if (m_xChartView.is()) |
435 | 0 | m_xChartView->update(); |
436 | |
|
437 | 0 | { |
438 | 0 | SolarMutexGuard aGuard; |
439 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
440 | 0 | if (pDrawViewWrapper) |
441 | 0 | pDrawViewWrapper->CompleteRedraw(&rRenderContext, vcl::Region(rRect)); |
442 | 0 | } |
443 | 0 | } |
444 | 0 | catch( const uno::Exception & ) |
445 | 0 | { |
446 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
447 | 0 | } |
448 | 0 | catch( ... ) |
449 | 0 | { |
450 | 0 | } |
451 | 0 | } |
452 | | |
453 | | static bool isDoubleClick( const MouseEvent& rMEvt ) |
454 | 0 | { |
455 | 0 | return rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && |
456 | 0 | !rMEvt.IsMod1() && !rMEvt.IsMod2() && !rMEvt.IsShift(); |
457 | 0 | } |
458 | | |
459 | | void ChartController::startDoubleClickWaiting() |
460 | 0 | { |
461 | 0 | SolarMutexGuard aGuard; |
462 | |
|
463 | 0 | m_bWaitingForDoubleClick = true; |
464 | |
|
465 | 0 | sal_uInt64 nDblClkTime = 500; |
466 | 0 | auto pChartWindow(GetChartWindow()); |
467 | 0 | if( pChartWindow ) |
468 | 0 | { |
469 | 0 | const MouseSettings& rMSettings = pChartWindow->GetSettings().GetMouseSettings(); |
470 | 0 | nDblClkTime = rMSettings.GetDoubleClickTime(); |
471 | 0 | } |
472 | 0 | m_aDoubleClickTimer.SetTimeout( nDblClkTime ); |
473 | 0 | m_aDoubleClickTimer.Start(); |
474 | 0 | } |
475 | | |
476 | | void ChartController::stopDoubleClickWaiting() |
477 | 0 | { |
478 | 0 | m_aDoubleClickTimer.Stop(); |
479 | 0 | m_bWaitingForDoubleClick = false; |
480 | 0 | } |
481 | | |
482 | | IMPL_LINK_NOARG(ChartController, DoubleClickWaitingHdl, Timer *, void) |
483 | 0 | { |
484 | 0 | m_bWaitingForDoubleClick = false; |
485 | |
|
486 | 0 | if( m_bWaitingForMouseUp || !m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() ) |
487 | 0 | return; |
488 | | |
489 | 0 | impl_selectObjectAndNotiy(); |
490 | 0 | SolarMutexGuard aGuard; |
491 | 0 | auto pChartWindow(GetChartWindow()); |
492 | 0 | if( pChartWindow ) |
493 | 0 | { |
494 | 0 | vcl::Window::PointerState aPointerState( pChartWindow->GetPointerState() ); |
495 | 0 | MouseEvent aMouseEvent( |
496 | 0 | aPointerState.maPos, |
497 | 0 | 1/*nClicks*/, |
498 | 0 | MouseEventModifiers::NONE, |
499 | 0 | static_cast< sal_uInt16 >( aPointerState.mnState )/*nButtons*/, |
500 | 0 | 0/*nModifier*/ ); |
501 | 0 | impl_SetMousePointer( aMouseEvent ); |
502 | 0 | } |
503 | 0 | } |
504 | | |
505 | | void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) |
506 | 0 | { |
507 | 0 | SolarMutexGuard aGuard; |
508 | |
|
509 | 0 | m_bWaitingForMouseUp = true; |
510 | 0 | m_bFieldButtonDown = false; |
511 | |
|
512 | 0 | if( isDoubleClick(rMEvt) ) |
513 | 0 | stopDoubleClickWaiting(); |
514 | 0 | else |
515 | 0 | startDoubleClickWaiting(); |
516 | |
|
517 | 0 | m_aSelection.remindSelectionBeforeMouseDown(); |
518 | |
|
519 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
520 | 0 | auto pChartWindow(GetChartWindow()); |
521 | 0 | if(!pChartWindow || !pDrawViewWrapper ) |
522 | 0 | return; |
523 | | |
524 | 0 | Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel()); |
525 | | |
526 | | // Check if button was clicked |
527 | 0 | SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos); |
528 | 0 | if (pObject) |
529 | 0 | { |
530 | 0 | OUString aCID = pObject->GetName(); |
531 | 0 | if (aCID.startsWith("FieldButton")) |
532 | 0 | { |
533 | 0 | m_bFieldButtonDown = true; |
534 | 0 | return; // Don't take any action if button was clicked |
535 | 0 | } |
536 | 0 | } |
537 | | |
538 | 0 | if ( rMEvt.GetButtons() == MOUSE_LEFT ) |
539 | 0 | { |
540 | 0 | pChartWindow->GrabFocus(); |
541 | 0 | pChartWindow->CaptureMouse(); |
542 | 0 | } |
543 | |
|
544 | 0 | if( pDrawViewWrapper->IsTextEdit() ) |
545 | 0 | { |
546 | 0 | SdrViewEvent aVEvt; |
547 | 0 | if ( pDrawViewWrapper->IsTextEditHit( aMPos ) || |
548 | | // #i12587# support for shapes in chart |
549 | 0 | ( rMEvt.IsRight() && pDrawViewWrapper->PickAnything( rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt ) == SdrHitKind::MarkedObject ) ) |
550 | 0 | { |
551 | 0 | pDrawViewWrapper->MouseButtonDown(rMEvt, pChartWindow->GetOutDev()); |
552 | 0 | return; |
553 | 0 | } |
554 | 0 | else |
555 | 0 | { |
556 | 0 | EndTextEdit(); |
557 | 0 | } |
558 | 0 | } |
559 | | |
560 | | //abort running action |
561 | 0 | if( pDrawViewWrapper->IsAction() ) |
562 | 0 | { |
563 | 0 | if( rMEvt.IsRight() ) |
564 | 0 | pDrawViewWrapper->BckAction(); |
565 | 0 | return; |
566 | 0 | } |
567 | | |
568 | 0 | if( isDoubleClick(rMEvt) ) //do not change selection if double click |
569 | 0 | return;//double click is handled further in mousebutton up |
570 | | |
571 | 0 | SdrHdl* pHitSelectionHdl = nullptr; |
572 | | //switch from move to resize if handle is hit on a resizable object |
573 | 0 | if( m_aSelection.isResizeableObjectSelected() ) |
574 | 0 | pHitSelectionHdl = pDrawViewWrapper->PickHandle( aMPos ); |
575 | | //only change selection if no selection handles are hit |
576 | 0 | if( !pHitSelectionHdl ) |
577 | 0 | { |
578 | | // #i12587# support for shapes in chart |
579 | 0 | if ( m_eDrawMode == CHARTDRAW_INSERT && |
580 | 0 | ( !pDrawViewWrapper->IsMarkedHit( aMPos ) || !m_aSelection.isDragableObjectSelected() ) ) |
581 | 0 | { |
582 | 0 | if ( m_aSelection.hasSelection() ) |
583 | 0 | { |
584 | 0 | m_aSelection.clearSelection(); |
585 | 0 | } |
586 | 0 | if ( !pDrawViewWrapper->IsAction() ) |
587 | 0 | { |
588 | 0 | if ( pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::Caption ) |
589 | 0 | { |
590 | 0 | Size aCaptionSize( 2268, 1134 ); |
591 | 0 | pDrawViewWrapper->BegCreateCaptionObj( aMPos, aCaptionSize ); |
592 | 0 | } |
593 | 0 | else |
594 | 0 | { |
595 | 0 | pDrawViewWrapper->BegCreateObj( aMPos); |
596 | 0 | } |
597 | 0 | SdrObject* pObj = pDrawViewWrapper->GetCreateObj(); |
598 | 0 | DrawCommandDispatch* pDrawCommandDispatch = m_aDispatchContainer.getDrawCommandDispatch(); |
599 | 0 | if ( pObj && m_pDrawModelWrapper && pDrawCommandDispatch ) |
600 | 0 | { |
601 | 0 | SfxItemSet aSet( m_pDrawModelWrapper->GetItemPool() ); |
602 | 0 | pDrawCommandDispatch->setAttributes( pObj ); |
603 | 0 | pDrawCommandDispatch->setLineEnds( aSet ); |
604 | 0 | pObj->SetMergedItemSet( aSet ); |
605 | 0 | } |
606 | 0 | } |
607 | 0 | impl_SetMousePointer( rMEvt ); |
608 | 0 | return; |
609 | 0 | } |
610 | | |
611 | 0 | m_aSelection.adaptSelectionToNewPos( |
612 | 0 | aMPos, |
613 | 0 | pDrawViewWrapper, |
614 | 0 | rMEvt.IsRight(), |
615 | 0 | m_bWaitingForDoubleClick ); |
616 | |
|
617 | 0 | if( !m_aSelection.isRotateableObjectSelected( getChartModel() ) ) |
618 | 0 | { |
619 | 0 | m_eDragMode = SdrDragMode::Move; |
620 | 0 | pDrawViewWrapper->SetDragMode(m_eDragMode); |
621 | 0 | } |
622 | |
|
623 | 0 | m_aSelection.applySelection(pDrawViewWrapper); |
624 | 0 | } |
625 | 0 | if( m_aSelection.isDragableObjectSelected() |
626 | 0 | && !rMEvt.IsRight() ) |
627 | 0 | { |
628 | | //start drag |
629 | 0 | sal_uInt16 nDrgLog = static_cast<sal_uInt16>(pChartWindow->PixelToLogic(Size(DRGPIX,0)).Width()); |
630 | 0 | SdrDragMethod* pDragMethod = nullptr; |
631 | | |
632 | | //change selection to 3D scene if rotate mode |
633 | 0 | SdrDragMode eDragMode = pDrawViewWrapper->GetDragMode(); |
634 | 0 | if( eDragMode==SdrDragMode::Rotate ) |
635 | 0 | { |
636 | 0 | E3dScene* pScene = SelectionHelper::getSceneToRotate( pDrawViewWrapper->getNamedSdrObject( m_aSelection.getSelectedCID() ) ); |
637 | 0 | if( pScene ) |
638 | 0 | { |
639 | 0 | DragMethod_RotateDiagram::RotationDirection eRotationDirection(DragMethod_RotateDiagram::ROTATIONDIRECTION_FREE); |
640 | 0 | if(pHitSelectionHdl) |
641 | 0 | { |
642 | 0 | SdrHdlKind eKind = pHitSelectionHdl->GetKind(); |
643 | 0 | if( eKind==SdrHdlKind::Upper || eKind==SdrHdlKind::Lower ) |
644 | 0 | eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_X; |
645 | 0 | else if( eKind==SdrHdlKind::Left || eKind==SdrHdlKind::Right ) |
646 | 0 | eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Y; |
647 | 0 | else if( eKind==SdrHdlKind::UpperLeft || eKind==SdrHdlKind::UpperRight || eKind==SdrHdlKind::LowerLeft || eKind==SdrHdlKind::LowerRight ) |
648 | 0 | eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z; |
649 | 0 | } |
650 | 0 | pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getChartModel(), eRotationDirection ); |
651 | 0 | } |
652 | 0 | } |
653 | 0 | else |
654 | 0 | { |
655 | 0 | std::u16string_view aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) ); |
656 | 0 | if( aDragMethodServiceName == ObjectIdentifier::getPieSegmentDragMethodServiceName() ) |
657 | 0 | pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getChartModel() ); |
658 | 0 | } |
659 | 0 | pDrawViewWrapper->SdrView::BegDragObj(aMPos, nullptr, pHitSelectionHdl, nDrgLog, pDragMethod); |
660 | 0 | } |
661 | |
|
662 | 0 | impl_SetMousePointer( rMEvt ); |
663 | 0 | } |
664 | | |
665 | | void ChartController::execute_MouseMove( const MouseEvent& rMEvt ) |
666 | 0 | { |
667 | 0 | SolarMutexGuard aGuard; |
668 | |
|
669 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
670 | 0 | auto pChartWindow(GetChartWindow()); |
671 | 0 | if(!pChartWindow || !pDrawViewWrapper) |
672 | 0 | return; |
673 | | |
674 | 0 | if( m_pDrawViewWrapper->IsTextEdit() ) |
675 | 0 | { |
676 | 0 | if( m_pDrawViewWrapper->MouseMove(rMEvt,pChartWindow->GetOutDev()) ) |
677 | 0 | return; |
678 | 0 | } |
679 | | |
680 | 0 | if(pDrawViewWrapper->IsAction()) |
681 | 0 | { |
682 | 0 | pDrawViewWrapper->MovAction( pChartWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); |
683 | 0 | } |
684 | |
|
685 | 0 | impl_SetMousePointer( rMEvt ); |
686 | 0 | } |
687 | | |
688 | | void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) |
689 | 0 | { |
690 | 0 | ControllerLockGuardUNO aCLGuard( getChartModel() ); |
691 | 0 | bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp; |
692 | 0 | m_bWaitingForMouseUp = false; |
693 | 0 | bool bNotifySelectionChange = false; |
694 | 0 | bool bEditText = false; |
695 | 0 | { |
696 | 0 | SolarMutexGuard aGuard; |
697 | |
|
698 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
699 | 0 | auto pChartWindow(GetChartWindow()); |
700 | 0 | if(!pChartWindow || !pDrawViewWrapper) |
701 | 0 | return; |
702 | | |
703 | 0 | Point aMPos = pChartWindow->PixelToLogic(rMEvt.GetPosPixel()); |
704 | | |
705 | | // Check if button was clicked |
706 | 0 | if (m_bFieldButtonDown) |
707 | 0 | { |
708 | 0 | m_bFieldButtonDown = false; |
709 | 0 | SdrObject* pObject = pDrawViewWrapper->getHitObject(aMPos); |
710 | 0 | if (pObject) |
711 | 0 | { |
712 | 0 | OUString aCID = pObject->GetName(); |
713 | 0 | if (aCID.startsWith("FieldButton")) |
714 | 0 | { |
715 | 0 | sendPopupRequest(aCID, pObject->GetCurrentBoundRect()); |
716 | 0 | return; |
717 | 0 | } |
718 | 0 | } |
719 | 0 | } |
720 | | |
721 | 0 | if(pDrawViewWrapper->IsTextEdit()) |
722 | 0 | { |
723 | 0 | if( pDrawViewWrapper->MouseButtonUp(rMEvt,pChartWindow->GetOutDev()) ) |
724 | 0 | return; |
725 | 0 | } |
726 | | |
727 | | // #i12587# support for shapes in chart |
728 | 0 | if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() ) |
729 | 0 | { |
730 | 0 | pDrawViewWrapper->EndCreateObj( SdrCreateCmd::ForceEnd ); |
731 | 0 | { |
732 | 0 | HiddenUndoContext aUndoContext( m_xUndoManager ); |
733 | | // don't want the positioning Undo action to appear in the UI |
734 | 0 | impl_switchDiagramPositioningToExcludingPositioning(); |
735 | 0 | } |
736 | 0 | if ( pDrawViewWrapper->GetMarkedObjectList().GetMarkCount() != 0 ) |
737 | 0 | { |
738 | 0 | if ( pDrawViewWrapper->GetCurrentObjIdentifier() == SdrObjKind::Text ) |
739 | 0 | { |
740 | 0 | executeDispatch_EditText(); |
741 | 0 | } |
742 | 0 | else |
743 | 0 | { |
744 | 0 | SdrObject* pObj = pDrawViewWrapper->getSelectedObject(); |
745 | 0 | if ( pObj ) |
746 | 0 | { |
747 | 0 | uno::Reference< drawing::XShape > xShape( pObj->getUnoShape(), uno::UNO_QUERY ); |
748 | 0 | if ( xShape.is() ) |
749 | 0 | { |
750 | 0 | m_aSelection.setSelection( xShape ); |
751 | 0 | m_aSelection.applySelection( pDrawViewWrapper ); |
752 | 0 | } |
753 | 0 | } |
754 | 0 | } |
755 | 0 | } |
756 | 0 | else |
757 | 0 | { |
758 | 0 | m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper, rMEvt.IsRight(), m_bWaitingForDoubleClick ); |
759 | 0 | m_aSelection.applySelection( pDrawViewWrapper ); |
760 | 0 | setDrawMode( CHARTDRAW_SELECT ); |
761 | 0 | } |
762 | 0 | } |
763 | 0 | else if ( pDrawViewWrapper->IsDragObj() ) |
764 | 0 | { |
765 | 0 | bool bDraggingDone = false; |
766 | 0 | SdrDragMethod* pDragMethod = pDrawViewWrapper->SdrView::GetDragMethod(); |
767 | 0 | bool bIsMoveOnly = pDragMethod && pDragMethod->getMoveOnly(); |
768 | 0 | DragMethod_Base* pChartDragMethod = dynamic_cast< DragMethod_Base* >(pDragMethod); |
769 | 0 | if( pChartDragMethod ) |
770 | 0 | { |
771 | 0 | UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(), |
772 | 0 | m_xUndoManager ); |
773 | |
|
774 | 0 | if( pDrawViewWrapper->EndDragObj() ) |
775 | 0 | { |
776 | 0 | bDraggingDone = true; |
777 | 0 | aUndoGuard.commit(); |
778 | 0 | } |
779 | 0 | } |
780 | |
|
781 | 0 | if( !bDraggingDone && pDrawViewWrapper->EndDragObj() ) |
782 | 0 | { |
783 | 0 | try |
784 | 0 | { |
785 | | //end move or size |
786 | 0 | SdrObject* pObj = pDrawViewWrapper->getSelectedObject(); |
787 | 0 | if( pObj ) |
788 | 0 | { |
789 | 0 | tools::Rectangle aObjectRect = pObj->GetSnapRect(); |
790 | 0 | tools::Rectangle aOldObjectRect = pObj->GetLastBoundRect(); |
791 | 0 | awt::Size aPageSize( getChartModel()->getPageSize() ); |
792 | 0 | tools::Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height ); |
793 | |
|
794 | 0 | const E3dObject* pE3dObject(DynCastE3dObject(pObj)); |
795 | 0 | if(nullptr != pE3dObject) |
796 | 0 | { |
797 | 0 | E3dScene* pScene(pE3dObject->getRootE3dSceneFromE3dObject()); |
798 | 0 | if(nullptr != pScene) |
799 | 0 | { |
800 | 0 | aObjectRect = pScene->GetSnapRect(); |
801 | 0 | } |
802 | 0 | } |
803 | |
|
804 | 0 | ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::ActionType::Move); |
805 | 0 | if( !bIsMoveOnly && m_aSelection.isResizeableObjectSelected() ) |
806 | 0 | eActionType = ActionDescriptionProvider::ActionType::Resize; |
807 | |
|
808 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); |
809 | |
|
810 | 0 | UndoGuard aUndoGuard( |
811 | 0 | ActionDescriptionProvider::createDescription( eActionType, ObjectNameProvider::getName( eObjectType)), |
812 | 0 | m_xUndoManager ); |
813 | |
|
814 | 0 | bool bChanged = false; |
815 | 0 | rtl::Reference< ChartModel > xModel = getChartModel(); |
816 | 0 | if ( eObjectType == OBJECTTYPE_LEGEND ) |
817 | 0 | bChanged = DiagramHelper::switchDiagramPositioningToExcludingPositioning( *xModel, false , true ); |
818 | |
|
819 | 0 | bool bMoved = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID() |
820 | 0 | , xModel |
821 | 0 | , awt::Rectangle(aObjectRect.Left(),aObjectRect.Top(),aObjectRect.getOpenWidth(),aObjectRect.getOpenHeight()) |
822 | 0 | , awt::Rectangle(aOldObjectRect.Left(), aOldObjectRect.Top(), 0, 0) |
823 | 0 | , awt::Rectangle(aPageRect.Left(),aPageRect.Top(),aPageRect.getOpenWidth(),aPageRect.getOpenHeight()) ); |
824 | |
|
825 | 0 | if( bMoved || bChanged ) |
826 | 0 | { |
827 | 0 | bDraggingDone = true; |
828 | 0 | aUndoGuard.commit(); |
829 | 0 | } |
830 | 0 | } |
831 | 0 | } |
832 | 0 | catch( const uno::Exception & ) |
833 | 0 | { |
834 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
835 | 0 | } |
836 | | //all wanted model changes will take effect |
837 | | //and all unwanted view modifications are cleaned |
838 | 0 | } |
839 | |
|
840 | 0 | if( !bDraggingDone ) //mouse wasn't moved while dragging |
841 | 0 | { |
842 | 0 | bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper ); |
843 | 0 | bool bIsRotateable = m_aSelection.isRotateableObjectSelected( getChartModel() ); |
844 | | |
845 | | //toggle between move and rotate |
846 | 0 | if( bIsRotateable && bClickedTwiceOnDragableObject && m_eDragMode==SdrDragMode::Move ) |
847 | 0 | m_eDragMode=SdrDragMode::Rotate; |
848 | 0 | else |
849 | 0 | m_eDragMode=SdrDragMode::Move; |
850 | |
|
851 | 0 | pDrawViewWrapper->SetDragMode(m_eDragMode); |
852 | |
|
853 | 0 | if( !m_bWaitingForDoubleClick && m_aSelection.maybeSwitchSelectionAfterSingleClickWasEnsured() ) |
854 | 0 | { |
855 | 0 | impl_selectObjectAndNotiy(); |
856 | 0 | } |
857 | 0 | } |
858 | 0 | else |
859 | 0 | m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured(); |
860 | 0 | } |
861 | | |
862 | | //@todo ForcePointer(&rMEvt); |
863 | 0 | pChartWindow->ReleaseMouse(); |
864 | | |
865 | | // In tiled rendering drag mode could be not yet over on the call |
866 | | // that should handle the double-click, so better to perform this check |
867 | | // always. |
868 | 0 | if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ ) |
869 | 0 | { |
870 | 0 | Point aMousePixel = rMEvt.GetPosPixel(); |
871 | 0 | execute_DoubleClick( &aMousePixel, bEditText ); |
872 | 0 | } |
873 | |
|
874 | 0 | if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() ) |
875 | 0 | bNotifySelectionChange = true; |
876 | 0 | } |
877 | | |
878 | 0 | impl_SetMousePointer( rMEvt ); |
879 | |
|
880 | 0 | if(bNotifySelectionChange || bEditText) |
881 | 0 | impl_notifySelectionChangeListeners(); |
882 | 0 | } |
883 | | |
884 | | void ChartController::execute_DoubleClick( const Point* pMousePixel, bool &bEditText ) |
885 | 0 | { |
886 | 0 | const SfxViewShell* pViewShell = SfxViewShell::Current(); |
887 | 0 | bool notAllowed = pViewShell && (pViewShell->isLOKMobilePhone() || pViewShell->IsLokReadOnlyView()); |
888 | 0 | if (notAllowed) |
889 | 0 | return; |
890 | | |
891 | 0 | if ( m_aSelection.hasSelection() ) |
892 | 0 | { |
893 | 0 | OUString aCID( m_aSelection.getSelectedCID() ); |
894 | 0 | if ( !aCID.isEmpty() ) |
895 | 0 | { |
896 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID ); |
897 | 0 | if ( eObjectType == OBJECTTYPE_TITLE ) |
898 | 0 | { |
899 | 0 | bEditText = true; |
900 | 0 | } |
901 | 0 | } |
902 | 0 | else |
903 | 0 | { |
904 | | // #i12587# support for shapes in chart |
905 | 0 | SdrObject* pObj = DrawViewWrapper::getSdrObject( m_aSelection.getSelectedAdditionalShape() ); |
906 | 0 | if ( DynCastSdrTextObj(pObj) != nullptr ) |
907 | 0 | { |
908 | 0 | bEditText = true; |
909 | 0 | } |
910 | 0 | } |
911 | 0 | } |
912 | |
|
913 | 0 | if ( bEditText ) |
914 | 0 | { |
915 | 0 | executeDispatch_EditText( pMousePixel ); |
916 | 0 | } |
917 | 0 | else |
918 | 0 | { |
919 | 0 | executeDispatch_ObjectProperties(); |
920 | 0 | } |
921 | 0 | } |
922 | | |
923 | | void ChartController::execute_Resize() |
924 | 0 | { |
925 | 0 | SolarMutexGuard aGuard; |
926 | 0 | auto pChartWindow(GetChartWindow()); |
927 | 0 | if(pChartWindow) |
928 | 0 | pChartWindow->Invalidate(); |
929 | 0 | } |
930 | | |
931 | | void ChartController::execute_Command( const CommandEvent& rCEvt ) |
932 | 0 | { |
933 | 0 | SolarMutexGuard aGuard; |
934 | 0 | auto pChartWindow(GetChartWindow()); |
935 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
936 | 0 | if(!pChartWindow || !pDrawViewWrapper) |
937 | 0 | return; |
938 | 0 | bool bIsAction = m_pDrawViewWrapper->IsAction(); |
939 | | |
940 | | // pop-up menu |
941 | 0 | if(rCEvt.GetCommand() == CommandEventId::ContextMenu && !bIsAction) |
942 | 0 | { |
943 | 0 | pChartWindow->ReleaseMouse(); |
944 | |
|
945 | 0 | if( m_aSelection.isSelectionDifferentFromBeforeMouseDown() ) |
946 | 0 | impl_notifySelectionChangeListeners(); |
947 | |
|
948 | 0 | rtl::Reference< VCLXPopupMenu > xPopupMenu = new VCLXPopupMenu(); |
949 | |
|
950 | 0 | Point aPos( rCEvt.GetMousePosPixel() ); |
951 | 0 | if( !rCEvt.IsMouseEvent() ) |
952 | 0 | { |
953 | 0 | aPos = pChartWindow->GetPointerState().maPos; |
954 | 0 | } |
955 | |
|
956 | 0 | OUString aMenuName; |
957 | 0 | if ( isShapeContext() ) |
958 | | // #i12587# support for shapes in chart |
959 | 0 | aMenuName = m_pDrawViewWrapper->IsTextEdit() ? std::u16string_view( u"drawtext" ) : std::u16string_view( u"draw" ); |
960 | 0 | else |
961 | 0 | { |
962 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); |
963 | | |
964 | | // todo: the context menu should be specified by an xml file in uiconfig |
965 | 0 | sal_Int16 nUniqueId = 1; |
966 | 0 | if (eObjectType != OBJECTTYPE_DATA_TABLE) |
967 | 0 | { |
968 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Cut"_ustr ); |
969 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Copy"_ustr ); |
970 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:Paste"_ustr ); |
971 | 0 | xPopupMenu->insertSeparator( -1 ); |
972 | 0 | } |
973 | |
|
974 | 0 | rtl::Reference< Diagram > xDiagram = getFirstDiagram(); |
975 | |
|
976 | 0 | OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) ); |
977 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, aFormatCommand ); |
978 | 0 | if (eObjectType == OBJECTTYPE_TITLE && m_pDrawViewWrapper->IsTextEdit()) |
979 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FontDialog"_ustr ); |
980 | | |
981 | | //some commands for dataseries and points: |
982 | |
|
983 | 0 | if( eObjectType == OBJECTTYPE_DATA_SERIES || eObjectType == OBJECTTYPE_DATA_POINT ) |
984 | 0 | { |
985 | 0 | bool bIsPoint = ( eObjectType == OBJECTTYPE_DATA_POINT ); |
986 | 0 | rtl::Reference< DataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getChartModel() ); |
987 | 0 | rtl::Reference< RegressionCurveModel > xTrendline = RegressionCurveHelper::getFirstCurveNotMeanValueLine( xSeries ); |
988 | 0 | bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline ); |
989 | 0 | rtl::Reference< RegressionCurveModel > xMeanValue = RegressionCurveHelper::getMeanValueLine( xSeries ); |
990 | 0 | bool bHasYErrorBars = StatisticsHelper::hasErrorBars( xSeries ); |
991 | 0 | bool bHasXErrorBars = StatisticsHelper::hasErrorBars( xSeries, false ); |
992 | 0 | bool bHasDataLabelsAtSeries = xSeries->hasDataLabelsAtSeries(); |
993 | 0 | bool bHasDataLabelsAtPoints = xSeries->hasDataLabelsAtPoints(); |
994 | 0 | bool bHasDataLabelAtPoint = false; |
995 | 0 | sal_Int32 nPointIndex = -1; |
996 | 0 | if( bIsPoint ) |
997 | 0 | { |
998 | 0 | nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() ); |
999 | 0 | bHasDataLabelAtPoint = xSeries->hasDataLabelAtPoint( nPointIndex ); |
1000 | 0 | } |
1001 | 0 | bool bSelectedPointIsFormatted = false; |
1002 | 0 | bool bHasFormattedDataPointsOtherThanSelected = false; |
1003 | |
|
1004 | 0 | if( xSeries.is() ) |
1005 | 0 | { |
1006 | 0 | uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; |
1007 | | // "AttributedDataPoints" |
1008 | 0 | if( xSeries->getFastPropertyValue( PROP_DATASERIES_ATTRIBUTED_DATA_POINTS ) >>= aAttributedDataPointIndexList ) |
1009 | 0 | { |
1010 | 0 | if( aAttributedDataPointIndexList.hasElements() ) |
1011 | 0 | { |
1012 | 0 | if( bIsPoint ) |
1013 | 0 | { |
1014 | 0 | auto aIt = std::find( aAttributedDataPointIndexList.begin(), aAttributedDataPointIndexList.end(), nPointIndex ); |
1015 | 0 | if (aIt != aAttributedDataPointIndexList.end()) |
1016 | 0 | bSelectedPointIsFormatted = true; |
1017 | 0 | else |
1018 | 0 | bHasFormattedDataPointsOtherThanSelected = true; |
1019 | 0 | } |
1020 | 0 | else |
1021 | 0 | bHasFormattedDataPointsOtherThanSelected = true; |
1022 | 0 | } |
1023 | 0 | } |
1024 | 0 | } |
1025 | |
|
1026 | 0 | if( bIsPoint ) |
1027 | 0 | { |
1028 | 0 | if( bHasDataLabelAtPoint ) |
1029 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataLabel"_ustr ); |
1030 | 0 | if( !bHasDataLabelAtPoint ) |
1031 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertDataLabel"_ustr ); |
1032 | 0 | else |
1033 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteDataLabel"_ustr ); |
1034 | 0 | if( bSelectedPointIsFormatted ) |
1035 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:ResetDataPoint"_ustr ); |
1036 | |
|
1037 | 0 | xPopupMenu->insertSeparator( -1 ); |
1038 | |
|
1039 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataSeries"_ustr ); |
1040 | 0 | } |
1041 | |
|
1042 | 0 | rtl::Reference< ChartType > xChartType( xDiagram->getChartTypeOfSeries( xSeries ) ); |
1043 | 0 | if( xChartType->getChartType() == CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK ) |
1044 | 0 | { |
1045 | 0 | try |
1046 | 0 | { |
1047 | 0 | bool bJapaneseStyle = false; |
1048 | 0 | xChartType->getPropertyValue( u"Japanese"_ustr ) >>= bJapaneseStyle; |
1049 | |
|
1050 | 0 | if( bJapaneseStyle ) |
1051 | 0 | { |
1052 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockLoss"_ustr ); |
1053 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockGain"_ustr ); |
1054 | 0 | } |
1055 | 0 | } |
1056 | 0 | catch( const uno::Exception & ) |
1057 | 0 | { |
1058 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
1059 | 0 | } |
1060 | 0 | } |
1061 | |
|
1062 | 0 | if( bHasDataLabelsAtSeries ) |
1063 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatDataLabels"_ustr ); |
1064 | 0 | if( bHasEquation ) |
1065 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatTrendlineEquation"_ustr ); |
1066 | 0 | if( xMeanValue.is() ) |
1067 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMeanValue"_ustr ); |
1068 | 0 | if( bHasXErrorBars ) |
1069 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatXErrorBars"_ustr ); |
1070 | 0 | if( bHasYErrorBars ) |
1071 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatYErrorBars"_ustr ); |
1072 | |
|
1073 | 0 | xPopupMenu->insertSeparator( -1 ); |
1074 | |
|
1075 | 0 | if( !bHasDataLabelsAtSeries ) |
1076 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertDataLabels"_ustr ); |
1077 | |
|
1078 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendline"_ustr ); |
1079 | |
|
1080 | 0 | if( !xMeanValue.is() ) |
1081 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMeanValue"_ustr ); |
1082 | 0 | if( !bHasXErrorBars ) |
1083 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertXErrorBars"_ustr ); |
1084 | 0 | if( !bHasYErrorBars ) |
1085 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertYErrorBars"_ustr ); |
1086 | 0 | if( bHasDataLabelsAtSeries || ( bHasDataLabelsAtPoints && bHasFormattedDataPointsOtherThanSelected ) ) |
1087 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteDataLabels"_ustr ); |
1088 | 0 | if( bHasEquation ) |
1089 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendlineEquation"_ustr ); |
1090 | 0 | if( xMeanValue.is() ) |
1091 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMeanValue"_ustr ); |
1092 | 0 | if( bHasXErrorBars ) |
1093 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteXErrorBars"_ustr ); |
1094 | 0 | if( bHasYErrorBars ) |
1095 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteYErrorBars"_ustr ); |
1096 | |
|
1097 | 0 | if( bHasFormattedDataPointsOtherThanSelected ) |
1098 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:ResetAllDataPoints"_ustr ); |
1099 | |
|
1100 | 0 | xPopupMenu->insertSeparator( -1 ); |
1101 | |
|
1102 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId, u".uno:ArrangeRow"_ustr ); |
1103 | 0 | rtl::Reference< VCLXPopupMenu > xArrangePopupMenu = new VCLXPopupMenu(); |
1104 | 0 | sal_Int16 nSubId = nUniqueId + 1; |
1105 | 0 | lcl_insertMenuCommand( xArrangePopupMenu, nSubId++, u".uno:Forward"_ustr ); |
1106 | 0 | lcl_insertMenuCommand( xArrangePopupMenu, nSubId, u".uno:Backward"_ustr ); |
1107 | 0 | xPopupMenu->setPopupMenu( nUniqueId, xArrangePopupMenu ); |
1108 | 0 | nUniqueId = nSubId; |
1109 | 0 | ++nUniqueId; |
1110 | 0 | } |
1111 | 0 | else if( eObjectType == OBJECTTYPE_DATA_CURVE ) |
1112 | 0 | { |
1113 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendline"_ustr ); |
1114 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatTrendlineEquation"_ustr ); |
1115 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendlineEquation"_ustr ); |
1116 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTrendlineEquationAndR2"_ustr ); |
1117 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertR2Value"_ustr ); |
1118 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteTrendlineEquation"_ustr ); |
1119 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteR2Value"_ustr ); |
1120 | 0 | } |
1121 | 0 | else if( eObjectType == OBJECTTYPE_DATA_CURVE_EQUATION ) |
1122 | 0 | { |
1123 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertR2Value"_ustr ); |
1124 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteR2Value"_ustr ); |
1125 | 0 | } |
1126 | | |
1127 | | //some commands for axes: and grids |
1128 | | |
1129 | 0 | else if( eObjectType == OBJECTTYPE_AXIS || eObjectType == OBJECTTYPE_GRID || eObjectType == OBJECTTYPE_SUBGRID ) |
1130 | 0 | { |
1131 | 0 | rtl::Reference< Axis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getChartModel() ); |
1132 | 0 | if( xAxis.is() && xDiagram.is() ) |
1133 | 0 | { |
1134 | 0 | sal_Int32 nDimensionIndex = -1; |
1135 | 0 | sal_Int32 nCooSysIndex = -1; |
1136 | 0 | sal_Int32 nAxisIndex = -1; |
1137 | 0 | AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ); |
1138 | 0 | bool bIsSecondaryAxis = nAxisIndex!=0; |
1139 | 0 | bool bIsAxisVisible = AxisHelper::isAxisVisible( xAxis ); |
1140 | 0 | bool bIsMajorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, true /*bMainGrid*/, xDiagram ); |
1141 | 0 | bool bIsMinorGridVisible = AxisHelper::isGridShown( nDimensionIndex, nCooSysIndex, false /*bMainGrid*/, xDiagram ); |
1142 | 0 | bool bHasTitle = !TitleHelper::getCompleteString( xAxis->getTitleObject2() ).isEmpty(); |
1143 | |
|
1144 | 0 | if( eObjectType != OBJECTTYPE_AXIS && bIsAxisVisible ) |
1145 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatAxis"_ustr ); |
1146 | 0 | if( eObjectType != OBJECTTYPE_GRID && bIsMajorGridVisible && !bIsSecondaryAxis ) |
1147 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMajorGrid"_ustr ); |
1148 | 0 | if( eObjectType != OBJECTTYPE_SUBGRID && bIsMinorGridVisible && !bIsSecondaryAxis ) |
1149 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatMinorGrid"_ustr ); |
1150 | |
|
1151 | 0 | xPopupMenu->insertSeparator( -1 ); |
1152 | |
|
1153 | 0 | if( eObjectType != OBJECTTYPE_AXIS && !bIsAxisVisible ) |
1154 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertAxis"_ustr ); |
1155 | 0 | if( eObjectType != OBJECTTYPE_GRID && !bIsMajorGridVisible && !bIsSecondaryAxis ) |
1156 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMajorGrid"_ustr ); |
1157 | 0 | if( eObjectType != OBJECTTYPE_SUBGRID && !bIsMinorGridVisible && !bIsSecondaryAxis ) |
1158 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertMinorGrid"_ustr ); |
1159 | 0 | if( !bHasTitle ) |
1160 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertAxisTitle"_ustr ); |
1161 | |
|
1162 | 0 | if( bIsAxisVisible ) |
1163 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteAxis"_ustr ); |
1164 | 0 | if( bIsMajorGridVisible && !bIsSecondaryAxis ) |
1165 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMajorGrid"_ustr ); |
1166 | 0 | if( bIsMinorGridVisible && !bIsSecondaryAxis ) |
1167 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteMinorGrid"_ustr ); |
1168 | 0 | if (bIsAxisVisible) |
1169 | 0 | lcl_insertMenuCommand(xPopupMenu, nUniqueId++, u".uno:InsertDataTable"_ustr); |
1170 | 0 | } |
1171 | 0 | } |
1172 | 0 | else if (eObjectType == OBJECTTYPE_DATA_TABLE) |
1173 | 0 | { |
1174 | 0 | lcl_insertMenuCommand(xPopupMenu, nUniqueId++, u".uno:DeleteDataTable"_ustr); |
1175 | 0 | } |
1176 | |
|
1177 | 0 | if( eObjectType == OBJECTTYPE_DATA_STOCK_LOSS ) |
1178 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockGain"_ustr ); |
1179 | 0 | else if( eObjectType == OBJECTTYPE_DATA_STOCK_GAIN ) |
1180 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:FormatStockLoss"_ustr ); |
1181 | |
|
1182 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:TransformDialog"_ustr ); |
1183 | |
|
1184 | 0 | if( eObjectType == OBJECTTYPE_PAGE || eObjectType == OBJECTTYPE_DIAGRAM |
1185 | 0 | || eObjectType == OBJECTTYPE_DIAGRAM_WALL |
1186 | 0 | || eObjectType == OBJECTTYPE_DIAGRAM_FLOOR |
1187 | 0 | || eObjectType == OBJECTTYPE_UNKNOWN ) |
1188 | 0 | { |
1189 | 0 | if( eObjectType != OBJECTTYPE_UNKNOWN ) |
1190 | 0 | xPopupMenu->insertSeparator( -1 ); |
1191 | 0 | bool bHasLegend = LegendHelper::hasLegend( xDiagram ); |
1192 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertTitles"_ustr ); |
1193 | 0 | if( !bHasLegend ) |
1194 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertLegend"_ustr ); |
1195 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:InsertRemoveAxes"_ustr ); |
1196 | 0 | if( bHasLegend ) |
1197 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DeleteLegend"_ustr ); |
1198 | 0 | } |
1199 | |
|
1200 | 0 | xPopupMenu->insertSeparator( -1 ); |
1201 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DiagramType"_ustr ); |
1202 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DataRanges"_ustr ); |
1203 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:DiagramData"_ustr ); |
1204 | 0 | lcl_insertMenuCommand( xPopupMenu, nUniqueId++, u".uno:View3D"_ustr ); |
1205 | 0 | } |
1206 | |
|
1207 | 0 | css::uno::Sequence< css::uno::Any > aArgs{ |
1208 | 0 | css::uno::Any(comphelper::makePropertyValue( u"IsContextMenu"_ustr, true )), |
1209 | 0 | css::uno::Any(comphelper::makePropertyValue( u"Frame"_ustr, m_xFrame )), |
1210 | 0 | css::uno::Any(comphelper::makePropertyValue( u"Value"_ustr, aMenuName )) |
1211 | 0 | }; |
1212 | |
|
1213 | 0 | css::uno::Reference< css::frame::XPopupMenuController > xPopupController( |
1214 | 0 | m_xCC->getServiceManager()->createInstanceWithArgumentsAndContext( |
1215 | 0 | u"com.sun.star.comp.framework.ResourceMenuController"_ustr, aArgs, m_xCC ), css::uno::UNO_QUERY ); |
1216 | |
|
1217 | 0 | if ( !xPopupController.is() || !xPopupMenu.is() ) |
1218 | 0 | return; |
1219 | | |
1220 | 0 | xPopupController->setPopupMenu( xPopupMenu ); |
1221 | |
|
1222 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
1223 | 0 | { |
1224 | 0 | if (SfxViewShell* pViewShell = SfxViewShell::Current()) |
1225 | 0 | { |
1226 | 0 | const ControllerCommandDispatch* pCommandDispatch = m_aDispatchContainer.getChartDispatcher(); |
1227 | 0 | if (pCommandDispatch) |
1228 | 0 | { |
1229 | 0 | for (int nPos = 0, nCount = xPopupMenu->getItemCount(); nPos < nCount; ++nPos) |
1230 | 0 | { |
1231 | 0 | auto nItemId = xPopupMenu->getItemId(nPos); |
1232 | 0 | OUString aCommandURL = xPopupMenu->getCommand(nItemId); |
1233 | 0 | if (!pCommandDispatch->commandAvailable(aCommandURL)) |
1234 | 0 | xPopupMenu->enableItem(nItemId, false); |
1235 | 0 | } |
1236 | 0 | } |
1237 | |
|
1238 | 0 | boost::property_tree::ptree aMenu = SfxDispatcher::fillPopupMenu(xPopupMenu); |
1239 | 0 | boost::property_tree::ptree aRoot; |
1240 | 0 | aRoot.add_child("menu", aMenu); |
1241 | |
|
1242 | 0 | std::stringstream aStream; |
1243 | 0 | boost::property_tree::write_json(aStream, aRoot, true); |
1244 | 0 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CONTEXT_MENU, OString(aStream.str())); |
1245 | 0 | } |
1246 | 0 | } |
1247 | 0 | else |
1248 | 0 | { |
1249 | 0 | xPopupMenu->execute( css::uno::Reference< css::awt::XWindowPeer >( m_xFrame->getContainerWindow(), css::uno::UNO_QUERY ), |
1250 | 0 | css::awt::Rectangle( aPos.X(), aPos.Y(), 0, 0 ), |
1251 | 0 | css::awt::PopupMenuDirection::EXECUTE_DEFAULT ); |
1252 | 0 | } |
1253 | |
|
1254 | 0 | css::uno::Reference< css::lang::XComponent > xComponent( xPopupController, css::uno::UNO_QUERY ); |
1255 | 0 | if ( xComponent.is() ) |
1256 | 0 | xComponent->dispose(); |
1257 | 0 | } |
1258 | 0 | else if( ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput ) || |
1259 | 0 | ( rCEvt.GetCommand() == CommandEventId::ExtTextInput ) || |
1260 | 0 | ( rCEvt.GetCommand() == CommandEventId::EndExtTextInput ) || |
1261 | 0 | ( rCEvt.GetCommand() == CommandEventId::InputContextChange ) ) |
1262 | 0 | { |
1263 | | //#i84417# enable editing with IME |
1264 | 0 | m_pDrawViewWrapper->Command( rCEvt, pChartWindow ); |
1265 | 0 | } |
1266 | 0 | } |
1267 | | |
1268 | | bool ChartController::execute_KeyInput( const KeyEvent& rKEvt ) |
1269 | 0 | { |
1270 | 0 | SolarMutexGuard aGuard; |
1271 | 0 | bool bReturn=false; |
1272 | |
|
1273 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
1274 | 0 | auto pChartWindow(GetChartWindow()); |
1275 | 0 | if (!pChartWindow || !pDrawViewWrapper) |
1276 | 0 | return bReturn; |
1277 | | |
1278 | | // handle accelerators |
1279 | 0 | if (!m_apAccelExecute && m_xFrame.is() && m_xCC.is()) |
1280 | 0 | { |
1281 | 0 | m_apAccelExecute = ::svt::AcceleratorExecute::createAcceleratorHelper(); |
1282 | 0 | OSL_ASSERT(m_apAccelExecute); |
1283 | 0 | if (m_apAccelExecute) |
1284 | 0 | m_apAccelExecute->init( m_xCC, m_xFrame ); |
1285 | 0 | } |
1286 | |
|
1287 | 0 | vcl::KeyCode aKeyCode( rKEvt.GetKeyCode()); |
1288 | 0 | sal_uInt16 nCode = aKeyCode.GetCode(); |
1289 | 0 | bool bAlternate = aKeyCode.IsMod2(); |
1290 | 0 | bool bCtrl = aKeyCode.IsMod1(); |
1291 | |
|
1292 | 0 | if (m_apAccelExecute) |
1293 | 0 | bReturn = m_apAccelExecute->execute( aKeyCode ); |
1294 | 0 | if( bReturn ) |
1295 | 0 | return bReturn; |
1296 | | |
1297 | 0 | if( pDrawViewWrapper->IsTextEdit() ) |
1298 | 0 | { |
1299 | 0 | if( pDrawViewWrapper->KeyInput(rKEvt, pChartWindow) ) |
1300 | 0 | { |
1301 | 0 | bReturn = true; |
1302 | 0 | if( nCode == KEY_ESCAPE ) |
1303 | 0 | { |
1304 | 0 | EndTextEdit(); |
1305 | 0 | } |
1306 | 0 | } |
1307 | 0 | } |
1308 | | |
1309 | | // keyboard accessibility |
1310 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); |
1311 | 0 | if( ! bReturn ) |
1312 | 0 | { |
1313 | | // Navigation (Tab/F3/Home/End) |
1314 | 0 | rtl::Reference<::chart::ChartModel> xChartDoc( getChartModel() ); |
1315 | 0 | ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, m_xChartView.get() ); |
1316 | 0 | awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode )); |
1317 | 0 | bReturn = aObjNav.handleKeyEvent( aKeyEvent ); |
1318 | 0 | if( bReturn ) |
1319 | 0 | { |
1320 | 0 | const ObjectIdentifier& aNewOID = aObjNav.getCurrentSelection(); |
1321 | 0 | uno::Any aNewSelection; |
1322 | 0 | if ( aNewOID.isValid() && !ObjectHierarchy::isRootNode( aNewOID ) ) |
1323 | 0 | { |
1324 | 0 | aNewSelection = aNewOID.getAny(); |
1325 | 0 | } |
1326 | 0 | if ( m_eDragMode == SdrDragMode::Rotate && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getChartModel() ) ) |
1327 | 0 | { |
1328 | 0 | m_eDragMode = SdrDragMode::Move; |
1329 | 0 | } |
1330 | 0 | bReturn = select( aNewSelection ); |
1331 | 0 | } |
1332 | 0 | } |
1333 | | |
1334 | | // Position and Size (+/-/arrow-keys) or pie segment dragging |
1335 | 0 | if( ! bReturn ) |
1336 | 0 | { |
1337 | | // pie segment dragging |
1338 | | // note: could also be done for data series |
1339 | 0 | if( eObjectType == OBJECTTYPE_DATA_POINT && |
1340 | 0 | ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) == |
1341 | 0 | ObjectIdentifier::getPieSegmentDragMethodServiceName()) |
1342 | 0 | { |
1343 | 0 | bool bDrag = false; |
1344 | 0 | bool bDragInside = false; |
1345 | 0 | if( nCode == KEY_ADD || |
1346 | 0 | nCode == KEY_SUBTRACT ) |
1347 | 0 | { |
1348 | 0 | bDrag = true; |
1349 | 0 | bDragInside = ( nCode == KEY_SUBTRACT ); |
1350 | 0 | } |
1351 | 0 | else if( |
1352 | 0 | nCode == KEY_LEFT || |
1353 | 0 | nCode == KEY_RIGHT || |
1354 | 0 | nCode == KEY_UP || |
1355 | 0 | nCode == KEY_DOWN ) |
1356 | 0 | { |
1357 | 0 | bDrag = true; |
1358 | 0 | std::u16string_view aParameter( ObjectIdentifier::getDragParameterString( m_aSelection.getSelectedCID() )); |
1359 | 0 | sal_Int32 nOffsetPercentDummy( 0 ); |
1360 | 0 | awt::Point aMinimumPosition( 0, 0 ); |
1361 | 0 | awt::Point aMaximumPosition( 0, 0 ); |
1362 | 0 | ObjectIdentifier::parsePieSegmentDragParameterString( |
1363 | 0 | aParameter, nOffsetPercentDummy, aMinimumPosition, aMaximumPosition ); |
1364 | 0 | aMaximumPosition.Y -= aMinimumPosition.Y; |
1365 | 0 | aMaximumPosition.X -= aMinimumPosition.X; |
1366 | |
|
1367 | 0 | bDragInside = |
1368 | 0 | (nCode == KEY_RIGHT && (aMaximumPosition.X < 0)) || |
1369 | 0 | (nCode == KEY_LEFT && (aMaximumPosition.X > 0)) || |
1370 | 0 | (nCode == KEY_DOWN && (aMaximumPosition.Y < 0)) || |
1371 | 0 | (nCode == KEY_UP && (aMaximumPosition.Y > 0)); |
1372 | 0 | } |
1373 | |
|
1374 | 0 | if( bDrag ) |
1375 | 0 | { |
1376 | 0 | double fAmount = bAlternate ? 0.01 : 0.05; |
1377 | 0 | if( bDragInside ) |
1378 | 0 | fAmount *= -1.0; |
1379 | |
|
1380 | 0 | bReturn = impl_DragDataPoint( m_aSelection.getSelectedCID(), fAmount ); |
1381 | 0 | } |
1382 | 0 | } |
1383 | 0 | else |
1384 | 0 | { |
1385 | | // size |
1386 | 0 | if( nCode == KEY_ADD || |
1387 | 0 | nCode == KEY_SUBTRACT ) |
1388 | 0 | { |
1389 | 0 | if( eObjectType == OBJECTTYPE_DIAGRAM ) |
1390 | 0 | { |
1391 | | // default 1 mm in each direction |
1392 | 0 | double fGrowAmountX = 200.0; |
1393 | 0 | double fGrowAmountY = 200.0; |
1394 | 0 | if (bAlternate) |
1395 | 0 | { |
1396 | | // together with Alt-key: 1 px in each direction |
1397 | 0 | Size aPixelSize = pChartWindow->PixelToLogic( Size( 2, 2 )); |
1398 | 0 | fGrowAmountX = static_cast< double >( aPixelSize.Width()); |
1399 | 0 | fGrowAmountY = static_cast< double >( aPixelSize.Height()); |
1400 | 0 | } |
1401 | 0 | if( nCode == KEY_SUBTRACT ) |
1402 | 0 | { |
1403 | 0 | fGrowAmountX = -fGrowAmountX; |
1404 | 0 | fGrowAmountY = -fGrowAmountY; |
1405 | 0 | } |
1406 | 0 | bReturn = impl_moveOrResizeObject( |
1407 | 0 | m_aSelection.getSelectedCID(), CENTERED_RESIZE_OBJECT, fGrowAmountX, fGrowAmountY ); |
1408 | 0 | } |
1409 | 0 | } |
1410 | | // position |
1411 | 0 | else if( nCode == KEY_LEFT || |
1412 | 0 | nCode == KEY_RIGHT || |
1413 | 0 | nCode == KEY_UP || |
1414 | 0 | nCode == KEY_DOWN ) |
1415 | 0 | { |
1416 | 0 | if( m_aSelection.isDragableObjectSelected() ) |
1417 | 0 | { |
1418 | | // default 1 mm |
1419 | 0 | double fShiftAmountX = 100.0; |
1420 | 0 | double fShiftAmountY = 100.0; |
1421 | 0 | if (bAlternate) |
1422 | 0 | { |
1423 | | // together with Alt-key: 1 px |
1424 | 0 | Size aPixelSize = pChartWindow->PixelToLogic( Size( 1, 1 )); |
1425 | 0 | fShiftAmountX = static_cast< double >( aPixelSize.Width()); |
1426 | 0 | fShiftAmountY = static_cast< double >( aPixelSize.Height()); |
1427 | 0 | } |
1428 | 0 | switch( nCode ) |
1429 | 0 | { |
1430 | 0 | case KEY_LEFT: |
1431 | 0 | fShiftAmountX = -fShiftAmountX; |
1432 | 0 | fShiftAmountY = 0.0; |
1433 | 0 | break; |
1434 | 0 | case KEY_RIGHT: |
1435 | 0 | fShiftAmountY = 0.0; |
1436 | 0 | break; |
1437 | 0 | case KEY_UP: |
1438 | 0 | fShiftAmountX = 0.0; |
1439 | 0 | fShiftAmountY = -fShiftAmountY; |
1440 | 0 | break; |
1441 | 0 | case KEY_DOWN: |
1442 | 0 | fShiftAmountX = 0.0; |
1443 | 0 | break; |
1444 | 0 | } |
1445 | 0 | if( !m_aSelection.getSelectedCID().isEmpty() ) |
1446 | 0 | { |
1447 | | //move chart objects |
1448 | 0 | if (eObjectType == OBJECTTYPE_DATA_LABEL) |
1449 | 0 | { |
1450 | 0 | SdrObject* pObj = pDrawViewWrapper->getSelectedObject(); |
1451 | 0 | if (pObj) |
1452 | 0 | { |
1453 | 0 | tools::Rectangle aRect = pObj->GetSnapRect(); |
1454 | 0 | awt::Size aPageSize(getChartModel()->getPageSize()); |
1455 | 0 | if ((fShiftAmountX > 0.0 && (aRect.Right() + fShiftAmountX > aPageSize.Width)) || |
1456 | 0 | (fShiftAmountX < 0.0 && (aRect.Left() + fShiftAmountX < 0)) || |
1457 | 0 | (fShiftAmountY > 0.0 && (aRect.Bottom() + fShiftAmountY > aPageSize.Height)) || |
1458 | 0 | (fShiftAmountY < 0.0 && (aRect.Top() + fShiftAmountY < 0))) |
1459 | 0 | bReturn = false; |
1460 | 0 | else |
1461 | 0 | bReturn = PositionAndSizeHelper::moveObject( |
1462 | 0 | m_aSelection.getSelectedCID(), getChartModel(), |
1463 | 0 | awt::Rectangle(aRect.Left() + fShiftAmountX, aRect.Top() + fShiftAmountY, aRect.getOpenWidth(), aRect.getOpenHeight()), |
1464 | 0 | awt::Rectangle(aRect.Left(), aRect.Top(), 0, 0), |
1465 | 0 | awt::Rectangle(0, 0, aPageSize.Width, aPageSize.Height)); |
1466 | 0 | } |
1467 | 0 | } |
1468 | 0 | else |
1469 | 0 | bReturn = impl_moveOrResizeObject( |
1470 | 0 | m_aSelection.getSelectedCID(), MOVE_OBJECT, fShiftAmountX, fShiftAmountY ); |
1471 | 0 | } |
1472 | 0 | else |
1473 | 0 | { |
1474 | | //move additional shapes |
1475 | 0 | uno::Reference< drawing::XShape > xShape( m_aSelection.getSelectedAdditionalShape() ); |
1476 | 0 | if( xShape.is() ) |
1477 | 0 | { |
1478 | 0 | awt::Point aPos( xShape->getPosition() ); |
1479 | 0 | awt::Size aSize( xShape->getSize() ); |
1480 | 0 | awt::Size aPageSize( getChartModel()->getPageSize() ); |
1481 | 0 | aPos.X = static_cast< tools::Long >( static_cast< double >( aPos.X ) + fShiftAmountX ); |
1482 | 0 | aPos.Y = static_cast< tools::Long >( static_cast< double >( aPos.Y ) + fShiftAmountY ); |
1483 | 0 | if( aPos.X + aSize.Width > aPageSize.Width ) |
1484 | 0 | aPos.X = aPageSize.Width - aSize.Width; |
1485 | 0 | if( aPos.X < 0 ) |
1486 | 0 | aPos.X = 0; |
1487 | 0 | if( aPos.Y + aSize.Height > aPageSize.Height ) |
1488 | 0 | aPos.Y = aPageSize.Height - aSize.Height; |
1489 | 0 | if( aPos.Y < 0 ) |
1490 | 0 | aPos.Y = 0; |
1491 | |
|
1492 | 0 | xShape->setPosition( aPos ); |
1493 | 0 | } |
1494 | 0 | } |
1495 | 0 | } |
1496 | 0 | } |
1497 | 0 | } |
1498 | 0 | } |
1499 | | |
1500 | | // dumping the shape |
1501 | 0 | if( !bReturn && bCtrl && nCode == KEY_F12) |
1502 | 0 | { |
1503 | 0 | rtl::Reference< ChartModel > xChartModel = getChartModel(); |
1504 | 0 | if(xChartModel.is()) |
1505 | 0 | { |
1506 | 0 | OUString aDump = xChartModel->dump(u"shapes"_ustr); |
1507 | 0 | SAL_WARN("chart2", aDump); |
1508 | 0 | } |
1509 | 0 | } |
1510 | | |
1511 | | // text edit |
1512 | 0 | if( ! bReturn && |
1513 | 0 | nCode == KEY_F2 ) |
1514 | 0 | { |
1515 | 0 | if( eObjectType == OBJECTTYPE_TITLE ) |
1516 | 0 | { |
1517 | 0 | executeDispatch_EditText(); |
1518 | 0 | bReturn = true; |
1519 | 0 | } |
1520 | 0 | } |
1521 | | |
1522 | | // deactivate inplace mode (this code should be unnecessary, but |
1523 | | // unfortunately is not) |
1524 | 0 | if( ! bReturn && |
1525 | 0 | nCode == KEY_ESCAPE ) |
1526 | 0 | { |
1527 | 0 | uno::Reference< frame::XDispatchHelper > xDispatchHelper( frame::DispatchHelper::create(m_xCC) ); |
1528 | 0 | uno::Sequence< beans::PropertyValue > aArgs; |
1529 | 0 | xDispatchHelper->executeDispatch( |
1530 | 0 | uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ), |
1531 | 0 | u".uno:TerminateInplaceActivation"_ustr, |
1532 | 0 | u"_parent"_ustr, |
1533 | 0 | frame::FrameSearchFlag::PARENT, |
1534 | 0 | aArgs ); |
1535 | 0 | bReturn = true; |
1536 | 0 | } |
1537 | |
|
1538 | 0 | if( ! bReturn && |
1539 | 0 | (nCode == KEY_DELETE || nCode == KEY_BACKSPACE )) |
1540 | 0 | { |
1541 | 0 | bReturn = executeDispatch_Delete(); |
1542 | 0 | if( ! bReturn ) |
1543 | 0 | { |
1544 | 0 | std::shared_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pChartWindow->GetFrameWeld(), |
1545 | 0 | VclMessageType::Info, VclButtonsType::Ok, |
1546 | 0 | SchResId(STR_ACTION_NOTPOSSIBLE))); |
1547 | 0 | xInfoBox->runAsync(xInfoBox, [] (int) {}); |
1548 | 0 | } |
1549 | 0 | } |
1550 | |
|
1551 | 0 | return bReturn; |
1552 | 0 | } |
1553 | | |
1554 | | bool ChartController::requestQuickHelp( |
1555 | | ::Point aAtLogicPosition, |
1556 | | bool bIsBalloonHelp, |
1557 | | OUString & rOutQuickHelpText, |
1558 | | awt::Rectangle & rOutEqualRect ) |
1559 | 0 | { |
1560 | 0 | rtl::Reference<::chart::ChartModel> xChartModel; |
1561 | 0 | if( m_aModel.is()) |
1562 | 0 | xChartModel = getChartModel(); |
1563 | 0 | if( !xChartModel.is()) |
1564 | 0 | return false; |
1565 | | |
1566 | | // help text |
1567 | 0 | OUString aCID; |
1568 | 0 | if( m_pDrawViewWrapper ) |
1569 | 0 | { |
1570 | 0 | aCID = SelectionHelper::getHitObjectCID( |
1571 | 0 | aAtLogicPosition, *m_pDrawViewWrapper ); |
1572 | 0 | } |
1573 | 0 | bool bResult( !aCID.isEmpty()); |
1574 | |
|
1575 | 0 | if( bResult ) |
1576 | 0 | { |
1577 | | // get help text |
1578 | 0 | rOutQuickHelpText = ObjectNameProvider::getHelpText( aCID, xChartModel, bIsBalloonHelp /* bVerbose */ ); |
1579 | | |
1580 | | // set rectangle |
1581 | 0 | if( m_xChartView ) |
1582 | 0 | rOutEqualRect = m_xChartView->getRectangleOfObject( aCID, true ); |
1583 | 0 | } |
1584 | |
|
1585 | 0 | return bResult; |
1586 | 0 | } |
1587 | | |
1588 | | // XSelectionSupplier (optional interface) |
1589 | | sal_Bool SAL_CALL ChartController::select( const uno::Any& rSelection ) |
1590 | 0 | { |
1591 | 0 | bool bSuccess = false; |
1592 | |
|
1593 | 0 | if ( rSelection.hasValue() ) |
1594 | 0 | { |
1595 | 0 | if (rSelection.getValueType() == cppu::UnoType<OUString>::get()) |
1596 | 0 | { |
1597 | 0 | OUString aNewCID; |
1598 | 0 | if ( ( rSelection >>= aNewCID ) && m_aSelection.setSelection( aNewCID ) ) |
1599 | 0 | { |
1600 | 0 | bSuccess = true; |
1601 | 0 | } |
1602 | 0 | } |
1603 | 0 | else if (uno::Reference<drawing::XShape> xShape; rSelection >>= xShape) |
1604 | 0 | { |
1605 | 0 | if (m_aSelection.setSelection(xShape)) |
1606 | 0 | { |
1607 | 0 | bSuccess = true; |
1608 | 0 | } |
1609 | 0 | } |
1610 | 0 | } |
1611 | 0 | else |
1612 | 0 | { |
1613 | 0 | if ( m_aSelection.hasSelection() ) |
1614 | 0 | { |
1615 | 0 | m_aSelection.clearSelection(); |
1616 | 0 | bSuccess = true; |
1617 | 0 | } |
1618 | 0 | } |
1619 | |
|
1620 | 0 | if ( bSuccess ) |
1621 | 0 | { |
1622 | 0 | SolarMutexGuard aGuard; |
1623 | 0 | if ( m_pDrawViewWrapper && m_pDrawViewWrapper->IsTextEdit() ) |
1624 | 0 | { |
1625 | 0 | EndTextEdit(); |
1626 | 0 | } |
1627 | 0 | impl_selectObjectAndNotiy(); |
1628 | 0 | auto pChartWindow(GetChartWindow()); |
1629 | 0 | if ( pChartWindow ) |
1630 | 0 | { |
1631 | 0 | pChartWindow->Invalidate(); |
1632 | 0 | } |
1633 | 0 | return true; |
1634 | 0 | } |
1635 | | |
1636 | 0 | return false; |
1637 | 0 | } |
1638 | | |
1639 | | uno::Any SAL_CALL ChartController::getSelection() |
1640 | 0 | { |
1641 | 0 | uno::Any aReturn; |
1642 | 0 | if ( m_aSelection.hasSelection() ) |
1643 | 0 | { |
1644 | 0 | OUString aCID( m_aSelection.getSelectedCID() ); |
1645 | 0 | if ( !aCID.isEmpty() ) |
1646 | 0 | { |
1647 | 0 | aReturn <<= aCID; |
1648 | 0 | } |
1649 | 0 | else |
1650 | 0 | { |
1651 | | // #i12587# support for shapes in chart |
1652 | 0 | aReturn <<= m_aSelection.getSelectedAdditionalShape(); |
1653 | 0 | } |
1654 | 0 | } |
1655 | 0 | return aReturn; |
1656 | 0 | } |
1657 | | |
1658 | | void SAL_CALL ChartController::addSelectionChangeListener( const uno::Reference<view::XSelectionChangeListener> & xListener ) |
1659 | 0 | { |
1660 | 0 | SolarMutexGuard aGuard; |
1661 | 0 | if( impl_isDisposedOrSuspended() )//@todo? allow adding of listeners in suspend mode? |
1662 | 0 | return; //behave passive if already disposed or suspended |
1663 | | |
1664 | | //--add listener |
1665 | 0 | std::unique_lock aGuard2(m_aLifeTimeManager.m_aAccessMutex); |
1666 | 0 | m_aLifeTimeManager.m_aSelectionChangeListeners.addInterface( aGuard2, xListener ); |
1667 | 0 | } |
1668 | | |
1669 | | void SAL_CALL ChartController::removeSelectionChangeListener( const uno::Reference<view::XSelectionChangeListener> & xListener ) |
1670 | 0 | { |
1671 | 0 | SolarMutexGuard aGuard; |
1672 | 0 | if( impl_isDisposedOrSuspended() ) //@todo? allow removing of listeners in suspend mode? |
1673 | 0 | return; //behave passive if already disposed or suspended |
1674 | | |
1675 | | //--remove listener |
1676 | 0 | std::unique_lock aGuard2(m_aLifeTimeManager.m_aAccessMutex); |
1677 | 0 | m_aLifeTimeManager.m_aSelectionChangeListeners.removeInterface( aGuard2, xListener ); |
1678 | 0 | } |
1679 | | |
1680 | | void ChartController::impl_notifySelectionChangeListeners() |
1681 | 0 | { |
1682 | 0 | std::unique_lock aGuard(m_aLifeTimeManager.m_aAccessMutex); |
1683 | 0 | if( m_aLifeTimeManager.m_aSelectionChangeListeners.getLength(aGuard) ) |
1684 | 0 | { |
1685 | 0 | uno::Reference< view::XSelectionSupplier > xSelectionSupplier(this); |
1686 | 0 | lang::EventObject aEvent( xSelectionSupplier ); |
1687 | 0 | m_aLifeTimeManager.m_aSelectionChangeListeners.notifyEach(aGuard, &view::XSelectionChangeListener::selectionChanged, aEvent); |
1688 | 0 | } |
1689 | 0 | } |
1690 | | |
1691 | | void ChartController::impl_selectObjectAndNotiy() |
1692 | 0 | { |
1693 | 0 | { |
1694 | 0 | SolarMutexGuard aGuard; |
1695 | 0 | DrawViewWrapper* pDrawViewWrapper = m_pDrawViewWrapper.get(); |
1696 | 0 | if( pDrawViewWrapper ) |
1697 | 0 | { |
1698 | 0 | pDrawViewWrapper->SetDragMode( m_eDragMode ); |
1699 | 0 | m_aSelection.applySelection( m_pDrawViewWrapper.get() ); |
1700 | 0 | } |
1701 | 0 | } |
1702 | 0 | impl_notifySelectionChangeListeners(); |
1703 | 0 | } |
1704 | | |
1705 | | bool ChartController::impl_moveOrResizeObject( |
1706 | | const OUString & rCID, |
1707 | | eMoveOrResizeType eType, |
1708 | | double fAmountLogicX, |
1709 | | double fAmountLogicY ) |
1710 | 0 | { |
1711 | 0 | bool bResult = false; |
1712 | 0 | bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT ); |
1713 | |
|
1714 | 0 | rtl::Reference<::chart::ChartModel> xChartModel( getChartModel() ); |
1715 | 0 | uno::Reference< beans::XPropertySet > xObjProp( |
1716 | 0 | ObjectIdentifier::getObjectPropertySet( rCID, xChartModel )); |
1717 | 0 | if( xObjProp.is()) |
1718 | 0 | { |
1719 | 0 | awt::Size aRefSize = xChartModel->getPageSize(); |
1720 | |
|
1721 | 0 | chart2::RelativePosition aRelPos; |
1722 | 0 | chart2::RelativeSize aRelSize; |
1723 | 0 | bool bDeterminePos = !(xObjProp->getPropertyValue( u"RelativePosition"_ustr) >>= aRelPos); |
1724 | 0 | bool bDetermineSize = !bNeedResize || !(xObjProp->getPropertyValue( u"RelativeSize"_ustr) >>= aRelSize); |
1725 | |
|
1726 | 0 | if( ( bDeterminePos || bDetermineSize ) && |
1727 | 0 | ( aRefSize.Width > 0 && aRefSize.Height > 0 ) ) |
1728 | 0 | { |
1729 | 0 | ChartView * pValueProvider( m_xChartView.get() ); |
1730 | 0 | if( pValueProvider ) |
1731 | 0 | { |
1732 | 0 | awt::Rectangle aRect( pValueProvider->getRectangleOfObject( rCID )); |
1733 | 0 | double fWidth = static_cast< double >( aRefSize.Width ); |
1734 | 0 | double fHeight = static_cast< double >( aRefSize.Height ); |
1735 | 0 | if( bDetermineSize ) |
1736 | 0 | { |
1737 | 0 | aRelSize.Primary = static_cast< double >( aRect.Width ) / fWidth; |
1738 | 0 | aRelSize.Secondary = static_cast< double >( aRect.Height ) / fHeight; |
1739 | 0 | } |
1740 | 0 | if( bDeterminePos ) |
1741 | 0 | { |
1742 | 0 | if( bNeedResize && aRelSize.Primary > 0.0 && aRelSize.Secondary > 0.0 ) |
1743 | 0 | { |
1744 | 0 | aRelPos.Primary = (static_cast< double >( aRect.X ) / fWidth) + |
1745 | 0 | (aRelSize.Primary / 2.0); |
1746 | 0 | aRelPos.Secondary = (static_cast< double >( aRect.Y ) / fHeight) + |
1747 | 0 | (aRelSize.Secondary / 2.0); |
1748 | 0 | aRelPos.Anchor = drawing::Alignment_CENTER; |
1749 | 0 | } |
1750 | 0 | else |
1751 | 0 | { |
1752 | 0 | aRelPos.Primary = static_cast< double >( aRect.X ) / fWidth; |
1753 | 0 | aRelPos.Secondary = static_cast< double >( aRect.Y ) / fHeight; |
1754 | 0 | aRelPos.Anchor = drawing::Alignment_TOP_LEFT; |
1755 | 0 | } |
1756 | 0 | } |
1757 | 0 | } |
1758 | 0 | } |
1759 | |
|
1760 | 0 | if( eType == CENTERED_RESIZE_OBJECT ) |
1761 | 0 | bResult = lcl_GrowAndShiftLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY ); |
1762 | 0 | else if( eType == MOVE_OBJECT ) |
1763 | 0 | bResult = lcl_MoveObjectLogic( aRelPos, aRelSize, aRefSize, fAmountLogicX, fAmountLogicY ); |
1764 | |
|
1765 | 0 | if( bResult ) |
1766 | 0 | { |
1767 | 0 | ActionDescriptionProvider::ActionType eActionType(ActionDescriptionProvider::ActionType::Move); |
1768 | 0 | if( bNeedResize ) |
1769 | 0 | eActionType = ActionDescriptionProvider::ActionType::Resize; |
1770 | |
|
1771 | 0 | ObjectType eObjectType = ObjectIdentifier::getObjectType( rCID ); |
1772 | 0 | UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( |
1773 | 0 | eActionType, ObjectNameProvider::getName( eObjectType )), m_xUndoManager ); |
1774 | 0 | { |
1775 | 0 | ControllerLockGuardUNO aCLGuard( xChartModel ); |
1776 | 0 | xObjProp->setPropertyValue( u"RelativePosition"_ustr, uno::Any( aRelPos )); |
1777 | 0 | if( bNeedResize || (eObjectType == OBJECTTYPE_DIAGRAM) )//Also set an explicit size at the diagram when an explicit position is set |
1778 | 0 | xObjProp->setPropertyValue( u"RelativeSize"_ustr, uno::Any( aRelSize )); |
1779 | 0 | } |
1780 | 0 | aUndoGuard.commit(); |
1781 | 0 | } |
1782 | 0 | } |
1783 | 0 | return bResult; |
1784 | 0 | } |
1785 | | |
1786 | | bool ChartController::impl_DragDataPoint( std::u16string_view rCID, double fAdditionalOffset ) |
1787 | 0 | { |
1788 | 0 | bool bResult = false; |
1789 | 0 | if( fAdditionalOffset < -1.0 || fAdditionalOffset > 1.0 || fAdditionalOffset == 0.0 ) |
1790 | 0 | return bResult; |
1791 | | |
1792 | 0 | sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID ); |
1793 | 0 | rtl::Reference< DataSeries > xSeries = |
1794 | 0 | ObjectIdentifier::getDataSeriesForCID( rCID, getChartModel() ); |
1795 | 0 | if( xSeries.is()) |
1796 | 0 | { |
1797 | 0 | try |
1798 | 0 | { |
1799 | 0 | uno::Reference< beans::XPropertySet > xPointProp( xSeries->getDataPointByIndex( nDataPointIndex )); |
1800 | 0 | double fOffset = 0.0; |
1801 | 0 | if( xPointProp.is() && |
1802 | 0 | (xPointProp->getPropertyValue( u"Offset"_ustr ) >>= fOffset ) && |
1803 | 0 | (( fAdditionalOffset > 0.0 && fOffset < 1.0 ) || (fOffset > 0.0)) ) |
1804 | 0 | { |
1805 | 0 | fOffset += fAdditionalOffset; |
1806 | 0 | if( fOffset > 1.0 ) |
1807 | 0 | fOffset = 1.0; |
1808 | 0 | else if( fOffset < 0.0 ) |
1809 | 0 | fOffset = 0.0; |
1810 | 0 | xPointProp->setPropertyValue( u"Offset"_ustr, uno::Any( fOffset )); |
1811 | 0 | bResult = true; |
1812 | 0 | } |
1813 | 0 | } |
1814 | 0 | catch( const uno::Exception & ) |
1815 | 0 | { |
1816 | 0 | DBG_UNHANDLED_EXCEPTION("chart2"); |
1817 | 0 | } |
1818 | 0 | } |
1819 | |
|
1820 | 0 | return bResult; |
1821 | 0 | } |
1822 | | |
1823 | | void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) |
1824 | 0 | { |
1825 | 0 | SolarMutexGuard aGuard; |
1826 | 0 | auto pChartWindow(GetChartWindow()); |
1827 | |
|
1828 | 0 | if (!m_pDrawViewWrapper || !pChartWindow) |
1829 | 0 | return; |
1830 | | |
1831 | 0 | Point aMousePos( pChartWindow->PixelToLogic( rEvent.GetPosPixel())); |
1832 | 0 | sal_uInt16 nModifier = rEvent.GetModifier(); |
1833 | 0 | bool bLeftDown = rEvent.IsLeft(); |
1834 | | |
1835 | | // Check if object is for field button and set the normal arrow pointer in this case |
1836 | 0 | SdrObject* pObject = m_pDrawViewWrapper->getHitObject(aMousePos); |
1837 | 0 | if (pObject && pObject->GetName().startsWith("FieldButton")) |
1838 | 0 | { |
1839 | 0 | pChartWindow->SetPointer(PointerStyle::Arrow); |
1840 | 0 | return; |
1841 | 0 | } |
1842 | | |
1843 | 0 | if ( m_pDrawViewWrapper->IsTextEdit() ) |
1844 | 0 | { |
1845 | 0 | if( m_pDrawViewWrapper->IsTextEditHit( aMousePos ) ) |
1846 | 0 | { |
1847 | 0 | pChartWindow->SetPointer( m_pDrawViewWrapper->GetPreferredPointer( |
1848 | 0 | aMousePos, pChartWindow->GetOutDev(), nModifier, bLeftDown ) ); |
1849 | 0 | return; |
1850 | 0 | } |
1851 | 0 | } |
1852 | 0 | else if( m_pDrawViewWrapper->IsAction() ) |
1853 | 0 | { |
1854 | 0 | return;//don't change pointer during running action |
1855 | 0 | } |
1856 | | |
1857 | 0 | SdrHdl* pHitSelectionHdl = nullptr; |
1858 | 0 | if( m_aSelection.isResizeableObjectSelected() ) |
1859 | 0 | pHitSelectionHdl = m_pDrawViewWrapper->PickHandle( aMousePos ); |
1860 | |
|
1861 | 0 | if( pHitSelectionHdl ) |
1862 | 0 | { |
1863 | 0 | PointerStyle aPointer = m_pDrawViewWrapper->GetPreferredPointer( |
1864 | 0 | aMousePos, pChartWindow->GetOutDev(), nModifier, bLeftDown ); |
1865 | 0 | bool bForceArrowPointer = false; |
1866 | |
|
1867 | 0 | ObjectIdentifier aOID( m_aSelection.getSelectedOID() ); |
1868 | |
|
1869 | 0 | switch( aPointer) |
1870 | 0 | { |
1871 | 0 | case PointerStyle::NSize: |
1872 | 0 | case PointerStyle::SSize: |
1873 | 0 | case PointerStyle::WSize: |
1874 | 0 | case PointerStyle::ESize: |
1875 | 0 | case PointerStyle::NWSize: |
1876 | 0 | case PointerStyle::NESize: |
1877 | 0 | case PointerStyle::SWSize: |
1878 | 0 | case PointerStyle::SESize: |
1879 | 0 | if( ! m_aSelection.isResizeableObjectSelected() ) |
1880 | 0 | bForceArrowPointer = true; |
1881 | 0 | break; |
1882 | 0 | case PointerStyle::Move: |
1883 | 0 | if ( !aOID.isDragableObject() ) |
1884 | 0 | bForceArrowPointer = true; |
1885 | 0 | break; |
1886 | 0 | case PointerStyle::MovePoint: |
1887 | 0 | case PointerStyle::MoveBezierWeight: |
1888 | | // there is no point-editing in a chart |
1889 | | // the PointerStyle::MoveBezierWeight appears in 3d data points |
1890 | 0 | bForceArrowPointer = true; |
1891 | 0 | break; |
1892 | 0 | default: |
1893 | 0 | break; |
1894 | 0 | } |
1895 | | |
1896 | 0 | if( bForceArrowPointer ) |
1897 | 0 | pChartWindow->SetPointer( PointerStyle::Arrow ); |
1898 | 0 | else |
1899 | 0 | pChartWindow->SetPointer( aPointer ); |
1900 | |
|
1901 | 0 | return; |
1902 | 0 | } |
1903 | | |
1904 | | // #i12587# support for shapes in chart |
1905 | 0 | if ( m_eDrawMode == CHARTDRAW_INSERT && |
1906 | 0 | ( !m_pDrawViewWrapper->IsMarkedHit( aMousePos ) || !m_aSelection.isDragableObjectSelected() ) ) |
1907 | 0 | { |
1908 | 0 | PointerStyle ePointerStyle = PointerStyle::DrawRect; |
1909 | 0 | SdrObjKind eKind = m_pDrawViewWrapper->GetCurrentObjIdentifier(); |
1910 | 0 | switch ( eKind ) |
1911 | 0 | { |
1912 | 0 | case SdrObjKind::Line: |
1913 | 0 | { |
1914 | 0 | ePointerStyle = PointerStyle::DrawLine; |
1915 | 0 | } |
1916 | 0 | break; |
1917 | 0 | case SdrObjKind::Rectangle: |
1918 | 0 | case SdrObjKind::CustomShape: |
1919 | 0 | { |
1920 | 0 | ePointerStyle = PointerStyle::DrawRect; |
1921 | 0 | } |
1922 | 0 | break; |
1923 | 0 | case SdrObjKind::CircleOrEllipse: |
1924 | 0 | { |
1925 | 0 | ePointerStyle = PointerStyle::DrawEllipse; |
1926 | 0 | } |
1927 | 0 | break; |
1928 | 0 | case SdrObjKind::FreehandLine: |
1929 | 0 | { |
1930 | 0 | ePointerStyle = PointerStyle::DrawPolygon; |
1931 | 0 | } |
1932 | 0 | break; |
1933 | 0 | case SdrObjKind::Text: |
1934 | 0 | { |
1935 | 0 | ePointerStyle = PointerStyle::DrawText; |
1936 | 0 | } |
1937 | 0 | break; |
1938 | 0 | case SdrObjKind::Caption: |
1939 | 0 | { |
1940 | 0 | ePointerStyle = PointerStyle::DrawCaption; |
1941 | 0 | } |
1942 | 0 | break; |
1943 | 0 | default: |
1944 | 0 | { |
1945 | 0 | ePointerStyle = PointerStyle::DrawRect; |
1946 | 0 | } |
1947 | 0 | break; |
1948 | 0 | } |
1949 | 0 | pChartWindow->SetPointer( ePointerStyle ); |
1950 | 0 | return; |
1951 | 0 | } |
1952 | | |
1953 | 0 | OUString aHitObjectCID( |
1954 | 0 | SelectionHelper::getHitObjectCID( |
1955 | 0 | aMousePos, *m_pDrawViewWrapper, true /*bGetDiagramInsteadOf_Wall*/ )); |
1956 | |
|
1957 | 0 | if( m_pDrawViewWrapper->IsTextEdit() ) |
1958 | 0 | { |
1959 | 0 | if( aHitObjectCID == m_aSelection.getSelectedCID() ) |
1960 | 0 | { |
1961 | 0 | pChartWindow->SetPointer( PointerStyle::Arrow ); |
1962 | 0 | return; |
1963 | 0 | } |
1964 | 0 | } |
1965 | | |
1966 | 0 | if( aHitObjectCID.isEmpty() ) |
1967 | 0 | { |
1968 | | //additional shape was hit |
1969 | 0 | pChartWindow->SetPointer( PointerStyle::Move ); |
1970 | 0 | } |
1971 | 0 | else if( ObjectIdentifier::isDragableObject( aHitObjectCID ) ) |
1972 | 0 | { |
1973 | 0 | if( (m_eDragMode == SdrDragMode::Rotate) |
1974 | 0 | && SelectionHelper::isRotateableObject( aHitObjectCID |
1975 | 0 | , getChartModel() ) ) |
1976 | 0 | pChartWindow->SetPointer( PointerStyle::Rotate ); |
1977 | 0 | else |
1978 | 0 | { |
1979 | 0 | ObjectType eHitObjectType = ObjectIdentifier::getObjectType( aHitObjectCID ); |
1980 | 0 | if( eHitObjectType == OBJECTTYPE_DATA_POINT ) |
1981 | 0 | { |
1982 | 0 | if( !ObjectIdentifier::areSiblings(aHitObjectCID,m_aSelection.getSelectedCID()) |
1983 | 0 | && !ObjectIdentifier::areIdenticalObjects(aHitObjectCID,m_aSelection.getSelectedCID()) ) |
1984 | 0 | { |
1985 | 0 | pChartWindow->SetPointer( PointerStyle::Arrow ); |
1986 | 0 | return; |
1987 | 0 | } |
1988 | 0 | } |
1989 | 0 | pChartWindow->SetPointer( PointerStyle::Move ); |
1990 | 0 | } |
1991 | 0 | } |
1992 | 0 | else |
1993 | 0 | pChartWindow->SetPointer( PointerStyle::Arrow ); |
1994 | 0 | } |
1995 | | |
1996 | | void ChartController::sendPopupRequest(std::u16string_view rCID, tools::Rectangle aRectangle) |
1997 | 0 | { |
1998 | 0 | ChartModel* pChartModel = m_aModel->getModel().get(); |
1999 | 0 | if (!pChartModel) |
2000 | 0 | return; |
2001 | | |
2002 | 0 | chart2api::AbstractPivotTableDataProvider* pPivotTableDataProvider = |
2003 | 0 | dynamic_cast<chart2api::AbstractPivotTableDataProvider*>(pChartModel->getDataProvider().get()); |
2004 | 0 | if (!pPivotTableDataProvider) |
2005 | 0 | return; |
2006 | | |
2007 | 0 | OUString sPivotTableName = pPivotTableDataProvider->getPivotTableName(); |
2008 | |
|
2009 | 0 | css::uno::Reference<css::awt::XRequestCallback> xPopupRequest = pChartModel->getPopupRequest(); |
2010 | 0 | PopupRequest* pPopupRequest = dynamic_cast<PopupRequest*>(xPopupRequest.get()); |
2011 | 0 | if (!pPopupRequest) |
2012 | 0 | return; |
2013 | | |
2014 | | // Get dimension index from CID |
2015 | 0 | size_t nStartPos = rCID.rfind('.'); |
2016 | 0 | nStartPos = (nStartPos == std::u16string_view::npos) ? 0 : (nStartPos + 1); |
2017 | 0 | sal_Int32 nEndPos = rCID.size(); |
2018 | 0 | std::u16string_view sDimensionIndex = rCID.substr(nStartPos, nEndPos - nStartPos); |
2019 | 0 | sal_Int32 nDimensionIndex = o3tl::toInt32(sDimensionIndex); |
2020 | |
|
2021 | 0 | awt::Rectangle xRectangle { |
2022 | 0 | sal_Int32(aRectangle.Left()), |
2023 | 0 | sal_Int32(aRectangle.Top()), |
2024 | 0 | sal_Int32(aRectangle.GetWidth()), |
2025 | 0 | sal_Int32(aRectangle.GetHeight()) |
2026 | 0 | }; |
2027 | |
|
2028 | 0 | uno::Sequence<beans::PropertyValue> aCallbackData = comphelper::InitPropertySequence( |
2029 | 0 | { |
2030 | 0 | {"Rectangle", uno::Any(xRectangle)}, |
2031 | 0 | {"DimensionIndex", uno::Any(sal_Int32(nDimensionIndex))}, |
2032 | 0 | {"PivotTableName", uno::Any(sPivotTableName)}, |
2033 | 0 | }); |
2034 | |
|
2035 | 0 | pPopupRequest->getCallback()->notify(uno::Any(aCallbackData)); |
2036 | 0 | } |
2037 | | |
2038 | | } //namespace chart |
2039 | | |
2040 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |