1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sfx2/app.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/docfilt.hxx>
36 #include <sfx2/docinsert.hxx>
37 #include <sfx2/filedlghelper.hxx>
38 #include <sfx2/msg.hxx>
39 #include <sfx2/objface.hxx>
40 #include <sfx2/printer.hxx>
41 #include <sfx2/request.hxx>
42 #include <svl/eitem.hxx>
43 #include <svl/intitem.hxx>
44 #include <svl/itemset.hxx>
45 #include <svl/poolitem.hxx>
46 #include <svl/ptitem.hxx>
47 #include <svl/stritem.hxx>
48 #include <svtools/transfer.hxx>
49 #include <svtools/miscopt.hxx>
50 #include <svl/undo.hxx>
51 #include <svl/whiter.hxx>
52 #include <svx/dialogs.hrc>
53 #include <svx/zoomslideritem.hxx>
54 #include <editeng/editeng.hxx>
55 #include <svx/svxdlg.hxx>
56 #include <sfx2/zoomitem.hxx>
57 #include <vcl/decoview.hxx>
58 #include <vcl/menu.hxx>
59 #include <vcl/msgbox.hxx>
60 #include <vcl/wrkwin.hxx>
61 #include <vcl/settings.hxx>
65 #include "unomodel.hxx"
69 #include "document.hxx"
70 #include "starmath.hrc"
71 #include "mathmlimport.hxx"
73 #include "accessibility.hxx"
74 #include "ElementsDockingWindow.hxx"
80 // space around the edit window, in pixels
81 // fdo#69111: Increased border on the top so that the window is
82 // easier to tear off.
83 #define CMD_BOX_PADDING 4
84 #define CMD_BOX_PADDING_TOP 10
87 #include "smslots.hxx"
90 using namespace css::accessibility
;
91 using namespace css::uno
;
93 SmGraphicWindow::SmGraphicWindow(SmViewShell
* pShell
)
94 : ScrollableWindow(&pShell
->GetViewFrame()->GetWindow(), 0)
99 // docking windows are usually hidden (often already done in the
100 // resource) and will be shown by the sfx framework.
103 const Fraction
aFraction(1, 1);
104 SetMapMode(MapMode(MAP_100TH_MM
, Point(), aFraction
, aFraction
));
108 SetHelpId(HID_SMA_WIN_DOCUMENT
);
109 SetUniqueId(HID_SMA_WIN_DOCUMENT
);
115 SmGraphicWindow::~SmGraphicWindow()
120 void SmGraphicWindow::dispose()
123 pAccessible
->ClearWin(); // make Accessible defunctional
124 // Note: memory for pAccessible will be freed when the reference
125 // xAccessible is released.
127 ScrollableWindow::dispose();
130 void SmGraphicWindow::StateChanged(StateChangedType eType
)
132 if (eType
== StateChangedType::InitShow
)
134 ScrollableWindow::StateChanged(eType
);
138 void SmGraphicWindow::ApplyColorConfigValues(const svtools::ColorConfig
&rColorCfg
)
140 // Note: SetTextColor not necessary since the nodes that
141 // get painted have the color information.
142 #if OSL_DEBUG_LEVEL > 1
143 // ColorData nVal = rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor;
145 SetBackground(Color( (ColorData
) rColorCfg
.GetColorValue(svtools::DOCCOLOR
).nColor
));
149 void SmGraphicWindow::DataChanged( const DataChangedEvent
& rEvt
)
151 ScrollableWindow::DataChanged( rEvt
);
155 void SmGraphicWindow::MouseButtonDown(const MouseEvent
& rMEvt
)
157 ScrollableWindow::MouseButtonDown(rMEvt
);
161 // set formula-cursor and selection of edit window according to the
162 // position clicked at
164 SAL_WARN_IF( rMEvt
.GetClicks() == 0, "starmath", "0 clicks" );
165 if ( rMEvt
.IsLeft() )
167 // get click position relativ to formula
168 Point
aPos (PixelToLogic(rMEvt
.GetPosPixel())
169 - GetFormulaDrawPos());
171 const SmNode
*pTree
= pViewShell
->GetDoc()->GetFormulaTree();
175 if (IsInlineEditEnabled()) {
176 pViewShell
->GetDoc()->GetCursor().MoveTo(this, aPos
, !rMEvt
.IsShift());
179 const SmNode
*pNode
= 0;
180 // if it was clicked inside the formula then get the appropriate node
181 if (pTree
->OrientedDist(aPos
) <= 0)
182 pNode
= pTree
->FindRectClosestTo(aPos
);
185 { SmEditWindow
*pEdit
= pViewShell
->GetEditWindow();
188 const SmToken
aToken (pNode
->GetToken());
190 // set selection to the beginning of the token
191 ESelection
aSel (aToken
.nRow
- 1, aToken
.nCol
- 1);
193 if (rMEvt
.GetClicks() != 1 || aToken
.eType
== TPLACE
)
194 aSel
.nEndPos
= aSel
.nEndPos
+ sal::static_int_cast
< sal_uInt16
>(aToken
.aText
.getLength());
196 pEdit
->SetSelection(aSel
);
199 // allow for immediate editing and
200 //! implicitly synchronize the cursor position mark in this window
206 void SmGraphicWindow::MouseMove(const MouseEvent
&rMEvt
)
208 ScrollableWindow::MouseMove(rMEvt
);
210 if (rMEvt
.IsLeft() && IsInlineEditEnabled())
212 Point
aPos(PixelToLogic(rMEvt
.GetPosPixel()) - GetFormulaDrawPos());
213 pViewShell
->GetDoc()->GetCursor().MoveTo(this, aPos
, false);
216 SetIsCursorVisible(true);
218 RepaintViewShellDoc();
222 bool SmGraphicWindow::IsInlineEditEnabled() const
224 return pViewShell
->IsInlineEditEnabled();
227 void SmGraphicWindow::GetFocus()
229 if (!IsInlineEditEnabled())
231 if (pViewShell
->GetEditWindow())
232 pViewShell
->GetEditWindow()->Flush();
233 //Let view shell know what insertions should be done in visual editor
234 pViewShell
->SetInsertIntoEditWindow(false);
235 SetIsCursorVisible(true);
238 RepaintViewShellDoc();
241 void SmGraphicWindow::LoseFocus()
243 ScrollableWindow::LoseFocus();
244 if (xAccessible
.is())
246 uno::Any aOldValue
, aNewValue
;
247 aOldValue
<<= AccessibleStateType::FOCUSED
;
248 // aNewValue remains empty
249 pAccessible
->LaunchEvent( AccessibleEventId::STATE_CHANGED
,
250 aOldValue
, aNewValue
);
252 if (!IsInlineEditEnabled())
254 SetIsCursorVisible(false);
257 RepaintViewShellDoc();
260 void SmGraphicWindow::RepaintViewShellDoc()
262 SmDocShell
* pDoc
= pViewShell
->GetDoc();
267 IMPL_LINK_NOARG_TYPED(SmGraphicWindow
, CaretBlinkTimerHdl
, Timer
*, void)
269 if (IsCursorVisible())
270 SetIsCursorVisible(false);
272 SetIsCursorVisible(true);
274 RepaintViewShellDoc();
277 void SmGraphicWindow::CaretBlinkInit()
279 aCaretBlinkTimer
.SetTimeoutHdl(LINK(this, SmGraphicWindow
, CaretBlinkTimerHdl
));
280 aCaretBlinkTimer
.SetTimeout( ScrollableWindow::GetSettings().GetStyleSettings().GetCursorBlinkTime() );
283 void SmGraphicWindow::CaretBlinkStart()
285 if (!IsInlineEditEnabled())
287 if (aCaretBlinkTimer
.GetTimeout() != STYLE_CURSOR_NOBLINKTIME
)
288 aCaretBlinkTimer
.Start();
291 void SmGraphicWindow::CaretBlinkStop()
293 if (!IsInlineEditEnabled())
295 aCaretBlinkTimer
.Stop();
298 void SmGraphicWindow::ShowCursor(bool bShow
)
299 // shows or hides the formula-cursor depending on 'bShow' is true or not
301 if (IsInlineEditEnabled())
304 bool bInvert
= bShow
!= IsCursorVisible();
307 InvertTracking(aCursorRect
, SHOWTRACK_SMALL
| SHOWTRACK_WINDOW
);
309 SetIsCursorVisible(bShow
);
312 void SmGraphicWindow::ShowLine(bool bShow
)
314 if (!IsInlineEditEnabled())
317 bIsLineVisible
= bShow
;
320 void SmGraphicWindow::SetCursor(const SmNode
*pNode
)
322 if (IsInlineEditEnabled())
325 const SmNode
*pTree
= pViewShell
->GetDoc()->GetFormulaTree();
327 // get appropriate rectangle
328 Point
aOffset (pNode
->GetTopLeft() - pTree
->GetTopLeft()),
329 aTLPos (GetFormulaDrawPos() + aOffset
);
330 aTLPos
.X() -= pNode
->GetItalicLeftSpace();
331 Size
aSize (pNode
->GetItalicSize());
333 SetCursor(Rectangle(aTLPos
, aSize
));
336 void SmGraphicWindow::SetCursor(const Rectangle
&rRect
)
337 // sets cursor to new position (rectangle) 'rRect'.
338 // The old cursor will be removed, and the new one will be shown if
339 // that is activated in the ConfigItem
341 if (IsInlineEditEnabled())
344 SmModule
*pp
= SM_MOD();
346 if (IsCursorVisible())
347 ShowCursor(false); // clean up remainings of old cursor
349 if (pp
->GetConfig()->IsShowFormulaCursor())
350 ShowCursor(true); // draw new cursor
353 const SmNode
* SmGraphicWindow::SetCursorPos(sal_uInt16 nRow
, sal_uInt16 nCol
)
354 // looks for a VISIBLE node in the formula tree with it's token at
355 // (or around) the position 'nRow', 'nCol' in the edit window
356 // (row and column numbering starts with 1 there!).
357 // If there is such a node the formula-cursor is set to cover that nodes
358 // rectangle. If not the formula-cursor will be hidden.
359 // In any case the search result is being returned.
361 if (IsInlineEditEnabled())
364 // find visible node with token at nRow, nCol
365 const SmNode
*pTree
= pViewShell
->GetDoc()->GetFormulaTree(),
368 pNode
= pTree
->FindTokenAt(nRow
, nCol
);
378 void SmGraphicWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
&)
380 SAL_WARN_IF(!pViewShell
, "starmath", "view shell missing");
382 ApplyColorConfigValues(SM_MOD()->GetColorConfig());
384 SmDocShell
& rDoc
= *pViewShell
->GetDoc();
387 rDoc
.DrawFormula(rRenderContext
, aPoint
, true); //! modifies aPoint to be the topleft
388 //! corner of the formula
389 SetFormulaDrawPos(aPoint
);
390 if (IsInlineEditEnabled())
392 //Draw cursor if any...
393 if (pViewShell
->GetDoc()->HasCursor() && IsLineVisible())
394 pViewShell
->GetDoc()->GetCursor().Draw(rRenderContext
, aPoint
, IsCursorVisible());
398 SetIsCursorVisible(false); // (old) cursor must be drawn again
400 const SmEditWindow
* pEdit
= pViewShell
->GetEditWindow();
402 { // get new position for formula-cursor (for possible altered formula)
405 SmGetLeftSelectionPart(pEdit
->GetSelection(), nRow
, nCol
);
408 const SmNode
*pFound
= SetCursorPos(static_cast<sal_uInt16
>(nRow
), nCol
);
410 SmModule
*pp
= SM_MOD();
411 if (pFound
&& pp
->GetConfig()->IsShowFormulaCursor())
418 void SmGraphicWindow::SetTotalSize ()
420 SmDocShell
&rDoc
= *pViewShell
->GetDoc();
421 const Size
aTmp( PixelToLogic( LogicToPixel( rDoc
.GetSize() )));
422 if ( aTmp
!= ScrollableWindow::GetTotalSize() )
423 ScrollableWindow::SetTotalSize( aTmp
);
426 void SmGraphicWindow::KeyInput(const KeyEvent
& rKEvt
)
428 if (!IsInlineEditEnabled()) {
429 if (! (GetView() && GetView()->KeyInput(rKEvt
)) )
430 ScrollableWindow::KeyInput(rKEvt
);
434 SmCursor
& rCursor
= pViewShell
->GetDoc()->GetCursor();
435 KeyFuncType eFunc
= rKEvt
.GetKeyCode().GetFunction();
436 if (eFunc
== KeyFuncType::COPY
)
438 else if (eFunc
== KeyFuncType::CUT
)
440 else if (eFunc
== KeyFuncType::PASTE
)
443 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
448 rCursor
.Move(this, MoveLeft
, !rKEvt
.GetKeyCode().IsShift());
452 rCursor
.Move(this, MoveRight
, !rKEvt
.GetKeyCode().IsShift());
456 rCursor
.Move(this, MoveUp
, !rKEvt
.GetKeyCode().IsShift());
460 rCursor
.Move(this, MoveDown
, !rKEvt
.GetKeyCode().IsShift());
464 if(!rKEvt
.GetKeyCode().IsShift())
466 #ifdef DEBUG_ENABLE_DUMPASDOT
468 SmNode
*pTree
= (SmNode
*)pViewShell
->GetDoc()->GetFormulaTree();
469 std::fstream
file("/tmp/smath-dump.gv", std::fstream::out
);
470 OUString
label(pViewShell
->GetDoc()->GetText());
471 pTree
->DumpAsDot(file
, &label
);
474 #endif /* DEBUG_ENABLE_DUMPASDOT */
478 if(!rCursor
.HasSelection()){
479 rCursor
.Move(this, MoveRight
, false);
480 if(rCursor
.HasComplexSelection()) break;
486 rCursor
.DeletePrev(this);
489 rCursor
.InsertElement(PlusElement
);
492 if(rKEvt
.GetKeyCode().IsShift())
493 rCursor
.InsertSubSup(RSUB
);
495 rCursor
.InsertElement(MinusElement
);
498 rCursor
.InsertElement(CDotElement
);
501 rCursor
.InsertFraction();
504 rCursor
.InsertElement(LessThanElement
);
507 rCursor
.InsertElement(GreaterThanElement
);
510 rCursor
.InsertElement(EqualElement
);
514 sal_Unicode code
= rKEvt
.GetCharCode();
515 SmBraceNode
* pBraceNode
= NULL
;
518 rCursor
.InsertElement(BlankElement
);
519 }else if(code
== '^') {
520 rCursor
.InsertSubSup(RSUP
);
521 }else if(code
== '(') {
522 rCursor
.InsertBrackets(RoundBrackets
);
523 }else if(code
== '[') {
524 rCursor
.InsertBrackets(SquareBrackets
);
525 }else if(code
== '{') {
526 rCursor
.InsertBrackets(CurlyBrackets
);
527 }else if(code
== '!') {
528 rCursor
.InsertElement(FactorialElement
);
529 }else if(code
== '%') {
530 rCursor
.InsertElement(PercentElement
);
531 }else if(code
== ')' && rCursor
.IsAtTailOfBracket(RoundBrackets
, &pBraceNode
)) {
532 rCursor
.MoveAfterBracket(pBraceNode
);
533 }else if(code
== ']' && rCursor
.IsAtTailOfBracket(SquareBrackets
, &pBraceNode
)) {
534 rCursor
.MoveAfterBracket(pBraceNode
);
535 }else if(code
== '}' && rCursor
.IsAtTailOfBracket(CurlyBrackets
, &pBraceNode
)) {
536 rCursor
.MoveAfterBracket(pBraceNode
);
539 rCursor
.InsertText(OUString(code
));
540 }else if (! (GetView() && GetView()->KeyInput(rKEvt
)) )
541 ScrollableWindow::KeyInput(rKEvt
);
548 SetIsCursorVisible(true);
549 RepaintViewShellDoc();
553 void SmGraphicWindow::Command(const CommandEvent
& rCEvt
)
555 bool bCallBase
= true;
556 if ( !pViewShell
->GetViewFrame()->GetFrame().IsInPlace() )
558 switch ( rCEvt
.GetCommand() )
560 case CommandEventId::ContextMenu
:
562 GetParent()->ToTop();
563 SmResId
aResId( RID_VIEWMENU
);
564 std::unique_ptr
<PopupMenu
> xPopupMenu(new PopupMenu(aResId
));
565 xPopupMenu
->SetSelectHdl(LINK(this, SmGraphicWindow
, MenuSelectHdl
));
567 if (rCEvt
.IsMouseEvent())
568 aPos
= rCEvt
.GetMousePosPixel();
569 SAL_WARN_IF( !pViewShell
, "starmath", "view shell missing" );
571 // added for replaceability of context menus
572 pViewShell
->GetViewFrame()->GetBindings().GetDispatcher()
573 ->ExecutePopup( aResId
, this, &aPos
);
579 case CommandEventId::Wheel
:
581 const CommandWheelData
* pWData
= rCEvt
.GetWheelData();
582 if ( pWData
&& CommandWheelMode::ZOOM
== pWData
->GetMode() )
584 sal_uInt16 nTmpZoom
= GetZoom();
585 if( 0L > pWData
->GetDelta() )
599 ScrollableWindow::Command (rCEvt
);
603 IMPL_LINK( SmGraphicWindow
, MenuSelectHdl
, Menu
*, pMenu
)
605 SmViewShell
*pViewSh
= GetView();
607 pViewSh
->GetViewFrame()->GetDispatcher()->Execute( pMenu
->GetCurItemId() );
611 void SmGraphicWindow::SetZoom(sal_uInt16 Factor
)
613 nZoom
= std::min(std::max((sal_uInt16
) Factor
, (sal_uInt16
) MINZOOM
), (sal_uInt16
) MAXZOOM
);
614 Fraction
aFraction (nZoom
, 100);
615 SetMapMode( MapMode(MAP_100TH_MM
, Point(), aFraction
, aFraction
) );
617 SmViewShell
*pViewSh
= GetView();
620 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM
);
621 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER
);
627 void SmGraphicWindow::ZoomToFitInWindow()
629 SmDocShell
&rDoc
= *pViewShell
->GetDoc();
631 // set defined mapmode before calling 'LogicToPixel' below
632 SetMapMode(MapMode(MAP_100TH_MM
));
634 Size
aSize (LogicToPixel(rDoc
.GetSize()));
635 Size
aWindowSize (GetSizePixel());
637 if (aSize
.Width() > 0 && aSize
.Height() > 0)
639 long nVal
= std::min ((85 * aWindowSize
.Width()) / aSize
.Width(),
640 (85 * aWindowSize
.Height()) / aSize
.Height());
641 SetZoom ( sal::static_int_cast
< sal_uInt16
>(nVal
) );
645 uno::Reference
< XAccessible
> SmGraphicWindow::CreateAccessible()
649 pAccessible
= new SmGraphicAccessible( this );
650 xAccessible
= pAccessible
;
655 /**************************************************************************/
658 SmGraphicController::SmGraphicController(SmGraphicWindow
&rSmGraphic
,
660 SfxBindings
&rBindings
) :
661 SfxControllerItem(nId_
, rBindings
),
667 void SmGraphicController::StateChanged(sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
669 rGraphic
.SetTotalSize();
670 rGraphic
.Invalidate();
671 SfxControllerItem::StateChanged (nSID
, eState
, pState
);
675 /**************************************************************************/
678 SmEditController::SmEditController(SmEditWindow
&rSmEdit
,
680 SfxBindings
&rBindings
) :
681 SfxControllerItem(nId_
, rBindings
),
687 #if OSL_DEBUG_LEVEL > 1
688 SmEditController::~SmEditController()
694 void SmEditController::StateChanged(sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
696 const SfxStringItem
*pItem
= PTR_CAST(SfxStringItem
, pState
);
698 if ((pItem
!= NULL
) && (rEdit
.GetText() != OUString(pItem
->GetValue())))
699 rEdit
.SetText(pItem
->GetValue());
700 SfxControllerItem::StateChanged (nSID
, eState
, pState
);
703 /**************************************************************************/
704 SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings
*pBindings_
, SfxChildWindow
*pChildWindow
,
705 vcl::Window
*pParent
) :
706 SfxDockingWindow(pBindings_
, pChildWindow
, pParent
, WB_MOVEABLE
|WB_CLOSEABLE
|WB_SIZEABLE
|WB_DOCKABLE
),
707 aEdit (VclPtr
<SmEditWindow
>::Create(*this)),
708 aController (*(aEdit
.get()), SID_TEXT
, *pBindings_
),
711 SetHelpId( HID_SMA_COMMAND_WIN
);
712 SetSizePixel(LogicToPixel(Size(292 , 94), MapMode(MAP_APPFONT
)));
713 SetText(SM_RESSTR(STR_CMDBOXWINDOW
));
717 aInitialFocusTimer
.SetTimeoutHdl(LINK(this, SmCmdBoxWindow
, InitialFocusTimerHdl
));
718 aInitialFocusTimer
.SetTimeout(100);
721 SmCmdBoxWindow::~SmCmdBoxWindow ()
726 void SmCmdBoxWindow::dispose()
728 aInitialFocusTimer
.Stop();
730 aController
.dispose();
731 aEdit
.disposeAndClear();
732 SfxDockingWindow::dispose();
735 SmViewShell
* SmCmdBoxWindow::GetView()
737 SfxDispatcher
*pDispatcher
= GetBindings().GetDispatcher();
738 SfxViewShell
*pView
= pDispatcher
? pDispatcher
->GetFrame()->GetViewShell() : NULL
;
739 return PTR_CAST(SmViewShell
, pView
);
742 void SmCmdBoxWindow::Resize()
744 Rectangle
aRect(Point(0, 0), GetOutputSizePixel());
745 aRect
.Left() += CMD_BOX_PADDING
;
746 aRect
.Top() += CMD_BOX_PADDING_TOP
;
747 aRect
.Right() -= CMD_BOX_PADDING
;
748 aRect
.Bottom() -= CMD_BOX_PADDING
;
750 DecorationView
aView(this);
751 aRect
= aView
.DrawFrame(aRect
, DrawFrameStyle::In
, DrawFrameFlags::NoDraw
);
753 aEdit
->SetPosSizePixel(aRect
.TopLeft(), aRect
.GetSize());
754 SfxDockingWindow::Resize();
758 void SmCmdBoxWindow::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& /*rRect*/)
760 Rectangle
aRect(Point(0, 0), GetOutputSizePixel());
761 aRect
.Left() += CMD_BOX_PADDING
;
762 aRect
.Top() += CMD_BOX_PADDING_TOP
;
763 aRect
.Right() -= CMD_BOX_PADDING
;
764 aRect
.Bottom() -= CMD_BOX_PADDING
;
766 aEdit
->SetPosSizePixel(aRect
.TopLeft(), aRect
.GetSize());
768 DecorationView
aView(&rRenderContext
);
769 aView
.DrawFrame( aRect
, DrawFrameStyle::In
);
772 Size
SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign
)
776 case SfxChildAlignment::LEFT
:
777 case SfxChildAlignment::RIGHT
:
782 return SfxDockingWindow::CalcDockingSize(eAlign
);
785 SfxChildAlignment
SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual
,
786 SfxChildAlignment eWish
)
790 case SfxChildAlignment::TOP
:
791 case SfxChildAlignment::BOTTOM
:
792 case SfxChildAlignment::NOALIGNMENT
:
801 void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange
)
803 if (StateChangedType::InitShow
== nStateChange
)
805 Resize(); // avoid SmEditWindow not being painted correctly
807 // set initial position of window in floating mode
808 if (IsFloatingMode())
809 AdjustPosition(); //! don't change pos in docking-mode !
811 aInitialFocusTimer
.Start();
814 SfxDockingWindow::StateChanged( nStateChange
);
817 IMPL_LINK_NOARG_TYPED( SmCmdBoxWindow
, InitialFocusTimerHdl
, Timer
*, void )
819 // We want to have the focus in the edit window once Math has been opened
820 // to allow for immediate typing.
821 // Problem: There is no proper way to do this
822 // Thus: this timer based solution has been implemented (see GrabFocus below)
824 // Follow-up problem (#i114910): grabing the focus may bust the help system since
825 // it relies on getting the current frame which conflicts with grabbing the focus.
826 // Thus aside from the 'GrabFocus' call everything else is to get the
827 // help reliably working despite using 'GrabFocus'.
831 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create( comphelper::getProcessComponentContext() );
835 bool bInPlace
= GetView()->GetViewFrame()->GetFrame().IsInPlace();
836 uno::Reference
< frame::XFrame
> xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface());
839 uno::Reference
< container::XChild
> xModel( GetView()->GetDoc()->GetModel(), uno::UNO_QUERY_THROW
);
840 uno::Reference
< frame::XModel
> xParent( xModel
->getParent(), uno::UNO_QUERY_THROW
);
841 uno::Reference
< frame::XController
> xParentCtrler( xParent
->getCurrentController() );
842 uno::Reference
< frame::XFramesSupplier
> xParentFrame( xParentCtrler
->getFrame(), uno::UNO_QUERY_THROW
);
843 xParentFrame
->setActiveFrame( xFrame
);
847 xDesktop
->setActiveFrame( xFrame
);
850 catch (uno::Exception
&)
852 SAL_WARN( "starmath", "failed to properly set initial focus to edit window" );
856 void SmCmdBoxWindow::AdjustPosition()
859 const Rectangle
aRect( aPt
, GetParent()->GetOutputSizePixel() );
860 Point
aTopLeft( Point( aRect
.Left(),
861 aRect
.Bottom() - GetSizePixel().Height() ) );
862 Point
aPos( GetParent()->OutputToScreenPixel( aTopLeft
) );
870 void SmCmdBoxWindow::ToggleFloatingMode()
872 SfxDockingWindow::ToggleFloatingMode();
874 if (GetFloatingWindow())
875 GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50));
878 void SmCmdBoxWindow::GetFocus()
884 SFX_IMPL_DOCKINGWINDOW_WITHID(SmCmdBoxWrapper
, SID_CMDBOXWINDOW
);
886 SmCmdBoxWrapper::SmCmdBoxWrapper(vcl::Window
*pParentWindow
, sal_uInt16 nId
,
887 SfxBindings
*pBindings
,
888 SfxChildWinInfo
*pInfo
) :
889 SfxChildWindow(pParentWindow
, nId
)
891 pWindow
.reset(VclPtr
<SmCmdBoxWindow
>::Create(pBindings
, this, pParentWindow
));
893 // make window docked to the bottom initially (after first start)
894 eChildAlignment
= SfxChildAlignment::BOTTOM
;
895 static_cast<SfxDockingWindow
*>(pWindow
.get())->Initialize(pInfo
);
898 #if OSL_DEBUG_LEVEL > 1
899 SmCmdBoxWrapper::~SmCmdBoxWrapper()
904 struct SmViewShell_Impl
906 std::unique_ptr
<sfx2::DocumentInserter
> pDocInserter
;
907 std::unique_ptr
<SfxRequest
> pRequest
;
908 SvtMiscOptions aOpts
;
911 TYPEINIT1(SmViewShell
, SfxViewShell
);
913 SFX_IMPL_SUPERCLASS_INTERFACE(SmViewShell
, SfxViewShell
)
915 void SmViewShell::InitInterface_Impl()
917 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS
| SFX_VISIBILITY_STANDARD
| SFX_VISIBILITY_FULLSCREEN
| SFX_VISIBILITY_SERVER
,
919 //Dummy-Objectbar, to avoid quiver while activating
921 GetStaticInterface()->RegisterChildWindow(SID_TASKPANE
);
922 GetStaticInterface()->RegisterChildWindow(SmCmdBoxWrapper::GetChildWindowId());
923 GetStaticInterface()->RegisterChildWindow(SmElementsDockingWindowWrapper::GetChildWindowId());
926 SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell
, "Default")
928 SFX_VIEW_REGISTRATION(SmDocShell
);
931 void SmViewShell::AdjustPosSizePixel(const Point
&rPos
, const Size
&rSize
)
933 aGraphic
->SetPosSizePixel(rPos
, rSize
);
936 void SmViewShell::InnerResizePixel(const Point
&rOfs
, const Size
&rSize
)
938 Size aObjSize
= GetObjectShell()->GetVisArea().GetSize();
939 if ( aObjSize
.Width() > 0 && aObjSize
.Height() > 0 )
941 Size aProvidedSize
= GetWindow()->PixelToLogic( rSize
, MAP_100TH_MM
);
942 SfxViewShell::SetZoomFactor( Fraction( aProvidedSize
.Width(), aObjSize
.Width() ),
943 Fraction( aProvidedSize
.Height(), aObjSize
.Height() ) );
946 SetBorderPixel( SvBorder() );
947 GetGraphicWindow().SetPosSizePixel(rOfs
, rSize
);
948 GetGraphicWindow().SetTotalSize();
951 void SmViewShell::OuterResizePixel(const Point
&rOfs
, const Size
&rSize
)
953 SmGraphicWindow
&rWin
= GetGraphicWindow();
954 rWin
.SetPosSizePixel(rOfs
, rSize
);
955 if (GetDoc()->IsPreview())
956 rWin
.ZoomToFitInWindow();
960 void SmViewShell::QueryObjAreaPixel( Rectangle
& rRect
) const
962 rRect
.SetSize( GetGraphicWindow().GetSizePixel() );
965 void SmViewShell::SetZoomFactor( const Fraction
&rX
, const Fraction
&rY
)
967 const Fraction
&rFrac
= rX
< rY
? rX
: rY
;
968 GetGraphicWindow().SetZoom( (sal_uInt16
) long(rFrac
* Fraction( 100, 1 )) );
970 //To avoid rounding errors base class regulates crooked values too
972 SfxViewShell::SetZoomFactor( rX
, rY
);
975 Size
SmViewShell::GetTextLineSize(OutputDevice
& rDevice
, const OUString
& rLine
)
977 Size
aSize(rDevice
.GetTextWidth(rLine
), rDevice
.GetTextHeight());
978 sal_uInt16 nTabs
= comphelper::string::getTokenCount(rLine
, '\t');
981 nTabPos
= rDevice
.approximate_char_width() * 8;
987 for (sal_uInt16 i
= 0; i
< nTabs
; i
++)
990 aSize
.Width() = ((aSize
.Width() / nTabPos
) + 1) * nTabPos
;
992 OUString aText
= rLine
.getToken(i
, '\t');
993 aText
= comphelper::string::stripStart(aText
, '\t');
994 aText
= comphelper::string::stripEnd(aText
, '\t');
995 aSize
.Width() += rDevice
.GetTextWidth(aText
);
1002 Size
SmViewShell::GetTextSize(OutputDevice
& rDevice
, const OUString
& rText
, long MaxWidth
)
1006 sal_uInt16 nLines
= comphelper::string::getTokenCount(rText
, '\n');
1008 for (sal_uInt16 i
= 0; i
< nLines
; i
++)
1010 OUString aLine
= rText
.getToken(i
, '\n');
1011 aLine
= comphelper::string::remove(aLine
, '\r');
1012 aLine
= comphelper::string::stripStart(aLine
, '\n');
1013 aLine
= comphelper::string::stripEnd(aLine
, '\n');
1015 aSize
= GetTextLineSize(rDevice
, aLine
);
1017 if (aSize
.Width() > MaxWidth
)
1022 sal_Int32 m
= aLine
.getLength();
1025 for (sal_Int32 n
= 0; n
< nLen
; n
++)
1027 sal_Unicode cLineChar
= aLine
[n
];
1028 if ((cLineChar
== ' ') || (cLineChar
== '\t'))
1030 aText
= aLine
.copy(0, n
);
1031 if (GetTextLineSize(rDevice
, aText
).Width() < MaxWidth
)
1038 aText
= aLine
.copy(0, m
);
1039 aLine
= aLine
.replaceAt(0, m
, "");
1040 aSize
= GetTextLineSize(rDevice
, aText
);
1041 aTextSize
.Height() += aSize
.Height();
1042 aTextSize
.Width() = std::max(aTextSize
.Width(), std::min(aSize
.Width(), MaxWidth
));
1044 aLine
= comphelper::string::stripStart(aLine
, ' ');
1045 aLine
= comphelper::string::stripStart(aLine
, '\t');
1046 aLine
= comphelper::string::stripStart(aLine
, ' ');
1048 while (!aLine
.isEmpty());
1052 aTextSize
.Height() += aSize
.Height();
1053 aTextSize
.Width() = std::max(aTextSize
.Width(), aSize
.Width());
1060 void SmViewShell::DrawTextLine(OutputDevice
& rDevice
, const Point
& rPosition
, const OUString
& rLine
)
1062 Point
aPoint(rPosition
);
1064 sal_uInt16 nTabs
= comphelper::string::getTokenCount(rLine
, '\t');
1067 nTabPos
= rDevice
.approximate_char_width() * 8;
1071 for (sal_uInt16 i
= 0; i
< nTabs
; ++i
)
1074 aPoint
.X() = ((aPoint
.X() / nTabPos
) + 1) * nTabPos
;
1076 OUString aText
= rLine
.getToken(i
, '\t');
1077 aText
= comphelper::string::stripStart(aText
, '\t');
1078 aText
= comphelper::string::stripEnd(aText
, '\t');
1079 rDevice
.DrawText(aPoint
, aText
);
1080 aPoint
.X() += rDevice
.GetTextWidth(aText
);
1084 rDevice
.DrawText(aPoint
, rLine
);
1088 void SmViewShell::DrawText(OutputDevice
& rDevice
, const Point
& rPosition
, const OUString
& rText
, sal_uInt16 MaxWidth
)
1090 sal_uInt16 nLines
= comphelper::string::getTokenCount(rText
, '\n');
1091 Point
aPoint(rPosition
);
1094 for (sal_uInt16 i
= 0; i
< nLines
; i
++)
1096 OUString aLine
= rText
.getToken(i
, '\n');
1097 aLine
= comphelper::string::remove(aLine
, '\r');
1098 aLine
= comphelper::string::stripEnd(aLine
, '\n');
1099 aLine
= comphelper::string::stripEnd(aLine
, '\n');
1100 aSize
= GetTextLineSize(rDevice
, aLine
);
1101 if (aSize
.Width() > MaxWidth
)
1106 sal_Int32 m
= aLine
.getLength();
1109 for (sal_Int32 n
= 0; n
< nLen
; n
++)
1111 sal_Unicode cLineChar
= aLine
[n
];
1112 if ((cLineChar
== ' ') || (cLineChar
== '\t'))
1114 aText
= aLine
.copy(0, n
);
1115 if (GetTextLineSize(rDevice
, aText
).Width() < MaxWidth
)
1121 aText
= aLine
.copy(0, m
);
1122 aLine
= aLine
.replaceAt(0, m
, "");
1124 DrawTextLine(rDevice
, aPoint
, aText
);
1125 aPoint
.Y() += aSize
.Height();
1127 aLine
= comphelper::string::stripStart(aLine
, ' ');
1128 aLine
= comphelper::string::stripStart(aLine
, '\t');
1129 aLine
= comphelper::string::stripStart(aLine
, ' ');
1131 while (GetTextLineSize(rDevice
, aLine
).Width() > MaxWidth
);
1133 // print the remaining text
1134 if (!aLine
.isEmpty())
1136 DrawTextLine(rDevice
, aPoint
, aLine
);
1137 aPoint
.Y() += aSize
.Height();
1142 DrawTextLine(rDevice
, aPoint
, aLine
);
1143 aPoint
.Y() += aSize
.Height();
1148 void SmViewShell::Impl_Print(OutputDevice
&rOutDev
, const SmPrintUIOptions
&rPrintUIOptions
, Rectangle aOutRect
, Point aZeroPoint
)
1150 const bool bIsPrintTitle
= rPrintUIOptions
.getBoolValue( PRTUIOPT_TITLE_ROW
, true );
1151 const bool bIsPrintFrame
= rPrintUIOptions
.getBoolValue( PRTUIOPT_BORDER
, true );
1152 const bool bIsPrintFormulaText
= rPrintUIOptions
.getBoolValue( PRTUIOPT_FORMULA_TEXT
, true );
1153 SmPrintSize
ePrintSize( static_cast< SmPrintSize
>( rPrintUIOptions
.getIntValue( PRTUIOPT_PRINT_FORMAT
, PRINT_SIZE_NORMAL
) ));
1154 const sal_uInt16 nZoomFactor
= static_cast< sal_uInt16
>(rPrintUIOptions
.getIntValue( PRTUIOPT_PRINT_SCALE
, 100 ));
1157 rOutDev
.SetLineColor( Color(COL_BLACK
) );
1159 // output text on top
1162 Size
aSize600 (0, 600);
1163 Size
aSize650 (0, 650);
1164 vcl::Font
aFont(FAMILY_DONTKNOW
, aSize600
);
1166 aFont
.SetAlign(ALIGN_TOP
);
1167 aFont
.SetWeight(WEIGHT_BOLD
);
1168 aFont
.SetSize(aSize650
);
1169 aFont
.SetColor( Color(COL_BLACK
) );
1170 rOutDev
.SetFont(aFont
);
1172 Size
aTitleSize (GetTextSize(rOutDev
, GetDoc()->GetTitle(), aOutRect
.GetWidth() - 200));
1174 aFont
.SetWeight(WEIGHT_NORMAL
);
1175 aFont
.SetSize(aSize600
);
1176 rOutDev
.SetFont(aFont
);
1178 Size
aDescSize (GetTextSize(rOutDev
, GetDoc()->GetComment(), aOutRect
.GetWidth() - 200));
1181 rOutDev
.DrawRect(Rectangle(aOutRect
.TopLeft(),
1182 Size(aOutRect
.GetWidth(), 100 + aTitleSize
.Height() + 200 + aDescSize
.Height() + 100)));
1183 aOutRect
.Top() += 200;
1186 aFont
.SetWeight(WEIGHT_BOLD
);
1187 aFont
.SetSize(aSize650
);
1188 rOutDev
.SetFont(aFont
);
1189 Point
aPoint(aOutRect
.Left() + (aOutRect
.GetWidth() - aTitleSize
.Width()) / 2,
1191 DrawText(rOutDev
, aPoint
, GetDoc()->GetTitle(),
1192 sal::static_int_cast
< sal_uInt16
>(aOutRect
.GetWidth() - 200));
1193 aOutRect
.Top() += aTitleSize
.Height() + 200;
1195 // output description
1196 aFont
.SetWeight(WEIGHT_NORMAL
);
1197 aFont
.SetSize(aSize600
);
1198 rOutDev
.SetFont(aFont
);
1199 aPoint
.X() = aOutRect
.Left() + (aOutRect
.GetWidth() - aDescSize
.Width()) / 2;
1200 aPoint
.Y() = aOutRect
.Top();
1201 DrawText(rOutDev
, aPoint
, GetDoc()->GetComment(),
1202 sal::static_int_cast
< sal_uInt16
>(aOutRect
.GetWidth() - 200));
1203 aOutRect
.Top() += aDescSize
.Height() + 300;
1206 // output text on bottom
1207 if (bIsPrintFormulaText
)
1209 vcl::Font
aFont(FAMILY_DONTKNOW
, Size(0, 600));
1210 aFont
.SetAlign(ALIGN_TOP
);
1211 aFont
.SetColor( Color(COL_BLACK
) );
1214 rOutDev
.SetFont(aFont
);
1216 Size
aSize (GetTextSize(rOutDev
, GetDoc()->GetText(), aOutRect
.GetWidth() - 200));
1218 aOutRect
.Bottom() -= aSize
.Height() + 600;
1221 rOutDev
.DrawRect(Rectangle(aOutRect
.BottomLeft(),
1222 Size(aOutRect
.GetWidth(), 200 + aSize
.Height() + 200)));
1224 Point
aPoint (aOutRect
.Left() + (aOutRect
.GetWidth() - aSize
.Width()) / 2,
1225 aOutRect
.Bottom() + 300);
1226 DrawText(rOutDev
, aPoint
, GetDoc()->GetText(),
1227 sal::static_int_cast
< sal_uInt16
>(aOutRect
.GetWidth() - 200));
1228 aOutRect
.Bottom() -= 200;
1232 rOutDev
.DrawRect(aOutRect
);
1234 aOutRect
.Top() += 100;
1235 aOutRect
.Left() += 100;
1236 aOutRect
.Bottom() -= 100;
1237 aOutRect
.Right() -= 100;
1239 Size
aSize (GetDoc()->GetSize());
1241 MapMode OutputMapMode
;
1242 // PDF export should always use PRINT_SIZE_NORMAL ...
1243 if (!rPrintUIOptions
.getBoolValue( "IsPrinter", false ) )
1244 ePrintSize
= PRINT_SIZE_NORMAL
;
1247 case PRINT_SIZE_NORMAL
:
1248 OutputMapMode
= MapMode(MAP_100TH_MM
);
1251 case PRINT_SIZE_SCALED
:
1252 if ((aSize
.Width() > 0) && (aSize
.Height() > 0))
1254 Size
OutputSize (rOutDev
.LogicToPixel(Size(aOutRect
.GetWidth(),
1255 aOutRect
.GetHeight()), MapMode(MAP_100TH_MM
)));
1256 Size
GraphicSize (rOutDev
.LogicToPixel(aSize
, MapMode(MAP_100TH_MM
)));
1257 sal_uInt16 nZ
= (sal_uInt16
) std::min((long)Fraction(OutputSize
.Width() * 100L, GraphicSize
.Width()),
1258 (long)Fraction(OutputSize
.Height() * 100L, GraphicSize
.Height()));
1259 Fraction
aFraction ((sal_uInt16
) std::max ((sal_uInt16
) MINZOOM
, std::min((sal_uInt16
) MAXZOOM
, (sal_uInt16
) (nZ
- 10))), (sal_uInt16
) 100);
1261 OutputMapMode
= MapMode(MAP_100TH_MM
, aZeroPoint
, aFraction
, aFraction
);
1264 OutputMapMode
= MapMode(MAP_100TH_MM
);
1267 case PRINT_SIZE_ZOOMED
:
1269 Fraction
aFraction( nZoomFactor
, 100 );
1271 OutputMapMode
= MapMode(MAP_100TH_MM
, aZeroPoint
, aFraction
, aFraction
);
1276 aSize
= rOutDev
.PixelToLogic(rOutDev
.LogicToPixel(aSize
, OutputMapMode
),
1277 MapMode(MAP_100TH_MM
));
1279 Point
aPos (aOutRect
.Left() + (aOutRect
.GetWidth() - aSize
.Width()) / 2,
1280 aOutRect
.Top() + (aOutRect
.GetHeight() - aSize
.Height()) / 2);
1282 aPos
= rOutDev
.PixelToLogic(rOutDev
.LogicToPixel(aPos
, MapMode(MAP_100TH_MM
)),
1284 aOutRect
= rOutDev
.PixelToLogic(rOutDev
.LogicToPixel(aOutRect
, MapMode(MAP_100TH_MM
)),
1287 rOutDev
.SetMapMode(OutputMapMode
);
1288 rOutDev
.SetClipRegion(vcl::Region(aOutRect
));
1289 GetDoc()->DrawFormula(rOutDev
, aPos
, false);
1290 rOutDev
.SetClipRegion();
1295 SfxPrinter
* SmViewShell::GetPrinter(bool bCreate
)
1297 SmDocShell
* pDoc
= GetDoc();
1298 if (pDoc
->HasPrinter() || bCreate
)
1299 return pDoc
->GetPrinter();
1303 sal_uInt16
SmViewShell::SetPrinter(SfxPrinter
*pNewPrinter
, SfxPrinterChangeFlags nDiffFlags
, bool )
1305 SfxPrinter
*pOld
= GetDoc()->GetPrinter();
1306 if ( pOld
&& pOld
->IsPrinting() )
1307 return SFX_PRINTERROR_BUSY
;
1309 if ((nDiffFlags
& SfxPrinterChangeFlags::PRINTER
) == SfxPrinterChangeFlags::PRINTER
)
1310 GetDoc()->SetPrinter( pNewPrinter
);
1312 if ((nDiffFlags
& SfxPrinterChangeFlags::OPTIONS
) == SfxPrinterChangeFlags::OPTIONS
)
1314 SmModule
*pp
= SM_MOD();
1315 pp
->GetConfig()->ItemSetToConfig(pNewPrinter
->GetOptions());
1320 bool SmViewShell::HasPrintOptionsPage() const
1325 VclPtr
<SfxTabPage
> SmViewShell::CreatePrintOptionsPage(vcl::Window
*pParent
,
1326 const SfxItemSet
&rOptions
)
1328 return SmPrintOptionsTabPage::Create(pParent
, rOptions
);
1331 SmEditWindow
*SmViewShell::GetEditWindow()
1333 SmCmdBoxWrapper
* pWrapper
= static_cast<SmCmdBoxWrapper
*>(
1334 GetViewFrame()->GetChildWindow(SmCmdBoxWrapper::GetChildWindowId()));
1336 if (pWrapper
!= nullptr)
1338 SmEditWindow
& rEditWin
= pWrapper
->GetEditWindow();
1345 void SmViewShell::SetStatusText(const OUString
& rText
)
1347 aStatusText
= rText
;
1348 GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS
);
1351 void SmViewShell::ShowError(const SmErrorDesc
* pErrorDesc
)
1353 SAL_WARN_IF( !GetDoc(), "starmath", "Document missing" );
1354 if (pErrorDesc
|| 0 != (pErrorDesc
= GetDoc()->GetParser().GetError(0)) )
1356 SetStatusText( pErrorDesc
->Text
);
1357 GetEditWindow()->MarkError( Point( pErrorDesc
->pNode
->GetColumn(),
1358 pErrorDesc
->pNode
->GetRow()));
1362 void SmViewShell::NextError()
1364 SAL_WARN_IF( !GetDoc(), "starmath", "Document missing" );
1365 const SmErrorDesc
*pErrorDesc
= GetDoc()->GetParser().NextError();
1368 ShowError( pErrorDesc
);
1371 void SmViewShell::PrevError()
1373 SAL_WARN_IF( !GetDoc(), "starmath", "Document missing" );
1374 const SmErrorDesc
*pErrorDesc
= GetDoc()->GetParser().PrevError();
1377 ShowError( pErrorDesc
);
1380 void SmViewShell::Insert( SfxMedium
& rMedium
)
1382 SmDocShell
*pDoc
= GetDoc();
1385 uno::Reference
<embed::XStorage
> xStorage
= rMedium
.GetStorage();
1386 uno::Reference
<container::XNameAccess
> xNameAccess(xStorage
, uno::UNO_QUERY
);
1387 if (xNameAccess
.is() && xNameAccess
->getElementNames().getLength())
1389 if (xNameAccess
->hasByName(OUString("content.xml")) || xNameAccess
->hasByName(OUString("Content.xml")))
1391 // is this a fabulous math package ?
1392 Reference
<com::sun::star::frame::XModel
> xModel(pDoc
->GetModel());
1393 SmXMLImportWrapper
aEquation(xModel
); //!! modifies the result of pDoc->GetText() !!
1394 bRet
= 0 == aEquation
.Import(rMedium
);
1400 OUString aText
= pDoc
->GetText();
1401 SmEditWindow
*pEditWin
= GetEditWindow();
1403 pEditWin
->InsertText( aText
);
1406 SAL_WARN( "starmath", "EditWindow missing" );
1410 pDoc
->SetModified(true);
1412 SfxBindings
&rBnd
= GetViewFrame()->GetBindings();
1413 rBnd
.Invalidate(SID_GAPHIC_SM
);
1414 rBnd
.Invalidate(SID_TEXT
);
1418 void SmViewShell::InsertFrom(SfxMedium
&rMedium
)
1420 bool bSuccess
= false;
1421 SmDocShell
* pDoc
= GetDoc();
1422 SvStream
* pStream
= rMedium
.GetInStream();
1426 const OUString
& rFltName
= rMedium
.GetFilter()->GetFilterName();
1427 if ( rFltName
== MATHML_XML
)
1429 Reference
<css::frame::XModel
> xModel(pDoc
->GetModel());
1430 SmXMLImportWrapper
aEquation(xModel
); //!! modifies the result of pDoc->GetText() !!
1431 bSuccess
= 0 == aEquation
.Import(rMedium
);
1437 OUString aText
= pDoc
->GetText();
1438 SmEditWindow
*pEditWin
= GetEditWindow();
1440 pEditWin
->InsertText(aText
);
1442 SAL_WARN( "starmath", "EditWindow missing" );
1445 pDoc
->SetModified(true);
1447 SfxBindings
& rBnd
= GetViewFrame()->GetBindings();
1448 rBnd
.Invalidate(SID_GAPHIC_SM
);
1449 rBnd
.Invalidate(SID_TEXT
);
1453 void SmViewShell::Execute(SfxRequest
& rReq
)
1455 SmEditWindow
*pWin
= GetEditWindow();
1457 switch (rReq
.GetSlot())
1459 case SID_FORMULACURSOR
:
1461 SmModule
*pp
= SM_MOD();
1463 const SfxItemSet
*pArgs
= rReq
.GetArgs();
1464 const SfxPoolItem
*pItem
;
1468 SfxItemState::SET
== pArgs
->GetItemState( SID_FORMULACURSOR
, false, &pItem
))
1469 bVal
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
1471 bVal
= !pp
->GetConfig()->IsShowFormulaCursor();
1473 pp
->GetConfig()->SetShowFormulaCursor(bVal
);
1474 if (!IsInlineEditEnabled())
1475 GetGraphicWindow().ShowCursor(bVal
);
1481 GetDoc()->SetText( pWin
->GetText() );
1482 SetStatusText(OUString());
1484 GetDoc()->Repaint();
1488 case SID_ZOOM_OPTIMAL
:
1489 aGraphic
->ZoomToFitInWindow();
1493 aGraphic
->SetZoom(aGraphic
->GetZoom() + 25);
1497 SAL_WARN_IF( aGraphic
->GetZoom() < 25, "starmath", "incorrect sal_uInt16 argument" );
1498 aGraphic
->SetZoom(aGraphic
->GetZoom() - 25);
1501 case SID_COPYOBJECT
:
1503 //TODO/LATER: does not work because of UNO Tunneling - will be fixed later
1504 Reference
< datatransfer::XTransferable
> xTrans( GetDoc()->GetModel(), uno::UNO_QUERY
);
1507 Reference
< lang::XUnoTunnel
> xTnnl( xTrans
, uno::UNO_QUERY
);
1510 TransferableHelper
* pTrans
= reinterpret_cast< TransferableHelper
* >(
1511 sal::static_int_cast
< sal_uIntPtr
>(
1512 xTnnl
->getSomething( TransferableHelper::getUnoTunnelId() )));
1514 pTrans
->CopyToClipboard(GetEditWindow());
1520 case SID_PASTEOBJECT
:
1522 TransferableDataHelper
aData( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) );
1523 uno::Reference
< io::XInputStream
> xStrm
;
1524 SotClipboardFormatId nId
;
1525 if( aData
.GetTransferable().is() &&
1526 ( aData
.HasFormat( nId
= SotClipboardFormatId::EMBEDDED_OBJ
) ||
1527 (aData
.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR
) &&
1528 aData
.HasFormat( nId
= SotClipboardFormatId::EMBED_SOURCE
))))
1529 xStrm
= aData
.GetInputStream(nId
, OUString());
1535 uno::Reference
< embed::XStorage
> xStorage
=
1536 ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm
, ::comphelper::getProcessComponentContext() );
1537 uno::Reference
< beans::XPropertySet
> xProps( xStorage
, uno::UNO_QUERY
);
1538 SfxMedium
aMedium( xStorage
, OUString() );
1540 GetDoc()->UpdateText();
1542 catch (uno::Exception
&)
1544 SAL_WARN( "starmath", "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" );
1559 if (pWin
->IsAllSelected())
1561 GetViewFrame()->GetDispatcher()->Execute(
1562 SID_COPYOBJECT
, SfxCallMode::RECORD
,
1563 new SfxVoidItem(SID_COPYOBJECT
), 0L);
1572 bool bCallExec
= 0 == pWin
;
1575 TransferableDataHelper
aDataHelper(
1576 TransferableDataHelper::CreateFromSystemClipboard(
1579 if( aDataHelper
.GetTransferable().is() &&
1580 aDataHelper
.HasFormat( SotClipboardFormatId::STRING
))
1587 GetViewFrame()->GetDispatcher()->Execute(
1588 SID_PASTEOBJECT
, SfxCallMode::RECORD
,
1589 new SfxVoidItem(SID_PASTEOBJECT
), 0L);
1604 case SID_INSERTCOMMAND
:
1606 const SfxInt16Item
& rItem
=
1607 static_cast<const SfxInt16Item
&>(rReq
.GetArgs()->Get(SID_INSERTCOMMAND
));
1609 if (pWin
&& (bInsertIntoEditWindow
|| !IsInlineEditEnabled()))
1610 pWin
->InsertCommand(rItem
.GetValue());
1611 if (IsInlineEditEnabled() && (GetDoc() && !bInsertIntoEditWindow
)) {
1612 GetDoc()->GetCursor().InsertCommand(rItem
.GetValue());
1613 GetGraphicWindow().GrabFocus();
1618 case SID_INSERTCOMMANDTEXT
:
1620 const SfxStringItem
& rItem
= static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_INSERTCOMMANDTEXT
));
1622 if (pWin
&& (bInsertIntoEditWindow
|| !IsInlineEditEnabled()))
1624 pWin
->InsertText(rItem
.GetValue());
1626 if (IsInlineEditEnabled() && (GetDoc() && !bInsertIntoEditWindow
))
1628 GetDoc()->GetCursor().InsertCommandText(rItem
.GetValue());
1629 GetGraphicWindow().GrabFocus();
1635 case SID_INSERTSYMBOL
:
1637 const SfxStringItem
& rItem
=
1638 static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_INSERTSYMBOL
));
1640 if (pWin
&& (bInsertIntoEditWindow
|| !IsInlineEditEnabled()))
1641 pWin
->InsertText(rItem
.GetValue());
1642 if (IsInlineEditEnabled() && (GetDoc() && !bInsertIntoEditWindow
))
1643 GetDoc()->GetCursor().InsertSpecial(rItem
.GetValue());
1647 case SID_IMPORT_FORMULA
:
1649 pImpl
->pRequest
.reset(new SfxRequest( rReq
));
1650 pImpl
->pDocInserter
.reset(new ::sfx2::DocumentInserter(
1651 GetDoc()->GetFactory().GetFactoryName(), false ));
1652 pImpl
->pDocInserter
->StartExecuteModal( LINK( this, SmViewShell
, DialogClosedHdl
) );
1671 pWin
->SelNextMark();
1679 pWin
->SelPrevMark();
1684 case SID_TEXTSTATUS
:
1686 if (rReq
.GetArgs() != NULL
)
1688 const SfxStringItem
& rItem
=
1689 static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_TEXTSTATUS
));
1691 SetStatusText(rItem
.GetValue());
1697 case SID_GETEDITTEXT
:
1699 if (!pWin
->GetText().isEmpty()) GetDoc()->SetText( pWin
->GetText() );
1704 if ( !GetViewFrame()->GetFrame().IsInPlace() )
1706 std::unique_ptr
<AbstractSvxZoomDialog
> xDlg
;
1707 const SfxItemSet
*pSet
= rReq
.GetArgs();
1710 SfxItemSet
aSet( SmDocShell::GetPool(), SID_ATTR_ZOOM
, SID_ATTR_ZOOM
);
1711 aSet
.Put( SvxZoomItem( SvxZoomType::PERCENT
, aGraphic
->GetZoom()));
1712 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
1715 xDlg
.reset(pFact
->CreateSvxZoomDialog(&GetViewFrame()->GetWindow(), aSet
));
1716 SAL_WARN_IF( !xDlg
, "starmath", "Dialog creation failed!" );
1717 xDlg
->SetLimits( MINZOOM
, MAXZOOM
);
1718 if (xDlg
->Execute() != RET_CANCEL
)
1719 pSet
= xDlg
->GetOutputItemSet();
1724 const SvxZoomItem
&rZoom
= static_cast<const SvxZoomItem
&>(pSet
->Get(SID_ATTR_ZOOM
));
1725 switch( rZoom
.GetType() )
1727 case SvxZoomType::PERCENT
:
1728 aGraphic
->SetZoom((sal_uInt16
)rZoom
.GetValue ());
1731 case SvxZoomType::OPTIMAL
:
1732 aGraphic
->ZoomToFitInWindow();
1735 case SvxZoomType::PAGEWIDTH
:
1736 case SvxZoomType::WHOLEPAGE
:
1738 const MapMode
aMap( MAP_100TH_MM
);
1739 SfxPrinter
*pPrinter
= GetPrinter( true );
1741 Rectangle
OutputRect(aPoint
, pPrinter
->GetOutputSize());
1742 Size
OutputSize(pPrinter
->LogicToPixel(Size(OutputRect
.GetWidth(),
1743 OutputRect
.GetHeight()), aMap
));
1744 Size
GraphicSize(pPrinter
->LogicToPixel(GetDoc()->GetSize(), aMap
));
1745 sal_uInt16 nZ
= (sal_uInt16
) std::min((long)Fraction(OutputSize
.Width() * 100L, GraphicSize
.Width()),
1746 (long)Fraction(OutputSize
.Height() * 100L, GraphicSize
.Height()));
1747 aGraphic
->SetZoom (nZ
);
1758 case SID_ATTR_ZOOMSLIDER
:
1760 const SfxItemSet
*pArgs
= rReq
.GetArgs();
1761 const SfxPoolItem
* pItem
;
1763 if ( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(SID_ATTR_ZOOMSLIDER
, true, &pItem
) )
1765 const sal_uInt16 nCurrentZoom
= static_cast<const SvxZoomSliderItem
*>(pItem
)->GetValue();
1766 aGraphic
->SetZoom( nCurrentZoom
);
1771 case SID_ELEMENTSDOCKINGWINDOW
:
1773 GetViewFrame()->ToggleChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() );
1774 GetViewFrame()->GetBindings().Invalidate( SID_ELEMENTSDOCKINGWINDOW
);
1780 case SID_SYMBOLS_CATALOGUE
:
1783 // get device used to retrieve the FontList
1784 SmDocShell
*pDoc
= GetDoc();
1785 OutputDevice
*pDev
= pDoc
->GetPrinter();
1786 if (!pDev
|| pDev
->GetDevFontCount() == 0)
1787 pDev
= &SM_MOD()->GetDefaultVirtualDev();
1788 SAL_WARN_IF( !pDev
, "starmath", "device for font list missing" );
1790 SmModule
*pp
= SM_MOD();
1791 ScopedVclPtrInstance
<SmSymbolDialog
>::Create( nullptr, pDev
, pp
->GetSymbolManager(), *this )->Execute();
1799 void SmViewShell::GetState(SfxItemSet
&rSet
)
1801 SfxWhichIter
aIter(rSet
);
1803 SmEditWindow
*pEditWin
= GetEditWindow();
1804 for (sal_uInt16 nWh
= aIter
.FirstWhich(); nWh
!= 0; nWh
= aIter
.NextWhich())
1811 if (! pEditWin
|| ! pEditWin
->IsSelected())
1812 rSet
.DisableItem(nWh
);
1818 TransferableDataHelper
aDataHelper(
1819 TransferableDataHelper::CreateFromSystemClipboard(
1822 bPasteState
= aDataHelper
.GetTransferable().is() &&
1823 ( aDataHelper
.HasFormat( SotClipboardFormatId::STRING
) ||
1824 aDataHelper
.HasFormat( SotClipboardFormatId::EMBEDDED_OBJ
) ||
1825 (aDataHelper
.HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR
)
1826 && aDataHelper
.HasFormat( SotClipboardFormatId::EMBED_SOURCE
)));
1829 rSet
.DisableItem( nWh
);
1833 rSet
.Put(SvxZoomItem( SvxZoomType::PERCENT
, aGraphic
->GetZoom()));
1837 case SID_ZOOM_OPTIMAL
:
1838 if ( GetViewFrame()->GetFrame().IsInPlace() )
1839 rSet
.DisableItem( nWh
);
1842 case SID_ATTR_ZOOMSLIDER
:
1844 const sal_uInt16 nCurrentZoom
= aGraphic
->GetZoom();
1845 SvxZoomSliderItem
aZoomSliderItem( nCurrentZoom
, MINZOOM
, MAXZOOM
);
1846 aZoomSliderItem
.AddSnappingPoint( 100 );
1847 rSet
.Put( aZoomSliderItem
);
1857 if (! pEditWin
|| pEditWin
->IsEmpty())
1858 rSet
.DisableItem(nWh
);
1861 case SID_TEXTSTATUS
:
1863 rSet
.Put(SfxStringItem(nWh
, aStatusText
));
1867 case SID_FORMULACURSOR
:
1869 SmModule
*pp
= SM_MOD();
1870 rSet
.Put(SfxBoolItem(nWh
, pp
->GetConfig()->IsShowFormulaCursor()));
1873 case SID_ELEMENTSDOCKINGWINDOW
:
1875 bool bState
= false;
1876 SfxChildWindow
*pChildWnd
= GetViewFrame()->
1877 GetChildWindow( SmElementsDockingWindowWrapper::GetChildWindowId() );
1878 if (pChildWnd
&& pChildWnd
->GetWindow()->IsVisible())
1880 rSet
.Put(SfxBoolItem(SID_ELEMENTSDOCKINGWINDOW
, bState
));
1887 SmViewShell::SmViewShell(SfxViewFrame
*pFrame_
, SfxViewShell
*)
1888 : SfxViewShell(pFrame_
, SfxViewShellFlags::HAS_PRINTOPTIONS
| SfxViewShellFlags::CAN_PRINT
)
1889 , pImpl(new SmViewShell_Impl
)
1890 , aGraphic(VclPtr
<SmGraphicWindow
>::Create(this))
1891 , aGraphicController(*aGraphic
.get(), SID_GAPHIC_SM
, pFrame_
->GetBindings())
1892 , bPasteState(false)
1893 , bInsertIntoEditWindow(false)
1895 SetStatusText(OUString());
1896 SetWindow(aGraphic
.get());
1897 SfxShell::SetName(OUString("SmView"));
1898 SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() );
1899 SetHelpId( HID_SMA_VIEWSHELL_DOCUMENT
);
1903 SmViewShell::~SmViewShell()
1905 //!! this view shell is not active anymore !!
1906 // Thus 'SmGetActiveView' will give a 0 pointer.
1907 // Thus we need to supply this view as argument
1908 SmEditWindow
*pEditWin
= GetEditWindow();
1910 pEditWin
->DeleteEditView( *this );
1911 aGraphic
.disposeAndClear();
1914 void SmViewShell::Deactivate( bool bIsMDIActivate
)
1916 SmEditWindow
*pEdit
= GetEditWindow();
1920 SfxViewShell::Deactivate( bIsMDIActivate
);
1923 void SmViewShell::Activate( bool bIsMDIActivate
)
1925 SfxViewShell::Activate( bIsMDIActivate
);
1927 SmEditWindow
*pEdit
= GetEditWindow();
1930 //! Since there is no way to be informed if a "drag and drop"
1931 //! event has taken place, we call SetText here in order to
1932 //! synchronize the GraphicWindow display with the text in the
1934 SmDocShell
*pDoc
= GetDoc();
1935 pDoc
->SetText( pDoc
->GetEditEngine().GetText( LINEEND_LF
) );
1937 if ( bIsMDIActivate
)
1942 IMPL_LINK( SmViewShell
, DialogClosedHdl
, sfx2::FileDialogHelper
*, _pFileDlg
)
1944 assert(_pFileDlg
&& "SmViewShell::DialogClosedHdl(): no file dialog");
1945 assert(pImpl
->pDocInserter
&& "ScDocShell::DialogClosedHdl(): no document inserter");
1947 if ( ERRCODE_NONE
== _pFileDlg
->GetError() )
1949 SfxMedium
* pMedium
= pImpl
->pDocInserter
->CreateMedium();
1951 if ( pMedium
!= NULL
)
1953 if ( pMedium
->IsStorage() )
1956 InsertFrom( *pMedium
);
1959 SmDocShell
* pDoc
= GetDoc();
1961 pDoc
->ArrangeFormula();
1963 // adjust window, repaint, increment ModifyCount,...
1964 GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM
);
1968 pImpl
->pRequest
->SetReturnValue( SfxBoolItem( pImpl
->pRequest
->GetSlot(), true ) );
1969 pImpl
->pRequest
->Done();
1973 void SmViewShell::Notify( SfxBroadcaster
& , const SfxHint
& rHint
)
1975 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
1978 switch( pSimpleHint
->GetId() )
1980 case SFX_HINT_MODECHANGED
:
1981 case SFX_HINT_DOCCHANGED
:
1982 GetViewFrame()->GetBindings().InvalidateAll(false);
1990 bool SmViewShell::IsInlineEditEnabled() const
1992 return pImpl
->aOpts
.IsExperimentalMode();
1995 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */