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