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/lang/Locale.hpp>
22 #include <com/sun/star/uno/Any.h>
24 #include <comphelper/accessibletexthelper.hxx>
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/storagehelper.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <rtl/ustring.hxx>
29 #include <unotools/eventcfg.hxx>
30 #include <sfx2/event.hxx>
31 #include <sfx2/app.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/docfile.hxx>
34 #include <sfx2/docfilt.hxx>
35 #include <sfx2/fcontnr.hxx>
36 #include <sfx2/msg.hxx>
37 #include <sfx2/objface.hxx>
38 #include <sfx2/printer.hxx>
39 #include <sfx2/request.hxx>
40 #include <sfx2/viewfrm.hxx>
41 #include <comphelper/classids.hxx>
42 #include <sot/exchange.hxx>
43 #include <sot/formats.hxx>
44 #include <sot/storage.hxx>
45 #include <svl/eitem.hxx>
46 #include <svl/fstathelper.hxx>
47 #include <svl/intitem.hxx>
48 #include <svl/itempool.hxx>
49 #include <unotools/lingucfg.hxx>
50 #include <unotools/linguprops.hxx>
51 #include <unotools/pathoptions.hxx>
52 #include <svl/ptitem.hxx>
53 #include <svtools/sfxecode.hxx>
54 #include <svl/slstitm.hxx>
55 #include <svl/hint.hxx>
56 #include <svl/stritem.hxx>
57 #include <svtools/transfer.hxx>
58 #include <svl/undo.hxx>
59 #include <svl/urihelper.hxx>
60 #include <svl/whiter.hxx>
61 #include <editeng/editeng.hxx>
62 #include <editeng/editstat.hxx>
63 #include <editeng/eeitem.hxx>
64 #include <editeng/fhgtitem.hxx>
65 #include <editeng/fontitem.hxx>
66 #include <editeng/unolingu.hxx>
67 #include <ucbhelper/content.hxx>
68 #include <vcl/mapmod.hxx>
69 #include <tools/mapunit.hxx>
70 #include <vcl/msgbox.hxx>
71 #include <vcl/settings.hxx>
73 #include <sfx2/sfx.hrc>
74 #include <document.hxx>
79 #include <starmath.hrc>
81 #include <unomodel.hxx>
82 #include <utility.hxx>
84 #include "mathtype.hxx"
85 #include "ooxmlexport.hxx"
86 #include "ooxmlimport.hxx"
87 #include "rtfexport.hxx"
88 #include "mathmlimport.hxx"
89 #include "mathmlexport.hxx"
90 #include <sfx2/sfxsids.hrc>
91 #include <svx/svxids.hrc>
93 #include <tools/diagnose_ex.h>
94 #include "visitors.hxx"
95 #include "accessibility.hxx"
96 #include "cfgitem.hxx"
99 using namespace ::com::sun::star
;
100 using namespace ::com::sun::star::accessibility
;
101 using namespace ::com::sun::star::uno
;
104 #include "smslots.hxx"
107 SFX_IMPL_SUPERCLASS_INTERFACE(SmDocShell
, SfxObjectShell
)
109 void SmDocShell::InitInterface_Impl()
111 GetStaticInterface()->RegisterPopupMenu("view");
114 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), SfxObjectShellFlags::STD_NORMAL
, "smath" )
116 void SmDocShell::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
118 switch (rHint
.GetId())
120 case HINT_FORMATCHANGED
:
121 SetFormulaArranged(false);
123 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
130 void SmDocShell::LoadSymbols()
132 SmModule
*pp
= SM_MOD();
133 pp
->GetSymbolManager().Load();
137 const OUString
SmDocShell::GetComment() const
139 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
140 GetModel(), uno::UNO_QUERY_THROW
);
141 uno::Reference
<document::XDocumentProperties
> xDocProps(
142 xDPS
->getDocumentProperties());
143 return xDocProps
->getDescription();
147 void SmDocShell::SetText(const OUString
& rBuffer
)
149 if (rBuffer
!= maText
)
151 bool bIsEnabled
= IsEnableSetModified();
153 EnableSetModified( false );
156 SetFormulaArranged( false );
160 SmViewShell
*pViewSh
= SmGetActiveView();
163 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_TEXT
);
164 if ( SfxObjectCreateMode::EMBEDDED
== GetCreateMode() )
166 // have SwOleClient::FormatChanged() to align the modified formula properly
167 // even if the vis area does not change (e.g. when formula text changes from
168 // "{a over b + c} over d" to "d over {a over b + c}"
169 SfxGetpApp()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED
, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED
), this));
174 pViewSh
->GetGraphicWindow().Invalidate();
178 EnableSetModified( bIsEnabled
);
181 // launch accessible event if necessary
182 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWindow().GetAccessible_Impl() : nullptr;
185 Any aOldValue
, aNewValue
;
186 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( maText
, rBuffer
, aOldValue
, aNewValue
) )
188 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
189 aOldValue
, aNewValue
);
193 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
194 OnDocumentPrinterChanged(nullptr);
198 void SmDocShell::SetFormat(SmFormat
& rFormat
)
201 SetFormulaArranged( false );
204 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
206 // don't use SmGetActiveView since the view shell might not be active (0 pointer)
207 // if for example the Basic Macro dialog currently has the focus. Thus:
208 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
211 pFrm
->GetBindings().Invalidate(SID_GAPHIC_SM
);
212 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
216 OUString
const & SmDocShell::GetAccessibleText()
219 if (maAccText
.isEmpty())
221 OSL_ENSURE( mpTree
, "Tree missing" );
225 mpTree
->GetAccessibleText(aBuf
);
226 maAccText
= aBuf
.makeStringAndClear();
232 void SmDocShell::Parse()
236 mpTree
= maParser
.Parse(maText
);
237 mnModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
238 SetFormulaArranged( false );
240 maUsedSymbols
= maParser
.GetUsedSymbols();
244 void SmDocShell::ArrangeFormula()
246 if (mbFormulaArranged
)
249 // Only for the duration of the existence of this object the correct settings
250 // at the printer are guaranteed!
251 SmPrinterAccess
aPrtAcc(*this);
252 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
254 SAL_WARN_IF( !pOutDev
, "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!");
256 // if necessary get another OutputDevice for which we format
259 SmViewShell
*pView
= SmGetActiveView();
261 pOutDev
= &pView
->GetGraphicWindow();
264 pOutDev
= &SM_MOD()->GetDefaultVirtualDev();
265 pOutDev
->SetMapMode( MapMode(MapUnit::Map100thMM
) );
268 OSL_ENSURE(pOutDev
->GetMapMode().GetMapUnit() == MapUnit::Map100thMM
,
269 "Sm : falscher MapMode");
271 const SmFormat
&rFormat
= GetFormat();
272 mpTree
->Prepare(rFormat
, *this);
274 // format/draw formulas always from left to right,
275 // and numbers should not be converted
276 ComplexTextLayoutFlags nLayoutMode
= pOutDev
->GetLayoutMode();
277 pOutDev
->SetLayoutMode( ComplexTextLayoutFlags::Default
);
278 sal_Int16 nDigitLang
= pOutDev
->GetDigitLanguage();
279 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
281 mpTree
->Arrange(*pOutDev
, rFormat
);
283 pOutDev
->SetLayoutMode( nLayoutMode
);
284 pOutDev
->SetDigitLanguage( nDigitLang
);
286 SetFormulaArranged(true);
288 // invalidate accessible text
293 void SetEditEngineDefaultFonts(SfxItemPool
&rEditEngineItemPool
)
296 // set fonts to be used
298 SvtLinguOptions aOpt
;
299 SvtLinguConfig().GetOptions( aOpt
);
302 sal_Int16 nFallbackLang
;
304 DefaultFontType nFontType
;
305 sal_uInt16 nFontInfoId
;
308 // info to get western font to be used
309 { LANGUAGE_ENGLISH_US
, LANGUAGE_NONE
,
310 DefaultFontType::FIXED
, EE_CHAR_FONTINFO
},
311 // info to get CJK font to be used
312 { LANGUAGE_JAPANESE
, LANGUAGE_NONE
,
313 DefaultFontType::CJK_TEXT
, EE_CHAR_FONTINFO_CJK
},
314 // info to get CTL font to be used
315 { LANGUAGE_ARABIC_SAUDI_ARABIA
, LANGUAGE_NONE
,
316 DefaultFontType::CTL_TEXT
, EE_CHAR_FONTINFO_CTL
}
318 aTable
[0].nLang
= aOpt
.nDefaultLanguage
;
319 aTable
[1].nLang
= aOpt
.nDefaultLanguage_CJK
;
320 aTable
[2].nLang
= aOpt
.nDefaultLanguage_CTL
;
322 for (FontDta
& rFntDta
: aTable
)
324 LanguageType nLang
= (LANGUAGE_NONE
== rFntDta
.nLang
) ?
325 rFntDta
.nFallbackLang
: rFntDta
.nLang
;
326 vcl::Font aFont
= OutputDevice::GetDefaultFont(
327 rFntDta
.nFontType
, nLang
, GetDefaultFontFlags::OnlyOne
);
328 rEditEngineItemPool
.SetPoolDefaultItem(
329 SvxFontItem( aFont
.GetFamilyType(), aFont
.GetFamilyName(),
330 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(),
331 rFntDta
.nFontInfoId
) );
335 SvxFontHeightItem
aFontHeigt(
336 Application::GetDefaultDevice()->LogicToPixel(
337 Size( 0, 11 ), MapMode( MapUnit::MapPoint
) ).Height(), 100,
338 EE_CHAR_FONTHEIGHT
);
339 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
340 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CJK
);
341 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
342 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CTL
);
343 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
347 EditEngine
& SmDocShell::GetEditEngine()
352 //! see also SmEditWindow::DataChanged !
355 mpEditEngineItemPool
= EditEngine::CreatePool();
357 SetEditEngineDefaultFonts(*mpEditEngineItemPool
);
359 mpEditEngine
= new EditEngine( mpEditEngineItemPool
);
361 mpEditEngine
->EnableUndo( true );
362 mpEditEngine
->SetDefTab( sal_uInt16(
363 Application::GetDefaultDevice()->GetTextWidth("XXXX")) );
365 mpEditEngine
->SetControlWord(
366 (mpEditEngine
->GetControlWord() | EEControlBits::AUTOINDENTING
) &
367 EEControlBits(~EEControlBits::UNDOATTRIBS
) &
368 EEControlBits(~EEControlBits::PASTESPECIAL
) );
370 mpEditEngine
->SetWordDelimiters(" .=+-*/(){}[];\"");
371 mpEditEngine
->SetRefMapMode( MapUnit::MapPixel
);
373 mpEditEngine
->SetPaperSize( Size( 800, 0 ) );
375 mpEditEngine
->EraseVirtualDevice();
377 // set initial text if the document already has some...
378 // (may be the case when reloading a doc)
379 OUString
aTxt( GetText() );
381 mpEditEngine
->SetText( aTxt
);
383 mpEditEngine
->ClearModifyFlag();
386 return *mpEditEngine
;
390 SfxItemPool
& SmDocShell::GetEditEngineItemPool()
392 if (!mpEditEngineItemPool
)
394 assert(mpEditEngineItemPool
&& "EditEngineItemPool missing");
395 return *mpEditEngineItemPool
;
398 void SmDocShell::DrawFormula(OutputDevice
&rDev
, Point
&rPosition
, bool bDrawSelection
)
402 OSL_ENSURE(mpTree
, "Sm : NULL pointer");
406 // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference
407 // device and aren't aligned to that either. So now there can be a difference between the
408 // VisArea (i.e. the size within the client) and the current size.
409 // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
411 rPosition
.X() += maFormat
.GetDistance( DIS_LEFTSPACE
);
412 rPosition
.Y() += maFormat
.GetDistance( DIS_TOPSPACE
);
414 //! in case of high contrast-mode (accessibility option!)
415 //! the draw mode needs to be set to default, because when imbedding
416 //! Math for example in Calc in "a over b" the fraction bar may not
417 //! be visible else. More generally: the FillColor may have been changed.
418 DrawModeFlags nOldDrawMode
= DrawModeFlags::Default
;
419 bool bRestoreDrawMode
= false;
420 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
421 static_cast<vcl::Window
&>(rDev
).GetSettings().GetStyleSettings().GetHighContrastMode())
423 nOldDrawMode
= rDev
.GetDrawMode();
424 rDev
.SetDrawMode( DrawModeFlags::Default
);
425 bRestoreDrawMode
= true;
428 // format/draw formulas always from left to right
429 // and numbers should not be converted
430 ComplexTextLayoutFlags nLayoutMode
= rDev
.GetLayoutMode();
431 rDev
.SetLayoutMode( ComplexTextLayoutFlags::Default
);
432 sal_Int16 nDigitLang
= rDev
.GetDigitLanguage();
433 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
435 //Set selection if any
436 if(mpCursor
&& bDrawSelection
){
437 mpCursor
->AnnotateSelection();
438 SmSelectionDrawingVisitor(rDev
, mpTree
, rPosition
);
441 //Drawing using visitor
442 SmDrawingVisitor(rDev
, rPosition
, mpTree
);
445 rDev
.SetLayoutMode( nLayoutMode
);
446 rDev
.SetDigitLanguage( nDigitLang
);
448 if (bRestoreDrawMode
)
449 rDev
.SetDrawMode( nOldDrawMode
);
452 Size
SmDocShell::GetSize()
462 aRet
= mpTree
->GetSize();
467 aRet
.Width() += maFormat
.GetDistance( DIS_LEFTSPACE
) +
468 maFormat
.GetDistance( DIS_RIGHTSPACE
);
469 if ( !aRet
.Height() )
470 aRet
.Height() = 1000;
472 aRet
.Height() += maFormat
.GetDistance( DIS_TOPSPACE
) +
473 maFormat
.GetDistance( DIS_BOTTOMSPACE
);
479 void SmDocShell::InvalidateCursor(){
483 SmCursor
& SmDocShell::GetCursor(){
485 mpCursor
.reset(new SmCursor(mpTree
, this));
489 bool SmDocShell::HasCursor()
491 return mpCursor
.get() != nullptr;
494 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
496 pPrinter
= rDocShell
.GetPrt();
499 pPrinter
->Push( PushFlags::MAPMODE
);
500 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
502 // if it is an embedded object (without it's own printer)
503 // we change the MapMode temporarily.
504 //!If it is a document with its own printer the MapMode should
505 //!be set correct (once) elsewhere(!), in order to avoid numerous
506 //!superfluous pushing and poping of the MapMode when using
509 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
510 if ( MapUnit::Map100thMM
!= eOld
)
512 MapMode
aMap( pPrinter
->GetMapMode() );
513 aMap
.SetMapUnit( MapUnit::Map100thMM
);
514 Point
aTmp( aMap
.GetOrigin() );
515 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MapUnit::Map100thMM
);
516 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MapUnit::Map100thMM
);
517 aMap
.SetOrigin( aTmp
);
518 pPrinter
->SetMapMode( aMap
);
522 if ( !!(pRefDev
= rDocShell
.GetRefDev()) && pPrinter
.get() != pRefDev
.get() )
524 pRefDev
->Push( PushFlags::MAPMODE
);
525 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
527 // if it is an embedded object (without it's own printer)
528 // we change the MapMode temporarily.
529 //!If it is a document with its own printer the MapMode should
530 //!be set correct (once) elsewhere(!), in order to avoid numerous
531 //!superfluous pushing and poping of the MapMode when using
534 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
535 if ( MapUnit::Map100thMM
!= eOld
)
537 MapMode
aMap( pRefDev
->GetMapMode() );
538 aMap
.SetMapUnit( MapUnit::Map100thMM
);
539 Point
aTmp( aMap
.GetOrigin() );
540 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MapUnit::Map100thMM
);
541 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MapUnit::Map100thMM
);
542 aMap
.SetOrigin( aTmp
);
543 pRefDev
->SetMapMode( aMap
);
549 SmPrinterAccess::~SmPrinterAccess()
553 if ( pRefDev
&& pRefDev
!= pPrinter
)
557 Printer
* SmDocShell::GetPrt()
559 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
561 // Normally the server provides the printer. But if it doesn't provide one (e.g. because
562 // there is no connection) it still can be the case that we know the printer because it
563 // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
564 Printer
* pPrt
= GetDocumentPrinter();
565 if (!pPrt
&& mpTmpPrinter
)
571 SfxItemSet
* pOptions
= new SfxItemSet(GetPool(),
572 SID_PRINTSIZE
, SID_PRINTSIZE
,
573 SID_PRINTZOOM
, SID_PRINTZOOM
,
574 SID_PRINTTITLE
, SID_PRINTTITLE
,
575 SID_PRINTTEXT
, SID_PRINTTEXT
,
576 SID_PRINTFRAME
, SID_PRINTFRAME
,
577 SID_NO_RIGHT_SPACES
, SID_NO_RIGHT_SPACES
,
578 SID_SAVE_ONLY_USED_SYMBOLS
, SID_SAVE_ONLY_USED_SYMBOLS
,
579 SID_AUTO_CLOSE_BRACKETS
, SID_AUTO_CLOSE_BRACKETS
,
581 SmModule
*pp
= SM_MOD();
582 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
583 mpPrinter
= VclPtr
<SfxPrinter
>::Create(pOptions
);
584 mpPrinter
->SetMapMode(MapMode(MapUnit::Map100thMM
));
589 OutputDevice
* SmDocShell::GetRefDev()
591 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
593 OutputDevice
* pOutDev
= GetDocumentRefDev();
601 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
603 mpPrinter
.disposeAndClear();
604 mpPrinter
= pNew
; //Transfer ownership
605 mpPrinter
->SetMapMode( MapMode(MapUnit::Map100thMM
) );
606 SetFormulaArranged(false);
610 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
613 SetFormulaArranged(false);
614 Size aOldSize
= GetVisArea().GetSize();
616 if( aOldSize
!= GetVisArea().GetSize() && !maText
.isEmpty() )
618 mpTmpPrinter
= nullptr;
621 void SmDocShell::Repaint()
623 bool bIsEnabled
= IsEnableSetModified();
625 EnableSetModified( false );
627 SetFormulaArranged(false);
629 Size aVisSize
= GetSize();
630 SetVisAreaSize(aVisSize
);
631 SmViewShell
* pViewSh
= SmGetActiveView();
633 pViewSh
->GetGraphicWindow().Invalidate();
636 EnableSetModified(bIsEnabled
);
639 SmDocShell::SmDocShell( SfxModelFlags i_nSfxCreationFlags
)
640 : SfxObjectShell(i_nSfxCreationFlags
)
642 , mpEditEngineItemPool(nullptr)
643 , mpEditEngine(nullptr)
645 , mpTmpPrinter(nullptr)
647 , mbFormulaArranged(false)
649 SetPool(&SfxGetpApp()->GetPool());
651 SmModule
*pp
= SM_MOD();
652 maFormat
= pp
->GetConfig()->GetStandardFormat();
654 StartListening(maFormat
);
655 StartListening(*pp
->GetConfig());
657 SetBaseModel(new SmModel(this));
660 SmDocShell::~SmDocShell()
662 SmModule
*pp
= SM_MOD();
664 EndListening(maFormat
);
665 EndListening(*pp
->GetConfig());
669 SfxItemPool::Free(mpEditEngineItemPool
);
671 mpPrinter
.disposeAndClear();
674 bool SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
676 bool bSuccess
= false;
677 const OUString
& rFltName
= rMedium
.GetFilter()->GetFilterName();
679 OSL_ENSURE( rFltName
!= STAROFFICE_XML
, "Wrong filter!");
681 if ( rFltName
== MATHML_XML
)
689 Reference
<css::frame::XModel
> xModel(GetModel());
690 SmXMLImportWrapper
aEquation(xModel
);
691 bSuccess
= ( ERRCODE_NONE
== aEquation
.Import(rMedium
) );
695 SvStream
*pStream
= rMedium
.GetInStream();
698 if ( SotStorage::IsStorageFile( pStream
) )
700 tools::SvRef
<SotStorage
> aStorage
= new SotStorage( pStream
, false );
701 if ( aStorage
->IsStream("Equation Native") )
703 // is this a MathType Storage?
704 MathType
aEquation( maText
);
705 bSuccess
= aEquation
.Parse( aStorage
.get() );
713 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
715 SetFormulaArranged( false );
724 bool SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
727 if ( SfxObjectShell::InitNew( xStorage
) )
730 SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
736 bool SmDocShell::Load( SfxMedium
& rMedium
)
739 if( SfxObjectShell::Load( rMedium
))
741 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
742 uno::Reference
< container::XNameAccess
> xAccess (xStorage
, uno::UNO_QUERY
);
745 xAccess
->hasByName( "content.xml" ) &&
746 xStorage
->isStreamElement( "content.xml" )
749 xAccess
->hasByName( "Content.xml" ) &&
750 xStorage
->isStreamElement( "Content.xml" )
754 // is this a fabulous math package ?
755 Reference
<css::frame::XModel
> xModel(GetModel());
756 SmXMLImportWrapper
aEquation(xModel
);
757 sal_uLong nError
= aEquation
.Import(rMedium
);
759 SetError( nError
, OSL_LOG_PREFIX
);
763 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
765 SetFormulaArranged( false );
774 bool SmDocShell::Save()
776 //! apply latest changes if necessary
779 if ( SfxObjectShell::Save() )
786 Reference
<css::frame::XModel
> xModel(GetModel());
787 SmXMLExportWrapper
aEquation(xModel
);
788 aEquation
.SetFlat(false);
789 return aEquation
.Export(*GetMedium());
796 * replace bad characters that can not be saved. (#i74144)
798 void SmDocShell::ReplaceBadChars()
800 bool bReplace
= false;
804 OUStringBuffer
aBuf( mpEditEngine
->GetText() );
806 for (sal_Int32 i
= 0; i
< aBuf
.getLength(); ++i
)
808 if (aBuf
[i
] < ' ' && aBuf
[i
] != '\r' && aBuf
[i
] != '\n' && aBuf
[i
] != '\t')
816 maText
= aBuf
.makeStringAndClear();
821 void SmDocShell::UpdateText()
823 if (mpEditEngine
&& mpEditEngine
->IsModified())
825 OUString
aEngTxt( mpEditEngine
->GetText() );
826 if (GetText() != aEngTxt
)
832 bool SmDocShell::SaveAs( SfxMedium
& rMedium
)
836 //! apply latest changes if necessary
839 if ( SfxObjectShell::SaveAs( rMedium
) )
846 Reference
<css::frame::XModel
> xModel(GetModel());
847 SmXMLExportWrapper
aEquation(xModel
);
848 aEquation
.SetFlat(false);
849 bRet
= aEquation
.Export(rMedium
);
854 bool SmDocShell::ConvertTo( SfxMedium
&rMedium
)
857 std::shared_ptr
<const SfxFilter
> pFlt
= rMedium
.GetFilter();
865 const OUString
& rFltName
= pFlt
->GetFilterName();
866 if(rFltName
== STAROFFICE_XML
)
868 Reference
<css::frame::XModel
> xModel(GetModel());
869 SmXMLExportWrapper
aEquation(xModel
);
870 aEquation
.SetFlat(false);
871 bRet
= aEquation
.Export(rMedium
);
873 else if(rFltName
== MATHML_XML
)
875 Reference
<css::frame::XModel
> xModel(GetModel());
876 SmXMLExportWrapper
aEquation(xModel
);
877 aEquation
.SetFlat(true);
878 bRet
= aEquation
.Export(rMedium
);
880 else if (pFlt
->GetFilterName() == "MathType 3.x")
881 bRet
= WriteAsMathType3( rMedium
);
886 bool SmDocShell::writeFormulaOoxml(
887 ::sax_fastparser::FSHelperPtr
const& pSerializer
,
888 oox::core::OoxmlVersion
const version
,
889 oox::drawingml::DocumentType
const documentType
)
895 SmOoxmlExport
aEquation(mpTree
, version
, documentType
);
896 return aEquation
.ConvertFromStarMath( pSerializer
);
899 void SmDocShell::writeFormulaRtf(OStringBuffer
& rBuffer
, rtl_TextEncoding nEncoding
)
905 SmRtfExport
aEquation(mpTree
);
906 aEquation
.ConvertFromStarMath(rBuffer
, nEncoding
);
909 void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream
& stream
)
911 SmOoxmlImport
aEquation( stream
);
912 SetText( aEquation
.ConvertToStarMath());
915 void SmDocShell::Execute(SfxRequest
& rReq
)
917 switch (rReq
.GetSlot())
921 SmFormat aOldFormat
= GetFormat();
922 SmFormat
aNewFormat( aOldFormat
);
923 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
925 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
927 pTmpUndoMgr
->AddUndoAction(
928 new SmFormatAction(this, aOldFormat
, aNewFormat
));
930 SetFormat( aNewFormat
);
935 case SID_AUTO_REDRAW
:
937 SmModule
*pp
= SM_MOD();
938 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
939 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
943 case SID_LOADSYMBOLS
:
947 case SID_SAVESYMBOLS
:
953 // get device used to retrieve the FontList
954 OutputDevice
*pDev
= GetPrinter();
955 if (!pDev
|| pDev
->GetDevFontCount() == 0)
956 pDev
= &SM_MOD()->GetDefaultVirtualDev();
957 OSL_ENSURE (pDev
, "device for font list missing" );
959 VclPtrInstance
< SmFontTypeDialog
> xFontTypeDialog( nullptr, pDev
);
961 SmFormat aOldFormat
= GetFormat();
962 xFontTypeDialog
->ReadFrom( aOldFormat
);
963 if (xFontTypeDialog
->Execute() == RET_OK
)
965 SmFormat
aNewFormat( aOldFormat
);
967 xFontTypeDialog
->WriteTo(aNewFormat
);
968 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
970 pTmpUndoMgr
->AddUndoAction(
971 new SmFormatAction(this, aOldFormat
, aNewFormat
));
973 SetFormat( aNewFormat
);
981 VclPtrInstance
< SmFontSizeDialog
> xFontSizeDialog(nullptr);
983 SmFormat aOldFormat
= GetFormat();
984 xFontSizeDialog
->ReadFrom( aOldFormat
);
985 if (xFontSizeDialog
->Execute() == RET_OK
)
987 SmFormat
aNewFormat( aOldFormat
);
989 xFontSizeDialog
->WriteTo(aNewFormat
);
991 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
993 pTmpUndoMgr
->AddUndoAction(
994 new SmFormatAction(this, aOldFormat
, aNewFormat
));
996 SetFormat( aNewFormat
);
1004 VclPtrInstance
< SmDistanceDialog
> xDistanceDialog(nullptr);
1006 SmFormat aOldFormat
= GetFormat();
1007 xDistanceDialog
->ReadFrom( aOldFormat
);
1008 if (xDistanceDialog
->Execute() == RET_OK
)
1010 SmFormat
aNewFormat( aOldFormat
);
1012 xDistanceDialog
->WriteTo(aNewFormat
);
1014 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1016 pTmpUndoMgr
->AddUndoAction(
1017 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1019 SetFormat( aNewFormat
);
1027 VclPtrInstance
< SmAlignDialog
> xAlignDialog(nullptr);
1029 SmFormat aOldFormat
= GetFormat();
1030 xAlignDialog
->ReadFrom( aOldFormat
);
1031 if (xAlignDialog
->Execute() == RET_OK
)
1033 SmFormat
aNewFormat( aOldFormat
);
1035 xAlignDialog
->WriteTo(aNewFormat
);
1037 SmModule
*pp
= SM_MOD();
1038 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
1039 xAlignDialog
->WriteTo( aFmt
);
1040 pp
->GetConfig()->SetStandardFormat( aFmt
);
1042 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1044 pTmpUndoMgr
->AddUndoAction(
1045 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1047 SetFormat( aNewFormat
);
1055 const SfxStringItem
& rItem
= static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_TEXT
));
1056 if (GetText() != OUString(rItem
.GetValue()))
1057 SetText(rItem
.GetValue());
1064 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1067 sal_uInt16 nId
= rReq
.GetSlot(), nCnt
= 1;
1068 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1069 const SfxPoolItem
* pItem
;
1070 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( nId
, false, &pItem
))
1071 nCnt
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1073 bool (::svl::IUndoManager:: *fnDo
)();
1076 if( SID_UNDO
== rReq
.GetSlot() )
1078 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1079 fnDo
= &::svl::IUndoManager::Undo
;
1083 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1084 fnDo
= &::svl::IUndoManager::Redo
;
1089 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
1090 (pTmpUndoMgr
->*fnDo
)();
1092 catch( const Exception
& )
1094 DBG_UNHANDLED_EXCEPTION();
1099 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1102 SfxBindings
& rBind
= pFrm
->GetBindings();
1103 rBind
.Invalidate(SID_UNDO
);
1104 rBind
.Invalidate(SID_REDO
);
1105 rBind
.Invalidate(SID_REPEAT
);
1106 rBind
.Invalidate(SID_CLEARHISTORY
);
1107 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1117 void SmDocShell::GetState(SfxItemSet
&rSet
)
1119 SfxWhichIter
aIter(rSet
);
1121 for (sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1126 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1129 case SID_DOCTEMPLATE
:
1130 rSet
.DisableItem(SID_DOCTEMPLATE
);
1133 case SID_AUTO_REDRAW
:
1135 SmModule
*pp
= SM_MOD();
1136 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1138 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1142 case SID_MODIFYSTATUS
:
1144 sal_Unicode cMod
= ' ';
1147 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, OUString(cMod
)));
1152 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1156 //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
1157 //! If mnModifyCount gets changed then the call below will implicitly notify
1158 //! SmGraphicController::StateChanged and there the window gets invalidated.
1159 //! Thus all the 'mnModifyCount++' before invalidating this slot.
1160 rSet
.Put(SfxInt16Item(SID_GAPHIC_SM
, mnModifyCount
));
1166 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1168 pFrm
->GetSlotState( nWh
, nullptr, &rSet
);
1170 rSet
.DisableItem( nWh
);
1174 case SID_GETUNDOSTRINGS
:
1175 case SID_GETREDOSTRINGS
:
1177 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1180 OUString(::svl::IUndoManager:: *fnGetComment
)( size_t, bool const ) const;
1183 if( SID_GETUNDOSTRINGS
== nWh
)
1185 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1186 fnGetComment
= &::svl::IUndoManager::GetUndoActionComment
;
1190 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1191 fnGetComment
= &::svl::IUndoManager::GetRedoActionComment
;
1195 OUStringBuffer aBuf
;
1196 for( sal_uInt16 n
= 0; n
< nCount
; ++n
)
1198 aBuf
.append((pTmpUndoMgr
->*fnGetComment
)( n
, ::svl::IUndoManager::TopLevel
));
1202 SfxStringListItem
aItem( nWh
);
1203 aItem
.SetString( aBuf
.makeStringAndClear() );
1208 rSet
.DisableItem( nWh
);
1216 ::svl::IUndoManager
*SmDocShell::GetUndoManager()
1220 return &mpEditEngine
->GetUndoManager();
1224 void SmDocShell::SaveSymbols()
1226 SmModule
*pp
= SM_MOD();
1227 pp
->GetSymbolManager().Save();
1231 void SmDocShell::Draw(OutputDevice
*pDevice
,
1233 sal_uInt16
/*nAspect*/)
1235 pDevice
->IntersectClipRegion(GetVisArea());
1237 DrawFormula(*pDevice
, atmppoint
);
1240 SfxItemPool
& SmDocShell::GetPool()
1242 return SfxGetpApp()->GetPool();
1245 void SmDocShell::SetVisArea(const Rectangle
& rVisArea
)
1247 Rectangle
aNewRect(rVisArea
);
1249 aNewRect
.SetPos(Point());
1251 if (! aNewRect
.Right()) aNewRect
.Right() = 2000;
1252 if (! aNewRect
.Bottom()) aNewRect
.Bottom() = 1000;
1254 bool bIsEnabled
= IsEnableSetModified();
1256 EnableSetModified( false );
1258 //TODO/LATER: it's unclear how this interacts with the SFX code
1259 // If outplace editing, then don't resize the OutplaceWindow. But the
1260 // ObjectShell has to resize. Bug 56470
1262 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1264 GetFrame()->LockAdjustPosSizePixel();
1265 bUnLockFrame
= true;
1268 bUnLockFrame
= false;
1270 SfxObjectShell::SetVisArea( aNewRect
);
1273 GetFrame()->UnlockAdjustPosSizePixel();
1276 EnableSetModified( bIsEnabled
);
1280 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1281 SotClipboardFormatId
* pFormat
,
1282 OUString
* /*pAppName*/,
1283 OUString
* pFullTypeName
,
1284 OUString
* pShortTypeName
,
1285 sal_Int32 nFileFormat
,
1286 bool bTemplate
/* = false */) const
1288 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1290 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1291 *pFormat
= SotClipboardFormatId::STARMATH_60
;
1292 *pFullTypeName
= SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1293 *pShortTypeName
= SM_RESSTR(RID_DOCUMENTSTR
);
1295 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1297 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1298 *pFormat
= bTemplate
? SotClipboardFormatId::STARMATH_8_TEMPLATE
: SotClipboardFormatId::STARMATH_8
;
1299 *pFullTypeName
= SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1300 *pShortTypeName
= SM_RESSTR(RID_DOCUMENTSTR
);
1304 sal_uLong
SmDocShell::GetMiscStatus() const
1306 return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
1307 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE
;
1310 void SmDocShell::SetModified(bool bModified
)
1312 if( IsEnableSetModified() )
1314 SfxObjectShell::SetModified( bModified
);
1315 Broadcast(SfxHint(SFX_HINT_DOCCHANGED
));
1319 bool SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1321 MathType
aEquation( maText
, mpTree
);
1322 return aEquation
.ConvertFromStarMath( rMedium
);
1325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */