/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
rClpDoc.GetDocumentFieldsManager().GCFieldTypes(); // delete the FieldTypes
// if a string was passed, copy it to the clipboard- // document. Then also the Calculator can use the internal // clipboard if( pNewClpText )
{
pTextNd->InsertText( *pNewClpText, SwContentIndex( pTextNd ) ); return; // that's it
}
rClpDoc.getIDocumentFieldsAccess().LockExpFields(); if (bDeleteRedlines)
{
rClpDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines );
}
// do we want to copy a FlyFrame? if( IsFrameSelected() )
{ // get the FlyFormat
SwFlyFrame* pFly = GetSelectedFlyFrame();
SwFrameFormat* pFlyFormat = pFly->GetFormat();
SwFormatAnchor aAnchor( pFlyFormat->GetAnchor() );
// assure the "RootFormat" is the first element in Spz-Array // (if necessary Flys were copied in Flys)
sw::SpzFrameFormats& rSpzFrameFormats = *rClpDoc.GetSpzFrameFormats(); if( rSpzFrameFormats[ 0 ] != pFlyFormat )
{ #ifndef NDEBUG bool inserted = #endif
rSpzFrameFormats.newDefault(static_cast<sw::SpzFrameFormat*>(pFlyFormat));
assert( !inserted && "Fly not contained in Spz-Array" );
}
if ( RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId() )
{ // JP 13.02.99 Bug 61863: if a frameselection is passed to the // clipboard, it should be found at pasting. Therefore // the copied TextAttribute should be removed in the node // otherwise it will be recognised as TextSelection const SwPosition& rPos = *pFlyFormat->GetAnchor().GetContentAnchor();
SwTextFlyCnt *const pTextFly = static_cast<SwTextFlyCnt *>(
pTextNd->GetTextAttrForCharAt(
rPos.GetContentIndex(), RES_TXTATR_FLYCNT)); if( pTextFly )
{ const_cast<SwFormatFlyCnt&>(pTextFly->GetFlyCnt()).SetFlyFormat();
pTextNd->EraseText( rPos, 1 );
}
}
} elseif ( GetSelectedObjCount() )
{
SwPosition aPos( aSttIdx, pTextNd, 0 ); const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
// The list should be copied, because below new objects will be selected const SdrMarkList aMrkList( Imp()->GetDrawView()->GetMarkedObjectList() ); const size_t nMarkCount = aMrkList.GetMarkCount(); if( !rDestShell.Imp()->GetDrawView() ) // should create it now
rDestShell.MakeDrawView(); elseif( bSelectInsert )
rDestShell.Imp()->GetDrawView()->UnmarkAll();
if( pDestDrwView->IsGroupEntered() )
{ // insert into the group, when it belongs to an entered group // or when the object is not anchored as a character if( pSrcDrwView->IsGroupEntered() ||
(RndStdIds::FLY_AS_CHAR != rAnchor.GetAnchorId()) )
// Can be 0, as Draws are not allowed in Headers/Footers if ( pFormat )
{ // #tdf33692 - drawing object has to be made visible on ctrl+drag copy.
pFormat->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PREPPASTING));
SdrObject* pNew = pFormat->FindSdrObject(); if ( RndStdIds::FLY_AS_CHAR != aAnchor.GetAnchorId() )
{
Point aPos( rInsPt );
aPos -= aNewAnch;
aPos -= rSttPt - pObj->GetSnapRect().TopLeft(); // OD 2004-04-05 #i26791# - change attributes instead of // direct positioning
pFormat->SetFormatAttr( SwFormatHoriOrient( aPos.getX(), text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
pFormat->SetFormatAttr( SwFormatVertOrient( aPos.getY(), text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); // #i47455# - notify draw frame format // that position attributes are already set. if (SwDrawFrameFormat *pDrawFormat = dynamic_cast<SwDrawFrameFormat*>(pFormat))
pDrawFormat->PosAttrSet();
} if (SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pObj))
{
SwTextBoxHelper::syncFlyFrameAttr(*pFormat, pFormat->GetAttrSet(), pObj);
}
// If there are table formulas in the area, then display the table first // so that the table formula can calculate a new value first // (individual boxes in the area are retrieved via the layout)
SwFieldType* pTableFieldTyp = rDestShell.GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Table );
// only select if it can be shifted/copied in the same shell if( bSelectInsert )
{
SwFlyFrame* pFlyFrame = static_cast<SwFlyFrameFormat*>(pFlyFormat)->GetFrame( &aPt ); if( pFlyFrame )
{ //JP 12.05.98: should this be in SelectFlyFrame???
rDestShell.Imp()->GetDrawView()->UnmarkAll();
rDestShell.SelectFlyFrame( *pFlyFrame );
}
}
if (this != &rDestShell && !rDestShell.HasShellFocus())
rDestShell.Imp()->GetDrawView()->hideMarkHandles();
}
} elseif ( GetSelectedObjCount() )
bRet = CopyDrawSel( rDestShell, rSttPt, rInsPt, bIsMove, bSelectInsert ); elseif( IsTableMode() )
{ // Copy parts from a table: create a table with the same // width as the original and copy the selected boxes. // Sizes will be corrected by percentage.
// find boxes via the layout
SwSelBoxes aBoxes;
GetTableSel( *this, aBoxes );
SwTableNode const*const pTableNd(
aBoxes.empty() ? nullptr : aBoxes[0]->GetSttNd()->FindTableNode()); if (nullptr != pTableNd)
{
std::optional<SwPosition> oDstPos; if( this == &rDestShell )
{ // same shell? Then create new Cursor at the // DocumentPosition passed
oDstPos.emplace( *GetCursor()->GetPoint() );
Point aPt( rInsPt );
GetLayout()->GetModelPositionForViewPoint( &*oDstPos, aPt ); if( !oDstPos->GetNode().IsNoTextNode() )
bRet = true;
} elseif( !rDestShell.GetCursor()->GetPointNode().IsNoTextNode() )
{
oDstPos.emplace( *rDestShell.GetCursor()->GetPoint() );
bRet = true;
}
// JP 16.04.99: Bug 64908 - Set InsPos, to assure the parked // Cursor is positioned at the insert position if( this == &rDestShell )
GetCursorDocPos() = rInsPt;
}
}
} else
{
bRet = true; if( this == &rDestShell )
{ // same shell? then request the position // at the passed document position
SwPosition aPos( *GetCursor()->GetPoint() );
Point aPt( rInsPt );
GetLayout()->GetModelPositionForViewPoint( &aPos, aPt );
bRet = !aPos.GetNode().IsNoTextNode();
} elseif( rDestShell.GetCursor()->GetPointNode().IsNoTextNode() )
bRet = false;
// have new table formulas been inserted? if( pTableFieldTyp->HasWriterListeners() )
{ // finish old actions: the table frames are created and // a selection can be made
sal_uInt16 nActCnt; for( nActCnt = 0; rDestShell.ActionPend(); ++nActCnt )
rDestShell.EndAllAction();
// Paste for the internal clipboard. Copy the content of the clipboard // in the document namespace { typedef std::shared_ptr<SwPaM> PaMPtr; typedef std::shared_ptr<SwPosition> PositionPtr; typedef std::pair< PaMPtr, PositionPtr > Insertion;
/// Is pFormat anchored in a fly frame which has an associated draw format? bool IsInTextBox(const SwFrameFormat* pFormat)
{ const SwFormatAnchor& rAnchor = pFormat->GetAnchor(); const SwNode* pAnchorNode = rAnchor.GetAnchorNode(); if (!pAnchorNode)
{ returnfalse;
}
const SwStartNode* pFlyNode = pAnchorNode->FindFlyStartNode(); if (!pFlyNode)
{ returnfalse;
}
namespace {
SwFrameFormat* lcl_PasteFlyOrDrawFormat(SwPaM& rPaM, SwFrameFormat* pCpyFormat, SwFEShell& rSh)
{ auto& rImp = *rSh.Imp(); auto& rDoc = *rSh.GetDoc(); auto& rDrawView = *rImp.GetDrawView(); if(rDrawView.IsGroupEntered() &&
RES_DRAWFRMFMT == pCpyFormat->Which() &&
(RndStdIds::FLY_AS_CHAR != pCpyFormat->GetAnchor().GetAnchorId()))
{ const SdrObject* pSdrObj = pCpyFormat->FindSdrObject(); if(pSdrObj)
{
rtl::Reference<SdrObject> xNew = rDoc.CloneSdrObj(*pSdrObj, false, false); // Insert object sets any anchor position to 0. // Therefore we calculate the absolute position here // and after the insert the anchor of the object // is set to the anchor of the group object.
tools::Rectangle aSnapRect = xNew->GetSnapRect(); if(xNew->GetAnchorPos().X() || xNew->GetAnchorPos().Y())
{ const Point aPoint(0, 0); // OD 2004-04-05 #i26791# - direct drawing object // positioning for group members
xNew->NbcSetAnchorPos(aPoint);
xNew->NbcSetSnapRect(aSnapRect);
}
void lcl_SelectFlyFormat(SwFrameFormat *const pNew, SwFEShell& rSh)
{ if(!pNew) return; switch(pNew->Which())
{ case RES_FLYFRMFMT:
{
assert(dynamic_cast<SwFlyFrameFormat*>(pNew)); const Point aPt(rSh.GetCursorDocPos());
SwFlyFrame* pFlyFrame = static_cast<SwFlyFrameFormat*>(pNew)->GetFrame(&aPt); if(pFlyFrame)
rSh.SelectFlyFrame(*pFlyFrame); break;
} case RES_DRAWFRMFMT:
{ auto& rDrawView = *rSh.Imp()->GetDrawView();
assert(dynamic_cast<SwDrawFrameFormat*>(pNew));
SwDrawFrameFormat* pDrawFormat = static_cast<SwDrawFrameFormat*>(pNew); // #i52780# - drawing object has to be made visible on paste.
pDrawFormat->CallSwClientNotify(sw::DrawFrameFormatHint(sw::DrawFrameFormatHintId::PREPPASTING));
SdrObject* pObj = pDrawFormat->FindSdrObject();
rDrawView.MarkObj(pObj, rDrawView.GetSdrPageView()); // #i47455# - notify draw frame format // that position attributes are already set.
pDrawFormat->PosAttrSet(); break;
} default:
SAL_WARN("sw.core", "unknown fly type");
}
}
}
bool SwFEShell::Paste(SwDoc& rClpDoc, bool bNestedTable)
{
CurrShell aCurr( this ); // then till end of the nodes array
SwNodeIndex aIdx( rClpDoc.GetNodes().GetEndOfExtras(), 2 ); // select content section, whatever it may contain
SwPaM aCpyPam(aIdx, SwNodeIndex(rClpDoc.GetNodes().GetEndOfContent(), -1)); if (SwContentNode *const pAtEnd = aCpyPam.GetPointNode().GetContentNode())
{
aCpyPam.GetPoint()->AssignEndIndex(*pAtEnd);
}
// If there are table formulas in the area, then display the table first // so that the table formula can calculate a new value first // (individual boxes in the area are retrieved via the layout)
SwFieldType* pTableFieldTyp = GetDoc()->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Table );
// When the clipboard content has been created by a rectangular selection // the pasting is more sophisticated: // every paragraph will be inserted into another position. // The first positions are given by the actual cursor ring, // if there are more text portions to insert than cursor in this ring, // the additional insert positions will be created by moving the last // cursor position into the next line (like pressing the cursor down key) if( rClpDoc.IsColumnSelection() && !IsTableMode() )
{ // Creation of the list of insert positions
std::vector< Insertion > aCopyVector; // The number of text portions of the rectangular selection const SwNodeOffset nSelCount = aCpyPam.GetPoint()->GetNodeIndex()
- aCpyPam.GetMark()->GetNodeIndex();
SwNodeOffset nCount = nSelCount;
SwNodeIndex aClpIdx( aIdx );
SwPaM* pStartCursor = GetCursor();
SwPaM* pCurrCursor = pStartCursor;
SwNodeOffset nCursorCount( pStartCursor->GetRingContainer().size() ); // If the target selection is a multi-selection, often the last and first // cursor of the ring points to identical document positions. Then // we should avoid double insertion of text portions... while( nCursorCount > SwNodeOffset(1) && *pCurrCursor->GetPoint() ==
*(pCurrCursor->GetPrev()->GetPoint()) )
{
--nCursorCount;
pCurrCursor = pCurrCursor->GetNext();
pStartCursor = pCurrCursor;
}
SwPosition aStartPos( *pStartCursor->GetPoint() );
SwPosition aInsertPos( aStartPos ); // first insertion position bool bCompletePara = false;
sal_uInt16 nMove = 0; while( nCount )
{
--nCount;
OSL_ENSURE( aIdx.GetNode().GetContentNode(), "Who filled the clipboard?!" ); if( aIdx.GetNode().GetContentNode() ) // robust
{
Insertion aInsertion( std::make_shared<SwPaM>( aIdx ),
std::make_shared<SwPosition>( aInsertPos ) );
++aIdx;
aInsertion.first->SetMark(); if( pStartCursor == pCurrCursor->GetNext() )
{ // Now we have to look for insertion positions... if( !nMove ) // Annotate the last given insert position
aStartPos = aInsertPos;
SwCursor aCursor( aStartPos, nullptr); // Check if we find another insert position by moving // down the last given position if (aCursor.UpDown(false, ++nMove, nullptr, 0, *GetLayout()))
aInsertPos = *aCursor.GetPoint(); else// if there is no paragraph we have to create it
bCompletePara = nCount > SwNodeOffset(0);
nCursorCount = SwNodeOffset(0);
} else// as long as we find more insert positions in the cursor ring
{ // we'll take them
pCurrCursor = pCurrCursor->GetNext();
aInsertPos = *pCurrCursor->GetPoint();
--nCursorCount;
} // If there are no more paragraphs e.g. at the end of a document, // we insert complete paragraphs instead of text portions if( bCompletePara )
aInsertion.first->GetPoint()->Assign(aIdx); else
aInsertion.first->GetPoint()->SetContent(
aInsertion.first->GetPointContentNode()->Len() );
aCopyVector.push_back( aInsertion );
} // If there are no text portions left but there are some more // cursor positions to fill we have to restart with the first // text portion if( !nCount && nCursorCount )
{
nCount = min( nSelCount, nCursorCount );
aIdx = aClpIdx; // Start of clipboard content
}
} for (autoconst& item : aCopyVector)
{
SwPosition& rInsPos = *item.second;
SwPaM& rCopy = *item.first; const SwStartNode* pBoxNd = rInsPos.GetNode().FindTableBoxStartNode(); if( pBoxNd && SwNodeOffset(2) == pBoxNd->EndOfSectionIndex() - pBoxNd->GetIndex() &&
rCopy.GetPoint()->GetNode() != rCopy.GetMark()->GetNode() )
{ // if more than one node will be copied into a cell // the box attributes have to be removed
GetDoc()->ClearBoxNumAttrs( rInsPos.GetNode() );
}
{
SwNodeIndex aIndexBefore(rInsPos.GetNode());
--aIndexBefore;
rClpDoc.getIDocumentContentOperations().CopyRange(rCopy, rInsPos, SwCopyFlags::CheckPosInFly);
{
++aIndexBefore;
SwPaM aPaM(SwPosition(aIndexBefore),
SwPosition(rInsPos.GetNode()));
aPaM.GetDoc().MakeUniqueNumRules(aPaM);
}
}
SaveTableBoxContent( &rInsPos );
}
} else
{ bool bDelTable = true;
SwTableNode *const pDestNd(SwDoc::IsInTable(rPaM.GetPoint()->GetNode())); if (pSrcNd && nullptr != pDestNd && // not a forced nested table insertion
!bNestedTable && // Heuristics to allow copying table rows or nesting tables without // using Edit -> Paste Special -> Paste as Nested Table: // Using table cursor, or if the text selection starts in the // first paragraph, or if there is no selection and the text cursor // is there in the first paragraph, overwrite content of the cell(s) // (else insert a nested table later, i.e. if nothing selected and // the cursor is not in the first paragraph, or the selected text // doesn't contain the first paragraph of the cell)
rPaM.GetPointNode().GetIndex() == rPaM.GetPointNode().FindTableBoxStartNode()->GetIndex() + 1)
{
SwPosition aDestPos( *rPaM.GetPoint() );
break; // exit the "while-loop"
} elseif(*aCpyPam.GetPoint() == *aCpyPam.GetMark() && !rClpDoc.GetSpzFrameFormats()->empty())
{ // we need a DrawView if(!Imp()->GetDrawView())
MakeDrawView();
::std::vector<SwFrameFormat*> inserted; for (sw::SpzFrameFormat* pFlyFormat: *rClpDoc.GetSpzFrameFormats())
{ // if anchored inside other fly, will be copied when copying // top-level fly, so skip here! (other non-body anchor // shouldn't happen here)
SwFormatAnchor const& rAnchor(pFlyFormat->GetAnchor()); if (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()
|| rClpDoc.GetNodes().GetEndOfExtras().GetIndex() < rAnchor.GetAnchorNode()->GetIndex())
{
inserted.emplace_back(
lcl_PasteFlyOrDrawFormat(rPaM, pFlyFormat, *this));
}
} for (autoconst pFlyFormat : inserted)
{
lcl_SelectFlyFormat(pFlyFormat, *this);
}
} else
{ if( bDelTable && IsTableMode() )
{
SwEditShell::Delete(false);
bDelTable = false;
}
SwPosition& rInsPos = *rPaM.GetPoint(); const SwStartNode* pBoxNd = rInsPos.GetNode().
FindTableBoxStartNode(); if( pBoxNd && SwNodeOffset(2) == pBoxNd->EndOfSectionIndex() -
pBoxNd->GetIndex() &&
aCpyPam.GetPoint()->GetNode() != aCpyPam.GetMark()->GetNode() )
{ // Copy more than 1 node in the current box. But // then the BoxAttribute should be removed
GetDoc()->ClearBoxNumAttrs( rInsPos.GetNode() );
}
// ** // ** Update SwDoc::Append, if you change the following code ** // **
{
SwNodeIndex aIndexBefore(rInsPos.GetNode());
--aIndexBefore;
// copying to the clipboard, the section is inserted // at the start of the nodes, followed by empty text node boolconst isSourceSection(aCpyPam.Start()->GetNode().IsSectionNode()
&& aCpyPam.End()->GetNodeIndex() == aCpyPam.Start()->GetNode().EndOfSectionIndex() + 1
&& aCpyPam.End()->GetNode().IsTextNode()
&& aCpyPam.End()->GetNode().GetTextNode()->Len() == 0);
rClpDoc.getIDocumentContentOperations().CopyRange(aCpyPam, rInsPos, SwCopyFlags::CheckPosInFly); // Note: aCpyPam is invalid now
if (isSourceSection
&& aIndexBefore.GetNode().IsStartNode()
&& rInsPos.GetNode().GetTextNode()->Len() == 0)
{ // if there is an empty text node at the start, it // should be *replaced* by the section, so delete it
GetDoc()->getIDocumentContentOperations().DelFullPara(rPaM);
}
// have new table formulas been inserted? if( pTableFieldTyp->HasWriterListeners() )
{ // finish old action: table-frames have been created // a selection can be made now
sal_uInt16 nActCnt; for( nActCnt = 0; ActionPend(); ++nActCnt )
EndAllAction();
StartAllAction();
GetDoc()->getIDocumentFieldsAccess().LockExpFields();
SetSelection(*oSourcePam); // copy the text of the selection
SwEditShell::Copy(rToFill);
oSourcePam.reset(); // delete it because Undo will remove its node!
if(pTableNode)
{ //remove the inserted paragraph
Undo(); //remove the paragraph in the second doc, too
SwPaM aPara( rToFill.GetDoc()->GetNodes().GetEndOfExtras(), SwNodeOffset(2) ); //DocStart
rToFill.GetDoc()->getIDocumentContentOperations().DelFullPara(aPara);
} // now the page bound objects // additionally copy page bound frames if( !GetDoc()->GetSpzFrameFormats()->empty() )
{ // create a draw view if necessary if( !rToFill.Imp()->GetDrawView() )
rToFill.MakeDrawView();
// #i50824# // replace method <lcl_RemoveOleObjsFromSdrModel> by <lcl_ConvertSdrOle2ObjsToSdrGrafObjs> staticvoid lcl_ConvertSdrOle2ObjsToSdrGrafObjs( SdrModel& _rModel )
{ for ( sal_uInt16 nPgNum = 0; nPgNum < _rModel.GetPageCount(); ++nPgNum )
{ // setup object iterator in order to iterate through all objects // including objects in group objects, but exclusive group objects.
SdrObjListIter aIter(_rModel.GetPage(nPgNum)); while( aIter.IsMore() )
{
SdrOle2Obj* pOle2Obj = dynamic_cast< SdrOle2Obj* >( aIter.Next() ); if( pOle2Obj )
{ // found an ole2 shape
SdrObjList* pObjList = pOle2Obj->getParentSdrObjListFromSdrObject();
// get its graphic
Graphic aGraphic;
pOle2Obj->Connect(); const Graphic* pGraphic = pOle2Obj->GetGraphic(); if( pGraphic )
aGraphic = *pGraphic;
pOle2Obj->Disconnect();
// create new graphic shape with the ole graphic and shape size
rtl::Reference<SdrGrafObj> pGraphicObj = new SdrGrafObj(
_rModel,
aGraphic,
pOle2Obj->GetCurrentBoundRect()); // apply layer of ole2 shape at graphic shape
pGraphicObj->SetLayer( pOle2Obj->GetLayer() );
// replace ole2 shape with the new graphic object and delete the ol2 shape
pObjList->ReplaceObject( pGraphicObj.get(), pOle2Obj->GetOrdNum() );
}
}
}
}
// drop on the existing object: replace object or apply new attributes if( pModel->GetPageCount() > 0 &&
1 == pModel->GetPage(0)->GetObjCount() &&
1 == pView->GetMarkedObjectList().GetMarkCount() )
{ // replace a marked 'virtual' drawing object // by its corresponding 'master' drawing object in the mark list.
SwDrawView::ReplaceMarkedDrawVirtObjs( *pView );
if (!pAnchor || pAnchor->FindFooterOrHeader())
{ // if there is a textframe in the header/footer: // do not replace but insert
nAction = SwPasteSdr::Insert; break;
}
}
Point aNewAnchor = pAnchor->GetFrameAnchorPos( ::HasWrap( pOldObj ) ); // OD 2004-04-05 #i26791# - direct positioning of Writer // fly frame object for <SwDoc::Insert(..)>
pNewObj->NbcSetRelativePos( aNullPt - aNewAnchor );
pNewObj->NbcSetAnchorPos( aNewAnchor );
pOldObj->GetOrdNum();
DelSelectedObj();
GetDoc()->getIDocumentContentOperations().InsertDrawObj( *GetCursor(), *pNewObj, aFrameSet );
} else
{ // #i123922# for handling MasterObject and virtual ones correctly, SW // wants us to call ReplaceObject at the page, but that also // triggers the same assertion (I tried it), so stay at the view method
pView->ReplaceObjectAtView(pOldObj, *Imp()->GetPageView(), pNewObj.get());
}
} break;
if(0 != pView->GetMarkedObjectList().GetMarkCount())
{ // try to get target (if it's at least one, take first)
SdrMark* pMark = pView->GetMarkedObjectList().GetMark(0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.