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/smplhint.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>
80 #include <starmath.hrc>
82 #include <unomodel.hxx>
83 #include <utility.hxx>
85 #include "mathtype.hxx"
86 #include "ooxmlexport.hxx"
87 #include "ooxmlimport.hxx"
88 #include "rtfexport.hxx"
89 #include "mathmlimport.hxx"
90 #include "mathmlexport.hxx"
91 #include <sfx2/sfxsids.hrc>
92 #include <svx/svxids.hrc>
94 #include <tools/diagnose_ex.h>
95 #include "visitors.hxx"
96 #include "accessibility.hxx"
99 using namespace ::com::sun::star
;
100 using namespace ::com::sun::star::accessibility
;
101 using namespace ::com::sun::star::lang
;
102 using namespace ::com::sun::star::ucb
;
103 using namespace ::com::sun::star::uno
;
106 #include "smslots.hxx"
108 TYPEINIT1( SmDocShell
, SfxObjectShell
);
110 SFX_IMPL_SUPERCLASS_INTERFACE(SmDocShell
, SfxObjectShell
)
112 void SmDocShell::InitInterface_Impl()
114 GetStaticInterface()->RegisterPopupMenu(SmResId(RID_VIEWMENU
));
115 GetStaticInterface()->RegisterPopupMenu(SmResId(RID_COMMANDMENU
));
118 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), SfxObjectShellFlags::STD_NORMAL
, "smath" )
120 void SmDocShell::SFX_NOTIFY(SfxBroadcaster
&, const TypeId
&,
121 const SfxHint
& rHint
, const TypeId
&)
123 switch (static_cast<const SfxSimpleHint
&>(rHint
).GetId())
125 case HINT_FORMATCHANGED
:
126 SetFormulaArranged(false);
128 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
135 void SmDocShell::LoadSymbols()
137 SmModule
*pp
= SM_MOD();
138 pp
->GetSymbolManager().Load();
142 const OUString
SmDocShell::GetComment() const
144 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
145 GetModel(), uno::UNO_QUERY_THROW
);
146 uno::Reference
<document::XDocumentProperties
> xDocProps(
147 xDPS
->getDocumentProperties());
148 return xDocProps
->getDescription();
152 void SmDocShell::SetText(const OUString
& rBuffer
)
154 if (rBuffer
!= aText
)
156 bool bIsEnabled
= IsEnableSetModified();
158 EnableSetModified( false );
161 SetFormulaArranged( false );
165 SmViewShell
*pViewSh
= SmGetActiveView();
168 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_TEXT
);
169 if ( SfxObjectCreateMode::EMBEDDED
== GetCreateMode() )
171 // have SwOleClient::FormatChanged() to align the modified formula properly
172 // even if the vis area does not change (e.g. when formula text changes from
173 // "{a over b + c} over d" to "d over {a over b + c}"
174 SfxGetpApp()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED
, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED
), this));
179 pViewSh
->GetGraphicWindow().Invalidate();
183 EnableSetModified( bIsEnabled
);
186 // launch accessible event if necessary
187 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWindow().GetAccessible_Impl() : 0;
190 Any aOldValue
, aNewValue
;
191 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText
, rBuffer
, aOldValue
, aNewValue
) )
193 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
194 aOldValue
, aNewValue
);
198 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
199 OnDocumentPrinterChanged(0);
203 void SmDocShell::SetFormat(SmFormat
& rFormat
)
206 SetFormulaArranged( false );
209 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
211 // don't use SmGetActiveView since the view shell might not be active (0 pointer)
212 // if for example the Basic Macro dialog currently has the focus. Thus:
213 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
216 pFrm
->GetBindings().Invalidate(SID_GAPHIC_SM
);
217 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
221 OUString
SmDocShell::GetAccessibleText()
223 if (!IsFormulaArranged())
225 if (aAccText
.isEmpty())
227 OSL_ENSURE( pTree
, "Tree missing" );
231 pTree
->GetAccessibleText(aBuf
);
232 aAccText
= aBuf
.makeStringAndClear();
238 void SmDocShell::Parse()
243 pTree
= aInterpreter
.Parse(aText
);
244 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
245 SetFormulaArranged( false );
247 aUsedSymbols
= aInterpreter
.GetUsedSymbols();
251 void SmDocShell::ArrangeFormula()
253 if (IsFormulaArranged())
256 // Only for the duration of the existence of this object the correct settings
257 // at the printer are guaranteed!
258 SmPrinterAccess
aPrtAcc(*this);
259 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
263 #if OSL_DEBUG_LEVEL > 1
264 SAL_WARN( "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!");
268 // if necessary get another OutputDevice for which we format
271 SmViewShell
*pView
= SmGetActiveView();
273 pOutDev
= &pView
->GetGraphicWindow();
276 pOutDev
= &SM_MOD()->GetDefaultVirtualDev();
277 pOutDev
->SetMapMode( MapMode(MAP_100TH_MM
) );
280 OSL_ENSURE(pOutDev
->GetMapMode().GetMapUnit() == MAP_100TH_MM
,
281 "Sm : falscher MapMode");
283 const SmFormat
&rFormat
= GetFormat();
284 pTree
->Prepare(rFormat
, *this);
286 // format/draw formulas always from left to right,
287 // and numbers should not be converted
288 ComplexTextLayoutMode nLayoutMode
= pOutDev
->GetLayoutMode();
289 pOutDev
->SetLayoutMode( TEXT_LAYOUT_DEFAULT
);
290 sal_Int16 nDigitLang
= pOutDev
->GetDigitLanguage();
291 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
293 pTree
->Arrange(*pOutDev
, rFormat
);
295 pOutDev
->SetLayoutMode( nLayoutMode
);
296 pOutDev
->SetDigitLanguage( nDigitLang
);
298 SetFormulaArranged(true);
300 // invalidate accessible text
305 void SetEditEngineDefaultFonts(SfxItemPool
&rEditEngineItemPool
)
308 // set fonts to be used
310 SvtLinguOptions aOpt
;
311 SvtLinguConfig().GetOptions( aOpt
);
314 sal_Int16 nFallbackLang
;
316 DefaultFontType nFontType
;
317 sal_uInt16 nFontInfoId
;
320 // info to get western font to be used
321 { LANGUAGE_ENGLISH_US
, LANGUAGE_NONE
,
322 DefaultFontType::FIXED
, EE_CHAR_FONTINFO
},
323 // info to get CJK font to be used
324 { LANGUAGE_JAPANESE
, LANGUAGE_NONE
,
325 DefaultFontType::CJK_TEXT
, EE_CHAR_FONTINFO_CJK
},
326 // info to get CTL font to be used
327 { LANGUAGE_ARABIC_SAUDI_ARABIA
, LANGUAGE_NONE
,
328 DefaultFontType::CTL_TEXT
, EE_CHAR_FONTINFO_CTL
}
330 aTable
[0].nLang
= aOpt
.nDefaultLanguage
;
331 aTable
[1].nLang
= aOpt
.nDefaultLanguage_CJK
;
332 aTable
[2].nLang
= aOpt
.nDefaultLanguage_CTL
;
334 for (int i
= 0; i
< 3; ++i
)
336 const FontDta
&rFntDta
= aTable
[i
];
337 LanguageType nLang
= (LANGUAGE_NONE
== rFntDta
.nLang
) ?
338 rFntDta
.nFallbackLang
: rFntDta
.nLang
;
339 vcl::Font aFont
= OutputDevice::GetDefaultFont(
340 rFntDta
.nFontType
, nLang
, GetDefaultFontFlags::OnlyOne
);
341 rEditEngineItemPool
.SetPoolDefaultItem(
342 SvxFontItem( aFont
.GetFamily(), aFont
.GetName(),
343 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(),
344 rFntDta
.nFontInfoId
) );
348 SvxFontHeightItem
aFontHeigt(
349 Application::GetDefaultDevice()->LogicToPixel(
350 Size( 0, 11 ), MapMode( MAP_POINT
) ).Height(), 100,
351 EE_CHAR_FONTHEIGHT
);
352 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
353 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CJK
);
354 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
355 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CTL
);
356 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
360 EditEngine
& SmDocShell::GetEditEngine()
365 //! see also SmEditWindow::DataChanged !
368 pEditEngineItemPool
= EditEngine::CreatePool();
370 SetEditEngineDefaultFonts(*pEditEngineItemPool
);
372 pEditEngine
= new EditEngine( pEditEngineItemPool
);
374 pEditEngine
->EnableUndo( true );
375 pEditEngine
->SetDefTab( sal_uInt16(
376 Application::GetDefaultDevice()->GetTextWidth(OUString("XXXX"))) );
378 pEditEngine
->SetControlWord(
379 (pEditEngine
->GetControlWord() | EEControlBits::AUTOINDENTING
) &
380 EEControlBits(~EEControlBits::UNDOATTRIBS
) &
381 EEControlBits(~EEControlBits::PASTESPECIAL
) );
383 pEditEngine
->SetWordDelimiters(" .=+-*/(){}[];\"");
384 pEditEngine
->SetRefMapMode( MAP_PIXEL
);
386 pEditEngine
->SetPaperSize( Size( 800, 0 ) );
388 pEditEngine
->EraseVirtualDevice();
390 // set initial text if the document already has some...
391 // (may be the case when reloading a doc)
392 OUString
aTxt( GetText() );
394 pEditEngine
->SetText( aTxt
);
396 pEditEngine
->ClearModifyFlag();
403 SfxItemPool
& SmDocShell::GetEditEngineItemPool()
405 if (!pEditEngineItemPool
)
407 assert(pEditEngineItemPool
&& "EditEngineItemPool missing");
408 return *pEditEngineItemPool
;
411 void SmDocShell::DrawFormula(OutputDevice
&rDev
, Point
&rPosition
, bool bDrawSelection
)
415 OSL_ENSURE(pTree
, "Sm : NULL pointer");
417 if (!IsFormulaArranged())
420 // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference
421 // device and aren't aligned to that either. So now there can be a difference between the
422 // VisArea (i.e. the size within the client) and the current size.
423 // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
425 rPosition
.X() += aFormat
.GetDistance( DIS_LEFTSPACE
);
426 rPosition
.Y() += aFormat
.GetDistance( DIS_TOPSPACE
);
428 //! in case of high contrast-mode (accessibility option!)
429 //! the draw mode needs to be set to default, because when imbedding
430 //! Math for example in Calc in "a over b" the fraction bar may not
431 //! be visible else. More generally: the FillColor may have been changed.
432 DrawModeFlags nOldDrawMode
= DrawModeFlags::Default
;
433 bool bRestoreDrawMode
= false;
434 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
435 static_cast<vcl::Window
&>(rDev
).GetSettings().GetStyleSettings().GetHighContrastMode())
437 nOldDrawMode
= rDev
.GetDrawMode();
438 rDev
.SetDrawMode( DrawModeFlags::Default
);
439 bRestoreDrawMode
= true;
442 // format/draw formulas always from left to right
443 // and numbers should not be converted
444 ComplexTextLayoutMode nLayoutMode
= rDev
.GetLayoutMode();
445 rDev
.SetLayoutMode( TEXT_LAYOUT_DEFAULT
);
446 sal_Int16 nDigitLang
= rDev
.GetDigitLanguage();
447 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
449 //Set selection if any
450 if(pCursor
&& bDrawSelection
){
451 pCursor
->AnnotateSelection();
452 SmSelectionDrawingVisitor(rDev
, pTree
, rPosition
);
455 //Drawing using visitor
456 SmDrawingVisitor(rDev
, rPosition
, pTree
);
459 rDev
.SetLayoutMode( nLayoutMode
);
460 rDev
.SetDigitLanguage( nDigitLang
);
462 if (bRestoreDrawMode
)
463 rDev
.SetDrawMode( nOldDrawMode
);
466 Size
SmDocShell::GetSize()
475 if (!IsFormulaArranged())
477 aRet
= pTree
->GetSize();
482 aRet
.Width() += aFormat
.GetDistance( DIS_LEFTSPACE
) +
483 aFormat
.GetDistance( DIS_RIGHTSPACE
);
484 if ( !aRet
.Height() )
485 aRet
.Height() = 1000;
487 aRet
.Height() += aFormat
.GetDistance( DIS_TOPSPACE
) +
488 aFormat
.GetDistance( DIS_BOTTOMSPACE
);
494 void SmDocShell::InvalidateCursor(){
499 SmCursor
& SmDocShell::GetCursor(){
501 pCursor
= new SmCursor(pTree
, this);
507 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
509 pPrinter
= rDocShell
.GetPrt();
512 pPrinter
->Push( PushFlags::MAPMODE
);
513 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
515 // if it is an embedded object (without it's own printer)
516 // we change the MapMode temporarily.
517 //!If it is a document with it's own printer the MapMode should
518 //!be set correct (once) elsewhere(!), in order to avoid numerous
519 //!superfluous pushing and poping of the MapMode when using
522 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
523 if ( MAP_100TH_MM
!= eOld
)
525 MapMode
aMap( pPrinter
->GetMapMode() );
526 aMap
.SetMapUnit( MAP_100TH_MM
);
527 Point
aTmp( aMap
.GetOrigin() );
528 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
529 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
530 aMap
.SetOrigin( aTmp
);
531 pPrinter
->SetMapMode( aMap
);
535 if ( !!(pRefDev
= rDocShell
.GetRefDev()) && pPrinter
.get() != pRefDev
.get() )
537 pRefDev
->Push( PushFlags::MAPMODE
);
538 if ( SfxObjectCreateMode::EMBEDDED
== rDocShell
.GetCreateMode() )
540 // if it is an embedded object (without it's own printer)
541 // we change the MapMode temporarily.
542 //!If it is a document with it's own printer the MapMode should
543 //!be set correct (once) elsewhere(!), in order to avoid numerous
544 //!superfluous pushing and poping of the MapMode when using
547 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
548 if ( MAP_100TH_MM
!= eOld
)
550 MapMode
aMap( pRefDev
->GetMapMode() );
551 aMap
.SetMapUnit( MAP_100TH_MM
);
552 Point
aTmp( aMap
.GetOrigin() );
553 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
554 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
555 aMap
.SetOrigin( aTmp
);
556 pRefDev
->SetMapMode( aMap
);
562 SmPrinterAccess::~SmPrinterAccess()
566 if ( pRefDev
&& pRefDev
!= pPrinter
)
570 Printer
* SmDocShell::GetPrt()
572 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
574 // Normally the server provides the printer. But if it doesn't provide one (e.g. because
575 // there is no connection) it still can be the case that we know the printer because it
576 // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
577 Printer
* pPrt
= GetDocumentPrinter();
578 if (!pPrt
&& pTmpPrinter
)
584 SfxItemSet
* pOptions
= new SfxItemSet(GetPool(),
585 SID_PRINTSIZE
, SID_PRINTSIZE
,
586 SID_PRINTZOOM
, SID_PRINTZOOM
,
587 SID_PRINTTITLE
, SID_PRINTTITLE
,
588 SID_PRINTTEXT
, SID_PRINTTEXT
,
589 SID_PRINTFRAME
, SID_PRINTFRAME
,
590 SID_NO_RIGHT_SPACES
, SID_NO_RIGHT_SPACES
,
591 SID_SAVE_ONLY_USED_SYMBOLS
, SID_SAVE_ONLY_USED_SYMBOLS
,
593 SmModule
*pp
= SM_MOD();
594 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
595 pPrinter
= VclPtr
<SfxPrinter
>::Create(pOptions
);
596 pPrinter
->SetMapMode(MapMode(MAP_100TH_MM
));
601 OutputDevice
* SmDocShell::GetRefDev()
603 if (SfxObjectCreateMode::EMBEDDED
== GetCreateMode())
605 OutputDevice
* pOutDev
= GetDocumentRefDev();
613 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
615 pPrinter
.disposeAndClear();
616 pPrinter
= pNew
; //Transfer ownership
617 pPrinter
->SetMapMode( MapMode(MAP_100TH_MM
) );
618 SetFormulaArranged(false);
622 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
625 SetFormulaArranged(false);
626 Size aOldSize
= GetVisArea().GetSize();
628 if( aOldSize
!= GetVisArea().GetSize() && !aText
.isEmpty() )
633 void SmDocShell::Repaint()
635 bool bIsEnabled
= IsEnableSetModified();
637 EnableSetModified( false );
639 SetFormulaArranged(false);
641 Size aVisSize
= GetSize();
642 SetVisAreaSize(aVisSize
);
643 SmViewShell
* pViewSh
= SmGetActiveView();
645 pViewSh
->GetGraphicWindow().Invalidate();
648 EnableSetModified(bIsEnabled
);
651 SmDocShell::SmDocShell( SfxModelFlags i_nSfxCreationFlags
)
652 : SfxObjectShell(i_nSfxCreationFlags
)
654 , pEditEngineItemPool(0)
659 , bIsFormulaArranged(false)
663 SetPool(&SfxGetpApp()->GetPool());
665 SmModule
*pp
= SM_MOD();
666 aFormat
= pp
->GetConfig()->GetStandardFormat();
668 StartListening(aFormat
);
669 StartListening(*pp
->GetConfig());
671 SetBaseModel(new SmModel(this));
674 SmDocShell::~SmDocShell()
676 SmModule
*pp
= SM_MOD();
678 EndListening(aFormat
);
679 EndListening(*pp
->GetConfig());
687 SfxItemPool::Free(pEditEngineItemPool
);
689 pPrinter
.disposeAndClear();
692 bool SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
694 bool bSuccess
= false;
695 const OUString
& rFltName
= rMedium
.GetFilter()->GetFilterName();
697 OSL_ENSURE( rFltName
!= STAROFFICE_XML
, "Wrong filter!");
699 if ( rFltName
== MATHML_XML
)
707 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
708 SmXMLImportWrapper
aEquation(xModel
);
709 bSuccess
= 0 == aEquation
.Import(rMedium
);
713 SvStream
*pStream
= rMedium
.GetInStream();
716 if ( SotStorage::IsStorageFile( pStream
) )
718 tools::SvRef
<SotStorage
> aStorage
= new SotStorage( pStream
, false );
719 if ( aStorage
->IsStream(OUString("Equation Native")) )
721 // is this a MathType Storage?
722 MathType
aEquation( aText
);
723 if ( (bSuccess
= (1 == aEquation
.Parse( aStorage
)) ))
730 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
732 SetFormulaArranged( false );
736 FinishedLoading( SfxLoadedFlags::ALL
);
741 bool SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
744 if ( SfxObjectShell::InitNew( xStorage
) )
747 SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
753 bool SmDocShell::Load( SfxMedium
& rMedium
)
756 if( SfxObjectShell::Load( rMedium
))
758 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
759 uno::Reference
< container::XNameAccess
> xAccess (xStorage
, uno::UNO_QUERY
);
762 xAccess
->hasByName( OUString("content.xml") ) &&
763 xStorage
->isStreamElement( OUString("content.xml") )
766 xAccess
->hasByName( OUString("Content.xml") ) &&
767 xStorage
->isStreamElement( OUString("Content.xml") )
771 // is this a fabulous math package ?
772 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
773 SmXMLImportWrapper
aEquation(xModel
);
774 sal_uLong nError
= aEquation
.Import(rMedium
);
776 SetError( nError
, OSL_LOG_PREFIX
);
780 if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
)
782 SetFormulaArranged( false );
786 FinishedLoading( SfxLoadedFlags::ALL
);
792 bool SmDocShell::Save()
794 //! apply latest changes if necessary
797 if ( SfxObjectShell::Save() )
801 if( pTree
&& !IsFormulaArranged() )
804 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
805 SmXMLExportWrapper
aEquation(xModel
);
806 aEquation
.SetFlat(false);
807 return aEquation
.Export(*GetMedium());
814 * replace bad characters that can not be saved. (#i74144)
816 bool SmDocShell::ReplaceBadChars()
818 bool bReplace
= false;
822 OUStringBuffer
aBuf( pEditEngine
->GetText( LINEEND_LF
) );
824 for (sal_Int32 i
= 0; i
< aBuf
.getLength(); ++i
)
826 if (aBuf
[i
] < ' ' && aBuf
[i
] != '\r' && aBuf
[i
] != '\n' && aBuf
[i
] != '\t')
834 aText
= aBuf
.makeStringAndClear();
841 void SmDocShell::UpdateText()
843 if (pEditEngine
&& pEditEngine
->IsModified())
845 OUString
aEngTxt( pEditEngine
->GetText( LINEEND_LF
) );
846 if (GetText() != aEngTxt
)
852 bool SmDocShell::SaveAs( SfxMedium
& rMedium
)
856 //! apply latest changes if necessary
859 if ( SfxObjectShell::SaveAs( rMedium
) )
863 if( pTree
&& !IsFormulaArranged() )
866 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
867 SmXMLExportWrapper
aEquation(xModel
);
868 aEquation
.SetFlat(false);
869 bRet
= aEquation
.Export(rMedium
);
874 bool SmDocShell::ConvertTo( SfxMedium
&rMedium
)
877 const SfxFilter
* pFlt
= rMedium
.GetFilter();
882 if( pTree
&& !IsFormulaArranged() )
885 const OUString
& rFltName
= pFlt
->GetFilterName();
886 if(rFltName
== STAROFFICE_XML
)
888 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
889 SmXMLExportWrapper
aEquation(xModel
);
890 aEquation
.SetFlat(false);
891 bRet
= aEquation
.Export(rMedium
);
893 else if(rFltName
== MATHML_XML
)
895 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
896 SmXMLExportWrapper
aEquation(xModel
);
897 aEquation
.SetFlat(true);
898 bRet
= aEquation
.Export(rMedium
);
900 else if (pFlt
->GetFilterName() == "MathType 3.x")
901 bRet
= WriteAsMathType3( rMedium
);
906 bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr pSerializer
, oox::core::OoxmlVersion version
)
910 if( pTree
&& !IsFormulaArranged() )
912 SmOoxmlExport
aEquation( pTree
, version
);
913 return aEquation
.ConvertFromStarMath( pSerializer
);
916 void SmDocShell::writeFormulaRtf(OStringBuffer
& rBuffer
, rtl_TextEncoding nEncoding
)
920 if (pTree
&& !IsFormulaArranged())
922 SmRtfExport
aEquation(pTree
);
923 aEquation
.ConvertFromStarMath(rBuffer
, nEncoding
);
926 void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream
& stream
)
928 SmOoxmlImport
aEquation( stream
);
929 SetText( aEquation
.ConvertToStarMath());
932 bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStorage
)
934 if( SfxObjectShell::SaveCompleted( xStorage
))
941 void SmDocShell::Execute(SfxRequest
& rReq
)
943 switch (rReq
.GetSlot())
947 SmFormat aOldFormat
= GetFormat();
948 SmFormat
aNewFormat( aOldFormat
);
949 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
951 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
953 pTmpUndoMgr
->AddUndoAction(
954 new SmFormatAction(this, aOldFormat
, aNewFormat
));
956 SetFormat( aNewFormat
);
961 case SID_AUTO_REDRAW
:
963 SmModule
*pp
= SM_MOD();
964 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
965 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
969 case SID_LOADSYMBOLS
:
973 case SID_SAVESYMBOLS
:
979 // get device used to retrieve the FontList
980 OutputDevice
*pDev
= GetPrinter();
981 if (!pDev
|| pDev
->GetDevFontCount() == 0)
982 pDev
= &SM_MOD()->GetDefaultVirtualDev();
983 OSL_ENSURE (pDev
, "device for font list missing" );
985 VclPtrInstance
< SmFontTypeDialog
> xFontTypeDialog( nullptr, pDev
);
987 SmFormat aOldFormat
= GetFormat();
988 xFontTypeDialog
->ReadFrom( aOldFormat
);
989 if (xFontTypeDialog
->Execute() == RET_OK
)
991 SmFormat
aNewFormat( aOldFormat
);
993 xFontTypeDialog
->WriteTo(aNewFormat
);
994 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
996 pTmpUndoMgr
->AddUndoAction(
997 new SmFormatAction(this, aOldFormat
, aNewFormat
));
999 SetFormat( aNewFormat
);
1007 VclPtrInstance
< SmFontSizeDialog
> xFontSizeDialog(nullptr);
1009 SmFormat aOldFormat
= GetFormat();
1010 xFontSizeDialog
->ReadFrom( aOldFormat
);
1011 if (xFontSizeDialog
->Execute() == RET_OK
)
1013 SmFormat
aNewFormat( aOldFormat
);
1015 xFontSizeDialog
->WriteTo(aNewFormat
);
1017 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1019 pTmpUndoMgr
->AddUndoAction(
1020 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1022 SetFormat( aNewFormat
);
1030 VclPtrInstance
< SmDistanceDialog
> xDistanceDialog(nullptr);
1032 SmFormat aOldFormat
= GetFormat();
1033 xDistanceDialog
->ReadFrom( aOldFormat
);
1034 if (xDistanceDialog
->Execute() == RET_OK
)
1036 SmFormat
aNewFormat( aOldFormat
);
1038 xDistanceDialog
->WriteTo(aNewFormat
);
1040 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1042 pTmpUndoMgr
->AddUndoAction(
1043 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1045 SetFormat( aNewFormat
);
1053 VclPtrInstance
< SmAlignDialog
> xAlignDialog(nullptr);
1055 SmFormat aOldFormat
= GetFormat();
1056 xAlignDialog
->ReadFrom( aOldFormat
);
1057 if (xAlignDialog
->Execute() == RET_OK
)
1059 SmFormat
aNewFormat( aOldFormat
);
1061 xAlignDialog
->WriteTo(aNewFormat
);
1063 SmModule
*pp
= SM_MOD();
1064 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
1065 xAlignDialog
->WriteTo( aFmt
);
1066 pp
->GetConfig()->SetStandardFormat( aFmt
);
1068 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1070 pTmpUndoMgr
->AddUndoAction(
1071 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1073 SetFormat( aNewFormat
);
1081 const SfxStringItem
& rItem
= static_cast<const SfxStringItem
&>(rReq
.GetArgs()->Get(SID_TEXT
));
1082 if (GetText() != OUString(rItem
.GetValue()))
1083 SetText(rItem
.GetValue());
1090 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1093 sal_uInt16 nId
= rReq
.GetSlot(), nCnt
= 1;
1094 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1095 const SfxPoolItem
* pItem
;
1096 if( pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( nId
, false, &pItem
))
1097 nCnt
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1099 bool (::svl::IUndoManager:: *fnDo
)();
1102 if( SID_UNDO
== rReq
.GetSlot() )
1104 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1105 fnDo
= &::svl::IUndoManager::Undo
;
1109 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1110 fnDo
= &::svl::IUndoManager::Redo
;
1115 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
1116 (pTmpUndoMgr
->*fnDo
)();
1118 catch( const Exception
& )
1120 DBG_UNHANDLED_EXCEPTION();
1125 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1128 SfxBindings
& rBind
= pFrm
->GetBindings();
1129 rBind
.Invalidate(SID_UNDO
);
1130 rBind
.Invalidate(SID_REDO
);
1131 rBind
.Invalidate(SID_REPEAT
);
1132 rBind
.Invalidate(SID_CLEARHISTORY
);
1133 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1143 void SmDocShell::GetState(SfxItemSet
&rSet
)
1145 SfxWhichIter
aIter(rSet
);
1147 for (sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1152 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1155 case SID_DOCTEMPLATE
:
1156 rSet
.DisableItem(SID_DOCTEMPLATE
);
1159 case SID_AUTO_REDRAW
:
1161 SmModule
*pp
= SM_MOD();
1162 bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1164 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1168 case SID_MODIFYSTATUS
:
1170 sal_Unicode cMod
= ' ';
1173 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, OUString(cMod
)));
1178 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1182 //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
1183 //! If nModifyCount gets changed then the call below will implicitly notify
1184 //! SmGraphicController::StateChanged and there the window gets invalidated.
1185 //! Thus all the 'nModifyCount++' before invalidating this slot.
1186 rSet
.Put(SfxInt16Item(SID_GAPHIC_SM
, nModifyCount
));
1192 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1194 pFrm
->GetSlotState( nWh
, NULL
, &rSet
);
1196 rSet
.DisableItem( nWh
);
1200 case SID_GETUNDOSTRINGS
:
1201 case SID_GETREDOSTRINGS
:
1203 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1206 OUString(::svl::IUndoManager:: *fnGetComment
)( size_t, bool const ) const;
1209 if( SID_GETUNDOSTRINGS
== nWh
)
1211 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1212 fnGetComment
= &::svl::IUndoManager::GetUndoActionComment
;
1216 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1217 fnGetComment
= &::svl::IUndoManager::GetRedoActionComment
;
1221 OUStringBuffer aBuf
;
1222 for( sal_uInt16 n
= 0; n
< nCount
; ++n
)
1224 aBuf
.append((pTmpUndoMgr
->*fnGetComment
)( n
, ::svl::IUndoManager::TopLevel
));
1228 SfxStringListItem
aItem( nWh
);
1229 aItem
.SetString( aBuf
.makeStringAndClear() );
1234 rSet
.DisableItem( nWh
);
1242 ::svl::IUndoManager
*SmDocShell::GetUndoManager()
1246 return &pEditEngine
->GetUndoManager();
1250 void SmDocShell::SaveSymbols()
1252 SmModule
*pp
= SM_MOD();
1253 pp
->GetSymbolManager().Save();
1257 void SmDocShell::Draw(OutputDevice
*pDevice
,
1259 sal_uInt16
/*nAspect*/)
1261 pDevice
->IntersectClipRegion(GetVisArea());
1263 DrawFormula(*pDevice
, atmppoint
);
1266 SfxItemPool
& SmDocShell::GetPool()
1268 return SfxGetpApp()->GetPool();
1271 void SmDocShell::SetVisArea(const Rectangle
& rVisArea
)
1273 Rectangle
aNewRect(rVisArea
);
1275 aNewRect
.SetPos(Point());
1277 if (! aNewRect
.Right()) aNewRect
.Right() = 2000;
1278 if (! aNewRect
.Bottom()) aNewRect
.Bottom() = 1000;
1280 bool bIsEnabled
= IsEnableSetModified();
1282 EnableSetModified( false );
1284 //TODO/LATER: it's unclear how this interacts with the SFX code
1285 // If outplace editing, then dont resize the OutplaceWindow. But the
1286 // ObjectShell has to resize. Bug 56470
1288 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1290 GetFrame()->LockAdjustPosSizePixel();
1291 bUnLockFrame
= true;
1294 bUnLockFrame
= false;
1296 SfxObjectShell::SetVisArea( aNewRect
);
1299 GetFrame()->UnlockAdjustPosSizePixel();
1302 EnableSetModified( bIsEnabled
);
1306 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1307 SotClipboardFormatId
* pFormat
,
1308 OUString
* /*pAppName*/,
1309 OUString
* pFullTypeName
,
1310 OUString
* pShortTypeName
,
1311 sal_Int32 nFileFormat
,
1312 bool bTemplate
/* = false */) const
1314 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1316 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1317 *pFormat
= SotClipboardFormatId::STARMATH_60
;
1318 *pFullTypeName
= SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1319 *pShortTypeName
= SM_RESSTR(RID_DOCUMENTSTR
);
1321 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1323 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1324 *pFormat
= bTemplate
? SotClipboardFormatId::STARMATH_8_TEMPLATE
: SotClipboardFormatId::STARMATH_8
;
1325 *pFullTypeName
= SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
);
1326 *pShortTypeName
= SM_RESSTR(RID_DOCUMENTSTR
);
1330 sal_uLong
SmDocShell::GetMiscStatus() const
1332 return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
1333 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE
;
1336 void SmDocShell::SetModified(bool bModified
)
1338 if( IsEnableSetModified() )
1340 SfxObjectShell::SetModified( bModified
);
1341 Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED
));
1345 bool SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1347 MathType
aEquation( aText
, pTree
);
1349 bool bRet
= 0 != aEquation
.ConvertFromStarMath( rMedium
);
1353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */