Commits

Anonymous committed 0e015c4

cws tl77: #i115136#, #i111876# new clipboard format for EditEngine

Comments (0)

Files changed (12)

editeng/inc/editeng/editeng.hxx

 	void			SetText( USHORT nPara, const EditTextObject& rTxtObj );
 	void			SetText( USHORT nPara, const String& rText);
 
+    ESelection      InsertText( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const ESelection& rSelection, BOOL bUseSpecial );
+
 	virtual void                SetParaAttribs( USHORT nPara, const SfxItemSet& rSet );
 	virtual const SfxItemSet&	GetParaAttribs( USHORT nPara ) const;
 

editeng/inc/editeng/outliner.hxx

 
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/datatransfer/XTransferable.hpp>
 
 #include <vos/ref.hxx>
 #include <editeng/svxfont.hxx>
 	OutlinerView*   GetView( ULONG nIndex ) const;
 	ULONG           GetViewCount() const;
 
+    ESelection      InsertText( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const ESelection& rSelection, BOOL bUseSpecial );
+
 	Paragraph*      Insert( const String& rText, ULONG nAbsPos = LIST_APPEND, sal_Int16 nDepth = 0 );
 	void            SetText( const OutlinerParaObject& );
 	void            AddText( const OutlinerParaObject& );

editeng/source/editeng/editeng.cxx

 	}
 }
 
+
+ESelection EditEngine::InsertText( const uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const ESelection& rSelection, BOOL bUseSpecial )
+{
+    EditSelection aSel( pImpEditEngine->CreateSel( rSelection ) );
+    aSel = pImpEditEngine->InsertText( rxDataObj, rBaseURL, aSel.Min(), bUseSpecial );
+    return pImpEditEngine->CreateESel( aSel );
+}
+
+
 void EditEngine::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
 {
 	DBG_CHKTHIS( EditEngine, 0 );

editeng/source/editeng/editobj.cxx

 
 bool ContentInfo::EETextObjEqual( const ContentInfo& rCompare ) const
 {
-    // similar to operator== but without comparing items
-    if( aText   == rCompare.aText && 
-        aStyle  == rCompare.aStyle  &&
-        eFamily == rCompare.eFamily )
-    {
-        return true;
-    }
+    // similar to operator== but without comparing para attribs
+	if( (aText == rCompare.aText) && 
+			(aStyle == rCompare.aStyle ) &&
+			(aAttribs.Count() == rCompare.aAttribs.Count() ) &&
+			(eFamily == rCompare.eFamily ) /*&&
+			(aParaAttribs == rCompare.aParaAttribs ) ??? 
+            if it happens that we actually need this then we probably need to 
+            copy SfxItemSet::operator== to SfxItemSet::EETextObjEqual modify the
+            latter one as needed and make use of it here in this if statement
+            */ )
+	{
+		const USHORT nCount = aAttribs.Count();
+		if( nCount == rCompare.aAttribs.Count() )
+		{
+			USHORT n;
+			for( n = 0; n < nCount; n++ )
+			{
+				if( !(*aAttribs.GetObject(n) == *rCompare.aAttribs.GetObject(n)) )
+					return false;
+			}
 
-    return false;
+			return true;
+		}
+	}
+
+	return false;
 }
     
 
 
 bool BinTextObject::EETextObjEqual( const BinTextObject& rCompare ) const
 {
-    // similar to operator== but without comparing the itempool
+    // identical to operator== but without comparing the itempool
     if( this == &rCompare )
         return true;
 

editeng/source/editeng/impedit.cxx

 
         if ( xDataObj.is() && EditEngine::HasValidData( xDataObj ) )
 	    {
-	        pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
+            ImpEditEngine *pImpEditEngine = pEditEngine->pImpEditEngine;
+	        pImpEditEngine->UndoActionStart( EDITUNDO_PASTE );
 
             EditSelection aSel( GetEditSelection() );
             if ( aSel.HasRange() )
 	        {
 		        DrawSelection();
-		        aSel = pEditEngine->pImpEditEngine->ImpDeleteSelection( aSel );
+		        aSel = pImpEditEngine->ImpDeleteSelection( aSel );
             }
 
             PasteOrDropInfos aPasteOrDropInfos;
             aPasteOrDropInfos.nAction = EE_ACTION_PASTE;
             aPasteOrDropInfos.nStartPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Min().GetNode() );
-            pEditEngine->pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );
+            pImpEditEngine->aBeginPasteOrDropHdl.Call( &aPasteOrDropInfos );
 
             if ( DoSingleLinePaste() )
 	        {
 			    }
 	        }
 	        else
