diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2009-06-17 10:58:14 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2009-06-17 10:58:14 +0000 |
commit | 09616816855320394fe9d2bf4dc2a949296dc80f (patch) | |
tree | dce11dca85d86c03f0a64be0fcab3e1c5ee091ee /svx | |
parent | b49ac08f3b5f9474f606bb76f9256d2a9aa1a522 (diff) |
CWS-TOOLING: integrate CWS impress171
2009-06-02 16:32:02 +0200 cl r272511 : fixed build error
2009-05-29 16:40:09 +0200 cl r272471 : CWS-TOOLING: rebase CWS impress171 to trunk@272291 (milestone: DEV300:m49)
2009-05-19 15:14:08 +0200 sj r272082 : #i101459# applied patch (writing out StyleTextProperties even if no chars given)
2009-05-19 15:09:31 +0200 sj r272081 : #i101459# applied patch (writing out StyleTextProperties even if no chars given)
2009-05-19 15:09:14 +0200 sj r272080 : #i101459# applied patch (writing out StyleTextProperties even if no chars given)
2009-05-18 13:34:05 +0200 sj r272015 : #i47689# fixed rectangles toolbar
2009-05-13 14:59:08 +0200 sj r271862 : #i101563# fixed crash when loading pptx document
2009-05-12 19:31:58 +0200 sj r271835 : #101684# fixed rotation of customshapes
2009-05-08 16:37:01 +0200 sj r271724 : #i101683,i101584,i48160# added shearing of customshapes, fixed rotation problem
2009-04-28 17:32:14 +0200 sj r271335 : #i48160# fixed gluepoint rotation of customshapes
2009-04-27 16:31:54 +0200 cl r271291 : #i100138# applied patch for japanese reconversion feature
2009-04-27 16:30:52 +0200 cl r271290 : #i100138# applied patch for japanese reconversion feature
2009-04-27 16:28:55 +0200 cl r271289 : #i100138# applied patch for japanese reconversion feature
2009-04-23 14:22:59 +0200 cl r271170 : #i95342# #i96820# #i97298# multiple table handling fixes
2009-04-23 14:18:54 +0200 sj r271169 : #i60368# ignoring gamma values for toolbar/menu icons
2009-04-23 11:54:28 +0200 cl r271146 : #i97298# set style to text even during text edit
2009-04-23 11:46:38 +0200 cl r271145 : fixed compiler error with debug
2009-04-22 19:09:37 +0200 sj r271135 : #i101051# applied patch (proper import of notes page object)
2009-04-22 11:07:54 +0200 cl r271082 : #i96820# modify doc after merging cells
2009-04-22 10:57:35 +0200 cl r271081 : #i100307# applied patch from jlcheng to correctly set modfiy state
2009-04-22 10:31:11 +0200 cl r271079 : #i96736# copy merge information on clone
2009-04-21 08:27:22 +0200 cl r271016 : #i89541# use SfxErrorContext to make the ErrorHandler dialog modal
2009-04-20 17:52:56 +0200 cl r271003 : #i98480# removed 'EndPosition' and 'StartPosition' from styles
2009-04-20 16:41:55 +0200 cl r270994 : #i98403# fixed state handling for selected motion path
2009-04-17 11:35:25 +0200 cl r270931 : #i61274# export to pdf should behave like printing considering layer visibility
2009-04-17 10:00:17 +0200 cl r270924 : #i98967# set default style on any new shape except a page obj
2009-04-16 16:28:20 +0200 cl r270893 : #i98859# use percentage type for relative font height
Diffstat (limited to 'svx')
-rw-r--r-- | svx/inc/svx/editview.hxx | 4 | ||||
-rw-r--r-- | svx/inc/svx/outliner.hxx | 3 | ||||
-rw-r--r-- | svx/inc/svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx | 3 | ||||
-rw-r--r-- | svx/inc/svx/svdfppt.hxx | 12 | ||||
-rw-r--r-- | svx/inc/svx/svdoashp.hxx | 2 | ||||
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShape2d.cxx | 35 | ||||
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShapeEngine.cxx | 32 | ||||
-rw-r--r-- | svx/source/dialog/imapdlg.cxx | 5 | ||||
-rw-r--r-- | svx/source/editeng/editview.cxx | 51 | ||||
-rw-r--r-- | svx/source/editeng/impedit2.cxx | 38 | ||||
-rw-r--r-- | svx/source/outliner/outlvw.cxx | 12 | ||||
-rw-r--r-- | svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx | 103 | ||||
-rw-r--r-- | svx/source/sdr/properties/textproperties.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdfppt.cxx | 493 | ||||
-rw-r--r-- | svx/source/svdraw/svdoashp.cxx | 119 | ||||
-rw-r--r-- | svx/source/table/cell.cxx | 5 | ||||
-rw-r--r-- | svx/source/table/cellcursor.cxx | 71 | ||||
-rw-r--r-- | svx/source/table/cellcursor.hxx | 2 | ||||
-rw-r--r-- | svx/source/table/tablelayouter.cxx | 134 | ||||
-rw-r--r-- | svx/source/table/tablemodel.cxx | 118 | ||||
-rw-r--r-- | svx/source/table/tablemodel.hxx | 3 |
21 files changed, 847 insertions, 400 deletions
diff --git a/svx/inc/svx/editview.hxx b/svx/inc/svx/editview.hxx index c7c9bd975428..79deaab4dc36 100644 --- a/svx/inc/svx/editview.hxx +++ b/svx/inc/svx/editview.hxx @@ -34,6 +34,7 @@ #include <rsc/rscsfx.hxx> #include <i18npool/lang.h> #include <tools/color.hxx> +#include <tools/gen.hxx> class EditEngine; class ImpEditEngine; @@ -242,6 +243,9 @@ public: void ChangeFontSize( bool bGrow, const FontList* pList ); static bool ChangeFontSize( bool bGrow, SfxItemSet& rSet, const FontList* pFontList ); + + String GetSurroundingText() const;
+ Selection GetSurroundingTextSelection() const; }; #endif // _MyEDITVIEW_HXX diff --git a/svx/inc/svx/outliner.hxx b/svx/inc/svx/outliner.hxx index 7b9b8c80708a..37e3d8ac71ee 100644 --- a/svx/inc/svx/outliner.hxx +++ b/svx/inc/svx/outliner.hxx @@ -387,6 +387,9 @@ public: void SetInvalidateMore( USHORT nPixel ); USHORT GetInvalidateMore() const; + + String GetSurroundingText() const;
+ Selection GetSurroundingTextSelection() const; }; //#if 0 // _SOLAR__PRIVATE diff --git a/svx/inc/svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx b/svx/inc/svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx index f9f19ba687bc..f1b515e8a198 100644 --- a/svx/inc/svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx +++ b/svx/inc/svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx @@ -53,6 +53,9 @@ namespace sdr return (SdrObjCustomShape&)GetSdrObject(); } + // #i101684# internal tooling + basegfx::B2DRange getCorrectedTextBoundRect() const; + public: // basic constructor, used from SdrObject. ViewContactOfSdrObjCustomShape(SdrObjCustomShape& rCustomShape); diff --git a/svx/inc/svx/svdfppt.hxx b/svx/inc/svx/svdfppt.hxx index 40c851d1c949..5a73bea5052f 100644 --- a/svx/inc/svx/svdfppt.hxx +++ b/svx/inc/svx/svdfppt.hxx @@ -989,6 +989,18 @@ struct PPTStyleTextPropReader PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImport&, const DffRecordHeader& rClientTextBoxHd, PPTTextRulerInterpreter& rInterpreter, const DffRecordHeader& rExtParaHd, sal_uInt32 nTextInstance ); + void Init( SvStream& rIn, SdrPowerPointImport&, const DffRecordHeader& rClientTextBoxHd, + PPTTextRulerInterpreter& rInterpreter, const DffRecordHeader& rExtParaHd, sal_uInt32 nTextInstance ); + void ReadParaProps( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader, + const String& aString, PPTTextRulerInterpreter& rRuler, + sal_uInt32& nCharCount, sal_Bool& bTextPropAtom ); + void ReadCharProps( SvStream& rIn, PPTCharPropSet& aCharPropSet, const String& aString, + sal_uInt32& nCharCount, sal_uInt32 nCharAnzRead, + sal_Bool& bTextPropAtom, sal_uInt32 nExtParaPos, + const std::vector< StyleTextProp9 >& aStyleTextProp9, + sal_uInt32& nExtParaFlags, sal_uInt16& nBuBlip, + sal_uInt16& nHasAnm, sal_uInt32& nAnmScheme ); + ~PPTStyleTextPropReader(); }; diff --git a/svx/inc/svx/svdoashp.hxx b/svx/inc/svx/svdoashp.hxx index a75c064e35ad..c1579cd583fe 100644 --- a/svx/inc/svx/svdoashp.hxx +++ b/svx/inc/svx/svdoashp.hxx @@ -199,6 +199,8 @@ public: virtual void NbcSetSnapRect(const Rectangle& rRect); virtual void NbcSetLogicRect(const Rectangle& rRect); + virtual SdrGluePoint GetVertexGluePoint(USHORT nNum) const; + virtual void NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr ); // special drag methods diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx index e4b2d1da1a0d..fb95a5bfbb15 100644 --- a/svx/source/customshapes/EnhancedCustomShape2d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx @@ -1152,6 +1152,14 @@ sal_Bool EnhancedCustomShape2d::GetHandlePosition( const sal_uInt32 nIndex, Poin } rReturnPosition = GetPoint( aHandle.aPosition, sal_True, sal_False ); } + const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() ); + if ( aGeoStat.nShearWink ) + { + double nTan = aGeoStat.nTan; + if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) + nTan = -nTan; + ShearPoint( rReturnPosition, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan ); + } if ( nRotateAngle ) { double a = nRotateAngle * F_PI18000; @@ -1193,6 +1201,15 @@ sal_Bool EnhancedCustomShape2d::SetHandleControllerPosition( const sal_uInt32 nI double a = -nRotateAngle * F_PI18000; RotatePoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), sin( a ), cos( a ) ); } + const GeoStat aGeoStat( ((SdrObjCustomShape*)pCustomShapeObj)->GetGeoStat() ); + if ( aGeoStat.nShearWink ) + { + double nTan = -aGeoStat.nTan; + if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) + nTan = -nTan; + ShearPoint( aP, Point( aLogicRect.GetWidth() / 2, aLogicRect.GetHeight() / 2 ), nTan ); + } + double fPos1 = aP.X(); //( bFlipH ) ? aLogicRect.GetWidth() - aP.X() : aP.X(); double fPos2 = aP.Y(); //( bFlipV ) ? aLogicRect.GetHeight() -aP.Y() : aP.Y(); fPos1 /= fXScale; @@ -2062,13 +2079,17 @@ void EnhancedCustomShape2d::ApplyGluePoints( SdrObject* pObj ) for ( i = 0; i < nCount; i++ ) { SdrGluePoint aGluePoint; - const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True ); - double fXRel = rPoint.X(); - double fYRel = rPoint.Y(); - fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000; - fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000; - aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) ); - aGluePoint.SetPercent( sal_True ); + + aGluePoint.SetPos( GetPoint( seqGluePoints[ i ], sal_True, sal_True ) ); + aGluePoint.SetPercent( sal_False ); + +// const Point& rPoint = GetPoint( seqGluePoints[ i ], sal_True, sal_True ); +// double fXRel = rPoint.X(); +// double fYRel = rPoint.Y(); +// fXRel = aLogicRect.GetWidth() == 0 ? 0.0 : fXRel / aLogicRect.GetWidth() * 10000; +// fYRel = aLogicRect.GetHeight() == 0 ? 0.0 : fYRel / aLogicRect.GetHeight() * 10000; +// aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) ); +// aGluePoint.SetPercent( sal_True ); aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT ); aGluePoint.SetEscDir( SDRESC_SMART ); SdrGluePointList* pList = pObj->ForceGluePointList(); diff --git a/svx/source/customshapes/EnhancedCustomShapeEngine.cxx b/svx/source/customshapes/EnhancedCustomShapeEngine.cxx index 0ac56ff21a43..8ae4e34197c5 100644 --- a/svx/source/customshapes/EnhancedCustomShapeEngine.cxx +++ b/svx/source/customshapes/EnhancedCustomShapeEngine.cxx @@ -307,6 +307,19 @@ REF( com::sun::star::drawing::XShape ) SAL_CALL EnhancedCustomShapeEngine::rende pRenderedShape = pRenderedShape3d; } Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); + + const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); + if ( rGeoStat.nShearWink ) + { + long nShearWink = rGeoStat.nShearWink; + double nTan = rGeoStat.nTan; + if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) + { + nShearWink = -nShearWink; + nTan = -nTan; + } + pRenderedShape->Shear( pSdrObjCustomShape->GetSnapRect().Center(), nShearWink, nTan, FALSE); + } if( nRotateAngle ) { double a = nRotateAngle * F_PI18000; @@ -374,19 +387,34 @@ com::sun::star::drawing::PolyPolygonBezierCoords SAL_CALL EnhancedCustomShapeEng if ( pObj ) { Rectangle aRect( pSdrObjCustomShape->GetSnapRect() ); + sal_Bool bFlipV = aCustomShape2d.IsFlipVert(); + sal_Bool bFlipH = aCustomShape2d.IsFlipHorz(); + + const GeoStat& rGeoStat = ((SdrObjCustomShape*)pSdrObjCustomShape)->GetGeoStat(); + if ( rGeoStat.nShearWink ) + { + long nShearWink = rGeoStat.nShearWink; + double nTan = rGeoStat.nTan; + if ((bFlipV&&!bFlipH )||(bFlipH&&!bFlipV)) + { + nShearWink = -nShearWink; + nTan = -nTan; + } + pObj->Shear( aRect.Center(), nShearWink, nTan, FALSE); + } sal_Int32 nRotateAngle = aCustomShape2d.GetRotateAngle(); if( nRotateAngle ) { double a = nRotateAngle * F_PI18000; pObj->NbcRotate( aRect.Center(), nRotateAngle, sin( a ), cos( a ) ); } - if ( aCustomShape2d.IsFlipHorz() ) + if ( bFlipH ) { Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() ); Point aBottom( aTop.X(), aTop.Y() + 1000 ); pObj->NbcMirror( aTop, aBottom ); } - if ( aCustomShape2d.IsFlipVert() ) + if ( bFlipV ) { Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 ); Point aRight( aLeft.X() + 1000, aLeft.Y() ); diff --git a/svx/source/dialog/imapdlg.cxx b/svx/source/dialog/imapdlg.cxx index 56fd8273fed2..5777dc8e7446 100644 --- a/svx/source/dialog/imapdlg.cxx +++ b/svx/source/dialog/imapdlg.cxx @@ -60,6 +60,8 @@ #include "com/sun/star/ui/dialogs/TemplateDescription.hpp" #include <svtools/urihelper.hxx> #include <svtools/miscopt.hxx> +#include <svtools/ehdl.hxx> +#include <svtools/sfxecode.hxx> #include <sfx2/viewfrm.hxx> #include <sfx2/objsh.hxx> #include <sfx2/docfile.hxx> @@ -654,7 +656,10 @@ void SvxIMapDlg::DoOpen() aLoadIMap.Read( *pIStm, IMAP_FORMAT_DETECT, String() ); if( pIStm->GetError() ) + { + SfxErrorContext eEC(ERRCODE_SFX_GENERAL,this); ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); + } else pIMapWnd->SetImageMap( aLoadIMap ); diff --git a/svx/source/editeng/editview.cxx b/svx/source/editeng/editview.cxx index 134e3d6c75b0..6776f57ea2b6 100644 --- a/svx/source/editeng/editview.cxx +++ b/svx/source/editeng/editview.cxx @@ -1546,3 +1546,54 @@ bool EditView::ChangeFontSize( bool bGrow, SfxItemSet& rSet, const FontList* pFo } return bRet; } + +String EditView::GetSurroundingText() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+ DBG_CHKOBJ( pImpEditView->pEditEngine, EditEngine, 0 );
+
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( PIMPEE->GetEditDoc() );
+
+ if( HasSelection() )
+ {
+ XubString aStr = PIMPEE->GetSelected( aSel );
+
+ // Stop reconversion if the selected text includes a line break.
+ if ( aStr.Search( 0x0A ) == STRING_NOTFOUND )
+ return aStr;
+ else
+ return String();
+ }
+ else
+ {
+ aSel.Min().SetIndex( 0 );
+ aSel.Max().SetIndex( aSel.Max().GetNode()->Len() );
+ return PIMPEE->GetSelected( aSel );
+ }
+}
+
+Selection EditView::GetSurroundingTextSelection() const
+{
+ DBG_CHKTHIS( EditView, 0 );
+
+ ESelection aSelection( GetSelection() );
+ aSelection.Adjust();
+
+ if( HasSelection() )
+ {
+ EditSelection aSel( pImpEditView->GetEditSelection() );
+ aSel.Adjust( PIMPEE->GetEditDoc() );
+ XubString aStr = PIMPEE->GetSelected( aSel );
+
+ // Stop reconversion if the selected text includes a line break.
+ if ( aStr.Search( 0x0A ) == STRING_NOTFOUND )
+ return Selection( 0, aSelection.nEndPos - aSelection.nStartPos );
+ else
+ return Selection( 0, 0 );
+ }
+ else
+ {
+ return Selection( aSelection.nStartPos, aSelection.nEndPos );
+ }
+}
diff --git a/svx/source/editeng/impedit2.cxx b/svx/source/editeng/impedit2.cxx index 9ae79e7b1391..1299cfd1520a 100644 --- a/svx/source/editeng/impedit2.cxx +++ b/svx/source/editeng/impedit2.cxx @@ -381,7 +381,6 @@ BOOL ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView ) void ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView ) { -#ifndef SVX_LIGHT GetSelEngine().SetCurView( pView ); SetActiveView( pView ); if ( rCEvt.GetCommand() == COMMAND_VOICE ) @@ -642,7 +641,42 @@ void ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView ) pView->GetWindow()->SetCursorRect(); } } -#endif // !SVX_LIGHT + else if ( rCEvt.GetCommand() == COMMAND_SELECTIONCHANGE )
+ {
+ const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
+
+ ESelection aSelection = pView->GetSelection();
+ aSelection.Adjust();
+
+ if( pView->HasSelection() )
+ {
+ aSelection.nEndPos = aSelection.nStartPos;
+ aSelection.nStartPos += pData->GetStart();
+ aSelection.nEndPos += pData->GetEnd();
+ }
+ else
+ {
+ aSelection.nStartPos = pData->GetStart();
+ aSelection.nEndPos = pData->GetEnd();
+ }
+ pView->SetSelection( aSelection );
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_PREPARERECONVERSION )
+ {
+ if ( pView->HasSelection() )
+ {
+ ESelection aSelection = pView->GetSelection();
+ aSelection.Adjust();
+
+ if ( aSelection.nStartPara != aSelection.nEndPara )
+ {
+ xub_StrLen aParaLen = pEditEngine->GetTextLen( aSelection.nStartPara );
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aParaLen;
+ pView->SetSelection( aSelection );
+ }
+ }
+ } GetSelEngine().Command( rCEvt ); } diff --git a/svx/source/outliner/outlvw.cxx b/svx/source/outliner/outlvw.cxx index 102a0318bcb5..098a4055ce0f 100644 --- a/svx/source/outliner/outlvw.cxx +++ b/svx/source/outliner/outlvw.cxx @@ -1635,3 +1635,15 @@ USHORT OutlinerView::GetSelectedScriptType() const DBG_CHKTHIS(OutlinerView,0); return pEditView->GetSelectedScriptType(); } + +String OutlinerView::GetSurroundingText() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSurroundingText();
+}
+
+Selection OutlinerView::GetSurroundingTextSelection() const
+{
+ DBG_CHKTHIS(OutlinerView,0);
+ return pEditView->GetSurroundingTextSelection();
+}
diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx index 317a49bb090d..0f4716e2d513 100644 --- a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx +++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx @@ -37,6 +37,8 @@ #include <svx/sdr/attribute/sdrallattribute.hxx> #include <svditer.hxx> #include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -53,6 +55,60 @@ namespace sdr { } + basegfx::B2DRange ViewContactOfSdrObjCustomShape::getCorrectedTextBoundRect() const + { + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + Rectangle aTextBound(aObjectBound); + GetCustomShapeObj().GetTextBounds(aTextBound); + basegfx::B2DRange aTextRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + + // no need to correct if no extra text range + if(aTextRange != aObjectRange) + { + const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); + + // only correct when rotation and/or shear is used + if(rGeoStat.nShearWink || rGeoStat.nDrehWink) + { + // text range needs to be corrected by + // aObjectRange.getCenter() - aRotObjectRange.getCenter() since it's + // defined differenly by using rotation around object center. Start + // with positive part + basegfx::B2DVector aTranslation(aObjectRange.getCenter()); + + // get rotated and sheared object's range + basegfx::B2DRange aRotObjectRange(aObjectRange); + basegfx::B2DHomMatrix aRotMatrix; + + aRotMatrix.translate(-aObjectRange.getMinimum().getX(), -aObjectRange.getMinimum().getY()); + + if(rGeoStat.nShearWink) + { + aRotMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aRotMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + aRotMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + aRotObjectRange.transform(aRotMatrix); + + // add negative translation part + aTranslation -= aRotObjectRange.getCenter(); + + // create new range + aTextRange = basegfx::B2DRange( + aTextRange.getMinX() + aTranslation.getX(), aTextRange.getMinY() + aTranslation.getY(), + aTextRange.getMaxX() + aTranslation.getX(), aTextRange.getMaxY() + aTranslation.getY()); + } + } + + return aTextRange; + } + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObjCustomShape::createViewIndependentPrimitive2DSequence() const { drawinglayer::primitive2d::Primitive2DSequence xRetval; @@ -88,38 +144,35 @@ namespace sdr if(bHasText || xGroup.hasElements()) { // prepare text box geometry - ::basegfx::B2DHomMatrix aTextBoxMatrix; + basegfx::B2DHomMatrix aTextBoxMatrix; bool bWordWrap(false); if(bHasText) { // take unrotated snap rect as default, then get the // unrotated text box. Rotation needs to be done centered - Rectangle aTextBound(GetCustomShapeObj().GetGeoRect()); - GetCustomShapeObj().GetTextBounds(aTextBound); - const ::basegfx::B2DRange aTextBoxRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); - // fill object matrix - if(!::basegfx::fTools::equalZero(aTextBoxRange.getWidth())) - { - aTextBoxMatrix.set(0, 0, aTextBoxRange.getWidth()); - } + // #i101684# get the text range unrotated and absolute to the object range + const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); - if(!::basegfx::fTools::equalZero(aTextBoxRange.getHeight())) - { - aTextBoxMatrix.set(1, 1, aTextBoxRange.getHeight()); - } + // give text object a size + aTextBoxMatrix.scale(aTextRange.getWidth(), aTextRange.getHeight()); + // check if we have a rotation/shear at all to take care of const double fExtraTextRotation(GetCustomShapeObj().GetExtraTextRotation()); const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); - if(rGeoStat.nShearWink || rGeoStat.nDrehWink || !::basegfx::fTools::equalZero(fExtraTextRotation)) + if(rGeoStat.nShearWink || rGeoStat.nDrehWink || !basegfx::fTools::equalZero(fExtraTextRotation)) { - const double fHalfWidth(aTextBoxRange.getWidth() * 0.5); - const double fHalfHeight(aTextBoxRange.getHeight() * 0.5); - - // move to it's own center to rotate around it - aTextBoxMatrix.translate(-fHalfWidth, -fHalfHeight); + if(aObjectRange != aTextRange) + { + // move relative to unrotated object range + aTextBoxMatrix.translate( + aTextRange.getMinX() - aObjectRange.getMinimum().getX(), + aTextRange.getMinY() - aObjectRange.getMinimum().getY()); + } if(rGeoStat.nShearWink) { @@ -131,16 +184,18 @@ namespace sdr aTextBoxMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); } - if(!::basegfx::fTools::equalZero(fExtraTextRotation)) + if(!basegfx::fTools::equalZero(fExtraTextRotation)) { aTextBoxMatrix.rotate((360.0 - fExtraTextRotation) * F_PI180); } - // move back - aTextBoxMatrix.translate(fHalfWidth, fHalfHeight); + // give text it's target position + aTextBoxMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + } + else + { + aTextBoxMatrix.translate(aTextRange.getMinX(), aTextRange.getMinY()); } - - aTextBoxMatrix.translate(aTextBoxRange.getMinX(), aTextBoxRange.getMinY()); // check if SdrTextWordWrapItem is set bWordWrap = ((SdrTextWordWrapItem&)(GetCustomShapeObj().GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue(); diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx index 59e1431a1487..5fb566e77dc2 100644 --- a/svx/source/sdr/properties/textproperties.cxx +++ b/svx/source/sdr/properties/textproperties.cxx @@ -237,7 +237,7 @@ namespace sdr // call parent AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); - if( rObj.GetModel() && !rObj.IsTextEditActive() && !rObj.IsLinkedText() ) + if( rObj.GetModel() /*&& !rObj.IsTextEditActive()*/ && !rObj.IsLinkedText() ) { SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); diff --git a/svx/source/svdraw/svdfppt.cxx b/svx/source/svdraw/svdfppt.cxx index aa51f524444a..e12ed76d52ce 100644 --- a/svx/source/svdraw/svdfppt.cxx +++ b/svx/source/svdraw/svdfppt.cxx @@ -4973,6 +4973,246 @@ void StyleTextProp9::Read( SvStream& rIn ) PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader, PPTTextRulerInterpreter& rRuler, const DffRecordHeader& rExtParaHd, sal_uInt32 nInstance ) { + Init(rIn, rMan, rTextHeader, rRuler, rExtParaHd, nInstance); +} + +void PPTStyleTextPropReader::ReadParaProps( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader, + const String& aString, PPTTextRulerInterpreter& rRuler, + sal_uInt32& nCharCount, sal_Bool& bTextPropAtom ) +{ + sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below + sal_uInt32 nCharAnzRead = 0; + sal_uInt16 nDummy16; + + sal_uInt16 nStringLen = aString.Len(); + + DffRecordHeader aTextHd2; + rTextHeader.SeekToContent( rIn ); + if ( rMan.SeekToRec( rIn, PPT_PST_StyleTextPropAtom, rTextHeader.GetRecEndFilePos(), &aTextHd2 ) ) + bTextPropAtom = sal_True; + while ( nCharAnzRead <= nStringLen ) + { + PPTParaPropSet aParaPropSet; + ImplPPTParaPropSet& aSet = *aParaPropSet.pParaSet; + if ( bTextPropAtom ) + { + rIn >> nCharCount + >> aParaPropSet.pParaSet->mnDepth; // Einruecktiefe + + nCharCount--; + + rIn >> nMask; + aSet.mnAttrSet = nMask & 0x207df7; + sal_uInt16 nBulFlg = 0; + if ( nMask & 0xF ) + rIn >> nBulFlg; // Bullet-HardAttr-Flags + aSet.mpArry[ PPT_ParaAttr_BulletOn ] = ( nBulFlg & 1 ) ? 1 : 0; + aSet.mpArry[ PPT_ParaAttr_BuHardFont ] = ( nBulFlg & 2 ) ? 1 : 0; + aSet.mpArry[ PPT_ParaAttr_BuHardColor ] = ( nBulFlg & 4 ) ? 1 : 0; + + if ( nMask & 0x0080 ) // buChar + rIn >> aSet.mpArry[ PPT_ParaAttr_BulletChar ]; + if ( nMask & 0x0010 ) // buTypeface + rIn >> aSet.mpArry[ PPT_ParaAttr_BulletFont ]; + if ( nMask & 0x0040 ) // buSize + { + rIn >> aSet.mpArry[ PPT_ParaAttr_BulletHeight ]; + if ( ! ( ( nMask & ( 1 << PPT_ParaAttr_BuHardHeight ) ) + && ( nBulFlg && ( 1 << PPT_ParaAttr_BuHardHeight ) ) ) ) + aSet.mnAttrSet ^= 0x40; + } + if ( nMask & 0x0020 ) // buColor + { + sal_uInt32 nVal32, nHiByte; + rIn >> nVal32; + nHiByte = nVal32 >> 24; + if ( nHiByte <= 8 ) + nVal32 = nHiByte | PPT_COLSCHEME; + aSet.mnBulletColor = nVal32; + } + if ( nMask & 0x0800 ) // pfAlignment + { + rIn >> nDummy16; + aSet.mpArry[ PPT_ParaAttr_Adjust ] = nDummy16 & 3; + } + if ( nMask & 0x1000 ) // pfLineSpacing + rIn >> aSet.mpArry[ PPT_ParaAttr_LineFeed ]; + if ( nMask & 0x2000 ) // pfSpaceBefore + rIn >> aSet.mpArry[ PPT_ParaAttr_UpperDist ]; + if ( nMask & 0x4000 ) // pfSpaceAfter + rIn >> aSet.mpArry[ PPT_ParaAttr_LowerDist ]; + if ( nMask & 0x100 ) // pfLeftMargin + rIn >> nDummy16; + if ( nMask & 0x400 ) // pfIndent + rIn >> nDummy16; + if ( nMask & 0x8000 ) // pfDefaultTabSize + rIn >> nDummy16; + if ( nMask & 0x100000 ) // pfTabStops + { + sal_uInt16 i, nDistance, nAlignment, nNumberOfTabStops = 0; + rIn >> nNumberOfTabStops; + for ( i = 0; i < nNumberOfTabStops; i++ ) + { + rIn >> nDistance + >> nAlignment; + } + } + if ( nMask & 0x10000 ) // pfBaseLine + rIn >> nDummy16; + if ( nMask & 0xe0000 ) // pfCharWrap, pfWordWrap, pfOverflow + { + rIn >> nDummy16; + if ( nMask & 0x20000 ) + aSet.mpArry[ PPT_ParaAttr_AsianLB_1 ] = nDummy16 & 1; + if ( nMask & 0x40000 ) + aSet.mpArry[ PPT_ParaAttr_AsianLB_2 ] = ( nDummy16 >> 1 ) & 1; + if ( nMask & 0x80000 ) + aSet.mpArry[ PPT_ParaAttr_AsianLB_3 ] = ( nDummy16 >> 2 ) & 1; + aSet.mnAttrSet |= ( ( nMask >> 17 ) & 7 ) << PPT_ParaAttr_AsianLB_1; + } + if ( nMask & 0x200000 ) // pfTextDirection + rIn >> aSet.mpArry[ PPT_ParaAttr_BiDi ]; + } + else + nCharCount = nStringLen; + + if ( rRuler.GetTextOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_TextOfs ] ) ) + aSet.mnAttrSet |= 1 << PPT_ParaAttr_TextOfs; + if ( rRuler.GetBulletOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_BulletOfs ] ) ) + aSet.mnAttrSet |= 1 << PPT_ParaAttr_BulletOfs; + if ( rRuler.GetDefaultTab( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_DefaultTab ] ) ) + aSet.mnAttrSet |= 1 << PPT_ParaAttr_DefaultTab; + + if ( ( nCharCount > nStringLen ) || ( nStringLen < nCharAnzRead + nCharCount ) ) + { + bTextPropAtom = sal_False; + nCharCount = nStringLen - nCharAnzRead; + // please fix the right hand side of + // PPTParaPropSet& PPTParaPropSet::operator=(PPTParaPropSet&), + // it should be a const reference + PPTParaPropSet aTmpPPTParaPropSet; + aParaPropSet = aTmpPPTParaPropSet; + DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the paragraph attributes" ); + } + PPTParaPropSet* pPara = new PPTParaPropSet( aParaPropSet ); + pPara->mnOriginalTextPos = nCharAnzRead; + aParaPropList.Insert( pPara, LIST_APPEND ); + if ( nCharCount ) + { + sal_uInt32 nCount; + const sal_Unicode* pDat = aString.GetBuffer() + nCharAnzRead; + for ( nCount = 0; nCount < nCharCount; nCount++ ) + { + if ( pDat[ nCount ] == 0xd ) + { + pPara = new PPTParaPropSet( aParaPropSet ); + pPara->mnOriginalTextPos = nCharAnzRead + nCount + 1; + aParaPropList.Insert( pPara, LIST_APPEND ); + } + } + } + nCharAnzRead += nCharCount + 1; + } +} + +void PPTStyleTextPropReader::ReadCharProps( SvStream& rIn, PPTCharPropSet& aCharPropSet, const String& aString, + sal_uInt32& nCharCount, sal_uInt32 nCharAnzRead, + sal_Bool& bTextPropAtom, sal_uInt32 nExtParaPos, + const std::vector< StyleTextProp9 >& aStyleTextProp9, + sal_uInt32& nExtParaFlags, sal_uInt16& nBuBlip, + sal_uInt16& nHasAnm, sal_uInt32& nAnmScheme ) +{ + sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below + sal_uInt16 nDummy16; + sal_Int32 nCharsToRead; + sal_uInt32 nExtParaNibble = 0; + + sal_uInt16 nStringLen = aString.Len(); + + rIn >> nDummy16; + nCharCount = nDummy16; + rIn >> nDummy16; + nCharsToRead = nStringLen - ( nCharAnzRead + nCharCount ); + if ( nCharsToRead < 0 ) + { + nCharCount = nStringLen - nCharAnzRead; + if ( nCharsToRead < -1 ) + { + bTextPropAtom = sal_False; + DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the character attributes" ); + } + } + ImplPPTCharPropSet& aSet = *aCharPropSet.pCharSet; + + // character attributes + rIn >> nMask; + if ( (sal_uInt16)nMask ) + { + aSet.mnAttrSet |= (sal_uInt16)nMask; + rIn >> aSet.mnFlags; + } + if ( nMask & 0x10000 ) // cfTypeface + { + rIn >> aSet.mnFont; + aSet.mnAttrSet |= 1 << PPT_CharAttr_Font; + } + if ( nMask & 0x200000 ) // cfFEOldTypeface + { + rIn >> aSet.mnAsianOrComplexFont; + aSet.mnAttrSet |= 1 << PPT_CharAttr_AsianOrComplexFont; + } + if ( nMask & 0x400000 ) // cfANSITypeface + { + rIn >> aSet.mnANSITypeface; + aSet.mnAttrSet |= 1 << PPT_CharAttr_ANSITypeface; + } + if ( nMask & 0x800000 ) // cfSymbolTypeface + { + rIn >> aSet.mnSymbolFont; + aSet.mnAttrSet |= 1 << PPT_CharAttr_Symbol; + } + if ( nMask & 0x20000 ) // cfSize + { + rIn >> aSet.mnFontHeight; + aSet.mnAttrSet |= 1 << PPT_CharAttr_FontHeight; + } + if ( nMask & 0x40000 ) // cfColor + { + sal_uInt32 nVal; + rIn >> nVal; + if ( !( nVal & 0xff000000 ) ) + nVal = PPT_COLSCHEME_HINTERGRUND; + aSet.mnColor = nVal; + aSet.mnAttrSet |= 1 << PPT_CharAttr_FontColor; + } + if ( nMask & 0x80000 ) // cfPosition + { + rIn >> aSet.mnEscapement; + aSet.mnAttrSet |= 1 << PPT_CharAttr_Escapement; + } + if ( nExtParaPos ) + { + sal_uInt32 nExtBuInd = nMask & 0x3c00; + if ( nExtBuInd ) + nExtBuInd = ( aSet.mnFlags & 0x3c00 ) >> 10; + if ( nExtBuInd < aStyleTextProp9.size() ) + { + if ( nExtParaNibble && ( ( nExtBuInd + nExtParaNibble ) < aStyleTextProp9.size() ) ) + nExtBuInd += nExtParaNibble; + + nExtParaFlags = aStyleTextProp9[ nExtBuInd ].mnExtParagraphMask; + nBuBlip = aStyleTextProp9[ nExtBuInd ].mnBuBlip; + nHasAnm = aStyleTextProp9[ nExtBuInd ].mnHasAnm; + nAnmScheme = aStyleTextProp9[ nExtBuInd ].mnAnmScheme; + } + if ( ( nExtBuInd & 0xf ) == 0xf ) + nExtParaNibble += 16; + } +} + +void PPTStyleTextPropReader::Init( SvStream& rIn, SdrPowerPointImport& rMan, const DffRecordHeader& rTextHeader, + PPTTextRulerInterpreter& rRuler, const DffRecordHeader& rExtParaHd, sal_uInt32 nInstance ) +{ sal_uInt32 nMerk = rIn.Tell(); sal_uInt32 nExtParaPos = ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom ) ? rExtParaHd.nFilePos + 8 : 0; @@ -5032,7 +5272,7 @@ PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImpo aString = String( pBuf, (sal_uInt16)i ); delete[] pBuf; } - else + else if( aTextHd.nRecType == PPT_PST_TextBytesAtom ) { sal_Char *pBuf = new sal_Char[ nMaxLen + 1 ]; pBuf[ nMaxLen ] = 0; @@ -5057,148 +5297,44 @@ PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImpo aString = String( pBuf, nLen, RTL_TEXTENCODING_MS_1252 ); delete[] pBuf; } - if ( aString.Len() ) + else { - sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below - sal_uInt32 nCharCount, nCharAnzRead = 0; - sal_Int32 nCharsToRead; - sal_uInt16 nDummy16; + // no chars, but potentially char/para props? + sal_uInt32 nCharCount; sal_Bool bTextPropAtom = sal_False; + ReadParaProps( rIn, rMan, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom ); - sal_uInt16 nStringLen = aString.Len(); - - DffRecordHeader aTextHd2; - rTextHeader.SeekToContent( rIn ); - if ( rMan.SeekToRec( rIn, PPT_PST_StyleTextPropAtom, rTextHeader.GetRecEndFilePos(), &aTextHd2 ) ) - bTextPropAtom = sal_True; - while ( nCharAnzRead <= nStringLen ) + if ( bTextPropAtom ) { - PPTParaPropSet aParaPropSet; - ImplPPTParaPropSet& aSet = *aParaPropSet.pParaSet; - if ( bTextPropAtom ) - { - rIn >> nCharCount - >> aParaPropSet.pParaSet->mnDepth; // Einruecktiefe - - nCharCount--; - - rIn >> nMask; - aSet.mnAttrSet = nMask & 0x207df7; - sal_uInt16 nBulFlg = 0; - if ( nMask & 0xF ) - rIn >> nBulFlg; // Bullet-HardAttr-Flags - aSet.mpArry[ PPT_ParaAttr_BulletOn ] = ( nBulFlg & 1 ) ? 1 : 0; - aSet.mpArry[ PPT_ParaAttr_BuHardFont ] = ( nBulFlg & 2 ) ? 1 : 0; - aSet.mpArry[ PPT_ParaAttr_BuHardColor ] = ( nBulFlg & 4 ) ? 1 : 0; - - if ( nMask & 0x0080 ) // buChar - rIn >> aSet.mpArry[ PPT_ParaAttr_BulletChar ]; - if ( nMask & 0x0010 ) // buTypeface - rIn >> aSet.mpArry[ PPT_ParaAttr_BulletFont ]; - if ( nMask & 0x0040 ) // buSize - { - rIn >> aSet.mpArry[ PPT_ParaAttr_BulletHeight ]; - if ( ! ( ( nMask & ( 1 << PPT_ParaAttr_BuHardHeight ) ) - && ( nBulFlg && ( 1 << PPT_ParaAttr_BuHardHeight ) ) ) ) - aSet.mnAttrSet ^= 0x40; - } - if ( nMask & 0x0020 ) // buColor - { - sal_uInt32 nVal32, nHiByte; - rIn >> nVal32; - nHiByte = nVal32 >> 24; - if ( nHiByte <= 8 ) - nVal32 = nHiByte | PPT_COLSCHEME; - aSet.mnBulletColor = nVal32; - } - if ( nMask & 0x0800 ) // pfAlignment - { - rIn >> nDummy16; - aSet.mpArry[ PPT_ParaAttr_Adjust ] = nDummy16 & 3; - } - if ( nMask & 0x1000 ) // pfLineSpacing - rIn >> aSet.mpArry[ PPT_ParaAttr_LineFeed ]; - if ( nMask & 0x2000 ) // pfSpaceBefore - rIn >> aSet.mpArry[ PPT_ParaAttr_UpperDist ]; - if ( nMask & 0x4000 ) // pfSpaceAfter - rIn >> aSet.mpArry[ PPT_ParaAttr_LowerDist ]; - if ( nMask & 0x100 ) // pfLeftMargin - rIn >> nDummy16; - if ( nMask & 0x400 ) // pfIndent - rIn >> nDummy16; - if ( nMask & 0x8000 ) // pfDefaultTabSize - rIn >> nDummy16; - if ( nMask & 0x100000 ) // pfTabStops - { - sal_uInt16 i, nDistance, nAlignment, nNumberOfTabStops = 0; - rIn >> nNumberOfTabStops; - for ( i = 0; i < nNumberOfTabStops; i++ ) - { - rIn >> nDistance - >> nAlignment; - } - } - if ( nMask & 0x10000 ) // pfBaseLine - rIn >> nDummy16; - if ( nMask & 0xe0000 ) // pfCharWrap, pfWordWrap, pfOverflow - { - rIn >> nDummy16; - if ( nMask & 0x20000 ) - aSet.mpArry[ PPT_ParaAttr_AsianLB_1 ] = nDummy16 & 1; - if ( nMask & 0x40000 ) - aSet.mpArry[ PPT_ParaAttr_AsianLB_2 ] = ( nDummy16 >> 1 ) & 1; - if ( nMask & 0x80000 ) - aSet.mpArry[ PPT_ParaAttr_AsianLB_3 ] = ( nDummy16 >> 2 ) & 1; - aSet.mnAttrSet |= ( ( nMask >> 17 ) & 7 ) << PPT_ParaAttr_AsianLB_1; - } - if ( nMask & 0x200000 ) // pfTextDirection - rIn >> aSet.mpArry[ PPT_ParaAttr_BiDi ]; - } - else - nCharCount = nStringLen; + // yeah, StyleTextProp is there, read it all & push to + // aParaPropList + PPTCharPropSet aCharPropSet(0); + aCharPropSet.mnOriginalTextPos = 0; - if ( rRuler.GetTextOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_TextOfs ] ) ) - aSet.mnAttrSet |= 1 << PPT_ParaAttr_TextOfs; - if ( rRuler.GetBulletOfs( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_BulletOfs ] ) ) - aSet.mnAttrSet |= 1 << PPT_ParaAttr_BulletOfs; - if ( rRuler.GetDefaultTab( aParaPropSet.pParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_DefaultTab ] ) ) - aSet.mnAttrSet |= 1 << PPT_ParaAttr_DefaultTab; + sal_uInt32 nCharAnzRead = 0; + sal_uInt32 nExtParaFlags = 0, nAnmScheme = 0; + sal_uInt16 nBuBlip = 0xffff, nHasAnm = 0; + ReadCharProps( rIn, aCharPropSet, aString, nCharCount, nCharAnzRead, + bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags, + nBuBlip, nHasAnm, nAnmScheme ); - if ( ( nCharCount > nStringLen ) || ( nStringLen < nCharAnzRead + nCharCount ) ) - { - bTextPropAtom = sal_False; - nCharCount = nStringLen - nCharAnzRead; - // please fix the right hand side of - // PPTParaPropSet& PPTParaPropSet::operator=(PPTParaPropSet&), - // it should be a const reference - PPTParaPropSet aTmpPPTParaPropSet; - aParaPropSet = aTmpPPTParaPropSet; - DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the paragraph attributes" ); - } - PPTParaPropSet* pPara = new PPTParaPropSet( aParaPropSet ); - pPara->mnOriginalTextPos = nCharAnzRead; - aParaPropList.Insert( pPara, LIST_APPEND ); - if ( nCharCount ) - { - sal_uInt32 nCount; - const sal_Unicode* pDat = aString.GetBuffer() + nCharAnzRead; - for ( nCount = 0; nCount < nCharCount; nCount++ ) - { - if ( pDat[ nCount ] == 0xd ) - { - pPara = new PPTParaPropSet( aParaPropSet ); - pPara->mnOriginalTextPos = nCharAnzRead + nCount + 1; - aParaPropList.Insert( pPara, LIST_APPEND ); - } - } - } - nCharAnzRead += nCharCount + 1; + aCharPropList.Insert( + new PPTCharPropSet( aCharPropSet, 0 ), LIST_APPEND ); } + } + + if ( aString.Len() ) + { + sal_uInt32 nCharCount; + sal_Bool bTextPropAtom = sal_False; + + ReadParaProps( rIn, rMan, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom ); sal_Bool bEmptyParaPossible = sal_True; - sal_uInt32 nCurrentPara = nCharAnzRead = 0; + sal_uInt32 nCharAnzRead = 0; + sal_uInt32 nCurrentPara = 0; sal_uInt32 nCurrentSpecMarker = (sal_uInt32)(sal_uIntPtr)aSpecMarkerList.First(); - sal_uInt32 nExtParaNibble = 0; + sal_uInt16 nStringLen = aString.Len(); while ( nCharAnzRead < nStringLen ) { @@ -5207,87 +5343,9 @@ PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, SdrPowerPointImpo PPTCharPropSet aCharPropSet( nCurrentPara ); if ( bTextPropAtom ) - { - rIn >> nDummy16; - nCharCount = nDummy16; - rIn >> nDummy16; - nCharsToRead = nStringLen - ( nCharAnzRead + nCharCount ); - if ( nCharsToRead < 0 ) - { - nCharCount = nStringLen - nCharAnzRead; - if ( nCharsToRead < -1 ) - { - bTextPropAtom = sal_False; - DBG_ERROR( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the character attributes" ); - } - } - ImplPPTCharPropSet& aSet = *aCharPropSet.pCharSet; - - // character attributes - rIn >> nMask; - if ( (sal_uInt16)nMask ) - { - aSet.mnAttrSet |= (sal_uInt16)nMask; - rIn >> aSet.mnFlags; - } - if ( nMask & 0x10000 ) // cfTypeface - { - rIn >> aSet.mnFont; - aSet.mnAttrSet |= 1 << PPT_CharAttr_Font; - } - if ( nMask & 0x200000 ) // cfFEOldTypeface - { - rIn >> aSet.mnAsianOrComplexFont; - aSet.mnAttrSet |= 1 << PPT_CharAttr_AsianOrComplexFont; - } - if ( nMask & 0x400000 ) // cfANSITypeface - { - rIn >> aSet.mnANSITypeface; - aSet.mnAttrSet |= 1 << PPT_CharAttr_ANSITypeface; - } - if ( nMask & 0x800000 ) // cfSymbolTypeface - { - rIn >> aSet.mnSymbolFont; - aSet.mnAttrSet |= 1 << PPT_CharAttr_Symbol; - } - if ( nMask & 0x20000 ) // cfSize - { - rIn >> aSet.mnFontHeight; - aSet.mnAttrSet |= 1 << PPT_CharAttr_FontHeight; - } - if ( nMask & 0x40000 ) // cfColor - { - sal_uInt32 nVal; - rIn >> nVal; - if ( !( nVal & 0xff000000 ) ) - nVal = PPT_COLSCHEME_HINTERGRUND; - aSet.mnColor = nVal; - aSet.mnAttrSet |= 1 << PPT_CharAttr_FontColor; - } - if ( nMask & 0x80000 ) // cfPosition - { - rIn >> aSet.mnEscapement; - aSet.mnAttrSet |= 1 << PPT_CharAttr_Escapement; - } - if ( nExtParaPos ) - { - sal_uInt32 nExtBuInd = nMask & 0x3c00; - if ( nExtBuInd ) - nExtBuInd = ( aSet.mnFlags & 0x3c00 ) >> 10; - if ( nExtBuInd < aStyleTextProp9.size() ) - { - if ( nExtParaNibble && ( ( nExtBuInd + nExtParaNibble ) < aStyleTextProp9.size() ) ) - nExtBuInd += nExtParaNibble; - - nExtParaFlags = aStyleTextProp9[ nExtBuInd ].mnExtParagraphMask; - nBuBlip = aStyleTextProp9[ nExtBuInd ].mnBuBlip; - nHasAnm = aStyleTextProp9[ nExtBuInd ].mnHasAnm; - nAnmScheme = aStyleTextProp9[ nExtBuInd ].mnAnmScheme; - } - if ( ( nExtBuInd & 0xf ) == 0xf ) - nExtParaNibble += 16; - } - } + ReadCharProps( rIn, aCharPropSet, aString, nCharCount, nCharAnzRead, + bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags, + nBuBlip, nHasAnm, nAnmScheme ); else nCharCount = nStringLen; @@ -6632,7 +6690,12 @@ PPTTextObj::PPTTextObj( SvStream& rIn, SdrPowerPointImport& rSdrPowerPointImport mpImplTextObj->mnInstance = nInstance; UINT32 nFilePos = rIn.Tell(); - if ( rSdrPowerPointImport.SeekToRec2( PPT_PST_TextBytesAtom, PPT_PST_TextCharsAtom, aClientTextBoxHd.GetRecEndFilePos() ) ) + if ( rSdrPowerPointImport.SeekToRec2( PPT_PST_TextBytesAtom, + PPT_PST_TextCharsAtom, + aClientTextBoxHd.GetRecEndFilePos() ) + || rSdrPowerPointImport.SeekToRec( rIn, + PPT_PST_StyleTextPropAtom, + aClientTextBoxHd.GetRecEndFilePos() ) ) { PPTTextRulerInterpreter aTextRulerInterpreter( nTextRulerAtomOfs, rSdrPowerPointImport, aClientTextBoxHd, rIn ); diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx index 70dda490a540..0f9e2e168721 100644 --- a/svx/source/svdraw/svdoashp.cxx +++ b/svx/source/svdraw/svdoashp.cxx @@ -1630,7 +1630,7 @@ void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const rInfo.bMirror90Allowed =TRUE; rInfo.bTransparenceAllowed = FALSE; rInfo.bGradientAllowed = FALSE; - rInfo.bShearAllowed =FALSE; + rInfo.bShearAllowed =TRUE; rInfo.bEdgeRadiusAllowed=FALSE; rInfo.bNoContortion =TRUE; @@ -1965,19 +1965,56 @@ void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 ) InvalidateRenderGeometry(); } -void SdrObjCustomShape::Shear( const Point& /*rRef*/, long /*nWink*/, double /*tn*/, FASTBOOL /*bVShear*/) +void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear ) { -/* SdrTextObj::Shear( rRef, nWink, tn, bVShear ); InvalidateRenderGeometry(); -*/ } -void SdrObjCustomShape::NbcShear( const Point& /*rRef*/, long /*nWink*/, double /*tn*/, FASTBOOL /*bVShear*/) +void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear ) { -/* + long nDrehWink = aGeo.nDrehWink; + if ( nDrehWink ) + { + aGeo.nDrehWink = -nDrehWink; + aGeo.RecalcSinCos(); + NbcRotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos ); + } SdrTextObj::NbcShear(rRef,nWink,tn,bVShear); + if ( nDrehWink ) + { + aGeo.nDrehWink = nDrehWink; + aGeo.RecalcSinCos(); + Rotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos ); + } InvalidateRenderGeometry(); -*/ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(USHORT nPosNum) const +{ + INT32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue(); + + // #i25616# + if(!LineIsOutsideGeometry()) + { + nWdt++; + nWdt /= 2; + } + + Point aPt; + switch (nPosNum) { + case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break; + case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break; + case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break; + case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break; + } + if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan); + if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos); + aPt-=GetSnapRect().Center(); + SdrGluePoint aGP(aPt); + aGP.SetPercent(FALSE); + return aGP; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2012,6 +2049,53 @@ void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded() aNewList.Insert(aCopy); } + sal_Bool bMirroredX = IsMirroredX(); + sal_Bool bMirroredY = IsMirroredY(); + + long nShearWink = aGeo.nShearWink; + double fTan = aGeo.nTan; + + if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY ) + { + Polygon aPoly( aRect ); + if( nShearWink ) + { + USHORT nPointCount=aPoly.GetSize(); + for (USHORT i=0; i<nPointCount; i++) + ShearPoint(aPoly[i],aRect.Center(), fTan, FALSE ); + } + if ( aGeo.nDrehWink ) + aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 ); + + Rectangle aBoundRect( aPoly.GetBoundRect() ); + sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left(); + sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top(); + + if (nShearWink&&(bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX)) + { + nShearWink = -nShearWink; + fTan = -fTan; + } + + Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 ); + for ( a = 0; a < aNewList.GetCount(); a++ ) + { + SdrGluePoint& rPoint = aNewList[ a ]; + Point aGlue( rPoint.GetPos() ); + if ( nShearWink ) + ShearPoint( aGlue, aRef, fTan ); + + RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) ); + if ( bMirroredX ) + aGlue.X() = aRect.GetWidth() - aGlue.X(); + if ( bMirroredY ) + aGlue.Y() = aRect.GetHeight() - aGlue.Y(); + aGlue.X() -= nXDiff; + aGlue.Y() -= nYDiff; + rPoint.SetPos( aGlue ); + } + } + for(a = 0; a < pList->GetCount(); a++) { const SdrGluePoint& rCandidate = (*pList)[a]; @@ -2162,12 +2246,13 @@ void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObj std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) ); + GeoStat aGeoStat( pObj->GetGeoStat() ); if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() && ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) ) { Point aNewPos( aNewRect.TopLeft() ); - if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), pObj->aGeo.nTan ); - if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), pObj->aGeo.nSin, pObj->aGeo.nCos ); + if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan ); + if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos ); aNewRect.SetPos( aNewPos ); } if ( aNewRect != pObj->aRect ) @@ -2180,7 +2265,6 @@ void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObj Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() ); Point aBottom( aTop.X(), aTop.Y() + 1000 ); pObj->NbcMirror( aTop, aBottom ); - } if ( rNewRect.Top() > rNewRect.Bottom() ) { @@ -2188,6 +2272,7 @@ void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObj Point aRight( aLeft.X() + 1000, aLeft.Y() ); pObj->NbcMirror( aLeft, aRight ); } + std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() ); while ( aIter != aInteractionHandles.end() ) { @@ -3301,13 +3386,13 @@ void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, SetSnapRect(aBaseRect); // shear? -// if(!basegfx::fTools::equalZero(fShearX)) -// { -// GeoStat aGeoStat; -// aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0); -// aGeoStat.RecalcTan(); -// Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE); -// } + if(!basegfx::fTools::equalZero(fShearX)) + { + GeoStat aGeoStat; + aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0); + aGeoStat.RecalcTan(); + Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE); + } // rotation? if(!basegfx::fTools::equalZero(fRotate)) diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx index 792176eecc01..4ac7b4754f8d 100644 --- a/svx/source/table/cell.cxx +++ b/svx/source/table/cell.cxx @@ -450,6 +450,11 @@ void Cell::cloneFrom( const CellRef& xCell ) msFormula = xCell->msFormula; mfValue = xCell->mfValue; mnError = xCell->mnError; + + mbMerged = xCell->mbMerged; + mnRowSpan = xCell->mnRowSpan; + mnColSpan = xCell->mnColSpan; + } notifyModified(); } diff --git a/svx/source/table/cellcursor.cxx b/svx/source/table/cellcursor.cxx index 4d7b6fa02e76..681546b9ebd9 100644 --- a/svx/source/table/cellcursor.cxx +++ b/svx/source/table/cellcursor.cxx @@ -201,6 +201,9 @@ bool CellCursor::GetMergedSelection( CellPos& rStart, CellPos& rEnd ) if( xCell->isMerged() ) { findMergeOrigin( mxTable, mnRight, mnBottom, rEnd.mnCol, rEnd.mnRow ); + // merge not possible if selection is only one cell and all its merges + if( rEnd == rStart ) + return false; xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( rEnd.mnCol, rEnd.mnRow ).get() ) ); } } @@ -271,7 +274,7 @@ void SAL_CALL CellCursor::merge( ) throw (NoSupportException, RuntimeException) try { - merge( aStart.mnCol, aStart.mnRow, aEnd.mnCol - aStart.mnCol + 1, aEnd.mnRow - aStart.mnRow + 1 ); + mxTable->merge( aStart.mnCol, aStart.mnRow, aEnd.mnCol - aStart.mnCol + 1, aEnd.mnRow - aStart.mnRow + 1 ); mxTable->optimize(); mxTable->setModified(sal_True); } @@ -286,40 +289,6 @@ void SAL_CALL CellCursor::merge( ) throw (NoSupportException, RuntimeException) // ----------------------------------------------------------------------------- -void CellCursor::merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ) -{ - // merge first cell - CellRef xOriginCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); - if( xOriginCell.is() ) - { - xOriginCell->AddUndo(); - xOriginCell->merge( nColSpan, nRowSpan ); - } - - const sal_Int32 nLastRow = nRow + nRowSpan; - const sal_Int32 nLastCol = nCol + nColSpan; - - sal_Int32 nTempCol = nCol + 1; - - // merge remaining cells - for( ; nRow < nLastRow; nRow++ ) - { - for( ; nTempCol < nLastCol; nTempCol++ ) - { - CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nTempCol, nRow ).get() ) ); - if( xCell.is() && !xCell->isMerged() ) - { - xCell->AddUndo(); - xCell->setMerged(); - xOriginCell->mergeContent( xCell ); - } - } - nTempCol = nCol; - } -} - -// ----------------------------------------------------------------------------- - void CellCursor::split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< sal_Int32 >& rLeftOvers ) { const sal_Int32 nRowCount = mxTable->getRowCount(); @@ -362,8 +331,13 @@ void CellCursor::split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); if( !xCell.is() || xCell->isMerged() ) { - // merged cells are ignored, but newly added columns will be added to leftovers - rLeftOvers[nRow] += nNewCols; + if( nNewCols > 0 ) + { + // merged cells are ignored, but newly added columns will be added to leftovers + xCell.set( dynamic_cast< Cell* >(mxTable->getCellByPosition( nCol+1, nRow ).get() ) ); + if( !xCell.is() || !xCell->isMerged() ) + rLeftOvers[nRow] += nNewCols; + } } else { @@ -388,12 +362,9 @@ void CellCursor::split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< if( nSplits == 0 ) nSplitSpan = nCellsAvailable - ((nSplitSpan+1) * nColumns) - 1; - xCell->merge( nSplitSpan + 1, nRowSpan + 1); + mxTable->merge( nSplitCol, nRow, nSplitSpan + 1, nRowSpan + 1); if( nSplits > 0 ) - { nSplitCol += nSplitSpan + 1; - xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( nSplitCol, nRow ).get() ) ); - } } do @@ -407,7 +378,7 @@ void CellCursor::split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< { // cope with outside cells, merge if needed if( nColSpan < (rLeftOvers[nRow] + nNewCols) ) - merge( nCol, nRow, (rLeftOvers[nRow] + nNewCols) + 1, nRowSpan + 1 ); + mxTable->merge( nCol, nRow, (rLeftOvers[nRow] + nNewCols) + 1, nRowSpan + 1 ); do { @@ -476,8 +447,13 @@ void CellCursor::split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_In CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); if( !xCell.is() || xCell->isMerged() ) { - // merged cells are ignored, but newly added columns will be added to leftovers - rLeftOvers[nCol] += nNewRows; + if( nNewRows ) + { + // merged cells are ignored, but newly added columns will be added to leftovers + xCell.set( dynamic_cast< Cell* >(mxTable->getCellByPosition( nCol, nRow+1 ).get() ) ); + if( !xCell.is() || !xCell->isMerged() ) + rLeftOvers[nCol] += nNewRows; + } } else { @@ -502,12 +478,9 @@ void CellCursor::split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_In if( nSplits == 0 ) nSplitSpan = nCellsAvailable - ((nSplitSpan+1) * nRows) - 1; - xCell->merge( nColSpan + 1, nSplitSpan + 1 ); + mxTable->merge( nCol, nSplitRow, nColSpan + 1, nSplitSpan + 1 ); if( nSplits > 0 ) - { nSplitRow += nSplitSpan + 1; - xCell.set( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nSplitRow ).get() ) ); - } } do @@ -521,7 +494,7 @@ void CellCursor::split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_In { // cope with outside cells, merge if needed if( nRowSpan < (rLeftOvers[nCol] + nNewRows) ) - merge( nCol, nRow, nColSpan + 1, (rLeftOvers[nCol] + nNewRows) + 1 ); + mxTable->merge( nCol, nRow, nColSpan + 1, (rLeftOvers[nCol] + nNewRows) + 1 ); do { diff --git a/svx/source/table/cellcursor.hxx b/svx/source/table/cellcursor.hxx index f4f242f39c0e..c23dbf12b210 100644 --- a/svx/source/table/cellcursor.hxx +++ b/svx/source/table/cellcursor.hxx @@ -75,8 +75,6 @@ public: protected: bool GetMergedSelection( CellPos& rStart, CellPos& rEnd ); - void merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ); - void split_column( sal_Int32 nCol, sal_Int32 nColumns, std::vector< sal_Int32 >& rLeftOvers ); void split_horizontal( sal_Int32 nColumns ); void split_row( sal_Int32 nRow, sal_Int32 nRows, std::vector< sal_Int32 >& rLeftOvers ); diff --git a/svx/source/table/tablelayouter.cxx b/svx/source/table/tablelayouter.cxx index 9c62d3ad4be9..5c1aca5a4542 100644 --- a/svx/source/table/tablelayouter.cxx +++ b/svx/source/table/tablelayouter.cxx @@ -102,6 +102,9 @@ basegfx::B2ITuple TableLayouter::getCellSize( const CellPos& rPos ) const sal_Int32 nRowSpan = std::max( xCell->getRowSpan(), (sal_Int32)1 ); while( nRowSpan && (aPos.mnRow < nRowCount) ) { + if( ((sal_Int32)maRows.size()) <= aPos.mnRow ) + break; + height += maRows[aPos.mnRow++].mnSize; nRowSpan--; } @@ -110,6 +113,9 @@ basegfx::B2ITuple TableLayouter::getCellSize( const CellPos& rPos ) const sal_Int32 nColSpan = std::max( xCell->getColumnSpan(), (sal_Int32)1 ); while( nColSpan && (aPos.mnCol < nColCount ) ) { + if( ((sal_Int32)maColumns.size()) <= aPos.mnCol ) + break; + width += maColumns[aPos.mnCol++].mnSize; nColSpan--; } @@ -133,11 +139,14 @@ bool TableLayouter::getCellArea( const CellPos& rPos, basegfx::B2IRectangle& rAr { const basegfx::B2ITuple aCellSize( getCellSize( rPos ) ); - const sal_Int32 x = maColumns[rPos.mnCol].mnPos; - const sal_Int32 y = maRows[rPos.mnRow].mnPos; + if( (rPos.mnCol < ((sal_Int32)maColumns.size()) && (rPos.mnRow < ((sal_Int32)maRows.size()) ) ) ) + { + const sal_Int32 x = maColumns[rPos.mnCol].mnPos; + const sal_Int32 y = maRows[rPos.mnRow].mnPos; - rArea = basegfx::B2IRectangle( x, y, x + aCellSize.getX(), y + aCellSize.getY() ); - return true; + rArea = basegfx::B2IRectangle( x, y, x + aCellSize.getX(), y + aCellSize.getY() ); + return true; + } } } catch( Exception& ) @@ -321,6 +330,21 @@ sal_Int32 TableLayouter::getVerticalEdge( int nEdgeX, sal_Int32* pnMin /*= 0*/, // ----------------------------------------------------------------------------- +static bool checkMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 nMergedY, sal_Int32 nCellX, sal_Int32 nCellY, bool& bRunning ) +{ + Reference< XMergeableCell > xCell( xTable->getCellByPosition( nCellX, nCellY ), UNO_QUERY ); + if( xCell.is() && !xCell->isMerged() ) + { + const sal_Int32 nRight = xCell->getColumnSpan() + nCellX; + const sal_Int32 nBottom = xCell->getRowSpan() + nCellY; + if( (nMergedX < nRight) && (nMergedY < nBottom) ) + return true; + + bRunning = false; + } + return false; +} + /** returns true if the cell(nMergedX,nMergedY) is merged with other cells. the returned cell( rOriginX, rOriginY ) is the origin( top left cell ) of the merge. */ @@ -336,49 +360,87 @@ bool findMergeOrigin( const TableModelRef& xTable, sal_Int32 nMergedX, sal_Int32 if( !xCell.is() || !xCell->isMerged() ) return true; - // check horizontal - sal_Int32 nCol = nMergedX-1; - while( nCol >= 0 ) + bool bCheckVert = true; + bool bCheckHorz = true; + + sal_Int32 nMinCol = 0; + sal_Int32 nMinRow = 0; + + sal_Int32 nStep = 1, i; + + sal_Int32 nRow, nCol; + do { - xCell = xCell.query( xTable->getCellByPosition( nCol, nMergedY ) ); - if( xCell.is() && !xCell->isMerged() ) + if( bCheckVert ) { - if( xCell->getColumnSpan() > 1 ) + nRow = nMergedY - nStep; + if( nRow >= nMinRow ) { - // hit! - rOriginX = nCol; - rOriginY = nMergedY; - return true; + nCol = nMergedX; + for( i = 0; (i <= nStep) && (nCol >= nMinCol); i++, nCol-- ) + { + if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckVert ) ) + { + rOriginX = nCol; rOriginY = nRow; + return true; + } + + if( !bCheckVert ) + { + if( nCol == nMergedX ) + { + nMinRow = nRow+1; + } + else + { + bCheckVert = true; + } + break; + } + } + } + else + { + bCheckVert = false; } - break; } - nCol--; - } - // check vertical - sal_Int32 nRow = nMergedY-1; - while( nRow >= 0 ) - { - xCell = xCell.query( xTable->getCellByPosition( nMergedX, nRow ) ); - if( xCell.is() && !xCell->isMerged() ) + if( bCheckHorz ) { - if( xCell->getRowSpan() > 1 ) + nCol = nMergedX - nStep; + if( nCol >= nMinCol ) + { + nRow = nMergedY; + for( i = 0; (i < nStep) && (nRow >= nMinRow); i++, nRow-- ) + { + if( checkMergeOrigin( xTable, nMergedX, nMergedY, nCol, nRow, bCheckHorz ) ) + { + rOriginX = nCol; rOriginY = nRow; + return true; + } + + if( !bCheckHorz ) + { + if( nRow == nMergedY ) + { + nMinCol = nCol+1; + } + else + { + bCheckHorz = true; + } + break; + } + } + } + else { - // hit! - rOriginX = nMergedX; - rOriginY = nRow; - return true; + bCheckHorz = false; } - break; } - nRow--; + nStep++; } - - // if origin is not at the edges, it must be the top left cell of the merged edges - rOriginX = nCol+1; - rOriginY = nRow+1; - xCell = xCell.query( xTable->getCellByPosition( rOriginX, rOriginY ) ); - return xCell.is() && (xCell->getRowSpan() > 1) && (xCell->getColumnSpan() > 1); + while( bCheckVert || bCheckHorz ); } catch( Exception& ) { diff --git a/svx/source/table/tablemodel.cxx b/svx/source/table/tablemodel.cxx index 83b1a95723a9..32646c8e0347 100644 --- a/svx/source/table/tablemodel.cxx +++ b/svx/source/table/tablemodel.cxx @@ -52,6 +52,8 @@ #include "svdstr.hrc" #include "svdglob.hxx" +//#define PLEASE_DEBUG_THE_TABLES 1 + using ::rtl::OUString; using namespace ::osl; using namespace ::vos; @@ -620,14 +622,29 @@ void TableModel::notifyModification() ::osl::MutexGuard guard( m_aMutex ); if( (mnNotifyLock == 0) && mpTableObj && mpTableObj->GetModel() ) { + mbNotifyPending = false; + + ::cppu::OInterfaceContainerHelper * pModifyListeners = rBHelper.getContainer( XModifyListener::static_type() ); + if( pModifyListeners ) + { + EventObject aSource; + aSource.Source = static_cast< ::cppu::OWeakObject* >(this); + pModifyListeners->notifyEach( &XModifyListener::modified, aSource); + } + } + else + { + mbNotifyPending = true; + } #ifdef PLEASE_DEBUG_THE_TABLES - FILE* file = fopen( "e:\\table.log","a+" ); + FILE* file = fopen( "c:\\table.xml","w" ); const sal_Int32 nColCount = getColumnCountImpl(); const sal_Int32 nRowCount = getRowCountImpl(); - fprintf( file, "<table columns=\"%ld\" rows=\"%ld\">\n\r", nColCount, nRowCount ); + fprintf( file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\r" ); + fprintf( file, "<table columns=\"%ld\" rows=\"%ld\" updated=\"%s\">\n\r", nColCount, nRowCount, mbNotifyPending ? "false" : "true"); for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol ) { @@ -647,9 +664,9 @@ void TableModel::notifyModification() sal_Int32 nColSpan = xCell->getColumnSpan(); sal_Bool bMerged = xCell->isMerged(); - if( nColSpan > 1 ) + if( nColSpan != 1 ) fprintf( file, " column-span=\"%ld\"", nColSpan ); - if( nRowSpan > 1 ) + if( nRowSpan != 1 ) fprintf( file, " row-span=\"%ld\"", nRowSpan ); if( bMerged ) @@ -663,20 +680,6 @@ void TableModel::notifyModification() fprintf( file, "</table>\n\r" ); fclose( file ); #endif - mbNotifyPending = false; - - ::cppu::OInterfaceContainerHelper * pModifyListeners = rBHelper.getContainer( XModifyListener::static_type() ); - if( pModifyListeners ) - { - EventObject aSource; - aSource.Source = static_cast< ::cppu::OWeakObject* >(this); - pModifyListeners->notifyEach( &XModifyListener::modified, aSource); - } - } - else - { - mbNotifyPending = true; - } } // ----------------------------------------------------------------------------- @@ -784,19 +787,7 @@ void TableModel::insertColumns( sal_Int32 nIndex, sal_Int32 nCount ) // cell merges over newly created columns, so add the new columns to the merged cell const sal_Int32 nRowSpan = xCell->getRowSpan(); nColSpan += nCount; - if( bUndo ) - xCell->AddUndo(); - xCell->merge( nColSpan, nRowSpan ); - // set newly inserted cells to merged state - for( sal_Int32 nColOffset = 0; nColOffset < nCount; ++nColOffset ) - { - for( sal_Int32 nRowOffset = 0; nRowOffset < nRowSpan; ++nRowOffset ) - { - CellRef xMergedCell( getCell( nIndex + nColOffset, nRow + nRowOffset ) ); - if( xMergedCell.is() ) - xMergedCell->setMerged(); - } - } + merge( nCol, nRow, nColSpan, nRowSpan ); } } } @@ -909,7 +900,10 @@ void TableModel::removeColumns( sal_Int32 nIndex, sal_Int32 nCount ) maRows[nRows]->removeColumns( nIndex, nCount ); if( bUndo ) + { pModel->EndUndo(); + pModel->SetChanged(); + } } catch( Exception& ) { @@ -964,20 +958,7 @@ void TableModel::insertRows( sal_Int32 nIndex, sal_Int32 nCount ) // cell merges over newly created columns, so add the new columns to the merged cell const sal_Int32 nColSpan = xCell->getColumnSpan(); nRowSpan += nCount; - if( bUndo ) - xCell->AddUndo(); - xCell->merge( nColSpan, nRowSpan ); - - // set newly inserted cells to merged state - for( sal_Int32 nColOffset = 1; nColOffset < nColSpan; ++nColOffset ) - { - for( sal_Int32 nRowOffset = 0; nRowOffset <= nCount; ++nRowOffset ) - { - CellRef xMergedCell( getCell( nCol + nColOffset - 1, nIndex + nRowOffset ) ); - if( xMergedCell.is() ) - xMergedCell->setMerged(); - } - } + merge( nCol, nRow, nColSpan, nRowSpan ); } } } @@ -1075,7 +1056,10 @@ void TableModel::removeRows( sal_Int32 nIndex, sal_Int32 nCount ) remove_range<RowVector,RowVector::iterator>( maRows, nIndex, nCount ); if( bUndo ) + { pModel->EndUndo(); + pModel->SetChanged(); + } } catch( Exception& ) { @@ -1198,6 +1182,50 @@ void TableModel::optimize() // ----------------------------------------------------------------------------- +void TableModel::merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ) +{ + const bool bUndo = pModel && mpTableObj->IsInserted() && pModel->IsUndoEnabled(); + + const sal_Int32 nLastRow = nRow + nRowSpan; + const sal_Int32 nLastCol = nCol + nColSpan; + + if( (nLastRow > getRowCount()) || (nLastCol > getRowCount() ) ) + { + DBG_ERROR("TableModel::merge(), merge beyound the table!"); + } + + // merge first cell + CellRef xOriginCell( dynamic_cast< Cell* >( getCellByPosition( nCol, nRow ).get() ) ); + if( xOriginCell.is() ) + { + if( bUndo ) + xOriginCell->AddUndo(); + xOriginCell->merge( nColSpan, nRowSpan ); + } + + sal_Int32 nTempCol = nCol + 1; + + // merge remaining cells + for( ; nRow < nLastRow; nRow++ ) + { + for( ; nTempCol < nLastCol; nTempCol++ ) + { + CellRef xCell( dynamic_cast< Cell* >( getCellByPosition( nTempCol, nRow ).get() ) ); + if( xCell.is() && !xCell->isMerged() ) + { + if( bUndo ) + xCell->AddUndo(); + xCell->setMerged(); + xOriginCell->mergeContent( xCell ); + } + } + nTempCol = nCol; + } +} + + +// ----------------------------------------------------------------------------- + void TableModel::updateRows() { sal_Int32 nRow = 0; diff --git a/svx/source/table/tablemodel.hxx b/svx/source/table/tablemodel.hxx index 73e188dd3f5c..e118999b276f 100644 --- a/svx/source/table/tablemodel.hxx +++ b/svx/source/table/tablemodel.hxx @@ -96,6 +96,9 @@ public: /** deletes rows and columns that are completly merged. Must be called between BegUndo/EndUndo! */ void optimize(); + /// merges the cell at the given position with the given span + void merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ); + // ICellRange virtual sal_Int32 getLeft(); virtual sal_Int32 getTop(); |