summaryrefslogtreecommitdiffstats
path: root/sw/source/core/edit/edglss.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/edit/edglss.cxx')
-rw-r--r--sw/source/core/edit/edglss.cxx340
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: */