1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_starmath.hxx"
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include <com/sun/star/lang/Locale.hpp>
34 #include <com/sun/star/uno/Any.h>
36 #include <comphelper/accessibletexthelper.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <comphelper/storagehelper.hxx>
39 #include <rtl/logfile.hxx>
40 #include <rtl/ustring.hxx>
41 #include <unotools/eventcfg.hxx>
42 #include <sfx2/event.hxx>
43 #include <sfx2/app.hxx>
44 #include <sfx2/dispatch.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/docfilt.hxx>
47 #include <sfx2/fcontnr.hxx>
48 #include <sfx2/msg.hxx>
49 #include <sfx2/objface.hxx>
50 #include <sfx2/printer.hxx>
51 #include <sfx2/request.hxx>
52 #include <sfx2/viewfrm.hxx>
53 #include <sot/clsids.hxx>
54 #include <sot/exchange.hxx>
55 #include <sot/formats.hxx>
56 #include <sot/storage.hxx>
57 #include <svl/eitem.hxx>
58 #include <svl/fstathelper.hxx>
59 #include <svl/intitem.hxx>
60 #include <svl/itempool.hxx>
61 #include <unotools/lingucfg.hxx>
62 #include <unotools/linguprops.hxx>
63 #include <unotools/pathoptions.hxx>
64 #include <svl/ptitem.hxx>
65 #include <svtools/sfxecode.hxx>
66 #include <svl/slstitm.hxx>
67 #include <svl/smplhint.hxx>
68 #include <svl/stritem.hxx>
69 #include <svtools/transfer.hxx>
70 #include <svl/undo.hxx>
71 #include <svl/urihelper.hxx>
72 #include <svl/whiter.hxx>
73 #include <editeng/editeng.hxx>
74 #include <editeng/editstat.hxx>
75 #include <editeng/eeitem.hxx>
76 #include <editeng/fhgtitem.hxx>
77 #include <editeng/fontitem.hxx>
78 #include <editeng/unolingu.hxx>
79 #include <ucbhelper/content.hxx>
80 #include <vcl/mapmod.hxx>
81 #include <tools/mapunit.hxx>
82 #include <vcl/msgbox.hxx>
83 #include <sfx2/sfx.hrc>
84 #include <document.hxx>
90 #include <starmath.hrc>
92 #include <toolbox.hxx>
93 #include <unomodel.hxx>
94 #include <utility.hxx>
96 #include "mathtype.hxx"
97 #include "mathmlimport.hxx"
98 #include "mathmlexport.hxx"
99 #include <sfx2/sfxsids.hrc>
100 #include <svx/svxids.hrc>
101 #include <tools/diagnose_ex.h>
103 using namespace ::com::sun::star
;
104 using namespace ::com::sun::star::accessibility
;
105 using namespace ::com::sun::star::lang
;
106 using namespace ::com::sun::star::ucb
;
107 using namespace ::com::sun::star::uno
;
110 #define DOCUMENT_BUFFER_SIZE (sal_uInt16)32768
112 static const char __FAR_DATA pStarMathDoc
[] = "StarMathDocument";
115 #include "smslots.hxx"
117 ////////////////////////////////////////////////////////////
120 TYPEINIT1( SmDocShell
, SfxObjectShell
);
122 SFX_IMPL_INTERFACE(SmDocShell
, SfxObjectShell
, SmResId(0))
124 SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU
));
125 SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU
));
128 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), SFXOBJECTSHELL_STD_NORMAL
, "smath" )
130 void SmDocShell::SFX_NOTIFY(SfxBroadcaster
&, const TypeId
&,
131 const SfxHint
& rHint
, const TypeId
&)
133 switch (((SfxSimpleHint
&)rHint
).GetId())
135 case HINT_FORMATCHANGED
:
136 SetFormulaArranged(sal_False
);
138 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
145 void SmDocShell::LoadSymbols()
147 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::LoadSymbols" );
149 SmModule
*pp
= SM_MOD();
150 pp
->GetSymbolManager().Load();
154 const String
SmDocShell::GetComment() const
156 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetComment" );
157 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
158 const_cast<SmDocShell
*>(this)->GetModel(), uno::UNO_QUERY_THROW
);
159 uno::Reference
<document::XDocumentProperties
> xDocProps(
160 xDPS
->getDocumentProperties());
161 return xDocProps
->getDescription();
165 void SmDocShell::SetText(const String
& rBuffer
)
167 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetText" );
169 if (rBuffer
!= aText
)
171 sal_Bool bIsEnabled
= IsEnableSetModified();
173 EnableSetModified( sal_False
);
176 SetFormulaArranged( sal_False
);
181 SmViewShell
*pViewSh
= SmGetActiveView();
184 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_TEXT
);
185 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
187 // have SwOleClient::FormatChanged() to align the modified formula properly
188 // even if the vis area does not change (e.g. when formula text changes from
189 // "{a over b + c} over d" to "d over {a over b + c}"
190 SFX_APP()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED
, GlobalEventConfig::GetEventName(STR_EVENT_VISAREACHANGED
), this));
195 pViewSh
->GetGraphicWindow().Invalidate();
199 EnableSetModified( bIsEnabled
);
200 SetModified(sal_True
);
202 // launch accessible event if necessary
203 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWindow().GetAccessible_Impl() : 0;
206 Any aOldValue
, aNewValue
;
207 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText
, rBuffer
, aOldValue
, aNewValue
) )
209 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
210 aOldValue
, aNewValue
);
214 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
215 OnDocumentPrinterChanged(0);
219 void SmDocShell::SetFormat(SmFormat
& rFormat
)
221 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetFormat" );
224 SetFormulaArranged( sal_False
);
225 SetModified( sal_True
);
227 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
229 // don't use SmGetActiveView since the view shell might not be active (0 pointer)
230 // if for example the Basic Macro dialog currently has the focus. Thus:
231 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
234 pFrm
->GetBindings().Invalidate(SID_GAPHIC_SM
);
235 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
239 String
SmDocShell::GetAccessibleText()
241 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetAccessibleText" );
243 if (!IsFormulaArranged())
245 if (0 == aAccText
.Len())
247 DBG_ASSERT( pTree
, "Tree missing" );
249 pTree
->GetAccessibleText( aAccText
);
254 void SmDocShell::Parse()
256 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Parse" );
261 pTree
= aInterpreter
.Parse(aText
);
262 nModifyCount
++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
263 SetFormulaArranged( sal_False
);
265 aUsedSymbols
= aInterpreter
.GetUsedSymbols();
269 void SmDocShell::ArrangeFormula()
271 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ArrangeFormula" );
273 if (IsFormulaArranged())
276 //! Nur f�r die Dauer der Existenz dieses Objekts sind am Drucker die
277 //! richtigen Einstellungen garantiert.
278 SmPrinterAccess
aPrtAcc(*this);
279 // OutputDevice *pOutDev = aPrtAcc.GetPrinter();
280 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
284 #if OSL_DEBUG_LEVEL > 1
285 DBG_ERROR("!! SmDocShell::ArrangeFormula: reference device missing !!");
289 // falls n�tig ein anderes OutputDevice holen f�r das formatiert wird
292 SmViewShell
*pView
= SmGetActiveView();
294 pOutDev
= &pView
->GetGraphicWindow();
297 pOutDev
= &SM_MOD()->GetDefaultVirtualDev();
298 pOutDev
->SetMapMode( MapMode(MAP_100TH_MM
) );
301 DBG_ASSERT(pOutDev
->GetMapMode().GetMapUnit() == MAP_100TH_MM
,
302 "Sm : falscher MapMode");
304 const SmFormat
&rFormat
= GetFormat();
305 pTree
->Prepare(rFormat
, *this);
307 // format/draw formulas always from left to right,
308 // and numbers should not be converted
309 sal_uLong nLayoutMode
= pOutDev
->GetLayoutMode();
310 pOutDev
->SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
);
311 sal_Int16 nDigitLang
= pOutDev
->GetDigitLanguage();
312 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
314 pTree
->Arrange(*pOutDev
, rFormat
);
316 pOutDev
->SetLayoutMode( nLayoutMode
);
317 pOutDev
->SetDigitLanguage( nDigitLang
);
319 SetFormulaArranged(sal_True
);
321 // invalidate accessible text
326 void SetEditEngineDefaultFonts(
327 EditEngine
&/*rEditEngine*/,
328 SfxItemPool
&rEditEngineItemPool
)
331 // set fonts to be used
333 SvtLinguOptions aOpt
;
334 SvtLinguConfig().GetOptions( aOpt
);
337 sal_Int16 nFallbackLang
;
339 sal_uInt16 nFontType
;
340 sal_uInt16 nFontInfoId
;
343 // info to get western font to be used
344 { LANGUAGE_ENGLISH_US
, LANGUAGE_NONE
,
345 DEFAULTFONT_FIXED
, EE_CHAR_FONTINFO
},
346 // info to get CJK font to be used
347 { LANGUAGE_JAPANESE
, LANGUAGE_NONE
,
348 DEFAULTFONT_CJK_TEXT
, EE_CHAR_FONTINFO_CJK
},
349 // info to get CTL font to be used
350 { LANGUAGE_ARABIC_SAUDI_ARABIA
, LANGUAGE_NONE
,
351 DEFAULTFONT_CTL_TEXT
, EE_CHAR_FONTINFO_CTL
}
353 aTable
[0].nLang
= aOpt
.nDefaultLanguage
;
354 aTable
[1].nLang
= aOpt
.nDefaultLanguage_CJK
;
355 aTable
[2].nLang
= aOpt
.nDefaultLanguage_CTL
;
357 for (int i
= 0; i
< 3; ++i
)
359 const FontDta
&rFntDta
= aTable
[i
];
360 LanguageType nLang
= (LANGUAGE_NONE
== rFntDta
.nLang
) ?
361 rFntDta
.nFallbackLang
: rFntDta
.nLang
;
362 Font aFont
= Application::GetDefaultDevice()->GetDefaultFont(
363 rFntDta
.nFontType
, nLang
, DEFAULTFONT_FLAGS_ONLYONE
);
365 ByteString
aFntName( aFont
.GetName(), 1 );
366 int eFntFamily
= aFont
.GetFamily();
367 ByteString
aFntStyleName( aFont
.GetStyleName(), 1 );
368 int ePitch
= aFont
.GetPitch();
369 int eCharSet
= aFont
.GetCharSet();
370 fprintf(stderr
, "\nFontName %s \n", aFntName
.GetBuffer() );
371 fprintf(stderr
, "StyleName %s \n", aFntStyleName
.GetBuffer() );
372 fprintf(stderr
, "eFntFamily %d \n", eFntFamily
);
373 fprintf(stderr
, "ePitch %d \n", ePitch
);
374 fprintf(stderr
, "eCharSet %d \n", eCharSet
);
376 rEditEngineItemPool
.SetPoolDefaultItem(
377 SvxFontItem( aFont
.GetFamily(), aFont
.GetName(),
378 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(),
379 rFntDta
.nFontInfoId
) );
383 SvxFontHeightItem
aFontHeigt(
384 Application::GetDefaultDevice()->LogicToPixel(
385 Size( 0, 11 ), MapMode( MAP_POINT
) ).Height(), 100,
386 EE_CHAR_FONTHEIGHT
);
387 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
388 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CJK
);
389 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
390 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CTL
);
391 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
395 EditEngine
& SmDocShell::GetEditEngine()
397 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetEditEngine" );
402 //! see also SmEditWindow::DataChanged !
405 pEditEngineItemPool
= EditEngine::CreatePool();
407 SetEditEngineDefaultFonts( *pEditEngine
, *pEditEngineItemPool
);
409 pEditEngine
= new EditEngine( pEditEngineItemPool
);
411 pEditEngine
->EnableUndo( sal_True
);
412 pEditEngine
->SetDefTab( sal_uInt16(
413 Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) );
415 pEditEngine
->SetControlWord(
416 (pEditEngine
->GetControlWord() | EE_CNTRL_AUTOINDENTING
) &
417 (~EE_CNTRL_UNDOATTRIBS
) &
418 (~EE_CNTRL_PASTESPECIAL
) );
420 pEditEngine
->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) );
421 pEditEngine
->SetRefMapMode( MAP_PIXEL
);
423 pEditEngine
->SetPaperSize( Size( 800, 0 ) );
425 pEditEngine
->EraseVirtualDevice();
427 // set initial text if the document already has some...
428 // (may be the case when reloading a doc)
429 String
aTxt( GetText() );
431 pEditEngine
->SetText( aTxt
);
433 pEditEngine
->ClearModifyFlag();
435 // forces new settings to be used if the itempool was modified
436 // after cthe creation of the EditEngine
437 //pEditEngine->Clear(); //#77957 incorrect font size
443 SfxItemPool
& SmDocShell::GetEditEngineItemPool()
445 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetEditEngineItemPool" );
447 if (!pEditEngineItemPool
)
449 DBG_ASSERT( pEditEngineItemPool
, "EditEngineItemPool missing" );
450 return *pEditEngineItemPool
;
454 void SmDocShell::Draw(OutputDevice
&rDev
, Point
&rPosition
)
456 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Draw" );
460 DBG_ASSERT(pTree
, "Sm : NULL pointer");
462 if (!IsFormulaArranged())
465 //Problem: Was passiert mit dem WYSIWYG? Wir haben waehrend wir inplace aktiv
466 //sind kein Referenzdevice und sind auch nicht darauf ausgerichtet. Es kann
467 //also jetzt eine Differenz zwischen der VisArea (spricht die Groesse im Client)
468 //und der jetzt vorliegenden Groese geben.
469 //Idee: Die Differenz koennte, zumindest behelfsmaessig, mit SmNod::SetSize
472 rPosition
.X() += aFormat
.GetDistance( DIS_LEFTSPACE
);
473 rPosition
.Y() += aFormat
.GetDistance( DIS_TOPSPACE
);
475 //! in case of high contrast-mode (accessibility option!)
476 //! the draw mode needs to be set to default, because when imbedding
477 //! Math for example in Calc in "a over b" the fraction bar may not
478 //! be visible else. More generally: the FillColor may have been changed.
479 sal_uLong nOldDrawMode
= DRAWMODE_DEFAULT
;
480 sal_Bool bRestoreDrawMode
= sal_False
;
481 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
482 ((Window
&) rDev
).GetSettings().GetStyleSettings().GetHighContrastMode())
484 nOldDrawMode
= rDev
.GetDrawMode();
485 rDev
.SetDrawMode( DRAWMODE_DEFAULT
);
486 bRestoreDrawMode
= sal_True
;
489 // format/draw formulas always from left to right
490 // and numbers should not be converted
491 sal_uLong nLayoutMode
= rDev
.GetLayoutMode();
492 rDev
.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
);
493 sal_Int16 nDigitLang
= rDev
.GetDigitLanguage();
494 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
496 pTree
->Draw(rDev
, rPosition
);
498 rDev
.SetLayoutMode( nLayoutMode
);
499 rDev
.SetDigitLanguage( nDigitLang
);
501 if (bRestoreDrawMode
)
502 rDev
.SetDrawMode( nOldDrawMode
);
507 Size
SmDocShell::GetSize()
509 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetSize" );
518 if (!IsFormulaArranged())
520 aRet
= pTree
->GetSize();
525 aRet
.Width() += aFormat
.GetDistance( DIS_LEFTSPACE
) +
526 aFormat
.GetDistance( DIS_RIGHTSPACE
);
527 if ( !aRet
.Height() )
528 aRet
.Height() = 1000;
530 aRet
.Height() += aFormat
.GetDistance( DIS_TOPSPACE
) +
531 aFormat
.GetDistance( DIS_BOTTOMSPACE
);
537 ////////////////////////////////////////
539 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
541 if ( 0 != (pPrinter
= rDocShell
.GetPrt()) )
543 pPrinter
->Push( PUSH_MAPMODE
);
544 if ( SFX_CREATE_MODE_EMBEDDED
== rDocShell
.GetCreateMode() )
546 // if it is an embedded object (without it's own printer)
547 // we change the MapMode temporarily.
548 //!If it is a document with it's own printer the MapMode should
549 //!be set correct (once) elsewhere(!), in order to avoid numerous
550 //!superfluous pushing and poping of the MapMode when using
553 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
554 if ( MAP_100TH_MM
!= eOld
)
556 MapMode
aMap( pPrinter
->GetMapMode() );
557 aMap
.SetMapUnit( MAP_100TH_MM
);
558 Point
aTmp( aMap
.GetOrigin() );
559 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
560 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
561 aMap
.SetOrigin( aTmp
);
562 pPrinter
->SetMapMode( aMap
);
566 if ( 0 != (pRefDev
= rDocShell
.GetRefDev()) && pPrinter
!= pRefDev
)
568 pRefDev
->Push( PUSH_MAPMODE
);
569 if ( SFX_CREATE_MODE_EMBEDDED
== rDocShell
.GetCreateMode() )
571 // if it is an embedded object (without it's own printer)
572 // we change the MapMode temporarily.
573 //!If it is a document with it's own printer the MapMode should
574 //!be set correct (once) elsewhere(!), in order to avoid numerous
575 //!superfluous pushing and poping of the MapMode when using
578 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
579 if ( MAP_100TH_MM
!= eOld
)
581 MapMode
aMap( pRefDev
->GetMapMode() );
582 aMap
.SetMapUnit( MAP_100TH_MM
);
583 Point
aTmp( aMap
.GetOrigin() );
584 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
585 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
586 aMap
.SetOrigin( aTmp
);
587 pRefDev
->SetMapMode( aMap
);
593 SmPrinterAccess::~SmPrinterAccess()
597 if ( pRefDev
&& pRefDev
!= pPrinter
)
601 ////////////////////////////////////////
603 Printer
* SmDocShell::GetPrt()
605 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetPrt" );
607 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
609 //Normalerweise wird der Printer vom Server besorgt. Wenn dieser aber
610 //keinen liefert (weil etwa noch keine connection da ist), kann es
611 //dennoch sein, dass wir den Printer kennen, denn dieser wird in
612 //OnDocumentPrinterChanged vom Server durchgereicht und dann temporaer
614 Printer
*pPrt
= GetDocumentPrinter();
615 if ( !pPrt
&& pTmpPrinter
)
619 else if ( !pPrinter
)
621 SfxItemSet
*pOptions
=
622 new SfxItemSet(GetPool(),
623 SID_PRINTSIZE
, SID_PRINTSIZE
,
624 SID_PRINTZOOM
, SID_PRINTZOOM
,
625 SID_PRINTTITLE
, SID_PRINTTITLE
,
626 SID_PRINTTEXT
, SID_PRINTTEXT
,
627 SID_PRINTFRAME
, SID_PRINTFRAME
,
628 SID_NO_RIGHT_SPACES
, SID_NO_RIGHT_SPACES
,
631 SmModule
*pp
= SM_MOD();
632 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
633 pPrinter
= new SfxPrinter(pOptions
);
634 pPrinter
->SetMapMode( MapMode(MAP_100TH_MM
) );
639 OutputDevice
* SmDocShell::GetRefDev()
641 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetRefDev" );
643 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
645 OutputDevice
* pOutDev
= GetDocumentRefDev();
654 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
656 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetPrinter" );
659 pPrinter
= pNew
; //Eigentumsuebergang!
660 pPrinter
->SetMapMode( MapMode(MAP_100TH_MM
) );
661 SetFormulaArranged(sal_False
);
665 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
667 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::OnDocumentPrinterChanged" );
670 SetFormulaArranged(sal_False
);
671 Size aOldSize
= GetVisArea().GetSize();
673 if( aOldSize
!= GetVisArea().GetSize() && aText
.Len() )
674 SetModified( sal_True
);
678 void SmDocShell::Repaint()
680 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Repaint" );
682 sal_Bool bIsEnabled
= IsEnableSetModified();
684 EnableSetModified( sal_False
);
686 SetFormulaArranged( sal_False
);
688 Size aVisSize
= GetSize();
689 SetVisAreaSize( aVisSize
);
690 SmViewShell
*pViewSh
= SmGetActiveView();
692 pViewSh
->GetGraphicWindow().Invalidate();
695 EnableSetModified( bIsEnabled
);
699 SmDocShell::SmDocShell( const sal_uInt64 i_nSfxCreationFlags
) :
700 SfxObjectShell( i_nSfxCreationFlags
),
702 pEditEngineItemPool ( 0 ),
707 bIsFormulaArranged ( sal_False
)
709 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SmDocShell" );
711 SetPool(&SFX_APP()->GetPool());
713 SmModule
*pp
= SM_MOD();
714 aFormat
= pp
->GetConfig()->GetStandardFormat();
716 StartListening(aFormat
);
717 StartListening(*pp
->GetConfig());
719 SetBaseModel( new SmModel(this) );
724 SmDocShell::~SmDocShell()
726 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::~SmDocShell" );
728 SmModule
*pp
= SM_MOD();
730 EndListening(aFormat
);
731 EndListening(*pp
->GetConfig());
734 SfxItemPool::Free(pEditEngineItemPool
);
740 sal_Bool
SmDocShell::SetData( const String
& rData
)
742 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetData" );
749 sal_Bool
SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
751 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ConvertFrom" );
753 sal_Bool bSuccess
= sal_False
;
754 const String
& rFltName
= rMedium
.GetFilter()->GetFilterName();
756 DBG_ASSERT( !rFltName
.EqualsAscii( STAROFFICE_XML
), "Wrong filter!");
758 if ( rFltName
.EqualsAscii( MATHML_XML
) )
765 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
766 SmXMLImportWrapper
aEquation(xModel
);
767 bSuccess
= 0 == aEquation
.Import(rMedium
);
771 SvStream
*pStream
= rMedium
.GetInStream();
774 if ( SotStorage::IsStorageFile( pStream
) )
776 SvStorageRef aStorage
= new SotStorage( pStream
, sal_False
);
777 if ( aStorage
->IsStream( C2S( "Equation Native" ) ) )
779 // is this a MathType Storage?
780 MathType
aEquation( aText
);
781 if ( sal_True
== (bSuccess
= (1 == aEquation
.Parse( aStorage
)) ))
787 //bSuccess = ImportSM20File( pStream );
792 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
794 //???OnDocumentPrinterChanged(0);
795 SetFormulaArranged( sal_False
);
799 FinishedLoading( SFX_LOADED_ALL
);
804 sal_Bool
SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
806 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::InitNew" );
808 sal_Bool bRet
= sal_False
;
809 if ( SfxObjectShell::InitNew( xStorage
) )
812 SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
818 sal_Bool
SmDocShell::Load( SfxMedium
& rMedium
)
820 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Load" );
822 sal_Bool bRet
= sal_False
;
823 if( SfxObjectShell::Load( rMedium
))
825 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
826 uno::Reference
< container::XNameAccess
> xAccess (xStorage
, uno::UNO_QUERY
);
829 xAccess
->hasByName( C2S( "content.xml" ) ) &&
830 xStorage
->isStreamElement( C2S( "content.xml" ) )
833 xAccess
->hasByName( C2S( "Content.xml" ) ) &&
834 xStorage
->isStreamElement( C2S( "Content.xml" ) )
838 // is this a fabulous math package ?
839 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
840 SmXMLImportWrapper
aEquation(xModel
);
841 sal_uLong nError
= aEquation
.Import(rMedium
);
843 SetError( nError
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
847 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
849 //???OnDocumentPrinterChanged(0);
850 SetFormulaArranged( sal_False
);
854 FinishedLoading( SFX_LOADED_ALL
);
858 //------------------------------------------------------------------
860 sal_Bool
SmDocShell::Save()
862 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Save" );
864 //! apply latest changes if necessary
867 if ( SfxObjectShell::Save() )
871 if( pTree
&& !IsFormulaArranged() )
874 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
875 SmXMLExportWrapper
aEquation(xModel
);
876 aEquation
.SetFlat(sal_False
);
877 return aEquation
.Export(*GetMedium());
884 * replace bad characters that can not be saved. (#i74144)
886 sal_Bool
SmDocShell::ReplaceBadChars()
888 sal_Bool bReplace
= sal_False
;
891 String
aEngTxt( pEditEngine
->GetText( LINEEND_LF
) );
892 const sal_Unicode
*pEngTxt
= aEngTxt
.GetBuffer();
893 xub_StrLen nLen
= aEngTxt
.Len();
894 for (xub_StrLen i
= 0; i
< nLen
&& !bReplace
; ++i
)
896 const sal_Unicode c
= *pEngTxt
++;
897 if (c
< ' ' && c
!= '\r' && c
!= '\n' && c
!= '\t')
902 sal_Unicode
*pChgTxt
= aEngTxt
.GetBufferAccess();
903 for (xub_StrLen i
= 0; i
< nLen
; ++i
)
905 sal_Unicode
&rc
= *pChgTxt
++;
906 if (rc
< ' ' && rc
!= '\r' && rc
!= '\n' && rc
!= '\t')
909 aEngTxt
.ReleaseBufferAccess( nLen
);
918 void SmDocShell::UpdateText()
920 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::UpdateText" );
922 if (pEditEngine
&& pEditEngine
->IsModified())
924 String
aEngTxt( pEditEngine
->GetText( LINEEND_LF
) );
925 if (GetText() != aEngTxt
)
931 sal_Bool
SmDocShell::SaveAs( SfxMedium
& rMedium
)
933 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveAs" );
935 sal_Bool bRet
= sal_False
;
937 //! apply latest changes if necessary
940 if ( SfxObjectShell::SaveAs( rMedium
) )
944 if( pTree
&& !IsFormulaArranged() )
947 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
948 SmXMLExportWrapper
aEquation(xModel
);
949 aEquation
.SetFlat(sal_False
);
950 bRet
= aEquation
.Export(rMedium
);
955 sal_Bool
SmDocShell::ConvertTo( SfxMedium
&rMedium
)
957 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ConvertTo" );
959 sal_Bool bRet
= sal_False
;
960 const SfxFilter
* pFlt
= rMedium
.GetFilter();
965 if( pTree
&& !IsFormulaArranged() )
968 const String
& rFltName
= pFlt
->GetFilterName();
969 if(rFltName
.EqualsAscii( STAROFFICE_XML
))
971 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
972 SmXMLExportWrapper
aEquation(xModel
);
973 aEquation
.SetFlat(sal_False
);
974 bRet
= aEquation
.Export(rMedium
);
976 else if(rFltName
.EqualsAscii( MATHML_XML
))
978 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
979 SmXMLExportWrapper
aEquation(xModel
);
980 aEquation
.SetFlat(sal_True
);
981 bRet
= aEquation
.Export(rMedium
);
983 else if( pFlt
->GetFilterName().EqualsAscii("MathType 3.x"))
984 bRet
= WriteAsMathType3( rMedium
);
989 sal_Bool
SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStorage
)
991 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveCompleted" );
993 if( SfxObjectShell::SaveCompleted( xStorage
))
1000 void SmDocShell::Execute(SfxRequest
& rReq
)
1002 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Execute" );
1004 switch (rReq
.GetSlot())
1008 SmFormat aOldFormat
= GetFormat();
1009 SmFormat
aNewFormat( aOldFormat
);
1010 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
1012 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1014 pTmpUndoMgr
->AddUndoAction(
1015 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1017 SetFormat( aNewFormat
);
1022 case SID_AUTO_REDRAW
:
1024 SmModule
*pp
= SM_MOD();
1025 sal_Bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1026 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
1030 case SID_LOADSYMBOLS
:
1034 case SID_SAVESYMBOLS
:
1040 // get device used to retrieve the FontList
1041 OutputDevice
*pDev
= GetPrinter();
1042 if (!pDev
|| pDev
->GetDevFontCount() == 0)
1043 pDev
= &SM_MOD()->GetDefaultVirtualDev();
1044 DBG_ASSERT (pDev
, "device for font list missing" );
1046 SmFontTypeDialog
*pFontTypeDialog
= new SmFontTypeDialog( NULL
, pDev
);
1048 SmFormat aOldFormat
= GetFormat();
1049 pFontTypeDialog
->ReadFrom( aOldFormat
);
1050 if (pFontTypeDialog
->Execute() == RET_OK
)
1052 SmFormat
aNewFormat( aOldFormat
);
1054 pFontTypeDialog
->WriteTo(aNewFormat
);
1055 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1057 pTmpUndoMgr
->AddUndoAction(
1058 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1060 SetFormat( aNewFormat
);
1063 delete pFontTypeDialog
;
1069 SmFontSizeDialog
*pFontSizeDialog
= new SmFontSizeDialog(NULL
);
1071 SmFormat aOldFormat
= GetFormat();
1072 pFontSizeDialog
->ReadFrom( aOldFormat
);
1073 if (pFontSizeDialog
->Execute() == RET_OK
)
1075 SmFormat
aNewFormat( aOldFormat
);
1077 pFontSizeDialog
->WriteTo(aNewFormat
);
1079 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1081 pTmpUndoMgr
->AddUndoAction(
1082 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1084 SetFormat( aNewFormat
);
1087 delete pFontSizeDialog
;
1093 SmDistanceDialog
*pDistanceDialog
= new SmDistanceDialog(NULL
);
1095 SmFormat aOldFormat
= GetFormat();
1096 pDistanceDialog
->ReadFrom( aOldFormat
);
1097 if (pDistanceDialog
->Execute() == RET_OK
)
1099 SmFormat
aNewFormat( aOldFormat
);
1101 pDistanceDialog
->WriteTo(aNewFormat
);
1103 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1105 pTmpUndoMgr
->AddUndoAction(
1106 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1108 SetFormat( aNewFormat
);
1111 delete pDistanceDialog
;
1117 SmAlignDialog
*pAlignDialog
= new SmAlignDialog(NULL
);
1119 SmFormat aOldFormat
= GetFormat();
1120 pAlignDialog
->ReadFrom( aOldFormat
);
1121 if (pAlignDialog
->Execute() == RET_OK
)
1123 SmFormat
aNewFormat( aOldFormat
);
1125 pAlignDialog
->WriteTo(aNewFormat
);
1127 SmModule
*pp
= SM_MOD();
1128 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
1129 pAlignDialog
->WriteTo( aFmt
);
1130 pp
->GetConfig()->SetStandardFormat( aFmt
);
1132 ::svl::IUndoManager
*pTmpUndoMgr
= GetUndoManager();
1134 pTmpUndoMgr
->AddUndoAction(
1135 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1137 SetFormat( aNewFormat
);
1140 delete pAlignDialog
;
1146 const SfxStringItem
& rItem
= (const SfxStringItem
&)rReq
.GetArgs()->Get(SID_TEXT
);
1147 if (GetText() != rItem
.GetValue())
1148 SetText(rItem
.GetValue());
1155 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1158 sal_uInt16 nId
= rReq
.GetSlot(), nCnt
= 1;
1159 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1160 const SfxPoolItem
* pItem
;
1161 if( pArgs
&& SFX_ITEM_SET
== pArgs
->GetItemState( nId
, sal_False
, &pItem
))
1162 nCnt
= ((SfxUInt16Item
*)pItem
)->GetValue();
1164 sal_Bool (::svl::IUndoManager:: *fnDo
)();
1167 if( SID_UNDO
== rReq
.GetSlot() )
1169 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1170 fnDo
= &::svl::IUndoManager::Undo
;
1174 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1175 fnDo
= &::svl::IUndoManager::Redo
;
1180 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
1181 (pTmpUndoMgr
->*fnDo
)();
1183 catch( const Exception
& e
)
1185 DBG_UNHANDLED_EXCEPTION();
1189 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1192 SfxBindings
& rBind
= pFrm
->GetBindings();
1193 rBind
.Invalidate(SID_UNDO
);
1194 rBind
.Invalidate(SID_REDO
);
1195 rBind
.Invalidate(SID_REPEAT
);
1196 rBind
.Invalidate(SID_CLEARHISTORY
);
1197 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1207 void SmDocShell::GetState(SfxItemSet
&rSet
)
1209 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetState" );
1211 SfxWhichIter
aIter(rSet
);
1213 for (sal_uInt16 nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1218 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1221 case SID_DOCTEMPLATE
:
1222 rSet
.DisableItem(SID_DOCTEMPLATE
);
1225 case SID_AUTO_REDRAW
:
1227 SmModule
*pp
= SM_MOD();
1228 sal_Bool bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1230 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1234 case SID_MODIFYSTATUS
:
1236 sal_Unicode cMod
= ' ';
1239 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, String(cMod
)));
1244 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1248 //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
1249 //! If nModifyCount gets changed then the call below will implicitly notify
1250 //! SmGraphicController::StateChanged and there the window gets invalidated.
1251 //! Thus all the 'nModifyCount++' before invalidating this slot.
1252 rSet
.Put(SfxInt16Item(SID_GAPHIC_SM
, nModifyCount
));
1258 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1260 pFrm
->GetSlotState( nWh
, NULL
, &rSet
);
1262 rSet
.DisableItem( nWh
);
1266 case SID_GETUNDOSTRINGS
:
1267 case SID_GETREDOSTRINGS
:
1269 ::svl::IUndoManager
* pTmpUndoMgr
= GetUndoManager();
1272 UniString(::svl::IUndoManager:: *fnGetComment
)( size_t, bool const ) const;
1275 if( SID_GETUNDOSTRINGS
== nWh
)
1277 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1278 fnGetComment
= &::svl::IUndoManager::GetUndoActionComment
;
1282 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1283 fnGetComment
= &::svl::IUndoManager::GetRedoActionComment
;
1288 for( sal_uInt16 n
= 0; n
< nCount
; ++n
)
1289 ( sList
+= (pTmpUndoMgr
->*fnGetComment
)( n
, ::svl::IUndoManager::TopLevel
) )
1292 SfxStringListItem
aItem( nWh
);
1293 aItem
.SetString( sList
);
1298 rSet
.DisableItem( nWh
);
1306 ::svl::IUndoManager
*SmDocShell::GetUndoManager()
1308 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetUndoManager" );
1312 return &pEditEngine
->GetUndoManager();
1316 void SmDocShell::SaveSymbols()
1318 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveSymbols" );
1320 SmModule
*pp
= SM_MOD();
1321 pp
->GetSymbolManager().Save();
1325 void SmDocShell::Draw(OutputDevice
*pDevice
,
1327 sal_uInt16
/*nAspect*/)
1329 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Draw" );
1331 pDevice
->IntersectClipRegion(GetVisArea());
1333 Draw(*pDevice
, atmppoint
);
1336 SfxItemPool
& SmDocShell::GetPool() const
1338 return SFX_APP()->GetPool();
1341 void SmDocShell::SetVisArea(const Rectangle
& rVisArea
)
1343 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetVisArea" );
1345 Rectangle
aNewRect(rVisArea
);
1347 aNewRect
.SetPos(Point());
1349 if (! aNewRect
.Right()) aNewRect
.Right() = 2000;
1350 if (! aNewRect
.Bottom()) aNewRect
.Bottom() = 1000;
1352 sal_Bool bIsEnabled
= IsEnableSetModified();
1354 EnableSetModified( sal_False
);
1356 //TODO/LATER: it's unclear how this interacts with the SFX code
1357 // If outplace editing, then dont resize the OutplaceWindow. But the
1358 // ObjectShell has to resize. Bug 56470
1359 sal_Bool bUnLockFrame
;
1360 if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1362 GetFrame()->LockAdjustPosSizePixel();
1363 bUnLockFrame
= sal_True
;
1366 bUnLockFrame
= sal_False
;
1368 SfxObjectShell::SetVisArea( aNewRect
);
1371 GetFrame()->UnlockAdjustPosSizePixel();
1374 EnableSetModified( bIsEnabled
);
1378 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1379 sal_uInt32
* pFormat
,
1380 String
* /*pAppName*/,
1381 String
* pFullTypeName
,
1382 String
* pShortTypeName
,
1383 sal_Int32 nFileFormat
,
1384 sal_Bool bTemplate
/* = sal_False */) const
1386 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::FillClass" );
1388 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1390 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1391 *pFormat
= SOT_FORMATSTR_ID_STARMATH_60
;
1392 *pFullTypeName
= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
));
1393 *pShortTypeName
= String(SmResId(RID_DOCUMENTSTR
));
1395 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1397 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1398 *pFormat
= bTemplate
? SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE
: SOT_FORMATSTR_ID_STARMATH_8
;
1399 *pFullTypeName
= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
));
1400 *pShortTypeName
= String(SmResId(RID_DOCUMENTSTR
));
1404 sal_uLong
SmDocShell::GetMiscStatus() const
1406 return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
1407 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE
;
1410 void SmDocShell::SetModified(sal_Bool bModified
)
1412 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetModified" );
1414 if( IsEnableSetModified() )
1416 SfxObjectShell::SetModified( bModified
);
1417 Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED
));
1421 sal_Bool
SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1423 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::WriteAsMathType3" );
1425 MathType
aEquation( aText
, pTree
);
1427 sal_Bool bRet
= 0 != aEquation
.ConvertFromStarMath( rMedium
);