-	        {
-                aSel = pEditEngine->pImpEditEngine->InsertText( xDataObj, String(), aSel.Min(), bUseSpecial && pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
-	        }
+                aSel = pImpEditEngine->InsertText( xDataObj, String(), aSel.Min(), bUseSpecial && pEditEngine->pImpEditEngine->GetStatus().AllowPasteSpecial() );
 
-            aPasteOrDropInfos.nEndPara = pEditEngine->pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
-            pEditEngine->pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );
+            aPasteOrDropInfos.nEndPara = pImpEditEngine->GetEditDoc().GetPos( aSel.Max().GetNode() );
+            pImpEditEngine->aEndPasteOrDropHdl.Call( &aPasteOrDropInfos );
 
-	        pEditEngine->pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
+	        pImpEditEngine->UndoActionEnd( EDITUNDO_PASTE );
 	        SetEditSelection( aSel );
-	        pEditEngine->pImpEditEngine->UpdateSelections();
-	        pEditEngine->pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
+	        pImpEditEngine->UpdateSelections();
+	        pImpEditEngine->FormatAndUpdate( GetEditViewPtr() );
             ShowCursor( DoAutoScroll(), TRUE );
         }
 	}

editeng/source/editeng/impedit.hxx

 	EditTextObject*		CreateBinTextObject( EditSelection aSelection, SfxItemPool*, sal_Bool bAllowBigObjects = sal_False, sal_uInt16 nBigObjStart = 0 ) const;
 	void 				StoreBinTextObject( SvStream& rOStream, BinTextObject& rTextObject );
 	EditSelection		InsertBinTextObject( BinTextObject&, EditPaM aPaM );
-    EditSelection       InsertText( ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial );
+    EditSelection       InsertText( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial );
 
 	EditPaM				Clear();
 	EditPaM				RemoveText();

editeng/source/editeng/impedit2.cxx

 #endif
 }
 
-EditSelection ImpEditEngine::InsertText( uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial )
+EditSelection ImpEditEngine::InsertText( const uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, BOOL bUseSpecial )
 {
 	EditSelection aNewSelection( rPaM );
 
             {
                 try
                 {
+                    // Two tasks:
+                    // 1) import of ODF format (via xmloff) inserts an unwanted paragraph break 
+                    // after the inserted text, thus we need to get rid of that one.
+                    // 2) Another problem is that when xmloff is used in SvxReadODF to import the
+                    // clipboard content then a correct result for the new selection after
+                    // the insertion of the text can not be obtained! Thus, to ensure that the cursor 
+                    // always gets placed at the end of the inserted text, we split the paragraph
+                    // before the insert point. The resulting para (which gets moved along with the 
+                    // new text) will then always be the para right BEHIND the end of the inserted text 
+                    // and this fact can be used to move the the cursor to the correct position.
+                    // (See also EditRTFParser::CallParser for the same approach.)
+
+                    const bool bOldUpdateMode = GetUpdateMode();
+                    // this call is especially required to prevent Calc from immediate and
+                    // unwanted growing of the cells heigth by the two temporary additional
+                    // paragraph breaks that we will remove again
+                    SetUpdateMode( false );
+
+                    EditDoc &rEditDoc = GetEditDoc();
+                    EditPaM aBefore( rPaM );
+                    const USHORT nBeforePos = rEditDoc.GetPos( aBefore.GetNode() );
+                    ContentNode* pNode = rEditDoc.SaveGetObject( nBeforePos );
+                    EditPaM aPaM( pNode, pNode->Len() );
+                    EditPaM aNewPara( ImpInsertParaBreak( aPaM ) );
+
+                    
+                    // now do the actual text insertion from clipboard
                     uno::Any aData = rxDataObj->getTransferData( aFlavor );
                     uno::Sequence< sal_Int8 > aSeq;
                     aData >>= aSeq;
                     {
                         SvMemoryStream aXMLStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
-                        aNewSelection = Read( aXMLStream, rBaseURL, EE_FORMAT_ODF, rPaM );
+                        Read( aXMLStream, rBaseURL, EE_FORMAT_ODF, rPaM );
                     }
                     bDone = TRUE;
+
+
+                    // since we have two addtional paragraph breaks following the inserted text
+                    // the node with the last inserted text is this:
+                    const USHORT nLastTextPara = CreateEPaM( aNewPara ).nPara - 2;
+
+                    // the *current* end of this para is where we want to place the cursor
+                    pNode = rEditDoc.SaveGetObject( nLastTextPara );
+                    aNewSelection = EditSelection( EditPaM( pNode, pNode->Len() ) );
+
+                    // now we can get rid of the two extra paragraph breaks.
+                    // Since unlike in EditRTFParser::CallParser here both paragraphs are empty
+                    // we do not need to call ParaAttribsToCharAttribs.
+                    ContentNode* pNode1 = rEditDoc.SaveGetObject( nLastTextPara );
+                    ContentNode* pNode2 = rEditDoc.SaveGetObject( nLastTextPara + 1 );
+                    ContentNode* pNode3 = rEditDoc.SaveGetObject( nLastTextPara + 2 );
+                    ImpConnectParagraphs( pNode2, pNode3, false );
+                    ImpConnectParagraphs( pNode1, pNode2, false );
+
+                    SetUpdateMode( bOldUpdateMode );
                 }
                 catch( const ::com::sun::star::uno::Exception& )
                 {

editeng/source/outliner/outliner.cxx

 // #101498# calculate if it's RTL or not
 #include <unicode/ubidi.h>
 
+using namespace ::com::sun::star;
+
+
 #define DEFAULT_SCALE	75
 
 static const USHORT nDefStyles = 3;	// Sonderbehandlung fuer die ersten 3 Ebenen
 	return bConverted;
 }
 
+
+ESelection Outliner::InsertText( const uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const ESelection& rSelection, BOOL bUseSpecial )
+{
+    return pEditEngine->InsertText( rxDataObj, rBaseURL, rSelection, bUseSpecial );
+}
+
+
 void Outliner::SetText( const OutlinerParaObject& rPObj )
 {
 	DBG_CHKTHIS(Outliner,0);

sd/source/ui/view/sdview3.cxx

 #include <svx/svdpagv.hxx>
 #include <editeng/eeitem.hxx>
 #include <editeng/colritem.hxx>
+#include <editeng/editview.hxx>
 #include <sfx2/docfile.hxx>
 #include <svx/svditer.hxx>
 #include <svx/svdogrp.hxx>
             bReturn = SdrView::Paste( *xStm, String(), EE_FORMAT_HTML, maDropPos, pPage, nPasteOptions );
 		}
 	}
+	else if( !bLink && CHECK_FORMAT_TRANS( SOT_FORMATSTR_ID_EDITENGINE ) )
+    {
+		OutlinerView* pOLV = GetTextEditOutlinerView();
+
+		if( pOLV )
+		{
+			Rectangle   aRect( pOLV->GetOutputArea() );
+			Point       aPos( pOLV->GetWindow()->PixelToLogic( maDropPos ) );
+
+			if( aRect.IsInside( aPos ) || ( !bDrag && IsTextEdit() ) )
+			{
+                pOLV->GetEditView().InsertText( aDataHelper.GetTransferable(), String(), true );
+				bReturn = TRUE;
+			}
+            DBG_ASSERT( bReturn, "failed to insert ODF text from clipboard" );
+		}
+
+		if( !bReturn )
+            bReturn = SdrView::Paste( aDataHelper.GetTransferable(), maDropPos, pPage, nPasteOptions );
+    }
 	else if( !bLink && CHECK_FORMAT_TRANS( FORMAT_RTF ) )
 	{
 		SotStorageStreamRef xStm;
 				}
 
 				if( !bReturn )
-					// mba: clipboard always must contain absolute URLs (could be from alien source)
+                    // mba: clipboard always must contain absolute URLs (could be from alien source)
 					bReturn = SdrView::Paste( *xStm, String(), EE_FORMAT_RTF, maDropPos, pPage, nPasteOptions );
 			}
 		}

svx/inc/svx/svdxcgv.hxx

 
 #include <svx/svdedxv.hxx>
 
-#ifndef _GDIMTF_HXX //autogen
 #include <vcl/gdimtf.hxx>
-#endif
 #include "svx/svxdllapi.h"
 
