1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: document.cxx,v $
10 * $Revision: 1.94.26.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_starmath.hxx"
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/lang/Locale.hpp>
37 #include <com/sun/star/uno/Any.h>
39 #include <comphelper/accessibletexthelper.hxx>
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/storagehelper.hxx>
42 #include <rtl/logfile.hxx>
43 #include <rtl/ustring.hxx>
44 #include <sfx2/app.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <sfx2/docfile.hxx>
47 #include <sfx2/docfilt.hxx>
48 #include <sfx2/fcontnr.hxx>
49 #include <sfx2/msg.hxx>
50 #include <sfx2/objface.hxx>
51 #include <sfx2/printer.hxx>
52 #include <sfx2/request.hxx>
53 #include <sfx2/viewfrm.hxx>
54 #include <sot/clsids.hxx>
55 #include <sot/exchange.hxx>
56 #include <sot/formats.hxx>
57 #include <sot/storage.hxx>
58 #include <svtools/eitem.hxx>
59 #include <svtools/fstathelper.hxx>
60 #include <svtools/intitem.hxx>
61 #include <svtools/itempool.hxx>
62 #include <svtools/lingucfg.hxx>
63 #include <svtools/linguprops.hxx>
64 #include <svtools/pathoptions.hxx>
65 #include <svtools/ptitem.hxx>
66 #include <svtools/sfxecode.hxx>
67 #include <svtools/slstitm.hxx>
68 #include <svtools/smplhint.hxx>
69 #include <svtools/stritem.hxx>
70 #include <svtools/transfer.hxx>
71 #include <svtools/undo.hxx>
72 #include <svtools/urihelper.hxx>
73 #include <svtools/whiter.hxx>
74 #include <svx/editeng.hxx>
75 #include <svx/editstat.hxx>
76 #include <svx/eeitem.hxx>
77 #include <svx/fhgtitem.hxx>
78 #include <svx/fontitem.hxx>
79 #include <svx/unolingu.hxx>
80 #include <ucbhelper/content.hxx>
81 #include <vcl/mapmod.hxx>
82 #include <vcl/mapunit.hxx>
83 #include <vcl/msgbox.hxx>
85 #include <document.hxx>
91 #include <starmath.hrc>
93 #include <toolbox.hxx>
94 #include <unomodel.hxx>
95 #include <utility.hxx>
97 #include "mathtype.hxx"
98 #include "mathmlimport.hxx"
99 #include "mathmlexport.hxx"
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 (USHORT)32768
112 static const char __FAR_DATA pStarMathDoc
[] = "StarMathDocument";
115 /**************************************************************************/
118 ** CLASS IMPLEMENTATION
123 #include "smslots.hxx"
125 TYPEINIT1( SmDocShell
, SfxObjectShell
);
127 SFX_IMPL_INTERFACE(SmDocShell
, SfxObjectShell
, SmResId(0))
129 SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU
));
130 SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU
));
133 SFX_IMPL_OBJECTFACTORY(SmDocShell
, SvGlobalName(SO3_SM_CLASSID
), SFXOBJECTSHELL_STD_NORMAL
, "smath" )
135 void SmDocShell::SFX_NOTIFY(SfxBroadcaster
&, const TypeId
&,
136 const SfxHint
& rHint
, const TypeId
&)
138 switch (((SfxSimpleHint
&)rHint
).GetId())
140 case HINT_FORMATCHANGED
:
141 SetFormulaArranged(FALSE
);
142 nModifyCount
++; //! merkwuerdig...
143 // ohne dies wird die Grafik letztlich
150 void SmDocShell::LoadSymbols()
152 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::LoadSymbols" );
154 SmModule
*pp
= SM_MOD1();
155 pp
->GetSymSetManager().Load();
159 const String
SmDocShell::GetComment() const
161 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetComment" );
162 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
163 const_cast<SmDocShell
*>(this)->GetModel(), uno::UNO_QUERY_THROW
);
164 uno::Reference
<document::XDocumentProperties
> xDocProps(
165 xDPS
->getDocumentProperties());
166 return xDocProps
->getDescription();
170 void SmDocShell::SetText(const String
& rBuffer
)
172 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetText" );
174 if (rBuffer
!= aText
)
176 BOOL bIsEnabled
= IsEnableSetModified();
178 EnableSetModified( FALSE
);
181 SetFormulaArranged( FALSE
);
186 SmViewShell
*pViewSh
= SmGetActiveView();
189 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_TEXT
);
190 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
193 pViewSh
->GetGraphicWindow().Invalidate();
197 EnableSetModified( bIsEnabled
);
200 // launch accessible event if necessary
201 SmGraphicAccessible
*pAcc
= pViewSh
? pViewSh
->GetGraphicWindow().GetAccessible_Impl() : 0;
204 Any aOldValue
, aNewValue
;
205 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText
, rBuffer
, aOldValue
, aNewValue
) )
207 pAcc
->LaunchEvent( AccessibleEventId::TEXT_CHANGED
,
208 aOldValue
, aNewValue
);
212 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
213 OnDocumentPrinterChanged(0);
217 void SmDocShell::SetFormat(SmFormat
& rFormat
)
219 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetFormat" );
222 SetFormulaArranged(FALSE
);
223 SmViewShell
*pViewSh
= SmGetActiveView();
225 pViewSh
->GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM
);
229 String
SmDocShell::GetAccessibleText()
231 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetAccessibleText" );
233 if (!IsFormulaArranged())
235 if (0 == aAccText
.Len())
237 DBG_ASSERT( pTree
, "Tree missing" );
239 pTree
->GetAccessibleText( aAccText
);
244 void SmDocShell::Parse()
246 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Parse" );
251 pTree
= aInterpreter
.Parse(aText
);
253 SetFormulaArranged( FALSE
);
257 void SmDocShell::ArrangeFormula()
259 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ArrangeFormula" );
261 if (IsFormulaArranged())
264 //! Nur f�r die Dauer der Existenz dieses Objekts sind am Drucker die
265 //! richtigen Einstellungen garantiert.
266 SmPrinterAccess
aPrtAcc(*this);
267 // OutputDevice *pOutDev = aPrtAcc.GetPrinter();
268 OutputDevice
* pOutDev
= aPrtAcc
.GetRefDev();
272 #if OSL_DEBUG_LEVEL > 1
273 DBG_ERROR("!! SmDocShell::ArrangeFormula: reference device missing !!");
277 // falls n�tig ein anderes OutputDevice holen f�r das formatiert wird
280 SmViewShell
*pView
= SmGetActiveView();
282 pOutDev
= &pView
->GetGraphicWindow();
285 pOutDev
= &SM_MOD1()->GetDefaultVirtualDev();
286 pOutDev
->SetMapMode( MapMode(MAP_100TH_MM
) );
289 DBG_ASSERT(pOutDev
->GetMapMode().GetMapUnit() == MAP_100TH_MM
,
290 "Sm : falscher MapMode");
292 const SmFormat
&rFormat
= GetFormat();
293 pTree
->Prepare(rFormat
, *this);
295 // format/draw formulas always from left to right,
296 // and numbers should not be converted
297 ULONG nLayoutMode
= pOutDev
->GetLayoutMode();
298 pOutDev
->SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
);
299 INT16 nDigitLang
= pOutDev
->GetDigitLanguage();
300 pOutDev
->SetDigitLanguage( LANGUAGE_ENGLISH
);
302 pTree
->Arrange(*pOutDev
, rFormat
);
304 pOutDev
->SetLayoutMode( nLayoutMode
);
305 pOutDev
->SetDigitLanguage( nDigitLang
);
307 SetFormulaArranged(TRUE
);
309 // invalidate accessible text
314 void SetEditEngineDefaultFonts(
315 EditEngine
&/*rEditEngine*/,
316 SfxItemPool
&rEditEngineItemPool
)
319 // set fonts to be used
321 SvtLinguOptions aOpt
;
322 SvtLinguConfig().GetOptions( aOpt
);
331 // info to get western font to be used
332 { LANGUAGE_ENGLISH_US
, LANGUAGE_NONE
,
333 DEFAULTFONT_FIXED
, EE_CHAR_FONTINFO
},
334 // info to get CJK font to be used
335 { LANGUAGE_JAPANESE
, LANGUAGE_NONE
,
336 DEFAULTFONT_CJK_TEXT
, EE_CHAR_FONTINFO_CJK
},
337 // info to get CTL font to be used
338 { LANGUAGE_ARABIC_SAUDI_ARABIA
, LANGUAGE_NONE
,
339 DEFAULTFONT_CTL_TEXT
, EE_CHAR_FONTINFO_CTL
}
341 aTable
[0].nLang
= aOpt
.nDefaultLanguage
;
342 aTable
[1].nLang
= aOpt
.nDefaultLanguage_CJK
;
343 aTable
[2].nLang
= aOpt
.nDefaultLanguage_CTL
;
345 for (int i
= 0; i
< 3; ++i
)
347 const FontDta
&rFntDta
= aTable
[i
];
348 LanguageType nLang
= (LANGUAGE_NONE
== rFntDta
.nLang
) ?
349 rFntDta
.nFallbackLang
: rFntDta
.nLang
;
350 Font aFont
= Application::GetDefaultDevice()->GetDefaultFont(
351 rFntDta
.nFontType
, nLang
, DEFAULTFONT_FLAGS_ONLYONE
);
353 ByteString
aFntName( aFont
.GetName(), 1 );
354 int eFntFamily
= aFont
.GetFamily();
355 ByteString
aFntStyleName( aFont
.GetStyleName(), 1 );
356 int ePitch
= aFont
.GetPitch();
357 int eCharSet
= aFont
.GetCharSet();
358 fprintf(stderr
, "\nFontName %s \n", aFntName
.GetBuffer() );
359 fprintf(stderr
, "StyleName %s \n", aFntStyleName
.GetBuffer() );
360 fprintf(stderr
, "eFntFamily %d \n", eFntFamily
);
361 fprintf(stderr
, "ePitch %d \n", ePitch
);
362 fprintf(stderr
, "eCharSet %d \n", eCharSet
);
364 rEditEngineItemPool
.SetPoolDefaultItem(
365 SvxFontItem( aFont
.GetFamily(), aFont
.GetName(),
366 aFont
.GetStyleName(), aFont
.GetPitch(), aFont
.GetCharSet(),
367 rFntDta
.nFontInfoId
) );
371 SvxFontHeightItem
aFontHeigt(
372 Application::GetDefaultDevice()->LogicToPixel(
373 Size( 0, 11 ), MapMode( MAP_POINT
) ).Height(), 100,
374 EE_CHAR_FONTHEIGHT
);
375 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
376 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CJK
);
377 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
378 aFontHeigt
.SetWhich( EE_CHAR_FONTHEIGHT_CTL
);
379 rEditEngineItemPool
.SetPoolDefaultItem( aFontHeigt
);
383 EditEngine
& SmDocShell::GetEditEngine()
385 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetEditEngine" );
390 //! see also SmEditWindow::DataChanged !
393 pEditEngineItemPool
= EditEngine::CreatePool();
395 SetEditEngineDefaultFonts( *pEditEngine
, *pEditEngineItemPool
);
397 pEditEngine
= new EditEngine( pEditEngineItemPool
);
399 pEditEngine
->EnableUndo( TRUE
);
400 pEditEngine
->SetDefTab( USHORT(
401 Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) );
403 pEditEngine
->SetControlWord(
404 (pEditEngine
->GetControlWord() | EE_CNTRL_AUTOINDENTING
) &
405 (~EE_CNTRL_UNDOATTRIBS
) &
406 (~EE_CNTRL_PASTESPECIAL
) );
408 pEditEngine
->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) );
409 pEditEngine
->SetRefMapMode( MAP_PIXEL
);
411 pEditEngine
->SetPaperSize( Size( 800, 0 ) );
413 pEditEngine
->EraseVirtualDevice();
415 // set initial text if the document already has some...
416 // (may be the case when reloading a doc)
417 String
aTxt( GetText() );
419 pEditEngine
->SetText( aTxt
);
421 pEditEngine
->ClearModifyFlag();
423 // forces new settings to be used if the itempool was modified
424 // after cthe creation of the EditEngine
425 //pEditEngine->Clear(); //#77957 incorrect font size
431 SfxItemPool
& SmDocShell::GetEditEngineItemPool()
433 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetEditEngineItemPool" );
435 if (!pEditEngineItemPool
)
437 DBG_ASSERT( pEditEngineItemPool
, "EditEngineItemPool missing" );
438 return *pEditEngineItemPool
;
442 void SmDocShell::Draw(OutputDevice
&rDev
, Point
&rPosition
)
444 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Draw" );
448 DBG_ASSERT(pTree
, "Sm : NULL pointer");
450 if (!IsFormulaArranged())
453 //Problem: Was passiert mit dem WYSIWYG? Wir haben waehrend wir inplace aktiv
454 //sind kein Referenzdevice und sind auch nicht darauf ausgerichtet. Es kann
455 //also jetzt eine Differenz zwischen der VisArea (spricht die Groesse im Client)
456 //und der jetzt vorliegenden Groese geben.
457 //Idee: Die Differenz koennte, zumindest behelfsmaessig, mit SmNod::SetSize
460 rPosition
.X() += aFormat
.GetDistance( DIS_LEFTSPACE
);
461 rPosition
.Y() += aFormat
.GetDistance( DIS_TOPSPACE
);
463 //! in case of high contrast-mode (accessibility option!)
464 //! the draw mode needs to be set to default, because when imbedding
465 //! Math for example in Calc in "a over b" the fraction bar may not
466 //! be visible else. More generally: the FillColor may have been changed.
467 ULONG nOldDrawMode
= DRAWMODE_DEFAULT
;
468 BOOL bRestoreDrawMode
= FALSE
;
469 if (OUTDEV_WINDOW
== rDev
.GetOutDevType() &&
470 ((Window
&) rDev
).GetDisplayBackground().GetColor().IsDark())
472 nOldDrawMode
= rDev
.GetDrawMode();
473 rDev
.SetDrawMode( DRAWMODE_DEFAULT
);
474 bRestoreDrawMode
= TRUE
;
477 // format/draw formulas always from left to right
478 // and numbers should not be converted
479 ULONG nLayoutMode
= rDev
.GetLayoutMode();
480 rDev
.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
);
481 INT16 nDigitLang
= rDev
.GetDigitLanguage();
482 rDev
.SetDigitLanguage( LANGUAGE_ENGLISH
);
484 pTree
->Draw(rDev
, rPosition
);
486 rDev
.SetLayoutMode( nLayoutMode
);
487 rDev
.SetDigitLanguage( nDigitLang
);
489 if (bRestoreDrawMode
)
490 rDev
.SetDrawMode( nOldDrawMode
);
495 Size
SmDocShell::GetSize()
497 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetSize" );
506 if (!IsFormulaArranged())
508 aRet
= pTree
->GetSize();
513 aRet
.Width() += aFormat
.GetDistance( DIS_LEFTSPACE
) +
514 aFormat
.GetDistance( DIS_RIGHTSPACE
);
515 if ( !aRet
.Height() )
516 aRet
.Height() = 1000;
518 aRet
.Height() += aFormat
.GetDistance( DIS_TOPSPACE
) +
519 aFormat
.GetDistance( DIS_BOTTOMSPACE
);
525 ////////////////////////////////////////
527 SmPrinterAccess::SmPrinterAccess( SmDocShell
&rDocShell
)
529 if ( 0 != (pPrinter
= rDocShell
.GetPrt()) )
531 pPrinter
->Push( PUSH_MAPMODE
);
532 if ( SFX_CREATE_MODE_EMBEDDED
== rDocShell
.GetCreateMode() )
534 // if it is an embedded object (without it's own printer)
535 // we change the MapMode temporarily.
536 //!If it is a document with it's own printer the MapMode should
537 //!be set correct (once) elsewhere(!), in order to avoid numerous
538 //!superfluous pushing and poping of the MapMode when using
541 const MapUnit eOld
= pPrinter
->GetMapMode().GetMapUnit();
542 if ( MAP_100TH_MM
!= eOld
)
544 MapMode
aMap( pPrinter
->GetMapMode() );
545 aMap
.SetMapUnit( MAP_100TH_MM
);
546 Point
aTmp( aMap
.GetOrigin() );
547 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
548 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
549 aMap
.SetOrigin( aTmp
);
550 pPrinter
->SetMapMode( aMap
);
554 if ( 0 != (pRefDev
= rDocShell
.GetRefDev()) && pPrinter
!= pRefDev
)
556 pRefDev
->Push( PUSH_MAPMODE
);
557 if ( SFX_CREATE_MODE_EMBEDDED
== rDocShell
.GetCreateMode() )
559 // if it is an embedded object (without it's own printer)
560 // we change the MapMode temporarily.
561 //!If it is a document with it's own printer the MapMode should
562 //!be set correct (once) elsewhere(!), in order to avoid numerous
563 //!superfluous pushing and poping of the MapMode when using
566 const MapUnit eOld
= pRefDev
->GetMapMode().GetMapUnit();
567 if ( MAP_100TH_MM
!= eOld
)
569 MapMode
aMap( pRefDev
->GetMapMode() );
570 aMap
.SetMapUnit( MAP_100TH_MM
);
571 Point
aTmp( aMap
.GetOrigin() );
572 aTmp
.X() = OutputDevice::LogicToLogic( aTmp
.X(), eOld
, MAP_100TH_MM
);
573 aTmp
.Y() = OutputDevice::LogicToLogic( aTmp
.Y(), eOld
, MAP_100TH_MM
);
574 aMap
.SetOrigin( aTmp
);
575 pRefDev
->SetMapMode( aMap
);
581 SmPrinterAccess::~SmPrinterAccess()
585 if ( pRefDev
&& pRefDev
!= pPrinter
)
589 ////////////////////////////////////////
591 Printer
* SmDocShell::GetPrt()
593 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetPrt" );
595 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
597 //Normalerweise wird der Printer vom Server besorgt. Wenn dieser aber
598 //keinen liefert (weil etwa noch keine connection da ist), kann es
599 //dennoch sein, dass wir den Printer kennen, denn dieser wird in
600 //OnDocumentPrinterChanged vom Server durchgereicht und dann temporaer
602 Printer
*pPrt
= GetDocumentPrinter();
603 if ( !pPrt
&& pTmpPrinter
)
607 else if ( !pPrinter
)
609 SfxItemSet
*pOptions
=
610 new SfxItemSet(GetPool(),
611 SID_PRINTSIZE
, SID_PRINTSIZE
,
612 SID_PRINTZOOM
, SID_PRINTZOOM
,
613 SID_PRINTTITLE
, SID_PRINTTITLE
,
614 SID_PRINTTEXT
, SID_PRINTTEXT
,
615 SID_PRINTFRAME
, SID_PRINTFRAME
,
616 SID_NO_RIGHT_SPACES
, SID_NO_RIGHT_SPACES
,
619 SmModule
*pp
= SM_MOD1();
620 pp
->GetConfig()->ConfigToItemSet(*pOptions
);
621 pPrinter
= new SfxPrinter(pOptions
);
622 pPrinter
->SetMapMode( MapMode(MAP_100TH_MM
) );
627 OutputDevice
* SmDocShell::GetRefDev()
629 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetRefDev" );
631 if ( SFX_CREATE_MODE_EMBEDDED
== GetCreateMode() )
633 OutputDevice
* pOutDev
= GetDocumentRefDev();
642 void SmDocShell::SetPrinter( SfxPrinter
*pNew
)
644 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetPrinter" );
647 pPrinter
= pNew
; //Eigentumsuebergang!
648 pPrinter
->SetMapMode( MapMode(MAP_100TH_MM
) );
649 SetFormulaArranged(FALSE
);
653 void SmDocShell::OnDocumentPrinterChanged( Printer
*pPrt
)
655 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::OnDocumentPrinterChanged" );
658 SetFormulaArranged(FALSE
);
659 Size aOldSize
= GetVisArea().GetSize();
661 if( aOldSize
!= GetVisArea().GetSize() && aText
.Len() )
666 void SmDocShell::Repaint()
668 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Repaint" );
670 BOOL bIsEnabled
= IsEnableSetModified();
672 EnableSetModified( FALSE
);
674 SetFormulaArranged( FALSE
);
676 Size aVisSize
= GetSize();
677 SetVisAreaSize( aVisSize
);
678 SmViewShell
*pViewSh
= SmGetActiveView();
680 pViewSh
->GetGraphicWindow().Invalidate();
683 EnableSetModified( bIsEnabled
);
687 SmDocShell::SmDocShell(SfxObjectCreateMode eMode
,const sal_Bool _bScriptSupport
) :
688 SfxObjectShell(eMode
),
690 pEditEngineItemPool ( 0 ),
695 bIsFormulaArranged ( FALSE
)
697 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SmDocShell" );
699 SetPool(&SFX_APP()->GetPool());
701 SmModule
*pp
= SM_MOD1();
702 aFormat
= pp
->GetConfig()->GetStandardFormat();
704 StartListening(aFormat
);
705 StartListening(*pp
->GetConfig());
707 if ( !_bScriptSupport
)
710 SetModel( new SmModel(this) ); //! das hier mit new erzeugte Model brauch
711 //! im Destruktor nicht explizit geloescht werden.
712 //! Dies erledigt das Sfx.
717 SmDocShell::~SmDocShell()
719 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::~SmDocShell" );
721 SmModule
*pp
= SM_MOD1();
723 EndListening(aFormat
);
724 EndListening(*pp
->GetConfig());
727 SfxItemPool::Free(pEditEngineItemPool
);
733 BOOL
SmDocShell::SetData( const String
& rData
)
735 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetData" );
742 BOOL
SmDocShell::ConvertFrom(SfxMedium
&rMedium
)
744 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ConvertFrom" );
746 BOOL bSuccess
= FALSE
;
747 const String
& rFltName
= rMedium
.GetFilter()->GetFilterName();
749 DBG_ASSERT( !rFltName
.EqualsAscii( STAROFFICE_XML
), "Wrong filter!");
751 if ( rFltName
.EqualsAscii( MATHML_XML
) )
758 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
759 SmXMLImportWrapper
aEquation(xModel
);
760 bSuccess
= 0 == aEquation
.Import(rMedium
);
764 SvStream
*pStream
= rMedium
.GetInStream();
767 if ( SotStorage::IsStorageFile( pStream
) )
769 SvStorageRef aStorage
= new SotStorage( pStream
, FALSE
);
770 if ( aStorage
->IsStream( C2S( "Equation Native" ) ) )
772 // is this a MathType Storage?
773 MathType
aEquation( aText
);
774 if ( TRUE
== (bSuccess
= (1 == aEquation
.Parse( aStorage
)) ))
780 //bSuccess = ImportSM20File( pStream );
785 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
787 //???OnDocumentPrinterChanged(0);
788 SetFormulaArranged( FALSE
);
792 FinishedLoading( SFX_LOADED_ALL
);
797 BOOL
SmDocShell::InitNew( const uno::Reference
< embed::XStorage
>& xStorage
)
799 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::InitNew" );
802 if ( SfxObjectShell::InitNew( xStorage
) )
805 SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
811 BOOL
SmDocShell::Load( SfxMedium
& rMedium
)
813 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Load" );
816 if( SfxObjectShell::Load( rMedium
))
818 uno::Reference
< embed::XStorage
> xStorage
= GetMedium()->GetStorage();
819 uno::Reference
< container::XNameAccess
> xAccess (xStorage
, uno::UNO_QUERY
);
822 xAccess
->hasByName( C2S( "content.xml" ) ) &&
823 xStorage
->isStreamElement( C2S( "content.xml" ) )
826 xAccess
->hasByName( C2S( "Content.xml" ) ) &&
827 xStorage
->isStreamElement( C2S( "Content.xml" ) )
831 // is this a fabulous math package ?
832 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
833 SmXMLImportWrapper
aEquation(xModel
);
834 ULONG nError
= aEquation
.Import(rMedium
);
836 SetError( nError
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX
) ) );
840 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
)
842 //???OnDocumentPrinterChanged(0);
843 SetFormulaArranged( FALSE
);
847 FinishedLoading( SFX_LOADED_ALL
);
851 //------------------------------------------------------------------
853 BOOL
SmDocShell::Save()
855 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Save" );
857 //! apply latest changes if necessary
860 if ( SfxObjectShell::Save() )
864 if( pTree
&& !IsFormulaArranged() )
867 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
868 SmXMLExportWrapper
aEquation(xModel
);
869 aEquation
.SetFlat(sal_False
);
870 return aEquation
.Export(*GetMedium());
877 * replace bad characters that can not be saved. (#i74144)
879 sal_Bool
SmDocShell::ReplaceBadChars()
881 sal_Bool bReplace
= sal_False
;
884 String
aEngTxt( pEditEngine
->GetText( LINEEND_LF
) );
885 const sal_Unicode
*pEngTxt
= aEngTxt
.GetBuffer();
886 xub_StrLen nLen
= aEngTxt
.Len();
887 for (xub_StrLen i
= 0; i
< nLen
&& !bReplace
; ++i
)
889 const sal_Unicode c
= *pEngTxt
++;
890 if (c
< ' ' && c
!= '\r' && c
!= '\n' && c
!= '\t')
895 sal_Unicode
*pChgTxt
= aEngTxt
.GetBufferAccess();
896 for (xub_StrLen i
= 0; i
< nLen
; ++i
)
898 sal_Unicode
&rc
= *pChgTxt
++;
899 if (rc
< ' ' && rc
!= '\r' && rc
!= '\n' && rc
!= '\t')
902 aEngTxt
.ReleaseBufferAccess( nLen
);
911 void SmDocShell::UpdateText()
913 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::UpdateText" );
915 if (pEditEngine
&& pEditEngine
->IsModified())
917 String
aEngTxt( pEditEngine
->GetText( LINEEND_LF
) );
918 if (GetText() != aEngTxt
)
924 BOOL
SmDocShell::SaveAs( SfxMedium
& rMedium
)
926 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveAs" );
930 //! apply latest changes if necessary
933 if ( SfxObjectShell::SaveAs( rMedium
) )
937 if( pTree
&& !IsFormulaArranged() )
940 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
941 SmXMLExportWrapper
aEquation(xModel
);
942 aEquation
.SetFlat(sal_False
);
943 bRet
= aEquation
.Export(rMedium
);
948 BOOL
SmDocShell::ConvertTo( SfxMedium
&rMedium
)
950 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::ConvertTo" );
953 const SfxFilter
* pFlt
= rMedium
.GetFilter();
958 if( pTree
&& !IsFormulaArranged() )
961 const String
& rFltName
= pFlt
->GetFilterName();
962 if(rFltName
.EqualsAscii( STAROFFICE_XML
))
964 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
965 SmXMLExportWrapper
aEquation(xModel
);
966 aEquation
.SetFlat(sal_False
);
967 bRet
= aEquation
.Export(rMedium
);
969 else if(rFltName
.EqualsAscii( MATHML_XML
))
971 Reference
<com::sun::star::frame::XModel
> xModel(GetModel());
972 SmXMLExportWrapper
aEquation(xModel
);
973 aEquation
.SetFlat(sal_True
);
974 bRet
= aEquation
.Export(rMedium
);
976 else if( pFlt
->GetFilterName().EqualsAscii("MathType 3.x"))
977 bRet
= WriteAsMathType3( rMedium
);
982 BOOL
SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference
< ::com::sun::star::embed::XStorage
>& xStorage
)
984 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveCompleted" );
986 if( SfxObjectShell::SaveCompleted( xStorage
))
993 void SmDocShell::Execute(SfxRequest
& rReq
)
995 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Execute" );
997 switch (rReq
.GetSlot())
1001 SmFormat aOldFormat
= GetFormat();
1002 SmFormat
aNewFormat( aOldFormat
);
1003 aNewFormat
.SetTextmode(!aOldFormat
.IsTextmode());
1005 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
1007 pTmpUndoMgr
->AddUndoAction(
1008 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1010 SetFormat( aNewFormat
);
1015 case SID_AUTO_REDRAW
:
1017 SmModule
*pp
= SM_MOD1();
1018 BOOL bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1019 pp
->GetConfig()->SetAutoRedraw(!bRedraw
);
1023 case SID_LOADSYMBOLS
:
1027 case SID_SAVESYMBOLS
:
1033 // get device used to retrieve the FontList
1034 OutputDevice
*pDev
= GetPrinter();
1035 if (!pDev
|| pDev
->GetDevFontCount() == 0)
1036 pDev
= &SM_MOD1()->GetDefaultVirtualDev();
1037 DBG_ASSERT (pDev
, "device for font list missing" );
1039 SmFontTypeDialog
*pFontTypeDialog
= new SmFontTypeDialog( NULL
, pDev
);
1041 SmFormat aOldFormat
= GetFormat();
1042 pFontTypeDialog
->ReadFrom( aOldFormat
);
1043 if (pFontTypeDialog
->Execute() == RET_OK
)
1045 SmFormat
aNewFormat( aOldFormat
);
1047 pFontTypeDialog
->WriteTo(aNewFormat
);
1048 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
1050 pTmpUndoMgr
->AddUndoAction(
1051 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1053 SetFormat( aNewFormat
);
1056 delete pFontTypeDialog
;
1062 SmFontSizeDialog
*pFontSizeDialog
= new SmFontSizeDialog(NULL
);
1064 SmFormat aOldFormat
= GetFormat();
1065 pFontSizeDialog
->ReadFrom( aOldFormat
);
1066 if (pFontSizeDialog
->Execute() == RET_OK
)
1068 SmFormat
aNewFormat( aOldFormat
);
1070 pFontSizeDialog
->WriteTo(aNewFormat
);
1072 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
1074 pTmpUndoMgr
->AddUndoAction(
1075 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1077 SetFormat( aNewFormat
);
1080 delete pFontSizeDialog
;
1086 SmDistanceDialog
*pDistanceDialog
= new SmDistanceDialog(NULL
);
1088 SmFormat aOldFormat
= GetFormat();
1089 pDistanceDialog
->ReadFrom( aOldFormat
);
1090 if (pDistanceDialog
->Execute() == RET_OK
)
1092 SmFormat
aNewFormat( aOldFormat
);
1094 pDistanceDialog
->WriteTo(aNewFormat
);
1096 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
1098 pTmpUndoMgr
->AddUndoAction(
1099 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1101 SetFormat( aNewFormat
);
1104 delete pDistanceDialog
;
1110 SmAlignDialog
*pAlignDialog
= new SmAlignDialog(NULL
);
1112 SmFormat aOldFormat
= GetFormat();
1113 pAlignDialog
->ReadFrom( aOldFormat
);
1114 if (pAlignDialog
->Execute() == RET_OK
)
1116 SmFormat
aNewFormat( aOldFormat
);
1118 pAlignDialog
->WriteTo(aNewFormat
);
1120 SmModule
*pp
= SM_MOD1();
1121 SmFormat
aFmt( pp
->GetConfig()->GetStandardFormat() );
1122 pAlignDialog
->WriteTo( aFmt
);
1123 pp
->GetConfig()->SetStandardFormat( aFmt
);
1125 SfxUndoManager
*pTmpUndoMgr
= GetUndoManager();
1127 pTmpUndoMgr
->AddUndoAction(
1128 new SmFormatAction(this, aOldFormat
, aNewFormat
));
1130 SetFormat( aNewFormat
);
1133 delete pAlignDialog
;
1139 const SfxStringItem
& rItem
=
1140 (const SfxStringItem
&)rReq
.GetArgs()->Get(SID_TEXT
);
1142 if (GetText() != rItem
.GetValue())
1144 SetText(rItem
.GetValue());
1152 SfxUndoManager
* pTmpUndoMgr
= GetUndoManager();
1155 USHORT nId
= rReq
.GetSlot(), nCnt
= 1;
1156 const SfxItemSet
* pArgs
= rReq
.GetArgs();
1157 const SfxPoolItem
* pItem
;
1158 if( pArgs
&& SFX_ITEM_SET
== pArgs
->GetItemState( nId
, FALSE
, &pItem
))
1159 nCnt
= ((SfxUInt16Item
*)pItem
)->GetValue();
1161 BOOL (SfxUndoManager:: *fnDo
)( USHORT
);
1164 if( SID_UNDO
== rReq
.GetSlot() )
1166 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1167 fnDo
= &SfxUndoManager::Undo
;
1171 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1172 fnDo
= &SfxUndoManager::Redo
;
1175 for( ; nCnt
&& nCount
; --nCnt
, --nCount
)
1176 (pTmpUndoMgr
->*fnDo
)( 0 );
1179 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1182 SfxBindings
& rBind
= pFrm
->GetBindings();
1183 rBind
.Invalidate(SID_UNDO
);
1184 rBind
.Invalidate(SID_REDO
);
1185 rBind
.Invalidate(SID_REPEAT
);
1186 rBind
.Invalidate(SID_CLEARHISTORY
);
1187 pFrm
= SfxViewFrame::GetNext( *pFrm
, this );
1197 void SmDocShell::GetState(SfxItemSet
&rSet
)
1199 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetState" );
1201 SfxWhichIter
aIter(rSet
);
1203 for (USHORT nWh
= aIter
.FirstWhich(); 0 != nWh
; nWh
= aIter
.NextWhich())
1208 rSet
.Put(SfxBoolItem(SID_TEXTMODE
, GetFormat().IsTextmode()));
1211 case SID_DOCTEMPLATE
:
1212 rSet
.DisableItem(SID_DOCTEMPLATE
);
1215 case SID_AUTO_REDRAW
:
1217 SmModule
*pp
= SM_MOD1();
1218 BOOL bRedraw
= pp
->GetConfig()->IsAutoRedraw();
1220 rSet
.Put(SfxBoolItem(SID_AUTO_REDRAW
, bRedraw
));
1224 case SID_MODIFYSTATUS
:
1226 sal_Unicode cMod
= ' ';
1229 rSet
.Put(SfxStringItem(SID_MODIFYSTATUS
, String(cMod
)));
1234 rSet
.Put(SfxStringItem(SID_TEXT
, GetText()));
1238 rSet
.Put(SfxInt16Item(SID_GAPHIC_SM
, nModifyCount
));
1244 SfxViewFrame
* pFrm
= SfxViewFrame::GetFirst( this );
1246 pFrm
->GetSlotState( nWh
, NULL
, &rSet
);
1248 rSet
.DisableItem( nWh
);
1252 case SID_GETUNDOSTRINGS
:
1253 case SID_GETREDOSTRINGS
:
1255 SfxUndoManager
* pTmpUndoMgr
= GetUndoManager();
1258 UniString(SfxUndoManager:: *fnGetComment
)( USHORT
) const;
1261 if( SID_GETUNDOSTRINGS
== nWh
)
1263 nCount
= pTmpUndoMgr
->GetUndoActionCount();
1264 fnGetComment
= &SfxUndoManager::GetUndoActionComment
;
1268 nCount
= pTmpUndoMgr
->GetRedoActionCount();
1269 fnGetComment
= &SfxUndoManager::GetRedoActionComment
;
1274 for( sal_uInt16 n
= 0; n
< nCount
; ++n
)
1275 ( sList
+= (pTmpUndoMgr
->*fnGetComment
)( n
) )
1278 SfxStringListItem
aItem( nWh
);
1279 aItem
.SetString( sList
);
1284 rSet
.DisableItem( nWh
);
1292 SfxUndoManager
*SmDocShell::GetUndoManager()
1294 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::GetUndoManager" );
1298 return &pEditEngine
->GetUndoManager();
1302 void SmDocShell::SaveSymbols()
1304 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SaveSymbols" );
1306 SmModule
*pp
= SM_MOD1();
1307 pp
->GetSymSetManager().Save();
1311 void SmDocShell::Draw(OutputDevice
*pDevice
,
1315 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::Draw" );
1317 pDevice
->IntersectClipRegion(GetVisArea());
1319 Draw(*pDevice
, atmppoint
);
1322 SfxItemPool
& SmDocShell::GetPool() const
1324 return SFX_APP()->GetPool();
1327 void SmDocShell::SetVisArea(const Rectangle
& rVisArea
)
1329 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetVisArea" );
1331 Rectangle
aNewRect(rVisArea
);
1333 aNewRect
.SetPos(Point());
1335 if (! aNewRect
.Right()) aNewRect
.Right() = 2000;
1336 if (! aNewRect
.Bottom()) aNewRect
.Bottom() = 1000;
1338 BOOL bIsEnabled
= IsEnableSetModified();
1340 EnableSetModified( FALSE
);
1342 //TODO/LATER: it's unclear how this interacts with the SFX code
1343 // If outplace editing, then dont resize the OutplaceWindow. But the
1344 // ObjectShell has to resize. Bug 56470
1346 if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED
&& !IsInPlaceActive() && GetFrame() )
1348 GetFrame()->LockAdjustPosSizePixel();
1349 bUnLockFrame
= TRUE
;
1352 bUnLockFrame
= FALSE
;
1354 SfxObjectShell::SetVisArea( aNewRect
);
1357 GetFrame()->UnlockAdjustPosSizePixel();
1360 EnableSetModified( bIsEnabled
);
1364 void SmDocShell::FillClass(SvGlobalName
* pClassName
,
1365 sal_uInt32
* pFormat
,
1366 String
* /*pAppName*/,
1367 String
* pFullTypeName
,
1368 String
* pShortTypeName
,
1369 sal_Int32 nFileFormat
,
1370 sal_Bool bTemplate
/* = sal_False */) const
1372 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::FillClass" );
1374 if (nFileFormat
== SOFFICE_FILEFORMAT_60
)
1376 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1377 *pFormat
= SOT_FORMATSTR_ID_STARMATH_60
;
1378 *pFullTypeName
= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
));
1379 *pShortTypeName
= String(SmResId(RID_DOCUMENTSTR
));
1381 else if (nFileFormat
== SOFFICE_FILEFORMAT_8
)
1383 *pClassName
= SvGlobalName(SO3_SM_CLASSID_60
);
1384 *pFormat
= bTemplate
? SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE
: SOT_FORMATSTR_ID_STARMATH_8
;
1385 *pFullTypeName
= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT
));
1386 *pShortTypeName
= String(SmResId(RID_DOCUMENTSTR
));
1390 ULONG
SmDocShell::GetMiscStatus() const
1392 return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
1393 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE
;
1396 void SmDocShell::SetModified(BOOL bModified
)
1398 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::SetModified" );
1400 if( IsEnableSetModified() )
1402 SfxObjectShell::SetModified( bModified
);
1403 Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED
));
1407 BOOL
SmDocShell::WriteAsMathType3( SfxMedium
& rMedium
)
1409 RTL_LOGFILE_CONTEXT( aLog
, "starmath: SmDocShell::WriteAsMathType3" );
1411 MathType
aEquation( aText
, pTree
);
1413 BOOL bRet
= 0 != aEquation
.ConvertFromStarMath( rMedium
);