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