xref: /trunk/main/starmath/source/view.cxx (revision ffd38472365e95f6a578737bc9a5eb0fac624a86)
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/accessibility/AccessibleEventObject.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/XAccessible.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/frame/XDesktop.hpp>
31 #include <com/sun/star/frame/XFramesSupplier.hpp>
32 #include <com/sun/star/container/XChild.hpp>
33 
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/storagehelper.hxx>
36 #include <rtl/logfile.hxx>
37 #include <sfx2/app.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <sfx2/docfilt.hxx>
41 #include <sfx2/docinsert.hxx>
42 #include <sfx2/filedlghelper.hxx>
43 #include <sfx2/msg.hxx>
44 #include <sfx2/objface.hxx>
45 #include <sfx2/printer.hxx>
46 #include <sfx2/request.hxx>
47 #include <svl/eitem.hxx>
48 #include <svl/intitem.hxx>
49 #include <svl/itemset.hxx>
50 #include <svl/poolitem.hxx>
51 #include <svl/ptitem.hxx>
52 #include <svl/stritem.hxx>
53 #include <svtools/transfer.hxx>
54 #include <svl/undo.hxx>
55 #include <svl/whiter.hxx>
56 #include <svx/dialogs.hrc>
57 #include <editeng/editeng.hxx>
58 #include <svx/svxdlg.hxx>
59 #include <svx/zoomitem.hxx>
60 #include <vcl/decoview.hxx>
61 #include <vcl/menu.hxx>
62 #include <vcl/msgbox.hxx>
63 #include <vcl/wrkwin.hxx>
64 #include <unotools/streamwrap.hxx>
65 
66 #include "unomodel.hxx"
67 #include "view.hxx"
68 #include "config.hxx"
69 #include "dialog.hxx"
70 #include "document.hxx"
71 #include "starmath.hrc"
72 #include "toolbox.hxx"
73 #include "mathmlimport.hxx"
74 
75 #define MINWIDTH        200
76 #define MINHEIGHT       200
77 #define MINSPLIT        40
78 #define SPLITTERWIDTH   2
79 
80 #define MINZOOM 25
81 #define MAXZOOM 800
82 
83 #define SmViewShell
84 #include "smslots.hxx"
85 
86 using namespace com::sun::star;
87 using namespace com::sun::star::accessibility;
88 using namespace com::sun::star::uno;
89 
90 using ::rtl::OUString;
91 
92 //////////////////////////////////////////////////////////////////////
93 
94 SmGraphicWindow::SmGraphicWindow(SmViewShell* pShell):
95     ScrollableWindow(&pShell->GetViewFrame()->GetWindow(), 0),
96     pAccessible(0),
97     pViewShell(pShell),
98     nZoom(100),
99     bIsCursorVisible(sal_False)
100 {
101     // docking windows are usually hidden (often already done in the
102     // resource) and will be shown by the sfx framework.
103     Hide();
104 
105     const Fraction aFraction (1,1);
106     SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction));
107 
108     ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
109 
110     SetTotalSize();
111 
112     SetHelpId(HID_SMA_WIN_DOCUMENT);
113     SetUniqueId(HID_SMA_WIN_DOCUMENT);
114 }
115 
116 SmGraphicWindow::~SmGraphicWindow()
117 {
118     if (pAccessible)
119         pAccessible->ClearWin(); // make Accessible dysfunctional
120     // Note: memory for pAccessible will be freed when the reference
121     // xAccessible is released.
122 }
123 
124 void SmGraphicWindow::StateChanged( StateChangedType eType )
125 {
126     if ( eType == STATE_CHANGE_INITSHOW )
127         Show();
128     ScrollableWindow::StateChanged( eType );
129 }
130 
131 
132 void SmGraphicWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg )
133 {
134     // Note: SetTextColor not necessary since the nodes that
135     // get painted have the color information.
136 #if OSL_DEBUG_LEVEL > 1
137 //  ColorData nVal = rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor;
138 #endif
139     SetBackground( Color( (ColorData) rColorCfg.GetColorValue(svtools::DOCCOLOR).nColor ) );
140     Invalidate();
141 }
142 
143 
144 void SmGraphicWindow::DataChanged( const DataChangedEvent& rEvt )
145 {
146     ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
147 
148     ScrollableWindow::DataChanged( rEvt );
149 }
150 
151 
152 void SmGraphicWindow::MouseButtonDown(const MouseEvent& rMEvt)
153 {
154     ScrollableWindow::MouseButtonDown(rMEvt);
155 
156     //
157     // set formula-cursor and selection of edit window according to the
158     // position clicked at
159     //
160     DBG_ASSERT(rMEvt.GetClicks() > 0, "Sm : 0 clicks");
161     if ( rMEvt.IsLeft() && pViewShell->GetEditWindow() )
162     {
163         const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
164         //! kann NULL sein! Z.B. wenn bereits beim laden des Dokuments (bevor der
165         //! Parser angeworfen wurde) ins Fenster geklickt wird.
166         if (!pTree)
167             return;
168 
169         // get click position relativ to formula
170         Point aPos (PixelToLogic(rMEvt.GetPosPixel())
171                     - GetFormulaDrawPos());
172 
173         // if it was clicked inside the formula then get the appropriate node
174         const SmNode *pNode = 0;
175         if (pTree->OrientedDist(aPos) <= 0)
176             pNode = pTree->FindRectClosestTo(aPos);
177 
178         if (pNode)
179         {   SmEditWindow *pEdit = pViewShell->GetEditWindow();
180             const SmToken aToken (pNode->GetToken());
181 
182 #ifdef notnow
183             // include introducing symbols of special char and text
184             // (i.e. '%' and '"')
185             sal_uInt16 nExtra = (aToken.eType == TSPECIAL || aToken.eType == TTEXT) ? 1 : 0;
186 
187             // set selection to the beginning of the token
188             ESelection aSel (aToken.nRow - 1, aToken.nCol - 1 - nExtra);
189 
190             if (rMEvt.GetClicks() != 1)
191             {   // select whole token
192                 // for text include terminating symbol (i.e. '"')
193                 aSel.nEndPos += aToken.aText.Len() + nExtra
194                                 + (aToken.eType == TTEXT ? 1 : 0);
195             }
196 #endif
197             // set selection to the beginning of the token
198             ESelection aSel (aToken.nRow - 1, aToken.nCol - 1);
199 
200             if (rMEvt.GetClicks() != 1 || aToken.eType == TPLACE)
201                 aSel.nEndPos = aSel.nEndPos + sal::static_int_cast< sal_uInt16 >(aToken.aText.Len());
202 
203             pEdit->SetSelection(aSel);
204             SetCursor(pNode);
205 
206             // allow for immediate editing and
207             //! implicitly synchronize the cursor position mark in this window
208             pEdit->GrabFocus();
209         }
210     }
211 }
212 
213 void SmGraphicWindow::GetFocus()
214 {
215 /*
216     if (xAccessible.is())
217     {
218         uno::Any aOldValue, aNewValue;
219         // aOldValue remains empty
220         aNewValue <<= AccessibleStateType::FOCUSED;
221         pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED,
222                 aOldValue, aNewValue );
223     }
224 */
225 }
226 
227 void SmGraphicWindow::LoseFocus()
228 {
229     ScrollableWindow::LoseFocus();
230     if (xAccessible.is())
231     {
232         uno::Any aOldValue, aNewValue;
233         aOldValue <<= AccessibleStateType::FOCUSED;
234         // aNewValue remains empty
235         pAccessible->LaunchEvent( AccessibleEventId::STATE_CHANGED,
236                 aOldValue, aNewValue );
237     }
238 }
239 
240 void SmGraphicWindow::ShowCursor(sal_Bool bShow)
241     // shows or hides the formula-cursor depending on 'bShow' is sal_True or not
242 {
243     sal_Bool bInvert = bShow != IsCursorVisible();
244 
245     if (bInvert)
246         InvertTracking(aCursorRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW);
247 
248     SetIsCursorVisible(bShow);
249 }
250 
251 
252 void SmGraphicWindow::SetCursor(const SmNode *pNode)
253 {
254     const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree();
255 
256     // get appropriate rectangle
257     Point aOffset (pNode->GetTopLeft() - pTree->GetTopLeft()),
258           aTLPos  (GetFormulaDrawPos() + aOffset);
259     aTLPos.X() -= pNode->GetItalicLeftSpace();
260     Size  aSize   (pNode->GetItalicSize());
261     Point aBRPos  (aTLPos.X() + aSize.Width(), aTLPos.Y() + aSize.Height());
262 
263     SetCursor(Rectangle(aTLPos, aSize));
264 }
265 
266 void SmGraphicWindow::SetCursor(const Rectangle &rRect)
267     // sets cursor to new position (rectangle) 'rRect'.
268     // The old cursor will be removed, and the new one will be shown if
269     // that is activated in the ConfigItem
270 {
271     SmModule *pp = SM_MOD();
272 
273     if (IsCursorVisible())
274         ShowCursor(sal_False);      // clean up remains of old cursor
275     aCursorRect = rRect;
276     if (pp->GetConfig()->IsShowFormulaCursor())
277         ShowCursor(sal_True);       // draw new cursor
278 }
279 
280 const SmNode * SmGraphicWindow::SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol)
281     // looks for a VISIBLE node in the formula tree with its token at
282     // (or around) the position 'nRow', 'nCol' in the edit window
283     // (row and column numbering starts with 1 there!).
284     // If there is such a node the formula-cursor is set to cover that nodes
285     // rectangle. If not the formula-cursor will be hidden.
286     // In any case the search result is being returned.
287 {
288     // find visible node with token at nRow, nCol
289     const SmNode *pTree = pViewShell->GetDoc()->GetFormulaTree(),
290                  *pNode = 0;
291     if (pTree)
292         pNode = pTree->FindTokenAt(nRow, nCol);
293 
294     if (pNode)
295         SetCursor(pNode);
296     else
297         ShowCursor(sal_False);
298 
299     return pNode;
300 }
301 
302 
303 void SmGraphicWindow::Paint(const Rectangle&)
304 {
305     DBG_ASSERT(pViewShell, "Sm : NULL pointer");
306 
307     SmDocShell &rDoc = *pViewShell->GetDoc();
308     Point aPoint;
309 
310     rDoc.Draw(*this, aPoint);   //! modifies aPoint to be the topleft
311                                 //! corner of the formula
312     SetFormulaDrawPos(aPoint);
313 
314     SetIsCursorVisible(sal_False);  // (old) cursor must be drawn again
315 
316     const SmEditWindow *pEdit = pViewShell->GetEditWindow();
317     if (pEdit)
318     {   // get new position for formula-cursor (for possible altered formula)
319         sal_uInt16  nRow, nCol;
320         SmGetLeftSelectionPart(pEdit->GetSelection(), nRow, nCol);
321         nRow++;
322         nCol++;
323         const SmNode *pFound = SetCursorPos(nRow, nCol);
324 
325         SmModule *pp = SM_MOD();
326         if (pFound && pp->GetConfig()->IsShowFormulaCursor())
327             ShowCursor(sal_True);
328     }
329 }
330 
331 
332 void SmGraphicWindow::SetTotalSize ()
333 {
334     SmDocShell &rDoc = *pViewShell->GetDoc();
335     const Size aTmp( PixelToLogic( LogicToPixel( rDoc.GetSize() )));
336     if ( aTmp != ScrollableWindow::GetTotalSize() )
337         ScrollableWindow::SetTotalSize( aTmp );
338 }
339 
340 
341 void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt)
342 {
343     if (! (GetView() && GetView()->KeyInput(rKEvt)) )
344         ScrollableWindow::KeyInput(rKEvt);
345 }
346 
347 
348 void SmGraphicWindow::Command(const CommandEvent& rCEvt)
349 {
350     sal_Bool bCallBase = sal_True;
351     if ( !pViewShell->GetViewFrame()->GetFrame().IsInPlace() )
352     {
353         switch ( rCEvt.GetCommand() )
354         {
355             case COMMAND_CONTEXTMENU:
356             {
357                 GetParent()->ToTop();
358                 SmResId aResId( RID_VIEWMENU );
359                 PopupMenu* pPopupMenu = new PopupMenu(aResId);
360                 pPopupMenu->SetSelectHdl(LINK(this, SmGraphicWindow, MenuSelectHdl));
361                 Point aPos(5, 5);
362                 if (rCEvt.IsMouseEvent())
363                     aPos = rCEvt.GetMousePosPixel();
364                 DBG_ASSERT( pViewShell, "view shell missing" );
365 
366                 // added for replaceability of context menus #96085, #93782
367                 pViewShell->GetViewFrame()->GetBindings().GetDispatcher()
368                         ->ExecutePopup( aResId, this, &aPos );
369                 //pPopupMenu->Execute( this, aPos );
370 
371                 delete pPopupMenu;
372                 bCallBase = sal_False;
373             }
374             break;
375 
376             case COMMAND_WHEEL:
377             {
378                 const CommandWheelData* pWData = rCEvt.GetWheelData();
379                 if ( pWData && COMMAND_WHEEL_ZOOM == pWData->GetMode() )
380                 {
381                     sal_uInt16 nTmpZoom = GetZoom();
382                     if( 0L > pWData->GetDelta() )
383                         nTmpZoom -= 10;
384                     else
385                         nTmpZoom += 10;
386                     SetZoom( nTmpZoom );
387                     bCallBase = sal_False;
388                 }
389             }
390             break;
391         }
392     }
393     if ( bCallBase )
394         ScrollableWindow::Command (rCEvt);
395 }
396 
397 
398 IMPL_LINK_INLINE_START( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu )
399 {
400     SmViewShell *pViewSh = GetView();
401     if (pViewSh)
402         pViewSh->GetViewFrame()->GetDispatcher()->Execute( pMenu->GetCurItemId() );
403     return 0;
404 }
405 IMPL_LINK_INLINE_END( SmGraphicWindow, MenuSelectHdl, Menu *, pMenu )
406 
407 
408 void SmGraphicWindow::SetZoom(sal_uInt16 Factor)
409 {
410     nZoom = Min(Max((sal_uInt16) Factor, (sal_uInt16) MINZOOM), (sal_uInt16) MAXZOOM);
411     Fraction   aFraction (nZoom, 100);
412     SetMapMode( MapMode(MAP_100TH_MM, Point(), aFraction, aFraction) );
413     SetTotalSize();
414     SmViewShell *pViewSh = GetView();
415     if (pViewSh)
416         pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM);
417     Invalidate();
418 }
419 
420 
421 void SmGraphicWindow::ZoomToFitInWindow()
422 {
423     SmDocShell &rDoc = *pViewShell->GetDoc();
424 
425     // set defined mapmode before calling 'LogicToPixel' below
426     SetMapMode(MapMode(MAP_100TH_MM));
427 
428     Size       aSize (LogicToPixel(rDoc.GetSize()));
429     Size       aWindowSize (GetSizePixel());
430 
431     if (aSize.Width() > 0 && aSize.Height() > 0)
432     {
433         long nVal = Min ((85 * aWindowSize.Width()) / aSize.Width(),
434                          (85 * aWindowSize.Height()) / aSize.Height());
435         SetZoom ( sal::static_int_cast< sal_uInt16 >(nVal) );
436     }
437 }
438 
439 uno::Reference< XAccessible > SmGraphicWindow::CreateAccessible()
440 {
441     if (!pAccessible)
442     {
443         pAccessible = new SmGraphicAccessible( this );
444         xAccessible = pAccessible;
445     }
446     return xAccessible;
447 }
448 
449 /**************************************************************************/
450 
451 
452 SmGraphicController::SmGraphicController(SmGraphicWindow &rSmGraphic,
453                         sal_uInt16          nId_,
454                         SfxBindings     &rBindings) :
455     SfxControllerItem(nId_, rBindings),
456     rGraphic(rSmGraphic)
457 {
458 }
459 
460 
461 void SmGraphicController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
462 {
463     rGraphic.SetTotalSize();
464     rGraphic.Invalidate();
465     SfxControllerItem::StateChanged (nSID, eState, pState);
466 }
467 
468 
469 /**************************************************************************/
470 
471 
472 SmEditController::SmEditController(SmEditWindow &rSmEdit,
473                      sal_uInt16       nId_,
474                      SfxBindings  &rBindings) :
475     SfxControllerItem(nId_, rBindings),
476     rEdit(rSmEdit)
477 {
478 }
479 
480 
481 #if OSL_DEBUG_LEVEL > 1
482 SmEditController::~SmEditController()
483 {
484 }
485 #endif
486 
487 
488 void SmEditController::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
489 {
490     const SfxStringItem *pItem = PTR_CAST(SfxStringItem, pState);
491 
492     if ((pItem != NULL) && (rEdit.GetText() != pItem->GetValue()))
493         rEdit.SetText(pItem->GetValue());
494     SfxControllerItem::StateChanged (nSID, eState, pState);
495 }
496 
497 
498 /**************************************************************************/
499 
500 SmCmdBoxWindow::SmCmdBoxWindow(SfxBindings *pBindings_, SfxChildWindow *pChildWindow,
501                                Window *pParent) :
502     SfxDockingWindow(pBindings_, pChildWindow, pParent, SmResId(RID_CMDBOXWINDOW)),
503     aEdit       (*this),
504     aController (aEdit, SID_TEXT, *pBindings_),
505     bExiting    (sal_False)
506 {
507     Hide ();
508 
509     aInitialFocusTimer.SetTimeoutHdl(LINK(this, SmCmdBoxWindow, InitialFocusTimerHdl));
510     aInitialFocusTimer.SetTimeout(100);
511 }
512 
513 
514 SmCmdBoxWindow::~SmCmdBoxWindow ()
515 {
516     aInitialFocusTimer.Stop();
517     bExiting = sal_True;
518 }
519 
520 
521 SmViewShell * SmCmdBoxWindow::GetView()
522 {
523     SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
524     return PTR_CAST(SmViewShell, pView);
525 }
526 
527 void SmCmdBoxWindow::Resize()
528 {
529     Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel());
530 
531     if (! IsFloatingMode())
532     {
533         switch (GetAlignment())
534         {
535             case SFX_ALIGN_TOP:     aRect.Bottom()--;   break;
536             case SFX_ALIGN_BOTTOM:  aRect.Top()++;      break;
537             case SFX_ALIGN_LEFT:    aRect.Right()--;    break;
538             case SFX_ALIGN_RIGHT:   aRect.Left()++;     break;
539             default:
540                 break;
541         }
542     }
543 
544     DecorationView aView(this);
545     aRect.Left() += 6; aRect.Top()   += 6;
546     aRect.Right()-= 6; aRect.Bottom()-= 6;
547     aRect = aView.DrawFrame( aRect, FRAME_DRAW_IN );
548 
549     aEdit.SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
550     SfxDockingWindow::Resize();
551     Invalidate();
552 }
553 
554 
555 void SmCmdBoxWindow::Paint(const Rectangle& /*rRect*/)
556 {
557     Rectangle aRect = Rectangle(Point(0, 0), GetOutputSizePixel());
558     DecorationView aView(this);
559 
560     if (! IsFloatingMode())
561     {
562         Point aFrom, aTo;
563         switch (GetAlignment())
564         {
565             case SFX_ALIGN_TOP:
566                 aFrom = aRect.BottomLeft(); aTo = aRect.BottomRight();
567                 aRect.Bottom()--;
568                 break;
569 
570             case SFX_ALIGN_BOTTOM:
571                 aFrom = aRect.TopLeft(); aTo = aRect.TopRight();
572                 aRect.Top()++;
573                 break;
574 
575             case SFX_ALIGN_LEFT:
576                 aFrom = aRect.TopRight(); aTo = aRect.BottomRight();
577                 aRect.Right()--;
578                 break;
579 
580             case SFX_ALIGN_RIGHT:
581                 aFrom = aRect.TopLeft(); aTo = aRect.BottomLeft();
582                 aRect.Left()++;
583                 break;
584 
585             default:
586                 break;
587         }
588         DrawLine( aFrom, aTo );
589         aView.DrawFrame(aRect, FRAME_DRAW_OUT);
590     }
591     aRect.Left() += 6; aRect.Top()   += 6;
592     aRect.Right()-= 6; aRect.Bottom()-= 6;
593     aRect = aView.DrawFrame( aRect, FRAME_DRAW_IN );
594 }
595 
596 
597 Size SmCmdBoxWindow::CalcDockingSize(SfxChildAlignment eAlign)
598 {
599     switch (eAlign)
600     {
601         case SFX_ALIGN_LEFT:
602         case SFX_ALIGN_RIGHT:
603             return Size();
604         default:
605             break;
606     }
607     return SfxDockingWindow::CalcDockingSize(eAlign);
608 }
609 
610 
611 SfxChildAlignment SmCmdBoxWindow::CheckAlignment(SfxChildAlignment eActual,
612                                              SfxChildAlignment eWish)
613 {
614     switch (eWish)
615     {
616         case SFX_ALIGN_TOP:
617         case SFX_ALIGN_BOTTOM:
618         case SFX_ALIGN_NOALIGNMENT:
619             return eWish;
620         default:
621             break;
622     }
623 
624     return eActual;
625 }
626 
627 
628 void SmCmdBoxWindow::StateChanged( StateChangedType nStateChange )
629 {
630     if (STATE_CHANGE_INITSHOW == nStateChange)
631     {
632         Resize(); // #98848# avoid SmEditWindow not being painted correctly
633 
634         // set initial position of window in floating mode
635         if (sal_True == IsFloatingMode())
636             AdjustPosition(); //! don't change pos in docking-mode !
637 
638 //      // make sure the formula can be edited right away
639 //      aEdit.GrabFocus();
640 
641         // grab focus as above does not work...
642         // Thus we implement a timer based solution to get the initial
643         // focus in the Edit window.
644         aInitialFocusTimer.Start();
645     }
646 
647     SfxDockingWindow::StateChanged( nStateChange );
648 }
649 
650 
651 IMPL_LINK( SmCmdBoxWindow, InitialFocusTimerHdl, Timer *, EMPTYARG /*pTimer*/ )
652 {
653     // We want to have the focus in the edit window once Math has been opened
654     // to allow for immediate typing.
655     // Problem: There is no proper way to do this
656     // Thus: this timer based solution has been implemented (see GrabFocus below)
657     //
658     // Follow-up problem (#i114910): grabbing the focus may bust the help system since
659     // it relies on getting the current frame which conflicts with grabbing the focus.
660     // Thus aside from the 'GrabFocus' call everything else is to get the
661     // help reliably working despite using 'GrabFocus'.
662 
663     try
664     {
665         uno::Reference< frame::XDesktop > xDesktop;
666         uno::Reference< lang::XMultiServiceFactory > xSMGR( comphelper::getProcessServiceFactory() );
667         if (xSMGR.is())
668         {
669             xDesktop = uno::Reference< frame::XDesktop >(
670                 xSMGR->createInstance( rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" )), uno::UNO_QUERY_THROW );
671         }
672 
673         aEdit.GrabFocus();
674 
675         if (xDesktop.is())
676         {
677             bool bInPlace = GetView()->GetViewFrame()->GetFrame().IsInPlace();
678             uno::Reference< frame::XFrame > xFrame( GetBindings().GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface());
679             if ( bInPlace )
680             {
681                 uno::Reference< container::XChild > xModel( GetView()->GetDoc()->GetModel(), uno::UNO_QUERY_THROW );
682                 uno::Reference< frame::XModel > xParent( xModel->getParent(), uno::UNO_QUERY_THROW );
683                 uno::Reference< frame::XController > xParentCtrler( xParent->getCurrentController() );
684                 uno::Reference< frame::XFramesSupplier > xParentFrame( xParentCtrler->getFrame(), uno::UNO_QUERY_THROW );
685                 xParentFrame->setActiveFrame( xFrame );
686             }
687             else
688             {
689                 uno::Reference< frame::XFramesSupplier > xFramesSupplier( xDesktop, uno::UNO_QUERY );
690                 xFramesSupplier->setActiveFrame( xFrame );
691             }
692         }
693     }
694     catch (uno::Exception &)
695     {
696         DBG_ASSERT( 0, "failed to properly set initial focus to edit window" );
697     }
698     return 0;
699 }
700 
701 
702 void SmCmdBoxWindow::AdjustPosition()
703 {
704     Point aPt;
705     const Rectangle aRect( aPt, GetParent()->GetOutputSizePixel() );
706     Point aTopLeft( Point( aRect.Left(),
707                            aRect.Bottom() - GetSizePixel().Height() ) );
708     Point aPos( GetParent()->OutputToScreenPixel( aTopLeft ) );
709     if (aPos.X() < 0)
710         aPos.X() = 0;
711     if (aPos.Y() < 0)
712         aPos.Y() = 0;
713     SetPosPixel( aPos );
714 }
715 
716 
717 void SmCmdBoxWindow::ToggleFloatingMode()
718 {
719     SfxDockingWindow::ToggleFloatingMode();
720 
721     if (GetFloatingWindow())
722         GetFloatingWindow()->SetMinOutputSizePixel(Size (200, 50));
723 }
724 
725 
726 void SmCmdBoxWindow::GetFocus()
727 {
728     if (!bExiting)
729         aEdit.GrabFocus();
730 }
731 
732 /**************************************************************************/
733 
734 
735 SFX_IMPL_DOCKINGWINDOW(SmCmdBoxWrapper, SID_CMDBOXWINDOW);
736 
737 SmCmdBoxWrapper::SmCmdBoxWrapper(Window *pParentWindow, sal_uInt16 nId,
738                                  SfxBindings *pBindings,
739                                  SfxChildWinInfo *pInfo) :
740     SfxChildWindow(pParentWindow, nId)
741 {
742     pWindow = new SmCmdBoxWindow(pBindings, this, pParentWindow);
743 
744     // make window docked to the bottom initially (after first start)
745     eChildAlignment = SFX_ALIGN_BOTTOM;
746     ((SfxDockingWindow *)pWindow)->Initialize(pInfo);
747 }
748 
749 
750 #if OSL_DEBUG_LEVEL > 1
751 SmCmdBoxWrapper::~SmCmdBoxWrapper()
752 {
753 }
754 #endif
755 
756 
757 /**************************************************************************/
758 
759 struct SmViewShell_Impl
760 {
761     sfx2::DocumentInserter* pDocInserter;
762     SfxRequest*             pRequest;
763 
764     SmViewShell_Impl() :
765           pDocInserter( NULL )
766         , pRequest( NULL )
767     {}
768 
769     ~SmViewShell_Impl()
770     {
771         delete pDocInserter;
772         delete pRequest;
773     }
774 };
775 
776 TYPEINIT1( SmViewShell, SfxViewShell );
777 
778 SFX_IMPL_INTERFACE(SmViewShell, SfxViewShell, SmResId(0))
779 {
780     SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS | SFX_VISIBILITY_STANDARD |
781                                 SFX_VISIBILITY_FULLSCREEN | SFX_VISIBILITY_SERVER,
782                                 SmResId(RID_MATH_TOOLBOX ));
783 
784     SFX_CHILDWINDOW_REGISTRATION(SmToolBoxWrapper::GetChildWindowId());
785     SFX_CHILDWINDOW_REGISTRATION(SmCmdBoxWrapper::GetChildWindowId());
786 }
787 
788 
789 SFX_IMPL_NAMED_VIEWFACTORY(SmViewShell, "Default")
790 {
791     SFX_VIEW_REGISTRATION(SmDocShell);
792 }
793 
794 
795 Size SmViewShell::GetOptimalSizePixel() const
796 {
797     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetOptimalSizePixel" );
798 
799     return aGraphic.LogicToPixel( ((SmViewShell*)this)->GetDoc()->GetSize() );
800 }
801 
802 
803 void SmViewShell::AdjustPosSizePixel(const Point &rPos, const Size &rSize)
804 {
805     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::AdjustPosSizePixel" );
806 
807     aGraphic.SetPosSizePixel(rPos, rSize);
808 }
809 
810 
811 void SmViewShell::InnerResizePixel(const Point &rOfs, const Size &rSize)
812 {
813     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InnerResizePixel" );
814 
815     Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
816     if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
817     {
818         Size aProvidedSize = GetWindow()->PixelToLogic( rSize, MAP_100TH_MM );
819         SfxViewShell::SetZoomFactor( Fraction( aProvidedSize.Width(), aObjSize.Width() ),
820                         Fraction( aProvidedSize.Height(), aObjSize.Height() ) );
821     }
822 
823     SetBorderPixel( SvBorder() );
824     GetGraphicWindow().SetPosSizePixel(rOfs, rSize);
825     GetGraphicWindow().SetTotalSize();
826 }
827 
828 
829 void SmViewShell::OuterResizePixel(const Point &rOfs, const Size &rSize)
830 {
831     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::OuterResizePixel" );
832 
833     SmGraphicWindow &rWin = GetGraphicWindow();
834     rWin.SetPosSizePixel(rOfs, rSize);
835     if (GetDoc()->IsPreview())
836         rWin.ZoomToFitInWindow();
837     rWin.Update();
838 }
839 
840 
841 void SmViewShell::QueryObjAreaPixel( Rectangle& rRect ) const
842 {
843     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::QueryObjAreaPixel" );
844 
845     rRect.SetSize( GetGraphicWindow().GetSizePixel() );
846 }
847 
848 
849 void SmViewShell::SetZoomFactor( const Fraction &rX, const Fraction &rY )
850 {
851     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetZoomFactor" );
852 
853     const Fraction &rFrac = rX < rY ? rX : rY;
854     GetGraphicWindow().SetZoom( (sal_uInt16) long(rFrac * Fraction( 100, 1 )) );
855 
856     //Um Rundungsfehler zu minimieren lassen wir von der Basisklasse ggf.
857     //auch die krummen Werte einstellen
858     SfxViewShell::SetZoomFactor( rX, rY );
859 }
860 
861 
862 Size SmViewShell::GetTextLineSize(OutputDevice& rDevice, const String& rLine)
863 {
864     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextLineSize" );
865 
866     String aText;
867     Size   aSize(rDevice.GetTextWidth(rLine), rDevice.GetTextHeight());
868     sal_uInt16 nTabs = rLine.GetTokenCount('\t');
869 
870     if (nTabs > 0)
871     {
872         long TabPos = rDevice.GetTextWidth('n') * 8;
873 
874         aSize.Width() = 0;
875 
876         for (sal_uInt16 i = 0; i < nTabs; i++)
877         {
878             if (i > 0)
879                 aSize.Width() = ((aSize.Width() / TabPos) + 1) * TabPos;
880 
881             aText = rLine.GetToken(i, '\t');
882             aText.EraseLeadingChars('\t');
883             aText.EraseTrailingChars('\t');
884             aSize.Width() += rDevice.GetTextWidth(aText);
885         }
886     }
887 
888     return aSize;
889 }
890 
891 
892 Size SmViewShell::GetTextSize(OutputDevice& rDevice, const String& rText, long MaxWidth)
893 {
894     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetTextSize" );
895 
896     Size    aSize;
897     String  aLine;
898     Size    TextSize;
899     String  aText;
900     sal_uInt16  nLines = rText.GetTokenCount('\n');
901 
902     for (sal_uInt16 i = 0; i < nLines; i++)
903     {
904         aLine = rText.GetToken(i, '\n');
905         aLine.EraseAllChars('\r');
906         aLine.EraseLeadingChars('\n');
907         aLine.EraseTrailingChars('\n');
908 
909         aSize = GetTextLineSize(rDevice, aLine);
910 
911         if (aSize.Width() > MaxWidth)
912         {
913             do
914             {
915                 xub_StrLen m    = aLine.Len();
916                 xub_StrLen nLen = m;
917 
918                 for (xub_StrLen n = 0; n < nLen; n++)
919                 {
920                     sal_Unicode cLineChar = aLine.GetChar(n);
921                     if ((cLineChar == ' ') || (cLineChar == '\t'))
922                     {
923                         aText = aLine.Copy(0, n);
924                         if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
925                             m = n;
926                         else
927                             break;
928                     }
929                 }
930 
931                 aText = aLine.Copy(0, m);
932                 aLine.Erase(0, m);
933                 aSize = GetTextLineSize(rDevice, aText);
934                 TextSize.Height() += aSize.Height();
935                 TextSize.Width() = Max(TextSize.Width(), Min(aSize.Width(), MaxWidth));
936 
937                 aLine.EraseLeadingChars(' ');
938                 aLine.EraseLeadingChars('\t');
939                 aLine.EraseLeadingChars(' ');
940             }
941             while (aLine.Len() > 0);
942         }
943         else
944         {
945             TextSize.Height() += aSize.Height();
946             TextSize.Width() = Max(TextSize.Width(), aSize.Width());
947         }
948     }
949 
950     return TextSize;
951 }
952 
953 
954 void SmViewShell::DrawTextLine(OutputDevice& rDevice, const Point& rPosition, const String& rLine)
955 {
956     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawTextLine" );
957 
958     String  aText;
959     Point   aPoint (rPosition);
960     sal_uInt16  nTabs = rLine.GetTokenCount('\t');
961 
962     if (nTabs > 0)
963     {
964         long TabPos = rDevice.GetTextWidth('n') * 8;
965 
966         for (sal_uInt16 i = 0; i < nTabs; i++)
967         {
968             if (i > 0)
969                 aPoint.X() = ((aPoint.X() / TabPos) + 1) * TabPos;
970 
971             aText = rLine.GetToken(i, '\t');
972             aText.EraseLeadingChars('\t');
973             aText.EraseTrailingChars('\t');
974             rDevice.DrawText(aPoint, aText);
975             aPoint.X() += rDevice.GetTextWidth(aText);
976         }
977     }
978     else
979         rDevice.DrawText(aPoint, rLine);
980 }
981 
982 
983 void SmViewShell::DrawText(OutputDevice& rDevice, const Point& rPosition, const String& rText, sal_uInt16 MaxWidth)
984 {
985     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::DrawText" );
986 
987     sal_uInt16  nLines = rText.GetTokenCount('\n');
988     Point   aPoint (rPosition);
989     Size    aSize;
990     String  aLine;
991     String  aText;
992 
993     for (sal_uInt16 i = 0; i < nLines; i++)
994     {
995         aLine = rText.GetToken(i, '\n');
996         aLine.EraseAllChars('\r');
997         aLine.EraseLeadingChars('\n');
998         aLine.EraseTrailingChars('\n');
999         aSize = GetTextLineSize(rDevice, aLine);
1000         if (aSize.Width() > MaxWidth)
1001         {
1002             do
1003             {
1004                 xub_StrLen m    = aLine.Len();
1005                 xub_StrLen nLen = m;
1006 
1007                 for (xub_StrLen n = 0; n < nLen; n++)
1008                 {
1009                     sal_Unicode cLineChar = aLine.GetChar(n);
1010                     if ((cLineChar == ' ') || (cLineChar == '\t'))
1011                     {
1012                         aText = aLine.Copy(0, n);
1013                         if (GetTextLineSize(rDevice, aText).Width() < MaxWidth)
1014                             m = n;
1015                         else
1016                             break;
1017                     }
1018                 }
1019                 aText = aLine.Copy(0, m);
1020                 aLine.Erase(0, m);
1021 
1022                 DrawTextLine(rDevice, aPoint, aText);
1023                 aPoint.Y() += aSize.Height();
1024 
1025                 aLine.EraseLeadingChars(' ');
1026                 aLine.EraseLeadingChars('\t');
1027                 aLine.EraseLeadingChars(' ');
1028             }
1029             while (GetTextLineSize(rDevice, aLine).Width() > MaxWidth);
1030 
1031             // print the remaining text
1032             if (aLine.Len() > 0)
1033             {
1034                 DrawTextLine(rDevice, aPoint, aLine);
1035                 aPoint.Y() += aSize.Height();
1036             }
1037         }
1038         else
1039         {
1040             DrawTextLine(rDevice, aPoint, aLine);
1041             aPoint.Y() += aSize.Height();
1042         }
1043     }
1044 }
1045 
1046 void SmViewShell::Impl_Print(
1047         OutputDevice &rOutDev,
1048         const SmPrintUIOptions &rPrintUIOptions,
1049         Rectangle aOutRect, Point aZeroPoint )
1050 {
1051     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Impl_Print" );
1052 
1053     const bool bIsPrintTitle = rPrintUIOptions.getBoolValue( PRTUIOPT_TITLE_ROW, sal_True );
1054     const bool bIsPrintFrame = rPrintUIOptions.getBoolValue( PRTUIOPT_BORDER, sal_True );
1055     const bool bIsPrintFormulaText = rPrintUIOptions.getBoolValue( PRTUIOPT_FORMULA_TEXT, sal_True );
1056     SmPrintSize ePrintSize( static_cast< SmPrintSize >( rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_FORMAT, PRINT_SIZE_NORMAL ) ));
1057     const sal_uInt16 nZoomFactor = static_cast< sal_uInt16 >(rPrintUIOptions.getIntValue( PRTUIOPT_PRINT_SCALE, 100 ));
1058 // IsIgnoreSpacesRight is a parser option! Thus it does not get evaluated here anymore (too late).
1059 //    const bool bNoRightSpaces = rPrintUIOptions.getBoolValue( PRTUIOPT_NO_RIGHT_SPACE, sal_True );
1060 
1061     rOutDev.Push();
1062     rOutDev.SetLineColor( Color(COL_BLACK) );
1063 
1064     // output text on top
1065     if (bIsPrintTitle)
1066     {
1067         Size aSize600 (0, 600);
1068         Size aSize650 (0, 650);
1069         Font aFont(FAMILY_DONTKNOW, aSize600);
1070 
1071         aFont.SetAlign(ALIGN_TOP);
1072         aFont.SetWeight(WEIGHT_BOLD);
1073         aFont.SetSize(aSize650);
1074         aFont.SetColor( Color(COL_BLACK) );
1075         rOutDev.SetFont(aFont);
1076 
1077         Size aTitleSize (GetTextSize(rOutDev, GetDoc()->GetTitle(), aOutRect.GetWidth() - 200));
1078 
1079         aFont.SetWeight(WEIGHT_NORMAL);
1080         aFont.SetSize(aSize600);
1081         rOutDev.SetFont(aFont);
1082 
1083         Size aDescSize (GetTextSize(rOutDev, GetDoc()->GetComment(), aOutRect.GetWidth() - 200));
1084 
1085         if (bIsPrintFrame)
1086             rOutDev.DrawRect(Rectangle(aOutRect.TopLeft(),
1087                                Size(aOutRect.GetWidth(), 100 + aTitleSize.Height() + 200 + aDescSize.Height() + 100)));
1088         aOutRect.Top() += 200;
1089 
1090         // output title
1091         aFont.SetWeight(WEIGHT_BOLD);
1092         aFont.SetSize(aSize650);
1093         rOutDev.SetFont(aFont);
1094         Point aPoint(aOutRect.Left() + (aOutRect.GetWidth() - aTitleSize.Width()) / 2,
1095                      aOutRect.Top());
1096         DrawText(rOutDev, aPoint, GetDoc()->GetTitle(),
1097                  sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1098         aOutRect.Top() += aTitleSize.Height() + 200;
1099 
1100         // output description
1101         aFont.SetWeight(WEIGHT_NORMAL);
1102         aFont.SetSize(aSize600);
1103         rOutDev.SetFont(aFont);
1104         aPoint.X() = aOutRect.Left() + (aOutRect.GetWidth() - aDescSize.Width()) / 2;
1105         aPoint.Y() = aOutRect.Top();
1106         DrawText(rOutDev, aPoint, GetDoc()->GetComment(),
1107                  sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1108         aOutRect.Top() += aDescSize.Height() + 300;
1109     }
1110 
1111     // output text on bottom
1112     if (bIsPrintFormulaText)
1113     {
1114         Font aFont(FAMILY_DONTKNOW, Size(0, 600));
1115         aFont.SetAlign(ALIGN_TOP);
1116         aFont.SetColor( Color(COL_BLACK) );
1117 
1118         // get size
1119         rOutDev.SetFont(aFont);
1120 
1121         Size aSize (GetTextSize(rOutDev, GetDoc()->GetText(), aOutRect.GetWidth() - 200));
1122 
1123         aOutRect.Bottom() -= aSize.Height() + 600;
1124 
1125         if (bIsPrintFrame)
1126             rOutDev.DrawRect(Rectangle(aOutRect.BottomLeft(),
1127                                Size(aOutRect.GetWidth(), 200 + aSize.Height() + 200)));
1128 
1129         Point aPoint (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
1130                       aOutRect.Bottom() + 300);
1131         DrawText(rOutDev, aPoint, GetDoc()->GetText(),
1132                  sal::static_int_cast< sal_uInt16 >(aOutRect.GetWidth() - 200));
1133         aOutRect.Bottom() -= 200;
1134     }
1135 
1136     if (bIsPrintFrame)
1137         rOutDev.DrawRect(aOutRect);
1138 
1139     aOutRect.Top()    += 100;
1140     aOutRect.Left()   += 100;
1141     aOutRect.Bottom() -= 100;
1142     aOutRect.Right()  -= 100;
1143 
1144     Size aSize (GetDoc()->GetSize());
1145 
1146     MapMode OutputMapMode;
1147     // PDF export should always use PRINT_SIZE_NORMAL ...
1148     if (!rPrintUIOptions.getBoolValue( "IsPrinter", sal_False ) )
1149         ePrintSize = PRINT_SIZE_NORMAL;
1150     switch (ePrintSize)
1151     {
1152         case PRINT_SIZE_NORMAL:
1153             OutputMapMode = MapMode(MAP_100TH_MM);
1154             break;
1155 
1156         case PRINT_SIZE_SCALED:
1157             if ((aSize.Width() > 0) && (aSize.Height() > 0))
1158             {
1159                 Size     OutputSize (rOutDev.LogicToPixel(Size(aOutRect.GetWidth(),
1160                                                             aOutRect.GetHeight()), MapMode(MAP_100TH_MM)));
1161                 Size     GraphicSize (rOutDev.LogicToPixel(aSize, MapMode(MAP_100TH_MM)));
1162                 sal_uInt16   nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width() * 100L, GraphicSize.Width()),
1163                                               (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height()));
1164                 Fraction aFraction ((sal_uInt16) Max ((sal_uInt16) MINZOOM, Min((sal_uInt16) MAXZOOM, (sal_uInt16) (nZ - 10))), (sal_uInt16) 100);
1165 
1166                 OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction);
1167             }
1168             else
1169                 OutputMapMode = MapMode(MAP_100TH_MM);
1170             break;
1171 
1172         case PRINT_SIZE_ZOOMED:
1173         {
1174             Fraction aFraction( nZoomFactor, 100 );
1175 
1176             OutputMapMode = MapMode(MAP_100TH_MM, aZeroPoint, aFraction, aFraction);
1177             break;
1178         }
1179     }
1180 
1181     aSize = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aSize, OutputMapMode),
1182                                    MapMode(MAP_100TH_MM));
1183 
1184     Point aPos (aOutRect.Left() + (aOutRect.GetWidth() - aSize.Width()) / 2,
1185                 aOutRect.Top()  + (aOutRect.GetHeight() - aSize.Height()) / 2);
1186 
1187     aPos     = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aPos, MapMode(MAP_100TH_MM)),
1188                                           OutputMapMode);
1189     aOutRect   = rOutDev.PixelToLogic(rOutDev.LogicToPixel(aOutRect, MapMode(MAP_100TH_MM)),
1190                                           OutputMapMode);
1191 
1192     rOutDev.SetMapMode(OutputMapMode);
1193     rOutDev.SetClipRegion(Region(aOutRect));
1194     GetDoc()->Draw(rOutDev, aPos);
1195     rOutDev.SetClipRegion();
1196 
1197     rOutDev.Pop();
1198 }
1199 
1200 sal_uInt16 SmViewShell::Print(SfxProgress & /*rProgress*/, sal_Bool /*bIsAPI*/)
1201 {
1202     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Print" );
1203     DBG_ASSERT( 0, "SmViewShell::Print: no longer used with new UI print dialog. Should be removed!!" );
1204     return 0;
1205 }
1206 
1207 
1208 SfxPrinter* SmViewShell::GetPrinter(sal_Bool bCreate)
1209 {
1210     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetPrinter" );
1211 
1212     SmDocShell *pDoc = GetDoc();
1213     if ( pDoc->HasPrinter() || bCreate )
1214         return pDoc->GetPrinter();
1215     return 0;
1216 }
1217 
1218 
1219 sal_uInt16 SmViewShell::SetPrinter(SfxPrinter *pNewPrinter, sal_uInt16 nDiffFlags, bool )
1220 {
1221     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetPrinter" );
1222     SfxPrinter *pOld = GetDoc()->GetPrinter();
1223     if ( pOld && pOld->IsPrinting() )
1224         return SFX_PRINTERROR_BUSY;
1225 
1226     if ((nDiffFlags & SFX_PRINTER_PRINTER) == SFX_PRINTER_PRINTER)
1227         GetDoc()->SetPrinter( pNewPrinter );
1228 
1229     if ((nDiffFlags & SFX_PRINTER_OPTIONS) == SFX_PRINTER_OPTIONS)
1230     {
1231         SmModule *pp = SM_MOD();
1232         pp->GetConfig()->ItemSetToConfig(pNewPrinter->GetOptions());
1233     }
1234     return 0;
1235 }
1236 
1237 
1238 SfxTabPage* SmViewShell::CreatePrintOptionsPage(Window *pParent,
1239                                                 const SfxItemSet &rOptions)
1240 {
1241     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::CreatePrintOptionsPage" );
1242 
1243     return SmPrintOptionsTabPage::Create(pParent, rOptions);
1244 }
1245 
1246 
1247 SmEditWindow *SmViewShell::GetEditWindow()
1248 {
1249     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetEditWindow" );
1250 
1251     SmCmdBoxWrapper *pWrapper = (SmCmdBoxWrapper *) GetViewFrame()->
1252             GetChildWindow( SmCmdBoxWrapper::GetChildWindowId() );
1253 
1254     if (pWrapper != NULL)
1255     {
1256         SmEditWindow *pEditWin  = pWrapper->GetEditWindow();
1257         DBG_ASSERT( pEditWin, "SmEditWindow missing" );
1258         return pEditWin;
1259     }
1260 
1261     return NULL;
1262 }
1263 
1264 
1265 void SmViewShell::SetStatusText(const String& Text)
1266 {
1267     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SetStatusText" );
1268 
1269     StatusText = Text;
1270     GetViewFrame()->GetBindings().Invalidate(SID_TEXTSTATUS);
1271 }
1272 
1273 
1274 void SmViewShell::ShowError( const SmErrorDesc *pErrorDesc )
1275 {
1276     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::ShowError" );
1277 
1278     DBG_ASSERT(GetDoc(), "Sm : Document missing");
1279     if (pErrorDesc || 0 != (pErrorDesc = GetDoc()->GetParser().GetError(0)) )
1280     {
1281         SetStatusText( pErrorDesc->Text );
1282         GetEditWindow()->MarkError( Point( pErrorDesc->pNode->GetColumn(),
1283                                            pErrorDesc->pNode->GetRow()));
1284     }
1285 }
1286 
1287 
1288 void SmViewShell::NextError()
1289 {
1290     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::NextError" );
1291 
1292     DBG_ASSERT(GetDoc(), "Sm : Document missing");
1293     const SmErrorDesc   *pErrorDesc = GetDoc()->GetParser().NextError();
1294 
1295     if (pErrorDesc)
1296         ShowError( pErrorDesc );
1297 }
1298 
1299 
1300 void SmViewShell::PrevError()
1301 {
1302     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::PrevError" );
1303 
1304     DBG_ASSERT(GetDoc(), "Sm : Document missing");
1305     const SmErrorDesc   *pErrorDesc = GetDoc()->GetParser().PrevError();
1306 
1307     if (pErrorDesc)
1308         ShowError( pErrorDesc );
1309 }
1310 
1311 
1312 sal_Bool SmViewShell::Insert( SfxMedium& rMedium )
1313 {
1314     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Insert" );
1315 
1316     SmDocShell *pDoc = GetDoc();
1317     String aText( pDoc->GetText() );
1318     String aTemp = aText;
1319     sal_Bool bRet = sal_False, bChkOldVersion = sal_True;
1320 
1321     uno::Reference < embed::XStorage > xStorage = rMedium.GetStorage();
1322     uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1323     if ( xNameAccess.is() && xNameAccess->getElementNames().getLength() )
1324     {
1325         if ( xNameAccess->hasByName( C2S( "content.xml" ) ) || xNameAccess->hasByName( C2S( "Content.xml" ) ))
1326         {
1327             bChkOldVersion = sal_False;
1328             // is this a fabulous math package ?
1329             Reference<com::sun::star::frame::XModel> xModel(pDoc->GetModel());
1330             SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
1331             bRet = 0 == aEquation.Import(rMedium);
1332         }
1333     }
1334 
1335     if( bRet )
1336     {
1337         aText = pDoc->GetText();
1338         SmEditWindow *pEditWin = GetEditWindow();
1339         if (pEditWin)
1340             pEditWin->InsertText( aText );
1341         else
1342         {
1343             DBG_ERROR( "EditWindow missing" );
1344             aTemp += aText;
1345             aText  = aTemp;
1346         }
1347 
1348         pDoc->Parse();
1349         pDoc->SetModified(sal_True);
1350 
1351         SfxBindings &rBnd = GetViewFrame()->GetBindings();
1352         rBnd.Invalidate(SID_GAPHIC_SM);
1353         rBnd.Invalidate(SID_TEXT);
1354     }
1355     return bRet;
1356 }
1357 
1358 
1359 sal_Bool SmViewShell::InsertFrom(SfxMedium &rMedium)
1360 {
1361     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::InsertFrom" );
1362 
1363     sal_Bool        bSuccess = sal_False;
1364     SmDocShell *pDoc = GetDoc();
1365     SvStream   *pStream = rMedium.GetInStream();
1366     String      aText( pDoc->GetText() );
1367     String      aTemp = aText;
1368 
1369     if (pStream)
1370     {
1371         const String& rFltName = rMedium.GetFilter()->GetFilterName();
1372         if ( rFltName.EqualsAscii(MATHML_XML) )
1373         {
1374             Reference<com::sun::star::frame::XModel> xModel( pDoc->GetModel() );
1375             SmXMLImportWrapper aEquation(xModel); //!! modifies the result of pDoc->GetText() !!
1376             bSuccess = 0 == aEquation.Import(rMedium);
1377         }
1378         else
1379         {
1380             //bSuccess = ImportSM20File( pStream );
1381         }
1382     }
1383 
1384     if( bSuccess )
1385     {
1386         aText = pDoc->GetText();
1387         SmEditWindow *pEditWin = GetEditWindow();
1388         if (pEditWin)
1389             pEditWin->InsertText( aText );
1390         else
1391         {
1392             DBG_ERROR( "EditWindow missing" );
1393             aTemp += aText;
1394             aText  = aTemp;
1395         }
1396 
1397         pDoc->Parse();
1398         pDoc->SetModified(sal_True);
1399 
1400         SfxBindings &rBnd = GetViewFrame()->GetBindings();
1401         rBnd.Invalidate(SID_GAPHIC_SM);
1402         rBnd.Invalidate(SID_TEXT);
1403     }
1404 
1405     return bSuccess;
1406 }
1407 
1408 
1409 void SmViewShell::Execute(SfxRequest& rReq)
1410 {
1411     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Execute" );
1412 
1413     SmEditWindow *pWin = GetEditWindow();
1414 
1415     switch (rReq.GetSlot())
1416     {
1417         case SID_FORMULACURSOR:
1418         {
1419             SmModule *pp = SM_MOD();
1420 
1421             const SfxItemSet *pArgs = rReq.GetArgs();
1422             const SfxPoolItem *pItem;
1423 
1424             sal_Bool bVal;
1425             if ( pArgs &&
1426                  SFX_ITEM_SET == pArgs->GetItemState( SID_FORMULACURSOR, sal_False, &pItem))
1427                 bVal = ((SfxBoolItem *) pItem)->GetValue();
1428             else
1429                 bVal = !pp->GetConfig()->IsShowFormulaCursor();
1430 
1431             pp->GetConfig()->SetShowFormulaCursor(bVal);
1432             GetGraphicWindow().ShowCursor(bVal);
1433             break;
1434         }
1435         case SID_DRAW:
1436             if (pWin)
1437             {
1438                 GetDoc()->SetText( pWin->GetText() );
1439                 SetStatusText(String());
1440                 ShowError( 0 );
1441                 GetDoc()->Repaint();
1442             }
1443             break;
1444 
1445         case SID_ADJUST:
1446         case SID_FITINWINDOW:
1447             aGraphic.ZoomToFitInWindow();
1448             break;
1449 
1450         case SID_VIEW050:
1451             aGraphic.SetZoom(50);
1452             break;
1453 
1454         case SID_VIEW100:
1455             aGraphic.SetZoom(100);
1456             break;
1457 
1458         case SID_VIEW200:
1459             aGraphic.SetZoom(200);
1460             break;
1461 
1462         case SID_ZOOMIN:
1463             aGraphic.SetZoom(aGraphic.GetZoom() + 25);
1464             break;
1465 
1466         case SID_ZOOMOUT:
1467             DBG_ASSERT(aGraphic.GetZoom() >= 25, "Sm: Wrong sal_uInt16 argument");
1468             aGraphic.SetZoom(aGraphic.GetZoom() - 25);
1469             break;
1470 
1471         case SID_COPYOBJECT:
1472         {
1473             // TODO/LATER: does not work because of UNO Tunneling - will be fixed later
1474             Reference< datatransfer::XTransferable > xTrans( GetDoc()->GetModel(), uno::UNO_QUERY );
1475             if( xTrans.is() )
1476             {
1477                 Reference< lang::XUnoTunnel> xTnnl( xTrans, uno::UNO_QUERY);
1478                 if( xTnnl.is() )
1479                 {
1480                     TransferableHelper* pTrans = reinterpret_cast< TransferableHelper * >(
1481                             sal::static_int_cast< sal_uIntPtr >(
1482                             xTnnl->getSomething( TransferableHelper::getUnoTunnelId() )));
1483                     if( pTrans )
1484                         pTrans->CopyToClipboard( this ? GetEditWindow() : 0 );
1485                 }
1486             }
1487         }
1488         break;
1489 
1490         case SID_PASTEOBJECT:
1491         {
1492             TransferableDataHelper aData( TransferableDataHelper::CreateFromSystemClipboard(this ? GetEditWindow(): 0) );
1493             uno::Reference < io::XInputStream > xStrm;
1494             SotFormatStringId nId;
1495             if( aData.GetTransferable().is() &&
1496                 ( aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ||
1497                   (aData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) &&
1498                    aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBED_SOURCE ))) &&
1499                 aData.GetInputStream( nId, xStrm ) && xStrm.is() )
1500             {
1501                 try
1502                 {
1503                     uno::Reference < embed::XStorage > xStorage =
1504                             ::comphelper::OStorageHelper::GetStorageFromInputStream( xStrm, ::comphelper::getProcessServiceFactory() );
1505                     uno::Reference < beans::XPropertySet > xProps( xStorage, uno::UNO_QUERY );
1506                     SfxMedium aMedium( xStorage, String() );
1507                     Insert( aMedium );
1508                     GetDoc()->UpdateText();
1509                 }
1510                 catch (uno::Exception &)
1511                 {
1512                     DBG_ERROR( "SmViewShell::Execute (SID_PASTEOBJECT): failed to get storage from input stream" );
1513                 }
1514             }
1515         }
1516         break;
1517 
1518 
1519         case SID_CUT:
1520             if (pWin)
1521                 pWin->Cut();
1522             break;
1523 
1524         case SID_COPY:
1525             if (pWin)
1526             {
1527                 if (pWin->IsAllSelected())
1528                 {
1529                     GetViewFrame()->GetDispatcher()->Execute(
1530                                 SID_COPYOBJECT, SFX_CALLMODE_STANDARD,
1531                                 new SfxVoidItem(SID_COPYOBJECT), 0L);
1532                 }
1533                 else
1534                     pWin->Copy();
1535             }
1536             break;
1537 
1538         case SID_PASTE:
1539             {
1540                 sal_Bool bCallExec = 0 == pWin;
1541                 if( !bCallExec )
1542                 {
1543                     TransferableDataHelper aDataHelper(
1544                         TransferableDataHelper::CreateFromSystemClipboard(
1545                                                     GetEditWindow()) );
1546 
1547                     if( aDataHelper.GetTransferable().is() &&
1548                         aDataHelper.HasFormat( FORMAT_STRING ))
1549                         pWin->Paste();
1550                     else
1551                         bCallExec = sal_True;
1552                 }
1553                 if( bCallExec )
1554                 {
1555                     GetViewFrame()->GetDispatcher()->Execute(
1556                             SID_PASTEOBJECT, SFX_CALLMODE_STANDARD,
1557                             new SfxVoidItem(SID_PASTEOBJECT), 0L);
1558                 }
1559             }
1560             break;
1561 
1562         case SID_DELETE:
1563             if (pWin)
1564                 pWin->Delete();
1565             break;
1566 
1567         case SID_SELECT:
1568             if (pWin)
1569                 pWin->SelectAll();
1570             break;
1571 
1572         case SID_INSERTCOMMAND:
1573         {
1574             const SfxInt16Item& rItem =
1575                 (const SfxInt16Item&)rReq.GetArgs()->Get(SID_INSERTCOMMAND);
1576 
1577             if (pWin)
1578                 pWin->InsertCommand(rItem.GetValue());
1579             break;
1580         }
1581 
1582         case SID_INSERTTEXT:
1583         {
1584             const SfxStringItem& rItem =
1585                     (const SfxStringItem&)rReq.GetArgs()->Get(SID_INSERTTEXT);
1586             if (pWin)
1587                 pWin->InsertText(rItem.GetValue());
1588             break;
1589         }
1590 
1591         case SID_IMPORT_FORMULA:
1592         {
1593             delete pImpl->pRequest;
1594             pImpl->pRequest = new SfxRequest( rReq );
1595             delete pImpl->pDocInserter;
1596             pImpl->pDocInserter =
1597                 new ::sfx2::DocumentInserter( 0, GetDoc()->GetFactory().GetFactoryName(), 0 );
1598             pImpl->pDocInserter->StartExecuteModal( LINK( this, SmViewShell, DialogClosedHdl ) );
1599             break;
1600         }
1601 
1602         case SID_IMPORT_MATHML_CLIPBOARD:
1603         {
1604             TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) );
1605             uno::Reference < io::XInputStream > xStrm;
1606             SotFormatStringId nId = SOT_FORMAT_SYSTEM_START; // dummy initialize to avoid warning
1607             if  ( aDataHelper.GetTransferable().is() )
1608             {
1609                 if ( aDataHelper.HasFormat( nId = SOT_FORMATSTR_ID_MATHML ) )
1610                 {
1611                     if ( aDataHelper.GetInputStream( nId, xStrm ) && xStrm.is() )
1612                     {
1613                         SfxMedium* pClipboardMedium = new SfxMedium();
1614                         pClipboardMedium->GetItemSet(); // generate initial itemset, not sure if necessary
1615                         const SfxFilter* pMathFilter = SfxFilter::GetFilterByName( String::CreateFromAscii(MATHML_XML) );
1616                         pClipboardMedium->SetFilter(pMathFilter);
1617                         pClipboardMedium->setStreamToLoadFrom( xStrm, sal_True /*bIsReadOnly*/ );
1618                         InsertFrom(*pClipboardMedium);
1619                         GetDoc()->UpdateText();
1620                         delete pClipboardMedium;
1621                     }
1622                 }
1623                 else
1624                 {
1625                     if ( aDataHelper.HasFormat( nId = FORMAT_STRING) )
1626                     {
1627                         // In case of FORMAT_STRING no stream exists, need to generate one
1628                         ::rtl::OUString aString;
1629                         if (aDataHelper.GetString( nId, aString))
1630                         {
1631                             SfxMedium* pClipboardMedium = new SfxMedium();
1632                             pClipboardMedium->GetItemSet(); //generates initial itemset, not sure if necessary
1633                             const SfxFilter* pMathFilter = SfxFilter::GetFilterByName( String::CreateFromAscii(MATHML_XML) );
1634                             pClipboardMedium->SetFilter(pMathFilter);
1635 
1636                             SvMemoryStream * pStrm;
1637                             // The text to be imported might assert encoding like 'encoding="utf-8"' but FORMAT_STRING is UTF-16.
1638                             // Force encoding to UTF-16, if encoding exists.
1639                             bool bForceUTF16 = false;
1640                             sal_Int32 nPosL = aString.indexOf( OUString::createFromAscii("encoding=\""));
1641                             sal_Int32 nPosU = -1;
1642                             if ( nPosL >= 0 && nPosL +10 < aString.getLength() )
1643                             {
1644                                 nPosL += 10;
1645                                 nPosU = aString.indexOf( '"',nPosL);
1646                                 if (nPosU > nPosL)
1647                                 {
1648                                     bForceUTF16 = true;
1649                                 }
1650                             }
1651                             if ( bForceUTF16 )
1652                             {
1653                                 OUString aNewString = aString.replaceAt( nPosL,nPosU-nPosL,OUString::createFromAscii("UTF-16"));
1654                                 pStrm = new SvMemoryStream( (void*)aNewString.getStr(), aNewString.getLength() * sizeof(sal_Unicode), STREAM_READ);
1655                             }
1656                             else
1657                             {
1658                                 pStrm = new SvMemoryStream( (void*)aString.getStr(), aString.getLength() * sizeof(sal_Unicode), STREAM_READ);
1659                             }
1660                             com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xStrm( new ::utl::OInputStreamWrapper( *pStrm ) );
1661                             pClipboardMedium->setStreamToLoadFrom( xStrm, sal_True /*bIsReadOnly*/ );
1662                             InsertFrom(*pClipboardMedium);
1663                             GetDoc()->UpdateText();
1664                             delete pClipboardMedium;
1665                             delete pStrm;
1666                         }
1667                     }
1668                 }
1669             }
1670             break;
1671         }
1672 
1673         case SID_NEXTERR:
1674             NextError();
1675             if (pWin)
1676                 pWin->GrabFocus();
1677             break;
1678 
1679         case SID_PREVERR:
1680             PrevError();
1681             if (pWin)
1682                 pWin->GrabFocus();
1683             break;
1684 
1685         case SID_NEXTMARK:
1686             if (pWin)
1687             {
1688                 pWin->SelNextMark();
1689                 pWin->GrabFocus();
1690             }
1691             break;
1692 
1693         case SID_PREVMARK:
1694             if (pWin)
1695             {
1696                 pWin->SelPrevMark();
1697                 pWin->GrabFocus();
1698             }
1699             break;
1700 
1701         case SID_TEXTSTATUS:
1702         {
1703             if (rReq.GetArgs() != NULL)
1704             {
1705                 const SfxStringItem& rItem =
1706                     (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXTSTATUS);
1707 
1708                 SetStatusText(rItem.GetValue());
1709             }
1710 
1711             break;
1712         }
1713 
1714         case SID_GETEDITTEXT:
1715             if (pWin)
1716                 if (pWin->GetText ().Len ()) GetDoc()->SetText( pWin->GetText() );
1717             break;
1718 
1719         case SID_ATTR_ZOOM:
1720         {
1721             if ( !GetViewFrame()->GetFrame().IsInPlace() )
1722             {
1723                 //CHINA001 SvxZoomDialog *pDlg = 0;
1724                 AbstractSvxZoomDialog *pDlg = 0;
1725                 const SfxItemSet *pSet = rReq.GetArgs();
1726                 if ( !pSet )
1727                 {
1728                     SfxItemSet aSet( GetDoc()->GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM);
1729                     aSet.Put( SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom()));
1730                     //CHINA001 pDlg = new SvxZoomDialog( &GetViewFrame()->GetWindow(), aSet);
1731                     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1732                     if(pFact)
1733                     {
1734                         pDlg = pFact->CreateSvxZoomDialog(&GetViewFrame()->GetWindow(), aSet);
1735                         DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
1736                     }
1737                     pDlg->SetLimits( MINZOOM, MAXZOOM );
1738                     if( pDlg->Execute() != RET_CANCEL )
1739                         pSet = pDlg->GetOutputItemSet();
1740                 }
1741                 if ( pSet )
1742                 {
1743                     const SvxZoomItem &rZoom = (const SvxZoomItem &)pSet->Get(SID_ATTR_ZOOM);
1744                     switch( rZoom.GetType() )
1745                     {
1746                         case SVX_ZOOM_PERCENT:
1747                             aGraphic.SetZoom((sal_uInt16)rZoom.GetValue ());
1748                             break;
1749 
1750                         case SVX_ZOOM_OPTIMAL:
1751                             aGraphic.ZoomToFitInWindow();
1752                             break;
1753 
1754                         case SVX_ZOOM_PAGEWIDTH:
1755                         case SVX_ZOOM_WHOLEPAGE:
1756                         {
1757                             const MapMode aMap( MAP_100TH_MM );
1758                             SfxPrinter *pPrinter = GetPrinter( sal_True );
1759                             Point aPoint;
1760                             Rectangle  OutputRect(aPoint, pPrinter->GetOutputSize());
1761                             Size       OutputSize(pPrinter->LogicToPixel(Size(OutputRect.GetWidth(),
1762                                                                               OutputRect.GetHeight()), aMap));
1763                             Size       GraphicSize(pPrinter->LogicToPixel(GetDoc()->GetSize(), aMap));
1764                             sal_uInt16     nZ = (sal_uInt16) Min((long)Fraction(OutputSize.Width()  * 100L, GraphicSize.Width()),
1765                                                          (long)Fraction(OutputSize.Height() * 100L, GraphicSize.Height()));
1766                             aGraphic.SetZoom (nZ);
1767                             break;
1768                         }
1769                         default:
1770                             break;
1771                     }
1772                 }
1773                 delete pDlg;
1774             }
1775         }
1776         break;
1777 
1778         case SID_TOOLBOX:
1779         {
1780             GetViewFrame()->ToggleChildWindow( SmToolBoxWrapper::GetChildWindowId() );
1781         }
1782         break;
1783 
1784         case SID_SYMBOLS_CATALOGUE:
1785         {
1786 
1787             // get device used to retrieve the FontList
1788             SmDocShell *pDoc = GetDoc();
1789             OutputDevice *pDev = pDoc->GetPrinter();
1790             if (!pDev || pDev->GetDevFontCount() == 0)
1791                 pDev = &SM_MOD()->GetDefaultVirtualDev();
1792             DBG_ASSERT (pDev, "device for font list missing" );
1793 
1794             SmModule *pp = SM_MOD();
1795             SmSymbolDialog( NULL, pDev, pp->GetSymbolManager(), *this ).Execute();
1796         }
1797         break;
1798     }
1799     rReq.Done();
1800 }
1801 
1802 
1803 void SmViewShell::GetState(SfxItemSet &rSet)
1804 {
1805     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::GetState" );
1806 
1807     SfxWhichIter aIter(rSet);
1808 
1809     SmEditWindow *pEditWin = GetEditWindow();
1810     for (sal_uInt16 nWh = aIter.FirstWhich(); nWh != 0; nWh = aIter.NextWhich())
1811     {
1812         switch (nWh)
1813         {
1814         case SID_CUT:
1815         case SID_COPY:
1816         case SID_DELETE:
1817             if (! pEditWin || ! pEditWin->IsSelected())
1818                 rSet.DisableItem(nWh);
1819             break;
1820 
1821         case SID_PASTE:
1822             if( !xClipEvtLstnr.is() && pEditWin)
1823             {
1824                 TransferableDataHelper aDataHelper(
1825                         TransferableDataHelper::CreateFromSystemClipboard(
1826                                                         pEditWin) );
1827 
1828                 bPasteState = aDataHelper.GetTransferable().is() &&
1829                  ( aDataHelper.HasFormat( FORMAT_STRING ) ||
1830                    aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ||
1831                    (aDataHelper.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR )
1832                      && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE )));
1833             }
1834             if( !bPasteState )
1835                 rSet.DisableItem( nWh );
1836             break;
1837 
1838         case SID_ATTR_ZOOM:
1839             rSet.Put(SvxZoomItem( SVX_ZOOM_PERCENT, aGraphic.GetZoom()));
1840             /* no break here */
1841         case SID_VIEW050:
1842         case SID_VIEW100:
1843         case SID_VIEW200:
1844         case SID_ADJUST:
1845         case SID_ZOOMIN:
1846         case SID_ZOOMOUT:
1847         case SID_FITINWINDOW:
1848             if ( GetViewFrame()->GetFrame().IsInPlace() )
1849                 rSet.DisableItem( nWh );
1850             break;
1851 
1852         case SID_NEXTERR:
1853         case SID_PREVERR:
1854         case SID_NEXTMARK:
1855         case SID_PREVMARK:
1856         case SID_DRAW:
1857         case SID_SELECT:
1858             if (! pEditWin || pEditWin->IsEmpty())
1859                 rSet.DisableItem(nWh);
1860             break;
1861 
1862         case SID_TEXTSTATUS:
1863             {
1864                 rSet.Put(SfxStringItem(nWh, StatusText));
1865             }
1866             break;
1867 
1868         case SID_FORMULACURSOR:
1869             {
1870                 SmModule *pp = SM_MOD();
1871                 rSet.Put(SfxBoolItem(nWh, pp->GetConfig()->IsShowFormulaCursor()));
1872             }
1873             break;
1874 
1875         case SID_TOOLBOX:
1876             {
1877                 sal_Bool bState = sal_False;
1878                 SfxChildWindow *pChildWnd = GetViewFrame()->
1879                         GetChildWindow( SmToolBoxWrapper::GetChildWindowId() );
1880                 if (pChildWnd && pChildWnd->GetWindow()->IsVisible())
1881                     bState = sal_True;
1882                 rSet.Put(SfxBoolItem(SID_TOOLBOX, bState));
1883             }
1884             break;
1885 
1886         }
1887     }
1888 }
1889 
1890 
1891 SmViewShell::SmViewShell(SfxViewFrame *pFrame_, SfxViewShell *):
1892     SfxViewShell(pFrame_, SFX_VIEW_HAS_PRINTOPTIONS | SFX_VIEW_CAN_PRINT),
1893     aGraphic(this),
1894     aGraphicController(aGraphic, SID_GAPHIC_SM, pFrame_->GetBindings()),
1895     pImpl( new SmViewShell_Impl )
1896 {
1897     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::SmViewShell" );
1898 
1899 //    pViewFrame = &pFrame_->GetWindow();
1900 
1901     SetStatusText(String());
1902     SetWindow(&aGraphic);
1903     SfxShell::SetName(C2S("SmView"));
1904     SfxShell::SetUndoManager( &GetDoc()->GetEditEngine().GetUndoManager() );
1905     SetHelpId( HID_SMA_VIEWSHELL_DOCUMENT );
1906 }
1907 
1908 
1909 SmViewShell::~SmViewShell()
1910 {
1911     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::~SmViewShell" );
1912 
1913     //!! this view shell is not active anymore !!
1914     // Thus 'SmGetActiveView' will give a 0 pointer.
1915     // Thus we need to supply this view as argument
1916     SmEditWindow *pEditWin = GetEditWindow();
1917     if (pEditWin)
1918         pEditWin->DeleteEditView( *this );
1919     delete pImpl;
1920 }
1921 
1922 void SmViewShell::Deactivate( sal_Bool bIsMDIActivate )
1923 {
1924     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Deactivate" );
1925 
1926     SmEditWindow *pEdit = GetEditWindow();
1927     if ( pEdit )
1928         pEdit->Flush();
1929 
1930     SfxViewShell::Deactivate( bIsMDIActivate );
1931 }
1932 
1933 
1934 void SmViewShell::Activate( sal_Bool bIsMDIActivate )
1935 {
1936     RTL_LOGFILE_CONTEXT( aLog, "starmath: SmViewShell::Activate" );
1937 
1938     SfxViewShell::Activate( bIsMDIActivate );
1939 
1940     SmEditWindow *pEdit = GetEditWindow();
1941     if ( pEdit )
1942     {
1943         //! Since there is no way to be informed if a "drag and drop"
1944         //! event has taken place, we call SetText here in order to
1945         //! synchronize the GraphicWindow display with the text in the
1946         //! EditEngine.
1947         SmDocShell *pDoc = GetDoc();
1948         pDoc->SetText( pDoc->GetEditEngine().GetText( LINEEND_LF ) );
1949 
1950         if ( bIsMDIActivate )
1951             pEdit->GrabFocus();
1952     }
1953 }
1954 
1955 //------------------------------------------------------------------
1956 
1957 IMPL_LINK( SmViewShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
1958 {
1959     DBG_ASSERT( _pFileDlg, "SmViewShell::DialogClosedHdl(): no file dialog" );
1960     DBG_ASSERT( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" );
1961 
1962     if ( ERRCODE_NONE == _pFileDlg->GetError() )
1963     {
1964         //sal_uInt16 nSlot = pImpl->pRequest->GetSlot();
1965         SfxMedium* pMedium = pImpl->pDocInserter->CreateMedium();
1966 
1967         if ( pMedium != NULL )
1968         {
1969             if ( pMedium->IsStorage() )
1970                 Insert( *pMedium );
1971             else
1972                 InsertFrom( *pMedium );
1973             delete pMedium;
1974 
1975             SmDocShell* pDoc = GetDoc();
1976             pDoc->UpdateText();
1977             pDoc->ArrangeFormula();
1978             pDoc->Repaint();
1979             // adjust window, repaint, increment ModifyCount,...
1980             GetViewFrame()->GetBindings().Invalidate(SID_GAPHIC_SM);
1981         }
1982     }
1983 
1984     pImpl->pRequest->SetReturnValue( SfxBoolItem( pImpl->pRequest->GetSlot(), sal_True ) );
1985     pImpl->pRequest->Done();
1986     return 0;
1987 }
1988 
1989 void SmViewShell::Notify( SfxBroadcaster& , const SfxHint& rHint )
1990 {
1991     if ( rHint.IsA(TYPE(SfxSimpleHint)) )
1992     {
1993         switch( ( (SfxSimpleHint&) rHint ).GetId() )
1994         {
1995             case SFX_HINT_MODECHANGED:
1996             case SFX_HINT_DOCCHANGED:
1997                 GetViewFrame()->GetBindings().InvalidateAll(sal_False);
1998                 break;
1999             default:
2000                 break;
2001         }
2002     }
2003 }
2004 
2005 /* vim: set noet sw=4 ts=4: */
2006