GSoC patch

Michal Spisiak <[email protected]> Fri, 20 Aug 2010 13:05:13 +0200
Newsgroups gmane.comp.gnome.ximian.openoffice
Message-ID <[email protected]>
Hello,

I was asked to send my patch that I worked on as a part of GSoC. My project
title Improving equation editor included mainly aligning Starmath formulas
(this is what I called Baseline). Associated with it was fix for adding
borders to non-resizable objects, which are for instance formulas. And
finally I implemented new feature for Math formulas in Writer, which enables
user to set font-height inside the formula by highlighting it (as any other
text) and change font using Writer UI.

This patch is created for ooo320-m19, hopefully it won't be problem to apply
it to master.

regards

Michal
Baseline_Borders_SizeChange_ooo320-m19_2010-8-20.diff (text/x-patch, 30.4 KB)
diff --git a/sfx2/inc/sfx2/ipclient.hxx b/sfx2/inc/sfx2/ipclient.hxx
index 141de70..2471323 100644
--- a/sfx2/inc/sfx2/ipclient.hxx
+++ b/sfx2/inc/sfx2/ipclient.hxx
@@ -101,6 +101,7 @@ public:
     // used in Writer
     // Rectangle           PixelObjVisAreaToLogic( const Rectangle & rObjRect ) const;
     // Rectangle           LogicObjAreaToPixel( const Rectangle & rRect ) const;
+    virtual void        FormatChanged(); // object format was changed (used for StarMath formulas aligning)
 };
 
 #endif
diff --git a/sfx2/source/view/ipclient.cxx b/sfx2/source/view/ipclient.cxx
index a0cd213..a486bc0 100644
--- a/sfx2/source/view/ipclient.cxx
+++ b/sfx2/source/view/ipclient.cxx
@@ -214,6 +214,7 @@ void SAL_CALL SfxInPlaceClient_Impl::notifyEvent( const document::EventObject& a
 
     if ( m_pClient && aEvent.EventName.equalsAscii("OnVisAreaChanged") && m_nAspect != embed::Aspects::MSOLE_ICON )
     {
+        m_pClient->FormatChanged(); // for Writer when format of the object is changed with the area
         m_pClient->ViewChanged();
         m_pClient->Invalidate();
     }
@@ -1074,6 +1075,11 @@ void SfxInPlaceClient::MakeVisible()
     // dummy implementation
 }
 
+void SfxInPlaceClient::FormatChanged()
+{
+    // dummy implementation
+}
+
 void SfxInPlaceClient::DeactivateObject()
 {
     if ( GetObject().is() )
diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
index dabb503..cfa8b2b 100644
--- a/starmath/inc/node.hxx
+++ b/starmath/inc/node.hxx
@@ -180,6 +180,9 @@ public:
 
     const SmNode *	FindTokenAt(USHORT nRow, USHORT nCol) const;
     const SmNode *	FindRectClosestTo(const Point &rPoint) const;
+    // --> 4.7.2010 #i972#
+    virtual long GetFormulaBaseline() const { return (long)0; } //dummy, used in SmTableNode
+    // <--
 };
 
 
@@ -467,6 +470,9 @@ public:
 
 class SmTableNode : public SmStructureNode
 {
+    // --> 4.7.2010 #i972#
+    long nFormulaBaseline;
+    // <--
 public:
     SmTableNode(const SmToken &rNodeToken)
     :	SmStructureNode(NTABLE, rNodeToken)
@@ -476,6 +482,7 @@ public:
     virtual SmNode * GetLeftMost();
 
     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
+    long GetFormulaBaseline() const { return nFormulaBaseline; }
 };
 
 
diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx
index b243ced..415a8c0 100644
--- a/starmath/source/node.cxx
+++ b/starmath/source/node.cxx
@@ -760,7 +760,7 @@ void SmTableNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
         }
 
     Point  aPos;
-    SmRect::operator = (SmRect(nMaxWidth, 0));
+    SmRect::operator = (SmRect(nMaxWidth, 1));
     for (i = 0;  i < nSize;  i++)
     {   if (NULL != (pNode = GetSubNode(i)))
         {	const SmRect &rNodeRect = pNode->GetRect();
@@ -776,6 +776,22 @@ void SmTableNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
             ExtendBy(rNodeRect, nSize > 1 ? RCP_NONE : RCP_ARG);
         }
     }
+    // --> 4.7.2010 #i972#
+    if (HasBaseline())
+        nFormulaBaseline = GetBaseline();
+    else
+    {
+        SmTmpDevice  aTmpDev ((OutputDevice &) rDev, TRUE);
+        aTmpDev.SetFont(GetFont());	
+
+        SmRect aRect = (SmRect(aTmpDev, &rFormat, C2S("a"),
+                               GetFont().GetBorderWidth()));
+        nFormulaBaseline = GetAlignM();
+        // move from middle position by constant - distance
+        // between middle and baseline for single letter
+        nFormulaBaseline+= aRect.GetBaseline() - aRect.GetAlignM();
+    }
+    // <--
 }
 
 
@@ -815,27 +831,33 @@ void SmLineNode::Arrange(const OutputDevice &rDev, const SmFormat &rFormat)
     SmTmpDevice  aTmpDev ((OutputDevice &) rDev, TRUE);
     aTmpDev.SetFont(GetFont());
 
-    // provide an empty rectangle with alignment parameters for the "current"
-    // font (in order to make "a^1 {}_2^3 a_4" work correct, that is, have the
-    // same sub-/supscript positions.)
-    //! be sure to use a character that has explicitly defined HiAttribut
-    //! line in rect.cxx such as 'a' in order to make 'vec a' look same to
-    //! 'vec {a}'.
-    SmRect::operator = (SmRect(aTmpDev, &rFormat, C2S("a"),
-                               GetFont().GetBorderWidth()));
-    // make sure that the rectangle occupies (almost) no space
-    SetWidth(1);
-    SetItalicSpaces(0, 0);
-
     if (nSize < 1)
+    { 
+        // provide an empty rectangle with alignment parameters for the "current"
+        // font (in order to make "a^1 {}_2^3 a_4" work correct, that is, have the
+        // same sub-/supscript positions.)
+        //! be sure to use a character that has explicitly defined HiAttribut
+        //! line in rect.cxx such as 'a' in order to make 'vec a' look same to
+        //! 'vec {a}'.
+        SmRect::operator = (SmRect(aTmpDev, &rFormat, C2S("a"),
+                                   GetFont().GetBorderWidth()));
+        // make sure that the rectangle occupies (almost) no space
+        SetWidth(1);
+        SetItalicSpaces(0, 0);
         return;
+    }
+
 
     // make distance depend on font size
     long  nDist = +(rFormat.GetDistance(DIS_HORIZONTAL)
                     * GetFont().GetSize().Height()) / 100L;
 
     Point   aPos;
-    for (i = 0;  i < nSize;  i++)
+    // copy the first node into LineNode and extend by the others
+    if (NULL != (pNode = GetSubNode(0)))
+        SmRect::operator = (pNode->GetRect());
+
+    for (i = 1;  i < nSize;  i++)
         if (NULL != (pNode = GetSubNode(i)))
         {
             aPos = pNode->AlignTo(*this, RP_RIGHT, RHA_CENTER, RVA_BASELINE);
diff --git a/starmath/source/unomodel.cxx b/starmath/source/unomodel.cxx
index ea2bcb4..6e49687 100644
--- a/starmath/source/unomodel.cxx
+++ b/starmath/source/unomodel.cxx
@@ -146,7 +146,8 @@ enum SmModelPropertyHandles
     // --> PB 2004-08-25 #i33095# Security Options
     HANDLE_LOAD_READONLY,
     // <--
-    HANDLE_DIALOG_LIBRARIES     // #i73329#
+    HANDLE_DIALOG_LIBRARIES,     // #i73329#
+    HANDLE_BASELINE // 3.7.2010 #i972#
 };
 
 PropertySetInfo * lcl_createModelPropertyInfo ()
@@ -217,6 +218,9 @@ PropertySetInfo * lcl_createModelPropertyInfo ()
         // --> PB 2004-08-25 #i33095# Security Options
         { RTL_CONSTASCII_STRINGPARAM( "LoadReadonly" ), HANDLE_LOAD_READONLY, &::getBooleanCppuType(), PROPERTY_NONE, 0 },
         // <--
+        // --> 3.7.2010 #i972#
+        { RTL_CONSTASCII_STRINGPARAM( "BaseLine"), HANDLE_BASELINE, &::getCppuType((const sal_Int16*)0), PROPERTY_NONE, 0},
+        // <--
         { NULL, 0, 0, NULL, 0, 0 }
     };
     PropertySetInfo *pInfo = new PropertySetInfo ( aModelPropertyInfoMap );
@@ -844,6 +848,21 @@ void SmModel::_getPropertyValues( const PropertyMapEntry **ppEntries, Any *pValu
                 break;
             }
             // <--
+            // --> 3.7.2010 #i972#
+            case HANDLE_BASELINE:
+            {
+                if ( !pDocSh->pTree )
+                    pDocSh->Parse();
+                if ( pDocSh->pTree )
+                {
+                    if ( !pDocSh->IsFormulaArranged() )
+                        pDocSh->ArrangeFormula();
+                    
+                    *pValue <<= static_cast<sal_Int32>( pDocSh->pTree->GetFormulaBaseline() );
+                }
+            }
+            break;
+            // <--
         }
     }
 }
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index c352cc7..29542a6 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -933,6 +933,9 @@ public:
     // character attribut dialog.
     USHORT GetScalingOfSelectedText() const;
 
+    // changes height of formulas in selection (used when height of text is changed)
+    void ChangeFormulaInSelFontSize( const SvxFontHeightItem *pHItem ) const;
+
     // ctor/dtor
     SwEditShell( SwDoc&, Window*, const SwViewOption *pOpt = 0 );
     // verkleideter Copy-Constructor
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 0318f99..7fafbca 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -543,6 +543,18 @@ public:
 
     BOOL ReplaceSdrObj( const String& rGrfName, const String& rFltName,
                         const Graphic* pGrf = 0 );
+    // --> #i972#
+    // Sets the format of the object to be aligned baseline to baseline
+    // for starmath formulas aligned as character.
+    // only set the SwFrmFmt if SwFlyFrm for the object doesn't exist yet
+    void AlignFormula( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj , SwFrmFmt* pFrmFmt = 0 );
+    // bSetAnchor determines whether the anchor is to be set to 'as char'
+    // then for starmath formulas anchored 'as char' it alignes it baseline to baseline
+    // changing the previous vertical orientation
+    void AlignFormulaToBaseline( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj , bool bSetAnchor = FALSE );
+    // aligns all formulas with anchor 'as char' to baseline
+    void AlignAllFormulasToBaseline();
+    // <--
 
 //------------------------------------------
 
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index e3074e4..9ff19de 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -149,7 +149,8 @@ public:
     // --> OD 2009-03-05 #i99665#
     bool IsChart() const;
     // <--
-
+    //Gets the position of Ole Object in the text node it lies in
+    const SwPosition* GetOlePosInTxtNode() const;
 #ifndef _FESHVIEW_ONLY_INLINE_NEEDED
     const String& GetChartTblName() const 		{ return sChartTblName; }
     void SetChartTblName( const String& rNm ) 	{ sChartTblName = rNm; }
diff --git a/sw/inc/pam.hxx b/sw/inc/pam.hxx
index 3227b89..4e71ccb 100644
--- a/sw/inc/pam.hxx
+++ b/sw/inc/pam.hxx
@@ -259,7 +259,7 @@ public:
     // etwas geschuetztes.
     BOOL HasReadonlySel( bool bFormView ) const;
 
-    BOOL ContainsPosition(const SwPosition & rPos)
+    BOOL ContainsPosition(const SwPosition & rPos) const
     { return *Start() <= rPos && rPos <= *End(); }
 
     static BOOL Overlap(const SwPaM & a, const SwPaM & b);
diff --git a/sw/inc/swcli.hxx b/sw/inc/swcli.hxx
index d4fe338..23fa501 100644
--- a/sw/inc/swcli.hxx
+++ b/sw/inc/swcli.hxx
@@ -53,6 +53,8 @@ public:
     void SetInDoVerb( BOOL bFlag )				{ bInDoVerb = bFlag; }
 
     BOOL IsCheckForOLEInCaption() const			{ return bOldCheckForOLEInCaption; }
+    
+    virtual void FormatChanged();
 };
 
 #endif
diff --git a/sw/source/core/doc/poolfmt.cxx b/sw/source/core/doc/poolfmt.cxx
index 5c85192..8032913 100644
--- a/sw/source/core/doc/poolfmt.cxx
+++ b/sw/source/core/doc/poolfmt.cxx
@@ -1336,7 +1336,7 @@ SwFmt* SwDoc::GetFmtFromPool( USHORT nId )
     case RES_POOLFRM_FORMEL:
         {
             aSet.Put( SwFmtAnchor( FLY_IN_CNTNT ) );
-            aSet.Put( SwFmtVertOrient( 0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::FRAME ) );
+            aSet.Put( SwFmtVertOrient( 0, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
             aSet.Put( SvxLRSpaceItem( 114, 114, 0, 0, RES_LR_SPACE ) );
         }
         break;
diff --git a/sw/source/core/edit/edatmisc.cxx b/sw/source/core/edit/edatmisc.cxx
index ce48d9f..ffed18d 100644
--- a/sw/source/core/edit/edatmisc.cxx
+++ b/sw/source/core/edit/edatmisc.cxx
@@ -36,7 +36,12 @@
 #include <swundo.hxx>   // fuer die UndoIds
 #include <ndtxt.hxx>    // fuer Get-/ChgFmt Set-/GetAttrXXX
 
+#include <svx/fhgtitem.hxx>
+#include <hintids.hxx>
+#include <ndole.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
 
+using namespace com::sun::star;
 
 /*************************************
  * harte Formatierung (Attribute)
@@ -159,6 +164,15 @@ void SwEditShell::SetAttr( const SfxItemSet& rSet, USHORT nFlags )
 {
     SET_CURR_SHELL( this );
     StartAllAction();
+    // -->
+    //when changing text font-size, Math formulas should be informed
+    USHORT nWhich = RES_CHRATR_FONTSIZE;
+    if  ( rSet.GetItemState( nWhich ) == SFX_ITEM_SET )
+    {
+        const SvxFontHeightItem *pItem = dynamic_cast< const SvxFontHeightItem* >( &rSet.Get( nWhich ));
+        ChangeFormulaInSelFontSize( pItem );
+    }
+    // <--
     SwPaM* pCrsr = GetCrsr();
     if( pCrsr->GetNext() != pCrsr ) 	// Ring von Cursorn
     {
@@ -184,6 +198,50 @@ void SwEditShell::SetAttr( const SfxItemSet& rSet, USHORT nFlags )
     EndAllAction();
 }
 
+void SwEditShell::ChangeFormulaInSelFontSize( const SvxFontHeightItem *pHItem ) const
+{
+    if ( !pHItem )
+        return;
+    sal_Int32 nHeight =  pHItem->GetHeight();
+    SwStartNode *pStNd;
+    SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+    const SwPosition* pPos;
+
+    while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+    {
+        aIdx++;
+        SwNode& rNd = aIdx.GetNode();
+        if( rNd.IsOLENode()  )
+        {
+            pPos = (dynamic_cast<SwOLENode&>(rNd)).GetOlePosInTxtNode();
+            bool bInSelection = false;
 
+            FOREACHPAM_START( this )
+                if ( pPos && PCURCRSR && PCURCRSR->ContainsPosition( *pPos ) )
+                    bInSelection = true;
+            FOREACHPAM_END()
 
+            if( bInSelection )
+            {
+                uno::Reference < embed::XEmbeddedObject > xObj = (dynamic_cast<SwOLENode&>(rNd)).GetOLEObj().GetOleRef();
+                if ( xObj.is() && svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+                {
+                    uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+                    if ( xSet.is() )
+                    {
+                        try
+                        {
+                            sal_Int16 nVal = nHeight / 20; //was in twips SmModel::_setPropertyValue changes it back
+                            xSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BaseFontHeight") ), uno::makeAny( nVal ) );
+                        }
+                        catch ( uno::Exception& )
+                        {
+                        }
+                    }
+                }
+            }
+        }
+        aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+    }
+}
 
diff --git a/sw/source/core/edit/makefile.mk b/sw/source/core/edit/makefile.mk
index 07904b7..828b1d1 100644
--- a/sw/source/core/edit/makefile.mk
+++ b/sw/source/core/edit/makefile.mk
@@ -44,13 +44,13 @@ EXCEPTIONSFILES=\
         $(SLO)$/eddel.obj \
         $(SLO)$/edlingu.obj \
         $(SLO)$/edfldexp.obj \
+        $(SLO)$/edatmisc.obj \
         $(SLO)$/edtab.obj
 
 SLOFILES =	\
         $(EXCEPTIONSFILES)\
         $(SLO)$/acorrect.obj \
         $(SLO)$/autofmt.obj \
-        $(SLO)$/edatmisc.obj \
         $(SLO)$/edattr.obj \
         $(SLO)$/edfcol.obj \
         $(SLO)$/edfld.obj \
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index 1458463..ed859cf 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -72,9 +72,10 @@
 // --> OD 2006-03-06 #125892#
 #include <HandleAnchorNodeChg.hxx>
 // <--
-
 #include <frmatr.hxx>
-
+// --> #i972#
+#include <ndole.hxx>
+// <--
 
 using ::rtl::OUString;
 using namespace ::com::sun::star;
@@ -1523,6 +1524,9 @@ Size SwFEShell::RequestObjectResize( const SwRect &rRect, const uno::Reference <
             pFly->ChgRelPos( aTmp );
         }
     }
+
+    pFly->SetLastFlyFrmPrtRectPos( pFly->Prt().Pos() ); //stores the value of last Prt rect
+
     EndAllAction();
 
     return aResult;
@@ -2161,3 +2165,137 @@ void SwFEShell::SetObjDescription( const String& rDescription )
     }
 }
 // <--
+// --> 8.7.2010 #i972#
+void SwFEShell::AlignFormula( const uno::Reference < embed::XEmbeddedObject >& xObj , SwFrmFmt* pFrmFmt )
+{
+    SvGlobalName aCLSID( xObj->getClassID() );
+    BOOL bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
+
+    if (bStarMath) //check the object is formula
+    {
+        SwFlyFrm *pFly = 0;
+
+        if ( !pFrmFmt ) //find format if it was not given
+        {
+            pFly = FindFlyFrm( xObj );
+            if ( !pFly )
+            {
+                ASSERT( pFly , "No fly frame!" );
+                return;
+            }
+            pFrmFmt = pFly->GetFmt();
+        }
+
+        if (pFrmFmt)
+        {
+            if (FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId()) // check the anchor is AsChar
+            {
+                uno::Any aBaseline;  
+
+                if( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+                {
+                    uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+                    if ( xSet.is() )
+                    {
+                        try
+                        {
+                            aBaseline = xSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BaseLine") ) );
+                        }
+                        catch ( uno::Exception& )
+                        {
+                            ASSERT( FALSE , "Baseline could not be retrieved from Starmath!" );
+                        }
+                    }
+                }
+
+                sal_Int32 nBaseline = ::comphelper::getINT32(aBaseline);
+                const MapMode aSourceMapMode( MAP_100TH_MM );
+                const MapMode aTargetMapMode( MAP_TWIP );
+                nBaseline = OutputDevice::LogicToLogic( nBaseline, aSourceMapMode.GetMapUnit(), aTargetMapMode.GetMapUnit() );
+
+                ASSERT( (nBaseline > 0) , "Wrong value of Baseline while retrieving from Starmath!" );
+                //nBaseline must be moved by aPrt position
+                if ( pFly )
+                    nBaseline += pFly->GetLastFlyFrmPrtRectPos().Y();
+
+                const SwFmtVertOrient &rVert = pFrmFmt->GetVertOrient();
+                SwFmtVertOrient aVert( rVert );
+                aVert.SetPos( -nBaseline );
+
+                pFrmFmt->LockModify();
+                pFrmFmt->SetFmtAttr( aVert );
+                pFrmFmt->UnlockModify();
+                if  ( pFly )
+                    pFly->InvalidatePos();
+            }
+        }
+    }
+}
+
+void SwFEShell::AlignFormulaToBaseline( const uno::Reference < embed::XEmbeddedObject >& xObj , bool bSetAnchor )
+{
+    SvGlobalName aCLSID( xObj->getClassID() );
+    BOOL bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
+
+    if ( bStarMath )
+    {
+        SwFlyFrm *pFly = FindFlyFrm( xObj );
+        if ( !pFly )
+        {
+            ASSERT( pFly , "No fly frame!" );
+            return;
+        }
+
+        SwFrmFmt *pFmt = pFly->GetFmt();
+        if ( pFmt )
+        {
+            if ( bSetAnchor )
+            {
+                const SwFmtAnchor &rAnchor = pFmt->GetAnchor();
+                SwFmtAnchor aAnchor( rAnchor );
+                aAnchor.SetType( FLY_IN_CNTNT );
+                pFmt->LockModify();
+                pFmt->SetFmtAttr( aAnchor );
+                pFmt->UnlockModify();	 
+            }
+
+            if ( FLY_IN_CNTNT == pFmt->GetAnchor().GetAnchorId() )
+            {
+                const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
+                SwFmtVertOrient aVert( rVert );
+                aVert.SetVertOrient( com::sun::star::text::VertOrientation::NONE );
+                pFmt->LockModify();
+                pFmt->SetFmtAttr( aVert );
+                pFmt->UnlockModify();
+
+                AlignFormula( xObj );
+            }
+        }
+    }
+}
+
+void SwFEShell::AlignAllFormulasToBaseline()
+{
+    StartAllAction();
+
+    SwStartNode *pStNd;
+    SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+    while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
+    {
+        aIdx++;
+        SwNode& rNd = aIdx.GetNode();
+        if( rNd.IsOLENode() )
+        {
+            const uno::Reference < embed::XEmbeddedObject >& xObj = (dynamic_cast<SwOLENode&>(rNd)).GetOLEObj().GetOleRef();
+            SvGlobalName aCLSID( xObj->getClassID() );
+            if ( SotExchange::IsMath( aCLSID ) )
+                AlignFormulaToBaseline( xObj );
+        }
+
+        aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
+    }
+
+    EndAllAction();
+}
+//<--
+
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index f698ff4..0402344 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -77,6 +77,9 @@ protected:
 
     // OD 2004-05-27 #i26791# - moved to <SwAnchoredObject>
 //    Point aRelPos;   //Die Relative Position zum Master
+    Point aLastFlyFrmPrtRectPos; // it stores the previous position of Prt rectangle from RequestObjectResize
+                                 // so it can be used to move frames of non-resizable objects to align them correctly
+                                 // when they get borders (this is done in SwWrtShell::CalcAndGetScale)
 
 private:
     BOOL bLocked	:1;	//Cntnt-gebundene Flys muessen derart blockiert werden
@@ -283,5 +286,9 @@ public:
         @author OD
     */
     virtual bool IsFormatPossible() const;
+        
+    const Point GetLastFlyFrmPrtRectPos() const { return aLastFlyFrmPrtRectPos; }
+    void SetLastFlyFrmPrtRectPos( Point aPoint ) { aLastFlyFrmPrtRectPos = aPoint; }
+    
 };
 #endif
diff --git a/sw/source/core/inc/flyfrms.hxx b/sw/source/core/inc/flyfrms.hxx
index 10791a4..6c3d18f 100644
--- a/sw/source/core/inc/flyfrms.hxx
+++ b/sw/source/core/inc/flyfrms.hxx
@@ -188,6 +188,7 @@ class SwFlyInCntFrm : public SwFlyFrm
 
     BOOL bInvalidLayout :1;
     BOOL bInvalidCntnt	:1;
+    bool bPosCalculated :1;
 
 protected:
     virtual void NotifyBackground( SwPageFrm *pPage,
@@ -237,6 +238,8 @@ public:
     // format of the anchor frame
     virtual void _ActionOnInvalidation( const InvalidationType _nInvalid );
     // <--
+
+    void SetPosCalculated( bool bNew ) { bPosCalculated = bNew; }
 };
 
 inline void SwFlyInCntFrm::InvalidateLayout() const
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 127bc24..ac192d1 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -121,6 +121,7 @@ SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
 //    aRelPos(),
     pPrevLink( 0 ),
     pNextLink( 0 ),
+    aLastFlyFrmPrtRectPos( Point(0,0) ),
     bInCnt( FALSE ),
     bAtCnt( FALSE ),
     bLayout( FALSE ),
diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx
index c724779..26a4252 100644
--- a/sw/source/core/layout/flyincnt.cxx
+++ b/sw/source/core/layout/flyincnt.cxx
@@ -56,6 +56,7 @@ SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
     SwFlyFrm( pFmt, pAnch )
 {
     bInCnt = bInvalidLayout = bInvalidCntnt = TRUE;
+    bPosCalculated = FALSE;
     SwTwips nRel = pFmt->GetVertOrient().GetPos();
     // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
     Point aRelPos;
@@ -203,6 +204,11 @@ void SwFlyInCntFrm::MakeObjPos()
     if ( !bValidPos )
     {
         bValidPos = TRUE;
+        // --> let the position be set, only if it was calculated in
+        // SwAsCharAnchoredObjectPosition::CalcPosition
+        if ( !bPosCalculated )
+            return;
+        // <--
         SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
         const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
         //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
diff --git a/sw/source/core/objectpositioning/ascharanchoredobjectposition.cxx b/sw/source/core/objectpositioning/ascharanchoredobjectposition.cxx
index 835ff3b..1ae7981 100644
--- a/sw/source/core/objectpositioning/ascharanchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/ascharanchoredobjectposition.cxx
@@ -328,7 +328,11 @@ void SwAsCharAnchoredObjectPosition::CalcPosition()
         {
             // set new anchor position and relative position
             SwFlyInCntFrm* pFlyInCntFrm = &(const_cast<SwFlyInCntFrm&>(rFlyInCntFrm));
+            // --> let SwFlyInCnt::MakeObjPos set position only at this place using bPosCalculated
+            pFlyInCntFrm->SetPosCalculated( TRUE );
             pFlyInCntFrm->SetRefPoint( aAnchorPos, aRelAttr, aRelPos );
+            pFlyInCntFrm->SetPosCalculated( FALSE );
+            // <--
             if( nObjWidth != (pFlyInCntFrm->Frm().*fnRect->fnGetWidth)() )
             {
                 // recalculate object bound rectangle, if object width has changed.
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index ccb2d9e..64961db 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -71,6 +71,7 @@
 #ifndef _COMCORE_HRC
 #include <comcore.hrc>
 #endif
+#include <layfrm.hxx>
 
 using rtl::OUString;
 using namespace utl;
@@ -657,6 +658,24 @@ bool SwOLENode::IsChart() const
 }
 // <--
 
+const SwPosition* SwOLENode::GetOlePosInTxtNode() const
+{
+    const SwCntntFrm* pCntntFrm = GetFrm();
+    if ( pCntntFrm )
+    {
+        const SwLayoutFrm *pLayoutFrm = pCntntFrm->GetUpper();
+        if ( pLayoutFrm )
+        {
+            const SwFrmFmt *pFrmFmt = pLayoutFrm->GetFmt();
+            if ( pFrmFmt )
+            {
+                return ( pFrmFmt->GetAnchor().GetCntntAnchor() );
+            }
+        }
+    }
+    return 0;
+}
+
 SwOLEObj::SwOLEObj( const svt::EmbeddedObjectRef& xObj ) :
     pOLENd( 0 ),
     pListener( 0 ),
diff --git a/sw/source/ui/uiview/swcli.cxx b/sw/source/ui/uiview/swcli.cxx
index f6415e4..b6890fd 100644
--- a/sw/source/ui/uiview/swcli.cxx
+++ b/sw/source/ui/uiview/swcli.cxx
@@ -169,3 +169,17 @@ void SwOleClient::MakeVisible()
     const SwWrtShell &rSh  = ((SwView*)GetViewShell())->GetWrtShell();
     rSh.MakeObjVisible( GetObject() );
 }
+
+void SwOleClient::FormatChanged()
+{
+    // --> #i972#
+    const uno::Reference < embed::XEmbeddedObject >& xObj = GetObject();
+
+    SvGlobalName aCLSID( xObj->getClassID() );
+    if ( SotExchange::IsMath( aCLSID ) )
+    {
+        SwWrtShell &rSh = ( dynamic_cast<SwView*>( GetViewShell() ) )->GetWrtShell();
+        rSh.AlignFormula( xObj );
+    }
+    // <--
+}
diff --git a/sw/source/ui/wrtsh/makefile.mk b/sw/source/ui/wrtsh/makefile.mk
index 66de5cb..7a79ed2 100644
--- a/sw/source/ui/wrtsh/makefile.mk
+++ b/sw/source/ui/wrtsh/makefile.mk
@@ -36,6 +36,8 @@ TARGET=wrtsh
 .INCLUDE :  settings.mk
 .INCLUDE :  $(PRJ)$/inc$/sw.mk
 
+INCPRE+=$(PRJ)$/source$/core$/inc
+
 # --- Files --------------------------------------------------------
 
 SRS1NAME=$(TARGET)
diff --git a/sw/source/ui/wrtsh/wrtsh1.cxx b/sw/source/ui/wrtsh/wrtsh1.cxx
index a7cd77a..d1f8514 100644
--- a/sw/source/ui/wrtsh/wrtsh1.cxx
+++ b/sw/source/ui/wrtsh/wrtsh1.cxx
@@ -124,6 +124,10 @@
 
 #include "PostItMgr.hxx"
 
+#include <flyfrm.hxx>
+#include <svx/fhgtitem.hxx>
+#include <ndole.hxx>
+
 using namespace sw::mark;
 using namespace com::sun::star;
 
@@ -493,7 +497,8 @@ void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef& xRef, SvGlobalName
 
         if ( xObj.is() )
         {
-            if( InsertOleObject( xObj ) && bActivate && bDoVerb )
+            BOOL bActivate2 = InsertOleObject( xObj );
+            if( bActivate && bDoVerb )
             {
                 SfxInPlaceClient* pClient = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() );
                 if ( !pClient )
@@ -517,7 +522,8 @@ void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef& xRef, SvGlobalName
 
                 //#50270# Error brauchen wir nicht handeln, das erledigt das
                 //DoVerb in der SfxViewShell
-                pClient->DoVerb( SVVERB_SHOW );
+                if ( bActivate2 )
+                    pClient->DoVerb( SVVERB_SHOW );
 
                 // TODO/LATER: set document name - should be done in Client
                 //if ( !ERRCODE_TOERROR( nErr ) )
@@ -614,6 +620,44 @@ BOOL SwWrtShell::InsertOleObject( const svt::EmbeddedObjectRef& xRef, SwFlyFrmFm
     aFrmMgr.SetSize( aSz );
     SwFlyFrmFmt *pFmt = SwFEShell::InsertObject( xRef, &aFrmMgr.GetAttrSet() );
 
+    // --> #i972#
+    if ( bStarMath ) //sets font-hight and baseline
+    {
+        const SwNode &rNd = *GetCrsr()->GetNode();
+        if ( rNd.IsOLENode() )
+        {
+            const SwPosition *pPos = (dynamic_cast<const SwOLENode&>(rNd)).GetOlePosInTxtNode();
+            const SwNode &rNode = pPos->nNode.GetNode();
+            const SwIndex &rIdx = pPos->nContent;
+            if( rNode.IsTxtNode() )
+            {
+                SfxItemSet aSet( pDoc->GetAttrPool() , RES_CHRATR_BEGIN, RES_CHRATR_END );
+                if ( ((SwTxtNode&)rNode).GetAttr(aSet, rIdx.GetIndex(), rIdx.GetIndex()) )
+                {
+                    sal_Int32 nHeight = ( dynamic_cast<const SvxFontHeightItem&>( aSet.Get( RES_CHRATR_FONTSIZE) ) ).GetHeight();
+                    uno::Reference < embed::XEmbeddedObject > xObj = xRef.GetObject();
+                    if ( xObj.is() && svt::EmbeddedObjectRef::TryRunningState( xObj ) )
+                    {
+                        uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
+                        if ( xSet.is() )
+                        {
+                            try
+                            {
+                                sal_Int16 nVal = nHeight / 20;
+                                xSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BaseFontHeight") ), uno::makeAny( nVal ) );
+                            }
+                            catch ( uno::Exception& )
+                            {
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        AlignFormula( xRef.GetObject() , pFmt );
+    }
+    // <--
+
     if (pFlyFrmFmt)
         *pFlyFrmFmt = pFmt;
 
@@ -774,6 +818,8 @@ void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,
         if ( (embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY & nMisc) || bLinkingChart
             // TODO/LATER: ResizeOnPrinterChange
              //|| SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE & xObj->GetMiscStatus()
+             || nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE // non-resizable objects need to be
+                                                            // set the size back by this method
              )
         {
             pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
@@ -884,6 +930,21 @@ void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,
 
     if ( bUseObjectSize )
     {
+        // --> this moves non-resizable object so that when adding borders the baseline remains the same 
+        const SwFlyFrm *pFly = GetCurrFlyFrm();
+        if ( pFly )
+        {
+            const Point aPoint = pFly->GetLastFlyFrmPrtRectPos();
+            SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
+                        : GetAnyCurRect( RECT_FLY_PRT_EMBEDDED, 0, xObj.GetObject() ));
+            aArea += aPoint - aRect.Pos();
+        }
+        else
+        {
+            ASSERT( false , "Could not find fly frame." );
+        }
+        // <--
+        
         aArea.Width ( _aVisArea.Width() );
         aArea.Height( _aVisArea.Height() );
         RequestObjectResize( aArea, xObj.GetObject() );