1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <o3tl/safeint.hxx>
23 #include <osl/endian.h>
24 #include <tools/urlobj.hxx>
26 #include <IDocumentRedlineAccess.hxx>
27 #include <IDocumentFieldsAccess.hxx>
32 #include <rootfrm.hxx>
34 #include <swtable.hxx>
35 #include <shellio.hxx>
36 #include <iodetect.hxx>
37 #include <frameformats.hxx>
39 void SwEditShell::InsertGlossary( SwTextBlocks
& rGlossary
, const OUString
& rStr
)
42 GetDoc()->InsertGlossary( rGlossary
, rStr
, *GetCursor(), this );
46 /// convert current selection into text block and add to the text block document, incl. templates
47 sal_uInt16
SwEditShell::MakeGlossary( SwTextBlocks
& rBlks
, const OUString
& rName
, const OUString
& rShortName
,
48 bool bSaveRelFile
, const OUString
* pOnlyText
)
50 SwDoc
* pGDoc
= rBlks
.GetDoc();
55 INetURLObject
aURL( rBlks
.GetFileName() );
56 sBase
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
58 rBlks
.SetBaseURL( sBase
);
61 return rBlks
.PutText( rShortName
, rName
, *pOnlyText
);
64 if( rBlks
.BeginPutDoc( rShortName
, rName
) )
66 rBlks
.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines
);
68 rBlks
.GetDoc()->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::NONE
);
69 return rBlks
.PutDoc();
75 sal_uInt16
SwEditShell::SaveGlossaryDoc( SwTextBlocks
& rBlock
,
76 const OUString
& rName
,
77 const OUString
& rShortName
,
83 SwDoc
* pGDoc
= rBlock
.GetDoc();
84 SwDoc
* pMyDoc
= GetDoc();
89 INetURLObject
aURL( rBlock
.GetFileName() );
90 sBase
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
92 rBlock
.SetBaseURL( sBase
);
93 sal_uInt16 nRet
= USHRT_MAX
;
99 SwPaM
* pCursor
= GetCursor();
101 SwNodeIndex
aStt( pMyDoc
->GetNodes().GetEndOfExtras(), 1 );
102 SwContentNode
* pContentNd
= pMyDoc
->GetNodes().GoNext( &aStt
);
103 const SwNode
* pNd
= pContentNd
->FindTableNode();
107 pCursor
->GetPoint()->nNode
= *pNd
;
108 if( pNd
== pContentNd
)
109 pCursor
->GetPoint()->nContent
.Assign( pContentNd
, 0 );
112 // then until the end of the Node array
113 pCursor
->GetPoint()->nNode
= pMyDoc
->GetNodes().GetEndOfContent().GetIndex()-1;
114 pContentNd
= pCursor
->GetContentNode();
116 pCursor
->GetPoint()->nContent
.Assign( pContentNd
, pContentNd
->Len() );
119 GetSelectedText( sBuf
, ParaBreakType::ToOnlyCR
);
120 if( !sBuf
.isEmpty() )
121 nRet
= rBlock
.PutText( rShortName
, rName
, sBuf
);
126 if( rBlock
.BeginPutDoc( rShortName
, rName
) )
128 SwNodeIndex
aStt( pMyDoc
->GetNodes().GetEndOfExtras(), 1 );
129 SwContentNode
* pContentNd
= pMyDoc
->GetNodes().GoNext( &aStt
);
130 const SwNode
* pNd
= pContentNd
->FindTableNode();
131 if( !pNd
) pNd
= pContentNd
;
132 SwPaM
aCpyPam( *pNd
);
135 // then until the end of the nodes array
136 aCpyPam
.GetPoint()->nNode
= pMyDoc
->GetNodes().GetEndOfContent().GetIndex()-1;
137 pContentNd
= aCpyPam
.GetContentNode();
138 aCpyPam
.GetPoint()->nContent
.Assign(
139 pContentNd
, pContentNd
? pContentNd
->Len() : 0);
141 aStt
= pGDoc
->GetNodes().GetEndOfExtras();
142 pContentNd
= pGDoc
->GetNodes().GoNext( &aStt
);
143 SwPosition
aInsPos( aStt
, SwIndex( pContentNd
));
144 pMyDoc
->getIDocumentContentOperations().CopyRange(aCpyPam
, aInsPos
, SwCopyFlags::CheckPosInFly
);
146 nRet
= rBlock
.PutDoc();
153 /// copy all selections to the doc
154 bool SwEditShell::CopySelToDoc( SwDoc
& rInsDoc
)
156 SwNodes
& rNds
= rInsDoc
.GetNodes();
158 SwNodeIndex
aIdx( rNds
.GetEndOfContent(), -1 );
159 SwContentNode
*const pContentNode
= aIdx
.GetNode().GetContentNode();
160 SwPosition
aPos( aIdx
,
161 SwIndex(pContentNode
, pContentNode
? pContentNode
->Len() : 0));
164 CurrShell
aCurr( this );
166 rInsDoc
.getIDocumentFieldsAccess().LockExpFields();
170 // Copy parts of a table: create a table with the width of the original one and copy the
171 // selected boxes. The sizes are corrected on a percentage basis.
173 // search boxes using the layout
174 SwTableNode
* pTableNd
;
176 GetTableSel( *this, aBoxes
);
177 if( !aBoxes
.empty() && nullptr != (pTableNd
= const_cast<SwTableNode
*>(aBoxes
[0]
178 ->GetSttNd()->FindTableNode()) ))
180 // check if the table name can be copied
181 bool bCpyTableNm
= aBoxes
.size() == pTableNd
->GetTable().GetTabSortBoxes().size();
184 const OUString rTableName
= pTableNd
->GetTable().GetFrameFormat()->GetName();
185 const SwFrameFormats
& rTableFormats
= *rInsDoc
.GetTableFrameFormats();
186 for( auto n
= rTableFormats
.size(); n
; )
187 if( rTableFormats
[ --n
]->GetName() == rTableName
)
193 bRet
= rInsDoc
.InsCopyOfTable( aPos
, aBoxes
, nullptr, bCpyTableNm
);
200 bool bColSel
= GetCursor_()->IsColumnSelection();
201 if( bColSel
&& rInsDoc
.IsClipBoard() )
202 rInsDoc
.SetColumnSelection( true );
203 bool bSelectAll
= StartsWithTable() && ExtendedSelectedAll();
205 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
207 if( !rPaM
.HasMark() )
209 SwContentNode
*const pNd
= rPaM
.GetContentNode();
210 if (nullptr != pNd
&&
211 ( bColSel
|| !pNd
->GetTextNode() ) )
214 rPaM
.Move( fnMoveForward
, GoInContent
);
215 bRet
= GetDoc()->getIDocumentContentOperations().CopyRange(rPaM
, aPos
, SwCopyFlags::CheckPosInFly
)
223 // Make a copy, so that in case we need to adjust the selection
224 // for the purpose of copying, our shell cursor is not touched.
225 // (Otherwise we would have to restore it.)
226 SwPaM
aPaM(*rPaM
.GetMark(), *rPaM
.GetPoint());
229 // Selection starts at the first para of the first cell,
230 // but we want to copy the table and the start node before
231 // the first cell as well.
232 // tdf#133982 tables can be nested
233 while (SwTableNode
const* pTableNode
=
234 aPaM
.Start()->nNode
.GetNode().StartOfSectionNode()->FindTableNode())
236 aPaM
.Start()->nNode
= *pTableNode
;
238 while (SwSectionNode
const* pSectionNode
=
239 aPaM
.Start()->nNode
.GetNode().StartOfSectionNode()->FindSectionNode())
241 aPaM
.Start()->nNode
= *pSectionNode
;
243 aPaM
.Start()->nContent
.Assign(nullptr, 0);
245 bRet
= GetDoc()->getIDocumentContentOperations().CopyRange( aPaM
, aPos
, SwCopyFlags::CheckPosInFly
)
252 rInsDoc
.getIDocumentFieldsAccess().UnlockExpFields();
253 if( !rInsDoc
.getIDocumentFieldsAccess().IsExpFieldsLocked() )
254 rInsDoc
.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
259 /** Get text in a Selection
261 void SwEditShell::GetSelectedText( OUString
&rBuf
, ParaBreakType nHndlParaBrk
)
263 GetCursor(); // creates all cursors if needed
267 if( ParaBreakType::ToBlank
== nHndlParaBrk
)
269 rBuf
= rBuf
.replaceAll("\x0a", " ");
271 else if( IsSelFullPara() &&
272 ParaBreakType::ToOnlyCR
!= nHndlParaBrk
)
281 else if( IsSelection() )
283 SvMemoryStream aStream
;
285 aStream
.SetEndian( SvStreamEndian::BIG
);
287 aStream
.SetEndian( SvStreamEndian::LITTLE
);
290 SwReaderWriter::GetWriter( FILTER_TEXT
, OUString(), xWrt
);
293 // write selected areas into an ASCII document
294 SwWriter
aWriter( aStream
, *this);
295 xWrt
->SetShowProgress(false);
297 switch( nHndlParaBrk
)
299 case ParaBreakType::ToBlank
:
300 xWrt
->m_bASCII_ParaAsBlank
= true;
301 xWrt
->m_bASCII_NoLastLineEnd
= true;
304 case ParaBreakType::ToOnlyCR
:
305 xWrt
->m_bASCII_ParaAsCR
= true;
306 xWrt
->m_bASCII_NoLastLineEnd
= true;
310 //JP 09.05.00: write as UNICODE ! (and not as ANSI)
311 SwAsciiOptions
aAsciiOpt( xWrt
->GetAsciiOptions() );
312 aAsciiOpt
.SetCharSet( RTL_TEXTENCODING_UCS2
);
313 xWrt
->SetAsciiOptions( aAsciiOpt
);
314 xWrt
->m_bUCS2_WithStartChar
= false;
315 xWrt
->m_bHideDeleteRedlines
= GetLayout()->IsHideRedlines();
317 if ( ! aWriter
.Write(xWrt
).IsError() )
319 aStream
.WriteUInt16( '\0' );
321 const sal_Unicode
*p
= static_cast<sal_Unicode
const *>(aStream
.GetData());
326 const sal_uInt64 nLen
= aStream
.GetSize();
327 OSL_ENSURE( nLen
/sizeof( sal_Unicode
)<o3tl::make_unsigned(SAL_MAX_INT32
), "Stream can't fit in OUString" );
328 rtl_uString
*pStr
= rtl_uString_alloc(static_cast<sal_Int32
>(nLen
/ sizeof( sal_Unicode
)));
330 aStream
.ResetError();
331 //endian specific?, yipes!
332 aStream
.ReadBytes(pStr
->buffer
, nLen
);
333 rBuf
= OUString(pStr
, SAL_NO_ACQUIRE
);
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */