tdf#100151: Dispose of window if DX device creation failed
[LibreOffice.git] / starmath / source / view.cxx
blob0da5ee3cd901a7497dc7b015af1288a5f4b4174a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
21 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
22 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
23 #include <com/sun/star/accessibility/XAccessible.hpp>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/frame/Desktop.hpp>
26 #include <com/sun/star/frame/XFramesSupplier.hpp>
27 #include <com/sun/star/container/XChild.hpp>
29 #include <comphelper/processfactory.hxx>
30 #include <comphelper/storagehelper.hxx>
31 #include <comphelper/string.hxx>
32 #include <i18nutil/unicode.hxx>
33 #include <sfx2/app.hxx>
34 #include <sfx2/dispatch.hxx>
35 #include <sfx2/docfile.hxx>
36 #include <sfx2/docfilt.hxx>
37 #include <sfx2/docinsert.hxx>
38 #include <sfx2/filedlghelper.hxx>
39 #include <sfx2/msg.hxx>
40 #include <sfx2/objface.hxx>
41 #include <sfx2/printer.hxx>
42 #include <sfx2/request.hxx>
43 #include <svl/eitem.hxx>
44 #include <svl/intitem.hxx>
45 #include <svl/itemset.hxx>
46 #include <svl/poolitem.hxx>
47 #include <svl/ptitem.hxx>
48 #include <svl/stritem.hxx>
49 #include <svtools/transfer.hxx>
50 #include <svtools/miscopt.hxx>
51 #include <svl/undo.hxx>
52 #include <svl/whiter.hxx>
53 #include <svx/dialogs.hrc>
54 #include <svx/zoomslideritem.hxx>
55 #include <editeng/editeng.hxx>
56 #include <editeng/editview.hxx>
57 #include <svx/svxdlg.hxx>
58 #include <sfx2/zoomitem.hxx>
59 #include <vcl/decoview.hxx>
60 #include <vcl/menu.hxx>
61 #include <vcl/msgbox.hxx>
62 #include <vcl/wrkwin.hxx>
63 #include <vcl/settings.hxx>
65 #include <unotools/streamwrap.hxx>
67 #include "unomodel.hxx"
68 #include "view.hxx"
69 #include "cfgitem.hxx"
70 #include "dialog.hxx"
71 #include "document.hxx"
72 #include "starmath.hrc"
73 #include "mathmlimport.hxx"
74 #include "cursor.hxx"
75 #include "accessibility.hxx"
76 #include "ElementsDockingWindow.hxx"
77 #include <cassert>
78 #include <memory>
80 #define MINZOOM sal_uInt16(25)
81 #define MAXZOOM sal_uInt16(800)
83 // space around the edit window, in pixels
84 // fdo#69111: Increased border on the top so that the window is
85 // easier to tear off.
86 #define CMD_BOX_PADDING 4
87 #define CMD_BOX_PADDING_TOP 10
89 #define SmViewShell
90 #include "smslots.hxx"
92 using namespace css;
93 using namespace css::accessibility;
94 using namespace css::uno;
96 SmGraphicWindow::SmGraphicWindow(SmViewShell* pShell)
97 : ScrollableWindow(&pShell->GetViewFrame()->GetWindow())
98 , pAccessible(nullptr)
99 , pViewShell(pShell)
100 , nZoom(100)
102 assert(pViewShell);
103 // docking windows are usually hidden (often already done in the
104 // resource) and will be shown by the sfx framework.
105 Hide();
107 const Fraction aFraction(1, 1);
108 SetMapMode(MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction));
110 SetTotalSize();
112 SetHelpId(HID_SMA_WIN_DOCUMENT);
114 ShowLine(false);
115 CaretBlinkInit();
118 SmGraphicWindow::~SmGraphicWindow()
120 disposeOnce();
123 void SmGraphicWindow::dispose()
125 if (pAccessible)
126 pAccessible->ClearWin(); // make Accessible defunctional
127 // Note: memory for pAccessible will be freed when the reference
128 // xAccessible is released.
129 CaretBlinkStop();
130 ScrollableWindow::dispose();
133 void SmGraphicWindow::StateChanged(StateChangedType eType)
135 if (eType == StateChangedType::InitShow)
136 Show();
137 ScrollableWindow::StateChanged(eType);
141 void SmGraphicWindow::ApplyColorConfigValues(const svtools::ColorConfig &rColorCfg)
143 // Note: SetTextColor not necessary since the nodes that
144 // get painted have the color information.
145 SetBackground(Color(static_cast<ColorData>(rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor)));
149 void SmGraphicWindow::MouseButtonDown(const MouseEvent& rMEvt)
151 ScrollableWindow::MouseButtonDown(rMEvt);
153 GrabFocus();
155 // set formula-cursor and selection of edit window according to the
156 // position clicked at
158 SAL_WARN_IF( rMEvt.GetClicks() == 0, "starmath", "0 clicks" );
159 if ( rMEvt.IsLeft() )
161 // get click position relativ to formula
162 Point aPos (PixelToLogic(rMEvt.GetPosPixel())
163 - GetFormulaDrawPos());
165 const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
166 if (!pTree)
167 return;
169 if (IsInlineEditEnabled()) {
170 pViewShell->GetDoc()->GetCursor().MoveTo(this, aPos, !rMEvt.IsShift());
171 return;
173 const SmNode *pNode = nullptr;
174 // if it was clicked inside the formula then get the appropriate node
175 if (pTree->OrientedDist(aPos) <= 0)
176 pNode = pTree->FindRectClosestTo(aPos);
178 if (pNode)
179 { SmEditWindow *pEdit = pViewShell->GetEditWindow();
180 if (!pEdit)
181 return;
182 const SmToken aToken (pNode->GetToken());
184 // set selection to the beginning of the token
185 ESelection aSel (aToken.nRow - 1, aToken.nCol - 1);
187 if (rMEvt.GetClicks() != 1 || aToken.eType == TPLACE)
188 aSel.nEndPos = aSel.nEndPos + sal::static_int_cast< sal_uInt16 >(aToken.aText.getLength());
190 pEdit->SetSelection(aSel);
191 SetCursor(pNode);
193 // allow for immediate editing and
194 //! implicitly synchronize the cursor position mark in this window
195 pEdit->GrabFocus();
200 void SmGraphicWindow::MouseMove(const MouseEvent &rMEvt)
202 ScrollableWindow::MouseMove(rMEvt);
204 if (rMEvt.IsLeft() && IsInlineEditEnabled())
206 Point aPos(PixelToLogic(rMEvt.GetPosPixel()) - GetFormulaDrawPos());
207 pViewShell->GetDoc()->GetCursor().MoveTo(this, aPos, false);
209 CaretBlinkStop();
210 SetIsCursorVisible(true);
211 CaretBlinkStart();
212 RepaintViewShellDoc();
216 bool SmGraphicWindow::IsInlineEditEnabled() const
218 return pViewShell->IsInlineEditEnabled();
221 void SmGraphicWindow::GetFocus()
223 if (!IsInlineEditEnabled())
224 return;
225 if (pViewShell->GetEditWindow())
226 pViewShell->GetEditWindow()->Flush();
227 //Let view shell know what insertions should be done in visual editor
228 pViewShell->SetInsertIntoEditWindow(false);
229 SetIsCursorVisible(true);
230 ShowLine(true);
231 CaretBlinkStart();
232 RepaintViewShellDoc();
235 void SmGraphicWindow::LoseFocus()
237 ScrollableWindow::LoseFocus();
238 if (xAccessible.is())
240 uno::Any aOldValue, aNewValue;
241 aOldValue <<= AccessibleStateType::FOCUSED;
242 // aNewValue remains empty
243 pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED,
244 aOldValue, aNewValue );
246 if (!IsInlineEditEnabled())
247 return;
248 SetIsCursorVisible(false);
249 ShowLine(false);
250 CaretBlinkStop();
251 RepaintViewShellDoc();
254 void SmGraphicWindow::RepaintViewShellDoc()
256 SmDocShell* pDoc = pViewShell->GetDoc();
257 if (pDoc)
258 pDoc->Repaint();
261 IMPL_LINK_NOARG(SmGraphicWindow, CaretBlinkTimerHdl, Timer *, void)
263 if (IsCursorVisible())
264 SetIsCursorVisible(false);
265 else
266 SetIsCursorVisible(true);
268 RepaintViewShellDoc();
271 void SmGraphicWindow::CaretBlinkInit()
273 aCaretBlinkTimer.SetTimeoutHdl(LINK(this, SmGraphicWindow, CaretBlinkTimerHdl));
274 aCaretBlinkTimer.SetTimeout( ScrollableWindow::GetSettings().GetStyleSettings().GetCursorBlinkTime() );
277 void SmGraphicWindow::CaretBlinkStart()
279 if (!IsInlineEditEnabled())
280 return;
281 if (aCaretBlinkTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME)
282 aCaretBlinkTimer.Start();
285 void SmGraphicWindow::CaretBlinkStop()
287 if (!IsInlineEditEnabled())
288 return;
289 aCaretBlinkTimer.Stop();
292 void SmGraphicWindow::ShowCursor(bool bShow)
293 // shows or hides the formula-cursor depending on 'bShow' is true or not
295 if (IsInlineEditEnabled())
296 return;
298 bool bInvert = bShow != IsCursorVisible();
300 if (bInvert)
301 InvertTracking(aCursorRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow);
303 SetIsCursorVisible(bShow);
306 void SmGraphicWindow::ShowLine(bool bShow)
308 if (!IsInlineEditEnabled())
309 return;
311 bIsLineVisible = bShow;
314 void SmGraphicWindow::SetCursor(const SmNode *pNode)
316 if (IsInlineEditEnabled())
317 return;
319 const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
321 // get appropriate rectangle
322 Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()),
323 aTLPos (GetFormulaDrawPos() + aOffset);
324 aTLPos.X() -= pNode->GetItalicLeftSpace();
325 Size aSize (pNode->GetItalicSize());
327 SetCursor(Rectangle(aTLPos, aSize));
330 void SmGraphicWindow::SetCursor(const Rectangle &rRect)
331 // sets cursor to new position (rectangle) 'rRect'.
332 // The old cursor will be removed, and the new one will be shown if
333 // that is activated in the ConfigItem
335 if (IsInlineEditEnabled())
336 return;
338 SmModule *pp = SM_MOD();
340 if (IsCursorVisible())
341 ShowCursor(false); // clean up remainings of old cursor
342 aCursorRect = rRect;
343 if (pp->GetConfig()->IsShowFormulaCursor())
344 ShowCursor(true); // draw new cursor
347 const SmNode * SmGraphicWindow::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol)
348 // looks for a VISIBLE node in the formula tree with its token at
349 // (or around) the position 'nRow', 'nCol' in the edit window
350 // (row and column numbering starts with 1 there!).
351 // If there is such a node the formula-cursor is set to cover that nodes
352 // rectangle. If not the formula-cursor will be hidden.
353 // In any case the search result is being returned.
355 if (IsInlineEditEnabled())
356 return nullptr;
358 // find visible node with token at nRow, nCol
359 const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(),
360 *pNode = nullptr;
361 if (pTree)
362 pNode = pTree->FindTokenAt(nRow, nCol);
364 if (pNode)
365 SetCursor(pNode);
366 else
367 ShowCursor(false);
369 return pNode;
372 void SmGraphicWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
374 ApplyColorConfigValues(SM_MOD()->GetColorConfig());
376 SmDocShell& rDoc = *pViewShell->GetDoc();
377 Point aPoint;
379 rDoc.DrawFormula(rRenderContext, aPoint, true); //! modifies aPoint to be the topleft
380 //! corner of the formula
381 aFormulaDrawPos = aPoint;
382 if (IsInlineEditEnabled())
384 //Draw cursor if any...
385 if (pViewShell->GetDoc()->HasCursor() && IsLineVisible())
386 pViewShell->GetDoc()->GetCursor().Draw(rRenderContext, aPoint, IsCursorVisible());
388 else
390 SetIsCursorVisible(false); // (old) cursor must be drawn again
392 const SmEditWindow* pEdit = pViewShell->GetEditWindow();
393 if (pEdit)
394 { // get new position for formula-cursor (for possible altered formula)
395 sal_Int32 nRow;
396 sal_uInt16 nCol;
397 SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol);
398 nRow++;
399 nCol++;
400 const SmNode *pFound = SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
402 SmModule *pp = SM_MOD();
403 if (pFound && pp->GetConfig()->IsShowFormulaCursor())
404 ShowCursor(true);
410 void SmGraphicWindow::SetTotalSize ()
412 SmDocShell &rDoc = *pViewShell->GetDoc();
413 const Size aTmp( PixelToLogic( LogicToPixel( rDoc.GetSize() )));
414 if ( aTmp != ScrollableWindow::GetTotalSize() )
415 ScrollableWindow::SetTotalSize( aTmp );
418 void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt)
420 if (!IsInlineEditEnabled()) {
421 if (! (GetView() && GetView()->KeyInput(rKEvt)) )
422 ScrollableWindow::KeyInput(rKEvt);
423 return;
426 SmCursor& rCursor = pViewShell->GetDoc()->GetCursor();
427 KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
428 if (eFunc == KeyFuncType::COPY)
429 rCursor.Copy();
430 else if (eFunc == KeyFuncType::CUT)
431 rCursor.Cut();
432 else if (eFunc == KeyFuncType::PASTE)
433 rCursor.Paste();
434 else {
435 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
436 switch(nCode)
438 case KEY_LEFT:
440 rCursor.Move(this, MoveLeft, !rKEvt.GetKeyCode().IsShift());
441 }break;
442 case KEY_RIGHT:
444 rCursor.Move(this, MoveRight, !rKEvt.GetKeyCode().IsShift());
445 }break;
446 case KEY_UP:
448 rCursor.Move(this, MoveUp, !rKEvt.GetKeyCode().IsShift());
449 }break;
450 case KEY_DOWN:
452 rCursor.Move(this, MoveDown, !rKEvt.GetKeyCode().IsShift());
453 }break;
454 case KEY_RETURN:
456 if(!rKEvt.GetKeyCode().IsShift())
457 rCursor.InsertRow();
458 }break;
459 case KEY_DELETE:
461 if(!rCursor.HasSelection()){
462 rCursor.Move(this, MoveRight, false);
463 if(rCursor.HasComplexSelection()) break;
465 rCursor.Delete();
466 }break;
467 case KEY_BACKSPACE:
469 rCursor.DeletePrev(this);
470 }break;
471 case KEY_ADD:
472 rCursor.InsertElement(PlusElement);
473 break;
474 case KEY_SUBTRACT:
475 if(rKEvt.GetKeyCode().IsShift())
476 rCursor.InsertSubSup(RSUB);
477 else
478 rCursor.InsertElement(MinusElement);
479 break;
480 case KEY_MULTIPLY:
481 rCursor.InsertElement(CDotElement);
482 break;
483 case KEY_DIVIDE:
484 rCursor.InsertFraction();
485 break;
486 case KEY_LESS:
487 rCursor.InsertElement(LessThanElement);
488 break;
489 case KEY_GREATER:
490 rCursor.InsertElement(GreaterThanElement);
491 break;
492 case KEY_EQUAL:
493 rCursor.InsertElement(EqualElement);
494 break;
495 default:
497 sal_Unicode code = rKEvt.GetCharCode();
498 SmBraceNode* pBraceNode = nullptr;
500 if(code == ' ') {
501 rCursor.InsertElement(BlankElement);
502 }else if(code == '^') {
503 rCursor.InsertSubSup(RSUP);
504 }else if(code == '(') {
505 rCursor.InsertBrackets(RoundBrackets);
506 }else if(code == '[') {
507 rCursor.InsertBrackets(SquareBrackets);
508 }else if(code == '{') {
509 rCursor.InsertBrackets(CurlyBrackets);
510 }else if(code == '!') {
511 rCursor.InsertElement(FactorialElement);
512 }else if(code == '%') {
513 rCursor.InsertElement(PercentElement);
514 }else if(code == ')' && rCursor.IsAtTailOfBracket(RoundBrackets, &pBraceNode)) {
515 rCursor.MoveAfterBracket(pBraceNode);
516 }else if(code == ']' && rCursor.IsAtTailOfBracket(SquareBrackets, &pBraceNode)) {
517 rCursor.MoveAfterBracket(pBraceNode);
518 }else if(code == '}' && rCursor.IsAtTailOfBracket(CurlyBrackets, &pBraceNode)) {
519 rCursor.MoveAfterBracket(pBraceNode);
520 }else{
521 if(code != 0){
522 rCursor.InsertText(OUString(code));
523 }else if (! (GetView() && GetView()->KeyInput(rKEvt)) )
524 ScrollableWindow::KeyInput(rKEvt);
529 CaretBlinkStop();
530 CaretBlinkStart();
531 SetIsCursorVisible(true);
532 RepaintViewShellDoc();
536 void SmGraphicWindow::Command(const CommandEvent& rCEvt)
538 bool bCallBase = true;
539 if ( !pViewShell->GetViewFrame()->GetFrame().IsInPlace() )
541 switch ( rCEvt.GetCommand() )
543 case CommandEventId::ContextMenu:
545 GetParent()->ToTop();
546 Point aPos(5, 5);
547 if (rCEvt.IsMouseEvent())
548 aPos = rCEvt.GetMousePosPixel();
550 // added for replaceability of context menus
551 SfxDispatcher::ExecutePopup( this, &aPos );
553 bCallBase = false;
555 break;
557 case CommandEventId::Wheel:
559 const CommandWheelData* pWData = rCEvt.GetWheelData();
560 if ( pWData && CommandWheelMode::ZOOM == pWData->GetMode() )
562 sal_uInt16 nTmpZoom = GetZoom();
563 if( 0 > pWData->GetDelta() )
564 nTmpZoom -= 10;
565 else
566 nTmpZoom += 10;
567 SetZoom( nTmpZoom );
568 bCallBase = false;
571 break;
573 default: break;
576 if ( bCallBase )
577 ScrollableWindow::Command (rCEvt);
581 void SmGraphicWindow::SetZoom(sal_uInt16 Factor)
583 nZoom = std::min(std::max(Factor, MINZOOM), MAXZOOM);
584 Fraction aFraction (nZoom, 100);
585 SetMapMode( MapMode(MapUnit::Map100thMM, Point(), aFraction, aFraction) );
586 SetTotalSize();
587 SmViewShell *pViewSh = GetView();
588 if (pViewSh)
590 pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM);
591 pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER);
593 Invalidate();
597 void SmGraphicWindow::ZoomToFitInWindow()
599 SmDocShell &rDoc = *pViewShell->GetDoc();
601 // set defined mapmode before calling 'LogicToPixel' below
602 SetMapMode(MapMode(MapUnit::Map100thMM));
604 Size aSize (LogicToPixel(rDoc.GetSize()));
605 Size aWindowSize (GetSizePixel());
607 if (aSize.Width() > 0 && aSize.Height() > 0)
609 long nVal = std::min ((85 * aWindowSize.Width()) / aSize.Width(),
610 (85 * aWindowSize.Height()) / aSize.Height());
611 SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) );
615 uno::Reference< XAccessible > SmGraphicWindow::CreateAccessible()
617 if (!pAccessible)
619 pAccessible = new SmGraphicAccessible( this );
620 xAccessible = pAccessible;
622 return xAccessible;
625 /**************************************************************************/
628 SmGraphicController::SmGraphicController(SmGraphicWindow &rSmGraphic,
629 sal_uInt16 nId_,
630 SfxBindings &rBindings) :
631 SfxControllerItem(nId_, rBindings),
632 rGraphic(rSmGraphic)
637 void SmGraphicController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
639 rGraphic.SetTotalSize();
640 rGraphic.Invalidate();
641 SfxControllerItem::StateChanged (nSID, eState, pState);
645 /**************************************************************************/
648 SmEditController::SmEditController(SmEditWindow &rSmEdit,
649 sal_uInt16 nId_,
650 SfxBindings &rBindings) :
651 SfxControllerItem(nId_, rBindings),
652 rEdit(rSmEdit)
658 void SmEditController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
660 const SfxStringItem *pItem = dynamic_cast<const SfxStringItem*>( pState);
662 if ((pItem != nullptr) && (rEdit.GetText() != OUString(pItem->GetValue())))
663 rEdit.SetText(pItem->GetValue());
664 SfxControllerItem::StateChanged (nSID, eState, pState);
667 /**************************************************************************/
668 SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings *pBindings_, SfxChildWindow *pChildWindow,
669 vcl::Window *pParent) :
670 SfxDockingWindow(pBindings_, pChildWindow, pParent, WB_MOVEABLE|WB_CLOSEABLE|WB_SIZEABLE|WB_DOCKABLE),
671 aEdit (VclPtr<SmEditWindow>::Create(*this)),
672 aController (*(aEdit.get()), SID_TEXT, *pBindings_),
673 bExiting (false)
675 SetHelpId( HID_SMA_COMMAND_WIN );
676 SetSizePixel(LogicToPixel(Size(292 , 94), MapMode(MapUnit::MapAppFont)));
677 SetText(SM_RESSTR(STR_CMDBOXWINDOW));
679 Hide();
681 aInitialFocusTimer.SetTimeoutHdl(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl));
682 aInitialFocusTimer.SetTimeout(100);
685 SmCmdBoxWindow::~SmCmdBoxWindow ()
687 disposeOnce();
690 void SmCmdBoxWindow::dispose()
692 aInitialFocusTimer.Stop();
693 bExiting = true;
694 aController.dispose();
695 aEdit.disposeAndClear();
696 SfxDockingWindow::dispose();
699 SmViewShell * SmCmdBoxWindow::GetView()
701 SfxDispatcher *pDispatcher = GetBindings().GetDispatcher();
702 SfxViewShell *pView = pDispatcher ? pDispatcher->GetFrame()->GetViewShell() : nullptr;
703 return dynamic_cast<SmViewShell*>( pView);
706 void SmCmdBoxWindow::Resize()
708 Rectangle aRect(Point(0, 0), GetOutputSizePixel());
709 aRect.Left() += CMD_BOX_PADDING;
710 aRect.Top() += CMD_BOX_PADDING_TOP;
711 aRect.Right() -= CMD_BOX_PADDING;
712 aRect.Bottom() -= CMD_BOX_PADDING;
714 DecorationView aView(this);
715 aRect = aView.DrawFrame(aRect, DrawFrameStyle::In, DrawFrameFlags::NoDraw);
717 aEdit->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
718 SfxDockingWindow::Resize();
719 Invalidate();
722 void SmCmdBoxWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
724 Rectangle aRect(Point(0, 0), GetOutputSizePixel());
725 aRect.Left() += CMD_BOX_PADDING;
726 aRect.Top() += CMD_BOX_PADDING_TOP;
727 aRect.Right() -= CMD_BOX_PADDING;
728 aRect.Bottom() -= CMD_BOX_PADDING;
730 aEdit->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
732 DecorationView aView(&rRenderContext);
733 aView.DrawFrame( aRect, DrawFrameStyle::In );
736 Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign)
738 switch (eAlign)
740 case SfxChildAlignment::LEFT:
741 case SfxChildAlignment::RIGHT:
742 return Size();
743 default:
744 break;
746 return SfxDockingWindow::CalcDockingSize(eAlign);
749 SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual,
750 SfxChildAlignment eWish)
752 switch (eWish)
754 case SfxChildAlignment::TOP:
755 case SfxChildAlignment::BOTTOM:
756 case SfxChildAlignment::NOALIGNMENT:
757 return eWish;
758 default:
759 break;
762 return eActual;
765 void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange )
767 if (StateChangedType::InitShow == nStateChange)
769 Resize(); // avoid SmEditWindow not being painted correctly
771 // set initial position of window in floating mode
772 if (IsFloatingMode())
773 AdjustPosition(); //! don't change pos in docking-mode !
775 aInitialFocusTimer.Start();
778 SfxDockingWindow::StateChanged( nStateChange );
781 IMPL_LINK_NOARG( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, void )
783 // We want to have the focus in the edit window once Math has been opened
784 // to allow for immediate typing.
785 // Problem: There is no proper way to do this
786 // Thus: this timer based solution has been implemented (see GrabFocus below)
788 // Follow-up problem (#i114910): grabbing the focus may bust the help system since
789 // it relies on getting the current frame which conflicts with grabbing the focus.
790 // Thus aside from the 'GrabFocus' call everything else is to get the
791 // help reliably working despite using 'GrabFocus'.
795 uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( comphelper::getProcessComponentContext() );
797 aEdit->GrabFocus();
799 bool bInPlace = GetView()->GetViewFrame()->GetFrame().IsInPlace();
800 uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface());
801 if ( bInPlace )
803 uno::Reference< container::XChild > xModel( GetView()->GetDoc()->GetModel(), uno::UNO_QUERY_THROW );
804 uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW );
805 uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() );
806 uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW );
807 xParentFrame->setActiveFrame( xFrame );
809 else
811 xDesktop->setActiveFrame( xFrame );
814 catch (uno::Exception &)
816 SAL_WARN( "starmath", "failed to properly set initial focus to edit window" );
820 void SmCmdBoxWindow::AdjustPosition()
822 Point aPt;
823 const Rectangle aRect( aPt, GetParent()->GetOutputSizePixel() );
824 Point aTopLeft( Point( aRect.Left(),
825 aRect.Bottom() - GetSizePixel().Height() ) );
826 Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) );
827 if (aPos.X() < 0)
828 aPos.X() = 0;
829 if (aPos.Y() < 0)
830 aPos.Y() = 0;
831 SetPosPixel( aPos );
834 void SmCmdBoxWindow::ToggleFloatingMode()
836 SfxDockingWindow::ToggleFloatingMode();
838 if (GetFloatingWindow())
839 GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50));
842 void SmCmdBoxWindow::GetFocus()
844 if (!bExiting)
845 aEdit->GrabFocus();
848 SFX_IMPL_DOCKINGWINDOW_WITHID(SmCmdBoxWrapper, SID_CMDBOXWINDOW);
850 SmCmdBoxWrapper::SmCmdBoxWrapper(vcl::Window *pParentWindow, sal_uInt16 nId,
851 SfxBindings *pBindings,
852 SfxChildWinInfo *pInfo) :
853 SfxChildWindow(pParentWindow, nId)
855 SetWindow(VclPtr<SmCmdBoxWindow>::Create(pBindings, this, pParentWindow));
857 // make window docked to the bottom initially (after first start)
858 SetAlignment(SfxChildAlignment::BOTTOM);
859 static_cast<SfxDockingWindow *>(GetWindow())->Initialize(pInfo);
862 struct SmViewShell_Impl
864 std::unique_ptr<sfx2::DocumentInserter> pDocInserter;
865 std::unique_ptr<SfxRequest> pRequest;
866 SvtMiscOptions aOpts;
870 SFX_IMPL_SUPERCLASS_INTERFACE(SmViewShell, SfxViewShell)
872 void SmViewShell::InitInterface_Impl()
874 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS,
875 SfxVisibilityFlags::Standard | SfxVisibilityFlags::FullScreen | SfxVisibilityFlags::Server,
876 RID_MATH_TOOLBOX);
877 //Dummy-Objectbar, to avoid quiver while activating
879 GetStaticInterface()->RegisterChildWindow(SmCmdBoxWrapper::GetChildWindowId());
880 GetStaticInterface()->RegisterChildWindow(SmElementsDockingWindowWrapper::GetChildWindowId());
883 SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default")
885 SFX_VIEW_REGISTRATION(SmDocShell);
888 void SmViewShell::AdjustPosSizePixel(const Point &rPos, const Size &rSize)
890 mpGraphic->SetPosSizePixel(rPos, rSize);
893 void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize, bool)
895 Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
896 if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
898 Size aProvidedSize = GetWindow()->PixelToLogic( rSize, MapUnit::Map100thMM );
899 SfxViewShell::SetZoomFactor( Fraction( aProvidedSize.Width(), aObjSize.Width() ),
900 Fraction( aProvidedSize.Height(), aObjSize.Height() ) );
903 SetBorderPixel( SvBorder() );
904 GetGraphicWindow().SetPosSizePixel(rOfs, rSize);
905 GetGraphicWindow().SetTotalSize();
908 void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize)
910 SmGraphicWindow &rWin = GetGraphicWindow();
911 rWin.SetPosSizePixel(rOfs, rSize);
912 if (GetDoc()->IsPreview())
913 rWin.ZoomToFitInWindow();
914 rWin.Update();
917 void SmViewShell::QueryObjAreaPixel( Rectangle& rRect ) const
919 rRect.SetSize( GetGraphicWindow().GetSizePixel() );
922 void SmViewShell::SetZoomFactor( const Fraction &rX, const Fraction &rY )
924 const Fraction &rFrac = rX < rY ? rX : rY;
925 GetGraphicWindow().SetZoom(sal::static_int_cast<sal_uInt16>(long(rFrac * Fraction( 100, 1 ))));
927 //To avoid rounding errors base class regulates crooked values too
928 //if necessary
929 SfxViewShell::SetZoomFactor( rX, rY );
932 Size SmViewShell::GetTextLineSize(OutputDevice& rDevice, const OUString& rLine)
934 Size aSize(rDevice.GetTextWidth(rLine), rDevice.GetTextHeight());
935 const long nTabPos = rLine.isEmpty() ? 0 : rDevice.approximate_char_width() * 8;
937 if (nTabPos)
939 aSize.Width() = 0;
940 sal_Int32 nPos = 0;
943 if (nPos > 0)
944 aSize.Width() = ((aSize.Width() / nTabPos) + 1) * nTabPos;
946 const OUString aText = rLine.getToken(0, '\t', nPos);
947 aSize.Width() += rDevice.GetTextWidth(aText);
949 while (nPos >= 0);
952 return aSize;
955 Size SmViewShell::GetTextSize(OutputDevice& rDevice, const OUString& rText, long MaxWidth)
957 Size aSize;
958 Size aTextSize;
959 if (rText.isEmpty())
960 return aTextSize;
962 sal_Int32 nPos = 0;
965 OUString aLine = rText.getToken(0, '\n', nPos);
966 aLine = aLine.replaceAll("\r", "");
968 aSize = GetTextLineSize(rDevice, aLine);
970 if (aSize.Width() > MaxWidth)
974 OUString aText;
975 sal_Int32 m = aLine.getLength();
976 sal_Int32 nLen = m;
978 for (sal_Int32 n = 0; n < nLen; n++)
980 sal_Unicode cLineChar = aLine[n];
981 if ((cLineChar == ' ') || (cLineChar == '\t'))
983 aText = aLine.copy(0, n);
984 if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
985 m = n;
986 else
987 break;
991 aText = aLine.copy(0, m);
992 aLine = aLine.replaceAt(0, m, "");
993 aSize = GetTextLineSize(rDevice, aText);
994 aTextSize.Height() += aSize.Height();
995 aTextSize.Width() = std::max(aTextSize.Width(), std::min(aSize.Width(), MaxWidth));
997 aLine = comphelper::string::stripStart(aLine, ' ');
998 aLine = comphelper::string::stripStart(aLine, '\t');
999 aLine = comphelper::string::stripStart(aLine, ' ');
1001 while (!aLine.isEmpty());
1003 else
1005 aTextSize.Height() += aSize.Height();
1006 aTextSize.Width() = std::max(aTextSize.Width(), aSize.Width());
1009 while (nPos >= 0);
1011 return aTextSize;
1014 void SmViewShell::DrawTextLine(OutputDevice& rDevice, const Point& rPosition, const OUString& rLine)
1016 Point aPoint(rPosition);
1017 const long nTabPos = rLine.isEmpty() ? 0 : rDevice.approximate_char_width() * 8;
1019 if (nTabPos)
1021 sal_Int32 nPos = 0;
1024 if (nPos > 0)
1025 aPoint.X() = ((aPoint.X() / nTabPos) + 1) * nTabPos;
1027 OUString aText = rLine.getToken(0, '\t', nPos);
1028 rDevice.DrawText(aPoint, aText);
1029 aPoint.X() += rDevice.GetTextWidth(aText);
1031 while ( nPos >= 0 );
1033 else
1034 rDevice.DrawText(aPoint, rLine);
1038 void SmViewShell::DrawText(OutputDevice& rDevice, const Point& rPosition, const OUString& rText, sal_uInt16 MaxWidth)
1040 if (rText.isEmpty())
1041 return;
1043 Point aPoint(rPosition);
1044 Size aSize;
1046 sal_Int32 nPos = 0;
1049 OUString aLine = rText.getToken(0, '\n', nPos);
1050 aLine = aLine.replaceAll("\r", "");
1051 aSize = GetTextLineSize(rDevice, aLine);
1052 if (aSize.Width() > MaxWidth)
1056 OUString aText;
1057 sal_Int32 m = aLine.getLength();
1058 sal_Int32 nLen = m;
1060 for (sal_Int32 n = 0; n < nLen; n++)
1062 sal_Unicode cLineChar = aLine[n];
1063 if ((cLineChar == ' ') || (cLineChar == '\t'))
1065 aText = aLine.copy(0, n);
1066 if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
1067 m = n;
1068 else
1069 break;
1072 aText = aLine.copy(0, m);
1073 aLine = aLine.replaceAt(0, m, "");
1075 DrawTextLine(rDevice, aPoint, aText);
1076 aPoint.Y() += aSize.Height();
1078 aLine = comphelper::string::stripStart(aLine, ' ');
1079 aLine = comphelper::string::stripStart(aLine, '\t');
1080 aLine = comphelper::string::stripStart(aLine, ' ');
1082 while (GetTextLineSize(rDevice, aLine).Width() > MaxWidth);
1084 // print the remaining text
1085 if (!aLine.isEmpty())
1087 DrawTextLine(rDevice, aPoint, aLine);
1088 aPoint.Y() += aSize.Height();
1091 else
1093 DrawTextLine(rDevice, aPoint, aLine);
1094 aPoint.Y() += aSize.Height();
1097 while ( nPos >= 0 );
1100 void SmViewShell::Impl_Print(OutputDevice &rOutDev, const SmPrintUIOptions &rPrintUIOptions, Rectangle aOutRect, Point aZeroPoint )
1102 const bool bIsPrintTitle = rPrintUIOptions.getBoolValue( PRTUIOPT_TITLE_ROW, true );
1103 const bool bIsPrintFrame = rPrintUIOptions.getBoolValue( PRTUIOPT_BORDER, true );
1104 const bool bIsPrintFormulaText = rPrintUIOptions.getBoolValue( PRTUIOPT_FORMULA_TEXT, true );
1105 SmPrintSize ePrintSize( static_cast< SmPrintSize >( rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_FORMAT, PRINT_SIZE_NORMAL ) ));
1106 const sal_uInt16 nZoomFactor = static_cast< sal_uInt16 >(rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_SCALE, 100 ));
1108 rOutDev.Push();
1109 rOutDev.SetLineColor( Color(COL_BLACK) );
1111 // output text on top
1112 if (bIsPrintTitle)
1114 Size aSize600 (0, 600);
1115 Size aSize650 (0, 650);
1116 vcl::Font aFont(FAMILY_DONTKNOW, aSize600);
1118 aFont.SetAlignment(ALIGN_TOP);
1119 aFont.SetWeight(WEIGHT_BOLD);
1120 aFont.SetFontSize(aSize650);
1121 aFont.SetColor( Color(COL_BLACK) );
1122 rOutDev.SetFont(aFont);
1124 Size aTitleSize (GetTextSize(rOutDev, GetDoc()->GetTitle(), aOutRect.GetWidth() - 200));
1126 aFont.SetWeight(WEIGHT_NORMAL);
1127 aFont.SetFontSize(aSize600);
1128 rOutDev.SetFont(aFont);
1130 Size aDescSize (GetTextSize(rOutDev, GetDoc()->GetComment(), aOutRect.GetWidth() - 200));
1132 if (bIsPrintFrame)
1133 rOutDev.DrawRect(Rectangle(aOutRect.TopLeft(),
1134 Size(aOutRect.GetWidth(), 100 + aTitleSize.Height() + 200 + aDescSize.Height() + 100)));
1135 aOutRect.Top() += 200;
1137 // output title
1138 aFont.SetWeight(WEIGHT_BOLD);
1139 aFont.SetFontSize(aSize650);
1140 rOutDev.SetFont(aFont);
1141 Point aPoint(aOutRect.Left() + (aOutRect.GetWidth() - aTitleSize.Width()) / 2,
1142 aOutRect.Top());
1143 DrawText(rOutDev, aPoint, GetDoc()->GetTitle(),
1144 sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1145 aOutRect.Top() += aTitleSize.Height() + 200;
1147 // output description
1148 aFont.SetWeight(WEIGHT_NORMAL);
1149 aFont.SetFontSize(aSize600);
1150 rOutDev.SetFont(aFont);
1151 aPoint.X() = aOutRect.Left() + (aOutRect.GetWidth() - aDescSize.Width()) / 2;
1152 aPoint.Y() = aOutRect.Top();
1153 DrawText(rOutDev, aPoint, GetDoc()->GetComment(),
1154 sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1155 aOutRect.Top() += aDescSize.Height() + 300;
1158 // output text on bottom
1159 if (bIsPrintFormulaText)
1161 vcl::Font aFont(FAMILY_DONTKNOW, Size(0, 600));
1162 aFont.SetAlignment(ALIGN_TOP);
1163 aFont.SetColor( Color(COL_BLACK) );
1165 // get size
1166 rOutDev.SetFont(aFont);
1168 Size aSize (GetTextSize(rOutDev, GetDoc()->GetText(), aOutRect.GetWidth() - 200));
1170 aOutRect.Bottom() -= aSize.Height() + 600;
1172 if (bIsPrintFrame)
1173 rOutDev.DrawRect(Rectangle(aOutRect.BottomLeft(),
1174 Size(aOutRect.GetWidth(), 200 + aSize.Height() + 200)));
1176 Point aPoint (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
1177 aOutRect.Bottom() + 300);
1178 DrawText(rOutDev, aPoint, GetDoc()->GetText(),
1179 sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1180 aOutRect.Bottom() -= 200;
1183 if (bIsPrintFrame)
1184 rOutDev.DrawRect(aOutRect);
1186 aOutRect.Top() += 100;
1187 aOutRect.Left() += 100;
1188 aOutRect.Bottom() -= 100;
1189 aOutRect.Right() -= 100;
1191 Size aSize (GetDoc()->GetSize());
1193 MapMode OutputMapMode;
1194 // PDF export should always use PRINT_SIZE_NORMAL ...
1195 if (!rPrintUIOptions.getBoolValue( "IsPrinter" ) )
1196 ePrintSize = PRINT_SIZE_NORMAL;
1197 switch (ePrintSize)
1199 case PRINT_SIZE_NORMAL:
1200 OutputMapMode = MapMode(MapUnit::Map100thMM);
1201 break;
1203 case PRINT_SIZE_SCALED:
1204 if ((aSize.Width() > 0) && (aSize.Height() > 0))
1206 Size OutputSize (rOutDev.LogicToPixel(Size(aOutRect.GetWidth(),
1207 aOutRect.GetHeight()), MapMode(MapUnit::Map100thMM)));
1208 Size GraphicSize (rOutDev.LogicToPixel(aSize, MapMode(MapUnit::Map100thMM)));
1209 sal_uInt16 nZ = sal::static_int_cast<sal_uInt16>(std::min(long(Fraction(OutputSize.Width() * 100L, GraphicSize.Width())),
1210 long(Fraction(OutputSize.Height() * 100L, GraphicSize.Height()))));
1211 nZ -= 10;
1212 Fraction aFraction (std::max(MINZOOM, std::min(MAXZOOM, nZ)), 100);
1214 OutputMapMode = MapMode(MapUnit::Map100thMM, aZeroPoint, aFraction, aFraction);
1216 else
1217 OutputMapMode = MapMode(MapUnit::Map100thMM);
1218 break;
1220 case PRINT_SIZE_ZOOMED:
1222 Fraction aFraction( nZoomFactor, 100 );
1224 OutputMapMode = MapMode(MapUnit::Map100thMM, aZeroPoint, aFraction, aFraction);
1225 break;
1229 aSize = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aSize, OutputMapMode),
1230 MapMode(MapUnit::Map100thMM));
1232 Point aPos (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
1233 aOutRect.Top() + (aOutRect.GetHeight() - aSize.Height()) / 2);
1235 aPos = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aPos, MapMode(MapUnit::Map100thMM)),
1236 OutputMapMode);
1237 aOutRect = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aOutRect, MapMode(MapUnit::Map100thMM)),
1238 OutputMapMode);
1240 rOutDev.SetMapMode(OutputMapMode);
1241 rOutDev.SetClipRegion(vcl::Region(aOutRect));
1242 GetDoc()->DrawFormula(rOutDev, aPos);
1243 rOutDev.SetClipRegion();
1245 rOutDev.Pop();
1248 SfxPrinter* SmViewShell::GetPrinter(bool bCreate)
1250 SmDocShell* pDoc = GetDoc();
1251 if (pDoc->HasPrinter() || bCreate)
1252 return pDoc->GetPrinter();
1253 return nullptr;
1256 sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
1258 SfxPrinter *pOld = GetDoc()->GetPrinter();
1259 if ( pOld && pOld->IsPrinting() )
1260 return SFX_PRINTERROR_BUSY;
1262 if ((nDiffFlags & SfxPrinterChangeFlags::PRINTER) == SfxPrinterChangeFlags::PRINTER)
1263 GetDoc()->SetPrinter( pNewPrinter );
1265 if ((nDiffFlags & SfxPrinterChangeFlags::OPTIONS) == SfxPrinterChangeFlags::OPTIONS)
1267 SmModule *pp = SM_MOD();
1268 pp->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions());
1270 return 0;
1273 bool SmViewShell::HasPrintOptionsPage() const
1275 return true;
1278 VclPtr<SfxTabPage> SmViewShell::CreatePrintOptionsPage(vcl::Window *pParent,
1279 const SfxItemSet &rOptions)
1281 return SmPrintOptionsTabPage::Create(pParent, rOptions);
1284 SmEditWindow *SmViewShell::GetEditWindow()
1286 SmCmdBoxWrapper* pWrapper = static_cast<SmCmdBoxWrapper*>(
1287 GetViewFrame()->GetChildWindow(SmCmdBoxWrapper::GetChildWindowId()));
1289 if (pWrapper != nullptr)
1291 SmEditWindow& rEditWin = pWrapper->GetEditWindow();
1292 return &rEditWin;
1295 return nullptr;
1298 void SmViewShell::SetStatusText(const OUString& rText)
1300 maStatusText = rText;
1301 GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS);
1304 void SmViewShell::ShowError(const SmErrorDesc* pErrorDesc)
1306 assert(GetDoc());
1307 if (pErrorDesc || nullptr != (pErrorDesc = GetDoc()->GetParser().GetError(0)) )
1309 SetStatusText( pErrorDesc->m_aText );
1310 GetEditWindow()->MarkError( Point( pErrorDesc->m_pNode->GetColumn(),
1311 pErrorDesc->m_pNode->GetRow()));
1315 void SmViewShell::NextError()
1317 assert(GetDoc());
1318 const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().NextError();
1320 if (pErrorDesc)
1321 ShowError( pErrorDesc );
1324 void SmViewShell::PrevError()
1326 assert(GetDoc());
1327 const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().PrevError();
1329 if (pErrorDesc)
1330 ShowError( pErrorDesc );
1333 void SmViewShell::Insert( SfxMedium& rMedium )
1335 SmDocShell *pDoc = GetDoc();
1336 bool bRet = false;
1338 uno::Reference <embed::XStorage> xStorage = rMedium.GetStorage();
1339 uno::Reference <container::XNameAccess> xNameAccess(xStorage, uno::UNO_QUERY);
1340 if (xNameAccess.is() && xNameAccess->getElementNames().getLength())
1342 if (xNameAccess->hasByName("content.xml") || xNameAccess->hasByName("Content.xml"))
1344 // is this a fabulous math package ?
1345 Reference<css::frame::XModel> xModel(pDoc->GetModel());
1346 SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
1347 bRet = 0 == aEquation.Import(rMedium);
1351 if (bRet)
1353 OUString aText = pDoc->GetText();
1354 SmEditWindow *pEditWin = GetEditWindow();
1355 if (pEditWin)
1356 pEditWin->InsertText( aText );
1357 else
1359 SAL_WARN( "starmath", "EditWindow missing" );
1362 pDoc->Parse();
1363 pDoc->SetModified();
1365 SfxBindings &rBnd = GetViewFrame()->GetBindings();
1366 rBnd.Invalidate(SID_GAPHIC_SM);
1367 rBnd.Invalidate(SID_TEXT);
1371 void SmViewShell::InsertFrom(SfxMedium &rMedium)
1373 bool bSuccess = false;
1374 SmDocShell* pDoc = GetDoc();
1375 SvStream* pStream = rMedium.GetInStream();
1377 if (pStream)
1379 const OUString& rFltName = rMedium.GetFilter()->GetFilterName();
1380 if ( rFltName == MATHML_XML )
1382 Reference<css::frame::XModel> xModel(pDoc->GetModel());
1383 SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
1384 bSuccess = 0 == aEquation.Import(rMedium);
1388 if (bSuccess)
1390 OUString aText = pDoc->GetText();
1391 SmEditWindow *pEditWin = GetEditWindow();
1392 if (pEditWin)
1393 pEditWin->InsertText(aText);
1394 else
1395 SAL_WARN( "starmath", "EditWindow missing" );
1397 pDoc->Parse();
1398 pDoc->SetModified();
1400 SfxBindings& rBnd = GetViewFrame()->GetBindings();
1401 rBnd.Invalidate(SID_GAPHIC_SM);
1402 rBnd.Invalidate(SID_TEXT);
1406 void SmViewShell::Execute(SfxRequest& rReq)
1408 SmEditWindow *pWin = GetEditWindow();
1410 switch (rReq.GetSlot())
1412 case SID_FORMULACURSOR:
1414 SmModule *pp = SM_MOD();
1416 const SfxItemSet *pArgs = rReq.GetArgs();
1417 const SfxPoolItem *pItem;
1419 bool bVal;
1420 if ( pArgs &&
1421 SfxItemState::SET == pArgs->GetItemState( SID_FORMULACURSOR, false, &pItem))
1422 bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
1423 else
1424 bVal = !pp->GetConfig()->IsShowFormulaCursor();
1426 pp->GetConfig()->SetShowFormulaCursor(bVal);
1427 if (!IsInlineEditEnabled())
1428 GetGraphicWindow().ShowCursor(bVal);
1429 break;
1431 case SID_DRAW:
1432 if (pWin)
1434 GetDoc()->SetText( pWin->GetText() );
1435 SetStatusText(OUString());
1436 ShowError( nullptr );
1437 GetDoc()->Repaint();
1439 break;
1441 case SID_ZOOM_OPTIMAL:
1442 mpGraphic->ZoomToFitInWindow();
1443 break;
1445 case SID_ZOOMIN:
1446 mpGraphic->SetZoom(mpGraphic->GetZoom() + 25);
1447 break;
1449 case SID_ZOOMOUT:
1450 SAL_WARN_IF( mpGraphic->GetZoom() < 25, "starmath", "incorrect sal_uInt16 argument" );
1451 mpGraphic->SetZoom(mpGraphic->GetZoom() - 25);
1452 break;
1454 case SID_COPYOBJECT:
1456 //TODO/LATER: does not work because of UNO Tunneling - will be fixed later
1457 Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY );
1458 if( xTrans.is() )
1460 Reference< lang::XUnoTunnel> xTnnl( xTrans, uno::UNO_QUERY);
1461 if( xTnnl.is() )
1463 TransferableHelper* pTrans = reinterpret_cast< TransferableHelper * >(
1464 sal::static_int_cast< sal_uIntPtr >(
1465 xTnnl->getSomething( TransferableHelper::getUnoTunnelId() )));
1466 if( pTrans )
1467 pTrans->CopyToClipboard(GetEditWindow());
1471 break;
1473 case SID_PASTEOBJECT:
1475 TransferableDataHelper aData( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) );
1476 uno::Reference < io::XInputStream > xStrm;
1477 SotClipboardFormatId nId;
1478 if( aData.GetTransferable().is() &&
1479 ( aData.HasFormat( nId = SotClipboardFormatId::EMBEDDED_OBJ ) ||
1480 (aData.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) &&
1481 aData.HasFormat( nId = SotClipboardFormatId::EMBED_SOURCE ))))
1482 xStrm = aData.GetInputStream(nId, OUString());
1484 if (xStrm.is())
1488 uno::Reference < embed::XStorage > xStorage =
1489 ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessComponentContext() );
1490 uno::Reference < beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
1491 SfxMedium aMedium( xStorage, OUString() );
1492 Insert( aMedium );
1493 GetDoc()->UpdateText();
1495 catch (uno::Exception &)
1497 SAL_WARN( "starmath", "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" );
1501 break;
1504 case SID_CUT:
1505 if (pWin)
1506 pWin->Cut();
1507 break;
1509 case SID_COPY:
1510 if (pWin)
1512 if (pWin->IsAllSelected())
1514 GetViewFrame()->GetDispatcher()->ExecuteList(
1515 SID_COPYOBJECT, SfxCallMode::RECORD,
1516 { new SfxVoidItem(SID_COPYOBJECT) });
1518 else
1519 pWin->Copy();
1521 break;
1523 case SID_PASTE:
1525 bool bCallExec = nullptr == pWin;
1526 if( !bCallExec )
1528 TransferableDataHelper aDataHelper(
1529 TransferableDataHelper::CreateFromSystemClipboard(
1530 GetEditWindow()) );
1532 if( aDataHelper.GetTransferable().is() &&
1533 aDataHelper.HasFormat( SotClipboardFormatId::STRING ))
1534 pWin->Paste();
1535 else
1536 bCallExec = true;
1538 if( bCallExec )
1540 GetViewFrame()->GetDispatcher()->ExecuteList(
1541 SID_PASTEOBJECT, SfxCallMode::RECORD,
1542 { new SfxVoidItem(SID_PASTEOBJECT) });
1545 break;
1547 case SID_DELETE:
1548 if (pWin)
1549 pWin->Delete();
1550 break;
1552 case SID_SELECT:
1553 if (pWin)
1554 pWin->SelectAll();
1555 break;
1557 case SID_INSERTCOMMAND:
1559 const SfxInt16Item& rItem =
1560 static_cast<const SfxInt16Item&>(rReq.GetArgs()->Get(SID_INSERTCOMMAND));
1562 if (pWin && (mbInsertIntoEditWindow || !IsInlineEditEnabled()))
1563 pWin->InsertCommand(rItem.GetValue());
1564 if (IsInlineEditEnabled() && (GetDoc() && !mbInsertIntoEditWindow)) {
1565 GetDoc()->GetCursor().InsertCommand(rItem.GetValue());
1566 GetGraphicWindow().GrabFocus();
1568 break;
1571 case SID_INSERTCOMMANDTEXT:
1573 const SfxStringItem& rItem = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_INSERTCOMMANDTEXT));
1575 if (pWin && (mbInsertIntoEditWindow || !IsInlineEditEnabled()))
1577 pWin->InsertText(rItem.GetValue());
1579 if (IsInlineEditEnabled() && (GetDoc() && !mbInsertIntoEditWindow))
1581 GetDoc()->GetCursor().InsertCommandText(rItem.GetValue());
1582 GetGraphicWindow().GrabFocus();
1584 break;
1588 case SID_INSERTSYMBOL:
1590 const SfxStringItem& rItem =
1591 static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_INSERTSYMBOL));
1593 if (pWin && (mbInsertIntoEditWindow || !IsInlineEditEnabled()))
1594 pWin->InsertText(rItem.GetValue());
1595 if (IsInlineEditEnabled() && (GetDoc() && !mbInsertIntoEditWindow))
1596 GetDoc()->GetCursor().InsertSpecial(rItem.GetValue());
1597 break;
1600 case SID_IMPORT_FORMULA:
1602 mpImpl->pRequest.reset(new SfxRequest( rReq ));
1603 mpImpl->pDocInserter.reset(new ::sfx2::DocumentInserter(
1604 GetDoc()->GetFactory().GetFactoryName(), false ));
1605 mpImpl->pDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl ) );
1606 break;
1609 case SID_IMPORT_MATHML_CLIPBOARD:
1611 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) );
1612 uno::Reference < io::XInputStream > xStrm;
1613 SotClipboardFormatId nId = SOT_FORMAT_SYSTEM_START; //dummy initialize to avoid warning
1614 if ( aDataHelper.GetTransferable().is() )
1616 if (aDataHelper.HasFormat(nId = SotClipboardFormatId::MATHML))
1618 xStrm = aDataHelper.GetInputStream(nId, "");
1619 if (xStrm.is())
1621 std::unique_ptr<SfxMedium> pClipboardMedium(new SfxMedium());
1622 pClipboardMedium->GetItemSet(); //generate initial itemset, not sure if necessary
1623 std::shared_ptr<const SfxFilter> pMathFilter =
1624 SfxFilter::GetFilterByName(MATHML_XML);
1625 pClipboardMedium->SetFilter(pMathFilter);
1626 pClipboardMedium->setStreamToLoadFrom(xStrm, true /*bIsReadOnly*/);
1627 InsertFrom(*pClipboardMedium);
1628 GetDoc()->UpdateText();
1631 else
1633 if (aDataHelper.HasFormat(nId = SotClipboardFormatId::STRING))
1635 // In case of FORMAT_STRING no stream exists, need to generate one
1636 ::rtl::OUString aString;
1637 if (aDataHelper.GetString( nId, aString))
1639 std::unique_ptr<SfxMedium> pClipboardMedium(new SfxMedium());
1640 pClipboardMedium->GetItemSet(); //generates initial itemset, not sure if necessary
1641 std::shared_ptr<const SfxFilter> pMathFilter =
1642 SfxFilter::GetFilterByName(MATHML_XML);
1643 pClipboardMedium->SetFilter(pMathFilter);
1645 std::unique_ptr<SvMemoryStream> pStrm;
1646 // The text to be imported might asserts encoding like 'encoding="utf-8"' but FORMAT_STRING is UTF-16.
1647 // Force encoding to UTF-16, if encoding exists.
1648 bool bForceUTF16 = false;
1649 sal_Int32 nPosL = aString.indexOf("encoding=\"");
1650 sal_Int32 nPosU = -1;
1651 if ( nPosL >= 0 && nPosL +10 < aString.getLength() )
1653 nPosL += 10;
1654 nPosU = aString.indexOf( '"',nPosL);
1655 if (nPosU > nPosL)
1657 bForceUTF16 = true;
1660 if ( bForceUTF16 )
1662 OUString aNewString = aString.replaceAt( nPosL,nPosU-nPosL,"UTF-16");
1663 pStrm.reset(new SvMemoryStream( const_cast<sal_Unicode *>(aNewString.getStr()), aNewString.getLength() * sizeof(sal_Unicode), StreamMode::READ));
1665 else
1667 pStrm.reset(new SvMemoryStream( const_cast<sal_Unicode *>(aString.getStr()), aString.getLength() * sizeof(sal_Unicode), StreamMode::READ));
1669 uno::Reference<io::XInputStream> xStrm2( new ::utl::OInputStreamWrapper(*pStrm) );
1670 pClipboardMedium->setStreamToLoadFrom(xStrm2, true /*bIsReadOnly*/);
1671 InsertFrom(*pClipboardMedium);
1672 GetDoc()->UpdateText();
1677 break;
1680 case SID_NEXTERR:
1681 NextError();
1682 if (pWin)
1683 pWin->GrabFocus();
1684 break;
1686 case SID_PREVERR:
1687 PrevError();
1688 if (pWin)
1689 pWin->GrabFocus();
1690 break;
1692 case SID_NEXTMARK:
1693 if (pWin)
1695 pWin->SelNextMark();
1696 pWin->GrabFocus();
1698 break;
1700 case SID_PREVMARK:
1701 if (pWin)
1703 pWin->SelPrevMark();
1704 pWin->GrabFocus();
1706 break;
1708 case SID_TEXTSTATUS:
1710 if (rReq.GetArgs() != nullptr)
1712 const SfxStringItem& rItem =
1713 static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_TEXTSTATUS));
1715 SetStatusText(rItem.GetValue());
1718 break;
1721 case SID_GETEDITTEXT:
1722 if (pWin)
1723 if (!pWin->GetText().isEmpty()) GetDoc()->SetText( pWin->GetText() );
1724 break;
1726 case SID_ATTR_ZOOM:
1728 if ( !GetViewFrame()->GetFrame().IsInPlace() )
1730 const SfxItemSet *pSet = rReq.GetArgs();
1731 if ( pSet )
1733 ZoomByItemSet(pSet);
1735 else
1737 SfxItemSet aSet( SmDocShell::GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
1738 aSet.Put( SvxZoomItem( SvxZoomType::PERCENT, mpGraphic->GetZoom()));
1739 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1740 if(pFact)
1742 ScopedVclPtr<AbstractSvxZoomDialog> xDlg(pFact->CreateSvxZoomDialog(&GetViewFrame()->GetWindow(), aSet));
1743 assert(xDlg);
1744 xDlg->SetLimits( MINZOOM, MAXZOOM );
1745 if (xDlg->Execute() != RET_CANCEL)
1746 ZoomByItemSet(xDlg->GetOutputItemSet());
1751 break;
1753 case SID_ATTR_ZOOMSLIDER:
1755 const SfxItemSet *pArgs = rReq.GetArgs();
1756 const SfxPoolItem* pItem;
1758 if ( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMSLIDER, true, &pItem ) )
1760 const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue();
1761 mpGraphic->SetZoom( nCurrentZoom );
1764 break;
1766 case SID_ELEMENTSDOCKINGWINDOW:
1768 GetViewFrame()->ToggleChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() );
1769 GetViewFrame()->GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW );
1771 rReq.Ignore ();
1773 break;
1775 case SID_UNICODE_NOTATION_TOGGLE:
1777 EditEngine* pEditEngine = nullptr;
1778 if( pWin )
1779 pEditEngine = pWin->GetEditEngine();
1781 EditView* pEditView = nullptr;
1782 if( pEditEngine )
1783 pEditView = pEditEngine->GetView();
1785 if( pEditView )
1787 const OUString sInput = pEditView->GetSurroundingText();
1788 ESelection aSel( pWin->GetSelection() );
1790 if ( aSel.nStartPos > aSel.nEndPos )
1791 aSel.nEndPos = aSel.nStartPos;
1793 //calculate a valid end-position by reading logical characters
1794 sal_Int32 nUtf16Pos=0;
1795 while( (nUtf16Pos < sInput.getLength()) && (nUtf16Pos < aSel.nEndPos) )
1797 sInput.iterateCodePoints(&nUtf16Pos);
1798 if( nUtf16Pos > aSel.nEndPos )
1799 aSel.nEndPos = nUtf16Pos;
1802 ToggleUnicodeCodepoint aToggle;
1803 while( nUtf16Pos && aToggle.AllowMoreInput( sInput[nUtf16Pos-1]) )
1804 --nUtf16Pos;
1805 const OUString sReplacement = aToggle.ReplacementString();
1806 if( !sReplacement.isEmpty() )
1808 pEditView->SetSelection( aSel );
1809 pEditEngine->UndoActionStart(EDITUNDO_REPLACEALL);
1810 aSel.nStartPos = aSel.nEndPos - aToggle.StringToReplace().getLength();
1811 pWin->SetSelection( aSel );
1812 pEditView->InsertText( sReplacement, true );
1813 pEditEngine->UndoActionEnd(EDITUNDO_REPLACEALL);
1814 pWin->Flush();
1818 break;
1820 case SID_SYMBOLS_CATALOGUE:
1823 // get device used to retrieve the FontList
1824 SmDocShell *pDoc = GetDoc();
1825 OutputDevice *pDev = pDoc->GetPrinter();
1826 if (!pDev || pDev->GetDevFontCount() == 0)
1827 pDev = &SM_MOD()->GetDefaultVirtualDev();
1828 SAL_WARN_IF( !pDev, "starmath", "device for font list missing" );
1830 SmModule *pp = SM_MOD();
1831 ScopedVclPtrInstance<SmSymbolDialog>( nullptr, pDev, pp->GetSymbolManager(), *this )->Execute();
1833 break;
1835 rReq.Done();
1839 void SmViewShell::GetState(SfxItemSet &rSet)
1841 SfxWhichIter aIter(rSet);
1843 SmEditWindow *pEditWin = GetEditWindow();
1844 for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich())
1846 switch (nWh)
1848 case SID_CUT:
1849 case SID_COPY:
1850 case SID_DELETE:
1851 if (! pEditWin || ! pEditWin->IsSelected())
1852 rSet.DisableItem(nWh);
1853 break;
1855 case SID_PASTE:
1856 if (pEditWin)
1858 TransferableDataHelper aDataHelper(
1859 TransferableDataHelper::CreateFromSystemClipboard(
1860 pEditWin) );
1862 mbPasteState = aDataHelper.GetTransferable().is() &&
1863 ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) ||
1864 aDataHelper.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ ) ||
1865 (aDataHelper.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR )
1866 && aDataHelper.HasFormat( SotClipboardFormatId::EMBED_SOURCE )));
1868 if( !mbPasteState )
1869 rSet.DisableItem( nWh );
1870 break;
1872 case SID_ATTR_ZOOM:
1873 rSet.Put(SvxZoomItem( SvxZoomType::PERCENT, mpGraphic->GetZoom()));
1874 SAL_FALLTHROUGH;
1875 case SID_ZOOMIN:
1876 case SID_ZOOMOUT:
1877 case SID_ZOOM_OPTIMAL:
1878 if ( GetViewFrame()->GetFrame().IsInPlace() )
1879 rSet.DisableItem( nWh );
1880 break;
1882 case SID_ATTR_ZOOMSLIDER :
1884 const sal_uInt16 nCurrentZoom = mpGraphic->GetZoom();
1885 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM );
1886 aZoomSliderItem.AddSnappingPoint( 100 );
1887 rSet.Put( aZoomSliderItem );
1889 break;
1891 case SID_NEXTERR:
1892 case SID_PREVERR:
1893 case SID_NEXTMARK:
1894 case SID_PREVMARK:
1895 case SID_DRAW:
1896 case SID_SELECT:
1897 if (! pEditWin || pEditWin->IsEmpty())
1898 rSet.DisableItem(nWh);
1899 break;
1901 case SID_TEXTSTATUS:
1903 rSet.Put(SfxStringItem(nWh, maStatusText));
1905 break;
1907 case SID_FORMULACURSOR:
1909 SmModule *pp = SM_MOD();
1910 rSet.Put(SfxBoolItem(nWh, pp->GetConfig()->IsShowFormulaCursor()));
1912 break;
1913 case SID_ELEMENTSDOCKINGWINDOW:
1915 bool bState = false;
1916 SfxChildWindow *pChildWnd = GetViewFrame()->
1917 GetChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() );
1918 if (pChildWnd && pChildWnd->GetWindow()->IsVisible())
1919 bState = true;
1920 rSet.Put(SfxBoolItem(SID_ELEMENTSDOCKINGWINDOW, bState));
1922 break;
1927 SmViewShell::SmViewShell(SfxViewFrame *pFrame_, SfxViewShell *)
1928 : SfxViewShell(pFrame_, SfxViewShellFlags::HAS_PRINTOPTIONS | SfxViewShellFlags::CAN_PRINT)
1929 , mpImpl(new SmViewShell_Impl)
1930 , mpGraphic(VclPtr<SmGraphicWindow>::Create(this))
1931 , maGraphicController(*mpGraphic.get(), SID_GAPHIC_SM, pFrame_->GetBindings())
1932 , mbPasteState(false)
1933 , mbInsertIntoEditWindow(false)
1935 SetStatusText(OUString());
1936 SetWindow(mpGraphic.get());
1937 SfxShell::SetName("SmView");
1938 SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() );
1939 SetHelpId( HID_SMA_VIEWSHELL_DOCUMENT );
1943 SmViewShell::~SmViewShell()
1945 //!! this view shell is not active anymore !!
1946 // Thus 'SmGetActiveView' will give a 0 pointer.
1947 // Thus we need to supply this view as argument
1948 SmEditWindow *pEditWin = GetEditWindow();
1949 if (pEditWin)
1950 pEditWin->DeleteEditView( *this );
1951 mpGraphic.disposeAndClear();
1954 void SmViewShell::Deactivate( bool bIsMDIActivate )
1956 SmEditWindow *pEdit = GetEditWindow();
1957 if ( pEdit )
1958 pEdit->Flush();
1960 SfxViewShell::Deactivate( bIsMDIActivate );
1963 void SmViewShell::Activate( bool bIsMDIActivate )
1965 SfxViewShell::Activate( bIsMDIActivate );
1967 SmEditWindow *pEdit = GetEditWindow();
1968 if ( pEdit )
1970 //! Since there is no way to be informed if a "drag and drop"
1971 //! event has taken place, we call SetText here in order to
1972 //! synchronize the GraphicWindow display with the text in the
1973 //! EditEngine.
1974 SmDocShell *pDoc = GetDoc();
1975 pDoc->SetText( pDoc->GetEditEngine().GetText() );
1977 if ( bIsMDIActivate )
1978 pEdit->GrabFocus();
1982 IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
1984 assert(_pFileDlg && "SmViewShell::DialogClosedHdl(): no file dialog");
1985 assert(mpImpl->pDocInserter && "ScDocShell::DialogClosedHdl(): no document inserter");
1987 if ( ERRCODE_NONE == _pFileDlg->GetError() )
1989 SfxMedium* pMedium = mpImpl->pDocInserter->CreateMedium();
1991 if ( pMedium != nullptr )
1993 if ( pMedium->IsStorage() )
1994 Insert( *pMedium );
1995 else
1996 InsertFrom( *pMedium );
1997 delete pMedium;
1999 SmDocShell* pDoc = GetDoc();
2000 pDoc->UpdateText();
2001 pDoc->ArrangeFormula();
2002 pDoc->Repaint();
2003 // adjust window, repaint, increment ModifyCount,...
2004 GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM);
2008 mpImpl->pRequest->SetReturnValue( SfxBoolItem( mpImpl->pRequest->GetSlot(), true ) );
2009 mpImpl->pRequest->Done();
2012 void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint )
2014 switch( rHint.GetId() )
2016 case SfxHintId::ModeChanged:
2017 case SfxHintId::DocChanged:
2018 GetViewFrame()->GetBindings().InvalidateAll(false);
2019 break;
2020 default:
2021 break;
2025 bool SmViewShell::IsInlineEditEnabled() const
2027 return mpImpl->aOpts.IsExperimentalMode();
2030 void SmViewShell::ZoomByItemSet(const SfxItemSet *pSet)
2032 assert(pSet);
2033 const SvxZoomItem &rZoom = static_cast<const SvxZoomItem &>(pSet->Get(SID_ATTR_ZOOM));
2034 switch( rZoom.GetType() )
2036 case SvxZoomType::PERCENT:
2037 mpGraphic->SetZoom(sal::static_int_cast<sal_uInt16>(rZoom.GetValue ()));
2038 break;
2040 case SvxZoomType::OPTIMAL:
2041 mpGraphic->ZoomToFitInWindow();
2042 break;
2044 case SvxZoomType::PAGEWIDTH:
2045 case SvxZoomType::WHOLEPAGE:
2047 const MapMode aMap( MapUnit::Map100thMM );
2048 SfxPrinter *pPrinter = GetPrinter( true );
2049 Point aPoint;
2050 Rectangle OutputRect(aPoint, pPrinter->GetOutputSize());
2051 Size OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(),
2052 OutputRect.GetHeight()), aMap));
2053 Size GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap));
2054 sal_uInt16 nZ = sal::static_int_cast<sal_uInt16>(std::min(long(Fraction(OutputSize.Width() * 100L, GraphicSize.Width())),
2055 long(Fraction(OutputSize.Height() * 100L, GraphicSize.Height()))));
2056 mpGraphic->SetZoom (nZ);
2057 break;
2059 default:
2060 break;
2064 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */