File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <com/sun/star/accessibility/AccessibleEventId.hpp> | |||
21 | #include <com/sun/star/accessibility/AccessibleStateType.hpp> | |||
22 | #include <com/sun/star/frame/Desktop.hpp> | |||
23 | #include <com/sun/star/frame/XFramesSupplier.hpp> | |||
24 | #include <com/sun/star/container/XChild.hpp> | |||
25 | ||||
26 | #include <comphelper/processfactory.hxx> | |||
27 | #include <comphelper/servicehelper.hxx> | |||
28 | #include <comphelper/storagehelper.hxx> | |||
29 | #include <comphelper/string.hxx> | |||
30 | #include <i18nutil/unicode.hxx> | |||
31 | #include <sfx2/dispatch.hxx> | |||
32 | #include <sfx2/docfile.hxx> | |||
33 | #include <sfx2/docfilt.hxx> | |||
34 | #include <sfx2/docinsert.hxx> | |||
35 | #include <sfx2/filedlghelper.hxx> | |||
36 | #include <sfx2/infobar.hxx> | |||
37 | #include <sfx2/msg.hxx> | |||
38 | #include <sfx2/objface.hxx> | |||
39 | #include <sfx2/printer.hxx> | |||
40 | #include <sfx2/request.hxx> | |||
41 | #include <sfx2/viewfac.hxx> | |||
42 | #include <svl/eitem.hxx> | |||
43 | #include <svl/itemset.hxx> | |||
44 | #include <svl/poolitem.hxx> | |||
45 | #include <svl/stritem.hxx> | |||
46 | #include <vcl/transfer.hxx> | |||
47 | #include <svtools/colorcfg.hxx> | |||
48 | #include <svtools/miscopt.hxx> | |||
49 | #include <svl/whiter.hxx> | |||
50 | #include <svx/zoomslideritem.hxx> | |||
51 | #include <editeng/editeng.hxx> | |||
52 | #include <editeng/editview.hxx> | |||
53 | #include <svx/svxdlg.hxx> | |||
54 | #include <sfx2/zoomitem.hxx> | |||
55 | #include <vcl/commandevent.hxx> | |||
56 | #include <vcl/event.hxx> | |||
57 | #include <vcl/decoview.hxx> | |||
58 | #include <vcl/menu.hxx> | |||
59 | #include <vcl/settings.hxx> | |||
60 | #include <vcl/virdev.hxx> | |||
61 | #include <sal/log.hxx> | |||
62 | #include <tools/svborder.hxx> | |||
63 | ||||
64 | #include <unotools/streamwrap.hxx> | |||
65 | ||||
66 | #include <unomodel.hxx> | |||
67 | #include <view.hxx> | |||
68 | #include "cfgitem.hxx" | |||
69 | #include <dialog.hxx> | |||
70 | #include <document.hxx> | |||
71 | #include <starmath.hrc> | |||
72 | #include <strings.hrc> | |||
73 | #include <smmod.hxx> | |||
74 | #include "mathmlimport.hxx" | |||
75 | #include <cursor.hxx> | |||
76 | #include "accessibility.hxx" | |||
77 | #include <ElementsDockingWindow.hxx> | |||
78 | #include <helpids.h> | |||
79 | #include <cassert> | |||
80 | #include <memory> | |||
81 | ||||
82 | #define MINZOOMsal_uInt16(25) sal_uInt16(25) | |||
83 | #define MAXZOOMsal_uInt16(800) sal_uInt16(800) | |||
84 | ||||
85 | // space around the edit window, in pixels | |||
86 | // fdo#69111: Increased border on the top so that the window is | |||
87 | // easier to tear off. | |||
88 | #define CMD_BOX_PADDING4 4 | |||
89 | #define CMD_BOX_PADDING_TOP10 10 | |||
90 | ||||
91 | #define ShellClass_SmViewShell | |||
92 | #include <smslots.hxx> | |||
93 | ||||
94 | using namespace css; | |||
95 | using namespace css::accessibility; | |||
96 | using namespace css::uno; | |||
97 | ||||
98 | SmGraphicWindow::SmGraphicWindow(SmViewShell* pShell) | |||
99 | : ScrollableWindow(&pShell->GetViewFrame()->GetWindow()) | |||
100 | , pViewShell(pShell) | |||
101 | , nZoom(100) | |||
102 | { | |||
103 | assert(pViewShell)(static_cast <bool> (pViewShell) ? void (0) : __assert_fail ("pViewShell", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 103, __extension__ __PRETTY_FUNCTION__)); | |||
104 | // docking windows are usually hidden (often already done in the | |||
105 | // resource) and will be shown by the sfx framework. | |||
106 | Hide(); | |||
107 | ||||
108 | const Fraction aFraction(1, 1); | |||
109 | SetMapMode(MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction)); | |||
110 | ||||
111 | SetTotalSize(); | |||
112 | ||||
113 | SetHelpId(HID_SMA_WIN_DOCUMENT"STARMATH_HID_SMA_WIN_DOCUMENT"); | |||
114 | ||||
115 | ShowLine(false); | |||
116 | CaretBlinkInit(); | |||
117 | } | |||
118 | ||||
119 | SmGraphicWindow::~SmGraphicWindow() | |||
120 | { | |||
121 | disposeOnce(); | |||
122 | } | |||
123 | ||||
124 | void SmGraphicWindow::dispose() | |||
125 | { | |||
126 | if (mxAccessible.is()) | |||
127 | mxAccessible->ClearWin(); // make Accessible nonfunctional | |||
128 | mxAccessible.clear(); | |||
129 | CaretBlinkStop(); | |||
130 | ScrollableWindow::dispose(); | |||
131 | } | |||
132 | ||||
133 | void SmGraphicWindow::StateChanged(StateChangedType eType) | |||
134 | { | |||
135 | if (eType == StateChangedType::InitShow) | |||
136 | Show(); | |||
137 | ScrollableWindow::StateChanged(eType); | |||
138 | } | |||
139 | ||||
140 | void SmGraphicWindow::MouseButtonDown(const MouseEvent& rMEvt) | |||
141 | { | |||
142 | ScrollableWindow::MouseButtonDown(rMEvt); | |||
143 | ||||
144 | GrabFocus(); | |||
145 | ||||
146 | // set formula-cursor and selection of edit window according to the | |||
147 | // position clicked at | |||
148 | ||||
149 | SAL_WARN_IF( rMEvt.GetClicks() == 0, "starmath", "0 clicks" )do { if (true && (rMEvt.GetClicks() == 0)) { switch ( sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "starmath" )) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "0 clicks") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "149" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "0 clicks"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "0 clicks"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath") , ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "149" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "0 clicks") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "149" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "0 clicks"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "0 clicks"; :: sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath") , ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "149" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
150 | if ( !rMEvt.IsLeft() ) | |||
151 | return; | |||
152 | ||||
153 | // get click position relative to formula | |||
154 | Point aPos (PixelToLogic(rMEvt.GetPosPixel()) | |||
155 | - GetFormulaDrawPos()); | |||
156 | ||||
157 | const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(); | |||
158 | if (!pTree) | |||
159 | return; | |||
160 | ||||
161 | if (IsInlineEditEnabled()) { | |||
162 | pViewShell->GetDoc()->GetCursor().MoveTo(this, aPos, !rMEvt.IsShift()); | |||
163 | return; | |||
164 | } | |||
165 | const SmNode *pNode = nullptr; | |||
166 | // if it was clicked inside the formula then get the appropriate node | |||
167 | if (pTree->OrientedDist(aPos) <= 0) | |||
168 | pNode = pTree->FindRectClosestTo(aPos); | |||
169 | ||||
170 | if (!pNode) | |||
171 | return; | |||
172 | ||||
173 | SmEditWindow *pEdit = pViewShell->GetEditWindow(); | |||
174 | if (!pEdit) | |||
175 | return; | |||
176 | const SmToken aToken (pNode->GetToken()); | |||
177 | ||||
178 | // set selection to the beginning of the token | |||
179 | ESelection aSel (aToken.nRow - 1, aToken.nCol - 1); | |||
180 | ||||
181 | if (rMEvt.GetClicks() != 1 || aToken.eType == TPLACE) | |||
182 | aSel.nEndPos = aSel.nEndPos + sal::static_int_cast< sal_uInt16 >(aToken.aText.getLength()); | |||
183 | ||||
184 | pEdit->SetSelection(aSel); | |||
185 | SetCursor(pNode); | |||
186 | ||||
187 | // allow for immediate editing and | |||
188 | //! implicitly synchronize the cursor position mark in this window | |||
189 | pEdit->GrabFocus(); | |||
190 | } | |||
191 | ||||
192 | void SmGraphicWindow::MouseMove(const MouseEvent &rMEvt) | |||
193 | { | |||
194 | ScrollableWindow::MouseMove(rMEvt); | |||
195 | ||||
196 | if (rMEvt.IsLeft() && IsInlineEditEnabled()) | |||
197 | { | |||
198 | Point aPos(PixelToLogic(rMEvt.GetPosPixel()) - GetFormulaDrawPos()); | |||
199 | pViewShell->GetDoc()->GetCursor().MoveTo(this, aPos, false); | |||
200 | ||||
201 | CaretBlinkStop(); | |||
202 | SetIsCursorVisible(true); | |||
203 | CaretBlinkStart(); | |||
204 | RepaintViewShellDoc(); | |||
205 | } | |||
206 | } | |||
207 | ||||
208 | bool SmGraphicWindow::IsInlineEditEnabled() const | |||
209 | { | |||
210 | return pViewShell->IsInlineEditEnabled(); | |||
211 | } | |||
212 | ||||
213 | void SmGraphicWindow::GetFocus() | |||
214 | { | |||
215 | if (!IsInlineEditEnabled()) | |||
216 | return; | |||
217 | if (pViewShell->GetEditWindow()) | |||
218 | pViewShell->GetEditWindow()->Flush(); | |||
219 | //Let view shell know what insertions should be done in visual editor | |||
220 | pViewShell->SetInsertIntoEditWindow(false); | |||
221 | SetIsCursorVisible(true); | |||
222 | ShowLine(true); | |||
223 | CaretBlinkStart(); | |||
224 | RepaintViewShellDoc(); | |||
225 | } | |||
226 | ||||
227 | void SmGraphicWindow::LoseFocus() | |||
228 | { | |||
229 | ScrollableWindow::LoseFocus(); | |||
230 | if (mxAccessible.is()) | |||
231 | { | |||
232 | uno::Any aOldValue, aNewValue; | |||
233 | aOldValue <<= AccessibleStateType::FOCUSED; | |||
234 | // aNewValue remains empty | |||
235 | mxAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED, | |||
236 | aOldValue, aNewValue ); | |||
237 | } | |||
238 | if (!IsInlineEditEnabled()) | |||
239 | return; | |||
240 | SetIsCursorVisible(false); | |||
241 | ShowLine(false); | |||
242 | CaretBlinkStop(); | |||
243 | RepaintViewShellDoc(); | |||
244 | } | |||
245 | ||||
246 | void SmGraphicWindow::RepaintViewShellDoc() | |||
247 | { | |||
248 | SmDocShell* pDoc = pViewShell->GetDoc(); | |||
249 | if (pDoc) | |||
250 | pDoc->Repaint(); | |||
251 | } | |||
252 | ||||
253 | IMPL_LINK_NOARG(SmGraphicWindow, CaretBlinkTimerHdl, Timer *, void)void SmGraphicWindow::LinkStubCaretBlinkTimerHdl(void * instance , Timer * data) { return static_cast<SmGraphicWindow *> (instance)->CaretBlinkTimerHdl(data); } void SmGraphicWindow ::CaretBlinkTimerHdl(__attribute__ ((unused)) Timer *) | |||
254 | { | |||
255 | if (IsCursorVisible()) | |||
256 | SetIsCursorVisible(false); | |||
257 | else | |||
258 | SetIsCursorVisible(true); | |||
259 | ||||
260 | RepaintViewShellDoc(); | |||
261 | } | |||
262 | ||||
263 | void SmGraphicWindow::CaretBlinkInit() | |||
264 | { | |||
265 | aCaretBlinkTimer.SetInvokeHandler(LINK(this, SmGraphicWindow, CaretBlinkTimerHdl)::tools::detail::makeLink( ::tools::detail::castTo<SmGraphicWindow *>(this), &SmGraphicWindow::LinkStubCaretBlinkTimerHdl )); | |||
266 | aCaretBlinkTimer.SetTimeout( ScrollableWindow::GetSettings().GetStyleSettings().GetCursorBlinkTime() ); | |||
267 | } | |||
268 | ||||
269 | void SmGraphicWindow::CaretBlinkStart() | |||
270 | { | |||
271 | if (!IsInlineEditEnabled()) | |||
272 | return; | |||
273 | if (aCaretBlinkTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME((sal_uInt64) 0xFFFFFFFFFFFFFFFFul)) | |||
274 | aCaretBlinkTimer.Start(); | |||
275 | } | |||
276 | ||||
277 | void SmGraphicWindow::CaretBlinkStop() | |||
278 | { | |||
279 | if (!IsInlineEditEnabled()) | |||
280 | return; | |||
281 | aCaretBlinkTimer.Stop(); | |||
282 | } | |||
283 | ||||
284 | void SmGraphicWindow::ShowCursor(bool bShow) | |||
285 | // shows or hides the formula-cursor depending on 'bShow' is true or not | |||
286 | { | |||
287 | if (IsInlineEditEnabled()) | |||
288 | return; | |||
289 | ||||
290 | bool bInvert = bShow != IsCursorVisible(); | |||
291 | ||||
292 | if (bInvert) | |||
293 | InvertTracking(aCursorRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow); | |||
294 | ||||
295 | SetIsCursorVisible(bShow); | |||
296 | } | |||
297 | ||||
298 | void SmGraphicWindow::ShowLine(bool bShow) | |||
299 | { | |||
300 | if (!IsInlineEditEnabled()) | |||
301 | return; | |||
302 | ||||
303 | bIsLineVisible = bShow; | |||
304 | } | |||
305 | ||||
306 | void SmGraphicWindow::SetCursor(const SmNode *pNode) | |||
307 | { | |||
308 | if (IsInlineEditEnabled()) | |||
309 | return; | |||
310 | ||||
311 | const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(); | |||
312 | ||||
313 | // get appropriate rectangle | |||
314 | Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()), | |||
315 | aTLPos (GetFormulaDrawPos() + aOffset); | |||
316 | aTLPos.AdjustX( -(pNode->GetItalicLeftSpace()) ); | |||
317 | Size aSize (pNode->GetItalicSize()); | |||
318 | ||||
319 | SetCursor(tools::Rectangle(aTLPos, aSize)); | |||
320 | } | |||
321 | ||||
322 | void SmGraphicWindow::SetCursor(const tools::Rectangle &rRect) | |||
323 | // sets cursor to new position (rectangle) 'rRect'. | |||
324 | // The old cursor will be removed, and the new one will be shown if | |||
325 | // that is activated in the ConfigItem | |||
326 | { | |||
327 | if (IsInlineEditEnabled()) | |||
328 | return; | |||
329 | ||||
330 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
331 | ||||
332 | if (IsCursorVisible()) | |||
333 | ShowCursor(false); // clean up remainings of old cursor | |||
334 | aCursorRect = rRect; | |||
335 | if (pp->GetConfig()->IsShowFormulaCursor()) | |||
336 | ShowCursor(true); // draw new cursor | |||
337 | } | |||
338 | ||||
339 | const SmNode * SmGraphicWindow::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol) | |||
340 | // looks for a VISIBLE node in the formula tree with its token at | |||
341 | // (or around) the position 'nRow', 'nCol' in the edit window | |||
342 | // (row and column numbering starts with 1 there!). | |||
343 | // If there is such a node the formula-cursor is set to cover that nodes | |||
344 | // rectangle. If not the formula-cursor will be hidden. | |||
345 | // In any case the search result is being returned. | |||
346 | { | |||
347 | if (IsInlineEditEnabled()) | |||
348 | return nullptr; | |||
349 | ||||
350 | // find visible node with token at nRow, nCol | |||
351 | const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(), | |||
352 | *pNode = nullptr; | |||
353 | if (pTree) | |||
354 | pNode = pTree->FindTokenAt(nRow, nCol); | |||
355 | ||||
356 | if (pNode) | |||
357 | SetCursor(pNode); | |||
358 | else | |||
359 | ShowCursor(false); | |||
360 | ||||
361 | return pNode; | |||
362 | } | |||
363 | ||||
364 | void SmGraphicWindow::ApplySettings(vcl::RenderContext& rRenderContext) | |||
365 | { | |||
366 | rRenderContext.SetBackground(SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) )->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor); | |||
367 | } | |||
368 | ||||
369 | void SmGraphicWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) | |||
370 | { | |||
371 | SmDocShell& rDoc = *pViewShell->GetDoc(); | |||
372 | Point aPoint; | |||
373 | ||||
374 | rDoc.DrawFormula(rRenderContext, aPoint, true); //! modifies aPoint to be the topleft | |||
375 | //! corner of the formula | |||
376 | aFormulaDrawPos = aPoint; | |||
377 | if (IsInlineEditEnabled()) | |||
378 | { | |||
379 | //Draw cursor if any... | |||
380 | if (pViewShell->GetDoc()->HasCursor() && IsLineVisible()) | |||
381 | pViewShell->GetDoc()->GetCursor().Draw(rRenderContext, aPoint, IsCursorVisible()); | |||
382 | } | |||
383 | else | |||
384 | { | |||
385 | SetIsCursorVisible(false); // (old) cursor must be drawn again | |||
386 | ||||
387 | const SmEditWindow* pEdit = pViewShell->GetEditWindow(); | |||
388 | if (pEdit) | |||
389 | { // get new position for formula-cursor (for possible altered formula) | |||
390 | sal_Int32 nRow; | |||
391 | sal_uInt16 nCol; | |||
392 | SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol); | |||
393 | nRow++; | |||
394 | nCol++; | |||
395 | const SmNode *pFound = SetCursorPos(static_cast<sal_uInt16>(nRow), nCol); | |||
396 | ||||
397 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
398 | if (pFound && pp->GetConfig()->IsShowFormulaCursor()) | |||
399 | ShowCursor(true); | |||
400 | } | |||
401 | } | |||
402 | } | |||
403 | ||||
404 | ||||
405 | void SmGraphicWindow::SetTotalSize () | |||
406 | { | |||
407 | SmDocShell &rDoc = *pViewShell->GetDoc(); | |||
408 | const Size aTmp( PixelToLogic( LogicToPixel( rDoc.GetSize() ))); | |||
409 | if ( aTmp != ScrollableWindow::GetTotalSize() ) | |||
410 | ScrollableWindow::SetTotalSize( aTmp ); | |||
411 | } | |||
412 | ||||
413 | void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt) | |||
414 | { | |||
415 | if (!IsInlineEditEnabled()) { | |||
416 | if (! (GetView() && GetView()->KeyInput(rKEvt)) ) | |||
417 | ScrollableWindow::KeyInput(rKEvt); | |||
418 | return; | |||
419 | } | |||
420 | ||||
421 | SmCursor& rCursor = pViewShell->GetDoc()->GetCursor(); | |||
422 | KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction(); | |||
423 | if (eFunc == KeyFuncType::COPY) | |||
424 | rCursor.Copy(); | |||
425 | else if (eFunc == KeyFuncType::CUT) | |||
426 | rCursor.Cut(); | |||
427 | else if (eFunc == KeyFuncType::PASTE) | |||
428 | rCursor.Paste(); | |||
429 | else { | |||
430 | sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); | |||
431 | switch(nCode) | |||
432 | { | |||
433 | case KEY_LEFT: | |||
434 | { | |||
435 | rCursor.Move(this, MoveLeft, !rKEvt.GetKeyCode().IsShift()); | |||
436 | }break; | |||
437 | case KEY_RIGHT: | |||
438 | { | |||
439 | rCursor.Move(this, MoveRight, !rKEvt.GetKeyCode().IsShift()); | |||
440 | }break; | |||
441 | case KEY_UP: | |||
442 | { | |||
443 | rCursor.Move(this, MoveUp, !rKEvt.GetKeyCode().IsShift()); | |||
444 | }break; | |||
445 | case KEY_DOWN: | |||
446 | { | |||
447 | rCursor.Move(this, MoveDown, !rKEvt.GetKeyCode().IsShift()); | |||
448 | }break; | |||
449 | case KEY_RETURN: | |||
450 | { | |||
451 | if(!rKEvt.GetKeyCode().IsShift()) | |||
452 | rCursor.InsertRow(); | |||
453 | }break; | |||
454 | case KEY_DELETE: | |||
455 | { | |||
456 | if(!rCursor.HasSelection()){ | |||
457 | rCursor.Move(this, MoveRight, false); | |||
458 | if(rCursor.HasComplexSelection()) break; | |||
459 | } | |||
460 | rCursor.Delete(); | |||
461 | }break; | |||
462 | case KEY_BACKSPACE: | |||
463 | { | |||
464 | rCursor.DeletePrev(this); | |||
465 | }break; | |||
466 | case KEY_ADD: | |||
467 | rCursor.InsertElement(PlusElement); | |||
468 | break; | |||
469 | case KEY_SUBTRACT: | |||
470 | if(rKEvt.GetKeyCode().IsShift()) | |||
471 | rCursor.InsertSubSup(RSUB); | |||
472 | else | |||
473 | rCursor.InsertElement(MinusElement); | |||
474 | break; | |||
475 | case KEY_MULTIPLY: | |||
476 | rCursor.InsertElement(CDotElement); | |||
477 | break; | |||
478 | case KEY_DIVIDE: | |||
479 | rCursor.InsertFraction(); | |||
480 | break; | |||
481 | case KEY_LESS: | |||
482 | rCursor.InsertElement(LessThanElement); | |||
483 | break; | |||
484 | case KEY_GREATER: | |||
485 | rCursor.InsertElement(GreaterThanElement); | |||
486 | break; | |||
487 | case KEY_EQUAL: | |||
488 | rCursor.InsertElement(EqualElement); | |||
489 | break; | |||
490 | default: | |||
491 | { | |||
492 | sal_Unicode code = rKEvt.GetCharCode(); | |||
493 | ||||
494 | if(code == ' ') { | |||
495 | rCursor.InsertElement(BlankElement); | |||
496 | }else if(code == '^') { | |||
497 | rCursor.InsertSubSup(RSUP); | |||
498 | }else if(code == '(') { | |||
499 | rCursor.InsertBrackets(SmBracketType::Round); | |||
500 | }else if(code == '[') { | |||
501 | rCursor.InsertBrackets(SmBracketType::Square); | |||
502 | }else if(code == '{') { | |||
503 | rCursor.InsertBrackets(SmBracketType::Curly); | |||
504 | }else if(code == '!') { | |||
505 | rCursor.InsertElement(FactorialElement); | |||
506 | }else if(code == '%') { | |||
507 | rCursor.InsertElement(PercentElement); | |||
508 | } | |||
509 | else if ((code == ')' && rCursor.IsAtTailOfBracket(SmBracketType::Round)) | |||
510 | || (code == ']' && rCursor.IsAtTailOfBracket(SmBracketType::Square)) | |||
511 | || (code == '}' && rCursor.IsAtTailOfBracket(SmBracketType::Curly))) | |||
512 | { | |||
513 | rCursor.Move(this, MoveRight); | |||
514 | } | |||
515 | else{ | |||
516 | if(code != 0){ | |||
517 | rCursor.InsertText(OUString(code)); | |||
518 | }else if (! (GetView() && GetView()->KeyInput(rKEvt)) ) | |||
519 | ScrollableWindow::KeyInput(rKEvt); | |||
520 | } | |||
521 | } | |||
522 | } | |||
523 | } | |||
524 | CaretBlinkStop(); | |||
525 | CaretBlinkStart(); | |||
526 | SetIsCursorVisible(true); | |||
527 | RepaintViewShellDoc(); | |||
528 | } | |||
529 | ||||
530 | ||||
531 | void SmGraphicWindow::Command(const CommandEvent& rCEvt) | |||
532 | { | |||
533 | bool bCallBase = true; | |||
534 | if ( !pViewShell->GetViewFrame()->GetFrame().IsInPlace() ) | |||
535 | { | |||
536 | switch ( rCEvt.GetCommand() ) | |||
537 | { | |||
538 | case CommandEventId::ContextMenu: | |||
539 | { | |||
540 | GetParent()->ToTop(); | |||
541 | Point aPos(5, 5); | |||
542 | if (rCEvt.IsMouseEvent()) | |||
543 | aPos = rCEvt.GetMousePosPixel(); | |||
544 | ||||
545 | // added for replaceability of context menus | |||
546 | SfxDispatcher::ExecutePopup( this, &aPos ); | |||
547 | ||||
548 | bCallBase = false; | |||
549 | } | |||
550 | break; | |||
551 | ||||
552 | case CommandEventId::Wheel: | |||
553 | { | |||
554 | const CommandWheelData* pWData = rCEvt.GetWheelData(); | |||
555 | if ( pWData && CommandWheelMode::ZOOM == pWData->GetMode() ) | |||
556 | { | |||
557 | sal_uInt16 nTmpZoom = GetZoom(); | |||
558 | if( 0 > pWData->GetDelta() ) | |||
559 | nTmpZoom -= 10; | |||
560 | else | |||
561 | nTmpZoom += 10; | |||
562 | SetZoom( nTmpZoom ); | |||
563 | bCallBase = false; | |||
564 | } | |||
565 | } | |||
566 | break; | |||
567 | ||||
568 | default: break; | |||
569 | } | |||
570 | } | |||
571 | if ( bCallBase ) | |||
572 | ScrollableWindow::Command (rCEvt); | |||
573 | } | |||
574 | ||||
575 | ||||
576 | void SmGraphicWindow::SetZoom(sal_uInt16 Factor) | |||
577 | { | |||
578 | nZoom = std::min(std::max(Factor, MINZOOMsal_uInt16(25)), MAXZOOMsal_uInt16(800)); | |||
579 | Fraction aFraction (nZoom, 100); | |||
580 | SetMapMode( MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction) ); | |||
581 | SetTotalSize(); | |||
582 | SmViewShell *pViewSh = GetView(); | |||
583 | if (pViewSh) | |||
584 | { | |||
585 | pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0)); | |||
586 | pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER( 10000 + 1065 )); | |||
587 | } | |||
588 | Invalidate(); | |||
589 | } | |||
590 | ||||
591 | ||||
592 | void SmGraphicWindow::ZoomToFitInWindow() | |||
593 | { | |||
594 | SmDocShell &rDoc = *pViewShell->GetDoc(); | |||
595 | ||||
596 | // set defined mapmode before calling 'LogicToPixel' below | |||
597 | SetMapMode(MapMode(MapUnit::Map100thMM)); | |||
598 | ||||
599 | Size aSize (LogicToPixel(rDoc.GetSize())); | |||
600 | Size aWindowSize (GetSizePixel()); | |||
601 | ||||
602 | if (!aSize.IsEmpty()) | |||
603 | { | |||
604 | long nVal = std::min ((85 * aWindowSize.Width()) / aSize.Width(), | |||
605 | (85 * aWindowSize.Height()) / aSize.Height()); | |||
606 | SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) ); | |||
607 | } | |||
608 | } | |||
609 | ||||
610 | uno::Reference< XAccessible > SmGraphicWindow::CreateAccessible() | |||
611 | { | |||
612 | if (!mxAccessible.is()) | |||
613 | { | |||
614 | mxAccessible = new SmGraphicAccessible( this ); | |||
615 | } | |||
616 | return mxAccessible.get(); | |||
617 | } | |||
618 | ||||
619 | /**************************************************************************/ | |||
620 | ||||
621 | ||||
622 | SmGraphicController::SmGraphicController(SmGraphicWindow &rSmGraphic, | |||
623 | sal_uInt16 nId_, | |||
624 | SfxBindings &rBindings) : | |||
625 | SfxControllerItem(nId_, rBindings), | |||
626 | rGraphic(rSmGraphic) | |||
627 | { | |||
628 | } | |||
629 | ||||
630 | ||||
631 | void SmGraphicController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) | |||
632 | { | |||
633 | rGraphic.SetTotalSize(); | |||
634 | rGraphic.Invalidate(); | |||
635 | SfxControllerItem::StateChanged (nSID, eState, pState); | |||
636 | } | |||
637 | ||||
638 | ||||
639 | /**************************************************************************/ | |||
640 | ||||
641 | ||||
642 | SmEditController::SmEditController(SmEditWindow &rSmEdit, | |||
643 | sal_uInt16 nId_, | |||
644 | SfxBindings &rBindings) : | |||
645 | SfxControllerItem(nId_, rBindings), | |||
646 | rEdit(rSmEdit) | |||
647 | { | |||
648 | } | |||
649 | ||||
650 | ||||
651 | ||||
652 | void SmEditController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) | |||
653 | { | |||
654 | const SfxStringItem *pItem = dynamic_cast<const SfxStringItem*>( pState); | |||
655 | ||||
656 | if ((pItem != nullptr) && (rEdit.GetText() != pItem->GetValue())) | |||
657 | rEdit.SetText(pItem->GetValue()); | |||
658 | SfxControllerItem::StateChanged (nSID, eState, pState); | |||
659 | } | |||
660 | ||||
661 | /**************************************************************************/ | |||
662 | SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings *pBindings_, SfxChildWindow *pChildWindow, | |||
663 | vcl::Window *pParent) : | |||
664 | SfxDockingWindow(pBindings_, pChildWindow, pParent, WB_MOVEABLE|WB_CLOSEABLE|WB_SIZEABLE|WB_DOCKABLE), | |||
665 | aEdit (VclPtr<SmEditWindow>::Create(*this)), | |||
666 | aController (*aEdit, SID_TEXT((30000 + 256) + 100), *pBindings_), | |||
667 | bExiting (false) | |||
668 | { | |||
669 | SetHelpId( HID_SMA_COMMAND_WIN"STARMATH_HID_SMA_COMMAND_WIN" ); | |||
670 | SetSizePixel(LogicToPixel(Size(292 , 94), MapMode(MapUnit::MapAppFont))); | |||
671 | SetText(SmResId(STR_CMDBOXWINDOWreinterpret_cast<char const *>("STR_CMDBOXWINDOW" "\004" u8"Commands"))); | |||
672 | ||||
673 | Hide(); | |||
674 | ||||
675 | aInitialFocusTimer.SetInvokeHandler(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl)::tools::detail::makeLink( ::tools::detail::castTo<SmCmdBoxWindow *>(this), &SmCmdBoxWindow::LinkStubInitialFocusTimerHdl )); | |||
676 | aInitialFocusTimer.SetTimeout(100); | |||
677 | } | |||
678 | ||||
679 | SmCmdBoxWindow::~SmCmdBoxWindow () | |||
680 | { | |||
681 | disposeOnce(); | |||
682 | } | |||
683 | ||||
684 | void SmCmdBoxWindow::dispose() | |||
685 | { | |||
686 | aInitialFocusTimer.Stop(); | |||
687 | bExiting = true; | |||
688 | aController.dispose(); | |||
689 | aEdit.disposeAndClear(); | |||
| ||||
690 | SfxDockingWindow::dispose(); | |||
691 | } | |||
692 | ||||
693 | SmViewShell * SmCmdBoxWindow::GetView() | |||
694 | { | |||
695 | SfxDispatcher *pDispatcher = GetBindings().GetDispatcher(); | |||
696 | SfxViewShell *pView = pDispatcher ? pDispatcher->GetFrame()->GetViewShell() : nullptr; | |||
697 | return dynamic_cast<SmViewShell*>( pView); | |||
698 | } | |||
699 | ||||
700 | void SmCmdBoxWindow::Resize() | |||
701 | { | |||
702 | tools::Rectangle aRect(Point(0, 0), GetOutputSizePixel()); | |||
703 | aRect.AdjustLeft(CMD_BOX_PADDING4 ); | |||
704 | aRect.AdjustTop(CMD_BOX_PADDING_TOP10 ); | |||
705 | aRect.AdjustRight( -(CMD_BOX_PADDING4) ); | |||
706 | aRect.AdjustBottom( -(CMD_BOX_PADDING4) ); | |||
707 | ||||
708 | DecorationView aView(this); | |||
709 | aRect = aView.DrawFrame(aRect, DrawFrameStyle::In, DrawFrameFlags::NoDraw); | |||
710 | ||||
711 | aEdit->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize()); | |||
712 | SfxDockingWindow::Resize(); | |||
713 | Invalidate(); | |||
714 | } | |||
715 | ||||
716 | void SmCmdBoxWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) | |||
717 | { | |||
718 | tools::Rectangle aRect(Point(0, 0), GetOutputSizePixel()); | |||
719 | aRect.AdjustLeft(CMD_BOX_PADDING4 ); | |||
720 | aRect.AdjustTop(CMD_BOX_PADDING_TOP10 ); | |||
721 | aRect.AdjustRight( -(CMD_BOX_PADDING4) ); | |||
722 | aRect.AdjustBottom( -(CMD_BOX_PADDING4) ); | |||
723 | ||||
724 | aEdit->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize()); | |||
725 | ||||
726 | DecorationView aView(&rRenderContext); | |||
727 | aView.DrawFrame( aRect, DrawFrameStyle::In ); | |||
728 | } | |||
729 | ||||
730 | Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign) | |||
731 | { | |||
732 | switch (eAlign) | |||
733 | { | |||
734 | case SfxChildAlignment::LEFT: | |||
735 | case SfxChildAlignment::RIGHT: | |||
736 | return Size(); | |||
737 | default: | |||
738 | break; | |||
739 | } | |||
740 | return SfxDockingWindow::CalcDockingSize(eAlign); | |||
741 | } | |||
742 | ||||
743 | SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual, | |||
744 | SfxChildAlignment eWish) | |||
745 | { | |||
746 | switch (eWish) | |||
747 | { | |||
748 | case SfxChildAlignment::TOP: | |||
749 | case SfxChildAlignment::BOTTOM: | |||
750 | case SfxChildAlignment::NOALIGNMENT: | |||
751 | return eWish; | |||
752 | default: | |||
753 | break; | |||
754 | } | |||
755 | ||||
756 | return eActual; | |||
757 | } | |||
758 | ||||
759 | void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange ) | |||
760 | { | |||
761 | if (StateChangedType::InitShow == nStateChange) | |||
762 | { | |||
763 | Resize(); // avoid SmEditWindow not being painted correctly | |||
764 | ||||
765 | // set initial position of window in floating mode | |||
766 | if (IsFloatingMode()) | |||
767 | AdjustPosition(); //! don't change pos in docking-mode ! | |||
768 | ||||
769 | aInitialFocusTimer.Start(); | |||
770 | } | |||
771 | ||||
772 | SfxDockingWindow::StateChanged( nStateChange ); | |||
773 | } | |||
774 | ||||
775 | IMPL_LINK_NOARG( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, void )void SmCmdBoxWindow::LinkStubInitialFocusTimerHdl(void * instance , Timer * data) { return static_cast<SmCmdBoxWindow *>( instance)->InitialFocusTimerHdl(data); } void SmCmdBoxWindow ::InitialFocusTimerHdl(__attribute__ ((unused)) Timer *) | |||
776 | { | |||
777 | // We want to have the focus in the edit window once Math has been opened | |||
778 | // to allow for immediate typing. | |||
779 | // Problem: There is no proper way to do this | |||
780 | // Thus: this timer based solution has been implemented (see GrabFocus below) | |||
781 | ||||
782 | // Follow-up problem (#i114910): grabbing the focus may bust the help system since | |||
783 | // it relies on getting the current frame which conflicts with grabbing the focus. | |||
784 | // Thus aside from the 'GrabFocus' call everything else is to get the | |||
785 | // help reliably working despite using 'GrabFocus'. | |||
786 | ||||
787 | try | |||
788 | { | |||
789 | uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( comphelper::getProcessComponentContext() ); | |||
790 | ||||
791 | aEdit->GrabFocus(); | |||
792 | ||||
793 | SmViewShell* pView = GetView(); | |||
794 | assert(pView)(static_cast <bool> (pView) ? void (0) : __assert_fail ( "pView", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 794, __extension__ __PRETTY_FUNCTION__)); | |||
795 | bool bInPlace = pView->GetViewFrame()->GetFrame().IsInPlace(); | |||
796 | uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface()); | |||
797 | if ( bInPlace ) | |||
798 | { | |||
799 | uno::Reference<container::XChild> xModel(pView->GetDoc()->GetModel(), | |||
800 | uno::UNO_QUERY_THROW); | |||
801 | uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW ); | |||
802 | uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() ); | |||
803 | uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW ); | |||
804 | xParentFrame->setActiveFrame( xFrame ); | |||
805 | } | |||
806 | else | |||
807 | { | |||
808 | xDesktop->setActiveFrame( xFrame ); | |||
809 | } | |||
810 | } | |||
811 | catch (uno::Exception &) | |||
812 | { | |||
813 | SAL_WARN( "starmath", "failed to properly set initial focus to edit window" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "failed to properly set initial focus to edit window" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "813" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "failed to properly set initial focus to edit window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "failed to properly set initial focus to edit window" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "813" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "failed to properly set initial focus to edit window" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "813" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "failed to properly set initial focus to edit window" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "failed to properly set initial focus to edit window" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "813" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
814 | } | |||
815 | } | |||
816 | ||||
817 | void SmCmdBoxWindow::AdjustPosition() | |||
818 | { | |||
819 | const tools::Rectangle aRect( Point(), GetParent()->GetOutputSizePixel() ); | |||
820 | Point aTopLeft( Point( aRect.Left(), | |||
821 | aRect.Bottom() - GetSizePixel().Height() ) ); | |||
822 | Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) ); | |||
823 | if (aPos.X() < 0) | |||
824 | aPos.setX( 0 ); | |||
825 | if (aPos.Y() < 0) | |||
826 | aPos.setY( 0 ); | |||
827 | SetPosPixel( aPos ); | |||
828 | } | |||
829 | ||||
830 | void SmCmdBoxWindow::ToggleFloatingMode() | |||
831 | { | |||
832 | SfxDockingWindow::ToggleFloatingMode(); | |||
833 | ||||
834 | if (GetFloatingWindow()) | |||
835 | GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50)); | |||
836 | } | |||
837 | ||||
838 | void SmCmdBoxWindow::GetFocus() | |||
839 | { | |||
840 | if (!bExiting) | |||
841 | aEdit->GrabFocus(); | |||
842 | } | |||
843 | ||||
844 | SFX_IMPL_DOCKINGWINDOW_WITHID(SmCmdBoxWrapper, SID_CMDBOXWINDOW)std::unique_ptr<SfxChildWindow> SmCmdBoxWrapper::CreateImpl ( vcl::Window *pParent, sal_uInt16 nId, SfxBindings *pBindings , SfxChildWinInfo* pInfo ) { return std::make_unique<SmCmdBoxWrapper >(pParent, nId, pBindings, pInfo); } void SmCmdBoxWrapper:: RegisterChildWindow (bool bVis, SfxModule *pMod, SfxChildWindowFlags nFlags) { auto pFact = std::make_unique<SfxChildWinFactory >( SmCmdBoxWrapper::CreateImpl, ((30000 + 256) + 122), (32767 *2 +1) ); pFact->aInfo.nFlags |= nFlags; pFact->aInfo. bVisible = bVis; SfxChildWindow::RegisterChildWindow(pMod, std ::move(pFact)); } sal_uInt16 SmCmdBoxWrapper::GetChildWindowId () { return ((30000 + 256) + 122); } SfxChildWinInfo SmCmdBoxWrapper ::GetInfo() const { SfxChildWinInfo aInfo = SfxChildWindow::GetInfo (); static_cast<SfxDockingWindow*>(GetWindow())->FillInfo ( aInfo ); return aInfo; }; | |||
845 | ||||
846 | SmCmdBoxWrapper::SmCmdBoxWrapper(vcl::Window *pParentWindow, sal_uInt16 nId, | |||
847 | SfxBindings *pBindings, | |||
848 | SfxChildWinInfo *pInfo) : | |||
849 | SfxChildWindow(pParentWindow, nId) | |||
850 | { | |||
851 | SetWindow(VclPtr<SmCmdBoxWindow>::Create(pBindings, this, pParentWindow)); | |||
852 | ||||
853 | // make window docked to the bottom initially (after first start) | |||
854 | SetAlignment(SfxChildAlignment::BOTTOM); | |||
855 | static_cast<SfxDockingWindow *>(GetWindow())->Initialize(pInfo); | |||
856 | } | |||
857 | ||||
858 | struct SmViewShell_Impl | |||
859 | { | |||
860 | std::unique_ptr<sfx2::DocumentInserter> pDocInserter; | |||
861 | std::unique_ptr<SfxRequest> pRequest; | |||
862 | SvtMiscOptions aOpts; | |||
863 | }; | |||
864 | ||||
865 | SFX_IMPL_SUPERCLASS_INTERFACE(SmViewShell, SfxViewShell)SfxInterface* SmViewShell::pInterface = nullptr; SfxInterface * SmViewShell::GetStaticInterface() { if ( !pInterface ) { pInterface = new SfxInterface( "SmViewShell", true, GetInterfaceId(), SfxViewShell ::GetStaticInterface(), aSmViewShellSlots_Impl[0], sal_uInt16 (sizeof(aSmViewShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl (); } return pInterface; } SfxInterface* SmViewShell::GetInterface () const { return GetStaticInterface(); } void SmViewShell::RegisterInterface (const SfxModule* pMod) { GetStaticInterface()->Register(pMod ); } | |||
866 | ||||
867 | void SmViewShell::InitInterface_Impl() | |||
868 | { | |||
869 | GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS2, | |||
870 | SfxVisibilityFlags::Standard | SfxVisibilityFlags::FullScreen | SfxVisibilityFlags::Server, | |||
871 | ToolbarId::Math_Toolbox); | |||
872 | //Dummy-Objectbar, to avoid quiver while activating | |||
873 | ||||
874 | GetStaticInterface()->RegisterChildWindow(SmCmdBoxWrapper::GetChildWindowId()); | |||
875 | GetStaticInterface()->RegisterChildWindow(SmElementsDockingWindowWrapper::GetChildWindowId()); | |||
876 | GetStaticInterface()->RegisterChildWindow(SfxInfoBarContainerChild::GetChildWindowId()); | |||
877 | } | |||
878 | ||||
879 | SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default")SfxViewFactory* SmViewShell::pFactory; SfxViewShell* SmViewShell ::CreateInstance(SfxViewFrame *pFrame, SfxViewShell *pOldView ) { return new SmViewShell(pFrame, pOldView); } void SmViewShell ::RegisterFactory( SfxInterfaceId nPrio ) { pFactory = new SfxViewFactory (&CreateInstance,nPrio,"Default"); InitFactory(); } void SmViewShell ::InitFactory() | |||
880 | { | |||
881 | SFX_VIEW_REGISTRATION(SmDocShell)SmDocShell::Factory().RegisterViewFactory( *Factory() ); | |||
882 | } | |||
883 | ||||
884 | void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize, bool) | |||
885 | { | |||
886 | Size aObjSize = GetObjectShell()->GetVisArea().GetSize(); | |||
887 | if ( !aObjSize.IsEmpty() ) | |||
888 | { | |||
889 | Size aProvidedSize = GetWindow()->PixelToLogic(rSize, MapMode(MapUnit::Map100thMM)); | |||
890 | SfxViewShell::SetZoomFactor( Fraction( aProvidedSize.Width(), aObjSize.Width() ), | |||
891 | Fraction( aProvidedSize.Height(), aObjSize.Height() ) ); | |||
892 | } | |||
893 | ||||
894 | SetBorderPixel( SvBorder() ); | |||
895 | GetGraphicWindow().SetPosSizePixel(rOfs, rSize); | |||
896 | GetGraphicWindow().SetTotalSize(); | |||
897 | } | |||
898 | ||||
899 | void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize) | |||
900 | { | |||
901 | SmGraphicWindow &rWin = GetGraphicWindow(); | |||
902 | rWin.SetPosSizePixel(rOfs, rSize); | |||
903 | if (GetDoc()->IsPreview()) | |||
904 | rWin.ZoomToFitInWindow(); | |||
905 | rWin.PaintImmediately(); | |||
906 | } | |||
907 | ||||
908 | void SmViewShell::QueryObjAreaPixel( tools::Rectangle& rRect ) const | |||
909 | { | |||
910 | rRect.SetSize( GetGraphicWindow().GetSizePixel() ); | |||
911 | } | |||
912 | ||||
913 | void SmViewShell::SetZoomFactor( const Fraction &rX, const Fraction &rY ) | |||
914 | { | |||
915 | const Fraction &rFrac = std::min(rX, rY); | |||
916 | GetGraphicWindow().SetZoom(sal::static_int_cast<sal_uInt16>(long(rFrac * Fraction( 100, 1 )))); | |||
917 | ||||
918 | //To avoid rounding errors base class regulates crooked values too | |||
919 | //if necessary | |||
920 | SfxViewShell::SetZoomFactor( rX, rY ); | |||
921 | } | |||
922 | ||||
923 | Size SmViewShell::GetTextLineSize(OutputDevice const & rDevice, const OUString& rLine) | |||
924 | { | |||
925 | Size aSize(rDevice.GetTextWidth(rLine), rDevice.GetTextHeight()); | |||
926 | const long nTabPos = rLine.isEmpty() ? 0 : rDevice.approximate_digit_width() * 8; | |||
927 | ||||
928 | if (nTabPos) | |||
929 | { | |||
930 | aSize.setWidth( 0 ); | |||
931 | sal_Int32 nPos = 0; | |||
932 | do | |||
933 | { | |||
934 | if (nPos > 0) | |||
935 | aSize.setWidth( ((aSize.Width() / nTabPos) + 1) * nTabPos ); | |||
936 | ||||
937 | const OUString aText = rLine.getToken(0, '\t', nPos); | |||
938 | aSize.AdjustWidth(rDevice.GetTextWidth(aText) ); | |||
939 | } | |||
940 | while (nPos >= 0); | |||
941 | } | |||
942 | ||||
943 | return aSize; | |||
944 | } | |||
945 | ||||
946 | Size SmViewShell::GetTextSize(OutputDevice const & rDevice, const OUString& rText, long MaxWidth) | |||
947 | { | |||
948 | Size aSize; | |||
949 | Size aTextSize; | |||
950 | if (rText.isEmpty()) | |||
951 | return aTextSize; | |||
952 | ||||
953 | sal_Int32 nPos = 0; | |||
954 | do | |||
955 | { | |||
956 | OUString aLine = rText.getToken(0, '\n', nPos); | |||
957 | aLine = aLine.replaceAll("\r", ""); | |||
958 | ||||
959 | aSize = GetTextLineSize(rDevice, aLine); | |||
960 | ||||
961 | if (aSize.Width() > MaxWidth) | |||
962 | { | |||
963 | do | |||
964 | { | |||
965 | OUString aText; | |||
966 | sal_Int32 m = aLine.getLength(); | |||
967 | sal_Int32 nLen = m; | |||
968 | ||||
969 | for (sal_Int32 n = 0; n < nLen; n++) | |||
970 | { | |||
971 | sal_Unicode cLineChar = aLine[n]; | |||
972 | if ((cLineChar == ' ') || (cLineChar == '\t')) | |||
973 | { | |||
974 | aText = aLine.copy(0, n); | |||
975 | if (GetTextLineSize(rDevice, aText).Width() < MaxWidth) | |||
976 | m = n; | |||
977 | else | |||
978 | break; | |||
979 | } | |||
980 | } | |||
981 | ||||
982 | aText = aLine.copy(0, m); | |||
983 | aLine = aLine.replaceAt(0, m, ""); | |||
984 | aSize = GetTextLineSize(rDevice, aText); | |||
985 | aTextSize.AdjustHeight(aSize.Height() ); | |||
986 | aTextSize.setWidth( std::max(aTextSize.Width(), std::min(aSize.Width(), MaxWidth)) ); | |||
987 | ||||
988 | aLine = comphelper::string::stripStart(aLine, ' '); | |||
989 | aLine = comphelper::string::stripStart(aLine, '\t'); | |||
990 | aLine = comphelper::string::stripStart(aLine, ' '); | |||
991 | } | |||
992 | while (!aLine.isEmpty()); | |||
993 | } | |||
994 | else | |||
995 | { | |||
996 | aTextSize.AdjustHeight(aSize.Height() ); | |||
997 | aTextSize.setWidth( std::max(aTextSize.Width(), aSize.Width()) ); | |||
998 | } | |||
999 | } | |||
1000 | while (nPos >= 0); | |||
1001 | ||||
1002 | return aTextSize; | |||
1003 | } | |||
1004 | ||||
1005 | void SmViewShell::DrawTextLine(OutputDevice& rDevice, const Point& rPosition, const OUString& rLine) | |||
1006 | { | |||
1007 | Point aPoint(rPosition); | |||
1008 | const long nTabPos = rLine.isEmpty() ? 0 : rDevice.approximate_digit_width() * 8; | |||
1009 | ||||
1010 | if (nTabPos) | |||
1011 | { | |||
1012 | sal_Int32 nPos = 0; | |||
1013 | do | |||
1014 | { | |||
1015 | if (nPos > 0) | |||
1016 | aPoint.setX( ((aPoint.X() / nTabPos) + 1) * nTabPos ); | |||
1017 | ||||
1018 | OUString aText = rLine.getToken(0, '\t', nPos); | |||
1019 | rDevice.DrawText(aPoint, aText); | |||
1020 | aPoint.AdjustX(rDevice.GetTextWidth(aText) ); | |||
1021 | } | |||
1022 | while ( nPos >= 0 ); | |||
1023 | } | |||
1024 | else | |||
1025 | rDevice.DrawText(aPoint, rLine); | |||
1026 | } | |||
1027 | ||||
1028 | ||||
1029 | void SmViewShell::DrawText(OutputDevice& rDevice, const Point& rPosition, const OUString& rText, sal_uInt16 MaxWidth) | |||
1030 | { | |||
1031 | if (rText.isEmpty()) | |||
1032 | return; | |||
1033 | ||||
1034 | Point aPoint(rPosition); | |||
1035 | Size aSize; | |||
1036 | ||||
1037 | sal_Int32 nPos = 0; | |||
1038 | do | |||
1039 | { | |||
1040 | OUString aLine = rText.getToken(0, '\n', nPos); | |||
1041 | aLine = aLine.replaceAll("\r", ""); | |||
1042 | aSize = GetTextLineSize(rDevice, aLine); | |||
1043 | if (aSize.Width() > MaxWidth) | |||
1044 | { | |||
1045 | do | |||
1046 | { | |||
1047 | OUString aText; | |||
1048 | sal_Int32 m = aLine.getLength(); | |||
1049 | sal_Int32 nLen = m; | |||
1050 | ||||
1051 | for (sal_Int32 n = 0; n < nLen; n++) | |||
1052 | { | |||
1053 | sal_Unicode cLineChar = aLine[n]; | |||
1054 | if ((cLineChar == ' ') || (cLineChar == '\t')) | |||
1055 | { | |||
1056 | aText = aLine.copy(0, n); | |||
1057 | if (GetTextLineSize(rDevice, aText).Width() < MaxWidth) | |||
1058 | m = n; | |||
1059 | else | |||
1060 | break; | |||
1061 | } | |||
1062 | } | |||
1063 | aText = aLine.copy(0, m); | |||
1064 | aLine = aLine.replaceAt(0, m, ""); | |||
1065 | ||||
1066 | DrawTextLine(rDevice, aPoint, aText); | |||
1067 | aPoint.AdjustY(aSize.Height() ); | |||
1068 | ||||
1069 | aLine = comphelper::string::stripStart(aLine, ' '); | |||
1070 | aLine = comphelper::string::stripStart(aLine, '\t'); | |||
1071 | aLine = comphelper::string::stripStart(aLine, ' '); | |||
1072 | } | |||
1073 | while (GetTextLineSize(rDevice, aLine).Width() > MaxWidth); | |||
1074 | ||||
1075 | // print the remaining text | |||
1076 | if (!aLine.isEmpty()) | |||
1077 | { | |||
1078 | DrawTextLine(rDevice, aPoint, aLine); | |||
1079 | aPoint.AdjustY(aSize.Height() ); | |||
1080 | } | |||
1081 | } | |||
1082 | else | |||
1083 | { | |||
1084 | DrawTextLine(rDevice, aPoint, aLine); | |||
1085 | aPoint.AdjustY(aSize.Height() ); | |||
1086 | } | |||
1087 | } | |||
1088 | while ( nPos >= 0 ); | |||
1089 | } | |||
1090 | ||||
1091 | void SmViewShell::Impl_Print(OutputDevice &rOutDev, const SmPrintUIOptions &rPrintUIOptions, tools::Rectangle aOutRect ) | |||
1092 | { | |||
1093 | const bool bIsPrintTitle = rPrintUIOptions.getBoolValue( PRTUIOPT_TITLE_ROW"TitleRow", true ); | |||
1094 | const bool bIsPrintFrame = rPrintUIOptions.getBoolValue( PRTUIOPT_BORDER"Border", true ); | |||
1095 | const bool bIsPrintFormulaText = rPrintUIOptions.getBoolValue( PRTUIOPT_FORMULA_TEXT"FormulaText", true ); | |||
1096 | SmPrintSize ePrintSize( static_cast< SmPrintSize >( rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_FORMAT"PrintFormat", PRINT_SIZE_NORMAL ) )); | |||
1097 | const sal_uInt16 nZoomFactor = static_cast< sal_uInt16 >(rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_SCALE"PrintScale", 100 )); | |||
1098 | ||||
1099 | rOutDev.Push(); | |||
1100 | rOutDev.SetLineColor( COL_BLACK ); | |||
1101 | ||||
1102 | // output text on top | |||
1103 | if (bIsPrintTitle) | |||
1104 | { | |||
1105 | Size aSize600 (0, 600); | |||
1106 | Size aSize650 (0, 650); | |||
1107 | vcl::Font aFont(FAMILY_DONTKNOW, aSize600); | |||
1108 | ||||
1109 | aFont.SetAlignment(ALIGN_TOP); | |||
1110 | aFont.SetWeight(WEIGHT_BOLD); | |||
1111 | aFont.SetFontSize(aSize650); | |||
1112 | aFont.SetColor( COL_BLACK ); | |||
1113 | rOutDev.SetFont(aFont); | |||
1114 | ||||
1115 | Size aTitleSize (GetTextSize(rOutDev, GetDoc()->GetTitle(), aOutRect.GetWidth() - 200)); | |||
1116 | ||||
1117 | aFont.SetWeight(WEIGHT_NORMAL); | |||
1118 | aFont.SetFontSize(aSize600); | |||
1119 | rOutDev.SetFont(aFont); | |||
1120 | ||||
1121 | Size aDescSize (GetTextSize(rOutDev, GetDoc()->GetComment(), aOutRect.GetWidth() - 200)); | |||
1122 | ||||
1123 | if (bIsPrintFrame) | |||
1124 | rOutDev.DrawRect(tools::Rectangle(aOutRect.TopLeft(), | |||
1125 | Size(aOutRect.GetWidth(), 100 + aTitleSize.Height() + 200 + aDescSize.Height() + 100))); | |||
1126 | aOutRect.AdjustTop(200 ); | |||
1127 | ||||
1128 | // output title | |||
1129 | aFont.SetWeight(WEIGHT_BOLD); | |||
1130 | aFont.SetFontSize(aSize650); | |||
1131 | rOutDev.SetFont(aFont); | |||
1132 | Point aPoint(aOutRect.Left() + (aOutRect.GetWidth() - aTitleSize.Width()) / 2, | |||
1133 | aOutRect.Top()); | |||
1134 | DrawText(rOutDev, aPoint, GetDoc()->GetTitle(), | |||
1135 | sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); | |||
1136 | aOutRect.AdjustTop(aTitleSize.Height() + 200 ); | |||
1137 | ||||
1138 | // output description | |||
1139 | aFont.SetWeight(WEIGHT_NORMAL); | |||
1140 | aFont.SetFontSize(aSize600); | |||
1141 | rOutDev.SetFont(aFont); | |||
1142 | aPoint.setX( aOutRect.Left() + (aOutRect.GetWidth() - aDescSize.Width()) / 2 ); | |||
1143 | aPoint.setY( aOutRect.Top() ); | |||
1144 | DrawText(rOutDev, aPoint, GetDoc()->GetComment(), | |||
1145 | sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); | |||
1146 | aOutRect.AdjustTop(aDescSize.Height() + 300 ); | |||
1147 | } | |||
1148 | ||||
1149 | // output text on bottom | |||
1150 | if (bIsPrintFormulaText) | |||
1151 | { | |||
1152 | vcl::Font aFont(FAMILY_DONTKNOW, Size(0, 600)); | |||
1153 | aFont.SetAlignment(ALIGN_TOP); | |||
1154 | aFont.SetColor( COL_BLACK ); | |||
1155 | ||||
1156 | // get size | |||
1157 | rOutDev.SetFont(aFont); | |||
1158 | ||||
1159 | Size aSize (GetTextSize(rOutDev, GetDoc()->GetText(), aOutRect.GetWidth() - 200)); | |||
1160 | ||||
1161 | aOutRect.AdjustBottom( -(aSize.Height() + 600) ); | |||
1162 | ||||
1163 | if (bIsPrintFrame) | |||
1164 | rOutDev.DrawRect(tools::Rectangle(aOutRect.BottomLeft(), | |||
1165 | Size(aOutRect.GetWidth(), 200 + aSize.Height() + 200))); | |||
1166 | ||||
1167 | Point aPoint (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2, | |||
1168 | aOutRect.Bottom() + 300); | |||
1169 | DrawText(rOutDev, aPoint, GetDoc()->GetText(), | |||
1170 | sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); | |||
1171 | aOutRect.AdjustBottom( -200 ); | |||
1172 | } | |||
1173 | ||||
1174 | if (bIsPrintFrame) | |||
1175 | rOutDev.DrawRect(aOutRect); | |||
1176 | ||||
1177 | aOutRect.AdjustTop(100 ); | |||
1178 | aOutRect.AdjustLeft(100 ); | |||
1179 | aOutRect.AdjustBottom( -100 ); | |||
1180 | aOutRect.AdjustRight( -100 ); | |||
1181 | ||||
1182 | Size aSize (GetDoc()->GetSize()); | |||
1183 | ||||
1184 | MapMode OutputMapMode; | |||
1185 | // PDF export should always use PRINT_SIZE_NORMAL ... | |||
1186 | if (!rPrintUIOptions.getBoolValue( "IsPrinter" ) ) | |||
1187 | ePrintSize = PRINT_SIZE_NORMAL; | |||
1188 | switch (ePrintSize) | |||
1189 | { | |||
1190 | case PRINT_SIZE_NORMAL: | |||
1191 | OutputMapMode = MapMode(MapUnit::Map100thMM); | |||
1192 | break; | |||
1193 | ||||
1194 | case PRINT_SIZE_SCALED: | |||
1195 | if (!aSize.IsEmpty()) | |||
1196 | { | |||
1197 | Size OutputSize (rOutDev.LogicToPixel(Size(aOutRect.GetWidth(), | |||
1198 | aOutRect.GetHeight()), MapMode(MapUnit::Map100thMM))); | |||
1199 | Size GraphicSize (rOutDev.LogicToPixel(aSize, MapMode(MapUnit::Map100thMM))); | |||
1200 | sal_uInt16 nZ = sal::static_int_cast<sal_uInt16>(std::min(long(Fraction(OutputSize.Width() * 100, GraphicSize.Width())), | |||
1201 | long(Fraction(OutputSize.Height() * 100, GraphicSize.Height())))); | |||
1202 | nZ -= 10; | |||
1203 | Fraction aFraction (std::max(MINZOOMsal_uInt16(25), std::min(MAXZOOMsal_uInt16(800), nZ)), 100); | |||
1204 | ||||
1205 | OutputMapMode = MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction); | |||
1206 | } | |||
1207 | else | |||
1208 | OutputMapMode = MapMode(MapUnit::Map100thMM); | |||
1209 | break; | |||
1210 | ||||
1211 | case PRINT_SIZE_ZOOMED: | |||
1212 | { | |||
1213 | Fraction aFraction( nZoomFactor, 100 ); | |||
1214 | ||||
1215 | OutputMapMode = MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction); | |||
1216 | break; | |||
1217 | } | |||
1218 | } | |||
1219 | ||||
1220 | aSize = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aSize, OutputMapMode), | |||
1221 | MapMode(MapUnit::Map100thMM)); | |||
1222 | ||||
1223 | Point aPos (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2, | |||
1224 | aOutRect.Top() + (aOutRect.GetHeight() - aSize.Height()) / 2); | |||
1225 | ||||
1226 | aPos = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aPos, MapMode(MapUnit::Map100thMM)), | |||
1227 | OutputMapMode); | |||
1228 | aOutRect = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aOutRect, MapMode(MapUnit::Map100thMM)), | |||
1229 | OutputMapMode); | |||
1230 | ||||
1231 | rOutDev.SetMapMode(OutputMapMode); | |||
1232 | rOutDev.SetClipRegion(vcl::Region(aOutRect)); | |||
1233 | GetDoc()->DrawFormula(rOutDev, aPos); | |||
1234 | rOutDev.SetClipRegion(); | |||
1235 | ||||
1236 | rOutDev.Pop(); | |||
1237 | } | |||
1238 | ||||
1239 | SfxPrinter* SmViewShell::GetPrinter(bool bCreate) | |||
1240 | { | |||
1241 | SmDocShell* pDoc = GetDoc(); | |||
1242 | if (pDoc->HasPrinter() || bCreate) | |||
1243 | return pDoc->GetPrinter(); | |||
1244 | return nullptr; | |||
1245 | } | |||
1246 | ||||
1247 | sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags ) | |||
1248 | { | |||
1249 | SfxPrinter *pOld = GetDoc()->GetPrinter(); | |||
1250 | if ( pOld && pOld->IsPrinting() ) | |||
1251 | return SFX_PRINTERROR_BUSY1; | |||
1252 | ||||
1253 | if ((nDiffFlags & SfxPrinterChangeFlags::PRINTER) == SfxPrinterChangeFlags::PRINTER) | |||
1254 | GetDoc()->SetPrinter( pNewPrinter ); | |||
1255 | ||||
1256 | if ((nDiffFlags & SfxPrinterChangeFlags::OPTIONS) == SfxPrinterChangeFlags::OPTIONS) | |||
1257 | { | |||
1258 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
1259 | pp->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions()); | |||
1260 | } | |||
1261 | return 0; | |||
1262 | } | |||
1263 | ||||
1264 | bool SmViewShell::HasPrintOptionsPage() const | |||
1265 | { | |||
1266 | return true; | |||
1267 | } | |||
1268 | ||||
1269 | std::unique_ptr<SfxTabPage> SmViewShell::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController, | |||
1270 | const SfxItemSet &rOptions) | |||
1271 | { | |||
1272 | return SmPrintOptionsTabPage::Create(pPage, pController, rOptions); | |||
1273 | } | |||
1274 | ||||
1275 | SmEditWindow *SmViewShell::GetEditWindow() | |||
1276 | { | |||
1277 | SmCmdBoxWrapper* pWrapper = static_cast<SmCmdBoxWrapper*>( | |||
1278 | GetViewFrame()->GetChildWindow(SmCmdBoxWrapper::GetChildWindowId())); | |||
1279 | ||||
1280 | if (pWrapper != nullptr) | |||
1281 | { | |||
1282 | SmEditWindow& rEditWin = pWrapper->GetEditWindow(); | |||
1283 | return &rEditWin; | |||
1284 | } | |||
1285 | ||||
1286 | return nullptr; | |||
1287 | } | |||
1288 | ||||
1289 | void SmViewShell::SetStatusText(const OUString& rText) | |||
1290 | { | |||
1291 | maStatusText = rText; | |||
1292 | GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS((30000 + 256) + 111)); | |||
1293 | } | |||
1294 | ||||
1295 | void SmViewShell::ShowError(const SmErrorDesc* pErrorDesc) | |||
1296 | { | |||
1297 | assert(GetDoc())(static_cast <bool> (GetDoc()) ? void (0) : __assert_fail ("GetDoc()", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 1297, __extension__ __PRETTY_FUNCTION__)); | |||
1298 | if (pErrorDesc || nullptr != (pErrorDesc = GetDoc()->GetParser().GetError()) ) | |||
1299 | { | |||
1300 | SetStatusText( pErrorDesc->m_aText ); | |||
1301 | GetEditWindow()->MarkError( Point( pErrorDesc->m_pNode->GetColumn(), | |||
1302 | pErrorDesc->m_pNode->GetRow())); | |||
1303 | } | |||
1304 | } | |||
1305 | ||||
1306 | void SmViewShell::NextError() | |||
1307 | { | |||
1308 | assert(GetDoc())(static_cast <bool> (GetDoc()) ? void (0) : __assert_fail ("GetDoc()", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 1308, __extension__ __PRETTY_FUNCTION__)); | |||
1309 | const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().NextError(); | |||
1310 | ||||
1311 | if (pErrorDesc) | |||
1312 | ShowError( pErrorDesc ); | |||
1313 | } | |||
1314 | ||||
1315 | void SmViewShell::PrevError() | |||
1316 | { | |||
1317 | assert(GetDoc())(static_cast <bool> (GetDoc()) ? void (0) : __assert_fail ("GetDoc()", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 1317, __extension__ __PRETTY_FUNCTION__)); | |||
1318 | const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().PrevError(); | |||
1319 | ||||
1320 | if (pErrorDesc) | |||
1321 | ShowError( pErrorDesc ); | |||
1322 | } | |||
1323 | ||||
1324 | void SmViewShell::Insert( SfxMedium& rMedium ) | |||
1325 | { | |||
1326 | SmDocShell *pDoc = GetDoc(); | |||
1327 | bool bRet = false; | |||
1328 | ||||
1329 | uno::Reference <embed::XStorage> xStorage = rMedium.GetStorage(); | |||
1330 | if (xStorage.is() && xStorage->getElementNames().hasElements()) | |||
1331 | { | |||
1332 | if (xStorage->hasByName("content.xml")) | |||
1333 | { | |||
1334 | // is this a fabulous math package ? | |||
1335 | Reference<css::frame::XModel> xModel(pDoc->GetModel()); | |||
1336 | SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! | |||
1337 | bRet = ERRCODE_NONEErrCode(0) == aEquation.Import(rMedium); | |||
1338 | } | |||
1339 | } | |||
1340 | ||||
1341 | if (!bRet) | |||
1342 | return; | |||
1343 | ||||
1344 | OUString aText = pDoc->GetText(); | |||
1345 | SmEditWindow *pEditWin = GetEditWindow(); | |||
1346 | if (pEditWin) | |||
1347 | pEditWin->InsertText( aText ); | |||
1348 | else | |||
1349 | { | |||
1350 | SAL_WARN( "starmath", "EditWindow missing" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "EditWindow missing") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1350" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "EditWindow missing"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "EditWindow missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1350" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "EditWindow missing") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1350" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "EditWindow missing"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "EditWindow missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1350" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1351 | } | |||
1352 | ||||
1353 | pDoc->Parse(); | |||
1354 | pDoc->SetModified(); | |||
1355 | ||||
1356 | SfxBindings &rBnd = GetViewFrame()->GetBindings(); | |||
1357 | rBnd.Invalidate(SID_GAPHIC_SM((30000 + 256) + 101)); | |||
1358 | rBnd.Invalidate(SID_TEXT((30000 + 256) + 100)); | |||
1359 | } | |||
1360 | ||||
1361 | void SmViewShell::InsertFrom(SfxMedium &rMedium) | |||
1362 | { | |||
1363 | bool bSuccess = false; | |||
1364 | SmDocShell* pDoc = GetDoc(); | |||
1365 | SvStream* pStream = rMedium.GetInStream(); | |||
1366 | ||||
1367 | if (pStream) | |||
1368 | { | |||
1369 | const OUString& rFltName = rMedium.GetFilter()->GetFilterName(); | |||
1370 | if ( rFltName == MATHML_XML"MathML XML (Math)" ) | |||
1371 | { | |||
1372 | Reference<css::frame::XModel> xModel(pDoc->GetModel()); | |||
1373 | SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! | |||
1374 | bSuccess = ERRCODE_NONEErrCode(0) == aEquation.Import(rMedium); | |||
1375 | } | |||
1376 | } | |||
1377 | ||||
1378 | if (!bSuccess) | |||
1379 | return; | |||
1380 | ||||
1381 | OUString aText = pDoc->GetText(); | |||
1382 | SmEditWindow *pEditWin = GetEditWindow(); | |||
1383 | if (pEditWin) | |||
1384 | pEditWin->InsertText(aText); | |||
1385 | else | |||
1386 | SAL_WARN( "starmath", "EditWindow missing" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "EditWindow missing") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1386" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "EditWindow missing"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "EditWindow missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1386" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "EditWindow missing") == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1386" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "EditWindow missing"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "EditWindow missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1386" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1387 | ||||
1388 | pDoc->Parse(); | |||
1389 | pDoc->SetModified(); | |||
1390 | ||||
1391 | SfxBindings& rBnd = GetViewFrame()->GetBindings(); | |||
1392 | rBnd.Invalidate(SID_GAPHIC_SM((30000 + 256) + 101)); | |||
1393 | rBnd.Invalidate(SID_TEXT((30000 + 256) + 100)); | |||
1394 | } | |||
1395 | ||||
1396 | void SmViewShell::Execute(SfxRequest& rReq) | |||
1397 | { | |||
1398 | SmEditWindow *pWin = GetEditWindow(); | |||
1399 | ||||
1400 | switch (rReq.GetSlot()) | |||
1401 | { | |||
1402 | case SID_FORMULACURSOR((30000 + 256) + 15): | |||
1403 | { | |||
1404 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
1405 | ||||
1406 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
1407 | const SfxPoolItem *pItem; | |||
1408 | ||||
1409 | bool bVal; | |||
1410 | if ( pArgs && | |||
1411 | SfxItemState::SET == pArgs->GetItemState( SID_FORMULACURSOR((30000 + 256) + 15), false, &pItem)) | |||
1412 | bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue(); | |||
1413 | else | |||
1414 | bVal = !pp->GetConfig()->IsShowFormulaCursor(); | |||
1415 | ||||
1416 | pp->GetConfig()->SetShowFormulaCursor(bVal); | |||
1417 | if (!IsInlineEditEnabled()) | |||
1418 | GetGraphicWindow().ShowCursor(bVal); | |||
1419 | break; | |||
1420 | } | |||
1421 | case SID_DRAW((30000 + 256) + 12): | |||
1422 | if (pWin) | |||
1423 | { | |||
1424 | GetDoc()->SetText( pWin->GetText() ); | |||
1425 | SetStatusText(OUString()); | |||
1426 | ShowError( nullptr ); | |||
1427 | GetDoc()->Repaint(); | |||
1428 | } | |||
1429 | break; | |||
1430 | ||||
1431 | case SID_ZOOM_OPTIMAL((27000 +99)): | |||
1432 | mpGraphic->ZoomToFitInWindow(); | |||
1433 | break; | |||
1434 | ||||
1435 | case SID_ZOOMIN((30000 + 256) + 10): | |||
1436 | mpGraphic->SetZoom(mpGraphic->GetZoom() + 25); | |||
1437 | break; | |||
1438 | ||||
1439 | case SID_ZOOMOUT((30000 + 256) + 11): | |||
1440 | SAL_WARN_IF( mpGraphic->GetZoom() < 25, "starmath", "incorrect sal_uInt16 argument" )do { if (true && (mpGraphic->GetZoom() < 25)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "starmath" )) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "incorrect sal_uInt16 argument") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1440" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "incorrect sal_uInt16 argument"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "incorrect sal_uInt16 argument"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1440" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "incorrect sal_uInt16 argument") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1440" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "incorrect sal_uInt16 argument"), 0) ; } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "incorrect sal_uInt16 argument"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1440" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1441 | mpGraphic->SetZoom(mpGraphic->GetZoom() - 25); | |||
1442 | break; | |||
1443 | ||||
1444 | case SID_COPYOBJECT((30000 + 256) + 117): | |||
1445 | { | |||
1446 | //TODO/LATER: does not work because of UNO Tunneling - will be fixed later | |||
1447 | Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY ); | |||
1448 | if( xTrans.is() ) | |||
1449 | { | |||
1450 | auto pTrans = comphelper::getUnoTunnelImplementation<TransferableHelper>(xTrans); | |||
1451 | if( pTrans ) | |||
1452 | pTrans->CopyToClipboard(GetEditWindow()); | |||
1453 | } | |||
1454 | } | |||
1455 | break; | |||
1456 | ||||
1457 | case SID_PASTEOBJECT((30000 + 256) + 118): | |||
1458 | { | |||
1459 | TransferableDataHelper aData( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) ); | |||
1460 | uno::Reference < io::XInputStream > xStrm; | |||
1461 | SotClipboardFormatId nId; | |||
1462 | if( aData.GetTransferable().is() && | |||
1463 | ( aData.HasFormat( nId = SotClipboardFormatId::EMBEDDED_OBJ ) || | |||
1464 | (aData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) && | |||
1465 | aData.HasFormat( nId = SotClipboardFormatId::EMBED_SOURCE )))) | |||
1466 | xStrm = aData.GetInputStream(nId, OUString()); | |||
1467 | ||||
1468 | if (xStrm.is()) | |||
1469 | { | |||
1470 | try | |||
1471 | { | |||
1472 | uno::Reference < embed::XStorage > xStorage = | |||
1473 | ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessComponentContext() ); | |||
1474 | SfxMedium aMedium( xStorage, OUString() ); | |||
1475 | Insert( aMedium ); | |||
1476 | GetDoc()->UpdateText(); | |||
1477 | } | |||
1478 | catch (uno::Exception &) | |||
1479 | { | |||
1480 | SAL_WARN( "starmath", "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1480" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1480" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1480" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1480" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1481 | } | |||
1482 | } | |||
1483 | } | |||
1484 | break; | |||
1485 | ||||
1486 | ||||
1487 | case SID_CUT(5000 + 710): | |||
1488 | if (pWin) | |||
1489 | pWin->Cut(); | |||
1490 | break; | |||
1491 | ||||
1492 | case SID_COPY(5000 + 711): | |||
1493 | if (pWin) | |||
1494 | { | |||
1495 | if (pWin->IsAllSelected()) | |||
1496 | { | |||
1497 | GetViewFrame()->GetDispatcher()->ExecuteList( | |||
1498 | SID_COPYOBJECT((30000 + 256) + 117), SfxCallMode::RECORD, | |||
1499 | { new SfxVoidItem(SID_COPYOBJECT((30000 + 256) + 117)) }); | |||
1500 | } | |||
1501 | else | |||
1502 | pWin->Copy(); | |||
1503 | } | |||
1504 | break; | |||
1505 | ||||
1506 | case SID_PASTE(5000 + 712): | |||
1507 | { | |||
1508 | bool bCallExec = nullptr == pWin; | |||
1509 | if( !bCallExec ) | |||
1510 | { | |||
1511 | TransferableDataHelper aDataHelper( | |||
1512 | TransferableDataHelper::CreateFromSystemClipboard( | |||
1513 | GetEditWindow()) ); | |||
1514 | ||||
1515 | if( aDataHelper.GetTransferable().is() && | |||
1516 | aDataHelper.HasFormat( SotClipboardFormatId::STRING )) | |||
1517 | pWin->Paste(); | |||
1518 | else | |||
1519 | bCallExec = true; | |||
1520 | } | |||
1521 | if( bCallExec ) | |||
1522 | { | |||
1523 | GetViewFrame()->GetDispatcher()->ExecuteList( | |||
1524 | SID_PASTEOBJECT((30000 + 256) + 118), SfxCallMode::RECORD, | |||
1525 | { new SfxVoidItem(SID_PASTEOBJECT((30000 + 256) + 118)) }); | |||
1526 | } | |||
1527 | } | |||
1528 | break; | |||
1529 | ||||
1530 | case SID_DELETE(5000 + 713): | |||
1531 | if (pWin) | |||
1532 | pWin->Delete(); | |||
1533 | break; | |||
1534 | ||||
1535 | case SID_SELECT(5000 + 720): | |||
1536 | if (pWin) | |||
1537 | pWin->SelectAll(); | |||
1538 | break; | |||
1539 | ||||
1540 | case SID_INSERTCOMMANDTEXT((30000 + 256) + 106): | |||
1541 | { | |||
1542 | const SfxStringItem& rItem = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_INSERTCOMMANDTEXT((30000 + 256) + 106))); | |||
1543 | ||||
1544 | if (pWin && (mbInsertIntoEditWindow || !IsInlineEditEnabled())) | |||
1545 | { | |||
1546 | pWin->InsertText(rItem.GetValue()); | |||
1547 | } | |||
1548 | if (IsInlineEditEnabled() && (GetDoc() && !mbInsertIntoEditWindow)) | |||
1549 | { | |||
1550 | GetDoc()->GetCursor().InsertCommandText(rItem.GetValue()); | |||
1551 | GetGraphicWindow().GrabFocus(); | |||
1552 | } | |||
1553 | break; | |||
1554 | ||||
1555 | } | |||
1556 | ||||
1557 | case SID_INSERTSPECIAL((30000 + 256) + 104): | |||
1558 | { | |||
1559 | const SfxStringItem& rItem = | |||
1560 | static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_INSERTSPECIAL((30000 + 256) + 104))); | |||
1561 | ||||
1562 | if (pWin && (mbInsertIntoEditWindow || !IsInlineEditEnabled())) | |||
1563 | pWin->InsertText(rItem.GetValue()); | |||
1564 | if (IsInlineEditEnabled() && (GetDoc() && !mbInsertIntoEditWindow)) | |||
1565 | GetDoc()->GetCursor().InsertSpecial(rItem.GetValue()); | |||
1566 | break; | |||
1567 | } | |||
1568 | ||||
1569 | case SID_IMPORT_FORMULA((30000 + 256) + 58): | |||
1570 | { | |||
1571 | mpImpl->pRequest.reset(new SfxRequest( rReq )); | |||
1572 | mpImpl->pDocInserter.reset(new ::sfx2::DocumentInserter(pWin ? pWin->GetFrameWeld() : nullptr, | |||
1573 | GetDoc()->GetFactory().GetFactoryName())); | |||
1574 | mpImpl->pDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl )::tools::detail::makeLink( ::tools::detail::castTo<SmViewShell *>(this), &SmViewShell::LinkStubDialogClosedHdl) ); | |||
1575 | break; | |||
1576 | } | |||
1577 | ||||
1578 | case SID_IMPORT_MATHML_CLIPBOARD((30000 + 256) + 59): | |||
1579 | { | |||
1580 | TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) ); | |||
1581 | uno::Reference < io::XInputStream > xStrm; | |||
1582 | if ( aDataHelper.GetTransferable().is() ) | |||
1583 | { | |||
1584 | SotClipboardFormatId nId = SotClipboardFormatId::MATHML; | |||
1585 | if (aDataHelper.HasFormat(nId)) | |||
1586 | { | |||
1587 | xStrm = aDataHelper.GetInputStream(nId, ""); | |||
1588 | if (xStrm.is()) | |||
1589 | { | |||
1590 | std::unique_ptr<SfxMedium> pClipboardMedium(new SfxMedium()); | |||
1591 | pClipboardMedium->GetItemSet(); //generate initial itemset, not sure if necessary | |||
1592 | std::shared_ptr<const SfxFilter> pMathFilter = | |||
1593 | SfxFilter::GetFilterByName(MATHML_XML"MathML XML (Math)"); | |||
1594 | pClipboardMedium->SetFilter(pMathFilter); | |||
1595 | pClipboardMedium->setStreamToLoadFrom(xStrm, true /*bIsReadOnly*/); | |||
1596 | InsertFrom(*pClipboardMedium); | |||
1597 | GetDoc()->UpdateText(); | |||
1598 | } | |||
1599 | } | |||
1600 | else | |||
1601 | { | |||
1602 | nId = SotClipboardFormatId::STRING; | |||
1603 | if (aDataHelper.HasFormat(nId)) | |||
1604 | { | |||
1605 | // In case of FORMAT_STRING no stream exists, need to generate one | |||
1606 | OUString aString; | |||
1607 | if (aDataHelper.GetString( nId, aString)) | |||
1608 | { | |||
1609 | // tdf#117091 force xml declaration to exist | |||
1610 | if (!aString.startsWith("<?xml")) | |||
1611 | aString = "<?xml version=\"1.0\"?>\n" + aString; | |||
1612 | ||||
1613 | std::unique_ptr<SfxMedium> pClipboardMedium(new SfxMedium()); | |||
1614 | pClipboardMedium->GetItemSet(); //generates initial itemset, not sure if necessary | |||
1615 | std::shared_ptr<const SfxFilter> pMathFilter = | |||
1616 | SfxFilter::GetFilterByName(MATHML_XML"MathML XML (Math)"); | |||
1617 | pClipboardMedium->SetFilter(pMathFilter); | |||
1618 | ||||
1619 | std::unique_ptr<SvMemoryStream> pStrm; | |||
1620 | // The text to be imported might asserts encoding like 'encoding="utf-8"' but FORMAT_STRING is UTF-16. | |||
1621 | // Force encoding to UTF-16, if encoding exists. | |||
1622 | bool bForceUTF16 = false; | |||
1623 | sal_Int32 nPosL = aString.indexOf("encoding=\""); | |||
1624 | sal_Int32 nPosU = -1; | |||
1625 | if ( nPosL >= 0 && nPosL +10 < aString.getLength() ) | |||
1626 | { | |||
1627 | nPosL += 10; | |||
1628 | nPosU = aString.indexOf( '"',nPosL); | |||
1629 | if (nPosU > nPosL) | |||
1630 | { | |||
1631 | bForceUTF16 = true; | |||
1632 | } | |||
1633 | } | |||
1634 | if ( bForceUTF16 ) | |||
1635 | { | |||
1636 | OUString aNewString = aString.replaceAt( nPosL,nPosU-nPosL,"UTF-16"); | |||
1637 | pStrm.reset(new SvMemoryStream( const_cast<sal_Unicode *>(aNewString.getStr()), aNewString.getLength() * sizeof(sal_Unicode), StreamMode::READ)); | |||
1638 | } | |||
1639 | else | |||
1640 | { | |||
1641 | pStrm.reset(new SvMemoryStream( const_cast<sal_Unicode *>(aString.getStr()), aString.getLength() * sizeof(sal_Unicode), StreamMode::READ)); | |||
1642 | } | |||
1643 | uno::Reference<io::XInputStream> xStrm2( new ::utl::OInputStreamWrapper(*pStrm) ); | |||
1644 | pClipboardMedium->setStreamToLoadFrom(xStrm2, true /*bIsReadOnly*/); | |||
1645 | InsertFrom(*pClipboardMedium); | |||
1646 | GetDoc()->UpdateText(); | |||
1647 | } | |||
1648 | } | |||
1649 | } | |||
1650 | } | |||
1651 | break; | |||
1652 | } | |||
1653 | ||||
1654 | case SID_NEXTERR((30000 + 256) + 1): | |||
1655 | NextError(); | |||
1656 | if (pWin) | |||
1657 | pWin->GrabFocus(); | |||
1658 | break; | |||
1659 | ||||
1660 | case SID_PREVERR((30000 + 256) + 2): | |||
1661 | PrevError(); | |||
1662 | if (pWin) | |||
1663 | pWin->GrabFocus(); | |||
1664 | break; | |||
1665 | ||||
1666 | case SID_NEXTMARK((30000 + 256) + 3): | |||
1667 | if (pWin) | |||
1668 | { | |||
1669 | pWin->SelNextMark(); | |||
1670 | pWin->GrabFocus(); | |||
1671 | } | |||
1672 | break; | |||
1673 | ||||
1674 | case SID_PREVMARK((30000 + 256) + 4): | |||
1675 | if (pWin) | |||
1676 | { | |||
1677 | pWin->SelPrevMark(); | |||
1678 | pWin->GrabFocus(); | |||
1679 | } | |||
1680 | break; | |||
1681 | ||||
1682 | case SID_TEXTSTATUS((30000 + 256) + 111): | |||
1683 | { | |||
1684 | if (rReq.GetArgs() != nullptr) | |||
1685 | { | |||
1686 | const SfxStringItem& rItem = | |||
1687 | static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_TEXTSTATUS((30000 + 256) + 111))); | |||
1688 | ||||
1689 | SetStatusText(rItem.GetValue()); | |||
1690 | } | |||
1691 | ||||
1692 | break; | |||
1693 | } | |||
1694 | ||||
1695 | case SID_GETEDITTEXT((30000 + 256) + 121): | |||
1696 | if (pWin && !pWin->GetText().isEmpty()) | |||
1697 | GetDoc()->SetText( pWin->GetText() ); | |||
1698 | break; | |||
1699 | ||||
1700 | case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0): | |||
1701 | { | |||
1702 | if ( !GetViewFrame()->GetFrame().IsInPlace() ) | |||
1703 | { | |||
1704 | const SfxItemSet *pSet = rReq.GetArgs(); | |||
1705 | if ( pSet ) | |||
1706 | { | |||
1707 | ZoomByItemSet(pSet); | |||
1708 | } | |||
1709 | else | |||
1710 | { | |||
1711 | SfxItemSet aSet( SmDocShell::GetPool(), svl::Items<SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0)>{}); | |||
1712 | aSet.Put( SvxZoomItem( SvxZoomType::PERCENT, mpGraphic->GetZoom())); | |||
1713 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); | |||
1714 | ScopedVclPtr<AbstractSvxZoomDialog> xDlg(pFact->CreateSvxZoomDialog(GetViewFrame()->GetWindow().GetFrameWeld(), aSet)); | |||
1715 | xDlg->SetLimits( MINZOOMsal_uInt16(25), MAXZOOMsal_uInt16(800) ); | |||
1716 | if (xDlg->Execute() != RET_CANCEL) | |||
1717 | ZoomByItemSet(xDlg->GetOutputItemSet()); | |||
1718 | } | |||
1719 | } | |||
1720 | } | |||
1721 | break; | |||
1722 | ||||
1723 | case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ): | |||
1724 | { | |||
1725 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
1726 | const SfxPoolItem* pItem; | |||
1727 | ||||
1728 | if ( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMSLIDER( 10000 + 1065 ), true, &pItem ) ) | |||
1729 | { | |||
1730 | const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue(); | |||
1731 | mpGraphic->SetZoom( nCurrentZoom ); | |||
1732 | } | |||
1733 | } | |||
1734 | break; | |||
1735 | ||||
1736 | case SID_ELEMENTSDOCKINGWINDOW((30000 + 256) + 126): | |||
1737 | { | |||
1738 | GetViewFrame()->ToggleChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() ); | |||
1739 | GetViewFrame()->GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW((30000 + 256) + 126) ); | |||
1740 | ||||
1741 | rReq.Ignore (); | |||
1742 | } | |||
1743 | break; | |||
1744 | ||||
1745 | case SID_UNICODE_NOTATION_TOGGLE(5000 + 792): | |||
1746 | { | |||
1747 | EditEngine* pEditEngine = nullptr; | |||
1748 | if( pWin ) | |||
1749 | pEditEngine = pWin->GetEditEngine(); | |||
1750 | ||||
1751 | EditView* pEditView = nullptr; | |||
1752 | if( pEditEngine ) | |||
1753 | pEditView = pEditEngine->GetView(); | |||
1754 | ||||
1755 | if( pEditView ) | |||
1756 | { | |||
1757 | const OUString sInput = pEditView->GetSurroundingText(); | |||
1758 | ESelection aSel( pWin->GetSelection() ); | |||
1759 | ||||
1760 | if ( aSel.nStartPos > aSel.nEndPos ) | |||
1761 | aSel.nEndPos = aSel.nStartPos; | |||
1762 | ||||
1763 | //calculate a valid end-position by reading logical characters | |||
1764 | sal_Int32 nUtf16Pos=0; | |||
1765 | while( (nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.nEndPos) ) | |||
1766 | { | |||
1767 | sInput.iterateCodePoints(&nUtf16Pos); | |||
1768 | if( nUtf16Pos > aSel.nEndPos ) | |||
1769 | aSel.nEndPos = nUtf16Pos; | |||
1770 | } | |||
1771 | ||||
1772 | ToggleUnicodeCodepoint aToggle; | |||
1773 | while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) ) | |||
1774 | --nUtf16Pos; | |||
1775 | const OUString sReplacement = aToggle.ReplacementString(); | |||
1776 | if( !sReplacement.isEmpty() ) | |||
1777 | { | |||
1778 | pEditView->SetSelection( aSel ); | |||
1779 | pEditEngine->UndoActionStart(EDITUNDO_REPLACEALL119); | |||
1780 | aSel.nStartPos = aSel.nEndPos - aToggle.StringToReplace().getLength(); | |||
1781 | pWin->SetSelection( aSel ); | |||
1782 | pEditView->InsertText( sReplacement, true ); | |||
1783 | pEditEngine->UndoActionEnd(); | |||
1784 | pWin->Flush(); | |||
1785 | } | |||
1786 | } | |||
1787 | } | |||
1788 | break; | |||
1789 | ||||
1790 | case SID_SYMBOLS_CATALOGUE((30000 + 256) + 5): | |||
1791 | { | |||
1792 | ||||
1793 | // get device used to retrieve the FontList | |||
1794 | SmDocShell *pDoc = GetDoc(); | |||
1795 | OutputDevice *pDev = pDoc->GetPrinter(); | |||
1796 | if (!pDev || pDev->GetDevFontCount() == 0) | |||
1797 | pDev = &SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) )->GetDefaultVirtualDev(); | |||
1798 | SAL_WARN_IF( !pDev, "starmath", "device for font list missing" )do { if (true && (!pDev)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "device for font list missing" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1798" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "device for font list missing"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "device for font list missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1798" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "device for font list missing") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1798" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "device for font list missing"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "device for font list missing"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath"), ("/home/maarten/src/libreoffice/core/starmath/source/view.cxx" ":" "1798" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1799 | ||||
1800 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
1801 | SmSymbolDialog aDialog(pWin ? pWin->GetFrameWeld() : nullptr, pDev, pp->GetSymbolManager(), *this); | |||
1802 | aDialog.run(); | |||
1803 | } | |||
1804 | break; | |||
1805 | } | |||
1806 | rReq.Done(); | |||
1807 | } | |||
1808 | ||||
1809 | ||||
1810 | void SmViewShell::GetState(SfxItemSet &rSet) | |||
1811 | { | |||
1812 | SfxWhichIter aIter(rSet); | |||
1813 | ||||
1814 | SmEditWindow *pEditWin = GetEditWindow(); | |||
1815 | for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich()) | |||
1816 | { | |||
1817 | switch (nWh) | |||
1818 | { | |||
1819 | case SID_CUT(5000 + 710): | |||
1820 | case SID_COPY(5000 + 711): | |||
1821 | case SID_DELETE(5000 + 713): | |||
1822 | if (! pEditWin || ! pEditWin->IsSelected()) | |||
1823 | rSet.DisableItem(nWh); | |||
1824 | break; | |||
1825 | ||||
1826 | case SID_PASTE(5000 + 712): | |||
1827 | if (pEditWin) | |||
1828 | { | |||
1829 | TransferableDataHelper aDataHelper( | |||
1830 | TransferableDataHelper::CreateFromSystemClipboard( | |||
1831 | pEditWin) ); | |||
1832 | ||||
1833 | mbPasteState = aDataHelper.GetTransferable().is() && | |||
1834 | ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) || | |||
1835 | aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) || | |||
1836 | (aDataHelper.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) | |||
1837 | && aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE ))); | |||
1838 | } | |||
1839 | if( !mbPasteState ) | |||
1840 | rSet.DisableItem( nWh ); | |||
1841 | break; | |||
1842 | ||||
1843 | case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0): | |||
1844 | rSet.Put(SvxZoomItem( SvxZoomType::PERCENT, mpGraphic->GetZoom())); | |||
1845 | [[fallthrough]]; | |||
1846 | case SID_ZOOMIN((30000 + 256) + 10): | |||
1847 | case SID_ZOOMOUT((30000 + 256) + 11): | |||
1848 | case SID_ZOOM_OPTIMAL((27000 +99)): | |||
1849 | if ( GetViewFrame()->GetFrame().IsInPlace() ) | |||
1850 | rSet.DisableItem( nWh ); | |||
1851 | break; | |||
1852 | ||||
1853 | case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) : | |||
1854 | { | |||
1855 | const sal_uInt16 nCurrentZoom = mpGraphic->GetZoom(); | |||
1856 | SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOMsal_uInt16(25), MAXZOOMsal_uInt16(800) ); | |||
1857 | aZoomSliderItem.AddSnappingPoint( 100 ); | |||
1858 | rSet.Put( aZoomSliderItem ); | |||
1859 | } | |||
1860 | break; | |||
1861 | ||||
1862 | case SID_NEXTERR((30000 + 256) + 1): | |||
1863 | case SID_PREVERR((30000 + 256) + 2): | |||
1864 | case SID_NEXTMARK((30000 + 256) + 3): | |||
1865 | case SID_PREVMARK((30000 + 256) + 4): | |||
1866 | case SID_DRAW((30000 + 256) + 12): | |||
1867 | case SID_SELECT(5000 + 720): | |||
1868 | if (! pEditWin || pEditWin->IsEmpty()) | |||
1869 | rSet.DisableItem(nWh); | |||
1870 | break; | |||
1871 | ||||
1872 | case SID_TEXTSTATUS((30000 + 256) + 111): | |||
1873 | { | |||
1874 | rSet.Put(SfxStringItem(nWh, maStatusText)); | |||
1875 | } | |||
1876 | break; | |||
1877 | ||||
1878 | case SID_FORMULACURSOR((30000 + 256) + 15): | |||
1879 | { | |||
1880 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | |||
1881 | rSet.Put(SfxBoolItem(nWh, pp->GetConfig()->IsShowFormulaCursor())); | |||
1882 | } | |||
1883 | break; | |||
1884 | case SID_ELEMENTSDOCKINGWINDOW((30000 + 256) + 126): | |||
1885 | { | |||
1886 | bool bState = false; | |||
1887 | SfxChildWindow *pChildWnd = GetViewFrame()-> | |||
1888 | GetChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() ); | |||
1889 | if (pChildWnd && pChildWnd->GetWindow()->IsVisible()) | |||
1890 | bState = true; | |||
1891 | rSet.Put(SfxBoolItem(SID_ELEMENTSDOCKINGWINDOW((30000 + 256) + 126), bState)); | |||
1892 | } | |||
1893 | break; | |||
1894 | } | |||
1895 | } | |||
1896 | } | |||
1897 | ||||
1898 | SmViewShell::SmViewShell(SfxViewFrame *pFrame_, SfxViewShell *) | |||
1899 | : SfxViewShell(pFrame_, SfxViewShellFlags::HAS_PRINTOPTIONS) | |||
1900 | , mpImpl(new SmViewShell_Impl) | |||
1901 | , mpGraphic(VclPtr<SmGraphicWindow>::Create(this)) | |||
1902 | , maGraphicController(*mpGraphic, SID_GAPHIC_SM((30000 + 256) + 101), pFrame_->GetBindings()) | |||
1903 | , mbPasteState(false) | |||
1904 | , mbInsertIntoEditWindow(false) | |||
1905 | { | |||
1906 | SetStatusText(OUString()); | |||
1907 | SetWindow(mpGraphic.get()); | |||
1908 | SfxShell::SetName("SmView"); | |||
1909 | SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() ); | |||
1910 | } | |||
1911 | ||||
1912 | ||||
1913 | SmViewShell::~SmViewShell() | |||
1914 | { | |||
1915 | //!! this view shell is not active anymore !! | |||
1916 | // Thus 'SmGetActiveView' will give a 0 pointer. | |||
1917 | // Thus we need to supply this view as argument | |||
1918 | SmEditWindow *pEditWin = GetEditWindow(); | |||
1919 | if (pEditWin) | |||
1920 | pEditWin->DeleteEditView(); | |||
1921 | mpGraphic.disposeAndClear(); | |||
1922 | } | |||
1923 | ||||
1924 | void SmViewShell::Deactivate( bool bIsMDIActivate ) | |||
1925 | { | |||
1926 | SmEditWindow *pEdit = GetEditWindow(); | |||
1927 | if ( pEdit ) | |||
1928 | pEdit->Flush(); | |||
1929 | ||||
1930 | SfxViewShell::Deactivate( bIsMDIActivate ); | |||
1931 | } | |||
1932 | ||||
1933 | void SmViewShell::Activate( bool bIsMDIActivate ) | |||
1934 | { | |||
1935 | SfxViewShell::Activate( bIsMDIActivate ); | |||
1936 | ||||
1937 | SmEditWindow *pEdit = GetEditWindow(); | |||
1938 | if ( pEdit ) | |||
1939 | { | |||
1940 | //! Since there is no way to be informed if a "drag and drop" | |||
1941 | //! event has taken place, we call SetText here in order to | |||
1942 | //! synchronize the GraphicWindow display with the text in the | |||
1943 | //! EditEngine. | |||
1944 | SmDocShell *pDoc = GetDoc(); | |||
1945 | pDoc->SetText( pDoc->GetEditEngine().GetText() ); | |||
1946 | ||||
1947 | if ( bIsMDIActivate ) | |||
1948 | pEdit->GrabFocus(); | |||
1949 | } | |||
1950 | } | |||
1951 | ||||
1952 | IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )void SmViewShell::LinkStubDialogClosedHdl(void * instance, sfx2 ::FileDialogHelper* data) { return static_cast<SmViewShell *>(instance)->DialogClosedHdl(data); } void SmViewShell ::DialogClosedHdl(sfx2::FileDialogHelper* _pFileDlg) | |||
1953 | { | |||
1954 | assert(_pFileDlg && "SmViewShell::DialogClosedHdl(): no file dialog")(static_cast <bool> (_pFileDlg && "SmViewShell::DialogClosedHdl(): no file dialog" ) ? void (0) : __assert_fail ("_pFileDlg && \"SmViewShell::DialogClosedHdl(): no file dialog\"" , "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 1954, __extension__ __PRETTY_FUNCTION__)); | |||
1955 | assert(mpImpl->pDocInserter && "ScDocShell::DialogClosedHdl(): no document inserter")(static_cast <bool> (mpImpl->pDocInserter && "ScDocShell::DialogClosedHdl(): no document inserter") ? void (0) : __assert_fail ("mpImpl->pDocInserter && \"ScDocShell::DialogClosedHdl(): no document inserter\"" , "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 1955, __extension__ __PRETTY_FUNCTION__)); | |||
1956 | ||||
1957 | if ( ERRCODE_NONEErrCode(0) == _pFileDlg->GetError() ) | |||
1958 | { | |||
1959 | std::unique_ptr<SfxMedium> pMedium = mpImpl->pDocInserter->CreateMedium(); | |||
1960 | ||||
1961 | if ( pMedium ) | |||
1962 | { | |||
1963 | if ( pMedium->IsStorage() ) | |||
1964 | Insert( *pMedium ); | |||
1965 | else | |||
1966 | InsertFrom( *pMedium ); | |||
1967 | pMedium.reset(); | |||
1968 | ||||
1969 | SmDocShell* pDoc = GetDoc(); | |||
1970 | pDoc->UpdateText(); | |||
1971 | pDoc->ArrangeFormula(); | |||
1972 | pDoc->Repaint(); | |||
1973 | // adjust window, repaint, increment ModifyCount,... | |||
1974 | GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM((30000 + 256) + 101)); | |||
1975 | } | |||
1976 | } | |||
1977 | ||||
1978 | mpImpl->pRequest->SetReturnValue( SfxBoolItem( mpImpl->pRequest->GetSlot(), true ) ); | |||
1979 | mpImpl->pRequest->Done(); | |||
1980 | } | |||
1981 | ||||
1982 | void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint ) | |||
1983 | { | |||
1984 | switch( rHint.GetId() ) | |||
1985 | { | |||
1986 | case SfxHintId::ModeChanged: | |||
1987 | case SfxHintId::DocChanged: | |||
1988 | GetViewFrame()->GetBindings().InvalidateAll(false); | |||
1989 | break; | |||
1990 | default: | |||
1991 | break; | |||
1992 | } | |||
1993 | } | |||
1994 | ||||
1995 | bool SmViewShell::IsInlineEditEnabled() const | |||
1996 | { | |||
1997 | return mpImpl->aOpts.IsExperimentalMode(); | |||
1998 | } | |||
1999 | ||||
2000 | void SmViewShell::ZoomByItemSet(const SfxItemSet *pSet) | |||
2001 | { | |||
2002 | assert(pSet)(static_cast <bool> (pSet) ? void (0) : __assert_fail ( "pSet", "/home/maarten/src/libreoffice/core/starmath/source/view.cxx" , 2002, __extension__ __PRETTY_FUNCTION__)); | |||
2003 | const SvxZoomItem &rZoom = pSet->Get(SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0)); | |||
2004 | switch( rZoom.GetType() ) | |||
2005 | { | |||
2006 | case SvxZoomType::PERCENT: | |||
2007 | mpGraphic->SetZoom(sal::static_int_cast<sal_uInt16>(rZoom.GetValue ())); | |||
2008 | break; | |||
2009 | ||||
2010 | case SvxZoomType::OPTIMAL: | |||
2011 | mpGraphic->ZoomToFitInWindow(); | |||
2012 | break; | |||
2013 | ||||
2014 | case SvxZoomType::PAGEWIDTH: | |||
2015 | case SvxZoomType::WHOLEPAGE: | |||
2016 | { | |||
2017 | const MapMode aMap( MapUnit::Map100thMM ); | |||
2018 | SfxPrinter *pPrinter = GetPrinter( true ); | |||
2019 | tools::Rectangle OutputRect(Point(), pPrinter->GetOutputSize()); | |||
2020 | Size OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(), | |||
2021 | OutputRect.GetHeight()), aMap)); | |||
2022 | Size GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap)); | |||
2023 | sal_uInt16 nZ = sal::static_int_cast<sal_uInt16>(std::min(long(Fraction(OutputSize.Width() * 100, GraphicSize.Width())), | |||
2024 | long(Fraction(OutputSize.Height() * 100, GraphicSize.Height())))); | |||
2025 | mpGraphic->SetZoom (nZ); | |||
2026 | break; | |||
2027 | } | |||
2028 | default: | |||
2029 | break; | |||
2030 | } | |||
2031 | } | |||
2032 | ||||
2033 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } // namespace vcl::detail |
48 | |
49 | /** |
50 | * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses. |
51 | * |
52 | * For more details on the design please see vcl/README.lifecycle |
53 | * |
54 | * @param reference_type must be a subclass of vcl::Window |
55 | */ |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | /** Constructor... |
68 | */ |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | /** Constructor... |
74 | */ |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | /** Constructor... that doesn't take a ref. |
80 | */ |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | /** Up-casting conversion constructor: Copies interface reference. |
86 | |
87 | Does not work for up-casts to ambiguous bases. For the special case of |
88 | up-casting to Reference< XInterface >, see the corresponding conversion |
89 | operator. |
90 | |
91 | @param rRef another reference |
92 | */ |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain ::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); |
107 | // We can be one of the intermediate counts, but if we are the last |
108 | // VclPtr keeping this object alive, then something forgot to call dispose(). |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)) |
110 | && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | /** |
119 | * A construction helper for VclPtr. Since VclPtr types are created |
120 | * with a reference-count of one - to help fit into the existing |
121 | * code-flow; this helps us to construct them easily. |
122 | * |
123 | * For more details on the design please see vcl/README.lifecycle |
124 | * |
125 | * @tparam reference_type must be a subclass of vcl::Window |
126 | */ |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | /** |
265 | * A construction helper for a temporary VclPtr. Since VclPtr types |
266 | * are created with a reference-count of one - to help fit into |
267 | * the existing code-flow; this helps us to construct them easily. |
268 | * see also VclPtr::Create and ScopedVclPtr |
269 | * |
270 | * For more details on the design please see vcl/README.lifecycle |
271 | * |
272 | * @param reference_type must be a subclass of vcl::Window |
273 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | /** |
284 | * Override and disallow this, to prevent people accidentally calling it and actually |
285 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
286 | */ |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | /** Constructor... |
295 | */ |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | /** Constructor |
301 | */ |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | /** Copy constructor... |
307 | */ |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | /** |
313 | Assignment that releases the last reference. |
314 | */ |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | Assignment that releases the last reference. |
325 | */ |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | /** Up-casting conversion constructor: Copies interface reference. |
333 | |
334 | Does not work for up-casts to ambiguous bases. For the special case of |
335 | up-casting to Reference< XInterface >, see the corresponding conversion |
336 | operator. |
337 | |
338 | @param rRef another reference |
339 | */ |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | /** Up-casting assignment operator. |
351 | |
352 | Does not work for up-casts to ambiguous bases. |
353 | |
354 | @param rRef another VclPtr |
355 | */ |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | /** |
367 | * Override and disallow this, to prevent people accidentally calling it and actually |
368 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
369 | */ |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get( ) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 375, __extension__ __PRETTY_FUNCTION__)); // make sure there are no lingering references |
376 | } |
377 | |
378 | private: |
379 | // Most likely we don't want this default copy-constructor. |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | // And certainly we don't want a default assignment operator. |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | // And disallow reset as that doesn't call disposeAndClear on the original reference |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | /** |
394 | * A construction helper for ScopedVclPtr. Since VclPtr types are created |
395 | * with a reference-count of one - to help fit into the existing |
396 | * code-flow; this helps us to construct them easily. |
397 | * |
398 | * For more details on the design please see vcl/README.lifecycle |
399 | * |
400 | * @param reference_type must be a subclass of vcl::Window |
401 | */ |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | /** |
416 | * Override and disallow this, to prevent people accidentally calling it and actually |
417 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
418 | */ |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | // Prevent the above perfect forwarding ctor from hijacking (accidental) |
423 | // attempts at ScopedVclPtrInstance copy construction (where the hijacking |
424 | // would typically lead to somewhat obscure error messages); both non-const |
425 | // and const variants are needed here, as the ScopedVclPtr base class has a |
426 | // const--variant copy ctor, so the implicitly declared copy ctor for |
427 | // ScopedVclPtrInstance would also be the const variant, so non-const copy |
428 | // construction attempts would be hijacked by the perfect forwarding ctor; |
429 | // but if we only declared a non-const variant here, the const variant would |
430 | // no longer be implicitly declared (as there would already be an explicitly |
431 | // declared copy ctor), so const copy construction attempts would then be |
432 | // hijacked by the perfect forwarding ctor: |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||
22 | |||||||||
23 | #include "sal/config.h" | ||||||||
24 | |||||||||
25 | #include <cassert> | ||||||||
26 | #include <cstddef> | ||||||||
27 | #include <functional> | ||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
29 | #include <type_traits> | ||||||||
30 | #endif | ||||||||
31 | |||||||||
32 | #include "sal/types.h" | ||||||||
33 | |||||||||
34 | namespace rtl | ||||||||
35 | { | ||||||||
36 | |||||||||
37 | /** Template reference class for reference type. | ||||||||
38 | */ | ||||||||
39 | template <class reference_type> | ||||||||
40 | class Reference | ||||||||
41 | { | ||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||
43 | */ | ||||||||
44 | reference_type * m_pBody; | ||||||||
45 | |||||||||
46 | |||||||||
47 | public: | ||||||||
48 | /** Constructor... | ||||||||
49 | */ | ||||||||
50 | Reference() | ||||||||
51 | : m_pBody (NULL__null) | ||||||||
52 | {} | ||||||||
53 | |||||||||
54 | |||||||||
55 | /** Constructor... | ||||||||
56 | */ | ||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||
58 | : m_pBody (pBody) | ||||||||
59 | { | ||||||||
60 | } | ||||||||
61 | |||||||||
62 | /** Constructor... | ||||||||
63 | */ | ||||||||
64 | Reference (reference_type * pBody) | ||||||||
65 | : m_pBody (pBody) | ||||||||
66 | { | ||||||||
67 | if (m_pBody) | ||||||||
68 | m_pBody->acquire(); | ||||||||
69 | } | ||||||||
70 | |||||||||
71 | /** Copy constructor... | ||||||||
72 | */ | ||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||
75 | { | ||||||||
76 | if (m_pBody) | ||||||||
77 | m_pBody->acquire(); | ||||||||
78 | } | ||||||||
79 | |||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
81 | /** Move constructor... | ||||||||
82 | */ | ||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||
85 | { | ||||||||
86 | handle.m_pBody = nullptr; | ||||||||
87 | } | ||||||||
88 | #endif | ||||||||
89 | |||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||
92 | |||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||
94 | |||||||||
95 | @param rRef another reference | ||||||||
96 | */ | ||||||||
97 | template< class derived_type > | ||||||||
98 | inline Reference( | ||||||||
99 | const Reference< derived_type > & rRef, | ||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||
101 | : m_pBody (rRef.get()) | ||||||||
102 | { | ||||||||
103 | if (m_pBody) | ||||||||
104 | m_pBody->acquire(); | ||||||||
105 | } | ||||||||
106 | #endif | ||||||||
107 | |||||||||
108 | /** Destructor... | ||||||||
109 | */ | ||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||
111 | { | ||||||||
112 | if (m_pBody) | ||||||||
113 | m_pBody->release(); | ||||||||
114 | } | ||||||||
115 | |||||||||
116 | /** Set... | ||||||||
117 | Similar to assignment. | ||||||||
118 | */ | ||||||||
119 | Reference<reference_type> & | ||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||
121 | { | ||||||||
122 | if (pBody) | ||||||||
123 | pBody->acquire(); | ||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||
125 | m_pBody = pBody; | ||||||||
126 | if (pOld) | ||||||||
127 | pOld->release(); | ||||||||
128 | return *this; | ||||||||
129 | } | ||||||||
130 | |||||||||
131 | /** Assignment. | ||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||
133 | bind it to the body represented by the handle. | ||||||||
134 | */ | ||||||||
135 | Reference<reference_type> & | ||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||
137 | { | ||||||||
138 | return set( handle.m_pBody ); | ||||||||
139 | } | ||||||||
140 | |||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
142 | /** Assignment. | ||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||
144 | * bind it to the body represented by the handle, and | ||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||
146 | */ | ||||||||
147 | Reference<reference_type> & | ||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||
149 | { | ||||||||
150 | // self-movement guts ourself | ||||||||
151 | if (m_pBody) | ||||||||
152 | m_pBody->release(); | ||||||||
153 | m_pBody = handle.m_pBody; | ||||||||
154 | handle.m_pBody = nullptr; | ||||||||
155 | return *this; | ||||||||
156 | } | ||||||||
157 | #endif | ||||||||
158 | |||||||||
159 | /** Assignment... | ||||||||
160 | */ | ||||||||
161 | Reference<reference_type> & | ||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||
163 | { | ||||||||
164 | return set( pBody ); | ||||||||
165 | } | ||||||||
166 | |||||||||
167 | /** Unbind the body from this handle. | ||||||||
168 | Note that for a handle representing a large body, | ||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||
171 | since in the second case two large objects exist in memory | ||||||||
172 | (the old body and the new body). | ||||||||
173 | */ | ||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||
175 | { | ||||||||
176 | if (m_pBody
| ||||||||
177 | { | ||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||
179 | m_pBody = NULL__null; | ||||||||
180 | pOld->release(); | ||||||||
181 | } | ||||||||
182 | return *this; | ||||||||
183 | } | ||||||||
184 | |||||||||
185 | |||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||
188 | are the same. | ||||||||
189 | */ | ||||||||
190 | reference_type * SAL_CALL get() const | ||||||||
191 | { | ||||||||
192 | return m_pBody; | ||||||||
| |||||||||
193 | } | ||||||||
194 | |||||||||
195 | |||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||
197 | */ | ||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||
199 | { | ||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||
201 | return m_pBody; | ||||||||
202 | } | ||||||||
203 | |||||||||
204 | |||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||
206 | */ | ||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||
208 | { | ||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||
210 | return *m_pBody; | ||||||||
211 | } | ||||||||
212 | |||||||||
213 | |||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||
215 | */ | ||||||||
216 | bool SAL_CALL is() const | ||||||||
217 | { | ||||||||
218 | return (m_pBody != NULL__null); | ||||||||
219 | } | ||||||||
220 | |||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||
223 | */ | ||||||||
224 | explicit operator bool() const | ||||||||
225 | { | ||||||||
226 | return is(); | ||||||||
227 | } | ||||||||
228 | #endif | ||||||||
229 | |||||||||
230 | /** Returns True if this points to pBody. | ||||||||
231 | */ | ||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||
233 | { | ||||||||
234 | return (m_pBody == pBody); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | |||||||||
238 | /** Returns True if handle points to the same body. | ||||||||
239 | */ | ||||||||
240 | bool | ||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||
242 | { | ||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||
244 | } | ||||||||
245 | |||||||||
246 | |||||||||
247 | /** Needed to place References into STL collection. | ||||||||
248 | */ | ||||||||
249 | bool | ||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||
251 | { | ||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||
253 | } | ||||||||
254 | |||||||||
255 | |||||||||
256 | /** Needed to place References into STL collection. | ||||||||
257 | */ | ||||||||
258 | bool | ||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||
260 | { | ||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||
262 | } | ||||||||
263 | |||||||||
264 | |||||||||
265 | /** Needed to place References into STL collection. | ||||||||
266 | */ | ||||||||
267 | bool | ||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||
269 | { | ||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||
271 | } | ||||||||
272 | }; | ||||||||
273 | |||||||||
274 | } // namespace rtl | ||||||||
275 | |||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
277 | namespace std | ||||||||
278 | { | ||||||||
279 | |||||||||
280 | /// @cond INTERNAL | ||||||||
281 | /** | ||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||
283 | |||||||||
284 | @since LibreOffice 6.3 | ||||||||
285 | */ | ||||||||
286 | template<typename T> | ||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||
288 | { | ||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||
290 | { return std::size_t(s.get()); } | ||||||||
291 | }; | ||||||||
292 | /// @endcond | ||||||||
293 | |||||||||
294 | } | ||||||||
295 | |||||||||
296 | #endif | ||||||||
297 | |||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||
299 | |||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |