Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
21 : #include <com/sun/star/lang/Locale.hpp>
22 : #include <com/sun/star/uno/Any.h>
23 :
24 : #include <comphelper/accessibletexthelper.hxx>
25 : #include <comphelper/processfactory.hxx>
26 : #include <comphelper/storagehelper.hxx>
27 : #include <rtl/ustring.hxx>
28 : #include <unotools/eventcfg.hxx>
29 : #include <sfx2/event.hxx>
30 : #include <sfx2/app.hxx>
31 : #include <sfx2/dispatch.hxx>
32 : #include <sfx2/docfile.hxx>
33 : #include <sfx2/docfilt.hxx>
34 : #include <sfx2/fcontnr.hxx>
35 : #include <sfx2/msg.hxx>
36 : #include <sfx2/objface.hxx>
37 : #include <sfx2/printer.hxx>
38 : #include <sfx2/request.hxx>
39 : #include <sfx2/viewfrm.hxx>
40 : #include <comphelper/classids.hxx>
41 : #include <sot/exchange.hxx>
42 : #include <sot/formats.hxx>
43 : #include <sot/storage.hxx>
44 : #include <svl/eitem.hxx>
45 : #include <svl/fstathelper.hxx>
46 : #include <svl/intitem.hxx>
47 : #include <svl/itempool.hxx>
48 : #include <unotools/lingucfg.hxx>
49 : #include <unotools/linguprops.hxx>
50 : #include <unotools/pathoptions.hxx>
51 : #include <svl/ptitem.hxx>
52 : #include <svtools/sfxecode.hxx>
53 : #include <svl/slstitm.hxx>
54 : #include <svl/smplhint.hxx>
55 : #include <svl/stritem.hxx>
56 : #include <svtools/transfer.hxx>
57 : #include <svl/undo.hxx>
58 : #include <svl/urihelper.hxx>
59 : #include <svl/whiter.hxx>
60 : #include <editeng/editeng.hxx>
61 : #include <editeng/editstat.hxx>
62 : #include <editeng/eeitem.hxx>
63 : #include <editeng/fhgtitem.hxx>
64 : #include <editeng/fontitem.hxx>
65 : #include <editeng/unolingu.hxx>
66 : #include <ucbhelper/content.hxx>
67 : #include <vcl/mapmod.hxx>
68 : #include <tools/mapunit.hxx>
69 : #include <vcl/msgbox.hxx>
70 : #include <vcl/settings.hxx>
71 :
72 : #include <sfx2/sfx.hrc>
73 : #include <document.hxx>
74 : #include <action.hxx>
75 : #include <config.hxx>
76 : #include <dialog.hxx>
77 : #include <format.hxx>
78 : #include <smdll.hxx>
79 : #include <starmath.hrc>
80 : #include <symbol.hxx>
81 : #include <toolbox.hxx>
82 : #include <unomodel.hxx>
83 : #include <utility.hxx>
84 : #include <view.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>
93 : #include "cursor.hxx"
94 : #include <tools/diagnose_ex.h>
95 : #include "visitors.hxx"
96 : #include "accessibility.hxx"
97 :
98 : using namespace ::com::sun::star;
99 : using namespace ::com::sun::star::accessibility;
100 : using namespace ::com::sun::star::lang;
101 : using namespace ::com::sun::star::ucb;
102 : using namespace ::com::sun::star::uno;
103 :
104 : #define SmDocShell
105 : #include "smslots.hxx"
106 :
107 :
108 :
109 :
110 0 : TYPEINIT1( SmDocShell, SfxObjectShell );
111 :
112 0 : SFX_IMPL_INTERFACE(SmDocShell, SfxObjectShell, SmResId(0))
113 : {
114 0 : SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU));
115 0 : SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU));
116 0 : }
117 :
118 0 : SFX_IMPL_OBJECTFACTORY(SmDocShell, SvGlobalName(SO3_SM_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "smath" )
119 :
120 0 : void SmDocShell::SFX_NOTIFY(SfxBroadcaster&, const TypeId&,
121 : const SfxHint& rHint, const TypeId&)
122 : {
123 0 : switch (((SfxSimpleHint&)rHint).GetId())
124 : {
125 : case HINT_FORMATCHANGED:
126 0 : SetFormulaArranged(false);
127 :
128 0 : nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
129 :
130 0 : Repaint();
131 0 : break;
132 : }
133 0 : }
134 :
135 0 : void SmDocShell::LoadSymbols()
136 : {
137 : SAL_INFO( "starmath", "SmDocShell::LoadSymbols" );
138 :
139 0 : SmModule *pp = SM_MOD();
140 0 : pp->GetSymbolManager().Load();
141 0 : }
142 :
143 :
144 0 : const OUString SmDocShell::GetComment() const
145 : {
146 : SAL_INFO( "starmath", "SmDocShell::GetComment" );
147 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
148 0 : const_cast<SmDocShell*>(this)->GetModel(), uno::UNO_QUERY_THROW);
149 : uno::Reference<document::XDocumentProperties> xDocProps(
150 0 : xDPS->getDocumentProperties());
151 0 : return xDocProps->getDescription();
152 : }
153 :
154 :
155 0 : void SmDocShell::SetText(const OUString& rBuffer)
156 : {
157 : SAL_INFO( "starmath", "SmDocShell::SetText" );
158 :
159 0 : if (rBuffer != aText)
160 : {
161 0 : bool bIsEnabled = IsEnableSetModified();
162 0 : if( bIsEnabled )
163 0 : EnableSetModified( false );
164 :
165 0 : aText = rBuffer;
166 0 : SetFormulaArranged( false );
167 :
168 0 : Parse();
169 :
170 0 : SmViewShell *pViewSh = SmGetActiveView();
171 0 : if( pViewSh )
172 : {
173 0 : pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT);
174 0 : if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
175 : {
176 : // have SwOleClient::FormatChanged() to align the modified formula properly
177 : // even if the vis area does not change (e.g. when formula text changes from
178 : // "{a over b + c} over d" to "d over {a over b + c}"
179 0 : SFX_APP()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED, GlobalEventConfig::GetEventName(STR_EVENT_VISAREACHANGED), this));
180 :
181 0 : Repaint();
182 : }
183 : else
184 0 : pViewSh->GetGraphicWindow().Invalidate();
185 : }
186 :
187 0 : if ( bIsEnabled )
188 0 : EnableSetModified( bIsEnabled );
189 0 : SetModified(true);
190 :
191 : // launch accessible event if necessary
192 0 : SmGraphicAccessible *pAcc = pViewSh ? pViewSh->GetGraphicWindow().GetAccessible_Impl() : 0;
193 0 : if (pAcc)
194 : {
195 0 : Any aOldValue, aNewValue;
196 0 : if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText, rBuffer, aOldValue, aNewValue ) )
197 : {
198 : pAcc->LaunchEvent( AccessibleEventId::TEXT_CHANGED,
199 0 : aOldValue, aNewValue );
200 0 : }
201 : }
202 :
203 0 : if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
204 0 : OnDocumentPrinterChanged(0);
205 : }
206 0 : }
207 :
208 0 : void SmDocShell::SetFormat(SmFormat& rFormat)
209 : {
210 : SAL_INFO( "starmath", "SmDocShell::SetFormat" );
211 :
212 0 : aFormat = rFormat;
213 0 : SetFormulaArranged( false );
214 0 : SetModified( true );
215 :
216 0 : nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
217 :
218 : // don't use SmGetActiveView since the view shell might not be active (0 pointer)
219 : // if for example the Basic Macro dialog currently has the focus. Thus:
220 0 : SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
221 0 : while (pFrm)
222 : {
223 0 : pFrm->GetBindings().Invalidate(SID_GAPHIC_SM);
224 0 : pFrm = SfxViewFrame::GetNext( *pFrm, this );
225 : }
226 0 : }
227 :
228 0 : OUString SmDocShell::GetAccessibleText()
229 : {
230 : SAL_INFO( "starmath", "SmDocShell::GetAccessibleText" );
231 :
232 0 : if (!IsFormulaArranged())
233 0 : ArrangeFormula();
234 0 : if (aAccText.isEmpty())
235 : {
236 : OSL_ENSURE( pTree, "Tree missing" );
237 0 : if (pTree)
238 : {
239 0 : OUStringBuffer aBuf;
240 0 : pTree->GetAccessibleText(aBuf);
241 0 : aAccText = aBuf.makeStringAndClear();
242 : }
243 : }
244 0 : return aAccText;
245 : }
246 :
247 0 : void SmDocShell::Parse()
248 : {
249 : SAL_INFO( "starmath", "SmDocShell::Parse" );
250 :
251 0 : if (pTree)
252 0 : delete pTree;
253 0 : ReplaceBadChars();
254 0 : pTree = aInterpreter.Parse(aText);
255 0 : nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState
256 0 : SetFormulaArranged( false );
257 0 : InvalidateCursor();
258 0 : aUsedSymbols = aInterpreter.GetUsedSymbols();
259 0 : }
260 :
261 :
262 0 : void SmDocShell::ArrangeFormula()
263 : {
264 : SAL_INFO( "starmath", "SmDocShell::ArrangeFormula" );
265 :
266 0 : if (IsFormulaArranged())
267 0 : return;
268 :
269 : // Only for the duration of the existence of this object the correct settings
270 : // at the printer are guaranteed!
271 0 : SmPrinterAccess aPrtAcc(*this);
272 0 : OutputDevice* pOutDev = aPrtAcc.GetRefDev();
273 :
274 : if (!pOutDev)
275 : {
276 : #if OSL_DEBUG_LEVEL > 1
277 : SAL_WARN( "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!");
278 : #endif
279 : }
280 :
281 : // if necessary get another OutputDevice for which we format
282 0 : if (!pOutDev)
283 : {
284 0 : SmViewShell *pView = SmGetActiveView();
285 0 : if (pView)
286 0 : pOutDev = &pView->GetGraphicWindow();
287 : else
288 : {
289 0 : pOutDev = &SM_MOD()->GetDefaultVirtualDev();
290 0 : pOutDev->SetMapMode( MapMode(MAP_100TH_MM) );
291 : }
292 : }
293 : OSL_ENSURE(pOutDev->GetMapMode().GetMapUnit() == MAP_100TH_MM,
294 : "Sm : falscher MapMode");
295 :
296 0 : const SmFormat &rFormat = GetFormat();
297 0 : pTree->Prepare(rFormat, *this);
298 :
299 : // format/draw formulas always from left to right,
300 : // and numbers should not be converted
301 0 : sal_uLong nLayoutMode = pOutDev->GetLayoutMode();
302 0 : pOutDev->SetLayoutMode( TEXT_LAYOUT_BIDI_LTR );
303 0 : sal_Int16 nDigitLang = pOutDev->GetDigitLanguage();
304 0 : pOutDev->SetDigitLanguage( LANGUAGE_ENGLISH );
305 :
306 0 : pTree->Arrange(*pOutDev, rFormat);
307 :
308 0 : pOutDev->SetLayoutMode( nLayoutMode );
309 0 : pOutDev->SetDigitLanguage( nDigitLang );
310 :
311 0 : SetFormulaArranged(true);
312 :
313 : // invalidate accessible text
314 0 : aAccText = OUString();
315 : }
316 :
317 :
318 0 : void SetEditEngineDefaultFonts(SfxItemPool &rEditEngineItemPool)
319 : {
320 :
321 : // set fonts to be used
322 :
323 0 : SvtLinguOptions aOpt;
324 0 : SvtLinguConfig().GetOptions( aOpt );
325 :
326 : struct FontDta {
327 : sal_Int16 nFallbackLang;
328 : sal_Int16 nLang;
329 : sal_uInt16 nFontType;
330 : sal_uInt16 nFontInfoId;
331 : } aTable[3] =
332 : {
333 : // info to get western font to be used
334 : { LANGUAGE_ENGLISH_US, LANGUAGE_NONE,
335 : DEFAULTFONT_FIXED, EE_CHAR_FONTINFO },
336 : // info to get CJK font to be used
337 : { LANGUAGE_JAPANESE, LANGUAGE_NONE,
338 : DEFAULTFONT_CJK_TEXT, EE_CHAR_FONTINFO_CJK },
339 : // info to get CTL font to be used
340 : { LANGUAGE_ARABIC_SAUDI_ARABIA, LANGUAGE_NONE,
341 : DEFAULTFONT_CTL_TEXT, EE_CHAR_FONTINFO_CTL }
342 0 : };
343 0 : aTable[0].nLang = aOpt.nDefaultLanguage;
344 0 : aTable[1].nLang = aOpt.nDefaultLanguage_CJK;
345 0 : aTable[2].nLang = aOpt.nDefaultLanguage_CTL;
346 :
347 0 : for (int i = 0; i < 3; ++i)
348 : {
349 0 : const FontDta &rFntDta = aTable[i];
350 0 : LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
351 0 : rFntDta.nFallbackLang : rFntDta.nLang;
352 0 : Font aFont = Application::GetDefaultDevice()->GetDefaultFont(
353 0 : rFntDta.nFontType, nLang, DEFAULTFONT_FLAGS_ONLYONE );
354 : rEditEngineItemPool.SetPoolDefaultItem(
355 0 : SvxFontItem( aFont.GetFamily(), aFont.GetName(),
356 0 : aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(),
357 0 : rFntDta.nFontInfoId ) );
358 0 : }
359 :
360 : // set font heights
361 : SvxFontHeightItem aFontHeigt(
362 : Application::GetDefaultDevice()->LogicToPixel(
363 0 : Size( 0, 11 ), MapMode( MAP_POINT ) ).Height(), 100,
364 0 : EE_CHAR_FONTHEIGHT );
365 0 : rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
366 0 : aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CJK );
367 0 : rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
368 0 : aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CTL );
369 0 : rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt );
370 0 : }
371 :
372 :
373 0 : EditEngine& SmDocShell::GetEditEngine()
374 : {
375 : SAL_INFO( "starmath", "SmDocShell::GetEditEngine" );
376 :
377 0 : if (!pEditEngine)
378 : {
379 : //!
380 : //! see also SmEditWindow::DataChanged !
381 : //!
382 :
383 0 : pEditEngineItemPool = EditEngine::CreatePool();
384 :
385 0 : SetEditEngineDefaultFonts(*pEditEngineItemPool);
386 :
387 0 : pEditEngine = new EditEngine( pEditEngineItemPool );
388 :
389 0 : pEditEngine->EnableUndo( true );
390 : pEditEngine->SetDefTab( sal_uInt16(
391 0 : Application::GetDefaultDevice()->GetTextWidth(OUString("XXXX"))) );
392 :
393 : pEditEngine->SetControlWord(
394 0 : (pEditEngine->GetControlWord() | EE_CNTRL_AUTOINDENTING) &
395 : (~EE_CNTRL_UNDOATTRIBS) &
396 0 : (~EE_CNTRL_PASTESPECIAL) );
397 :
398 0 : pEditEngine->SetWordDelimiters(" .=+-*/(){}[];\"");
399 0 : pEditEngine->SetRefMapMode( MAP_PIXEL );
400 :
401 0 : pEditEngine->SetPaperSize( Size( 800, 0 ) );
402 :
403 0 : pEditEngine->EraseVirtualDevice();
404 :
405 : // set initial text if the document already has some...
406 : // (may be the case when reloading a doc)
407 0 : OUString aTxt( GetText() );
408 0 : if (!aTxt.isEmpty())
409 0 : pEditEngine->SetText( aTxt );
410 :
411 0 : pEditEngine->ClearModifyFlag();
412 :
413 : }
414 0 : return *pEditEngine;
415 : }
416 :
417 :
418 0 : SfxItemPool& SmDocShell::GetEditEngineItemPool()
419 : {
420 : SAL_INFO( "starmath", "SmDocShell::GetEditEngineItemPool" );
421 :
422 0 : if (!pEditEngineItemPool)
423 0 : GetEditEngine();
424 : OSL_ENSURE( pEditEngineItemPool, "EditEngineItemPool missing" );
425 0 : return *pEditEngineItemPool;
426 : }
427 :
428 0 : void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection)
429 : {
430 : SAL_INFO( "starmath", "SmDocShell::Draw" );
431 :
432 0 : if (!pTree)
433 0 : Parse();
434 : OSL_ENSURE(pTree, "Sm : NULL pointer");
435 :
436 0 : if (!IsFormulaArranged())
437 0 : ArrangeFormula();
438 :
439 : // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference
440 : // device and aren't aligned to that either. So now there can be a difference between the
441 : // VisArea (i.e. the size within the client) and the current size.
442 : // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution)
443 :
444 0 : rPosition.X() += aFormat.GetDistance( DIS_LEFTSPACE );
445 0 : rPosition.Y() += aFormat.GetDistance( DIS_TOPSPACE );
446 :
447 : //! in case of high contrast-mode (accessibility option!)
448 : //! the draw mode needs to be set to default, because when imbedding
449 : //! Math for example in Calc in "a over b" the fraction bar may not
450 : //! be visible else. More generally: the FillColor may have been changed.
451 0 : sal_uLong nOldDrawMode = DRAWMODE_DEFAULT;
452 0 : bool bRestoreDrawMode = false;
453 0 : if (OUTDEV_WINDOW == rDev.GetOutDevType() &&
454 0 : ((Window &) rDev).GetSettings().GetStyleSettings().GetHighContrastMode())
455 : {
456 0 : nOldDrawMode = rDev.GetDrawMode();
457 0 : rDev.SetDrawMode( DRAWMODE_DEFAULT );
458 0 : bRestoreDrawMode = true;
459 : }
460 :
461 : // format/draw formulas always from left to right
462 : // and numbers should not be converted
463 0 : sal_uLong nLayoutMode = rDev.GetLayoutMode();
464 0 : rDev.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR );
465 0 : sal_Int16 nDigitLang = rDev.GetDigitLanguage();
466 0 : rDev.SetDigitLanguage( LANGUAGE_ENGLISH );
467 :
468 : //Set selection if any
469 0 : if(pCursor && bDrawSelection){
470 0 : pCursor->AnnotateSelection();
471 0 : SmSelectionDrawingVisitor(rDev, pTree, rPosition);
472 : }
473 :
474 : //Drawing using visitor
475 0 : SmDrawingVisitor(rDev, rPosition, pTree);
476 :
477 :
478 0 : rDev.SetLayoutMode( nLayoutMode );
479 0 : rDev.SetDigitLanguage( nDigitLang );
480 :
481 0 : if (bRestoreDrawMode)
482 0 : rDev.SetDrawMode( nOldDrawMode );
483 0 : }
484 :
485 0 : Size SmDocShell::GetSize()
486 : {
487 : SAL_INFO( "starmath", "SmDocShell::GetSize" );
488 :
489 0 : Size aRet;
490 :
491 0 : if (!pTree)
492 0 : Parse();
493 :
494 0 : if (pTree)
495 : {
496 0 : if (!IsFormulaArranged())
497 0 : ArrangeFormula();
498 0 : aRet = pTree->GetSize();
499 :
500 0 : if ( !aRet.Width() )
501 0 : aRet.Width() = 2000;
502 : else
503 0 : aRet.Width() += aFormat.GetDistance( DIS_LEFTSPACE ) +
504 0 : aFormat.GetDistance( DIS_RIGHTSPACE );
505 0 : if ( !aRet.Height() )
506 0 : aRet.Height() = 1000;
507 : else
508 0 : aRet.Height() += aFormat.GetDistance( DIS_TOPSPACE ) +
509 0 : aFormat.GetDistance( DIS_BOTTOMSPACE );
510 : }
511 :
512 0 : return aRet;
513 : }
514 :
515 0 : void SmDocShell::InvalidateCursor(){
516 0 : delete pCursor;
517 0 : pCursor = NULL;
518 0 : }
519 :
520 0 : SmCursor& SmDocShell::GetCursor(){
521 0 : if(!pCursor)
522 0 : pCursor = new SmCursor(pTree, this);
523 0 : return *pCursor;
524 : }
525 :
526 :
527 :
528 0 : SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell )
529 : {
530 0 : if ( 0 != (pPrinter = rDocShell.GetPrt()) )
531 : {
532 0 : pPrinter->Push( PUSH_MAPMODE );
533 0 : if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
534 : {
535 : // if it is an embedded object (without it's own printer)
536 : // we change the MapMode temporarily.
537 : //!If it is a document with it's own printer the MapMode should
538 : //!be set correct (once) elsewhere(!), in order to avoid numerous
539 : //!superfluous pushing and poping of the MapMode when using
540 : //!this class.
541 :
542 0 : const MapUnit eOld = pPrinter->GetMapMode().GetMapUnit();
543 0 : if ( MAP_100TH_MM != eOld )
544 : {
545 0 : MapMode aMap( pPrinter->GetMapMode() );
546 0 : aMap.SetMapUnit( MAP_100TH_MM );
547 0 : Point aTmp( aMap.GetOrigin() );
548 0 : aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
549 0 : aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
550 0 : aMap.SetOrigin( aTmp );
551 0 : pPrinter->SetMapMode( aMap );
552 : }
553 : }
554 : }
555 0 : if ( 0 != (pRefDev = rDocShell.GetRefDev()) && pPrinter != pRefDev )
556 : {
557 0 : pRefDev->Push( PUSH_MAPMODE );
558 0 : if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
559 : {
560 : // if it is an embedded object (without it's own printer)
561 : // we change the MapMode temporarily.
562 : //!If it is a document with it's own printer the MapMode should
563 : //!be set correct (once) elsewhere(!), in order to avoid numerous
564 : //!superfluous pushing and poping of the MapMode when using
565 : //!this class.
566 :
567 0 : const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit();
568 0 : if ( MAP_100TH_MM != eOld )
569 : {
570 0 : MapMode aMap( pRefDev->GetMapMode() );
571 0 : aMap.SetMapUnit( MAP_100TH_MM );
572 0 : Point aTmp( aMap.GetOrigin() );
573 0 : aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
574 0 : aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
575 0 : aMap.SetOrigin( aTmp );
576 0 : pRefDev->SetMapMode( aMap );
577 : }
578 : }
579 : }
580 0 : }
581 :
582 0 : SmPrinterAccess::~SmPrinterAccess()
583 : {
584 0 : if ( pPrinter )
585 0 : pPrinter->Pop();
586 0 : if ( pRefDev && pRefDev != pPrinter )
587 0 : pRefDev->Pop();
588 0 : }
589 :
590 :
591 :
592 0 : Printer* SmDocShell::GetPrt()
593 : {
594 : SAL_INFO( "starmath", "SmDocShell::GetPrt" );
595 :
596 0 : if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
597 : {
598 : // Normally the server provides the printer. But if it doesn't provide one (e.g. because
599 : // there is no connection) it still can be the case that we know the printer because it
600 : // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily.
601 0 : Printer *pPrt = GetDocumentPrinter();
602 0 : if ( !pPrt && pTmpPrinter )
603 0 : pPrt = pTmpPrinter;
604 0 : return pPrt;
605 : }
606 0 : else if ( !pPrinter )
607 : {
608 : SfxItemSet *pOptions =
609 0 : new SfxItemSet(GetPool(),
610 : SID_PRINTSIZE, SID_PRINTSIZE,
611 : SID_PRINTZOOM, SID_PRINTZOOM,
612 : SID_PRINTTITLE, SID_PRINTTITLE,
613 : SID_PRINTTEXT, SID_PRINTTEXT,
614 : SID_PRINTFRAME, SID_PRINTFRAME,
615 : SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES,
616 : SID_SAVE_ONLY_USED_SYMBOLS, SID_SAVE_ONLY_USED_SYMBOLS,
617 0 : 0);
618 :
619 0 : SmModule *pp = SM_MOD();
620 0 : pp->GetConfig()->ConfigToItemSet(*pOptions);
621 0 : pPrinter = new SfxPrinter(pOptions);
622 0 : pPrinter->SetMapMode( MapMode(MAP_100TH_MM) );
623 : }
624 0 : return pPrinter;
625 : }
626 :
627 0 : OutputDevice* SmDocShell::GetRefDev()
628 : {
629 : SAL_INFO( "starmath", "SmDocShell::GetRefDev" );
630 :
631 0 : if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
632 : {
633 0 : OutputDevice* pOutDev = GetDocumentRefDev();
634 0 : if ( pOutDev )
635 0 : return pOutDev;
636 : }
637 :
638 0 : return GetPrt();
639 : }
640 :
641 :
642 0 : void SmDocShell::SetPrinter( SfxPrinter *pNew )
643 : {
644 : SAL_INFO( "starmath", "SmDocShell::SetPrinter" );
645 :
646 0 : delete pPrinter;
647 0 : pPrinter = pNew; //Transfer ownership
648 0 : pPrinter->SetMapMode( MapMode(MAP_100TH_MM) );
649 0 : SetFormulaArranged(false);
650 0 : Repaint();
651 0 : }
652 :
653 0 : void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt )
654 : {
655 : SAL_INFO( "starmath", "SmDocShell::OnDocumentPrinterChanged" );
656 :
657 0 : pTmpPrinter = pPrt;
658 0 : SetFormulaArranged(false);
659 0 : Size aOldSize = GetVisArea().GetSize();
660 0 : Repaint();
661 0 : if( aOldSize != GetVisArea().GetSize() && !aText.isEmpty() )
662 0 : SetModified( true );
663 0 : pTmpPrinter = 0;
664 0 : }
665 :
666 0 : void SmDocShell::Repaint()
667 : {
668 : SAL_INFO( "starmath", "SmDocShell::Repaint" );
669 :
670 0 : bool bIsEnabled = IsEnableSetModified();
671 0 : if ( bIsEnabled )
672 0 : EnableSetModified( false );
673 :
674 0 : SetFormulaArranged( false );
675 :
676 0 : Size aVisSize = GetSize();
677 0 : SetVisAreaSize( aVisSize );
678 0 : SmViewShell *pViewSh = SmGetActiveView();
679 0 : if (pViewSh)
680 0 : pViewSh->GetGraphicWindow().Invalidate();
681 :
682 0 : if ( bIsEnabled )
683 0 : EnableSetModified( bIsEnabled );
684 0 : }
685 :
686 :
687 0 : SmDocShell::SmDocShell( const sal_uInt64 i_nSfxCreationFlags ) :
688 : SfxObjectShell( i_nSfxCreationFlags ),
689 : pTree ( 0 ),
690 : pEditEngineItemPool ( 0 ),
691 : pEditEngine ( 0 ),
692 : pPrinter ( 0 ),
693 : pTmpPrinter ( 0 ),
694 : nModifyCount ( 0 ),
695 0 : bIsFormulaArranged ( false )
696 : {
697 0 : pCursor = NULL;
698 : SAL_INFO( "starmath", "SmDocShell::SmDocShell" );
699 :
700 0 : SetPool(&SFX_APP()->GetPool());
701 :
702 0 : SmModule *pp = SM_MOD();
703 0 : aFormat = pp->GetConfig()->GetStandardFormat();
704 :
705 0 : StartListening(aFormat);
706 0 : StartListening(*pp->GetConfig());
707 :
708 0 : SetBaseModel( new SmModel(this) );
709 0 : }
710 :
711 :
712 :
713 0 : SmDocShell::~SmDocShell()
714 : {
715 : SAL_INFO( "starmath", "SmDocShell::~SmDocShell" );
716 :
717 0 : SmModule *pp = SM_MOD();
718 :
719 0 : EndListening(aFormat);
720 0 : EndListening(*pp->GetConfig());
721 :
722 :
723 0 : if(pCursor)
724 0 : delete pCursor;
725 0 : pCursor = NULL;
726 :
727 0 : delete pEditEngine;
728 0 : SfxItemPool::Free(pEditEngineItemPool);
729 0 : delete pTree;
730 0 : delete pPrinter;
731 0 : }
732 :
733 :
734 0 : sal_Bool SmDocShell::SetData( const OUString& rData )
735 : {
736 : SAL_INFO( "starmath", "SmDocShell::SetData" );
737 :
738 0 : SetText( rData );
739 0 : return true;
740 : }
741 :
742 :
743 0 : bool SmDocShell::ConvertFrom(SfxMedium &rMedium)
744 : {
745 : SAL_INFO( "starmath", "SmDocShell::ConvertFrom" );
746 :
747 0 : bool bSuccess = false;
748 0 : const OUString& rFltName = rMedium.GetFilter()->GetFilterName();
749 :
750 : OSL_ENSURE( !rFltName.equals( STAROFFICE_XML ), "Wrong filter!");
751 :
752 0 : if ( rFltName.equals( MATHML_XML ) )
753 : {
754 0 : if (pTree)
755 : {
756 0 : delete pTree;
757 0 : pTree = 0;
758 0 : InvalidateCursor();
759 : }
760 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
761 0 : SmXMLImportWrapper aEquation(xModel);
762 0 : bSuccess = 0 == aEquation.Import(rMedium);
763 : }
764 : else
765 : {
766 0 : SvStream *pStream = rMedium.GetInStream();
767 0 : if ( pStream )
768 : {
769 0 : if ( SotStorage::IsStorageFile( pStream ) )
770 : {
771 0 : SvStorageRef aStorage = new SotStorage( pStream, false );
772 0 : if ( aStorage->IsStream(OUString("Equation Native")) )
773 : {
774 : // is this a MathType Storage?
775 0 : MathType aEquation( aText );
776 0 : if ( true == (bSuccess = (1 == aEquation.Parse( aStorage )) ))
777 0 : Parse();
778 0 : }
779 : }
780 : }
781 : }
782 :
783 0 : if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
784 : {
785 0 : SetFormulaArranged( false );
786 0 : Repaint();
787 : }
788 :
789 0 : FinishedLoading( SFX_LOADED_ALL );
790 0 : return bSuccess;
791 : }
792 :
793 :
794 0 : bool SmDocShell::InitNew( const uno::Reference < embed::XStorage >& xStorage )
795 : {
796 : SAL_INFO( "starmath", "SmDocShell::InitNew" );
797 :
798 0 : bool bRet = false;
799 0 : if ( SfxObjectShell::InitNew( xStorage ) )
800 : {
801 0 : bRet = true;
802 0 : SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
803 : }
804 0 : return bRet;
805 : }
806 :
807 :
808 0 : bool SmDocShell::Load( SfxMedium& rMedium )
809 : {
810 : SAL_INFO( "starmath", "SmDocShell::Load" );
811 :
812 0 : bool bRet = false;
813 0 : if( SfxObjectShell::Load( rMedium ))
814 : {
815 0 : uno::Reference < embed::XStorage > xStorage = GetMedium()->GetStorage();
816 0 : uno::Reference < container::XNameAccess > xAccess (xStorage, uno::UNO_QUERY);
817 0 : if (
818 : (
819 0 : xAccess->hasByName( OUString("content.xml") ) &&
820 0 : xStorage->isStreamElement( OUString("content.xml") )
821 0 : ) ||
822 : (
823 0 : xAccess->hasByName( OUString("Content.xml") ) &&
824 0 : xStorage->isStreamElement( OUString("Content.xml") )
825 : )
826 : )
827 : {
828 : // is this a fabulous math package ?
829 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
830 0 : SmXMLImportWrapper aEquation(xModel);
831 0 : sal_uLong nError = aEquation.Import(rMedium);
832 0 : bRet = 0 == nError;
833 0 : SetError( nError, OSL_LOG_PREFIX );
834 0 : }
835 : }
836 :
837 0 : if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
838 : {
839 0 : SetFormulaArranged( false );
840 0 : Repaint();
841 : }
842 :
843 0 : FinishedLoading( SFX_LOADED_ALL );
844 0 : return bRet;
845 : }
846 :
847 :
848 :
849 0 : bool SmDocShell::Save()
850 : {
851 : SAL_INFO( "starmath", "SmDocShell::Save" );
852 :
853 : //! apply latest changes if necessary
854 0 : UpdateText();
855 :
856 0 : if ( SfxObjectShell::Save() )
857 : {
858 0 : if (!pTree)
859 0 : Parse();
860 0 : if( pTree && !IsFormulaArranged() )
861 0 : ArrangeFormula();
862 :
863 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
864 0 : SmXMLExportWrapper aEquation(xModel);
865 0 : aEquation.SetFlat(sal_False);
866 0 : return aEquation.Export(*GetMedium());
867 : }
868 :
869 0 : return false;
870 : }
871 :
872 : /*
873 : * replace bad characters that can not be saved. (#i74144)
874 : * */
875 0 : sal_Bool SmDocShell::ReplaceBadChars()
876 : {
877 0 : sal_Bool bReplace = sal_False;
878 :
879 0 : if (pEditEngine)
880 : {
881 0 : OUStringBuffer aBuf( pEditEngine->GetText( LINEEND_LF ) );
882 :
883 0 : for (sal_Int32 i = 0; i < aBuf.getLength(); ++i)
884 : {
885 0 : if (aBuf[i] < ' ' && aBuf[i] != '\r' && aBuf[i] != '\n' && aBuf[i] != '\t')
886 : {
887 0 : aBuf[i] = ' ';
888 0 : bReplace = sal_True;
889 : }
890 : }
891 :
892 0 : if (bReplace)
893 0 : aText = aBuf.makeStringAndClear();
894 : }
895 :
896 0 : return bReplace;
897 : }
898 :
899 :
900 0 : void SmDocShell::UpdateText()
901 : {
902 : SAL_INFO( "starmath", "SmDocShell::UpdateText" );
903 :
904 0 : if (pEditEngine && pEditEngine->IsModified())
905 : {
906 0 : OUString aEngTxt( pEditEngine->GetText( LINEEND_LF ) );
907 0 : if (GetText() != aEngTxt)
908 0 : SetText( aEngTxt );
909 : }
910 0 : }
911 :
912 :
913 0 : bool SmDocShell::SaveAs( SfxMedium& rMedium )
914 : {
915 : SAL_INFO( "starmath", "SmDocShell::SaveAs" );
916 :
917 0 : bool bRet = false;
918 :
919 : //! apply latest changes if necessary
920 0 : UpdateText();
921 :
922 0 : if ( SfxObjectShell::SaveAs( rMedium ) )
923 : {
924 0 : if (!pTree)
925 0 : Parse();
926 0 : if( pTree && !IsFormulaArranged() )
927 0 : ArrangeFormula();
928 :
929 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
930 0 : SmXMLExportWrapper aEquation(xModel);
931 0 : aEquation.SetFlat(sal_False);
932 0 : bRet = aEquation.Export(rMedium);
933 : }
934 0 : return bRet;
935 : }
936 :
937 0 : bool SmDocShell::ConvertTo( SfxMedium &rMedium )
938 : {
939 : SAL_INFO( "starmath", "SmDocShell::ConvertTo" );
940 :
941 0 : bool bRet = false;
942 0 : const SfxFilter* pFlt = rMedium.GetFilter();
943 0 : if( pFlt )
944 : {
945 0 : if( !pTree )
946 0 : Parse();
947 0 : if( pTree && !IsFormulaArranged() )
948 0 : ArrangeFormula();
949 :
950 0 : const OUString& rFltName = pFlt->GetFilterName();
951 0 : if(rFltName.equals( STAROFFICE_XML ))
952 : {
953 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
954 0 : SmXMLExportWrapper aEquation(xModel);
955 0 : aEquation.SetFlat(sal_False);
956 0 : bRet = aEquation.Export(rMedium);
957 : }
958 0 : else if(rFltName.equals( MATHML_XML ))
959 : {
960 0 : Reference<com::sun::star::frame::XModel> xModel(GetModel());
961 0 : SmXMLExportWrapper aEquation(xModel);
962 0 : aEquation.SetFlat(sal_True);
963 0 : bRet = aEquation.Export(rMedium);
964 : }
965 0 : else if (pFlt->GetFilterName().equalsAscii("MathType 3.x"))
966 0 : bRet = WriteAsMathType3( rMedium );
967 : }
968 0 : return bRet;
969 : }
970 :
971 0 : bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr pSerializer, oox::core::OoxmlVersion version )
972 : {
973 : SAL_INFO( "starmath", "SmDocShell::writeFormulaOoxml" );
974 :
975 0 : if( !pTree )
976 0 : Parse();
977 0 : if( pTree && !IsFormulaArranged() )
978 0 : ArrangeFormula();
979 0 : SmOoxmlExport aEquation( pTree, version );
980 0 : return aEquation.ConvertFromStarMath( pSerializer );
981 : }
982 :
983 0 : void SmDocShell::writeFormulaRtf(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding)
984 : {
985 0 : if (!pTree)
986 0 : Parse();
987 0 : if (pTree && !IsFormulaArranged())
988 0 : ArrangeFormula();
989 0 : SmRtfExport aEquation(pTree);
990 0 : aEquation.ConvertFromStarMath(rBuffer, nEncoding);
991 0 : }
992 :
993 0 : void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream& stream )
994 : {
995 : SAL_INFO( "starmath", "SmDocShell::readFormulaOoxml" );
996 :
997 0 : SmOoxmlImport aEquation( stream );
998 0 : SetText( aEquation.ConvertToStarMath());
999 0 : }
1000 :
1001 0 : bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
1002 : {
1003 : SAL_INFO( "starmath", "SmDocShell::SaveCompleted" );
1004 :
1005 0 : if( SfxObjectShell::SaveCompleted( xStorage ))
1006 0 : return true;
1007 :
1008 0 : return false;
1009 : }
1010 :
1011 :
1012 0 : void SmDocShell::Execute(SfxRequest& rReq)
1013 : {
1014 : SAL_INFO( "starmath", "SmDocShell::Execute" );
1015 :
1016 0 : switch (rReq.GetSlot())
1017 : {
1018 : case SID_TEXTMODE:
1019 : {
1020 0 : SmFormat aOldFormat = GetFormat();
1021 0 : SmFormat aNewFormat( aOldFormat );
1022 0 : aNewFormat.SetTextmode(!aOldFormat.IsTextmode());
1023 :
1024 0 : ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
1025 0 : if (pTmpUndoMgr)
1026 : pTmpUndoMgr->AddUndoAction(
1027 0 : new SmFormatAction(this, aOldFormat, aNewFormat));
1028 :
1029 0 : SetFormat( aNewFormat );
1030 0 : Repaint();
1031 : }
1032 0 : break;
1033 :
1034 : case SID_AUTO_REDRAW :
1035 : {
1036 0 : SmModule *pp = SM_MOD();
1037 0 : bool bRedraw = pp->GetConfig()->IsAutoRedraw();
1038 0 : pp->GetConfig()->SetAutoRedraw(!bRedraw);
1039 : }
1040 0 : break;
1041 :
1042 : case SID_LOADSYMBOLS:
1043 0 : LoadSymbols();
1044 0 : break;
1045 :
1046 : case SID_SAVESYMBOLS:
1047 0 : SaveSymbols();
1048 0 : break;
1049 :
1050 : case SID_FONT:
1051 : {
1052 : // get device used to retrieve the FontList
1053 0 : OutputDevice *pDev = GetPrinter();
1054 0 : if (!pDev || pDev->GetDevFontCount() == 0)
1055 0 : pDev = &SM_MOD()->GetDefaultVirtualDev();
1056 : OSL_ENSURE (pDev, "device for font list missing" );
1057 :
1058 0 : SmFontTypeDialog *pFontTypeDialog = new SmFontTypeDialog( NULL, pDev );
1059 :
1060 0 : SmFormat aOldFormat = GetFormat();
1061 0 : pFontTypeDialog->ReadFrom( aOldFormat );
1062 0 : if (pFontTypeDialog->Execute() == RET_OK)
1063 : {
1064 0 : SmFormat aNewFormat( aOldFormat );
1065 :
1066 0 : pFontTypeDialog->WriteTo(aNewFormat);
1067 0 : ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
1068 0 : if (pTmpUndoMgr)
1069 : pTmpUndoMgr->AddUndoAction(
1070 0 : new SmFormatAction(this, aOldFormat, aNewFormat));
1071 :
1072 0 : SetFormat( aNewFormat );
1073 0 : Repaint();
1074 : }
1075 0 : delete pFontTypeDialog;
1076 : }
1077 0 : break;
1078 :
1079 : case SID_FONTSIZE:
1080 : {
1081 0 : SmFontSizeDialog *pFontSizeDialog = new SmFontSizeDialog(NULL);
1082 :
1083 0 : SmFormat aOldFormat = GetFormat();
1084 0 : pFontSizeDialog->ReadFrom( aOldFormat );
1085 0 : if (pFontSizeDialog->Execute() == RET_OK)
1086 : {
1087 0 : SmFormat aNewFormat( aOldFormat );
1088 :
1089 0 : pFontSizeDialog->WriteTo(aNewFormat);
1090 :
1091 0 : ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
1092 0 : if (pTmpUndoMgr)
1093 : pTmpUndoMgr->AddUndoAction(
1094 0 : new SmFormatAction(this, aOldFormat, aNewFormat));
1095 :
1096 0 : SetFormat( aNewFormat );
1097 0 : Repaint();
1098 : }
1099 0 : delete pFontSizeDialog;
1100 : }
1101 0 : break;
1102 :
1103 : case SID_DISTANCE:
1104 : {
1105 0 : SmDistanceDialog *pDistanceDialog = new SmDistanceDialog(NULL);
1106 :
1107 0 : SmFormat aOldFormat = GetFormat();
1108 0 : pDistanceDialog->ReadFrom( aOldFormat );
1109 0 : if (pDistanceDialog->Execute() == RET_OK)
1110 : {
1111 0 : SmFormat aNewFormat( aOldFormat );
1112 :
1113 0 : pDistanceDialog->WriteTo(aNewFormat);
1114 :
1115 0 : ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
1116 0 : if (pTmpUndoMgr)
1117 : pTmpUndoMgr->AddUndoAction(
1118 0 : new SmFormatAction(this, aOldFormat, aNewFormat));
1119 :
1120 0 : SetFormat( aNewFormat );
1121 0 : Repaint();
1122 : }
1123 0 : delete pDistanceDialog;
1124 : }
1125 0 : break;
1126 :
1127 : case SID_ALIGN:
1128 : {
1129 0 : SmAlignDialog *pAlignDialog = new SmAlignDialog(NULL);
1130 :
1131 0 : SmFormat aOldFormat = GetFormat();
1132 0 : pAlignDialog->ReadFrom( aOldFormat );
1133 0 : if (pAlignDialog->Execute() == RET_OK)
1134 : {
1135 0 : SmFormat aNewFormat( aOldFormat );
1136 :
1137 0 : pAlignDialog->WriteTo(aNewFormat);
1138 :
1139 0 : SmModule *pp = SM_MOD();
1140 0 : SmFormat aFmt( pp->GetConfig()->GetStandardFormat() );
1141 0 : pAlignDialog->WriteTo( aFmt );
1142 0 : pp->GetConfig()->SetStandardFormat( aFmt );
1143 :
1144 0 : ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager();
1145 0 : if (pTmpUndoMgr)
1146 : pTmpUndoMgr->AddUndoAction(
1147 0 : new SmFormatAction(this, aOldFormat, aNewFormat));
1148 :
1149 0 : SetFormat( aNewFormat );
1150 0 : Repaint();
1151 : }
1152 0 : delete pAlignDialog;
1153 : }
1154 0 : break;
1155 :
1156 : case SID_TEXT:
1157 : {
1158 0 : const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXT);
1159 0 : if (GetText() != OUString(rItem.GetValue()))
1160 0 : SetText(rItem.GetValue());
1161 : }
1162 0 : break;
1163 :
1164 : case SID_UNDO:
1165 : case SID_REDO:
1166 : {
1167 0 : ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager();
1168 0 : if( pTmpUndoMgr )
1169 : {
1170 0 : sal_uInt16 nId = rReq.GetSlot(), nCnt = 1;
1171 0 : const SfxItemSet* pArgs = rReq.GetArgs();
1172 : const SfxPoolItem* pItem;
1173 0 : if( pArgs && SFX_ITEM_SET == pArgs->GetItemState( nId, false, &pItem ))
1174 0 : nCnt = ((SfxUInt16Item*)pItem)->GetValue();
1175 :
1176 : bool (::svl::IUndoManager:: *fnDo)();
1177 :
1178 : sal_uInt16 nCount;
1179 0 : if( SID_UNDO == rReq.GetSlot() )
1180 : {
1181 0 : nCount = pTmpUndoMgr->GetUndoActionCount();
1182 0 : fnDo = &::svl::IUndoManager::Undo;
1183 : }
1184 : else
1185 : {
1186 0 : nCount = pTmpUndoMgr->GetRedoActionCount();
1187 0 : fnDo = &::svl::IUndoManager::Redo;
1188 : }
1189 :
1190 : try
1191 : {
1192 0 : for( ; nCnt && nCount; --nCnt, --nCount )
1193 0 : (pTmpUndoMgr->*fnDo)();
1194 : }
1195 0 : catch( const Exception& )
1196 : {
1197 : DBG_UNHANDLED_EXCEPTION();
1198 : }
1199 : }
1200 0 : Repaint();
1201 0 : UpdateText();
1202 0 : SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
1203 0 : while( pFrm )
1204 : {
1205 0 : SfxBindings& rBind = pFrm->GetBindings();
1206 0 : rBind.Invalidate(SID_UNDO);
1207 0 : rBind.Invalidate(SID_REDO);
1208 0 : rBind.Invalidate(SID_REPEAT);
1209 0 : rBind.Invalidate(SID_CLEARHISTORY);
1210 0 : pFrm = SfxViewFrame::GetNext( *pFrm, this );
1211 : }
1212 : }
1213 0 : break;
1214 : }
1215 :
1216 0 : rReq.Done();
1217 0 : }
1218 :
1219 :
1220 0 : void SmDocShell::GetState(SfxItemSet &rSet)
1221 : {
1222 : SAL_INFO( "starmath", "SmDocShell::GetState" );
1223 :
1224 0 : SfxWhichIter aIter(rSet);
1225 :
1226 0 : for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich())
1227 : {
1228 0 : switch (nWh)
1229 : {
1230 : case SID_TEXTMODE:
1231 0 : rSet.Put(SfxBoolItem(SID_TEXTMODE, GetFormat().IsTextmode()));
1232 0 : break;
1233 :
1234 : case SID_DOCTEMPLATE :
1235 0 : rSet.DisableItem(SID_DOCTEMPLATE);
1236 0 : break;
1237 :
1238 : case SID_AUTO_REDRAW :
1239 : {
1240 0 : SmModule *pp = SM_MOD();
1241 0 : bool bRedraw = pp->GetConfig()->IsAutoRedraw();
1242 :
1243 0 : rSet.Put(SfxBoolItem(SID_AUTO_REDRAW, bRedraw));
1244 : }
1245 0 : break;
1246 :
1247 : case SID_MODIFYSTATUS:
1248 : {
1249 0 : sal_Unicode cMod = ' ';
1250 0 : if (IsModified())
1251 0 : cMod = '*';
1252 0 : rSet.Put(SfxStringItem(SID_MODIFYSTATUS, OUString(cMod)));
1253 : }
1254 0 : break;
1255 :
1256 : case SID_TEXT:
1257 0 : rSet.Put(SfxStringItem(SID_TEXT, GetText()));
1258 0 : break;
1259 :
1260 : case SID_GAPHIC_SM:
1261 : //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow.
1262 : //! If nModifyCount gets changed then the call below will implicitly notify
1263 : //! SmGraphicController::StateChanged and there the window gets invalidated.
1264 : //! Thus all the 'nModifyCount++' before invalidating this slot.
1265 0 : rSet.Put(SfxInt16Item(SID_GAPHIC_SM, nModifyCount));
1266 0 : break;
1267 :
1268 : case SID_UNDO:
1269 : case SID_REDO:
1270 : {
1271 0 : SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
1272 0 : if( pFrm )
1273 0 : pFrm->GetSlotState( nWh, NULL, &rSet );
1274 : else
1275 0 : rSet.DisableItem( nWh );
1276 : }
1277 0 : break;
1278 :
1279 : case SID_GETUNDOSTRINGS:
1280 : case SID_GETREDOSTRINGS:
1281 : {
1282 0 : ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager();
1283 0 : if( pTmpUndoMgr )
1284 : {
1285 : OUString(::svl::IUndoManager:: *fnGetComment)( size_t, bool const ) const;
1286 :
1287 : sal_uInt16 nCount;
1288 0 : if( SID_GETUNDOSTRINGS == nWh )
1289 : {
1290 0 : nCount = pTmpUndoMgr->GetUndoActionCount();
1291 0 : fnGetComment = &::svl::IUndoManager::GetUndoActionComment;
1292 : }
1293 : else
1294 : {
1295 0 : nCount = pTmpUndoMgr->GetRedoActionCount();
1296 0 : fnGetComment = &::svl::IUndoManager::GetRedoActionComment;
1297 : }
1298 0 : if( nCount )
1299 : {
1300 0 : OUString sList;
1301 0 : for( sal_uInt16 n = 0; n < nCount; ++n )
1302 0 : sList += (pTmpUndoMgr->*fnGetComment)( n, ::svl::IUndoManager::TopLevel ) + "\n";
1303 :
1304 0 : SfxStringListItem aItem( nWh );
1305 0 : aItem.SetString( sList );
1306 0 : rSet.Put( aItem );
1307 : }
1308 : }
1309 : else
1310 0 : rSet.DisableItem( nWh );
1311 : }
1312 0 : break;
1313 : }
1314 0 : }
1315 0 : }
1316 :
1317 :
1318 0 : ::svl::IUndoManager *SmDocShell::GetUndoManager()
1319 : {
1320 : SAL_INFO( "starmath", "SmDocShell::GetUndoManager" );
1321 :
1322 0 : if (!pEditEngine)
1323 0 : GetEditEngine();
1324 0 : return &pEditEngine->GetUndoManager();
1325 : }
1326 :
1327 :
1328 0 : void SmDocShell::SaveSymbols()
1329 : {
1330 : SAL_INFO( "starmath", "SmDocShell::SaveSymbols" );
1331 :
1332 0 : SmModule *pp = SM_MOD();
1333 0 : pp->GetSymbolManager().Save();
1334 0 : }
1335 :
1336 :
1337 0 : void SmDocShell::Draw(OutputDevice *pDevice,
1338 : const JobSetup &,
1339 : sal_uInt16 /*nAspect*/)
1340 : {
1341 : SAL_INFO( "starmath", "SmDocShell::Draw" );
1342 :
1343 0 : pDevice->IntersectClipRegion(GetVisArea());
1344 0 : Point atmppoint;
1345 0 : DrawFormula(*pDevice, atmppoint);
1346 0 : }
1347 :
1348 0 : SfxItemPool& SmDocShell::GetPool() const
1349 : {
1350 0 : return SFX_APP()->GetPool();
1351 : }
1352 :
1353 0 : void SmDocShell::SetVisArea(const Rectangle & rVisArea)
1354 : {
1355 : SAL_INFO( "starmath", "SmDocShell::SetVisArea" );
1356 :
1357 0 : Rectangle aNewRect(rVisArea);
1358 :
1359 0 : aNewRect.SetPos(Point());
1360 :
1361 0 : if (! aNewRect.Right()) aNewRect.Right() = 2000;
1362 0 : if (! aNewRect.Bottom()) aNewRect.Bottom() = 1000;
1363 :
1364 0 : bool bIsEnabled = IsEnableSetModified();
1365 0 : if ( bIsEnabled )
1366 0 : EnableSetModified( false );
1367 :
1368 : //TODO/LATER: it's unclear how this interacts with the SFX code
1369 : // If outplace editing, then dont resize the OutplaceWindow. But the
1370 : // ObjectShell has to resize. Bug 56470
1371 : bool bUnLockFrame;
1372 0 : if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !IsInPlaceActive() && GetFrame() )
1373 : {
1374 0 : GetFrame()->LockAdjustPosSizePixel();
1375 0 : bUnLockFrame = true;
1376 : }
1377 : else
1378 0 : bUnLockFrame = false;
1379 :
1380 0 : SfxObjectShell::SetVisArea( aNewRect );
1381 :
1382 0 : if( bUnLockFrame )
1383 0 : GetFrame()->UnlockAdjustPosSizePixel();
1384 :
1385 0 : if ( bIsEnabled )
1386 0 : EnableSetModified( bIsEnabled );
1387 0 : }
1388 :
1389 :
1390 0 : void SmDocShell::FillClass(SvGlobalName* pClassName,
1391 : sal_uInt32* pFormat,
1392 : OUString* /*pAppName*/,
1393 : OUString* pFullTypeName,
1394 : OUString* pShortTypeName,
1395 : sal_Int32 nFileFormat,
1396 : bool bTemplate /* = false */) const
1397 : {
1398 : SAL_INFO( "starmath", "SmDocShell::FillClass" );
1399 :
1400 0 : if (nFileFormat == SOFFICE_FILEFORMAT_60 )
1401 : {
1402 0 : *pClassName = SvGlobalName(SO3_SM_CLASSID_60);
1403 0 : *pFormat = SOT_FORMATSTR_ID_STARMATH_60;
1404 0 : *pFullTypeName = SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT);
1405 0 : *pShortTypeName = SM_RESSTR(RID_DOCUMENTSTR);
1406 : }
1407 0 : else if (nFileFormat == SOFFICE_FILEFORMAT_8 )
1408 : {
1409 0 : *pClassName = SvGlobalName(SO3_SM_CLASSID_60);
1410 0 : *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE : SOT_FORMATSTR_ID_STARMATH_8;
1411 0 : *pFullTypeName = SM_RESSTR(STR_MATH_DOCUMENT_FULLTYPE_CURRENT);
1412 0 : *pShortTypeName = SM_RESSTR(RID_DOCUMENTSTR);
1413 : }
1414 0 : }
1415 :
1416 0 : sal_uLong SmDocShell::GetMiscStatus() const
1417 : {
1418 0 : return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
1419 0 : | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE;
1420 : }
1421 :
1422 0 : void SmDocShell::SetModified(bool bModified)
1423 : {
1424 : SAL_INFO( "starmath", "SmDocShell::SetModified" );
1425 :
1426 0 : if( IsEnableSetModified() )
1427 : {
1428 0 : SfxObjectShell::SetModified( bModified );
1429 0 : Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
1430 : }
1431 0 : }
1432 :
1433 0 : bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium )
1434 : {
1435 : SAL_INFO( "starmath", "SmDocShell::WriteAsMathType3" );
1436 :
1437 0 : MathType aEquation( aText, pTree );
1438 :
1439 0 : bool bRet = 0 != aEquation.ConvertFromStarMath( rMedium );
1440 0 : return bRet;
1441 0 : }
1442 :
1443 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|