+namespace com { namespace sun { namespace star { 
+    namespace datatransfer {
+        class XTransferable;
+    }
+} } }        
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 //
 	virtual BOOL    Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst=NULL, UINT32 nOptions=0);
 	BOOL            Paste(const String& rStr, SdrObjList* pLst=NULL, OutputDevice* pOut=NULL, UINT32 nOptions=0) { return Paste(rStr,GetPastePos(pLst,pOut),pLst,nOptions); }
 	BOOL            Paste(const String& rStr, const Point& rPos, SdrObjList* pLst=NULL, UINT32 nOptions=0);
+    BOOL            Paste(const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > & rxDataObj, const Point& rPos, SdrObjList* pLst=NULL, UINT32 nOptions=0);
 	// der USHORT eFormat nimmt Werte des enum EETextFormat entgegen
     BOOL            Paste(SvStream& rInput, const String& rBaseURL, USHORT eFormat, SdrObjList* pLst=NULL, OutputDevice* pOut=NULL, UINT32 nOptions=0) { return Paste(rInput,rBaseURL,eFormat,GetPastePos(pLst,pOut),pLst,nOptions); }
     BOOL            Paste(SvStream& rInput, const String& rBaseURL, USHORT eFormat, const Point& rPos, SdrObjList* pLst=NULL, UINT32 nOptions=0);

svx/source/svdraw/svdxcgv.cxx

 
 #include <vector>
 #include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
 #include "xexch.hxx"
 #include <svx/xflclit.hxx>
 #include <svx/svdxcgv.hxx>
 #include <svx/svdoutl.hxx>
+#include <svx/svdview.hxx>
 #include "svditext.hxx"
 #include <svx/svdetc.hxx>
 #include <svx/svdundo.hxx>
 // #i72535#
 #include "fmobj.hxx"
 
+using namespace ::com::sun::star;
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
 	return TRUE;
 }
 
+
+BOOL SdrExchangeView::Paste( const uno::Reference< datatransfer::XTransferable > & rxDataObj, const Point& rPos, SdrObjList* pLst, UINT32 nOptions )
+{
+	Point aPos(rPos);
+	ImpGetPasteObjList(aPos,pLst);
+	ImpLimitToWorkArea( aPos );
+	if (pLst==NULL) return FALSE;
+	SdrLayerID nLayer;
+	if (!ImpGetPasteLayer(pLst,nLayer)) return FALSE;
+	BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+	if (bUnmark) UnmarkAllObj();
+	Rectangle aTextRect(0,0,500,500);
+	SdrPage* pPage=pLst->GetPage();
+	if (pPage!=NULL) {
+		aTextRect.SetSize(pPage->GetSize());
+	}
+	SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
+	pObj->SetModel(pMod);
+	pObj->SetLayer(nLayer);
+
+
+    // set default styles and attriubutes
+    if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
+	pObj->SetMergedItemSet(aDefaultAttr);
+	SfxItemSet aTempAttr(pMod->GetItemPool());  // Keine Fuellung oder Linie
+	aTempAttr.Put(XLineStyleItem(XLINE_NONE));
+	aTempAttr.Put(XFillStyleItem(XFILL_NONE));
+	pObj->SetMergedItemSet(aTempAttr);
+
+    // insert ODF text in current EditEngine
+    SdrOutliner &rOL = pMod->GetDrawOutliner( pObj );
+    rOL.SetStyleSheet( 0, pObj->GetStyleSheet());   // set the correct style sheet to use
+    uno::Reference< frame::XModel > xModel( pMod->getUnoModel(), uno::UNO_QUERY );
+    rOL.SetEditEngineUnoModel( xModel );
+    rOL.InsertText( rxDataObj, String(), ESelection(), true );
+
+    // copy text back to SdrObject
+    pObj->SetOutlinerParaObject( rOL.CreateParaObject() );
+  
+
+	pObj->FitFrameToTextSize();
+	Size aSiz(pObj->GetLogicRect().GetSize());
+	MapUnit eMap=pMod->GetScaleUnit();
+	Fraction aMap=pMod->GetScaleFraction();
+	ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
+    return TRUE;
+}
+
+
 BOOL SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, USHORT eFormat, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
 {
 	Point aPos(rPos);

xmloff/source/text/txtparai.cxx

     }
 
 	// insert a paragraph break
-	xTxtImport->InsertControlCharacter( ControlCharacter::APPEND_PARAGRAPH );
+	xTxtImport->InsertControlCharacter( ControlCharacter::PARAGRAPH_BREAK );
 
 	// create a cursor that select the whole last paragraph
 	Reference < XTextCursor > xAttrCursor(