/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_starmath.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "unomodel.hxx" #include "view.hxx" #include "config.hxx" #include "dialog.hxx" #include "document.hxx" #include "starmath.hrc" #include "toolbox.hxx" #include "mathmlimport.hxx" #define MINWIDTH 200 #define MINHEIGHT 200 #define MINSPLIT 40 #define SPLITTERWIDTH 2 #define MINZOOM 25 #define MAXZOOM 800 #define SmViewShell #include "smslots.hxx" using namespace com::sun::star; using namespace com::sun::star::accessibility; using namespace com::sun::star::uno; using ::rtl::OUString; ////////////////////////////////////////////////////////////////////// SmGraphicWindow::SmGraphicWindow(SmViewShell* pShell): ScrollableWindow(&pShell->GetViewFrame()->GetWindow(), 0), pAccessible(0), pViewShell(pShell), nZoom(100), bIsCursorVisible(sal_False) { // docking windows are usually hidden (often already done in the // resource) and will be shown by the sfx framework. Hide(); const Fraction aFraction (1,1); SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction)); ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); SetTotalSize(); SetHelpId(HID_SMA_WIN_DOCUMENT); SetUniqueId(HID_SMA_WIN_DOCUMENT); } SmGraphicWindow::~SmGraphicWindow() { if (pAccessible) pAccessible->ClearWin(); // make Accessible dysfunctional // Note: memory for pAccessible will be freed when the reference // xAccessible is released. } void SmGraphicWindow::StateChanged( StateChangedType eType ) { if ( eType == STATE_CHANGE_INITSHOW ) Show(); ScrollableWindow::StateChanged( eType ); } void SmGraphicWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg ) { // Note: SetTextColor not necessary since the nodes that // get painted have the color information. #if OSL_DEBUG_LEVEL > 1 // ColorData nVal = rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor; #endif SetBackground( Color( (ColorData) rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor ) ); Invalidate(); } void SmGraphicWindow::DataChanged( const DataChangedEvent& rEvt ) { ApplyColorConfigValues( SM_MOD()->GetColorConfig() ); ScrollableWindow::DataChanged( rEvt ); } void SmGraphicWindow::MouseButtonDown(const MouseEvent& rMEvt) { ScrollableWindow::MouseButtonDown(rMEvt); // // set formula-cursor and selection of edit window according to the // position clicked at // DBG_ASSERT(rMEvt.GetClicks() > 0, "Sm : 0 clicks"); if ( rMEvt.IsLeft() && pViewShell->GetEditWindow() ) { const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(); //! kann NULL sein! Z.B. wenn bereits beim laden des Dokuments (bevor der //! Parser angeworfen wurde) ins Fenster geklickt wird. if (!pTree) return; // get click position relativ to formula Point aPos (PixelToLogic(rMEvt.GetPosPixel()) - GetFormulaDrawPos()); // if it was clicked inside the formula then get the appropriate node const SmNode *pNode = 0; if (pTree->OrientedDist(aPos) <= 0) pNode = pTree->FindRectClosestTo(aPos); if (pNode) { SmEditWindow *pEdit = pViewShell->GetEditWindow(); const SmToken aToken (pNode->GetToken()); #ifdef notnow // include introducing symbols of special char and text // (i.e. '%' and '"') sal_uInt16 nExtra = (aToken.eType == TSPECIAL || aToken.eType == TTEXT) ? 1 : 0; // set selection to the beginning of the token ESelection aSel (aToken.nRow - 1, aToken.nCol - 1 - nExtra); if (rMEvt.GetClicks() != 1) { // select whole token // for text include terminating symbol (ie '"') aSel.nEndPos += aToken.aText.Len() + nExtra + (aToken.eType == TTEXT ? 1 : 0); } #endif // set selection to the beginning of the token ESelection aSel (aToken.nRow - 1, aToken.nCol - 1); if (rMEvt.GetClicks() != 1 || aToken.eType == TPLACE) aSel.nEndPos = aSel.nEndPos + sal::static_int_cast< sal_uInt16 >(aToken.aText.Len()); pEdit->SetSelection(aSel); SetCursor(pNode); // allow for immediate editing and //! implicitly synchronize the cursor position mark in this window pEdit->GrabFocus(); } } } void SmGraphicWindow::GetFocus() { /* if (xAccessible.is()) { uno::Any aOldValue, aNewValue; // aOldValue remains empty aNewValue <<= AccessibleStateType::FOCUSED; pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); } */ } void SmGraphicWindow::LoseFocus() { ScrollableWindow::LoseFocus(); if (xAccessible.is()) { uno::Any aOldValue, aNewValue; aOldValue <<= AccessibleStateType::FOCUSED; // aNewValue remains empty pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); } } void SmGraphicWindow::ShowCursor(sal_Bool bShow) // shows or hides the formula-cursor depending on 'bShow' is sal_True or not { sal_Bool bInvert = bShow != IsCursorVisible(); if (bInvert) InvertTracking(aCursorRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW); SetIsCursorVisible(bShow); } void SmGraphicWindow::SetCursor(const SmNode *pNode) { const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(); // get appropriate rectangle Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()), aTLPos (GetFormulaDrawPos() + aOffset); aTLPos.X() -= pNode->GetItalicLeftSpace(); Size aSize (pNode->GetItalicSize()); Point aBRPos (aTLPos.X() + aSize.Width(), aTLPos.Y() + aSize.Height()); SetCursor(Rectangle(aTLPos, aSize)); } void SmGraphicWindow::SetCursor(const Rectangle &rRect) // sets cursor to new position (rectangle) 'rRect'. // The old cursor will be removed, and the new one will be shown if // that is activated in the ConfigItem { SmModule *pp = SM_MOD(); if (IsCursorVisible()) ShowCursor(sal_False); // clean up remains of old cursor aCursorRect = rRect; if (pp->GetConfig()->IsShowFormulaCursor()) ShowCursor(sal_True); // draw new cursor } const SmNode * SmGraphicWindow::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol) // looks for a VISIBLE node in the formula tree with its token at // (or around) the position 'nRow', 'nCol' in the edit window // (row and column numbering starts with 1 there!). // If there is such a node the formula-cursor is set to cover that nodes // rectangle. If not the formula-cursor will be hidden. // In any case the search result is being returned. { // find visible node with token at nRow, nCol const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(), *pNode = 0; if (pTree) pNode = pTree->FindTokenAt(nRow, nCol); if (pNode) SetCursor(pNode); else ShowCursor(sal_False); return pNode; } void SmGraphicWindow::Paint(const Rectangle&) { DBG_ASSERT(pViewShell, "Sm : NULL pointer"); SmDocShell &rDoc = *pViewShell->GetDoc(); Point aPoint; rDoc.Draw(*this, aPoint); //! modifies aPoint to be the topleft //! corner of the formula SetFormulaDrawPos(aPoint); SetIsCursorVisible(sal_False); // (old) cursor must be drawn again const SmEditWindow *pEdit = pViewShell->GetEditWindow(); if (pEdit) { // get new position for formula-cursor (for possible altered formula) sal_uInt16 nRow, nCol; SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol); nRow++; nCol++; const SmNode *pFound = SetCursorPos(nRow, nCol); SmModule *pp = SM_MOD(); if (pFound && pp->GetConfig()->IsShowFormulaCursor()) ShowCursor(sal_True); } } void SmGraphicWindow::SetTotalSize () { SmDocShell &rDoc = *pViewShell->GetDoc(); const Size aTmp( PixelToLogic( LogicToPixel( rDoc.GetSize() ))); if ( aTmp != ScrollableWindow::GetTotalSize() ) ScrollableWindow::SetTotalSize( aTmp ); } void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt) { if (! (GetView() && GetView()->KeyInput(rKEvt)) ) ScrollableWindow::KeyInput(rKEvt); } void SmGraphicWindow::Command(const CommandEvent& rCEvt) { sal_Bool bCallBase = sal_True; if ( !pViewShell->GetViewFrame()->GetFrame().IsInPlace() ) { switch ( rCEvt.GetCommand() ) { case COMMAND_CONTEXTMENU: { GetParent()->ToTop(); SmResId aResId( RID_VIEWMENU ); PopupMenu* pPopupMenu = new PopupMenu(aResId); pPopupMenu->SetSelectHdl(LINK(this, SmGraphicWindow, MenuSelectHdl)); Point aPos(5, 5); if (rCEvt.IsMouseEvent()) aPos = rCEvt.GetMousePosPixel(); DBG_ASSERT( pViewShell, "view shell missing" ); // added for replaceability of context menus #96085, #93782 pViewShell->GetViewFrame()->GetBindings().GetDispatcher() ->ExecutePopup( aResId, this, &aPos ); //pPopupMenu->Execute( this, aPos ); delete pPopupMenu; bCallBase = sal_False; } break; case COMMAND_WHEEL: { const CommandWheelData* pWData = rCEvt.GetWheelData(); if ( pWData && COMMAND_WHEEL_ZOOM == pWData->GetMode() ) { sal_uInt16 nTmpZoom = GetZoom(); if( 0L > pWData->GetDelta() ) nTmpZoom -= 10; else nTmpZoom += 10; SetZoom( nTmpZoom ); bCallBase = sal_False; } } break; } } if ( bCallBase ) ScrollableWindow::Command (rCEvt); } IMPL_LINK_INLINE_START( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu ) { SmViewShell *pViewSh = GetView(); if (pViewSh) pViewSh->GetViewFrame()->GetDispatcher()->Execute( pMenu->GetCurItemId() ); return 0; } IMPL_LINK_INLINE_END( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu ) void SmGraphicWindow::SetZoom(sal_uInt16 Factor) { nZoom = Min(Max((sal_uInt16) Factor, (sal_uInt16) MINZOOM), (sal_uInt16) MAXZOOM); Fraction aFraction (nZoom, 100); SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction) ); SetTotalSize(); SmViewShell *pViewSh = GetView(); if (pViewSh) pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM); Invalidate(); } void SmGraphicWindow::ZoomToFitInWindow() { SmDocShell &rDoc = *pViewShell->GetDoc(); // set defined mapmode before calling 'LogicToPixel' below SetMapMode(MapMode(MAP_100TH_MM)); Size aSize (LogicToPixel(rDoc.GetSize())); Size aWindowSize (GetSizePixel()); if (aSize.Width() > 0 && aSize.Height() > 0) { long nVal = Min ((85 * aWindowSize.Width()) / aSize.Width(), (85 * aWindowSize.Height()) / aSize.Height()); SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) ); } } uno::Reference< XAccessible > SmGraphicWindow::CreateAccessible() { if (!pAccessible) { pAccessible = new SmGraphicAccessible( this ); xAccessible = pAccessible; } return xAccessible; } /**************************************************************************/ SmGraphicController::SmGraphicController(SmGraphicWindow &rSmGraphic, sal_uInt16 nId_, SfxBindings &rBindings) : SfxControllerItem(nId_, rBindings), rGraphic(rSmGraphic) { } void SmGraphicController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) { rGraphic.SetTotalSize(); rGraphic.Invalidate(); SfxControllerItem::StateChanged (nSID, eState, pState); } /**************************************************************************/ SmEditController::SmEditController(SmEditWindow &rSmEdit, sal_uInt16 nId_, SfxBindings &rBindings) : SfxControllerItem(nId_, rBindings), rEdit(rSmEdit) { } #if OSL_DEBUG_LEVEL > 1 SmEditController::~SmEditController() { } #endif void SmEditController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) { const SfxStringItem *pItem = PTR_CAST(SfxStringItem, pState); if ((pItem != NULL) && (rEdit.GetText() != pItem->GetValue())) rEdit.SetText(pItem->GetValue()); SfxControllerItem::StateChanged (nSID, eState, pState); } /**************************************************************************/ SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings *pBindings_, SfxChildWindow *pChildWindow, Window *pParent) : SfxDockingWindow(pBindings_, pChildWindow, pParent, SmResId(RID_CMDBOXWINDOW)), aEdit (*this), aController (aEdit, SID_TEXT, *pBindings_), bExiting (sal_False) { Hide (); aInitialFocusTimer.SetTimeoutHdl(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl)); aInitialFocusTimer.SetTimeout(100); } SmCmdBoxWindow::~SmCmdBoxWindow () { aInitialFocusTimer.Stop(); bExiting = sal_True; } SmViewShell * SmCmdBoxWindow::GetView() { SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell(); return PTR_CAST(SmViewShell, pView); } void SmCmdBoxWindow::Resize() { Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel()); if (! IsFloatingMode()) { switch (GetAlignment()) { case SFX_ALIGN_TOP: aRect.Bottom()--; break; case SFX_ALIGN_BOTTOM: aRect.Top()++; break; case SFX_ALIGN_LEFT: aRect.Right()--; break; case SFX_ALIGN_RIGHT: aRect.Left()++; break; default: break; } } DecorationView aView(this); aRect.Left() += 6; aRect.Top() += 6; aRect.Right()-= 6; aRect.Bottom()-= 6; aRect = aView.DrawFrame( aRect, FRAME_DRAW_IN ); aEdit.SetPosSizePixel(aRect.TopLeft(), aRect.GetSize()); SfxDockingWindow::Resize(); Invalidate(); } void SmCmdBoxWindow::Paint(const Rectangle& /*rRect*/) { Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel()); DecorationView aView(this); if (! IsFloatingMode()) { Point aFrom, aTo; switch (GetAlignment()) { case SFX_ALIGN_TOP: aFrom = aRect.BottomLeft(); aTo = aRect.BottomRight(); aRect.Bottom()--; break; case SFX_ALIGN_BOTTOM: aFrom = aRect.TopLeft(); aTo = aRect.TopRight(); aRect.Top()++; break; case SFX_ALIGN_LEFT: aFrom = aRect.TopRight(); aTo = aRect.BottomRight(); aRect.Right()--; break; case SFX_ALIGN_RIGHT: aFrom = aRect.TopLeft(); aTo = aRect.BottomLeft(); aRect.Left()++; break; default: break; } DrawLine( aFrom, aTo ); aView.DrawFrame(aRect, FRAME_DRAW_OUT); } aRect.Left() += 6; aRect.Top() += 6; aRect.Right()-= 6; aRect.Bottom()-= 6; aRect = aView.DrawFrame( aRect, FRAME_DRAW_IN ); } Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign) { switch (eAlign) { case SFX_ALIGN_LEFT: case SFX_ALIGN_RIGHT: return Size(); default: break; } return SfxDockingWindow::CalcDockingSize(eAlign); } SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual, SfxChildAlignment eWish) { switch (eWish) { case SFX_ALIGN_TOP: case SFX_ALIGN_BOTTOM: case SFX_ALIGN_NOALIGNMENT: return eWish; default: break; } return eActual; } void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange ) { if (STATE_CHANGE_INITSHOW == nStateChange) { Resize(); // #98848# avoid SmEditWindow not being painted correctly // set initial position of window in floating mode if (sal_True == IsFloatingMode()) AdjustPosition(); //! don't change pos in docking-mode ! // // make sure the formula can be edited right away // aEdit.GrabFocus(); // grab focus as above does not work... // Thus we implement a timer based solution to get the initial // focus in the Edit window. aInitialFocusTimer.Start(); } SfxDockingWindow::StateChanged( nStateChange ); } IMPL_LINK( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, EMPTYARG /*pTimer*/ ) { // We want to have the focus in the edit window once Math has been opened // to allow for immediate typing. // Problem: There is no proper way to do this // Thus: this timer based solution has been implemented (see GrabFocus below) // // Follow-up problem (#i114910): grabbing the focus may bust the help system since // it relies on getting the current frame which conflicts with grabbing the focus. // Thus aside from the 'GrabFocus' call everything else is to get the // help reliably working despite using 'GrabFocus'. try { uno::Reference< frame::XDesktop > xDesktop; uno::Reference< lang::XMultiServiceFactory > xSMGR( comphelper::getProcessServiceFactory() ); if (xSMGR.is()) { xDesktop = uno::Reference< frame::XDesktop >( xSMGR->createInstance( rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" )), uno::UNO_QUERY_THROW ); } aEdit.GrabFocus(); if (xDesktop.is()) { bool bInPlace = GetView()->GetViewFrame()->GetFrame().IsInPlace(); uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface()); if ( bInPlace ) { uno::Reference< container::XChild > xModel( GetView()->GetDoc()->GetModel(), uno::UNO_QUERY_THROW ); uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW ); uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() ); uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW ); xParentFrame->setActiveFrame( xFrame ); } else { uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY ); xFramesSupplier->setActiveFrame( xFrame ); } } } catch (uno::Exception &) { DBG_ASSERT( 0, "failed to properly set initial focus to edit window" ); } return 0; } void SmCmdBoxWindow::AdjustPosition() { Point aPt; const Rectangle aRect( aPt, GetParent()->GetOutputSizePixel() ); Point aTopLeft( Point( aRect.Left(), aRect.Bottom() - GetSizePixel().Height() ) ); Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) ); if (aPos.X() < 0) aPos.X() = 0; if (aPos.Y() < 0) aPos.Y() = 0; SetPosPixel( aPos ); } void SmCmdBoxWindow::ToggleFloatingMode() { SfxDockingWindow::ToggleFloatingMode(); if (GetFloatingWindow()) GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50)); } void SmCmdBoxWindow::GetFocus() { if (!bExiting) aEdit.GrabFocus(); } /**************************************************************************/ SFX_IMPL_DOCKINGWINDOW(SmCmdBoxWrapper, SID_CMDBOXWINDOW); SmCmdBoxWrapper::SmCmdBoxWrapper(Window *pParentWindow, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo *pInfo) : SfxChildWindow(pParentWindow, nId) { pWindow = new SmCmdBoxWindow(pBindings, this, pParentWindow); // make window docked to the bottom initially (after first start) eChildAlignment = SFX_ALIGN_BOTTOM; ((SfxDockingWindow *)pWindow)->Initialize(pInfo); } #if OSL_DEBUG_LEVEL > 1 SmCmdBoxWrapper::~SmCmdBoxWrapper() { } #endif /**************************************************************************/ struct SmViewShell_Impl { sfx2::DocumentInserter* pDocInserter; SfxRequest* pRequest; SmViewShell_Impl() : pDocInserter( NULL ) , pRequest( NULL ) {} ~SmViewShell_Impl() { delete pDocInserter; delete pRequest; } }; TYPEINIT1( SmViewShell, SfxViewShell ); SFX_IMPL_INTERFACE(SmViewShell, SfxViewShell, SmResId(0)) { SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS | SFX_VISIBILITY_STANDARD | SFX_VISIBILITY_FULLSCREEN | SFX_VISIBILITY_SERVER, SmResId(RID_MATH_TOOLBOX )); SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE); SFX_CHILDWINDOW_REGISTRATION(SmToolBoxWrapper::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(SmCmdBoxWrapper::GetChildWindowId()); } SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default") { SFX_VIEW_REGISTRATION(SmDocShell); } Size SmViewShell::GetOptimalSizePixel() const { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetOptimalSizePixel" ); return aGraphic.LogicToPixel( ((SmViewShell*)this)->GetDoc()->GetSize() ); } void SmViewShell::AdjustPosSizePixel(const Point &rPos, const Size &rSize) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::AdjustPosSizePixel" ); aGraphic.SetPosSizePixel(rPos, rSize); } void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InnerResizePixel" ); Size aObjSize = GetObjectShell()->GetVisArea().GetSize(); if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 ) { Size aProvidedSize = GetWindow()->PixelToLogic( rSize, MAP_100TH_MM ); SfxViewShell::SetZoomFactor( Fraction( aProvidedSize.Width(), aObjSize.Width() ), Fraction( aProvidedSize.Height(), aObjSize.Height() ) ); } SetBorderPixel( SvBorder() ); GetGraphicWindow().SetPosSizePixel(rOfs, rSize); GetGraphicWindow().SetTotalSize(); } void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::OuterResizePixel" ); SmGraphicWindow &rWin = GetGraphicWindow(); rWin.SetPosSizePixel(rOfs, rSize); if (GetDoc()->IsPreview()) rWin.ZoomToFitInWindow(); rWin.Update(); } void SmViewShell::QueryObjAreaPixel( Rectangle& rRect ) const { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::QueryObjAreaPixel" ); rRect.SetSize( GetGraphicWindow().GetSizePixel() ); } void SmViewShell::SetZoomFactor( const Fraction &rX, const Fraction &rY ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetZoomFactor" ); const Fraction &rFrac = rX < rY ? rX : rY; GetGraphicWindow().SetZoom( (sal_uInt16) long(rFrac * Fraction( 100, 1 )) ); //Um Rundungsfehler zu minimieren lassen wir von der Basisklasse ggf. //auch die krummen Werte einstellen SfxViewShell::SetZoomFactor( rX, rY ); } Size SmViewShell::GetTextLineSize(OutputDevice& rDevice, const String& rLine) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextLineSize" ); String aText; Size aSize(rDevice.GetTextWidth(rLine), rDevice.GetTextHeight()); sal_uInt16 nTabs = rLine.GetTokenCount('\t'); if (nTabs > 0) { long TabPos = rDevice.GetTextWidth('n') * 8; aSize.Width() = 0; for (sal_uInt16 i = 0; i < nTabs; i++) { if (i > 0) aSize.Width() = ((aSize.Width() / TabPos) + 1) * TabPos; aText = rLine.GetToken(i, '\t'); aText.EraseLeadingChars('\t'); aText.EraseTrailingChars('\t'); aSize.Width() += rDevice.GetTextWidth(aText); } } return aSize; } Size SmViewShell::GetTextSize(OutputDevice& rDevice, const String& rText, long MaxWidth) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextSize" ); Size aSize; String aLine; Size TextSize; String aText; sal_uInt16 nLines = rText.GetTokenCount('\n'); for (sal_uInt16 i = 0; i < nLines; i++) { aLine = rText.GetToken(i, '\n'); aLine.EraseAllChars('\r'); aLine.EraseLeadingChars('\n'); aLine.EraseTrailingChars('\n'); aSize = GetTextLineSize(rDevice, aLine); if (aSize.Width() > MaxWidth) { do { xub_StrLen m = aLine.Len(); xub_StrLen nLen = m; for (xub_StrLen n = 0; n < nLen; n++) { sal_Unicode cLineChar = aLine.GetChar(n); if ((cLineChar == ' ') || (cLineChar == '\t')) { aText = aLine.Copy(0, n); if (GetTextLineSize(rDevice, aText).Width() < MaxWidth) m = n; else break; } } aText = aLine.Copy(0, m); aLine.Erase(0, m); aSize = GetTextLineSize(rDevice, aText); TextSize.Height() += aSize.Height(); TextSize.Width() = Max(TextSize.Width(), Min(aSize.Width(), MaxWidth)); aLine.EraseLeadingChars(' '); aLine.EraseLeadingChars('\t'); aLine.EraseLeadingChars(' '); } while (aLine.Len() > 0); } else { TextSize.Height() += aSize.Height(); TextSize.Width() = Max(TextSize.Width(), aSize.Width()); } } return TextSize; } void SmViewShell::DrawTextLine(OutputDevice& rDevice, const Point& rPosition, const String& rLine) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawTextLine" ); String aText; Point aPoint (rPosition); sal_uInt16 nTabs = rLine.GetTokenCount('\t'); if (nTabs > 0) { long TabPos = rDevice.GetTextWidth('n') * 8; for (sal_uInt16 i = 0; i < nTabs; i++) { if (i > 0) aPoint.X() = ((aPoint.X() / TabPos) + 1) * TabPos; aText = rLine.GetToken(i, '\t'); aText.EraseLeadingChars('\t'); aText.EraseTrailingChars('\t'); rDevice.DrawText(aPoint, aText); aPoint.X() += rDevice.GetTextWidth(aText); } } else rDevice.DrawText(aPoint, rLine); } void SmViewShell::DrawText(OutputDevice& rDevice, const Point& rPosition, const String& rText, sal_uInt16 MaxWidth) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawText" ); sal_uInt16 nLines = rText.GetTokenCount('\n'); Point aPoint (rPosition); Size aSize; String aLine; String aText; for (sal_uInt16 i = 0; i < nLines; i++) { aLine = rText.GetToken(i, '\n'); aLine.EraseAllChars('\r'); aLine.EraseLeadingChars('\n'); aLine.EraseTrailingChars('\n'); aSize = GetTextLineSize(rDevice, aLine); if (aSize.Width() > MaxWidth) { do { xub_StrLen m = aLine.Len(); xub_StrLen nLen = m; for (xub_StrLen n = 0; n < nLen; n++) { sal_Unicode cLineChar = aLine.GetChar(n); if ((cLineChar == ' ') || (cLineChar == '\t')) { aText = aLine.Copy(0, n); if (GetTextLineSize(rDevice, aText).Width() < MaxWidth) m = n; else break; } } aText = aLine.Copy(0, m); aLine.Erase(0, m); DrawTextLine(rDevice, aPoint, aText); aPoint.Y() += aSize.Height(); aLine.EraseLeadingChars(' '); aLine.EraseLeadingChars('\t'); aLine.EraseLeadingChars(' '); } while (GetTextLineSize(rDevice, aLine).Width() > MaxWidth); // print the remaining text if (aLine.Len() > 0) { DrawTextLine(rDevice, aPoint, aLine); aPoint.Y() += aSize.Height(); } } else { DrawTextLine(rDevice, aPoint, aLine); aPoint.Y() += aSize.Height(); } } } void SmViewShell::Impl_Print( OutputDevice &rOutDev, const SmPrintUIOptions &rPrintUIOptions, Rectangle aOutRect, Point aZeroPoint ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Impl_Print" ); const bool bIsPrintTitle = rPrintUIOptions.getBoolValue( PRTUIOPT_TITLE_ROW, sal_True ); const bool bIsPrintFrame = rPrintUIOptions.getBoolValue( PRTUIOPT_BORDER, sal_True ); const bool bIsPrintFormulaText = rPrintUIOptions.getBoolValue( PRTUIOPT_FORMULA_TEXT, sal_True ); SmPrintSize ePrintSize( static_cast< SmPrintSize >( rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_FORMAT, PRINT_SIZE_NORMAL ) )); const sal_uInt16 nZoomFactor = static_cast< sal_uInt16 >(rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_SCALE, 100 )); // IsIgnoreSpacesRight is a parser option! Thus it does not get evaluated here anymore (too late). // const bool bNoRightSpaces = rPrintUIOptions.getBoolValue( PRTUIOPT_NO_RIGHT_SPACE, sal_True ); rOutDev.Push(); rOutDev.SetLineColor( Color(COL_BLACK) ); // output text on top if (bIsPrintTitle) { Size aSize600 (0, 600); Size aSize650 (0, 650); Font aFont(FAMILY_DONTKNOW, aSize600); aFont.SetAlign(ALIGN_TOP); aFont.SetWeight(WEIGHT_BOLD); aFont.SetSize(aSize650); aFont.SetColor( Color(COL_BLACK) ); rOutDev.SetFont(aFont); Size aTitleSize (GetTextSize(rOutDev, GetDoc()->GetTitle(), aOutRect.GetWidth() - 200)); aFont.SetWeight(WEIGHT_NORMAL); aFont.SetSize(aSize600); rOutDev.SetFont(aFont); Size aDescSize (GetTextSize(rOutDev, GetDoc()->GetComment(), aOutRect.GetWidth() - 200)); if (bIsPrintFrame) rOutDev.DrawRect(Rectangle(aOutRect.TopLeft(), Size(aOutRect.GetWidth(), 100 + aTitleSize.Height() + 200 + aDescSize.Height() + 100))); aOutRect.Top() += 200; // output title aFont.SetWeight(WEIGHT_BOLD); aFont.SetSize(aSize650); rOutDev.SetFont(aFont); Point aPoint(aOutRect.Left() + (aOutRect.GetWidth() - aTitleSize.Width()) / 2, aOutRect.Top()); DrawText(rOutDev, aPoint, GetDoc()->GetTitle(), sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); aOutRect.Top() += aTitleSize.Height() + 200; // output description aFont.SetWeight(WEIGHT_NORMAL); aFont.SetSize(aSize600); rOutDev.SetFont(aFont); aPoint.X() = aOutRect.Left() + (aOutRect.GetWidth() - aDescSize.Width()) / 2; aPoint.Y() = aOutRect.Top(); DrawText(rOutDev, aPoint, GetDoc()->GetComment(), sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); aOutRect.Top() += aDescSize.Height() + 300; } // output text on bottom if (bIsPrintFormulaText) { Font aFont(FAMILY_DONTKNOW, Size(0, 600)); aFont.SetAlign(ALIGN_TOP); aFont.SetColor( Color(COL_BLACK) ); // get size rOutDev.SetFont(aFont); Size aSize (GetTextSize(rOutDev, GetDoc()->GetText(), aOutRect.GetWidth() - 200)); aOutRect.Bottom() -= aSize.Height() + 600; if (bIsPrintFrame) rOutDev.DrawRect(Rectangle(aOutRect.BottomLeft(), Size(aOutRect.GetWidth(), 200 + aSize.Height() + 200))); Point aPoint (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2, aOutRect.Bottom() + 300); DrawText(rOutDev, aPoint, GetDoc()->GetText(), sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200)); aOutRect.Bottom() -= 200; } if (bIsPrintFrame) rOutDev.DrawRect(aOutRect); aOutRect.Top() += 100; aOutRect.Left() += 100; aOutRect.Bottom() -= 100; aOutRect.Right() -= 100; Size aSize (GetDoc()->GetSize()); MapMode OutputMapMode; // PDF export should always use PRINT_SIZE_NORMAL ... if (!rPrintUIOptions.getBoolValue( "IsPrinter", sal_False ) ) ePrintSize = PRINT_SIZE_NORMAL; switch (ePrintSize) { case PRINT_SIZE_NORMAL: OutputMapMode = MapMode(MAP_100TH_MM); break; case PRINT_SIZE_SCALED: if ((aSize.Width() > 0) && (aSize.Height() > 0)) { Size OutputSize (rOutDev.LogicToPixel(Size(aOutRect.GetWidth(), aOutRect.GetHeight()), MapMode(MAP_100TH_MM))); Size GraphicSize (rOutDev.LogicToPixel(aSize, MapMode(MAP_100TH_MM))); sal_uInt16 nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width() * 100L, GraphicSize.Width()), (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height())); Fraction aFraction ((sal_uInt16) Max ((sal_uInt16) MINZOOM, Min((sal_uInt16) MAXZOOM, (sal_uInt16) (nZ - 10))), (sal_uInt16) 100); OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction); } else OutputMapMode = MapMode(MAP_100TH_MM); break; case PRINT_SIZE_ZOOMED: { Fraction aFraction( nZoomFactor, 100 ); OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction); break; } } aSize = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aSize, OutputMapMode), MapMode(MAP_100TH_MM)); Point aPos (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2, aOutRect.Top() + (aOutRect.GetHeight() - aSize.Height()) / 2); aPos = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aPos, MapMode(MAP_100TH_MM)), OutputMapMode); aOutRect = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aOutRect, MapMode(MAP_100TH_MM)), OutputMapMode); rOutDev.SetMapMode(OutputMapMode); rOutDev.SetClipRegion(Region(aOutRect)); GetDoc()->Draw(rOutDev, aPos); rOutDev.SetClipRegion(); rOutDev.Pop(); } sal_uInt16 SmViewShell::Print(SfxProgress & /*rProgress*/, sal_Bool /*bIsAPI*/) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Print" ); DBG_ASSERT( 0, "SmViewShell::Print: no longer used with new UI print dialog. Should be removed!!" ); return 0; } SfxPrinter* SmViewShell::GetPrinter(sal_Bool bCreate) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetPrinter" ); SmDocShell *pDoc = GetDoc(); if ( pDoc->HasPrinter() || bCreate ) return pDoc->GetPrinter(); return 0; } sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, sal_uInt16 nDiffFlags, bool ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetPrinter" ); SfxPrinter *pOld = GetDoc()->GetPrinter(); if ( pOld && pOld->IsPrinting() ) return SFX_PRINTERROR_BUSY; if ((nDiffFlags & SFX_PRINTER_PRINTER) == SFX_PRINTER_PRINTER) GetDoc()->SetPrinter( pNewPrinter ); if ((nDiffFlags & SFX_PRINTER_OPTIONS) == SFX_PRINTER_OPTIONS) { SmModule *pp = SM_MOD(); pp->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions()); } return 0; } SfxTabPage* SmViewShell::CreatePrintOptionsPage(Window *pParent, const SfxItemSet &rOptions) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::CreatePrintOptionsPage" ); return SmPrintOptionsTabPage::Create(pParent, rOptions); } SmEditWindow *SmViewShell::GetEditWindow() { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetEditWindow" ); SmCmdBoxWrapper *pWrapper = (SmCmdBoxWrapper *) GetViewFrame()-> GetChildWindow( SmCmdBoxWrapper::GetChildWindowId() ); if (pWrapper != NULL) { SmEditWindow *pEditWin = pWrapper->GetEditWindow(); DBG_ASSERT( pEditWin, "SmEditWindow missing" ); return pEditWin; } return NULL; } void SmViewShell::SetStatusText(const String& Text) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetStatusText" ); StatusText = Text; GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS); } void SmViewShell::ShowError( const SmErrorDesc *pErrorDesc ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::ShowError" ); DBG_ASSERT(GetDoc(), "Sm : Document missing"); if (pErrorDesc || 0 != (pErrorDesc = GetDoc()->GetParser().GetError(0)) ) { SetStatusText( pErrorDesc->Text ); GetEditWindow()->MarkError( Point( pErrorDesc->pNode->GetColumn(), pErrorDesc->pNode->GetRow())); } } void SmViewShell::NextError() { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::NextError" ); DBG_ASSERT(GetDoc(), "Sm : Document missing"); const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().NextError(); if (pErrorDesc) ShowError( pErrorDesc ); } void SmViewShell::PrevError() { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::PrevError" ); DBG_ASSERT(GetDoc(), "Sm : Document missing"); const SmErrorDesc *pErrorDesc = GetDoc()->GetParser().PrevError(); if (pErrorDesc) ShowError( pErrorDesc ); } sal_Bool SmViewShell::Insert( SfxMedium& rMedium ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Insert" ); SmDocShell *pDoc = GetDoc(); String aText( pDoc->GetText() ); String aTemp = aText; sal_Bool bRet = sal_False, bChkOldVersion = sal_True; uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage(); uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY ); if ( xNameAccess.is() && xNameAccess->getElementNames().getLength() ) { if ( xNameAccess->hasByName( C2S( "content.xml" ) ) || xNameAccess->hasByName( C2S( "Content.xml" ) )) { bChkOldVersion = sal_False; // is this a fabulous math package ? Reference xModel(pDoc->GetModel()); SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! bRet = 0 == aEquation.Import(rMedium); } } if( bRet ) { aText = pDoc->GetText(); SmEditWindow *pEditWin = GetEditWindow(); if (pEditWin) pEditWin->InsertText( aText ); else { DBG_ERROR( "EditWindow missing" ); aTemp += aText; aText = aTemp; } pDoc->Parse(); pDoc->SetModified(sal_True); SfxBindings &rBnd = GetViewFrame()->GetBindings(); rBnd.Invalidate(SID_GAPHIC_SM); rBnd.Invalidate(SID_TEXT); } return bRet; } sal_Bool SmViewShell::InsertFrom(SfxMedium &rMedium) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InsertFrom" ); sal_Bool bSuccess = sal_False; SmDocShell *pDoc = GetDoc(); SvStream *pStream = rMedium.GetInStream(); String aText( pDoc->GetText() ); String aTemp = aText; if (pStream) { const String& rFltName = rMedium.GetFilter()->GetFilterName(); if ( rFltName.EqualsAscii(MATHML_XML) ) { Reference xModel( pDoc->GetModel() ); SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !! bSuccess = 0 == aEquation.Import(rMedium); } else { //bSuccess = ImportSM20File( pStream ); } } if( bSuccess ) { aText = pDoc->GetText(); SmEditWindow *pEditWin = GetEditWindow(); if (pEditWin) pEditWin->InsertText( aText ); else { DBG_ERROR( "EditWindow missing" ); aTemp += aText; aText = aTemp; } pDoc->Parse(); pDoc->SetModified(sal_True); SfxBindings &rBnd = GetViewFrame()->GetBindings(); rBnd.Invalidate(SID_GAPHIC_SM); rBnd.Invalidate(SID_TEXT); } return bSuccess; } void SmViewShell::Execute(SfxRequest& rReq) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Execute" ); SmEditWindow *pWin = GetEditWindow(); switch (rReq.GetSlot()) { case SID_FORMULACURSOR: { SmModule *pp = SM_MOD(); const SfxItemSet *pArgs = rReq.GetArgs(); const SfxPoolItem *pItem; sal_Bool bVal; if ( pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_FORMULACURSOR, sal_False, &pItem)) bVal = ((SfxBoolItem *) pItem)->GetValue(); else bVal = !pp->GetConfig()->IsShowFormulaCursor(); pp->GetConfig()->SetShowFormulaCursor(bVal); GetGraphicWindow().ShowCursor(bVal); break; } case SID_DRAW: if (pWin) { GetDoc()->SetText( pWin->GetText() ); SetStatusText(String()); ShowError( 0 ); GetDoc()->Repaint(); } break; case SID_ADJUST: case SID_FITINWINDOW: aGraphic.ZoomToFitInWindow(); break; case SID_VIEW050: aGraphic.SetZoom(50); break; case SID_VIEW100: aGraphic.SetZoom(100); break; case SID_VIEW200: aGraphic.SetZoom(200); break; case SID_ZOOMIN: aGraphic.SetZoom(aGraphic.GetZoom() + 25); break; case SID_ZOOMOUT: DBG_ASSERT(aGraphic.GetZoom() >= 25, "Sm: falsches sal_uInt16 Argument"); aGraphic.SetZoom(aGraphic.GetZoom() - 25); break; case SID_COPYOBJECT: { //TODO/LATER: does not work because of UNO Tunneling - will be fixed later Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY ); if( xTrans.is() ) { Reference< lang::XUnoTunnel> xTnnl( xTrans, uno::UNO_QUERY); if( xTnnl.is() ) { TransferableHelper* pTrans = reinterpret_cast< TransferableHelper * >( sal::static_int_cast< sal_uIntPtr >( xTnnl->getSomething( TransferableHelper::getUnoTunnelId() ))); if( pTrans ) pTrans->CopyToClipboard( this ? GetEditWindow() : 0 ); } } } break; case SID_PASTEOBJECT: { TransferableDataHelper aData( TransferableDataHelper::CreateFromSystemClipboard(this ? GetEditWindow(): 0) ); uno::Reference < io::XInputStream > xStrm; SotFormatStringId nId; if( aData.GetTransferable().is() && ( aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBEDDED_OBJ ) || (aData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) && aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBED_SOURCE ))) && aData.GetInputStream( nId, xStrm ) && xStrm.is() ) { try { uno::Reference < embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessServiceFactory() ); uno::Reference < beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY ); SfxMedium aMedium( xStorage, String() ); Insert( aMedium ); GetDoc()->UpdateText(); } catch (uno::Exception &) { DBG_ERROR( "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" ); } } } break; case SID_CUT: if (pWin) pWin->Cut(); break; case SID_COPY: if (pWin) { if (pWin->IsAllSelected()) { GetViewFrame()->GetDispatcher()->Execute( SID_COPYOBJECT, SFX_CALLMODE_STANDARD, new SfxVoidItem(SID_COPYOBJECT), 0L); } else pWin->Copy(); } break; case SID_PASTE: { sal_Bool bCallExec = 0 == pWin; if( !bCallExec ) { TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( GetEditWindow()) ); if( aDataHelper.GetTransferable().is() && aDataHelper.HasFormat( FORMAT_STRING )) pWin->Paste(); else bCallExec = sal_True; } if( bCallExec ) { GetViewFrame()->GetDispatcher()->Execute( SID_PASTEOBJECT, SFX_CALLMODE_STANDARD, new SfxVoidItem(SID_PASTEOBJECT), 0L); } } break; case SID_DELETE: if (pWin) pWin->Delete(); break; case SID_SELECT: if (pWin) pWin->SelectAll(); break; case SID_INSERTCOMMAND: { const SfxInt16Item& rItem = (const SfxInt16Item&)rReq.GetArgs()->Get(SID_INSERTCOMMAND); if (pWin) pWin->InsertCommand(rItem.GetValue()); break; } case SID_INSERTTEXT: { const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_INSERTTEXT); if (pWin) pWin->InsertText(rItem.GetValue()); break; } case SID_IMPORT_FORMULA: { delete pImpl->pRequest; pImpl->pRequest = new SfxRequest( rReq ); delete pImpl->pDocInserter; pImpl->pDocInserter = new ::sfx2::DocumentInserter( 0, GetDoc()->GetFactory().GetFactoryName(), 0 ); pImpl->pDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl ) ); break; } case SID_IMPORT_MATHML_CLIPBOARD: { TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) ); uno::Reference < io::XInputStream > xStrm; SotFormatStringId nId = SOT_FORMAT_SYSTEM_START; // dummy initialize to avoid warning if ( aDataHelper.GetTransferable().is() ) { if ( aDataHelper.HasFormat( nId = SOT_FORMATSTR_ID_MATHML ) ) { if ( aDataHelper.GetInputStream( nId, xStrm ) && xStrm.is() ) { SfxMedium* pClipboardMedium = new SfxMedium(); pClipboardMedium->GetItemSet(); // generate initial itemset, not sure if necessary const SfxFilter* pMathFilter = SfxFilter::GetFilterByName( String::CreateFromAscii(MATHML_XML) ); pClipboardMedium->SetFilter(pMathFilter); pClipboardMedium->setStreamToLoadFrom( xStrm, sal_True /*bIsReadOnly*/ ); InsertFrom(*pClipboardMedium); GetDoc()->UpdateText(); delete pClipboardMedium; } } else { if ( aDataHelper.HasFormat( nId = FORMAT_STRING) ) { // In case of FORMAT_STRING no stream exists, need to generate one ::rtl::OUString aString; if (aDataHelper.GetString( nId, aString)) { SfxMedium* pClipboardMedium = new SfxMedium(); pClipboardMedium->GetItemSet(); //generates initial itemset, not sure if necessary const SfxFilter* pMathFilter = SfxFilter::GetFilterByName( String::CreateFromAscii(MATHML_XML) ); pClipboardMedium->SetFilter(pMathFilter); SvMemoryStream * pStrm; // The text to be imported might assert encoding like 'encoding="utf-8"' but FORMAT_STRING is UTF-16. // Force encoding to UTF-16, if encoding exists. bool bForceUTF16 = false; sal_Int32 nPosL = aString.indexOf( OUString::createFromAscii("encoding=\"")); sal_Int32 nPosU = -1; if ( nPosL >= 0 && nPosL +10 < aString.getLength() ) { nPosL += 10; nPosU = aString.indexOf( '"',nPosL); if (nPosU > nPosL) { bForceUTF16 = true; } } if ( bForceUTF16 ) { OUString aNewString = aString.replaceAt( nPosL,nPosU-nPosL,OUString::createFromAscii("UTF-16")); pStrm = new SvMemoryStream( (void*)aNewString.getStr(), aNewString.getLength() * sizeof(sal_Unicode), STREAM_READ); } else { pStrm = new SvMemoryStream( (void*)aString.getStr(), aString.getLength() * sizeof(sal_Unicode), STREAM_READ); } com::sun::star::uno::Reference xStrm( new ::utl::OInputStreamWrapper( *pStrm ) ); pClipboardMedium->setStreamToLoadFrom( xStrm, sal_True /*bIsReadOnly*/ ); InsertFrom(*pClipboardMedium); GetDoc()->UpdateText(); delete pClipboardMedium; delete pStrm; } } } } break; } case SID_NEXTERR: NextError(); if (pWin) pWin->GrabFocus(); break; case SID_PREVERR: PrevError(); if (pWin) pWin->GrabFocus(); break; case SID_NEXTMARK: if (pWin) { pWin->SelNextMark(); pWin->GrabFocus(); } break; case SID_PREVMARK: if (pWin) { pWin->SelPrevMark(); pWin->GrabFocus(); } break; case SID_TEXTSTATUS: { if (rReq.GetArgs() != NULL) { const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXTSTATUS); SetStatusText(rItem.GetValue()); } break; } case SID_GETEDITTEXT: if (pWin) if (pWin->GetText ().Len ()) GetDoc()->SetText( pWin->GetText() ); break; case SID_ATTR_ZOOM: { if ( !GetViewFrame()->GetFrame().IsInPlace() ) { //CHINA001 SvxZoomDialog *pDlg = 0; AbstractSvxZoomDialog *pDlg = 0; const SfxItemSet *pSet = rReq.GetArgs(); if ( !pSet ) { SfxItemSet aSet( GetDoc()->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM); aSet.Put( SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom())); //CHINA001 pDlg = new SvxZoomDialog( &GetViewFrame()->GetWindow(), aSet); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); if(pFact) { pDlg = pFact->CreateSvxZoomDialog(&GetViewFrame()->GetWindow(), aSet); DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001 } pDlg->SetLimits( MINZOOM, MAXZOOM ); if( pDlg->Execute() != RET_CANCEL ) pSet = pDlg->GetOutputItemSet(); } if ( pSet ) { const SvxZoomItem &rZoom = (const SvxZoomItem &)pSet->Get(SID_ATTR_ZOOM); switch( rZoom.GetType() ) { case SVX_ZOOM_PERCENT: aGraphic.SetZoom((sal_uInt16)rZoom.GetValue ()); break; case SVX_ZOOM_OPTIMAL: aGraphic.ZoomToFitInWindow(); break; case SVX_ZOOM_PAGEWIDTH: case SVX_ZOOM_WHOLEPAGE: { const MapMode aMap( MAP_100TH_MM ); SfxPrinter *pPrinter = GetPrinter( sal_True ); Point aPoint; Rectangle OutputRect(aPoint, pPrinter->GetOutputSize()); Size OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(), OutputRect.GetHeight()), aMap)); Size GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap)); sal_uInt16 nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width() * 100L, GraphicSize.Width()), (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height())); aGraphic.SetZoom (nZ); break; } default: break; } } delete pDlg; } } break; case SID_TOOLBOX: { GetViewFrame()->ToggleChildWindow( SmToolBoxWrapper::GetChildWindowId() ); } break; case SID_SYMBOLS_CATALOGUE: { // get device used to retrieve the FontList SmDocShell *pDoc = GetDoc(); OutputDevice *pDev = pDoc->GetPrinter(); if (!pDev || pDev->GetDevFontCount() == 0) pDev = &SM_MOD()->GetDefaultVirtualDev(); DBG_ASSERT (pDev, "device for font list missing" ); SmModule *pp = SM_MOD(); SmSymbolDialog( NULL, pDev, pp->GetSymbolManager(), *this ).Execute(); } break; } rReq.Done(); } void SmViewShell::GetState(SfxItemSet &rSet) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetState" ); SfxWhichIter aIter(rSet); SmEditWindow *pEditWin = GetEditWindow(); for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich()) { switch (nWh) { case SID_CUT: case SID_COPY: case SID_DELETE: if (! pEditWin || ! pEditWin->IsSelected()) rSet.DisableItem(nWh); break; case SID_PASTE: if( !xClipEvtLstnr.is() && pEditWin) { TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pEditWin) ); bPasteState = aDataHelper.GetTransferable().is() && ( aDataHelper.HasFormat( FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ ) || (aDataHelper.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))); } if( !bPasteState ) rSet.DisableItem( nWh ); break; case SID_ATTR_ZOOM: rSet.Put(SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom())); /* no break here */ case SID_VIEW050: case SID_VIEW100: case SID_VIEW200: case SID_ADJUST: case SID_ZOOMIN: case SID_ZOOMOUT: case SID_FITINWINDOW: if ( GetViewFrame()->GetFrame().IsInPlace() ) rSet.DisableItem( nWh ); break; case SID_NEXTERR: case SID_PREVERR: case SID_NEXTMARK: case SID_PREVMARK: case SID_DRAW: case SID_SELECT: if (! pEditWin || pEditWin->IsEmpty()) rSet.DisableItem(nWh); break; case SID_TEXTSTATUS: { rSet.Put(SfxStringItem(nWh, StatusText)); } break; case SID_FORMULACURSOR: { SmModule *pp = SM_MOD(); rSet.Put(SfxBoolItem(nWh, pp->GetConfig()->IsShowFormulaCursor())); } break; case SID_TOOLBOX: { sal_Bool bState = sal_False; SfxChildWindow *pChildWnd = GetViewFrame()-> GetChildWindow( SmToolBoxWrapper::GetChildWindowId() ); if (pChildWnd && pChildWnd->GetWindow()->IsVisible()) bState = sal_True; rSet.Put(SfxBoolItem(SID_TOOLBOX, bState)); } break; } } } SmViewShell::SmViewShell(SfxViewFrame *pFrame_, SfxViewShell *): SfxViewShell(pFrame_, SFX_VIEW_HAS_PRINTOPTIONS | SFX_VIEW_CAN_PRINT), aGraphic(this), aGraphicController(aGraphic, SID_GAPHIC_SM, pFrame_->GetBindings()), pImpl( new SmViewShell_Impl ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SmViewShell" ); // pViewFrame = &pFrame_->GetWindow(); SetStatusText(String()); SetWindow(&aGraphic); SfxShell::SetName(C2S("SmView")); SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() ); SetHelpId( HID_SMA_VIEWSHELL_DOCUMENT ); } SmViewShell::~SmViewShell() { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::~SmViewShell" ); //!! this view shell is not active anymore !! // Thus 'SmGetActiveView' will give a 0 pointer. // Thus we need to supply this view as argument SmEditWindow *pEditWin = GetEditWindow(); if (pEditWin) pEditWin->DeleteEditView( *this ); delete pImpl; } void SmViewShell::Deactivate( sal_Bool bIsMDIActivate ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Deactivate" ); SmEditWindow *pEdit = GetEditWindow(); if ( pEdit ) pEdit->Flush(); SfxViewShell::Deactivate( bIsMDIActivate ); } void SmViewShell::Activate( sal_Bool bIsMDIActivate ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Activate" ); SfxViewShell::Activate( bIsMDIActivate ); SmEditWindow *pEdit = GetEditWindow(); if ( pEdit ) { //! Since there is no way to be informed if a "drag and drop" //! event has taken place, we call SetText here in order to //! synchronize the GraphicWindow display with the text in the //! EditEngine. SmDocShell *pDoc = GetDoc(); pDoc->SetText( pDoc->GetEditEngine().GetText( LINEEND_LF ) ); if ( bIsMDIActivate ) pEdit->GrabFocus(); } } //------------------------------------------------------------------ IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg ) { DBG_ASSERT( _pFileDlg, "SmViewShell::DialogClosedHdl(): no file dialog" ); DBG_ASSERT( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" ); if ( ERRCODE_NONE == _pFileDlg->GetError() ) { //sal_uInt16 nSlot = pImpl->pRequest->GetSlot(); SfxMedium* pMedium = pImpl->pDocInserter->CreateMedium(); if ( pMedium != NULL ) { if ( pMedium->IsStorage() ) Insert( *pMedium ); else InsertFrom( *pMedium ); delete pMedium; SmDocShell* pDoc = GetDoc(); pDoc->UpdateText(); pDoc->ArrangeFormula(); pDoc->Repaint(); // adjust window, repaint, increment ModifyCount,... GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM); } } pImpl->pRequest->SetReturnValue( SfxBoolItem( pImpl->pRequest->GetSlot(), sal_True ) ); pImpl->pRequest->Done(); return 0; } void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint ) { if ( rHint.IsA(TYPE(SfxSimpleHint)) ) { switch( ( (SfxSimpleHint&) rHint ).GetId() ) { case SFX_HINT_MODECHANGED: case SFX_HINT_DOCCHANGED: GetViewFrame()->GetBindings().InvalidateAll(sal_False); break; default: break; } } }