1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_starmath.hxx" 30 31 32 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 33 #include <com/sun/star/lang/Locale.hpp> 34 #include <com/sun/star/uno/Any.h> 35 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> 85 #include <action.hxx> 86 #include <config.hxx> 87 #include <dialog.hxx> 88 #include <format.hxx> 89 #include <smdll.hxx> 90 #include <starmath.hrc> 91 #include <symbol.hxx> 92 #include <toolbox.hxx> 93 #include <unomodel.hxx> 94 #include <utility.hxx> 95 #include <view.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> 102 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; 108 109 110 #define DOCUMENT_BUFFER_SIZE (sal_uInt16)32768 111 112 static const char __FAR_DATA pStarMathDoc[] = "StarMathDocument"; 113 114 #define SmDocShell 115 #include "smslots.hxx" 116 117 //////////////////////////////////////////////////////////// 118 119 120 TYPEINIT1( SmDocShell, SfxObjectShell ); 121 122 SFX_IMPL_INTERFACE(SmDocShell, SfxObjectShell, SmResId(0)) 123 { 124 SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU)); 125 SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU)); 126 } 127 128 SFX_IMPL_OBJECTFACTORY(SmDocShell, SvGlobalName(SO3_SM_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "smath" ) 129 130 void SmDocShell::SFX_NOTIFY(SfxBroadcaster&, const TypeId&, 131 const SfxHint& rHint, const TypeId&) 132 { 133 switch (((SfxSimpleHint&)rHint).GetId()) 134 { 135 case HINT_FORMATCHANGED: 136 SetFormulaArranged(sal_False); 137 138 nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState 139 140 Repaint(); 141 break; 142 } 143 } 144 145 void SmDocShell::LoadSymbols() 146 { 147 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::LoadSymbols" ); 148 149 SmModule *pp = SM_MOD(); 150 pp->GetSymbolManager().Load(); 151 } 152 153 154 const String SmDocShell::GetComment() const 155 { 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(); 162 } 163 164 165 void SmDocShell::SetText(const String& rBuffer) 166 { 167 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetText" ); 168 169 if (rBuffer != aText) 170 { 171 sal_Bool bIsEnabled = IsEnableSetModified(); 172 if( bIsEnabled ) 173 EnableSetModified( sal_False ); 174 175 aText = rBuffer; 176 SetFormulaArranged( sal_False ); 177 178 Parse(); 179 //Repaint(); 180 181 SmViewShell *pViewSh = SmGetActiveView(); 182 if( pViewSh ) 183 { 184 pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT); 185 if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) 186 { 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)); 191 192 Repaint(); 193 } 194 else 195 pViewSh->GetGraphicWindow().Invalidate(); 196 } 197 198 if ( bIsEnabled ) 199 EnableSetModified( bIsEnabled ); 200 SetModified(sal_True); 201 202 // launch accessible event if necessary 203 SmGraphicAccessible *pAcc = pViewSh ? pViewSh->GetGraphicWindow().GetAccessible_Impl() : 0; 204 if (pAcc) 205 { 206 Any aOldValue, aNewValue; 207 if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText, rBuffer, aOldValue, aNewValue ) ) 208 { 209 pAcc->LaunchEvent( AccessibleEventId::TEXT_CHANGED, 210 aOldValue, aNewValue ); 211 } 212 } 213 214 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) 215 OnDocumentPrinterChanged(0); 216 } 217 } 218 219 void SmDocShell::SetFormat(SmFormat& rFormat) 220 { 221 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetFormat" ); 222 223 aFormat = rFormat; 224 SetFormulaArranged( sal_False ); 225 SetModified( sal_True ); 226 227 nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState 228 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 ); 232 while (pFrm) 233 { 234 pFrm->GetBindings().Invalidate(SID_GAPHIC_SM); 235 pFrm = SfxViewFrame::GetNext( *pFrm, this ); 236 } 237 } 238 239 String SmDocShell::GetAccessibleText() 240 { 241 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetAccessibleText" ); 242 243 if (!IsFormulaArranged()) 244 ArrangeFormula(); 245 if (0 == aAccText.Len()) 246 { 247 DBG_ASSERT( pTree, "Tree missing" ); 248 if (pTree) 249 pTree->GetAccessibleText( aAccText ); 250 } 251 return aAccText; 252 } 253 254 void SmDocShell::Parse() 255 { 256 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Parse" ); 257 258 if (pTree) 259 delete pTree; 260 ReplaceBadChars(); 261 pTree = aInterpreter.Parse(aText); 262 nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState 263 SetFormulaArranged( sal_False ); 264 265 aUsedSymbols = aInterpreter.GetUsedSymbols(); 266 } 267 268 269 void SmDocShell::ArrangeFormula() 270 { 271 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ArrangeFormula" ); 272 273 if (IsFormulaArranged()) 274 return; 275 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(); 281 282 if (!pOutDev) 283 { 284 #if OSL_DEBUG_LEVEL > 1 285 DBG_ERROR("!! SmDocShell::ArrangeFormula: reference device missing !!"); 286 #endif 287 } 288 289 // falls n�tig ein anderes OutputDevice holen f�r das formatiert wird 290 if (!pOutDev) 291 { 292 SmViewShell *pView = SmGetActiveView(); 293 if (pView) 294 pOutDev = &pView->GetGraphicWindow(); 295 else 296 { 297 pOutDev = &SM_MOD()->GetDefaultVirtualDev(); 298 pOutDev->SetMapMode( MapMode(MAP_100TH_MM) ); 299 } 300 } 301 DBG_ASSERT(pOutDev->GetMapMode().GetMapUnit() == MAP_100TH_MM, 302 "Sm : falscher MapMode"); 303 304 const SmFormat &rFormat = GetFormat(); 305 pTree->Prepare(rFormat, *this); 306 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 ); 313 // 314 pTree->Arrange(*pOutDev, rFormat); 315 // 316 pOutDev->SetLayoutMode( nLayoutMode ); 317 pOutDev->SetDigitLanguage( nDigitLang ); 318 319 SetFormulaArranged(sal_True); 320 321 // invalidate accessible text 322 aAccText = String(); 323 } 324 325 326 void SetEditEngineDefaultFonts( 327 EditEngine &/*rEditEngine*/, 328 SfxItemPool &rEditEngineItemPool ) 329 { 330 // 331 // set fonts to be used 332 // 333 SvtLinguOptions aOpt; 334 SvtLinguConfig().GetOptions( aOpt ); 335 // 336 struct FontDta { 337 sal_Int16 nFallbackLang; 338 sal_Int16 nLang; 339 sal_uInt16 nFontType; 340 sal_uInt16 nFontInfoId; 341 } aTable[3] = 342 { 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 } 352 }; 353 aTable[0].nLang = aOpt.nDefaultLanguage; 354 aTable[1].nLang = aOpt.nDefaultLanguage_CJK; 355 aTable[2].nLang = aOpt.nDefaultLanguage_CTL; 356 // 357 for (int i = 0; i < 3; ++i) 358 { 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 ); 364 #ifdef DEBUG_TL 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 ); 375 #endif 376 rEditEngineItemPool.SetPoolDefaultItem( 377 SvxFontItem( aFont.GetFamily(), aFont.GetName(), 378 aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), 379 rFntDta.nFontInfoId ) ); 380 } 381 382 // set font heights 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 ); 392 } 393 394 395 EditEngine& SmDocShell::GetEditEngine() 396 { 397 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngine" ); 398 399 if (!pEditEngine) 400 { 401 //! 402 //! see also SmEditWindow::DataChanged ! 403 //! 404 405 pEditEngineItemPool = EditEngine::CreatePool(); 406 407 SetEditEngineDefaultFonts( *pEditEngine, *pEditEngineItemPool ); 408 409 pEditEngine = new EditEngine( pEditEngineItemPool ); 410 411 pEditEngine->EnableUndo( sal_True ); 412 pEditEngine->SetDefTab( sal_uInt16( 413 Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) ); 414 415 pEditEngine->SetControlWord( 416 (pEditEngine->GetControlWord() | EE_CNTRL_AUTOINDENTING) & 417 (~EE_CNTRL_UNDOATTRIBS) & 418 (~EE_CNTRL_PASTESPECIAL) ); 419 420 pEditEngine->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) ); 421 pEditEngine->SetRefMapMode( MAP_PIXEL ); 422 423 pEditEngine->SetPaperSize( Size( 800, 0 ) ); 424 425 pEditEngine->EraseVirtualDevice(); 426 427 // set initial text if the document already has some... 428 // (may be the case when reloading a doc) 429 String aTxt( GetText() ); 430 if (aTxt.Len()) 431 pEditEngine->SetText( aTxt ); 432 433 pEditEngine->ClearModifyFlag(); 434 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 438 } 439 return *pEditEngine; 440 } 441 442 443 SfxItemPool& SmDocShell::GetEditEngineItemPool() 444 { 445 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngineItemPool" ); 446 447 if (!pEditEngineItemPool) 448 GetEditEngine(); 449 DBG_ASSERT( pEditEngineItemPool, "EditEngineItemPool missing" ); 450 return *pEditEngineItemPool; 451 } 452 453 454 void SmDocShell::Draw(OutputDevice &rDev, Point &rPosition) 455 { 456 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" ); 457 458 if (!pTree) 459 Parse(); 460 DBG_ASSERT(pTree, "Sm : NULL pointer"); 461 462 if (!IsFormulaArranged()) 463 ArrangeFormula(); 464 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 470 //angepasst werden. 471 472 rPosition.X() += aFormat.GetDistance( DIS_LEFTSPACE ); 473 rPosition.Y() += aFormat.GetDistance( DIS_TOPSPACE ); 474 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()) 483 { 484 nOldDrawMode = rDev.GetDrawMode(); 485 rDev.SetDrawMode( DRAWMODE_DEFAULT ); 486 bRestoreDrawMode = sal_True; 487 } 488 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 ); 495 // 496 pTree->Draw(rDev, rPosition); 497 // 498 rDev.SetLayoutMode( nLayoutMode ); 499 rDev.SetDigitLanguage( nDigitLang ); 500 501 if (bRestoreDrawMode) 502 rDev.SetDrawMode( nOldDrawMode ); 503 } 504 505 506 507 Size SmDocShell::GetSize() 508 { 509 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetSize" ); 510 511 Size aRet; 512 513 if (!pTree) 514 Parse(); 515 516 if (pTree) 517 { 518 if (!IsFormulaArranged()) 519 ArrangeFormula(); 520 aRet = pTree->GetSize(); 521 522 if ( !aRet.Width() ) 523 aRet.Width() = 2000; 524 else 525 aRet.Width() += aFormat.GetDistance( DIS_LEFTSPACE ) + 526 aFormat.GetDistance( DIS_RIGHTSPACE ); 527 if ( !aRet.Height() ) 528 aRet.Height() = 1000; 529 else 530 aRet.Height() += aFormat.GetDistance( DIS_TOPSPACE ) + 531 aFormat.GetDistance( DIS_BOTTOMSPACE ); 532 } 533 534 return aRet; 535 } 536 537 //////////////////////////////////////// 538 539 SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell ) 540 { 541 if ( 0 != (pPrinter = rDocShell.GetPrt()) ) 542 { 543 pPrinter->Push( PUSH_MAPMODE ); 544 if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() ) 545 { 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 551 //!this class. 552 553 const MapUnit eOld = pPrinter->GetMapMode().GetMapUnit(); 554 if ( MAP_100TH_MM != eOld ) 555 { 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 ); 563 } 564 } 565 } 566 if ( 0 != (pRefDev = rDocShell.GetRefDev()) && pPrinter != pRefDev ) 567 { 568 pRefDev->Push( PUSH_MAPMODE ); 569 if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() ) 570 { 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 576 //!this class. 577 578 const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit(); 579 if ( MAP_100TH_MM != eOld ) 580 { 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 ); 588 } 589 } 590 } 591 } 592 593 SmPrinterAccess::~SmPrinterAccess() 594 { 595 if ( pPrinter ) 596 pPrinter->Pop(); 597 if ( pRefDev && pRefDev != pPrinter ) 598 pRefDev->Pop(); 599 } 600 601 //////////////////////////////////////// 602 603 Printer* SmDocShell::GetPrt() 604 { 605 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetPrt" ); 606 607 if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) 608 { 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 613 //festgehalten. 614 Printer *pPrt = GetDocumentPrinter(); 615 if ( !pPrt && pTmpPrinter ) 616 pPrt = pTmpPrinter; 617 return pPrt; 618 } 619 else if ( !pPrinter ) 620 { 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, 629 0); 630 631 SmModule *pp = SM_MOD(); 632 pp->GetConfig()->ConfigToItemSet(*pOptions); 633 pPrinter = new SfxPrinter(pOptions); 634 pPrinter->SetMapMode( MapMode(MAP_100TH_MM) ); 635 } 636 return pPrinter; 637 } 638 639 OutputDevice* SmDocShell::GetRefDev() 640 { 641 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetRefDev" ); 642 643 if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) 644 { 645 OutputDevice* pOutDev = GetDocumentRefDev(); 646 if ( pOutDev ) 647 return pOutDev; 648 } 649 650 return GetPrt(); 651 } 652 653 654 void SmDocShell::SetPrinter( SfxPrinter *pNew ) 655 { 656 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetPrinter" ); 657 658 delete pPrinter; 659 pPrinter = pNew; //Eigentumsuebergang! 660 pPrinter->SetMapMode( MapMode(MAP_100TH_MM) ); 661 SetFormulaArranged(sal_False); 662 Repaint(); 663 } 664 665 void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt ) 666 { 667 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::OnDocumentPrinterChanged" ); 668 669 pTmpPrinter = pPrt; 670 SetFormulaArranged(sal_False); 671 Size aOldSize = GetVisArea().GetSize(); 672 Repaint(); 673 if( aOldSize != GetVisArea().GetSize() && aText.Len() ) 674 SetModified( sal_True ); 675 pTmpPrinter = 0; 676 } 677 678 void SmDocShell::Repaint() 679 { 680 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Repaint" ); 681 682 sal_Bool bIsEnabled = IsEnableSetModified(); 683 if ( bIsEnabled ) 684 EnableSetModified( sal_False ); 685 686 SetFormulaArranged( sal_False ); 687 688 Size aVisSize = GetSize(); 689 SetVisAreaSize( aVisSize ); 690 SmViewShell *pViewSh = SmGetActiveView(); 691 if (pViewSh) 692 pViewSh->GetGraphicWindow().Invalidate(); 693 694 if ( bIsEnabled ) 695 EnableSetModified( bIsEnabled ); 696 } 697 698 699 SmDocShell::SmDocShell( const sal_uInt64 i_nSfxCreationFlags ) : 700 SfxObjectShell( i_nSfxCreationFlags ), 701 pTree ( 0 ), 702 pEditEngineItemPool ( 0 ), 703 pEditEngine ( 0 ), 704 pPrinter ( 0 ), 705 pTmpPrinter ( 0 ), 706 nModifyCount ( 0 ), 707 bIsFormulaArranged ( sal_False ) 708 { 709 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SmDocShell" ); 710 711 SetPool(&SFX_APP()->GetPool()); 712 713 SmModule *pp = SM_MOD(); 714 aFormat = pp->GetConfig()->GetStandardFormat(); 715 716 StartListening(aFormat); 717 StartListening(*pp->GetConfig()); 718 719 SetBaseModel( new SmModel(this) ); 720 } 721 722 723 724 SmDocShell::~SmDocShell() 725 { 726 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::~SmDocShell" ); 727 728 SmModule *pp = SM_MOD(); 729 730 EndListening(aFormat); 731 EndListening(*pp->GetConfig()); 732 733 delete pEditEngine; 734 SfxItemPool::Free(pEditEngineItemPool); 735 delete pTree; 736 delete pPrinter; 737 } 738 739 740 sal_Bool SmDocShell::SetData( const String& rData ) 741 { 742 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetData" ); 743 744 SetText( rData ); 745 return sal_True; 746 } 747 748 749 sal_Bool SmDocShell::ConvertFrom(SfxMedium &rMedium) 750 { 751 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertFrom" ); 752 753 sal_Bool bSuccess = sal_False; 754 const String& rFltName = rMedium.GetFilter()->GetFilterName(); 755 756 DBG_ASSERT( !rFltName.EqualsAscii( STAROFFICE_XML ), "Wrong filter!"); 757 758 if ( rFltName.EqualsAscii( MATHML_XML ) ) 759 { 760 if (pTree) 761 { 762 delete pTree; 763 pTree = 0; 764 } 765 Reference<com::sun::star::frame::XModel> xModel(GetModel()); 766 SmXMLImportWrapper aEquation(xModel); 767 bSuccess = 0 == aEquation.Import(rMedium); 768 } 769 else 770 { 771 SvStream *pStream = rMedium.GetInStream(); 772 if ( pStream ) 773 { 774 if ( SotStorage::IsStorageFile( pStream ) ) 775 { 776 SvStorageRef aStorage = new SotStorage( pStream, sal_False ); 777 if ( aStorage->IsStream( C2S( "Equation Native" ) ) ) 778 { 779 // is this a MathType Storage? 780 MathType aEquation( aText ); 781 if ( sal_True == (bSuccess = (1 == aEquation.Parse( aStorage )) )) 782 Parse(); 783 } 784 } 785 else 786 { 787 //bSuccess = ImportSM20File( pStream ); 788 } 789 } 790 } 791 792 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) 793 { 794 //???OnDocumentPrinterChanged(0); 795 SetFormulaArranged( sal_False ); 796 Repaint(); 797 } 798 799 FinishedLoading( SFX_LOADED_ALL ); 800 return bSuccess; 801 } 802 803 804 sal_Bool SmDocShell::InitNew( const uno::Reference < embed::XStorage >& xStorage ) 805 { 806 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::InitNew" ); 807 808 sal_Bool bRet = sal_False; 809 if ( SfxObjectShell::InitNew( xStorage ) ) 810 { 811 bRet = sal_True; 812 SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000))); 813 } 814 return bRet; 815 } 816 817 818 sal_Bool SmDocShell::Load( SfxMedium& rMedium ) 819 { 820 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Load" ); 821 822 sal_Bool bRet = sal_False; 823 if( SfxObjectShell::Load( rMedium )) 824 { 825 uno::Reference < embed::XStorage > xStorage = GetMedium()->GetStorage(); 826 uno::Reference < container::XNameAccess > xAccess (xStorage, uno::UNO_QUERY); 827 if ( 828 ( 829 xAccess->hasByName( C2S( "content.xml" ) ) && 830 xStorage->isStreamElement( C2S( "content.xml" ) ) 831 ) || 832 ( 833 xAccess->hasByName( C2S( "Content.xml" ) ) && 834 xStorage->isStreamElement( C2S( "Content.xml" ) ) 835 ) 836 ) 837 { 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); 842 bRet = 0 == nError; 843 SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); 844 } 845 } 846 847 if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) 848 { 849 //???OnDocumentPrinterChanged(0); 850 SetFormulaArranged( sal_False ); 851 Repaint(); 852 } 853 854 FinishedLoading( SFX_LOADED_ALL ); 855 return bRet; 856 } 857 858 //------------------------------------------------------------------ 859 860 sal_Bool SmDocShell::Save() 861 { 862 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Save" ); 863 864 //! apply latest changes if necessary 865 UpdateText(); 866 867 if ( SfxObjectShell::Save() ) 868 { 869 if (!pTree) 870 Parse(); 871 if( pTree && !IsFormulaArranged() ) 872 ArrangeFormula(); 873 874 Reference<com::sun::star::frame::XModel> xModel(GetModel()); 875 SmXMLExportWrapper aEquation(xModel); 876 aEquation.SetFlat(sal_False); 877 return aEquation.Export(*GetMedium()); 878 } 879 880 return sal_False; 881 } 882 883 /* 884 * replace bad characters that can not be saved. (#i74144) 885 * */ 886 sal_Bool SmDocShell::ReplaceBadChars() 887 { 888 sal_Bool bReplace = sal_False; 889 if (pEditEngine) 890 { 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) 895 { 896 const sal_Unicode c = *pEngTxt++; 897 if (c < ' ' && c != '\r' && c != '\n' && c != '\t') 898 bReplace = sal_True; 899 } 900 if (bReplace) 901 { 902 sal_Unicode *pChgTxt = aEngTxt.GetBufferAccess(); 903 for (xub_StrLen i = 0; i < nLen; ++i) 904 { 905 sal_Unicode &rc = *pChgTxt++; 906 if (rc < ' ' && rc != '\r' && rc != '\n' && rc != '\t') 907 rc = ' '; 908 } 909 aEngTxt.ReleaseBufferAccess( nLen ); 910 911 aText = aEngTxt; 912 } 913 } 914 return bReplace; 915 } 916 917 918 void SmDocShell::UpdateText() 919 { 920 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::UpdateText" ); 921 922 if (pEditEngine && pEditEngine->IsModified()) 923 { 924 String aEngTxt( pEditEngine->GetText( LINEEND_LF ) ); 925 if (GetText() != aEngTxt) 926 SetText( aEngTxt ); 927 } 928 } 929 930 931 sal_Bool SmDocShell::SaveAs( SfxMedium& rMedium ) 932 { 933 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveAs" ); 934 935 sal_Bool bRet = sal_False; 936 937 //! apply latest changes if necessary 938 UpdateText(); 939 940 if ( SfxObjectShell::SaveAs( rMedium ) ) 941 { 942 if (!pTree) 943 Parse(); 944 if( pTree && !IsFormulaArranged() ) 945 ArrangeFormula(); 946 947 Reference<com::sun::star::frame::XModel> xModel(GetModel()); 948 SmXMLExportWrapper aEquation(xModel); 949 aEquation.SetFlat(sal_False); 950 bRet = aEquation.Export(rMedium); 951 } 952 return bRet; 953 } 954 955 sal_Bool SmDocShell::ConvertTo( SfxMedium &rMedium ) 956 { 957 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertTo" ); 958 959 sal_Bool bRet = sal_False; 960 const SfxFilter* pFlt = rMedium.GetFilter(); 961 if( pFlt ) 962 { 963 if( !pTree ) 964 Parse(); 965 if( pTree && !IsFormulaArranged() ) 966 ArrangeFormula(); 967 968 const String& rFltName = pFlt->GetFilterName(); 969 if(rFltName.EqualsAscii( STAROFFICE_XML )) 970 { 971 Reference<com::sun::star::frame::XModel> xModel(GetModel()); 972 SmXMLExportWrapper aEquation(xModel); 973 aEquation.SetFlat(sal_False); 974 bRet = aEquation.Export(rMedium); 975 } 976 else if(rFltName.EqualsAscii( MATHML_XML )) 977 { 978 Reference<com::sun::star::frame::XModel> xModel(GetModel()); 979 SmXMLExportWrapper aEquation(xModel); 980 aEquation.SetFlat(sal_True); 981 bRet = aEquation.Export(rMedium); 982 } 983 else if( pFlt->GetFilterName().EqualsAscii("MathType 3.x")) 984 bRet = WriteAsMathType3( rMedium ); 985 } 986 return bRet; 987 } 988 989 sal_Bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ) 990 { 991 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveCompleted" ); 992 993 if( SfxObjectShell::SaveCompleted( xStorage )) 994 return sal_True; 995 996 return sal_False; 997 } 998 999 1000 void SmDocShell::Execute(SfxRequest& rReq) 1001 { 1002 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Execute" ); 1003 1004 switch (rReq.GetSlot()) 1005 { 1006 case SID_TEXTMODE: 1007 { 1008 SmFormat aOldFormat = GetFormat(); 1009 SmFormat aNewFormat( aOldFormat ); 1010 aNewFormat.SetTextmode(!aOldFormat.IsTextmode()); 1011 1012 ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); 1013 if (pTmpUndoMgr) 1014 pTmpUndoMgr->AddUndoAction( 1015 new SmFormatAction(this, aOldFormat, aNewFormat)); 1016 1017 SetFormat( aNewFormat ); 1018 Repaint(); 1019 } 1020 break; 1021 1022 case SID_AUTO_REDRAW : 1023 { 1024 SmModule *pp = SM_MOD(); 1025 sal_Bool bRedraw = pp->GetConfig()->IsAutoRedraw(); 1026 pp->GetConfig()->SetAutoRedraw(!bRedraw); 1027 } 1028 break; 1029 1030 case SID_LOADSYMBOLS: 1031 LoadSymbols(); 1032 break; 1033 1034 case SID_SAVESYMBOLS: 1035 SaveSymbols(); 1036 break; 1037 1038 case SID_FONT: 1039 { 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" ); 1045 1046 SmFontTypeDialog *pFontTypeDialog = new SmFontTypeDialog( NULL, pDev ); 1047 1048 SmFormat aOldFormat = GetFormat(); 1049 pFontTypeDialog->ReadFrom( aOldFormat ); 1050 if (pFontTypeDialog->Execute() == RET_OK) 1051 { 1052 SmFormat aNewFormat( aOldFormat ); 1053 1054 pFontTypeDialog->WriteTo(aNewFormat); 1055 ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); 1056 if (pTmpUndoMgr) 1057 pTmpUndoMgr->AddUndoAction( 1058 new SmFormatAction(this, aOldFormat, aNewFormat)); 1059 1060 SetFormat( aNewFormat ); 1061 Repaint(); 1062 } 1063 delete pFontTypeDialog; 1064 } 1065 break; 1066 1067 case SID_FONTSIZE: 1068 { 1069 SmFontSizeDialog *pFontSizeDialog = new SmFontSizeDialog(NULL); 1070 1071 SmFormat aOldFormat = GetFormat(); 1072 pFontSizeDialog->ReadFrom( aOldFormat ); 1073 if (pFontSizeDialog->Execute() == RET_OK) 1074 { 1075 SmFormat aNewFormat( aOldFormat ); 1076 1077 pFontSizeDialog->WriteTo(aNewFormat); 1078 1079 ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); 1080 if (pTmpUndoMgr) 1081 pTmpUndoMgr->AddUndoAction( 1082 new SmFormatAction(this, aOldFormat, aNewFormat)); 1083 1084 SetFormat( aNewFormat ); 1085 Repaint(); 1086 } 1087 delete pFontSizeDialog; 1088 } 1089 break; 1090 1091 case SID_DISTANCE: 1092 { 1093 SmDistanceDialog *pDistanceDialog = new SmDistanceDialog(NULL); 1094 1095 SmFormat aOldFormat = GetFormat(); 1096 pDistanceDialog->ReadFrom( aOldFormat ); 1097 if (pDistanceDialog->Execute() == RET_OK) 1098 { 1099 SmFormat aNewFormat( aOldFormat ); 1100 1101 pDistanceDialog->WriteTo(aNewFormat); 1102 1103 ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); 1104 if (pTmpUndoMgr) 1105 pTmpUndoMgr->AddUndoAction( 1106 new SmFormatAction(this, aOldFormat, aNewFormat)); 1107 1108 SetFormat( aNewFormat ); 1109 Repaint(); 1110 } 1111 delete pDistanceDialog; 1112 } 1113 break; 1114 1115 case SID_ALIGN: 1116 { 1117 SmAlignDialog *pAlignDialog = new SmAlignDialog(NULL); 1118 1119 SmFormat aOldFormat = GetFormat(); 1120 pAlignDialog->ReadFrom( aOldFormat ); 1121 if (pAlignDialog->Execute() == RET_OK) 1122 { 1123 SmFormat aNewFormat( aOldFormat ); 1124 1125 pAlignDialog->WriteTo(aNewFormat); 1126 1127 SmModule *pp = SM_MOD(); 1128 SmFormat aFmt( pp->GetConfig()->GetStandardFormat() ); 1129 pAlignDialog->WriteTo( aFmt ); 1130 pp->GetConfig()->SetStandardFormat( aFmt ); 1131 1132 ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); 1133 if (pTmpUndoMgr) 1134 pTmpUndoMgr->AddUndoAction( 1135 new SmFormatAction(this, aOldFormat, aNewFormat)); 1136 1137 SetFormat( aNewFormat ); 1138 Repaint(); 1139 } 1140 delete pAlignDialog; 1141 } 1142 break; 1143 1144 case SID_TEXT: 1145 { 1146 const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXT); 1147 if (GetText() != rItem.GetValue()) 1148 SetText(rItem.GetValue()); 1149 } 1150 break; 1151 1152 case SID_UNDO: 1153 case SID_REDO: 1154 { 1155 ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager(); 1156 if( pTmpUndoMgr ) 1157 { 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(); 1163 1164 sal_Bool (::svl::IUndoManager:: *fnDo)(); 1165 1166 sal_uInt16 nCount; 1167 if( SID_UNDO == rReq.GetSlot() ) 1168 { 1169 nCount = pTmpUndoMgr->GetUndoActionCount(); 1170 fnDo = &::svl::IUndoManager::Undo; 1171 } 1172 else 1173 { 1174 nCount = pTmpUndoMgr->GetRedoActionCount(); 1175 fnDo = &::svl::IUndoManager::Redo; 1176 } 1177 1178 try 1179 { 1180 for( ; nCnt && nCount; --nCnt, --nCount ) 1181 (pTmpUndoMgr->*fnDo)(); 1182 } 1183 catch( const Exception& e ) 1184 { 1185 DBG_UNHANDLED_EXCEPTION(); 1186 } 1187 } 1188 Repaint(); 1189 SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); 1190 while( pFrm ) 1191 { 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 ); 1198 } 1199 } 1200 break; 1201 } 1202 1203 rReq.Done(); 1204 } 1205 1206 1207 void SmDocShell::GetState(SfxItemSet &rSet) 1208 { 1209 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetState" ); 1210 1211 SfxWhichIter aIter(rSet); 1212 1213 for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich()) 1214 { 1215 switch (nWh) 1216 { 1217 case SID_TEXTMODE: 1218 rSet.Put(SfxBoolItem(SID_TEXTMODE, GetFormat().IsTextmode())); 1219 break; 1220 1221 case SID_DOCTEMPLATE : 1222 rSet.DisableItem(SID_DOCTEMPLATE); 1223 break; 1224 1225 case SID_AUTO_REDRAW : 1226 { 1227 SmModule *pp = SM_MOD(); 1228 sal_Bool bRedraw = pp->GetConfig()->IsAutoRedraw(); 1229 1230 rSet.Put(SfxBoolItem(SID_AUTO_REDRAW, bRedraw)); 1231 } 1232 break; 1233 1234 case SID_MODIFYSTATUS: 1235 { 1236 sal_Unicode cMod = ' '; 1237 if (IsModified()) 1238 cMod = '*'; 1239 rSet.Put(SfxStringItem(SID_MODIFYSTATUS, String(cMod))); 1240 } 1241 break; 1242 1243 case SID_TEXT: 1244 rSet.Put(SfxStringItem(SID_TEXT, GetText())); 1245 break; 1246 1247 case SID_GAPHIC_SM: 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)); 1253 break; 1254 1255 case SID_UNDO: 1256 case SID_REDO: 1257 { 1258 SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); 1259 if( pFrm ) 1260 pFrm->GetSlotState( nWh, NULL, &rSet ); 1261 else 1262 rSet.DisableItem( nWh ); 1263 } 1264 break; 1265 1266 case SID_GETUNDOSTRINGS: 1267 case SID_GETREDOSTRINGS: 1268 { 1269 ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager(); 1270 if( pTmpUndoMgr ) 1271 { 1272 UniString(::svl::IUndoManager:: *fnGetComment)( size_t, bool const ) const; 1273 1274 sal_uInt16 nCount; 1275 if( SID_GETUNDOSTRINGS == nWh ) 1276 { 1277 nCount = pTmpUndoMgr->GetUndoActionCount(); 1278 fnGetComment = &::svl::IUndoManager::GetUndoActionComment; 1279 } 1280 else 1281 { 1282 nCount = pTmpUndoMgr->GetRedoActionCount(); 1283 fnGetComment = &::svl::IUndoManager::GetRedoActionComment; 1284 } 1285 if( nCount ) 1286 { 1287 String sList; 1288 for( sal_uInt16 n = 0; n < nCount; ++n ) 1289 ( sList += (pTmpUndoMgr->*fnGetComment)( n, ::svl::IUndoManager::TopLevel ) ) 1290 += '\n'; 1291 1292 SfxStringListItem aItem( nWh ); 1293 aItem.SetString( sList ); 1294 rSet.Put( aItem ); 1295 } 1296 } 1297 else 1298 rSet.DisableItem( nWh ); 1299 } 1300 break; 1301 } 1302 } 1303 } 1304 1305 1306 ::svl::IUndoManager *SmDocShell::GetUndoManager() 1307 { 1308 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetUndoManager" ); 1309 1310 if (!pEditEngine) 1311 GetEditEngine(); 1312 return &pEditEngine->GetUndoManager(); 1313 } 1314 1315 1316 void SmDocShell::SaveSymbols() 1317 { 1318 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveSymbols" ); 1319 1320 SmModule *pp = SM_MOD(); 1321 pp->GetSymbolManager().Save(); 1322 } 1323 1324 1325 void SmDocShell::Draw(OutputDevice *pDevice, 1326 const JobSetup &, 1327 sal_uInt16 /*nAspect*/) 1328 { 1329 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" ); 1330 1331 pDevice->IntersectClipRegion(GetVisArea()); 1332 Point atmppoint; 1333 Draw(*pDevice, atmppoint); 1334 } 1335 1336 SfxItemPool& SmDocShell::GetPool() const 1337 { 1338 return SFX_APP()->GetPool(); 1339 } 1340 1341 void SmDocShell::SetVisArea(const Rectangle & rVisArea) 1342 { 1343 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetVisArea" ); 1344 1345 Rectangle aNewRect(rVisArea); 1346 1347 aNewRect.SetPos(Point()); 1348 1349 if (! aNewRect.Right()) aNewRect.Right() = 2000; 1350 if (! aNewRect.Bottom()) aNewRect.Bottom() = 1000; 1351 1352 sal_Bool bIsEnabled = IsEnableSetModified(); 1353 if ( bIsEnabled ) 1354 EnableSetModified( sal_False ); 1355 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() ) 1361 { 1362 GetFrame()->LockAdjustPosSizePixel(); 1363 bUnLockFrame = sal_True; 1364 } 1365 else 1366 bUnLockFrame = sal_False; 1367 1368 SfxObjectShell::SetVisArea( aNewRect ); 1369 1370 if( bUnLockFrame ) 1371 GetFrame()->UnlockAdjustPosSizePixel(); 1372 1373 if ( bIsEnabled ) 1374 EnableSetModified( bIsEnabled ); 1375 } 1376 1377 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 1385 { 1386 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::FillClass" ); 1387 1388 if (nFileFormat == SOFFICE_FILEFORMAT_60 ) 1389 { 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)); 1394 } 1395 else if (nFileFormat == SOFFICE_FILEFORMAT_8 ) 1396 { 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)); 1401 } 1402 } 1403 1404 sal_uLong SmDocShell::GetMiscStatus() const 1405 { 1406 return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE 1407 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE; 1408 } 1409 1410 void SmDocShell::SetModified(sal_Bool bModified) 1411 { 1412 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetModified" ); 1413 1414 if( IsEnableSetModified() ) 1415 { 1416 SfxObjectShell::SetModified( bModified ); 1417 Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED)); 1418 } 1419 } 1420 1421 sal_Bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium ) 1422 { 1423 RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::WriteAsMathType3" ); 1424 1425 MathType aEquation( aText, pTree ); 1426 1427 sal_Bool bRet = 0 != aEquation.ConvertFromStarMath( rMedium ); 1428 return bRet; 1429 } 1430 1431 1432