diff options
Diffstat (limited to 'sw/source/core/edit/edglss.cxx')
-rw-r--r-- | sw/source/core/edit/edglss.cxx | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx new file mode 100644 index 000000000..47791dc69 --- /dev/null +++ b/sw/source/core/edit/edglss.cxx @@ -0,0 +1,340 @@ +/* -*- 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 . + */ + +#include <sal/config.h> + +#include <o3tl/safeint.hxx> +#include <osl/diagnose.h> +#include <osl/endian.h> +#include <tools/urlobj.hxx> +#include <doc.hxx> +#include <IDocumentRedlineAccess.hxx> +#include <IDocumentFieldsAccess.hxx> +#include <pam.hxx> +#include <editsh.hxx> +#include <frmfmt.hxx> +#include <rootfrm.hxx> +#include <ndtxt.hxx> +#include <swtable.hxx> +#include <shellio.hxx> +#include <iodetect.hxx> +#include <frameformats.hxx> + +void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const OUString& rStr ) +{ + StartAllAction(); + GetDoc()->InsertGlossary( rGlossary, rStr, *GetCursor(), this ); + EndAllAction(); +} + +/// convert current selection into text block and add to the text block document, incl. templates +sal_uInt16 SwEditShell::MakeGlossary( SwTextBlocks& rBlks, const OUString& rName, const OUString& rShortName, + bool bSaveRelFile, const OUString* pOnlyText ) +{ + SwDoc* pGDoc = rBlks.GetDoc(); + + OUString sBase; + if(bSaveRelFile) + { + INetURLObject aURL( rBlks.GetFileName() ); + sBase = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); + } + rBlks.SetBaseURL( sBase ); + + if( pOnlyText ) + return rBlks.PutText( rShortName, rName, *pOnlyText ); + + rBlks.ClearDoc(); + if( rBlks.BeginPutDoc( rShortName, rName ) ) + { + rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines ); + CopySelToDoc(*pGDoc); + rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::NONE ); + return rBlks.PutDoc(); + } + + return USHRT_MAX; +} + +sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock, + const OUString& rName, + const OUString& rShortName, + bool bSaveRelFile, + bool bOnlyText ) +{ + StartAllAction(); + + SwDoc* pGDoc = rBlock.GetDoc(); + SwDoc* pMyDoc = GetDoc(); + + OUString sBase; + if(bSaveRelFile) + { + INetURLObject aURL( rBlock.GetFileName() ); + sBase = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); + } + rBlock.SetBaseURL( sBase ); + sal_uInt16 nRet = USHRT_MAX; + + if( bOnlyText ) + { + KillPams(); + + SwPaM* pCursor = GetCursor(); + + SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 ); + SwContentNode* pContentNd = pMyDoc->GetNodes().GoNext( &aStt ); + const SwNode* pNd = pContentNd->FindTableNode(); + if( !pNd ) + pNd = pContentNd; + + pCursor->GetPoint()->nNode = *pNd; + if( pNd == pContentNd ) + pCursor->GetPoint()->nContent.Assign( pContentNd, 0 ); + pCursor->SetMark(); + + // then until the end of the Node array + pCursor->GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1; + pContentNd = pCursor->GetContentNode(); + if( pContentNd ) + pCursor->GetPoint()->nContent.Assign( pContentNd, pContentNd->Len() ); + + OUString sBuf; + GetSelectedText( sBuf, ParaBreakType::ToOnlyCR ); + if( !sBuf.isEmpty() ) + nRet = rBlock.PutText( rShortName, rName, sBuf ); + } + else + { + rBlock.ClearDoc(); + if( rBlock.BeginPutDoc( rShortName, rName ) ) + { + SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 ); + SwContentNode* pContentNd = pMyDoc->GetNodes().GoNext( &aStt ); + const SwNode* pNd = pContentNd->FindTableNode(); + if( !pNd ) pNd = pContentNd; + SwPaM aCpyPam( *pNd ); + aCpyPam.SetMark(); + + // then until the end of the nodes array + aCpyPam.GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1; + pContentNd = aCpyPam.GetContentNode(); + aCpyPam.GetPoint()->nContent.Assign( + pContentNd, pContentNd ? pContentNd->Len() : 0); + + aStt = pGDoc->GetNodes().GetEndOfExtras(); + pContentNd = pGDoc->GetNodes().GoNext( &aStt ); + SwPosition aInsPos( aStt, SwIndex( pContentNd )); + pMyDoc->getIDocumentContentOperations().CopyRange(aCpyPam, aInsPos, SwCopyFlags::CheckPosInFly); + + nRet = rBlock.PutDoc(); + } + } + EndAllAction(); + return nRet; +} + +/// copy all selections to the doc +bool SwEditShell::CopySelToDoc( SwDoc& rInsDoc ) +{ + SwNodes& rNds = rInsDoc.GetNodes(); + + SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 ); + SwContentNode *const pContentNode = aIdx.GetNode().GetContentNode(); + SwPosition aPos( aIdx, + SwIndex(pContentNode, pContentNode ? pContentNode->Len() : 0)); + + bool bRet = false; + CurrShell aCurr( this ); + + rInsDoc.getIDocumentFieldsAccess().LockExpFields(); + + if( IsTableMode() ) + { + // Copy parts of a table: create a table with the width of the original one and copy the + // selected boxes. The sizes are corrected on a percentage basis. + + // search boxes using the layout + SwTableNode* pTableNd; + SwSelBoxes aBoxes; + GetTableSel( *this, aBoxes ); + if( !aBoxes.empty() && nullptr != (pTableNd = const_cast<SwTableNode*>(aBoxes[0] + ->GetSttNd()->FindTableNode()) )) + { + // check if the table name can be copied + bool bCpyTableNm = aBoxes.size() == pTableNd->GetTable().GetTabSortBoxes().size(); + if( bCpyTableNm ) + { + const OUString rTableName = pTableNd->GetTable().GetFrameFormat()->GetName(); + const SwFrameFormats& rTableFormats = *rInsDoc.GetTableFrameFormats(); + for( auto n = rTableFormats.size(); n; ) + if( rTableFormats[ --n ]->GetName() == rTableName ) + { + bCpyTableNm = false; + break; + } + } + bRet = rInsDoc.InsCopyOfTable( aPos, aBoxes, nullptr, bCpyTableNm, false, pTableNd->GetTable().GetTableStyleName() ); + } + else + bRet = false; + } + else + { + bool bColSel = GetCursor_()->IsColumnSelection(); + if( bColSel && rInsDoc.IsClipBoard() ) + rInsDoc.SetColumnSelection( true ); + bool bSelectAll = StartsWithTable() && ExtendedSelectedAll(); + { + for(SwPaM& rPaM : GetCursor()->GetRingContainer()) + { + if( !rPaM.HasMark() ) + { + SwContentNode *const pNd = rPaM.GetContentNode(); + if (nullptr != pNd && + ( bColSel || !pNd->GetTextNode() ) ) + { + rPaM.SetMark(); + rPaM.Move( fnMoveForward, GoInContent ); + bRet = GetDoc()->getIDocumentContentOperations().CopyRange(rPaM, aPos, SwCopyFlags::CheckPosInFly) + || bRet; + rPaM.Exchange(); + rPaM.DeleteMark(); + } + } + else + { + // Make a copy, so that in case we need to adjust the selection + // for the purpose of copying, our shell cursor is not touched. + // (Otherwise we would have to restore it.) + SwPaM aPaM(*rPaM.GetMark(), *rPaM.GetPoint()); + if (bSelectAll) + { + // Selection starts at the first para of the first cell, + // but we want to copy the table and the start node before + // the first cell as well. + // tdf#133982 tables can be nested + while (SwTableNode const* pTableNode = + aPaM.Start()->nNode.GetNode().StartOfSectionNode()->FindTableNode()) + { + aPaM.Start()->nNode = *pTableNode; + } + while (SwSectionNode const* pSectionNode = + aPaM.Start()->nNode.GetNode().StartOfSectionNode()->FindSectionNode()) + { + aPaM.Start()->nNode = *pSectionNode; + } + aPaM.Start()->nContent.Assign(nullptr, 0); + } + bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, SwCopyFlags::CheckPosInFly) + || bRet; + } + } + } + } + + rInsDoc.getIDocumentFieldsAccess().UnlockExpFields(); + if( !rInsDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() ) + rInsDoc.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true); + + return bRet; +} + +/** Get text in a Selection + */ +void SwEditShell::GetSelectedText( OUString &rBuf, ParaBreakType nHndlParaBrk ) +{ + GetCursor(); // creates all cursors if needed + if( IsSelOnePara() ) + { + rBuf = GetSelText(); + if( ParaBreakType::ToBlank == nHndlParaBrk ) + { + rBuf = rBuf.replaceAll("\x0a", " "); + } + else if( IsSelFullPara() && + ParaBreakType::ToOnlyCR != nHndlParaBrk ) + { +#ifdef _WIN32 + rBuf += "\015\012"; +#else + rBuf += "\012"; +#endif + } + } + else if( IsSelection() ) + { + SvMemoryStream aStream; +#ifdef OSL_BIGENDIAN + aStream.SetEndian( SvStreamEndian::BIG ); +#else + aStream.SetEndian( SvStreamEndian::LITTLE ); +#endif + WriterRef xWrt; + SwReaderWriter::GetWriter( FILTER_TEXT, OUString(), xWrt ); + if( xWrt.is() ) + { + // write selected areas into an ASCII document + SwWriter aWriter( aStream, *this); + xWrt->SetShowProgress(false); + + switch( nHndlParaBrk ) + { + case ParaBreakType::ToBlank: + xWrt->m_bASCII_ParaAsBlank = true; + xWrt->m_bASCII_NoLastLineEnd = true; + break; + + case ParaBreakType::ToOnlyCR: + xWrt->m_bASCII_ParaAsCR = true; + xWrt->m_bASCII_NoLastLineEnd = true; + break; + } + + //JP 09.05.00: write as UNICODE ! (and not as ANSI) + SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() ); + aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 ); + xWrt->SetAsciiOptions( aAsciiOpt ); + xWrt->m_bUCS2_WithStartChar = false; + xWrt->m_bHideDeleteRedlines = GetLayout()->IsHideRedlines(); + + if ( ! aWriter.Write(xWrt).IsError() ) + { + aStream.WriteUInt16( '\0' ); + + const sal_Unicode *p = static_cast<sal_Unicode const *>(aStream.GetData()); + if (p) + rBuf = OUString(p); + else + { + const sal_uInt64 nLen = aStream.GetSize(); + OSL_ENSURE( nLen/sizeof( sal_Unicode )<o3tl::make_unsigned(SAL_MAX_INT32), "Stream can't fit in OUString" ); + rtl_uString *pStr = rtl_uString_alloc(static_cast<sal_Int32>(nLen / sizeof( sal_Unicode ))); + aStream.Seek( 0 ); + aStream.ResetError(); + //endian specific?, yipes! + aStream.ReadBytes(pStr->buffer, nLen); + rBuf = OUString(pStr, SAL_NO_ACQUIRE); + } + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |