Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <comphelper/string.hxx>
21 : #include <osl/endian.h>
22 : #include <hintids.hxx>
23 : #include <svl/urihelper.hxx>
24 : #include <doc.hxx>
25 : #include <IDocumentRedlineAccess.hxx>
26 : #include <IDocumentFieldsAccess.hxx>
27 : #include <pam.hxx>
28 : #include <docary.hxx>
29 : #include <editsh.hxx>
30 : #include <edimp.hxx>
31 : #include <frmfmt.hxx>
32 : #include <swundo.hxx>
33 : #include <ndtxt.hxx>
34 : #include <swtable.hxx>
35 : #include <shellio.hxx>
36 : #include <acorrect.hxx>
37 : #include <swerror.h>
38 :
39 1 : void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const OUString& rStr )
40 : {
41 1 : StartAllAction();
42 1 : GetDoc()->InsertGlossary( rGlossary, rStr, *GetCrsr(), this );
43 1 : EndAllAction();
44 1 : }
45 :
46 : /// convert current selection into text block and add to the text block document, incl. templates
47 0 : sal_uInt16 SwEditShell::MakeGlossary( SwTextBlocks& rBlks, const OUString& rName, const OUString& rShortName,
48 : bool bSaveRelFile, const OUString* pOnlyText )
49 : {
50 0 : SwDoc* pGDoc = rBlks.GetDoc();
51 :
52 0 : OUString sBase;
53 0 : if(bSaveRelFile)
54 : {
55 0 : INetURLObject aURL( rBlks.GetFileName() );
56 0 : sBase = aURL.GetMainURL( INetURLObject::NO_DECODE );
57 : }
58 0 : rBlks.SetBaseURL( sBase );
59 :
60 0 : if( pOnlyText )
61 0 : return rBlks.PutText( rShortName, rName, *pOnlyText );
62 :
63 0 : rBlks.ClearDoc();
64 0 : if( rBlks.BeginPutDoc( rShortName, rName ) )
65 : {
66 0 : rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
67 0 : _CopySelToDoc( pGDoc );
68 0 : rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)0 );
69 0 : return rBlks.PutDoc();
70 : }
71 :
72 0 : return USHRT_MAX;
73 : }
74 :
75 2 : sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock,
76 : const OUString& rName,
77 : const OUString& rShortName,
78 : bool bSaveRelFile,
79 : bool bOnlyText )
80 : {
81 2 : StartAllAction();
82 :
83 2 : SwDoc* pGDoc = rBlock.GetDoc();
84 2 : SwDoc* pMyDoc = GetDoc();
85 :
86 2 : OUString sBase;
87 2 : if(bSaveRelFile)
88 : {
89 0 : INetURLObject aURL( rBlock.GetFileName() );
90 0 : sBase = aURL.GetMainURL( INetURLObject::NO_DECODE );
91 : }
92 2 : rBlock.SetBaseURL( sBase );
93 2 : sal_uInt16 nRet = USHRT_MAX;
94 :
95 2 : if( bOnlyText )
96 : {
97 1 : KillPams();
98 :
99 1 : SwPaM* pCrsr = GetCrsr();
100 :
101 1 : SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
102 1 : SwContentNode* pContentNd = pMyDoc->GetNodes().GoNext( &aStt );
103 1 : const SwNode* pNd = pContentNd->FindTableNode();
104 1 : if( !pNd )
105 1 : pNd = pContentNd;
106 :
107 1 : pCrsr->GetPoint()->nNode = *pNd;
108 1 : if( pNd == pContentNd )
109 1 : pCrsr->GetPoint()->nContent.Assign( pContentNd, 0 );
110 1 : pCrsr->SetMark();
111 :
112 : // then until the end of the Node array
113 1 : pCrsr->GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
114 1 : pContentNd = pCrsr->GetContentNode();
115 1 : if( pContentNd )
116 1 : pCrsr->GetPoint()->nContent.Assign( pContentNd, pContentNd->Len() );
117 :
118 2 : OUString sBuf;
119 1 : if( GetSelectedText( sBuf, GETSELTXT_PARABRK_TO_ONLYCR ) && !sBuf.isEmpty() )
120 2 : nRet = rBlock.PutText( rShortName, rName, sBuf );
121 : }
122 : else
123 : {
124 1 : rBlock.ClearDoc();
125 1 : if( rBlock.BeginPutDoc( rShortName, rName ) )
126 : {
127 1 : SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
128 1 : SwContentNode* pContentNd = pMyDoc->GetNodes().GoNext( &aStt );
129 1 : const SwNode* pNd = pContentNd->FindTableNode();
130 1 : if( !pNd ) pNd = pContentNd;
131 2 : SwPaM aCpyPam( *pNd );
132 1 : aCpyPam.SetMark();
133 :
134 : // then until the end of the nodes array
135 1 : aCpyPam.GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
136 1 : pContentNd = aCpyPam.GetContentNode();
137 1 : aCpyPam.GetPoint()->nContent.Assign(
138 2 : pContentNd, (pContentNd) ? pContentNd->Len() : 0);
139 :
140 1 : aStt = pGDoc->GetNodes().GetEndOfExtras();
141 1 : pContentNd = pGDoc->GetNodes().GoNext( &aStt );
142 2 : SwPosition aInsPos( aStt, SwIndex( pContentNd ));
143 1 : pMyDoc->getIDocumentContentOperations().CopyRange( aCpyPam, aInsPos, /*bCopyAll=*/false, /*bCheckPos=*/true );
144 :
145 2 : nRet = rBlock.PutDoc();
146 : }
147 : }
148 2 : EndAllAction();
149 2 : return nRet;
150 : }
151 :
152 : /// copy all selections to the doc
153 2 : bool SwEditShell::_CopySelToDoc( SwDoc* pInsDoc, SwNodeIndex* pSttNd )
154 : {
155 : OSL_ENSURE( pInsDoc, "no Ins.Document" );
156 :
157 2 : SwNodes& rNds = pInsDoc->GetNodes();
158 :
159 2 : SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
160 2 : SwContentNode *const pContentNode = aIdx.GetNode().GetContentNode();
161 : SwPosition aPos( aIdx,
162 4 : SwIndex(pContentNode, (pContentNode) ? pContentNode->Len() : 0));
163 :
164 : // Should the index be reset to start?
165 2 : if( pSttNd )
166 : {
167 0 : *pSttNd = aPos.nNode;
168 0 : --(*pSttNd);
169 : }
170 :
171 2 : bool bRet = false;
172 4 : SET_CURR_SHELL( this );
173 :
174 2 : pInsDoc->getIDocumentFieldsAccess().LockExpFields();
175 :
176 2 : if( IsTableMode() )
177 : {
178 : // Copy parts of a table: create a table with the width of the original one and copy the
179 : // selected boxes. The sizes are corrected on a percentage basis.
180 :
181 : // search boxes using the layout
182 : SwTableNode* pTableNd;
183 0 : SwSelBoxes aBoxes;
184 0 : GetTableSel( *this, aBoxes );
185 0 : if( !aBoxes.empty() && 0 != (pTableNd = const_cast<SwTableNode*>(aBoxes[0]
186 0 : ->GetSttNd()->FindTableNode()) ))
187 : {
188 : // check if the table name can be copied
189 0 : bool bCpyTableNm = aBoxes.size() == pTableNd->GetTable().GetTabSortBoxes().size();
190 0 : if( bCpyTableNm )
191 : {
192 0 : const OUString rTableName = pTableNd->GetTable().GetFrameFormat()->GetName();
193 0 : const SwFrameFormats& rTableFormats = *pInsDoc->GetTableFrameFormats();
194 0 : for( auto n = rTableFormats.size(); n; )
195 0 : if( rTableFormats[ --n ]->GetName() == rTableName )
196 : {
197 0 : bCpyTableNm = false;
198 0 : break;
199 0 : }
200 : }
201 0 : bRet = pInsDoc->InsCopyOfTable( aPos, aBoxes, 0, bCpyTableNm, false );
202 : }
203 : else
204 0 : bRet = false;
205 : }
206 : else
207 : {
208 2 : bool bColSel = _GetCrsr()->IsColumnSelection();
209 2 : if( bColSel && pInsDoc->IsClipBoard() )
210 0 : pInsDoc->SetColumnSelection( true );
211 2 : bool bSelectAll = StartsWithTable() && ExtendedSelectedAll(/*bFootnotes =*/ false);
212 : {
213 4 : for(SwPaM& rPaM : GetCrsr()->GetRingContainer())
214 : {
215 2 : if( !rPaM.HasMark() )
216 : {
217 0 : SwContentNode *const pNd = rPaM.GetContentNode();
218 0 : if (0 != pNd &&
219 0 : ( bColSel || !pNd->GetTextNode() ) )
220 : {
221 0 : rPaM.SetMark();
222 0 : rPaM.Move( fnMoveForward, fnGoContent );
223 0 : bRet = GetDoc()->getIDocumentContentOperations().CopyRange( rPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true )
224 0 : || bRet;
225 0 : rPaM.Exchange();
226 0 : rPaM.DeleteMark();
227 : }
228 : }
229 : else
230 : {
231 : // Make a copy, so that in case we need to adjust the selection
232 : // for the purpose of copying, our shell cursor is not touched.
233 : // (Otherwise we would have to restore it.)
234 2 : SwPaM aPaM(*rPaM.GetMark(), *rPaM.GetPoint());
235 2 : if (bSelectAll)
236 : {
237 : // Selection starts at the first para of the first cell,
238 : // but we want to copy the table and the start node before
239 : // the first cell as well.
240 1 : aPaM.Start()->nNode = aPaM.Start()->nNode.GetNode().FindTableNode()->GetIndex();
241 1 : aPaM.Start()->nContent.Assign(nullptr, 0);
242 : }
243 2 : bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true ) || bRet;
244 : }
245 : }
246 : }
247 : }
248 :
249 2 : pInsDoc->getIDocumentFieldsAccess().UnlockExpFields();
250 2 : if( !pInsDoc->getIDocumentFieldsAccess().IsExpFieldsLocked() )
251 0 : pInsDoc->getIDocumentFieldsAccess().UpdateExpFields(NULL, true);
252 :
253 : // set the saved Node position back to the correct Node
254 2 : if( bRet && pSttNd )
255 0 : ++(*pSttNd);
256 :
257 4 : return bRet;
258 : }
259 :
260 : /** Get text in a Selection
261 : *
262 : * @return false if the selected area is too big for being copied into the string buffer
263 : */
264 1 : bool SwEditShell::GetSelectedText( OUString &rBuf, int nHndlParaBrk )
265 : {
266 1 : GetCrsr(); // creates all cursors if needed
267 1 : if( IsSelOnePara() )
268 : {
269 0 : rBuf = GetSelText();
270 0 : if( GETSELTXT_PARABRK_TO_BLANK == nHndlParaBrk )
271 : {
272 0 : rBuf = rBuf.replaceAll(OUString(0x0a), " ");
273 : }
274 0 : else if( IsSelFullPara() &&
275 : GETSELTXT_PARABRK_TO_ONLYCR != nHndlParaBrk )
276 : {
277 : #ifdef _WIN32
278 : rBuf += "\015\012";
279 : #else
280 0 : rBuf += "\012";
281 : #endif
282 : }
283 : }
284 1 : else if( IsSelection() )
285 : {
286 1 : SvMemoryStream aStream;
287 : #ifdef OSL_BIGENDIAN
288 : aStream.SetEndian( SvStreamEndian::BIG );
289 : #else
290 1 : aStream.SetEndian( SvStreamEndian::LITTLE );
291 : #endif
292 2 : WriterRef xWrt;
293 1 : SwReaderWriter::GetWriter( OUString(FILTER_TEXT), OUString(), xWrt );
294 1 : if( xWrt.Is() )
295 : {
296 : // write selected areas into a ASCII document
297 1 : SwWriter aWriter( aStream, *this);
298 1 : xWrt->SetShowProgress( false );
299 :
300 1 : switch( nHndlParaBrk )
301 : {
302 : case GETSELTXT_PARABRK_TO_BLANK:
303 0 : xWrt->bASCII_ParaAsBlanc = true;
304 0 : xWrt->bASCII_NoLastLineEnd = true;
305 0 : break;
306 :
307 : case GETSELTXT_PARABRK_TO_ONLYCR:
308 1 : xWrt->bASCII_ParaAsCR = true;
309 1 : xWrt->bASCII_NoLastLineEnd = true;
310 1 : break;
311 : }
312 :
313 : //JP 09.05.00: write as UNICODE ! (and not as ANSI)
314 1 : SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() );
315 1 : aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
316 1 : xWrt->SetAsciiOptions( aAsciiOpt );
317 1 : xWrt->bUCS2_WithStartChar = false;
318 :
319 1 : if (!IsError(aWriter.Write(xWrt)))
320 : {
321 1 : aStream.WriteUInt16( '\0' );
322 :
323 1 : const sal_Unicode *p = static_cast<sal_Unicode const *>(aStream.GetBuffer());
324 1 : if (p)
325 1 : rBuf = OUString(p);
326 : else
327 : {
328 0 : sal_Size nLen = aStream.GetSize();
329 0 : rtl_uString *pStr = rtl_uString_alloc(nLen / sizeof( sal_Unicode ));
330 0 : aStream.Seek( 0 );
331 0 : aStream.ResetError();
332 : //endian specific?, yipes!
333 0 : aStream.Read(pStr->buffer, nLen);
334 0 : rBuf = OUString(pStr, SAL_NO_ACQUIRE);
335 : }
336 1 : }
337 1 : }
338 : }
339 :
340 1 : return true;
341 177 : }
342 :
343 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|