/src/libreoffice/starmath/source/view.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 <com/sun/star/accessibility/AccessibleEventId.hpp> |
23 | | #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
24 | | #include <com/sun/star/frame/Desktop.hpp> |
25 | | #include <com/sun/star/frame/XFramesSupplier.hpp> |
26 | | #include <com/sun/star/frame/XModel.hpp> |
27 | | #include <com/sun/star/container/XChild.hpp> |
28 | | |
29 | | #include <comphelper/lok.hxx> |
30 | | #include <comphelper/processfactory.hxx> |
31 | | #include <comphelper/servicehelper.hxx> |
32 | | #include <comphelper/storagehelper.hxx> |
33 | | #include <comphelper/string.hxx> |
34 | | #include <i18nutil/unicode.hxx> |
35 | | #include <LibreOfficeKit/LibreOfficeKitEnums.h> |
36 | | #include <officecfg/Office/Common.hxx> |
37 | | #include <sfx2/chalign.hxx> |
38 | | #include <sfx2/dispatch.hxx> |
39 | | #include <sfx2/docfile.hxx> |
40 | | #include <sfx2/docfilt.hxx> |
41 | | #include <sfx2/docinsert.hxx> |
42 | | #include <sfx2/filedlghelper.hxx> |
43 | | #include <sfx2/infobar.hxx> |
44 | | #include <sfx2/lokcomponenthelpers.hxx> |
45 | | #include <sfx2/lokhelper.hxx> |
46 | | #include <sfx2/msg.hxx> |
47 | | #include <sfx2/objface.hxx> |
48 | | #include <sfx2/printer.hxx> |
49 | | #include <sfx2/request.hxx> |
50 | | #include <sfx2/sfxbasecontroller.hxx> |
51 | | #include <sfx2/sidebar/Sidebar.hxx> |
52 | | #include <sfx2/sidebar/SidebarChildWindow.hxx> |
53 | | #include <sfx2/sidebar/SidebarController.hxx> |
54 | | #include <sfx2/toolbarids.hxx> |
55 | | #include <sfx2/viewfac.hxx> |
56 | | #include <svl/eitem.hxx> |
57 | | #include <svl/itemset.hxx> |
58 | | #include <svl/poolitem.hxx> |
59 | | #include <svl/stritem.hxx> |
60 | | #include <svl/voiditem.hxx> |
61 | | #include <vcl/transfer.hxx> |
62 | | #include <svtools/colorcfg.hxx> |
63 | | #include <svtools/dlgname.hxx> |
64 | | #include <svl/whiter.hxx> |
65 | | #include <svx/sidebar/SelectionChangeHandler.hxx> |
66 | | #include <svx/zoomslideritem.hxx> |
67 | | #include <editeng/editeng.hxx> |
68 | | #include <editeng/editview.hxx> |
69 | | #include <editeng/editund2.hxx> |
70 | | #include <svx/svxdlg.hxx> |
71 | | #include <sfx2/zoomitem.hxx> |
72 | | #include <vcl/commandevent.hxx> |
73 | | #include <vcl/event.hxx> |
74 | | #include <vcl/help.hxx> |
75 | | #include <vcl/settings.hxx> |
76 | | #include <vcl/svapp.hxx> |
77 | | #include <vcl/virdev.hxx> |
78 | | #include <vcl/weld/MessageDialog.hxx> |
79 | | #include <sal/log.hxx> |
80 | | #include <tools/stream.hxx> |
81 | | #include <tools/svborder.hxx> |
82 | | #include <o3tl/string_view.hxx> |
83 | | #include <o3tl/temporary.hxx> |
84 | | |
85 | | #include <unotools/streamwrap.hxx> |
86 | | |
87 | | #include <unomodel.hxx> |
88 | | #include <view.hxx> |
89 | | #include <cfgitem.hxx> |
90 | | #include <dialog.hxx> |
91 | | #include <document.hxx> |
92 | | #include <starmath.hrc> |
93 | | #include <strings.hrc> |
94 | | #include <smmod.hxx> |
95 | | #include <mathmlimport.hxx> |
96 | | #include <cursor.hxx> |
97 | | #include "accessibility.hxx" |
98 | | #include <svl/hint.hxx> |
99 | | #include <ElementsDockingWindow.hxx> |
100 | | #include <helpids.h> |
101 | | |
102 | | // space around the edit window, in pixels |
103 | | // fdo#69111: Increased border on the top so that the window is |
104 | | // easier to tear off. |
105 | 0 | #define CMD_BOX_PADDING 3 |
106 | 0 | #define CMD_BOX_PADDING_TOP 11 |
107 | | |
108 | | #define ShellClass_SmViewShell |
109 | | #include <smslots.hxx> |
110 | | |
111 | | using namespace css; |
112 | | using namespace css::accessibility; |
113 | | using namespace css::uno; |
114 | | |
115 | | static OUString GetScrollUIName(const SmViewShell& rShell) |
116 | 0 | { |
117 | 0 | const SmDocShell* pShell = rShell.GetDoc(); |
118 | 0 | if (pShell && pShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) |
119 | 0 | { |
120 | | // This one has no border on the scrolledwindow, to maximize the space |
121 | | // available when in embedded mode and minimize the difference from |
122 | | // the ole preview to give a more seamless embedded editing experience. |
123 | 0 | return "modules/smath/ui/embedwindow.ui"; |
124 | 0 | } |
125 | 0 | return "modules/smath/ui/mathwindow.ui"; |
126 | 0 | } |
127 | | |
128 | | SmGraphicWindow::SmGraphicWindow(SmViewShell& rShell) |
129 | 0 | : InterimItemWindow(&rShell.GetViewFrame().GetWindow(), GetScrollUIName(rShell), u"MathWindow"_ustr) |
130 | 0 | , nLinePixH(GetSettings().GetStyleSettings().GetScrollBarSize()) |
131 | 0 | , nColumnPixW(nLinePixH) |
132 | 0 | , nZoom(100) |
133 | | // continue to use user-scrolling to make this work equivalent to how it 'always' worked |
134 | 0 | , mxScrolledWindow(m_xBuilder->weld_scrolled_window(u"scrolledwindow"_ustr, true)) |
135 | 0 | , mxGraphic(new SmGraphicWidget(rShell, *this)) |
136 | 0 | , mxGraphicWin(new weld::CustomWeld(*m_xBuilder, u"mathview"_ustr, *mxGraphic)) |
137 | 0 | { |
138 | 0 | InitControlBase(mxGraphic->GetDrawingArea()); |
139 | |
|
140 | 0 | mxScrolledWindow->connect_hadjustment_value_changed(LINK(this, SmGraphicWindow, ScrollHdl)); |
141 | 0 | mxScrolledWindow->connect_vadjustment_value_changed(LINK(this, SmGraphicWindow, ScrollHdl)); |
142 | | |
143 | | // docking windows are usually hidden (often already done in the |
144 | | // resource) and will be shown by the sfx framework. |
145 | 0 | Hide(); |
146 | 0 | } Unexecuted instantiation: SmGraphicWindow::SmGraphicWindow(SmViewShell&) Unexecuted instantiation: SmGraphicWindow::SmGraphicWindow(SmViewShell&) |
147 | | |
148 | | void SmGraphicWindow::dispose() |
149 | 0 | { |
150 | 0 | InitControlBase(nullptr); |
151 | 0 | mxGraphicWin.reset(); |
152 | 0 | mxGraphic.reset(); |
153 | 0 | mxScrolledWindow.reset(); |
154 | 0 | InterimItemWindow::dispose(); |
155 | 0 | } |
156 | | |
157 | | SmGraphicWindow::~SmGraphicWindow() |
158 | 0 | { |
159 | 0 | disposeOnce(); |
160 | 0 | } |
161 | | |
162 | | void SmGraphicWindow::Resize() |
163 | 0 | { |
164 | 0 | InterimItemWindow::Resize(); |
165 | | |
166 | | // get the new output-size in pixel |
167 | 0 | Size aOutPixSz = GetOutputSizePixel(); |
168 | | |
169 | | // determine the size of the output-area and if we need scrollbars |
170 | 0 | const auto nScrSize = mxScrolledWindow->get_scroll_thickness(); |
171 | 0 | bool bVVisible = false; // by default no vertical-ScrollBar |
172 | 0 | bool bHVisible = false; // by default no horizontal-ScrollBar |
173 | 0 | bool bChanged; // determines if a visibility was changed |
174 | 0 | do |
175 | 0 | { |
176 | 0 | bChanged = false; |
177 | | |
178 | | // does we need a vertical ScrollBar |
179 | 0 | if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible ) |
180 | 0 | { |
181 | 0 | bHVisible = true; |
182 | 0 | aOutPixSz.AdjustHeight( -nScrSize ); |
183 | 0 | bChanged = true; |
184 | 0 | } |
185 | | |
186 | | // does we need a horizontal ScrollBar |
187 | 0 | if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible ) |
188 | 0 | { |
189 | 0 | bVVisible = true; |
190 | 0 | aOutPixSz.AdjustWidth( -nScrSize ); |
191 | 0 | bChanged = true; |
192 | 0 | } |
193 | |
|
194 | 0 | } |
195 | 0 | while ( bChanged ); // until no visibility has changed |
196 | | |
197 | | // store the old offset and map-mode |
198 | 0 | MapMode aMap(GetGraphicMapMode()); |
199 | 0 | Point aOldPixOffset(aPixOffset); |
200 | | |
201 | | // justify (right/bottom borders should never exceed the virtual window) |
202 | 0 | Size aPixDelta; |
203 | 0 | if ( aPixOffset.X() < 0 && |
204 | 0 | aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() ) |
205 | 0 | aPixDelta.setWidth( |
206 | 0 | aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() ) ); |
207 | 0 | if ( aPixOffset.Y() < 0 && |
208 | 0 | aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() ) |
209 | 0 | aPixDelta.setHeight( |
210 | 0 | aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() ) ); |
211 | 0 | if ( aPixDelta.Width() || aPixDelta.Height() ) |
212 | 0 | { |
213 | 0 | aPixOffset.AdjustX(aPixDelta.Width() ); |
214 | 0 | aPixOffset.AdjustY(aPixDelta.Height() ); |
215 | 0 | } |
216 | | |
217 | | // for axis without scrollbar restore the origin |
218 | 0 | if ( !bVVisible || !bHVisible ) |
219 | 0 | { |
220 | 0 | aPixOffset = Point( |
221 | 0 | bHVisible |
222 | 0 | ? aPixOffset.X() |
223 | 0 | : (aOutPixSz.Width()-aTotPixSz.Width()) / 2, |
224 | 0 | bVVisible |
225 | 0 | ? aPixOffset.Y() |
226 | 0 | : (aOutPixSz.Height()-aTotPixSz.Height()) / 2 ); |
227 | 0 | } |
228 | 0 | if (bHVisible && mxScrolledWindow->get_hpolicy() == VclPolicyType::NEVER) |
229 | 0 | aPixOffset.setX( 0 ); |
230 | 0 | if (bVVisible && mxScrolledWindow->get_vpolicy() == VclPolicyType::NEVER) |
231 | 0 | aPixOffset.setY( 0 ); |
232 | | |
233 | | // select the shifted map-mode |
234 | 0 | if (aPixOffset != aOldPixOffset) |
235 | 0 | SetGraphicMapMode(aMap); |
236 | | |
237 | | // show or hide scrollbars |
238 | 0 | mxScrolledWindow->set_vpolicy(bVVisible ? VclPolicyType::ALWAYS : VclPolicyType::NEVER); |
239 | 0 | mxScrolledWindow->set_hpolicy(bHVisible ? VclPolicyType::ALWAYS : VclPolicyType::NEVER); |
240 | | |
241 | | // resize scrollbars and set their ranges |
242 | 0 | if ( bHVisible ) |
243 | 0 | { |
244 | 0 | mxScrolledWindow->hadjustment_configure(-aPixOffset.X(), aTotPixSz.Width(), nColumnPixW, |
245 | 0 | aOutPixSz.Width(), aOutPixSz.Width()); |
246 | 0 | } |
247 | 0 | if ( bVVisible ) |
248 | 0 | { |
249 | 0 | mxScrolledWindow->vadjustment_configure(-aPixOffset.Y(), aTotPixSz.Height(), nLinePixH, |
250 | 0 | aOutPixSz.Height(), aOutPixSz.Height()); |
251 | 0 | } |
252 | 0 | } |
253 | | |
254 | | IMPL_LINK_NOARG(SmGraphicWindow, ScrollHdl, weld::ScrolledWindow&, void) |
255 | 0 | { |
256 | 0 | MapMode aMap(GetGraphicMapMode()); |
257 | 0 | Point aNewPixOffset(aPixOffset); |
258 | | |
259 | | // scrolling horizontally? |
260 | 0 | if (mxScrolledWindow->get_hpolicy() == VclPolicyType::ALWAYS) |
261 | 0 | aNewPixOffset.setX(-mxScrolledWindow->hadjustment_get_value()); |
262 | | |
263 | | // scrolling vertically? |
264 | 0 | if (mxScrolledWindow->get_vpolicy() == VclPolicyType::ALWAYS) |
265 | 0 | aNewPixOffset.setY(-mxScrolledWindow->vadjustment_get_value()); |
266 | | |
267 | | // scrolling? |
268 | 0 | if (aPixOffset == aNewPixOffset) |
269 | 0 | return; |
270 | | |
271 | | // recompute the logical scroll units |
272 | 0 | aPixOffset = aNewPixOffset; |
273 | |
|
274 | 0 | SetGraphicMapMode(aMap); |
275 | 0 | } |
276 | | |
277 | | void SmGraphicWindow::SetGraphicMapMode(const MapMode& rNewMapMode) |
278 | 0 | { |
279 | 0 | OutputDevice& rDevice = mxGraphic->GetOutputDevice(); |
280 | 0 | MapMode aMap( rNewMapMode ); |
281 | 0 | aMap.SetOrigin( aMap.GetOrigin() + rDevice.PixelToLogic( aPixOffset, aMap ) ); |
282 | 0 | rDevice.SetMapMode( aMap ); |
283 | 0 | mxGraphic->Invalidate(); |
284 | 0 | } |
285 | | |
286 | | MapMode SmGraphicWindow::GetGraphicMapMode() const |
287 | 0 | { |
288 | 0 | OutputDevice& rDevice = mxGraphic->GetOutputDevice(); |
289 | 0 | MapMode aMap(rDevice.GetMapMode()); |
290 | 0 | aMap.SetOrigin( aMap.GetOrigin() - rDevice.PixelToLogic( aPixOffset ) ); |
291 | 0 | return aMap; |
292 | 0 | } |
293 | | |
294 | | void SmGraphicWindow::SetTotalSize( const Size& rNewSize ) |
295 | 0 | { |
296 | 0 | aTotPixSz = mxGraphic->GetOutputDevice().LogicToPixel(rNewSize); |
297 | 0 | Resize(); |
298 | 0 | } |
299 | | |
300 | | Size SmGraphicWindow::GetTotalSize() const |
301 | 0 | { |
302 | 0 | return mxGraphic->GetOutputDevice().PixelToLogic(aTotPixSz); |
303 | 0 | } |
304 | | |
305 | | void SmGraphicWindow::ShowContextMenu(const CommandEvent& rCEvt) |
306 | 0 | { |
307 | 0 | GetParent()->ToTop(); |
308 | 0 | Point aPos(5, 5); |
309 | 0 | if (rCEvt.IsMouseEvent()) |
310 | 0 | aPos = rCEvt.GetMousePosPixel(); |
311 | | |
312 | | // added for replaceability of context menus |
313 | 0 | SfxDispatcher::ExecutePopup( this, &aPos ); |
314 | 0 | } |
315 | | |
316 | | SmGraphicWidget::SmGraphicWidget(SmViewShell& rShell, SmGraphicWindow& rGraphicWindow) |
317 | 0 | : mrGraphicWindow(rGraphicWindow) |
318 | 0 | , bIsCursorVisible(false) |
319 | 0 | , bIsLineVisible(false) |
320 | 0 | , aCaretBlinkTimer("SmGraphicWidget aCaretBlinkTimer") |
321 | 0 | , mrViewShell(rShell) |
322 | 0 | { |
323 | 0 | } |
324 | | |
325 | | void SmGraphicWidget::SetDrawingArea(weld::DrawingArea* pDrawingArea) |
326 | 0 | { |
327 | 0 | weld::CustomWidgetController::SetDrawingArea(pDrawingArea); |
328 | |
|
329 | 0 | OutputDevice& rDevice = GetOutputDevice(); |
330 | |
|
331 | 0 | rDevice.EnableRTL(GetDoc()->GetFormat().IsRightToLeft()); |
332 | 0 | rDevice.SetBackground( |
333 | 0 | SmModule::get()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor); |
334 | |
|
335 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
336 | 0 | { |
337 | | // Disable map mode, so that it's possible to send mouse event coordinates |
338 | | // directly in twips. |
339 | 0 | rDevice.EnableMapMode(false); |
340 | 0 | } |
341 | 0 | else |
342 | 0 | { |
343 | 0 | rDevice.SetMapMode(MapMode(SmMapUnit(), Point(), 1.0, 1.0)); |
344 | 0 | } |
345 | |
|
346 | 0 | SetTotalSize(); |
347 | |
|
348 | 0 | SetHelpId(HID_SMA_WIN_DOCUMENT); |
349 | |
|
350 | 0 | ShowLine(false); |
351 | 0 | CaretBlinkInit(); |
352 | 0 | } |
353 | | |
354 | | SmGraphicWidget::~SmGraphicWidget() |
355 | 0 | { |
356 | 0 | if (mxAccessible.is()) |
357 | 0 | mxAccessible->dispose(); |
358 | 0 | mxAccessible.clear(); |
359 | 0 | CaretBlinkStop(); |
360 | 0 | } |
361 | | |
362 | 0 | SmDocShell* SmGraphicWidget::GetDoc() { return GetView().GetDoc(); } |
363 | | |
364 | | SmCursor& SmGraphicWidget::GetCursor() |
365 | 0 | { |
366 | 0 | assert(GetDoc()); |
367 | 0 | return GetDoc()->GetCursor(); |
368 | 0 | } |
369 | | |
370 | | bool SmGraphicWidget::MouseButtonDown(const MouseEvent& rMEvt) |
371 | 0 | { |
372 | 0 | GrabFocus(); |
373 | | |
374 | | // set formula-cursor and selection of edit window according to the |
375 | | // position clicked at |
376 | |
|
377 | 0 | SAL_WARN_IF( rMEvt.GetClicks() == 0, "starmath", "0 clicks" ); |
378 | 0 | if ( !rMEvt.IsLeft() ) |
379 | 0 | return true; |
380 | | |
381 | 0 | OutputDevice& rDevice = GetOutputDevice(); |
382 | | // get click position relative to formula |
383 | 0 | Point aPos(rDevice.PixelToLogic(rMEvt.GetPosPixel()) - GetFormulaDrawPos()); |
384 | |
|
385 | 0 | const SmNode *pTree = GetDoc()->GetFormulaTree(); |
386 | 0 | if (!pTree) |
387 | 0 | return true; |
388 | | |
389 | 0 | SmEditWindow* pEdit = GetView().GetEditWindow(); |
390 | |
|
391 | 0 | if (SmViewShell::IsInlineEditEnabled()) { |
392 | 0 | GetCursor().MoveTo(&rDevice, aPos, !rMEvt.IsShift()); |
393 | 0 | GetView().InvalidateSlots(); |
394 | | // 'on grab' window events are missing in lok, do it explicitly |
395 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
396 | 0 | SetIsCursorVisible(true); |
397 | 0 | return true; |
398 | 0 | } |
399 | 0 | const SmNode *pNode = nullptr; |
400 | | // if it was clicked inside the formula then get the appropriate node |
401 | 0 | if (pTree->OrientedDist(aPos) <= 0) |
402 | 0 | pNode = pTree->FindRectClosestTo(aPos); |
403 | |
|
404 | 0 | if (!pNode) |
405 | 0 | return true; |
406 | | |
407 | 0 | if (!pEdit) |
408 | 0 | return true; |
409 | | |
410 | | // set selection to the beginning of the token |
411 | 0 | pEdit->SetSelection(pNode->GetSelection()); |
412 | 0 | SetCursor(pNode); |
413 | | |
414 | | // allow for immediate editing and |
415 | | //! implicitly synchronize the cursor position mark in this window |
416 | 0 | pEdit->GrabFocus(); |
417 | |
|
418 | 0 | return true; |
419 | 0 | } |
420 | | |
421 | | bool SmGraphicWidget::MouseMove(const MouseEvent &rMEvt) |
422 | 0 | { |
423 | 0 | if (rMEvt.IsLeft() && SmViewShell::IsInlineEditEnabled()) |
424 | 0 | { |
425 | 0 | OutputDevice& rDevice = GetOutputDevice(); |
426 | 0 | Point aPos(rDevice.PixelToLogic(rMEvt.GetPosPixel()) - GetFormulaDrawPos()); |
427 | 0 | GetCursor().MoveTo(&rDevice, aPos, false); |
428 | |
|
429 | 0 | CaretBlinkStop(); |
430 | 0 | SetIsCursorVisible(true); |
431 | 0 | CaretBlinkStart(); |
432 | 0 | RepaintViewShellDoc(); |
433 | 0 | } |
434 | 0 | return true; |
435 | 0 | } |
436 | | |
437 | | void SmGraphicWidget::GetFocus() |
438 | 0 | { |
439 | 0 | if (!SmViewShell::IsInlineEditEnabled()) |
440 | 0 | return; |
441 | 0 | if (SmEditWindow* pEdit = GetView().GetEditWindow()) |
442 | 0 | pEdit->Flush(); |
443 | 0 | SetIsCursorVisible(true); |
444 | 0 | ShowLine(true); |
445 | 0 | CaretBlinkStart(); |
446 | 0 | RepaintViewShellDoc(); |
447 | 0 | } |
448 | | |
449 | | void SmGraphicWidget::LoseFocus() |
450 | 0 | { |
451 | 0 | if (mxAccessible.is()) |
452 | 0 | { |
453 | 0 | uno::Any aOldValue, aNewValue; |
454 | 0 | aOldValue <<= AccessibleStateType::FOCUSED; |
455 | | // aNewValue remains empty |
456 | 0 | mxAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED, |
457 | 0 | aOldValue, aNewValue ); |
458 | 0 | } |
459 | 0 | if (!SmViewShell::IsInlineEditEnabled()) |
460 | 0 | return; |
461 | 0 | SetIsCursorVisible(false); |
462 | 0 | ShowLine(false); |
463 | 0 | CaretBlinkStop(); |
464 | 0 | RepaintViewShellDoc(); |
465 | 0 | } |
466 | | |
467 | | void SmGraphicWidget::RepaintViewShellDoc() |
468 | 0 | { |
469 | 0 | if (SmDocShell* pDoc = GetDoc()) |
470 | 0 | pDoc->Repaint(); |
471 | 0 | } |
472 | | |
473 | | IMPL_LINK_NOARG(SmGraphicWidget, CaretBlinkTimerHdl, Timer *, void) |
474 | 0 | { |
475 | 0 | if (IsCursorVisible()) |
476 | 0 | SetIsCursorVisible(false); |
477 | 0 | else |
478 | 0 | SetIsCursorVisible(true); |
479 | |
|
480 | 0 | RepaintViewShellDoc(); |
481 | 0 | } |
482 | | |
483 | | void SmGraphicWidget::CaretBlinkInit() |
484 | 0 | { |
485 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
486 | 0 | return; // No blinking in lok case |
487 | 0 | aCaretBlinkTimer.SetInvokeHandler(LINK(this, SmGraphicWidget, CaretBlinkTimerHdl)); |
488 | 0 | aCaretBlinkTimer.SetTimeout(Application::GetSettings().GetStyleSettings().GetCursorBlinkTime()); |
489 | 0 | } |
490 | | |
491 | | void SmGraphicWidget::CaretBlinkStart() |
492 | 0 | { |
493 | 0 | if (!SmViewShell::IsInlineEditEnabled() || comphelper::LibreOfficeKit::isActive()) |
494 | 0 | return; |
495 | 0 | if (aCaretBlinkTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME) |
496 | 0 | aCaretBlinkTimer.Start(); |
497 | 0 | } |
498 | | |
499 | | void SmGraphicWidget::CaretBlinkStop() |
500 | 0 | { |
501 | 0 | if (!SmViewShell::IsInlineEditEnabled() || comphelper::LibreOfficeKit::isActive()) |
502 | 0 | return; |
503 | 0 | aCaretBlinkTimer.Stop(); |
504 | 0 | } |
505 | | |
506 | | // shows or hides the formula-cursor depending on 'bShow' is true or not |
507 | | void SmGraphicWidget::ShowCursor(bool bShow) |
508 | 0 | { |
509 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
510 | 0 | return; |
511 | | |
512 | 0 | bool bInvert = bShow != IsCursorVisible(); |
513 | 0 | if (bInvert) |
514 | 0 | InvertFocusRect(GetOutputDevice(), aCursorRect); |
515 | |
|
516 | 0 | SetIsCursorVisible(bShow); |
517 | 0 | } |
518 | | |
519 | | void SmGraphicWidget::ShowLine(bool bShow) |
520 | 0 | { |
521 | 0 | if (!SmViewShell::IsInlineEditEnabled()) |
522 | 0 | return; |
523 | | |
524 | 0 | bIsLineVisible = bShow; |
525 | 0 | } |
526 | | |
527 | | void SmGraphicWidget::SetIsCursorVisible(bool bVis) |
528 | 0 | { |
529 | 0 | bIsCursorVisible = bVis; |
530 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
531 | 0 | { |
532 | 0 | mrViewShell.SendCaretToLOK(); |
533 | 0 | mrViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, |
534 | 0 | OString::boolean(bVis)); |
535 | 0 | } |
536 | 0 | } |
537 | | |
538 | | void SmGraphicWidget::SetCursor(const SmNode *pNode) |
539 | 0 | { |
540 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
541 | 0 | return; |
542 | | |
543 | 0 | const SmNode *pTree = GetDoc()->GetFormulaTree(); |
544 | | |
545 | | // get appropriate rectangle |
546 | 0 | Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()), |
547 | 0 | aTLPos (GetFormulaDrawPos() + aOffset); |
548 | 0 | aTLPos.AdjustX( -(pNode->GetItalicLeftSpace()) ); |
549 | 0 | Size aSize (pNode->GetItalicSize()); |
550 | |
|
551 | 0 | SetCursor(tools::Rectangle(aTLPos, aSize)); |
552 | 0 | } |
553 | | |
554 | | void SmGraphicWidget::SetCursor(const tools::Rectangle &rRect) |
555 | | // sets cursor to new position (rectangle) 'rRect'. |
556 | | // The old cursor will be removed, and the new one will be shown if |
557 | | // that is activated in the ConfigItem |
558 | 0 | { |
559 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
560 | 0 | return; |
561 | | |
562 | 0 | if (IsCursorVisible()) |
563 | 0 | ShowCursor(false); // clean up remainings of old cursor |
564 | 0 | aCursorRect = rRect; |
565 | 0 | if (SmModule::get()->GetConfig()->IsShowFormulaCursor()) |
566 | 0 | ShowCursor(true); // draw new cursor |
567 | 0 | } |
568 | | |
569 | | const SmNode * SmGraphicWidget::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol) |
570 | | // looks for a VISIBLE node in the formula tree with its token at |
571 | | // (or around) the position 'nRow', 'nCol' in the edit window |
572 | | // (row and column numbering starts with 1 there!). |
573 | | // If there is such a node the formula-cursor is set to cover that nodes |
574 | | // rectangle. If not the formula-cursor will be hidden. |
575 | | // In any case the search result is being returned. |
576 | 0 | { |
577 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
578 | 0 | return nullptr; |
579 | | |
580 | | // find visible node with token at nRow, nCol |
581 | 0 | const SmNode *pTree = GetDoc()->GetFormulaTree(), |
582 | 0 | *pNode = nullptr; |
583 | 0 | if (pTree) |
584 | 0 | pNode = pTree->FindTokenAt(nRow, nCol); |
585 | |
|
586 | 0 | if (pNode) |
587 | 0 | SetCursor(pNode); |
588 | 0 | else |
589 | 0 | ShowCursor(false); |
590 | |
|
591 | 0 | return pNode; |
592 | 0 | } |
593 | | |
594 | | void SmGraphicWidget::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) |
595 | 0 | { |
596 | 0 | assert(GetDoc()); |
597 | 0 | SmDocShell& rDoc = *GetDoc(); |
598 | 0 | Point aPoint; |
599 | |
|
600 | 0 | rDoc.DrawFormula(rRenderContext, aPoint, true); //! modifies aPoint to be the topleft |
601 | | //! corner of the formula |
602 | 0 | aFormulaDrawPos = aPoint; |
603 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
604 | 0 | { |
605 | | //Draw cursor if any... |
606 | 0 | if (rDoc.HasCursor() && IsLineVisible()) |
607 | 0 | rDoc.GetCursor().Draw(rRenderContext, aPoint, IsCursorVisible()); |
608 | 0 | } |
609 | 0 | else |
610 | 0 | { |
611 | 0 | SetIsCursorVisible(false); // (old) cursor must be drawn again |
612 | |
|
613 | 0 | if (const SmEditWindow* pEdit = GetView().GetEditWindow()) |
614 | 0 | { // get new position for formula-cursor (for possible altered formula) |
615 | 0 | sal_Int32 nRow; |
616 | 0 | sal_uInt16 nCol; |
617 | 0 | SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol); |
618 | 0 | const SmNode *pFound = SetCursorPos(static_cast<sal_uInt16>(nRow), nCol); |
619 | |
|
620 | 0 | if (pFound && SmModule::get()->GetConfig()->IsShowFormulaCursor()) |
621 | 0 | ShowCursor(true); |
622 | 0 | } |
623 | 0 | } |
624 | 0 | } |
625 | | |
626 | | void SmGraphicWidget::SetTotalSize() |
627 | 0 | { |
628 | 0 | assert(GetDoc()); |
629 | 0 | OutputDevice& rDevice = GetOutputDevice(); |
630 | 0 | const Size aTmp(rDevice.PixelToLogic(rDevice.LogicToPixel(GetDoc()->GetSize()))); |
631 | 0 | if (aTmp != mrGraphicWindow.GetTotalSize()) |
632 | 0 | mrGraphicWindow.SetTotalSize(aTmp); |
633 | 0 | } |
634 | | |
635 | | namespace |
636 | | { |
637 | | SmBracketType BracketTypeOf(sal_uInt32 c) |
638 | 0 | { |
639 | 0 | switch (c) |
640 | 0 | { |
641 | 0 | case '(': |
642 | 0 | case ')': |
643 | 0 | return SmBracketType::Round; |
644 | 0 | case '[': |
645 | 0 | case ']': |
646 | 0 | return SmBracketType::Square; |
647 | 0 | case '{': |
648 | 0 | case '}': |
649 | 0 | return SmBracketType::Curly; |
650 | 0 | } |
651 | 0 | assert(false); // Unreachable |
652 | 0 | return SmBracketType::Round; |
653 | 0 | } |
654 | | |
655 | | bool CharInput(sal_uInt32 c, SmCursor& rCursor, OutputDevice& rDevice) |
656 | 0 | { |
657 | 0 | switch (c) |
658 | 0 | { |
659 | 0 | case 0: |
660 | 0 | return false; |
661 | 0 | case ' ': |
662 | 0 | rCursor.InsertElement(BlankElement); |
663 | 0 | break; |
664 | 0 | case '!': |
665 | 0 | rCursor.InsertElement(FactorialElement); |
666 | 0 | break; |
667 | 0 | case '%': |
668 | 0 | rCursor.InsertElement(PercentElement); |
669 | 0 | break; |
670 | 0 | case '*': |
671 | 0 | rCursor.InsertElement(CDotElement); |
672 | 0 | break; |
673 | 0 | case '+': |
674 | 0 | rCursor.InsertElement(PlusElement); |
675 | 0 | break; |
676 | 0 | case '-': |
677 | 0 | rCursor.InsertElement(MinusElement); |
678 | 0 | break; |
679 | 0 | case '<': |
680 | 0 | rCursor.InsertElement(LessThanElement); |
681 | 0 | break; |
682 | 0 | case '=': |
683 | 0 | rCursor.InsertElement(EqualElement); |
684 | 0 | break; |
685 | 0 | case '>': |
686 | 0 | rCursor.InsertElement(GreaterThanElement); |
687 | 0 | break; |
688 | 0 | case '^': |
689 | 0 | rCursor.InsertSubSup(RSUP); |
690 | 0 | break; |
691 | 0 | case '_': |
692 | 0 | rCursor.InsertSubSup(RSUB); |
693 | 0 | break; |
694 | 0 | case '/': |
695 | 0 | rCursor.InsertFraction(); |
696 | 0 | break; |
697 | 0 | case '(': |
698 | 0 | case '[': |
699 | 0 | case '{': |
700 | 0 | rCursor.InsertBrackets(BracketTypeOf(c)); |
701 | 0 | break; |
702 | 0 | case ')': |
703 | 0 | case ']': |
704 | 0 | case '}': |
705 | 0 | if (rCursor.IsAtTailOfBracket(BracketTypeOf(c))) |
706 | 0 | { |
707 | 0 | rCursor.Move(&rDevice, MoveRight); |
708 | 0 | break; |
709 | 0 | } |
710 | 0 | [[fallthrough]]; |
711 | 0 | default: |
712 | 0 | rCursor.InsertText(OUString(&c, 1)); |
713 | 0 | break; |
714 | 0 | } |
715 | 0 | return true; |
716 | 0 | } |
717 | | } |
718 | | |
719 | | bool SmGraphicWidget::KeyInput(const KeyEvent& rKEvt) |
720 | 0 | { |
721 | 0 | if (rKEvt.GetKeyCode().GetCode() == KEY_F1) |
722 | 0 | { |
723 | 0 | GetView().StartMainHelp(); |
724 | 0 | return true; |
725 | 0 | } |
726 | | |
727 | 0 | if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE) |
728 | 0 | { |
729 | | // Terminate possible InPlace mode |
730 | 0 | return GetView().Escape(); |
731 | 0 | } |
732 | | |
733 | 0 | if (!SmViewShell::IsInlineEditEnabled()) |
734 | 0 | return GetView().KeyInput(rKEvt); |
735 | | |
736 | 0 | bool bConsumed = true; |
737 | |
|
738 | 0 | SmCursor& rCursor = GetCursor(); |
739 | 0 | switch (rKEvt.GetKeyCode().GetFunction()) |
740 | 0 | { |
741 | 0 | case KeyFuncType::COPY: |
742 | 0 | rCursor.Copy(&mrGraphicWindow); |
743 | 0 | break; |
744 | 0 | case KeyFuncType::CUT: |
745 | 0 | rCursor.Cut(&mrGraphicWindow); |
746 | 0 | break; |
747 | 0 | case KeyFuncType::PASTE: |
748 | 0 | rCursor.Paste(&mrGraphicWindow); |
749 | 0 | break; |
750 | 0 | case KeyFuncType::UNDO: |
751 | 0 | GetDoc()->Execute(o3tl::temporary(SfxRequest(*GetView().GetFrame(), SID_UNDO))); |
752 | 0 | break; |
753 | 0 | case KeyFuncType::REDO: |
754 | 0 | GetDoc()->Execute(o3tl::temporary(SfxRequest(*GetView().GetFrame(), SID_REDO))); |
755 | 0 | break; |
756 | 0 | default: |
757 | 0 | switch (rKEvt.GetKeyCode().GetCode()) |
758 | 0 | { |
759 | 0 | case KEY_LEFT: |
760 | 0 | rCursor.Move(&GetOutputDevice(), MoveLeft, !rKEvt.GetKeyCode().IsShift()); |
761 | 0 | break; |
762 | 0 | case KEY_RIGHT: |
763 | 0 | rCursor.Move(&GetOutputDevice(), MoveRight, !rKEvt.GetKeyCode().IsShift()); |
764 | 0 | break; |
765 | 0 | case KEY_UP: |
766 | 0 | rCursor.Move(&GetOutputDevice(), MoveUp, !rKEvt.GetKeyCode().IsShift()); |
767 | 0 | break; |
768 | 0 | case KEY_DOWN: |
769 | 0 | rCursor.Move(&GetOutputDevice(), MoveDown, !rKEvt.GetKeyCode().IsShift()); |
770 | 0 | break; |
771 | 0 | case KEY_RETURN: |
772 | 0 | if (!rKEvt.GetKeyCode().IsShift()) |
773 | 0 | rCursor.InsertRow(); |
774 | 0 | break; |
775 | 0 | case KEY_DELETE: |
776 | 0 | if (!rCursor.HasSelection()) |
777 | 0 | { |
778 | 0 | rCursor.Move(&GetOutputDevice(), MoveRight, false); |
779 | 0 | if (rCursor.HasComplexSelection()) |
780 | 0 | break; |
781 | 0 | } |
782 | 0 | rCursor.Delete(); |
783 | 0 | break; |
784 | 0 | case KEY_BACKSPACE: |
785 | 0 | rCursor.DeletePrev(&GetOutputDevice()); |
786 | 0 | break; |
787 | 0 | default: |
788 | 0 | if (!CharInput(rKEvt.GetCharCode(), rCursor, GetOutputDevice())) |
789 | 0 | bConsumed = GetView().KeyInput(rKEvt); |
790 | 0 | } |
791 | 0 | } |
792 | | |
793 | 0 | GetView().InvalidateSlots(); |
794 | 0 | CaretBlinkStop(); |
795 | 0 | CaretBlinkStart(); |
796 | 0 | SetIsCursorVisible(true); |
797 | 0 | RepaintViewShellDoc(); |
798 | |
|
799 | 0 | return bConsumed; |
800 | 0 | } |
801 | | |
802 | | bool SmGraphicWidget::Command(const CommandEvent& rCEvt) |
803 | 0 | { |
804 | 0 | bool bCallBase = true; |
805 | 0 | if (!GetView().GetViewFrame().GetFrame().IsInPlace()) |
806 | 0 | { |
807 | 0 | switch ( rCEvt.GetCommand() ) |
808 | 0 | { |
809 | 0 | case CommandEventId::ContextMenu: |
810 | | // purely for "ExecutePopup" taking a vcl::Window and |
811 | | // we assume SmGraphicWindow 0,0 is at SmEditWindow 0,0 |
812 | 0 | mrGraphicWindow.ShowContextMenu(rCEvt); |
813 | 0 | bCallBase = false; |
814 | 0 | break; |
815 | | |
816 | 0 | case CommandEventId::Wheel: |
817 | 0 | { |
818 | 0 | const CommandWheelData* pWData = rCEvt.GetWheelData(); |
819 | 0 | if ( pWData && CommandWheelMode::ZOOM == pWData->GetMode() ) |
820 | 0 | { |
821 | 0 | sal_uInt16 nTmpZoom = mrGraphicWindow.GetZoom(); |
822 | 0 | if( 0 > pWData->GetDelta() ) |
823 | 0 | nTmpZoom -= 10; |
824 | 0 | else |
825 | 0 | nTmpZoom += 10; |
826 | 0 | mrGraphicWindow.SetZoom(nTmpZoom); |
827 | 0 | bCallBase = false; |
828 | 0 | } |
829 | 0 | break; |
830 | 0 | } |
831 | 0 | case CommandEventId::GestureZoom: |
832 | 0 | { |
833 | 0 | const CommandGestureZoomData* pData = rCEvt.GetGestureZoomData(); |
834 | 0 | if (pData) |
835 | 0 | { |
836 | 0 | if (pData->meEventType == GestureEventZoomType::Begin) |
837 | 0 | { |
838 | 0 | mfLastZoomScale = pData->mfScaleDelta; |
839 | 0 | } |
840 | 0 | else if (pData->meEventType == GestureEventZoomType::Update) |
841 | 0 | { |
842 | 0 | double deltaBetweenEvents = (pData->mfScaleDelta - mfLastZoomScale) / mfLastZoomScale; |
843 | 0 | mfLastZoomScale = pData->mfScaleDelta; |
844 | | |
845 | | // Accumulate fractional zoom to avoid small zoom changes from being ignored |
846 | 0 | mfAccumulatedZoom += deltaBetweenEvents; |
847 | 0 | int nZoomChangePercent = mfAccumulatedZoom * 100; |
848 | 0 | mfAccumulatedZoom -= nZoomChangePercent / 100.0; |
849 | |
|
850 | 0 | sal_uInt16 nZoom = mrGraphicWindow.GetZoom(); |
851 | 0 | nZoom += nZoomChangePercent; |
852 | 0 | mrGraphicWindow.SetZoom(nZoom); |
853 | 0 | } |
854 | 0 | bCallBase = false; |
855 | 0 | } |
856 | 0 | break; |
857 | 0 | } |
858 | | |
859 | 0 | default: break; |
860 | 0 | } |
861 | 0 | } |
862 | | |
863 | 0 | switch (rCEvt.GetCommand()) |
864 | 0 | { |
865 | 0 | case CommandEventId::ExtTextInput: |
866 | 0 | if (SmViewShell::IsInlineEditEnabled()) |
867 | 0 | { |
868 | 0 | const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData(); |
869 | 0 | assert(pData); |
870 | 0 | const OUString& rText = pData->GetText(); |
871 | 0 | SmCursor& rCursor = GetCursor(); |
872 | 0 | OutputDevice& rDevice = GetOutputDevice(); |
873 | 0 | for (sal_Int32 i = 0; i < rText.getLength();) |
874 | 0 | CharInput(rText.iterateCodePoints(&i), rCursor, rDevice); |
875 | 0 | bCallBase = false; |
876 | 0 | } |
877 | 0 | break; |
878 | 0 | default: |
879 | 0 | break; |
880 | 0 | } |
881 | 0 | return !bCallBase; |
882 | 0 | } |
883 | | |
884 | | void SmGraphicWindow::SetZoom(sal_uInt16 Factor) |
885 | 0 | { |
886 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
887 | 0 | return; |
888 | 0 | nZoom = std::clamp(Factor, MINZOOM, MAXZOOM); |
889 | 0 | double fFraction = nZoom / 100.0; |
890 | 0 | SetGraphicMapMode(MapMode(SmMapUnit(), Point(), fFraction, fFraction)); |
891 | 0 | mxGraphic->SetTotalSize(); |
892 | 0 | SmViewShell& rViewSh = mxGraphic->GetView(); |
893 | 0 | rViewSh.GetViewFrame().GetBindings().Invalidate(SID_ATTR_ZOOM); |
894 | 0 | rViewSh.GetViewFrame().GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER); |
895 | 0 | } |
896 | | |
897 | | void SmGraphicWindow::ZoomToFitInWindow() |
898 | 0 | { |
899 | | // set defined mapmode before calling 'LogicToPixel' below |
900 | 0 | SetGraphicMapMode(MapMode(SmMapUnit())); |
901 | |
|
902 | 0 | assert(mxGraphic->GetDoc()); |
903 | 0 | Size aSize(mxGraphic->GetOutputDevice().LogicToPixel(mxGraphic->GetDoc()->GetSize())); |
904 | 0 | Size aWindowSize(GetSizePixel()); |
905 | |
|
906 | 0 | if (!aSize.IsEmpty()) |
907 | 0 | { |
908 | 0 | tools::Long nVal = std::min ((85 * aWindowSize.Width()) / aSize.Width(), |
909 | 0 | (85 * aWindowSize.Height()) / aSize.Height()); |
910 | 0 | SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) ); |
911 | 0 | } |
912 | 0 | } |
913 | | |
914 | | rtl::Reference<comphelper::OAccessible> SmGraphicWidget::CreateAccessible() |
915 | 0 | { |
916 | 0 | if (!mxAccessible.is()) |
917 | 0 | { |
918 | 0 | mxAccessible = new SmGraphicAccessible( this ); |
919 | 0 | } |
920 | 0 | return mxAccessible; |
921 | 0 | } |
922 | | |
923 | | /**************************************************************************/ |
924 | | SmGraphicController::SmGraphicController(SmGraphicWidget &rSmGraphic, |
925 | | sal_uInt16 nId_, |
926 | | SfxBindings &rBindings) : |
927 | 0 | SfxControllerItem(nId_, rBindings), |
928 | 0 | rGraphic(rSmGraphic) |
929 | 0 | { |
930 | 0 | } |
931 | | |
932 | | void SmGraphicController::StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) |
933 | 0 | { |
934 | 0 | rGraphic.SetTotalSize(); |
935 | 0 | rGraphic.Invalidate(); |
936 | 0 | SfxControllerItem::StateChangedAtToolBoxControl (nSID, eState, pState); |
937 | 0 | } |
938 | | |
939 | | /**************************************************************************/ |
940 | | SmEditController::SmEditController(SmEditWindow &rSmEdit, |
941 | | sal_uInt16 nId_, |
942 | | SfxBindings &rBindings) : |
943 | 0 | SfxControllerItem(nId_, rBindings), |
944 | 0 | rEdit(rSmEdit) |
945 | 0 | { |
946 | 0 | } |
947 | | |
948 | | void SmEditController::StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) |
949 | 0 | { |
950 | 0 | const SfxStringItem *pItem = dynamic_cast<const SfxStringItem*>( pState); |
951 | |
|
952 | 0 | if ((pItem != nullptr) && (rEdit.GetText() != pItem->GetValue())) |
953 | 0 | rEdit.SetText(pItem->GetValue()); |
954 | 0 | SfxControllerItem::StateChangedAtToolBoxControl (nSID, eState, pState); |
955 | 0 | } |
956 | | |
957 | | /**************************************************************************/ |
958 | | SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings& rBindings_, SfxChildWindow* pChildWindow, |
959 | | vcl::Window* pParent) |
960 | 0 | : SfxDockingWindow(rBindings_, pChildWindow, pParent, u"EditWindow"_ustr, |
961 | 0 | u"modules/smath/ui/editwindow.ui"_ustr) |
962 | 0 | , m_xEdit(new SmEditWindow(*this, *m_xBuilder)) |
963 | 0 | , aController(*m_xEdit, SID_TEXT, rBindings_) |
964 | 0 | , bExiting(false) |
965 | 0 | , aInitialFocusTimer("SmCmdBoxWindow aInitialFocusTimer") |
966 | 0 | { |
967 | 0 | set_id(u"math_edit"_ustr); |
968 | |
|
969 | 0 | SetHelpId( HID_SMA_COMMAND_WIN ); |
970 | 0 | SetSizePixel(LogicToPixel(Size(292 , 94), MapMode(MapUnit::MapAppFont))); |
971 | 0 | SetText(SmResId(STR_CMDBOXWINDOW)); |
972 | |
|
973 | 0 | Hide(); |
974 | | |
975 | | // Don't try to grab focus in inline edit mode |
976 | 0 | if (!SmViewShell::IsInlineEditEnabled()) |
977 | 0 | { |
978 | 0 | aInitialFocusTimer.SetInvokeHandler(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl)); |
979 | 0 | aInitialFocusTimer.SetTimeout(100); |
980 | 0 | } |
981 | 0 | } Unexecuted instantiation: SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings&, SfxChildWindow*, vcl::Window*) Unexecuted instantiation: SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings&, SfxChildWindow*, vcl::Window*) |
982 | | |
983 | | Point SmCmdBoxWindow::WidgetToWindowPos(const weld::Widget& rWidget, const Point& rPos) |
984 | 0 | { |
985 | 0 | Point aRet(rPos); |
986 | 0 | int x(0), y(0), width(0), height(0); |
987 | 0 | rWidget.get_extents_relative_to(*m_xContainer, x, y, width, height); |
988 | 0 | aRet.Move(x, y); |
989 | 0 | aRet.Move(m_xBox->GetPosPixel().X(), m_xBox->GetPosPixel().Y()); |
990 | 0 | return aRet; |
991 | 0 | } |
992 | | |
993 | | void SmCmdBoxWindow::ShowContextMenu(const Point& rPos) |
994 | 0 | { |
995 | 0 | ToTop(); |
996 | 0 | SmViewShell *pViewSh = GetView(); |
997 | 0 | if (pViewSh) |
998 | 0 | pViewSh->GetViewFrame().GetDispatcher()->ExecutePopup(u"edit"_ustr, this, &rPos); |
999 | 0 | } |
1000 | | |
1001 | | void SmCmdBoxWindow::Command(const CommandEvent& rCEvt) |
1002 | 0 | { |
1003 | 0 | if (rCEvt.GetCommand() == CommandEventId::ContextMenu) |
1004 | 0 | { |
1005 | 0 | ShowContextMenu(rCEvt.GetMousePosPixel()); |
1006 | 0 | return; |
1007 | 0 | } |
1008 | | |
1009 | 0 | SfxDockingWindow::Command(rCEvt); |
1010 | 0 | } |
1011 | | |
1012 | | SmCmdBoxWindow::~SmCmdBoxWindow () |
1013 | 0 | { |
1014 | 0 | disposeOnce(); |
1015 | 0 | } |
1016 | | |
1017 | | void SmCmdBoxWindow::dispose() |
1018 | 0 | { |
1019 | 0 | aInitialFocusTimer.Stop(); |
1020 | 0 | bExiting = true; |
1021 | 0 | aController.dispose(); |
1022 | 0 | m_xEdit.reset(); |
1023 | 0 | SfxDockingWindow::dispose(); |
1024 | 0 | } |
1025 | | |
1026 | | SmViewShell * SmCmdBoxWindow::GetView() |
1027 | 0 | { |
1028 | 0 | SfxDispatcher *pDispatcher = GetBindings().GetDispatcher(); |
1029 | 0 | SfxViewShell *pView = pDispatcher ? pDispatcher->GetFrame()->GetViewShell() : nullptr; |
1030 | 0 | return dynamic_cast<SmViewShell*>( pView); |
1031 | 0 | } |
1032 | | |
1033 | | Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign) |
1034 | 0 | { |
1035 | 0 | switch (eAlign) |
1036 | 0 | { |
1037 | 0 | case SfxChildAlignment::LEFT: |
1038 | 0 | case SfxChildAlignment::RIGHT: |
1039 | 0 | return Size(); |
1040 | 0 | default: |
1041 | 0 | break; |
1042 | 0 | } |
1043 | 0 | return SfxDockingWindow::CalcDockingSize(eAlign); |
1044 | 0 | } |
1045 | | |
1046 | | SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual, |
1047 | | SfxChildAlignment eWish) |
1048 | 0 | { |
1049 | 0 | switch (eWish) |
1050 | 0 | { |
1051 | 0 | case SfxChildAlignment::TOP: |
1052 | 0 | case SfxChildAlignment::BOTTOM: |
1053 | 0 | case SfxChildAlignment::NOALIGNMENT: |
1054 | 0 | return eWish; |
1055 | 0 | default: |
1056 | 0 | break; |
1057 | 0 | } |
1058 | | |
1059 | 0 | return eActual; |
1060 | 0 | } |
1061 | | |
1062 | | void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange ) |
1063 | 0 | { |
1064 | 0 | if (StateChangedType::InitShow == nStateChange) |
1065 | 0 | { |
1066 | 0 | Resize(); // avoid SmEditWindow not being painted correctly |
1067 | | |
1068 | | // set initial position of window in floating mode |
1069 | 0 | if (IsFloatingMode()) |
1070 | 0 | AdjustPosition(); //! don't change pos in docking-mode ! |
1071 | |
|
1072 | 0 | aInitialFocusTimer.Start(); |
1073 | 0 | } |
1074 | |
|
1075 | 0 | SfxDockingWindow::StateChanged( nStateChange ); |
1076 | 0 | } |
1077 | | |
1078 | | IMPL_LINK_NOARG( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, void ) |
1079 | 0 | { |
1080 | | // We want to have the focus in the edit window once Math has been opened |
1081 | | // to allow for immediate typing. |
1082 | | // Problem: There is no proper way to do this |
1083 | | // Thus: this timer based solution has been implemented (see GrabFocus below) |
1084 | | |
1085 | | // Follow-up problem (#i114910): grabbing the focus may bust the help system since |
1086 | | // it relies on getting the current frame which conflicts with grabbing the focus. |
1087 | | // Thus aside from the 'GrabFocus' call everything else is to get the |
1088 | | // help reliably working despite using 'GrabFocus'. |
1089 | |
|
1090 | 0 | try |
1091 | 0 | { |
1092 | 0 | uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( comphelper::getProcessComponentContext() ); |
1093 | |
|
1094 | 0 | m_xEdit->GrabFocus(); |
1095 | |
|
1096 | 0 | SmViewShell* pView = GetView(); |
1097 | 0 | assert(pView); |
1098 | 0 | bool bInPlace = pView->GetViewFrame().GetFrame().IsInPlace(); |
1099 | 0 | uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface()); |
1100 | 0 | if ( bInPlace ) |
1101 | 0 | { |
1102 | 0 | uno::Reference<container::XChild> xModel(pView->GetDoc()->GetModel(), |
1103 | 0 | uno::UNO_QUERY_THROW); |
1104 | 0 | uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW ); |
1105 | 0 | uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() ); |
1106 | 0 | uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW ); |
1107 | 0 | xParentFrame->setActiveFrame( xFrame ); |
1108 | 0 | } |
1109 | 0 | else |
1110 | 0 | { |
1111 | 0 | xDesktop->setActiveFrame( xFrame ); |
1112 | 0 | } |
1113 | 0 | } |
1114 | 0 | catch (uno::Exception &) |
1115 | 0 | { |
1116 | 0 | SAL_WARN( "starmath", "failed to properly set initial focus to edit window" ); |
1117 | 0 | } |
1118 | 0 | } |
1119 | | |
1120 | | void SmCmdBoxWindow::AdjustPosition() |
1121 | 0 | { |
1122 | 0 | const tools::Rectangle aRect( Point(), GetParent()->GetOutputSizePixel() ); |
1123 | 0 | Point aTopLeft( Point( aRect.Left(), |
1124 | 0 | aRect.Bottom() - GetSizePixel().Height() ) ); |
1125 | 0 | Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) ); |
1126 | 0 | if (aPos.X() < 0) |
1127 | 0 | aPos.setX( 0 ); |
1128 | 0 | if (aPos.Y() < 0) |
1129 | 0 | aPos.setY( 0 ); |
1130 | 0 | SetPosPixel( aPos ); |
1131 | 0 | } |
1132 | | |
1133 | | void SmCmdBoxWindow::ToggleFloatingMode() |
1134 | 0 | { |
1135 | 0 | SfxDockingWindow::ToggleFloatingMode(); |
1136 | |
|
1137 | 0 | if (GetFloatingWindow()) |
1138 | 0 | GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50)); |
1139 | 0 | } |
1140 | | |
1141 | | void SmCmdBoxWindow::GetFocus() |
1142 | 0 | { |
1143 | 0 | if (!bExiting) |
1144 | 0 | m_xEdit->GrabFocus(); |
1145 | 0 | } |
1146 | | |
1147 | | SFX_IMPL_DOCKINGWINDOW_WITHID(SmCmdBoxWrapper, SID_CMDBOXWINDOW); |
1148 | | |
1149 | | SmCmdBoxWrapper::SmCmdBoxWrapper(vcl::Window* pParentWindow, sal_uInt16 nId, SfxBindings& rBindings, |
1150 | | SfxChildWinInfo& rInfo) |
1151 | 0 | : SfxChildWindow(pParentWindow, nId) |
1152 | 0 | { |
1153 | 0 | VclPtrInstance<SmCmdBoxWindow> pDialog(rBindings, this, pParentWindow); |
1154 | 0 | SetWindow(pDialog); |
1155 | | // make window docked to the bottom initially (after first start) |
1156 | 0 | SetAlignment(SfxChildAlignment::BOTTOM); |
1157 | 0 | pDialog->setDeferredProperties(); |
1158 | 0 | pDialog->set_border_width(CMD_BOX_PADDING); |
1159 | 0 | pDialog->set_margin_top(CMD_BOX_PADDING_TOP); |
1160 | 0 | pDialog->Initialize(rInfo); |
1161 | 0 | } |
1162 | | |
1163 | | SFX_IMPL_SUPERCLASS_INTERFACE(SmViewShell, SfxViewShell) |
1164 | | |
1165 | | void SmViewShell::InitInterface_Impl() |
1166 | 1 | { |
1167 | 1 | GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS, |
1168 | 1 | SfxVisibilityFlags::Standard | SfxVisibilityFlags::FullScreen | SfxVisibilityFlags::Server, |
1169 | 1 | ToolbarId::Math_Toolbox); |
1170 | | //Dummy-Objectbar, to avoid quiver while activating |
1171 | | |
1172 | 1 | GetStaticInterface()->RegisterChildWindow(SmCmdBoxWrapper::GetChildWindowId()); |
1173 | 1 | GetStaticInterface()->RegisterChildWindow(SfxInfoBarContainerChild::GetChildWindowId()); |
1174 | | |
1175 | 1 | GetStaticInterface()->RegisterChildWindow(::sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); |
1176 | 1 | } |
1177 | | |
1178 | 1 | SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default") |
1179 | 1 | { |
1180 | 1 | SFX_VIEW_REGISTRATION(SmDocShell); |
1181 | 1 | } |
1182 | | |
1183 | | void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize, bool) |
1184 | 0 | { |
1185 | 0 | Size aObjSize = GetObjectShell()->GetVisArea().GetSize(); |
1186 | 0 | if ( !aObjSize.IsEmpty() ) |
1187 | 0 | { |
1188 | 0 | Size aProvidedSize = GetWindow()->PixelToLogic(rSize, MapMode(SmMapUnit())); |
1189 | 0 | double fZoomX = double(aProvidedSize.Width()) / aObjSize.Width(); |
1190 | 0 | double fZoomY = double(aProvidedSize.Height()) / aObjSize.Height(); |
1191 | 0 | MapMode aMap(mxGraphicWindow->GetGraphicMapMode()); |
1192 | 0 | aMap.SetScaleX(fZoomX); |
1193 | 0 | aMap.SetScaleY(fZoomY); |
1194 | 0 | mxGraphicWindow->SetGraphicMapMode(aMap); |
1195 | 0 | } |
1196 | |
|
1197 | 0 | SetBorderPixel( SvBorder() ); |
1198 | 0 | mxGraphicWindow->SetPosSizePixel(rOfs, rSize); |
1199 | 0 | GetGraphicWidget().SetTotalSize(); |
1200 | 0 | } |
1201 | | |
1202 | | void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize) |
1203 | 0 | { |
1204 | 0 | mxGraphicWindow->SetPosSizePixel(rOfs, rSize); |
1205 | 0 | if (GetDoc()->IsPreview()) |
1206 | 0 | mxGraphicWindow->ZoomToFitInWindow(); |
1207 | 0 | } |
1208 | | |
1209 | | void SmViewShell::QueryObjAreaPixel( tools::Rectangle& rRect ) const |
1210 | 0 | { |
1211 | 0 | rRect.SetSize(mxGraphicWindow->GetSizePixel()); |
1212 | 0 | } |
1213 | | |
1214 | | void SmViewShell::SetZoomFactor( double fX, double fY ) |
1215 | 0 | { |
1216 | 0 | double fFrac = std::min(fX, fY); |
1217 | 0 | mxGraphicWindow->SetZoom(sal::static_int_cast<sal_uInt16>(tools::Long(fFrac * 100))); |
1218 | | |
1219 | | //To avoid rounding errors base class regulates crooked values too |
1220 | | //if necessary |
1221 | 0 | SfxViewShell::SetZoomFactor( fX, fY ); |
1222 | 0 | } |
1223 | | |
1224 | | SfxPrinter* SmViewShell::GetPrinter(bool bCreate) |
1225 | 0 | { |
1226 | 0 | SmDocShell* pDoc = GetDoc(); |
1227 | 0 | if (pDoc->HasPrinter() || bCreate) |
1228 | 0 | return pDoc->GetPrinter(); |
1229 | 0 | return nullptr; |
1230 | 0 | } |
1231 | | |
1232 | | sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags ) |
1233 | 0 | { |
1234 | 0 | SfxPrinter *pOld = GetDoc()->GetPrinter(); |
1235 | 0 | if ( pOld && pOld->IsPrinting() ) |
1236 | 0 | return SFX_PRINTERROR_BUSY; |
1237 | | |
1238 | 0 | if ((nDiffFlags & SfxPrinterChangeFlags::PRINTER) == SfxPrinterChangeFlags::PRINTER) |
1239 | 0 | GetDoc()->SetPrinter( pNewPrinter ); |
1240 | |
|
1241 | 0 | if ((nDiffFlags & SfxPrinterChangeFlags::OPTIONS) == SfxPrinterChangeFlags::OPTIONS) |
1242 | 0 | { |
1243 | 0 | SmModule::get()->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions()); |
1244 | 0 | } |
1245 | 0 | return 0; |
1246 | 0 | } |
1247 | | |
1248 | | bool SmViewShell::HasPrintOptionsPage() const |
1249 | 0 | { |
1250 | 0 | return true; |
1251 | 0 | } |
1252 | | |
1253 | | std::unique_ptr<SfxTabPage> SmViewShell::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController, |
1254 | | const SfxItemSet &rOptions) |
1255 | 0 | { |
1256 | 0 | return SmPrintOptionsTabPage::Create(pPage, pController, rOptions); |
1257 | 0 | } |
1258 | | |
1259 | | SmEditWindow *SmViewShell::GetEditWindow() |
1260 | 0 | { |
1261 | 0 | SmCmdBoxWrapper* pWrapper = static_cast<SmCmdBoxWrapper*>( |
1262 | 0 | GetViewFrame().GetChildWindow(SmCmdBoxWrapper::GetChildWindowId())); |
1263 | |
|
1264 | 0 | if (pWrapper != nullptr) |
1265 | 0 | { |
1266 | 0 | SmEditWindow& rEditWin = pWrapper->GetEditWindow(); |
1267 | 0 | return &rEditWin; |
1268 | 0 | } |
1269 | | |
1270 | 0 | return nullptr; |
1271 | 0 | } |
1272 | | |
1273 | | void SmViewShell::SetStatusText(const OUString& rText) |
1274 | 0 | { |
1275 | 0 | maStatusText = rText; |
1276 | 0 | GetViewFrame().GetBindings().Invalidate(SID_TEXTSTATUS); |
1277 | 0 | } |
1278 | | |
1279 | | void SmViewShell::ShowError(const SmErrorDesc* pErrorDesc) |
1280 | 0 | { |
1281 | 0 | assert(GetDoc()); |
1282 | 0 | if (pErrorDesc || nullptr != (pErrorDesc = GetDoc()->GetParser()->GetError()) ) |
1283 | 0 | { |
1284 | 0 | SetStatusText( pErrorDesc->m_aText ); |
1285 | 0 | if (SmEditWindow* pEdit = GetEditWindow()) |
1286 | 0 | pEdit->MarkError( Point( pErrorDesc->m_pNode->GetColumn(), |
1287 | 0 | pErrorDesc->m_pNode->GetRow())); |
1288 | 0 | } |
1289 | 0 | } |
1290 | | |
1291 | | void SmViewShell::NextError() |
1292 | 0 | { |
1293 | 0 | assert(GetDoc()); |
1294 | 0 | const SmErrorDesc *pErrorDesc = GetDoc()->GetParser()->NextError(); |
1295 | |
|
1296 | 0 | if (pErrorDesc) |
1297 | 0 | ShowError( pErrorDesc ); |
1298 | 0 | } |
1299 | | |
1300 | | void SmViewShell::PrevError() |
1301 | 0 | { |
1302 | 0 | assert(GetDoc()); |
1303 | 0 | const SmErrorDesc *pErrorDesc = GetDoc()->GetParser()->PrevError(); |
1304 | |
|
1305 | 0 | if (pErrorDesc) |
1306 | 0 | ShowError( pErrorDesc ); |
1307 | 0 | } |
1308 | | |
1309 | | void SmViewShell::Insert( SfxMedium& rMedium ) |
1310 | 0 | { |
1311 | 0 | SmDocShell *pDoc = GetDoc(); |
1312 | 0 | bool bRet = false; |
1313 | |
|
1314 | 0 | uno::Reference <embed::XStorage> xStorage = rMedium.GetStorage(); |
1315 | 0 | if (xStorage.is() && xStorage->getElementNames().hasElements()) |
1316 | 0 | { |
1317 | 0 | if (xStorage->hasByName(u"content.xml"_ustr)) |
1318 | 0 | { |
1319 | | // is this a fabulous math package ? |
1320 | 0 | rtl::Reference<SmModel> xModel(dynamic_cast<SmModel*>(pDoc->GetModel().get())); |
1321 | 0 | SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! |
1322 | 0 | bRet = ERRCODE_NONE == aEquation.Import(rMedium); |
1323 | 0 | } |
1324 | 0 | } |
1325 | |
|
1326 | 0 | if (!bRet) |
1327 | 0 | return; |
1328 | | |
1329 | 0 | OUString aText = pDoc->GetText(); |
1330 | 0 | if (SmEditWindow *pEditWin = GetEditWindow()) |
1331 | 0 | pEditWin->InsertText( aText ); |
1332 | 0 | else |
1333 | 0 | { |
1334 | 0 | SAL_WARN( "starmath", "EditWindow missing" ); |
1335 | 0 | } |
1336 | | |
1337 | 0 | pDoc->Parse(); |
1338 | 0 | pDoc->SetModified(); |
1339 | |
|
1340 | 0 | SfxBindings &rBnd = GetViewFrame().GetBindings(); |
1341 | 0 | rBnd.Invalidate(SID_GRAPHIC_SM); |
1342 | 0 | rBnd.Invalidate(SID_TEXT); |
1343 | 0 | } |
1344 | | |
1345 | | void SmViewShell::InsertFrom(SfxMedium &rMedium) |
1346 | 0 | { |
1347 | 0 | bool bSuccess = false; |
1348 | 0 | SmDocShell* pDoc = GetDoc(); |
1349 | 0 | SvStream* pStream = rMedium.GetInStream(); |
1350 | |
|
1351 | 0 | if (pStream) |
1352 | 0 | { |
1353 | 0 | const OUString& rFltName = rMedium.GetFilter()->GetFilterName(); |
1354 | 0 | if ( rFltName == MATHML_XML ) |
1355 | 0 | { |
1356 | 0 | rtl::Reference<SmModel> xModel(dynamic_cast<SmModel*>(pDoc->GetModel().get())); |
1357 | 0 | SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! |
1358 | 0 | bSuccess = ERRCODE_NONE == aEquation.Import(rMedium); |
1359 | 0 | } |
1360 | 0 | } |
1361 | |
|
1362 | 0 | if (!bSuccess) |
1363 | 0 | return; |
1364 | | |
1365 | 0 | OUString aText = pDoc->GetText(); |
1366 | 0 | if (SmEditWindow *pEditWin = GetEditWindow()) |
1367 | 0 | pEditWin->InsertText(aText); |
1368 | 0 | else |
1369 | 0 | SAL_WARN( "starmath", "EditWindow missing" ); |
1370 | | |
1371 | 0 | pDoc->Parse(); |
1372 | 0 | pDoc->SetModified(); |
1373 | |
|
1374 | 0 | SfxBindings& rBnd = GetViewFrame().GetBindings(); |
1375 | 0 | rBnd.Invalidate(SID_GRAPHIC_SM); |
1376 | 0 | rBnd.Invalidate(SID_TEXT); |
1377 | 0 | } |
1378 | | |
1379 | | void SmViewShell::Execute(SfxRequest& rReq) |
1380 | 0 | { |
1381 | 0 | SmEditWindow *pWin = GetEditWindow(); |
1382 | |
|
1383 | 0 | switch (rReq.GetSlot()) |
1384 | 0 | { |
1385 | 0 | case SID_FORMULACURSOR: |
1386 | 0 | { |
1387 | 0 | auto* config = SmModule::get()->GetConfig(); |
1388 | |
|
1389 | 0 | const SfxItemSet *pArgs = rReq.GetArgs(); |
1390 | 0 | const SfxPoolItem *pItem; |
1391 | |
|
1392 | 0 | bool bVal; |
1393 | 0 | if ( pArgs && |
1394 | 0 | SfxItemState::SET == pArgs->GetItemState( SID_FORMULACURSOR, false, &pItem)) |
1395 | 0 | bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue(); |
1396 | 0 | else |
1397 | 0 | bVal = !config->IsShowFormulaCursor(); |
1398 | |
|
1399 | 0 | config->SetShowFormulaCursor(bVal); |
1400 | 0 | if (!IsInlineEditEnabled()) |
1401 | 0 | GetGraphicWidget().ShowCursor(bVal); |
1402 | 0 | break; |
1403 | 0 | } |
1404 | 0 | case SID_DRAW: |
1405 | 0 | if (pWin) |
1406 | 0 | { |
1407 | 0 | GetDoc()->SetText( pWin->GetText() ); |
1408 | 0 | SetStatusText(OUString()); |
1409 | 0 | ShowError( nullptr ); |
1410 | 0 | GetDoc()->Repaint(); |
1411 | 0 | } |
1412 | 0 | break; |
1413 | | |
1414 | 0 | case SID_ZOOM_OPTIMAL: |
1415 | 0 | mxGraphicWindow->ZoomToFitInWindow(); |
1416 | 0 | break; |
1417 | | |
1418 | 0 | case SID_ZOOMIN: |
1419 | 0 | mxGraphicWindow->SetZoom(mxGraphicWindow->GetZoom() + 25); |
1420 | 0 | break; |
1421 | | |
1422 | 0 | case SID_ZOOMOUT: |
1423 | 0 | SAL_WARN_IF( mxGraphicWindow->GetZoom() < 25, "starmath", "incorrect sal_uInt16 argument" ); |
1424 | 0 | mxGraphicWindow->SetZoom(mxGraphicWindow->GetZoom() - 25); |
1425 | 0 | break; |
1426 | | |
1427 | 0 | case SID_COPYOBJECT: |
1428 | 0 | { |
1429 | | //TODO/LATER: does not work because of UNO Tunneling - will be fixed later |
1430 | 0 | Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY ); |
1431 | 0 | if( xTrans.is() ) |
1432 | 0 | { |
1433 | 0 | auto pTrans = dynamic_cast<TransferableHelper*>(xTrans.get()); |
1434 | 0 | if (pTrans) |
1435 | 0 | { |
1436 | 0 | if (pWin) |
1437 | 0 | pTrans->CopyToClipboard(pWin->GetClipboard()); |
1438 | 0 | } |
1439 | 0 | } |
1440 | 0 | } |
1441 | 0 | break; |
1442 | | |
1443 | 0 | case SID_PASTEOBJECT: |
1444 | 0 | { |
1445 | 0 | uno::Reference < io::XInputStream > xStrm; |
1446 | 0 | if (pWin) |
1447 | 0 | { |
1448 | 0 | TransferableDataHelper aData(TransferableDataHelper::CreateFromClipboard(pWin->GetClipboard())); |
1449 | 0 | SotClipboardFormatId nId; |
1450 | 0 | if( aData.GetTransferable().is() && |
1451 | 0 | ( aData.HasFormat( nId = SotClipboardFormatId::EMBEDDED_OBJ ) || |
1452 | 0 | (aData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) && |
1453 | 0 | aData.HasFormat( nId = SotClipboardFormatId::EMBED_SOURCE )))) |
1454 | 0 | xStrm = aData.GetInputStream(nId, OUString()); |
1455 | 0 | } |
1456 | |
|
1457 | 0 | if (xStrm.is()) |
1458 | 0 | { |
1459 | 0 | try |
1460 | 0 | { |
1461 | 0 | uno::Reference < embed::XStorage > xStorage = |
1462 | 0 | ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessComponentContext() ); |
1463 | 0 | SfxMedium aMedium( xStorage, OUString() ); |
1464 | 0 | Insert( aMedium ); |
1465 | 0 | GetDoc()->UpdateText(); |
1466 | 0 | } |
1467 | 0 | catch (uno::Exception &) |
1468 | 0 | { |
1469 | 0 | SAL_WARN( "starmath", "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ); |
1470 | 0 | } |
1471 | 0 | } |
1472 | 0 | } |
1473 | 0 | break; |
1474 | | |
1475 | | |
1476 | 0 | case SID_CUT: |
1477 | 0 | if (IsInlineEditEnabled()) |
1478 | 0 | { |
1479 | 0 | GetDoc()->GetCursor().Cut(&GetGraphicWindow()); |
1480 | 0 | GetGraphicWidget().GrabFocus(); |
1481 | 0 | } |
1482 | 0 | else if (pWin) |
1483 | 0 | pWin->Cut(); |
1484 | 0 | break; |
1485 | | |
1486 | 0 | case SID_COPY: |
1487 | 0 | if (IsInlineEditEnabled()) |
1488 | 0 | { |
1489 | 0 | GetDoc()->GetCursor().Copy(&GetGraphicWindow()); |
1490 | 0 | GetGraphicWidget().GrabFocus(); |
1491 | 0 | } |
1492 | 0 | else if (pWin) |
1493 | 0 | { |
1494 | 0 | if (pWin->IsAllSelected()) |
1495 | 0 | { |
1496 | 0 | GetViewFrame().GetDispatcher()->ExecuteList( |
1497 | 0 | SID_COPYOBJECT, SfxCallMode::RECORD, |
1498 | 0 | { new SfxVoidItem(SID_COPYOBJECT) }); |
1499 | 0 | } |
1500 | 0 | else |
1501 | 0 | pWin->Copy(); |
1502 | 0 | } |
1503 | 0 | break; |
1504 | | |
1505 | 0 | case SID_PASTE: |
1506 | 0 | { |
1507 | 0 | if (IsInlineEditEnabled()) |
1508 | 0 | { |
1509 | 0 | GetDoc()->GetCursor().Paste(&GetGraphicWindow()); |
1510 | 0 | GetGraphicWidget().GrabFocus(); |
1511 | 0 | break; |
1512 | 0 | } |
1513 | | |
1514 | 0 | if( pWin ) |
1515 | 0 | { |
1516 | 0 | TransferableDataHelper aDataHelper( |
1517 | 0 | TransferableDataHelper::CreateFromClipboard( |
1518 | 0 | pWin->GetClipboard())); |
1519 | |
|
1520 | 0 | if( aDataHelper.GetTransferable().is() && |
1521 | 0 | aDataHelper.HasFormat( SotClipboardFormatId::STRING )) |
1522 | 0 | pWin->Paste(); |
1523 | 0 | else |
1524 | 0 | { |
1525 | 0 | GetViewFrame().GetDispatcher()->ExecuteList( |
1526 | 0 | SID_PASTEOBJECT, SfxCallMode::RECORD, |
1527 | 0 | { new SfxVoidItem(SID_PASTEOBJECT) }); |
1528 | 0 | } |
1529 | 0 | } |
1530 | 0 | } |
1531 | 0 | break; |
1532 | | |
1533 | 0 | case SID_MATRIXEDITOR: |
1534 | 0 | if (pWin) |
1535 | 0 | { |
1536 | 0 | auto pMatrixCreatorDialog = std::make_unique<MatrixCreatorDialog>(rReq.GetFrameWeld()); |
1537 | |
|
1538 | 0 | if (pMatrixCreatorDialog->run() == RET_OK) |
1539 | 0 | { |
1540 | 0 | OUString result = pMatrixCreatorDialog->getMatrix(); |
1541 | |
|
1542 | 0 | ESelection eSelection = pWin->GetSelection(); |
1543 | 0 | eSelection.Adjust(); |
1544 | |
|
1545 | 0 | auto pEngine = pWin->GetEditEngine(); |
1546 | 0 | OUString sText; |
1547 | |
|
1548 | 0 | for (sal_Int32 p = 0; p < pEngine->GetParagraphCount(); ++p) |
1549 | 0 | { |
1550 | 0 | if (p == eSelection.start.nPara) |
1551 | 0 | { |
1552 | 0 | OUString pText = pEngine->GetText(p); |
1553 | 0 | sText += pText.replaceAt(eSelection.start.nIndex, |
1554 | 0 | eSelection.end.nIndex - eSelection.start.nIndex, |
1555 | 0 | result) |
1556 | 0 | + "\n"; |
1557 | 0 | } |
1558 | 0 | else |
1559 | 0 | sText += pEngine->GetText(p) + "\n"; |
1560 | 0 | } |
1561 | |
|
1562 | 0 | GetDoc()->SetText(sText); |
1563 | 0 | SetStatusText(OUString()); |
1564 | 0 | ShowError(nullptr); |
1565 | 0 | GetDoc()->Repaint(); |
1566 | 0 | } |
1567 | 0 | } |
1568 | 0 | break; |
1569 | | |
1570 | 0 | case SID_DELETE: |
1571 | 0 | if (IsInlineEditEnabled()) |
1572 | 0 | { |
1573 | 0 | if (!GetDoc()->GetCursor().HasSelection()) |
1574 | 0 | { |
1575 | 0 | GetDoc()->GetCursor().Move(&GetGraphicWindow().GetGraphicWidget().GetOutputDevice(), MoveRight, false); |
1576 | 0 | if (!GetDoc()->GetCursor().HasComplexSelection()) |
1577 | 0 | GetDoc()->GetCursor().Delete(); |
1578 | 0 | } |
1579 | 0 | else |
1580 | 0 | GetDoc()->GetCursor().Delete(); |
1581 | 0 | GetGraphicWidget().GrabFocus(); |
1582 | 0 | } |
1583 | 0 | else if (pWin) |
1584 | 0 | pWin->Delete(); |
1585 | 0 | break; |
1586 | | |
1587 | 0 | case SID_SELECT: |
1588 | 0 | if (pWin) |
1589 | 0 | pWin->SelectAll(); |
1590 | 0 | break; |
1591 | | |
1592 | 0 | case SID_INSERTCOMMANDTEXT: |
1593 | 0 | { |
1594 | 0 | const SfxStringItem& rItem = rReq.GetArgs()->Get(SID_INSERTCOMMANDTEXT); |
1595 | |
|
1596 | 0 | if (IsInlineEditEnabled()) |
1597 | 0 | { |
1598 | 0 | GetDoc()->GetCursor().InsertCommandText(rItem.GetValue()); |
1599 | 0 | GetGraphicWidget().GrabFocus(); |
1600 | 0 | } |
1601 | 0 | else if (pWin) |
1602 | 0 | { |
1603 | 0 | pWin->InsertText(rItem.GetValue()); |
1604 | 0 | } |
1605 | 0 | break; |
1606 | |
|
1607 | 0 | } |
1608 | | |
1609 | 0 | case SID_INSERTSPECIAL: |
1610 | 0 | { |
1611 | 0 | const SfxStringItem& rItem = rReq.GetArgs()->Get(SID_INSERTSPECIAL); |
1612 | |
|
1613 | 0 | if (IsInlineEditEnabled()) |
1614 | 0 | GetDoc()->GetCursor().InsertSpecial(rItem.GetValue()); |
1615 | 0 | else if (pWin) |
1616 | 0 | pWin->InsertText(rItem.GetValue()); |
1617 | 0 | break; |
1618 | 0 | } |
1619 | | |
1620 | 0 | case SID_IMPORT_FORMULA: |
1621 | 0 | { |
1622 | 0 | mpRequest.reset(new SfxRequest( rReq )); |
1623 | 0 | mpDocInserter.reset(new ::sfx2::DocumentInserter(pWin ? pWin->GetFrameWeld() : nullptr, |
1624 | 0 | GetDoc()->GetFactory().GetFactoryName())); |
1625 | 0 | mpDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl ) ); |
1626 | 0 | break; |
1627 | 0 | } |
1628 | | |
1629 | 0 | case SID_IMPORT_MATHML_CLIPBOARD: |
1630 | 0 | { |
1631 | 0 | if (pWin) |
1632 | 0 | { |
1633 | 0 | TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromClipboard(pWin->GetClipboard())); |
1634 | 0 | uno::Reference < io::XInputStream > xStrm; |
1635 | 0 | if ( aDataHelper.GetTransferable().is() ) |
1636 | 0 | { |
1637 | 0 | SotClipboardFormatId nId = SotClipboardFormatId::MATHML; |
1638 | 0 | if (aDataHelper.HasFormat(nId)) |
1639 | 0 | { |
1640 | 0 | xStrm = aDataHelper.GetInputStream(nId, u""_ustr); |
1641 | 0 | if (xStrm.is()) |
1642 | 0 | { |
1643 | 0 | SfxMedium aClipboardMedium; |
1644 | 0 | aClipboardMedium.GetItemSet(); //generate initial itemset, not sure if necessary |
1645 | 0 | std::shared_ptr<const SfxFilter> pMathFilter = |
1646 | 0 | SfxFilter::GetFilterByName(MATHML_XML); |
1647 | 0 | aClipboardMedium.SetFilter(pMathFilter); |
1648 | 0 | aClipboardMedium.setStreamToLoadFrom(xStrm, true /*bIsReadOnly*/); |
1649 | 0 | InsertFrom(aClipboardMedium); |
1650 | 0 | GetDoc()->UpdateText(); |
1651 | 0 | } |
1652 | 0 | } |
1653 | 0 | else |
1654 | 0 | { |
1655 | 0 | nId = SotClipboardFormatId::STRING; |
1656 | 0 | if (aDataHelper.HasFormat(nId)) |
1657 | 0 | { |
1658 | | // In case of FORMAT_STRING no stream exists, need to generate one |
1659 | 0 | OUString aString; |
1660 | 0 | if (aDataHelper.GetString( nId, aString)) |
1661 | 0 | { |
1662 | | // tdf#117091 force xml declaration to exist |
1663 | 0 | if (!aString.startsWith("<?xml")) |
1664 | 0 | aString = "<?xml version=\"1.0\"?>\n" + aString; |
1665 | |
|
1666 | 0 | SfxMedium aClipboardMedium; |
1667 | 0 | aClipboardMedium.GetItemSet(); //generates initial itemset, not sure if necessary |
1668 | 0 | std::shared_ptr<const SfxFilter> pMathFilter = |
1669 | 0 | SfxFilter::GetFilterByName(MATHML_XML); |
1670 | 0 | aClipboardMedium.SetFilter(pMathFilter); |
1671 | |
|
1672 | 0 | SvMemoryStream aStrm( const_cast<sal_Unicode *>(aString.getStr()), aString.getLength() * sizeof(sal_Unicode), StreamMode::READ); |
1673 | 0 | uno::Reference<io::XInputStream> xStrm2( new ::utl::OInputStreamWrapper(aStrm) ); |
1674 | 0 | aClipboardMedium.setStreamToLoadFrom(xStrm2, true /*bIsReadOnly*/); |
1675 | 0 | InsertFrom(aClipboardMedium); |
1676 | 0 | GetDoc()->UpdateText(); |
1677 | 0 | } |
1678 | 0 | } |
1679 | 0 | } |
1680 | 0 | } |
1681 | 0 | } |
1682 | 0 | break; |
1683 | 0 | } |
1684 | | |
1685 | 0 | case SID_NEXTERR: |
1686 | 0 | NextError(); |
1687 | 0 | if (pWin) |
1688 | 0 | pWin->GrabFocus(); |
1689 | 0 | break; |
1690 | | |
1691 | 0 | case SID_PREVERR: |
1692 | 0 | PrevError(); |
1693 | 0 | if (pWin) |
1694 | 0 | pWin->GrabFocus(); |
1695 | 0 | break; |
1696 | | |
1697 | 0 | case SID_NEXTMARK: |
1698 | 0 | if (pWin) |
1699 | 0 | { |
1700 | 0 | pWin->SelNextMark(); |
1701 | 0 | pWin->GrabFocus(); |
1702 | 0 | } |
1703 | 0 | break; |
1704 | | |
1705 | 0 | case SID_PREVMARK: |
1706 | 0 | if (pWin) |
1707 | 0 | { |
1708 | 0 | pWin->SelPrevMark(); |
1709 | 0 | pWin->GrabFocus(); |
1710 | 0 | } |
1711 | 0 | break; |
1712 | | |
1713 | 0 | case SID_TEXTSTATUS: |
1714 | 0 | { |
1715 | 0 | if (rReq.GetArgs() != nullptr) |
1716 | 0 | { |
1717 | 0 | const SfxStringItem& rItem = rReq.GetArgs()->Get(SID_TEXTSTATUS); |
1718 | |
|
1719 | 0 | SetStatusText(rItem.GetValue()); |
1720 | 0 | } |
1721 | |
|
1722 | 0 | break; |
1723 | 0 | } |
1724 | | |
1725 | 0 | case SID_GETEDITTEXT: |
1726 | 0 | if (pWin && !pWin->GetText().isEmpty()) |
1727 | 0 | GetDoc()->SetText( pWin->GetText() ); |
1728 | 0 | break; |
1729 | | |
1730 | 0 | case SID_ATTR_ZOOM: |
1731 | 0 | { |
1732 | 0 | if ( !GetViewFrame().GetFrame().IsInPlace() ) |
1733 | 0 | { |
1734 | 0 | const SfxItemSet *pSet = rReq.GetArgs(); |
1735 | 0 | if ( pSet ) |
1736 | 0 | { |
1737 | 0 | ZoomByItemSet(pSet); |
1738 | 0 | } |
1739 | 0 | else |
1740 | 0 | { |
1741 | 0 | SfxItemSet aSet(SfxItemSet::makeFixedSfxItemSet<SID_ATTR_ZOOM, SID_ATTR_ZOOM>( SmDocShell::GetPool() )); |
1742 | 0 | aSet.Put( SvxZoomItem( SvxZoomType::PERCENT, mxGraphicWindow->GetZoom())); |
1743 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
1744 | 0 | ScopedVclPtr<AbstractSvxZoomDialog> xDlg(pFact->CreateSvxZoomDialog(GetViewFrame().GetWindow().GetFrameWeld(), aSet)); |
1745 | 0 | xDlg->SetLimits( MINZOOM, MAXZOOM ); |
1746 | 0 | if (xDlg->Execute() != RET_CANCEL) |
1747 | 0 | ZoomByItemSet(xDlg->GetOutputItemSet()); |
1748 | 0 | } |
1749 | 0 | } |
1750 | 0 | } |
1751 | 0 | break; |
1752 | | |
1753 | 0 | case SID_ATTR_ZOOMSLIDER: |
1754 | 0 | { |
1755 | 0 | const SfxItemSet *pArgs = rReq.GetArgs(); |
1756 | 0 | const SfxPoolItem* pItem; |
1757 | |
|
1758 | 0 | if ( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMSLIDER, true, &pItem ) ) |
1759 | 0 | { |
1760 | 0 | const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue(); |
1761 | 0 | mxGraphicWindow->SetZoom(nCurrentZoom); |
1762 | 0 | } |
1763 | 0 | } |
1764 | 0 | break; |
1765 | | |
1766 | 0 | case SID_ELEMENTSDOCKINGWINDOW: |
1767 | 0 | { |
1768 | | // First make sure that the sidebar is visible |
1769 | 0 | GetViewFrame().ShowChildWindow(SID_SIDEBAR); |
1770 | |
|
1771 | 0 | sfx2::sidebar::Sidebar::TogglePanel(u"MathElementsPanel", |
1772 | 0 | GetViewFrame().GetFrame().GetFrameInterface()); |
1773 | 0 | GetViewFrame().GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW ); |
1774 | |
|
1775 | 0 | rReq.Ignore (); |
1776 | 0 | } |
1777 | 0 | break; |
1778 | | |
1779 | 0 | case SID_CMDBOXWINDOW: |
1780 | 0 | { |
1781 | 0 | GetViewFrame().ToggleChildWindow(SID_CMDBOXWINDOW); |
1782 | 0 | GetViewFrame().GetBindings().Invalidate(SID_CMDBOXWINDOW); |
1783 | 0 | } |
1784 | 0 | break; |
1785 | | |
1786 | 0 | case SID_UNICODE_NOTATION_TOGGLE: |
1787 | 0 | { |
1788 | 0 | EditEngine* pEditEngine = nullptr; |
1789 | 0 | if( pWin ) |
1790 | 0 | pEditEngine = pWin->GetEditEngine(); |
1791 | |
|
1792 | 0 | EditView* pEditView = nullptr; |
1793 | 0 | if( pEditEngine ) |
1794 | 0 | pEditView = pEditEngine->GetView(); |
1795 | |
|
1796 | 0 | if( pEditView ) |
1797 | 0 | { |
1798 | 0 | const OUString sInput = pEditView->GetSurroundingText(); |
1799 | 0 | ESelection aSel( pWin->GetSelection() ); |
1800 | |
|
1801 | 0 | if (aSel.start.nIndex > aSel.end.nIndex) |
1802 | 0 | aSel.end.nIndex = aSel.start.nIndex; |
1803 | | |
1804 | | //calculate a valid end-position by reading logical characters |
1805 | 0 | sal_Int32 nUtf16Pos=0; |
1806 | 0 | while ((nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.end.nIndex)) |
1807 | 0 | { |
1808 | 0 | sInput.iterateCodePoints(&nUtf16Pos); |
1809 | 0 | if (nUtf16Pos > aSel.end.nIndex) |
1810 | 0 | aSel.end.nIndex = nUtf16Pos; |
1811 | 0 | } |
1812 | |
|
1813 | 0 | ToggleUnicodeCodepoint aToggle; |
1814 | 0 | while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) ) |
1815 | 0 | --nUtf16Pos; |
1816 | 0 | const OUString sReplacement = aToggle.ReplacementString(); |
1817 | 0 | if( !sReplacement.isEmpty() ) |
1818 | 0 | { |
1819 | 0 | pEditView->SetSelection( aSel ); |
1820 | 0 | pEditEngine->UndoActionStart(EDITUNDO_REPLACEALL); |
1821 | 0 | aSel.start.nIndex = aSel.end.nIndex - aToggle.StringToReplace().getLength(); |
1822 | 0 | pWin->SetSelection( aSel ); |
1823 | 0 | pEditView->InsertText( sReplacement, true ); |
1824 | 0 | pEditEngine->UndoActionEnd(); |
1825 | 0 | pWin->Flush(); |
1826 | 0 | } |
1827 | 0 | } |
1828 | 0 | } |
1829 | 0 | break; |
1830 | | |
1831 | 0 | case SID_SYMBOLS_CATALOGUE: |
1832 | 0 | { |
1833 | 0 | SmModule* pp = SmModule::get(); |
1834 | | |
1835 | | // get device used to retrieve the FontList |
1836 | 0 | SmDocShell *pDoc = GetDoc(); |
1837 | 0 | OutputDevice *pDev = pDoc->GetPrinter(); |
1838 | 0 | if (!pDev || pDev->GetFontFaceCollectionCount() == 0) |
1839 | 0 | pDev = &pp->GetDefaultVirtualDev(); |
1840 | 0 | SAL_WARN_IF( !pDev, "starmath", "device for font list missing" ); |
1841 | | |
1842 | 0 | SmSymbolDialog aDialog(pWin ? pWin->GetFrameWeld() : nullptr, pDev, pp->GetSymbolManager(), *this); |
1843 | 0 | aDialog.run(); |
1844 | 0 | } |
1845 | 0 | break; |
1846 | | |
1847 | 0 | case SID_CHARMAP: |
1848 | 0 | { |
1849 | 0 | const SfxItemSet* pArgs = rReq.GetArgs(); |
1850 | 0 | const SfxStringItem* pItem = nullptr; |
1851 | 0 | if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_CHARMAP, true, &pItem)) |
1852 | 0 | { |
1853 | 0 | if (IsInlineEditEnabled()) |
1854 | 0 | GetDoc()->GetCursor().InsertText(pItem->GetValue()); |
1855 | 0 | else if (pWin) |
1856 | 0 | pWin->InsertText(pItem->GetValue()); |
1857 | 0 | break; |
1858 | 0 | } |
1859 | | |
1860 | 0 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); |
1861 | 0 | SfxAllItemSet aSet(GetViewFrame().GetObjectShell()->GetPool()); |
1862 | 0 | aSet.Put(SfxBoolItem(FN_PARAM_1, false)); |
1863 | 0 | aSet.Put(SfxStringItem(SID_FONT_NAME, |
1864 | 0 | GetDoc()->GetFormat().GetFont(FNT_VARIABLE).GetFamilyName())); |
1865 | 0 | VclPtr<SfxAbstractDialog> pDialog( |
1866 | 0 | pFact->CreateCharMapDialog(pWin ? pWin->GetFrameWeld() : nullptr, aSet, |
1867 | 0 | GetViewFrame().GetFrame().GetFrameInterface())); |
1868 | 0 | pDialog->StartExecuteAsync( |
1869 | 0 | [pDialog] (sal_Int32 /*nResult*/)->void |
1870 | 0 | { |
1871 | 0 | pDialog->disposeOnce(); |
1872 | 0 | } |
1873 | 0 | ); |
1874 | 0 | } |
1875 | 0 | break; |
1876 | | |
1877 | 0 | case SID_ATTR_PARA_LEFT_TO_RIGHT: |
1878 | 0 | case SID_ATTR_PARA_RIGHT_TO_LEFT: |
1879 | 0 | { |
1880 | 0 | bool bRTL = rReq.GetSlot() == SID_ATTR_PARA_RIGHT_TO_LEFT; |
1881 | 0 | GetDoc()->SetRightToLeft(bRTL); |
1882 | 0 | GetGraphicWindow().GetGraphicWidget().GetOutputDevice().EnableRTL(bRTL); |
1883 | 0 | GetViewFrame().GetBindings().Invalidate(bRTL ? SID_ATTR_PARA_LEFT_TO_RIGHT : SID_ATTR_PARA_RIGHT_TO_LEFT); |
1884 | 0 | } |
1885 | 0 | break; |
1886 | 0 | case SID_SAVE_FORMULA: |
1887 | 0 | { |
1888 | 0 | OUString aName = "My Formula 1"; |
1889 | 0 | OUString aDesc(SmResId(STR_USER_DEFINED_FORMULA)); |
1890 | 0 | SvxNameDialog aDlg(GetFrameWeld(), aName, aDesc); |
1891 | |
|
1892 | 0 | if (aDlg.run() == RET_OK) |
1893 | 0 | { |
1894 | 0 | aName = aDlg.GetName(); |
1895 | 0 | if (SmModule::get()->GetConfig()->HasUserDefinedFormula(aName)) |
1896 | 0 | { |
1897 | 0 | std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog( |
1898 | 0 | GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, |
1899 | 0 | SmResId(STR_USER_DEFINED_FORMULA_EXISTS).replaceAll("%1", aName))); |
1900 | 0 | if (xQuery->run() == RET_NO) |
1901 | 0 | break; |
1902 | 0 | } |
1903 | 0 | if (SmEditWindow* pEditWin = GetEditWindow()) |
1904 | 0 | SmModule::get()->GetConfig()->SaveUserDefinedFormula(aName, pEditWin->GetText()); |
1905 | | |
1906 | | // Show the Elements sidebar with the "User-defined" entry selected |
1907 | 0 | GetViewFrame().ShowChildWindow(SID_SIDEBAR); |
1908 | 0 | sfx2::sidebar::Sidebar::ShowPanel(u"MathElementsPanel", |
1909 | 0 | GetViewFrame().GetFrame().GetFrameInterface()); |
1910 | 0 | GetViewFrame().GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW ); |
1911 | 0 | Broadcast(SfxHint(SfxHintId::SmNewUserFormula)); |
1912 | 0 | rReq.Ignore (); |
1913 | 0 | } |
1914 | 0 | } |
1915 | 0 | break; |
1916 | 0 | } |
1917 | 0 | rReq.Done(); |
1918 | 0 | } |
1919 | | |
1920 | | |
1921 | | void SmViewShell::GetState(SfxItemSet &rSet) |
1922 | 0 | { |
1923 | 0 | SfxWhichIter aIter(rSet); |
1924 | |
|
1925 | 0 | SmEditWindow *pEditWin = GetEditWindow(); |
1926 | 0 | for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich()) |
1927 | 0 | { |
1928 | 0 | switch (nWh) |
1929 | 0 | { |
1930 | 0 | case SID_CUT: |
1931 | 0 | case SID_COPY: |
1932 | 0 | case SID_DELETE: |
1933 | 0 | if (IsInlineEditEnabled()) |
1934 | 0 | { |
1935 | 0 | if (!GetDoc()->GetCursor().HasSelection()) |
1936 | 0 | rSet.DisableItem(nWh); |
1937 | 0 | } |
1938 | 0 | else if (! pEditWin || ! pEditWin->IsSelected()) |
1939 | 0 | rSet.DisableItem(nWh); |
1940 | 0 | break; |
1941 | | |
1942 | 0 | case SID_PASTE: |
1943 | 0 | if (pEditWin) |
1944 | 0 | { |
1945 | 0 | TransferableDataHelper aDataHelper( |
1946 | 0 | TransferableDataHelper::CreateFromClipboard( |
1947 | 0 | pEditWin->GetClipboard()) ); |
1948 | |
|
1949 | 0 | mbPasteState = aDataHelper.GetTransferable().is() && |
1950 | 0 | ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) || |
1951 | 0 | aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) || |
1952 | 0 | (aDataHelper.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) |
1953 | 0 | && aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE ))); |
1954 | 0 | } |
1955 | 0 | if( !mbPasteState ) |
1956 | 0 | rSet.DisableItem( nWh ); |
1957 | 0 | break; |
1958 | | |
1959 | 0 | case SID_ATTR_ZOOM: |
1960 | 0 | rSet.Put(SvxZoomItem( SvxZoomType::PERCENT, mxGraphicWindow->GetZoom())); |
1961 | 0 | [[fallthrough]]; |
1962 | 0 | case SID_ZOOMIN: |
1963 | 0 | case SID_ZOOMOUT: |
1964 | 0 | case SID_ZOOM_OPTIMAL: |
1965 | 0 | if ( GetViewFrame().GetFrame().IsInPlace() ) |
1966 | 0 | rSet.DisableItem( nWh ); |
1967 | 0 | break; |
1968 | | |
1969 | 0 | case SID_ATTR_ZOOMSLIDER : |
1970 | 0 | { |
1971 | 0 | const sal_uInt16 nCurrentZoom = mxGraphicWindow->GetZoom(); |
1972 | 0 | SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM ); |
1973 | 0 | aZoomSliderItem.AddSnappingPoint( 100 ); |
1974 | 0 | rSet.Put( aZoomSliderItem ); |
1975 | 0 | } |
1976 | 0 | break; |
1977 | | |
1978 | 0 | case SID_NEXTERR: |
1979 | 0 | case SID_PREVERR: |
1980 | 0 | case SID_NEXTMARK: |
1981 | 0 | case SID_PREVMARK: |
1982 | 0 | case SID_DRAW: |
1983 | 0 | case SID_SELECT: |
1984 | 0 | if (! pEditWin || pEditWin->IsEmpty()) |
1985 | 0 | rSet.DisableItem(nWh); |
1986 | 0 | break; |
1987 | | |
1988 | 0 | case SID_TEXTSTATUS: |
1989 | 0 | { |
1990 | 0 | rSet.Put(SfxStringItem(nWh, maStatusText)); |
1991 | 0 | } |
1992 | 0 | break; |
1993 | | |
1994 | 0 | case SID_FORMULACURSOR: |
1995 | 0 | { |
1996 | 0 | if (IsInlineEditEnabled()) |
1997 | 0 | rSet.DisableItem(nWh); |
1998 | 0 | else |
1999 | 0 | rSet.Put(SfxBoolItem(nWh, SmModule::get()->GetConfig()->IsShowFormulaCursor())); |
2000 | 0 | } |
2001 | 0 | break; |
2002 | 0 | case SID_ELEMENTSDOCKINGWINDOW: |
2003 | 0 | { |
2004 | 0 | const bool bState = sfx2::sidebar::Sidebar::IsPanelVisible( |
2005 | 0 | u"MathElementsPanel", GetViewFrame().GetFrame().GetFrameInterface()); |
2006 | 0 | rSet.Put(SfxBoolItem(SID_ELEMENTSDOCKINGWINDOW, bState)); |
2007 | 0 | } |
2008 | 0 | break; |
2009 | 0 | case SID_CMDBOXWINDOW: |
2010 | 0 | { |
2011 | 0 | bool bState = false; |
2012 | 0 | auto pCmdWin = GetViewFrame().GetChildWindow(SID_CMDBOXWINDOW); |
2013 | 0 | if (pCmdWin) |
2014 | 0 | bState = pCmdWin->IsVisible(); |
2015 | 0 | rSet.Put(SfxBoolItem(SID_CMDBOXWINDOW, bState)); |
2016 | 0 | } |
2017 | 0 | break; |
2018 | 0 | case SID_ATTR_PARA_LEFT_TO_RIGHT: |
2019 | 0 | rSet.Put(SfxBoolItem(nWh, !GetDoc()->GetFormat().IsRightToLeft())); |
2020 | 0 | break; |
2021 | | |
2022 | 0 | case SID_ATTR_PARA_RIGHT_TO_LEFT: |
2023 | 0 | rSet.Put(SfxBoolItem(nWh, GetDoc()->GetFormat().IsRightToLeft())); |
2024 | 0 | break; |
2025 | 0 | case SID_SAVE_FORMULA: |
2026 | 0 | if (!pEditWin || pEditWin->IsEmpty()) |
2027 | 0 | rSet.DisableItem(nWh); |
2028 | 0 | break; |
2029 | 0 | } |
2030 | 0 | } |
2031 | 0 | } |
2032 | | |
2033 | | namespace |
2034 | | { |
2035 | | css::uno::Reference<css::ui::XSidebar> |
2036 | | getSidebarFromModel(const css::uno::Reference<css::frame::XModel>& xModel) |
2037 | 0 | { |
2038 | 0 | css::uno::Reference<css::container::XChild> xChild(xModel, css::uno::UNO_QUERY); |
2039 | 0 | if (!xChild.is()) |
2040 | 0 | return nullptr; |
2041 | 0 | css::uno::Reference<css::frame::XModel> xParent(xChild->getParent(), css::uno::UNO_QUERY); |
2042 | 0 | if (!xParent.is()) |
2043 | 0 | return nullptr; |
2044 | 0 | css::uno::Reference<css::frame::XController2> xController(xParent->getCurrentController(), |
2045 | 0 | css::uno::UNO_QUERY); |
2046 | 0 | if (!xController.is()) |
2047 | 0 | return nullptr; |
2048 | 0 | css::uno::Reference<css::ui::XSidebarProvider> xSidebarProvider = xController->getSidebar(); |
2049 | 0 | if (!xSidebarProvider.is()) |
2050 | 0 | return nullptr; |
2051 | 0 | return xSidebarProvider->getSidebar(); |
2052 | 0 | } |
2053 | | class SmController : public SfxBaseController |
2054 | | { |
2055 | | public: |
2056 | | SmController(SfxViewShell& rViewShell) |
2057 | 0 | : SfxBaseController(&rViewShell) |
2058 | 0 | , mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler( |
2059 | 0 | GetContextName, this, vcl::EnumContext::Context::Math)) |
2060 | 0 | { |
2061 | 0 | rViewShell.SetContextName(GetContextName()); |
2062 | 0 | } |
2063 | | // No need to call mpSelectionChangeHandler->Disconnect() unless SmController implements XSelectionSupplier |
2064 | | // ~SmController() { mpSelectionChangeHandler->Disconnect(); } |
2065 | | |
2066 | | // css::frame::XController |
2067 | | void SAL_CALL attachFrame(const css::uno::Reference<css::frame::XFrame>& xFrame) override |
2068 | 0 | { |
2069 | 0 | SfxBaseController::attachFrame(xFrame); |
2070 | |
|
2071 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
2072 | 0 | { |
2073 | 0 | CopyLokViewCallbackFromFrameCreator(); |
2074 | | // In lok mode, DocumentHolder::ShowUI is not called on OLE in-place activation, |
2075 | | // because respective code is skipped in OCommonEmbeddedObject::SwitchStateTo_Impl, |
2076 | | // so sidebar controller does not get registered properly; do it here |
2077 | 0 | if (auto xSidebar = getSidebarFromModel(getModel())) |
2078 | 0 | { |
2079 | 0 | auto pSidebar = dynamic_cast<sfx2::sidebar::SidebarController*>(xSidebar.get()); |
2080 | 0 | assert(pSidebar); |
2081 | 0 | pSidebar->registerSidebarForFrame(this); |
2082 | 0 | pSidebar->updateModel(getModel()); |
2083 | 0 | } |
2084 | 0 | } |
2085 | | |
2086 | | // No need to call mpSelectionChangeHandler->Connect() unless SmController implements XSelectionSupplier |
2087 | 0 | mpSelectionChangeHandler->selectionChanged({}); // Installs the correct context |
2088 | 0 | } |
2089 | | |
2090 | | virtual void SAL_CALL dispose() override |
2091 | 0 | { |
2092 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
2093 | 0 | if (auto pViewShell = GetViewShell_Impl()) |
2094 | 0 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, |
2095 | 0 | OString::boolean(false)); |
2096 | |
|
2097 | 0 | SfxBaseController::dispose(); |
2098 | 0 | } |
2099 | | |
2100 | | private: |
2101 | 0 | static OUString GetContextName() { return u"Math"_ustr; } // Static constant for now |
2102 | | |
2103 | | rtl::Reference<svx::sidebar::SelectionChangeHandler> mpSelectionChangeHandler; |
2104 | | }; |
2105 | | } |
2106 | | |
2107 | | SmViewShell::SmViewShell(SfxViewFrame& rFrame_, SfxViewShell *) |
2108 | 0 | : SfxViewShell(rFrame_, SfxViewShellFlags::HAS_PRINTOPTIONS) |
2109 | 0 | , mxGraphicWindow(VclPtr<SmGraphicWindow>::Create(*this)) |
2110 | 0 | , maGraphicController(mxGraphicWindow->GetGraphicWidget(), SID_GRAPHIC_SM, rFrame_.GetBindings()) |
2111 | 0 | , mbPasteState(false) |
2112 | 0 | { |
2113 | 0 | SetStatusText(OUString()); |
2114 | 0 | SetWindow(mxGraphicWindow.get()); |
2115 | 0 | SfxShell::SetName(u"SmView"_ustr); |
2116 | 0 | SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() ); |
2117 | 0 | SetController(new SmController(*this)); |
2118 | 0 | } |
2119 | | |
2120 | | SmViewShell::~SmViewShell() |
2121 | 0 | { |
2122 | | //!! this view shell is not active anymore !! |
2123 | | // Thus 'SmGetActiveView' will give a 0 pointer. |
2124 | | // Thus we need to supply this view as argument |
2125 | 0 | if (SmEditWindow *pEditWin = GetEditWindow()) |
2126 | 0 | pEditWin->DeleteEditView(); |
2127 | 0 | mxGraphicWindow.disposeAndClear(); |
2128 | 0 | } |
2129 | | |
2130 | | void SmViewShell::Deactivate( bool bIsMDIActivate ) |
2131 | 0 | { |
2132 | 0 | if (SmEditWindow *pEdit = GetEditWindow()) |
2133 | 0 | pEdit->Flush(); |
2134 | |
|
2135 | 0 | SfxViewShell::Deactivate( bIsMDIActivate ); |
2136 | 0 | } |
2137 | | |
2138 | | void SmViewShell::Activate( bool bIsMDIActivate ) |
2139 | 0 | { |
2140 | 0 | SfxViewShell::Activate( bIsMDIActivate ); |
2141 | |
|
2142 | 0 | if (IsInlineEditEnabled()) |
2143 | 0 | { |
2144 | | // In LOK, activate in-place editing |
2145 | 0 | GetGraphicWidget().GrabFocus(); |
2146 | 0 | } |
2147 | 0 | else if (SmEditWindow *pEdit = GetEditWindow()) |
2148 | 0 | { |
2149 | | //! Since there is no way to be informed if a "drag and drop" |
2150 | | //! event has taken place, we call SetText here in order to |
2151 | | //! synchronize the GraphicWindow display with the text in the |
2152 | | //! EditEngine. |
2153 | 0 | SmDocShell *pDoc = GetDoc(); |
2154 | 0 | pDoc->SetText( pDoc->GetEditEngine().GetText() ); |
2155 | |
|
2156 | 0 | if ( bIsMDIActivate ) |
2157 | 0 | pEdit->GrabFocus(); |
2158 | 0 | } |
2159 | 0 | } |
2160 | | |
2161 | | IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void ) |
2162 | 0 | { |
2163 | 0 | assert(_pFileDlg && "SmViewShell::DialogClosedHdl(): no file dialog"); |
2164 | 0 | assert(mpDocInserter && "ScDocShell::DialogClosedHdl(): no document inserter"); |
2165 | |
|
2166 | 0 | if ( ERRCODE_NONE == _pFileDlg->GetError() ) |
2167 | 0 | { |
2168 | 0 | std::unique_ptr<SfxMedium> pMedium = mpDocInserter->CreateMedium(); |
2169 | |
|
2170 | 0 | if ( pMedium ) |
2171 | 0 | { |
2172 | 0 | if ( pMedium->IsStorage() ) |
2173 | 0 | Insert( *pMedium ); |
2174 | 0 | else |
2175 | 0 | InsertFrom( *pMedium ); |
2176 | 0 | pMedium.reset(); |
2177 | |
|
2178 | 0 | SmDocShell* pDoc = GetDoc(); |
2179 | 0 | pDoc->UpdateText(); |
2180 | 0 | pDoc->ArrangeFormula(); |
2181 | 0 | pDoc->Repaint(); |
2182 | | // adjust window, repaint, increment ModifyCount,... |
2183 | 0 | GetViewFrame().GetBindings().Invalidate(SID_GRAPHIC_SM); |
2184 | 0 | } |
2185 | 0 | } |
2186 | |
|
2187 | 0 | mpRequest->SetReturnValue( SfxBoolItem( mpRequest->GetSlot(), true ) ); |
2188 | 0 | mpRequest->Done(); |
2189 | 0 | } |
2190 | | |
2191 | | void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint ) |
2192 | 0 | { |
2193 | 0 | switch( rHint.GetId() ) |
2194 | 0 | { |
2195 | 0 | case SfxHintId::ModeChanged: |
2196 | 0 | case SfxHintId::DocChanged: |
2197 | 0 | GetViewFrame().GetBindings().InvalidateAll(false); |
2198 | 0 | break; |
2199 | 0 | default: |
2200 | 0 | break; |
2201 | 0 | } |
2202 | 0 | } |
2203 | | |
2204 | | bool SmViewShell::IsInlineEditEnabled() |
2205 | 0 | { |
2206 | 0 | return comphelper::LibreOfficeKit::isActive() |
2207 | 0 | || SmModule::get()->GetConfig()->IsInlineEditEnable(); |
2208 | 0 | } |
2209 | | |
2210 | | void SmViewShell::StartMainHelp() |
2211 | 0 | { |
2212 | 0 | Help* pHelp = Application::GetHelp(); |
2213 | 0 | if (pHelp) |
2214 | 0 | pHelp->Start(HID_SMA_MAIN_HELP, GetViewFrame().GetFrameWeld()); |
2215 | 0 | } |
2216 | | |
2217 | | void SmViewShell::ZoomByItemSet(const SfxItemSet *pSet) |
2218 | 0 | { |
2219 | 0 | assert(pSet); |
2220 | 0 | const SvxZoomItem &rZoom = pSet->Get(SID_ATTR_ZOOM); |
2221 | 0 | switch( rZoom.GetType() ) |
2222 | 0 | { |
2223 | 0 | case SvxZoomType::PERCENT: |
2224 | 0 | mxGraphicWindow->SetZoom(sal::static_int_cast<sal_uInt16>(rZoom.GetValue ())); |
2225 | 0 | break; |
2226 | | |
2227 | 0 | case SvxZoomType::OPTIMAL: |
2228 | 0 | mxGraphicWindow->ZoomToFitInWindow(); |
2229 | 0 | break; |
2230 | | |
2231 | 0 | case SvxZoomType::PAGEWIDTH: |
2232 | 0 | case SvxZoomType::WHOLEPAGE: |
2233 | 0 | { |
2234 | 0 | const MapMode aMap( SmMapUnit() ); |
2235 | 0 | SfxPrinter *pPrinter = GetPrinter( true ); |
2236 | 0 | tools::Rectangle OutputRect(Point(), pPrinter->GetOutputSize()); |
2237 | 0 | Size OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(), |
2238 | 0 | OutputRect.GetHeight()), aMap)); |
2239 | 0 | Size GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap)); |
2240 | 0 | if (GraphicSize.Width() <= 0 || GraphicSize.Height() <= 0) |
2241 | 0 | break; |
2242 | 0 | sal_uInt16 nZ = std::min(o3tl::convert(OutputSize.Width(), 100, GraphicSize.Width()), |
2243 | 0 | o3tl::convert(OutputSize.Height(), 100, GraphicSize.Height())); |
2244 | 0 | mxGraphicWindow->SetZoom(nZ); |
2245 | 0 | break; |
2246 | 0 | } |
2247 | 0 | default: |
2248 | 0 | break; |
2249 | 0 | } |
2250 | 0 | } |
2251 | | |
2252 | | std::optional<OString> SmViewShell::getLOKPayload(int nType, int nViewId) const |
2253 | 0 | { |
2254 | 0 | switch (nType) |
2255 | 0 | { |
2256 | 0 | case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: |
2257 | 0 | { |
2258 | 0 | OString sRectangle; |
2259 | 0 | if (const SmGraphicWidget& widget = GetGraphicWidget(); widget.IsCursorVisible()) |
2260 | 0 | { |
2261 | 0 | SmCursor& rCursor = GetDoc()->GetCursor(); |
2262 | 0 | OutputDevice& rOutDev = const_cast<SmGraphicWidget&>(widget).GetOutputDevice(); |
2263 | 0 | tools::Rectangle aCaret = rCursor.GetCaretRectangle(rOutDev); |
2264 | 0 | Point aFormulaDrawPos = widget.GetFormulaDrawPos(); |
2265 | 0 | aCaret.Move(aFormulaDrawPos.X(), aFormulaDrawPos.Y()); |
2266 | 0 | LokStarMathHelper helper(SfxViewShell::Current()); |
2267 | 0 | tools::Rectangle aBounds = helper.GetBoundingBox(); |
2268 | 0 | aCaret.Move(aBounds.Left(), aBounds.Top()); |
2269 | 0 | sRectangle = aCaret.toString(); |
2270 | 0 | } |
2271 | 0 | return SfxLokHelper::makeVisCursorInvalidation(nViewId, sRectangle, false, {}); |
2272 | 0 | } |
2273 | 0 | case LOK_CALLBACK_TEXT_SELECTION: |
2274 | 0 | { |
2275 | 0 | OString sRectangle; |
2276 | 0 | if (const SmGraphicWidget& widget = GetGraphicWidget(); widget.IsCursorVisible()) |
2277 | 0 | { |
2278 | 0 | SmCursor& rCursor = GetDoc()->GetCursor(); |
2279 | 0 | OutputDevice& rOutDev = const_cast<SmGraphicWidget&>(widget).GetOutputDevice(); |
2280 | 0 | tools::Rectangle aSelection = rCursor.GetSelectionRectangle(rOutDev); |
2281 | 0 | if (!aSelection.IsEmpty()) |
2282 | 0 | { |
2283 | 0 | Point aFormulaDrawPos = widget.GetFormulaDrawPos(); |
2284 | 0 | aSelection.Move(aFormulaDrawPos.X(), aFormulaDrawPos.Y()); |
2285 | 0 | LokStarMathHelper helper(SfxViewShell::Current()); |
2286 | 0 | tools::Rectangle aBounds = helper.GetBoundingBox(); |
2287 | |
|
2288 | 0 | aSelection.Move(aBounds.Left(), aBounds.Top()); |
2289 | 0 | sRectangle = aSelection.toString(); |
2290 | 0 | } |
2291 | 0 | } |
2292 | 0 | return sRectangle; |
2293 | 0 | } |
2294 | 0 | case LOK_CALLBACK_TEXT_SELECTION_START: |
2295 | 0 | case LOK_CALLBACK_TEXT_SELECTION_END: |
2296 | 0 | case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR: |
2297 | 0 | case LOK_CALLBACK_TEXT_VIEW_SELECTION: |
2298 | 0 | return {}; |
2299 | 0 | } |
2300 | 0 | return SfxViewShell::getLOKPayload(nType, nViewId); // aborts |
2301 | 0 | } |
2302 | | |
2303 | | void SmViewShell::SendCaretToLOK() const |
2304 | 0 | { |
2305 | 0 | const int nViewId = sal_Int32(GetViewShellId()); |
2306 | 0 | if (const auto payload = getLOKPayload(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, nViewId)) |
2307 | 0 | { |
2308 | 0 | libreOfficeKitViewCallbackWithViewId(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, |
2309 | 0 | *payload, nViewId); |
2310 | 0 | } |
2311 | 0 | if (const auto payload = getLOKPayload(LOK_CALLBACK_TEXT_SELECTION, nViewId)) |
2312 | 0 | { |
2313 | 0 | libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, *payload); |
2314 | 0 | } |
2315 | 0 | } |
2316 | | |
2317 | | void SmViewShell::InvalidateSlots() |
2318 | 0 | { |
2319 | 0 | auto& rBind = GetViewFrame().GetBindings(); |
2320 | 0 | rBind.Invalidate(SID_COPY); |
2321 | 0 | rBind.Invalidate(SID_CUT); |
2322 | 0 | rBind.Invalidate(SID_DELETE); |
2323 | 0 | } |
2324 | | |
2325 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |