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 2 : void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const OUString& rStr )
40 : {
41 2 : StartAllAction();
42 2 : GetDoc()->InsertGlossary( rGlossary, rStr, *GetCrsr(), this );
43 2 : EndAllAction();
44 2 : }
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* pOnlyTxt )
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 : sal_uInt16 nRet;
61 :
62 0 : if( pOnlyTxt )
63 0 : nRet = rBlks.PutText( rShortName, rName, *pOnlyTxt );
64 : else
65 : {
66 0 : rBlks.ClearDoc();
67 0 : if( rBlks.BeginPutDoc( rShortName, rName ) )
68 : {
69 0 : rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
70 0 : _CopySelToDoc( pGDoc );
71 0 : rBlks.GetDoc()->getIDocumentRedlineAccess().SetRedlineMode_intern( (RedlineMode_t)0 );
72 0 : nRet = rBlks.PutDoc();
73 : }
74 : else
75 0 : nRet = (sal_uInt16) -1;
76 : }
77 :
78 0 : return nRet;
79 : }
80 :
81 4 : sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock,
82 : const OUString& rName,
83 : const OUString& rShortName,
84 : bool bSaveRelFile,
85 : bool bOnlyTxt )
86 : {
87 4 : StartAllAction();
88 :
89 4 : SwDoc* pGDoc = rBlock.GetDoc();
90 4 : SwDoc* pMyDoc = GetDoc();
91 :
92 4 : OUString sBase;
93 4 : if(bSaveRelFile)
94 : {
95 0 : INetURLObject aURL( rBlock.GetFileName() );
96 0 : sBase = aURL.GetMainURL( INetURLObject::NO_DECODE );
97 : }
98 4 : rBlock.SetBaseURL( sBase );
99 4 : sal_uInt16 nRet = USHRT_MAX;
100 :
101 4 : if( bOnlyTxt )
102 : {
103 2 : KillPams();
104 :
105 2 : SwPaM* pCrsr = GetCrsr();
106 :
107 2 : SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
108 2 : SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt );
109 2 : const SwNode* pNd = pCntntNd->FindTableNode();
110 2 : if( !pNd )
111 2 : pNd = pCntntNd;
112 :
113 2 : pCrsr->GetPoint()->nNode = *pNd;
114 2 : if( pNd == pCntntNd )
115 2 : pCrsr->GetPoint()->nContent.Assign( pCntntNd, 0 );
116 2 : pCrsr->SetMark();
117 :
118 : // then until the end of the Node array
119 2 : pCrsr->GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
120 2 : pCntntNd = pCrsr->GetCntntNode();
121 2 : if( pCntntNd )
122 2 : pCrsr->GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
123 :
124 4 : OUString sBuf;
125 2 : if( GetSelectedText( sBuf, GETSELTXT_PARABRK_TO_ONLYCR ) && !sBuf.isEmpty() )
126 4 : nRet = rBlock.PutText( rShortName, rName, sBuf );
127 : }
128 : else
129 : {
130 2 : rBlock.ClearDoc();
131 2 : if( rBlock.BeginPutDoc( rShortName, rName ) )
132 : {
133 2 : SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
134 2 : SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt );
135 2 : const SwNode* pNd = pCntntNd->FindTableNode();
136 2 : if( !pNd ) pNd = pCntntNd;
137 4 : SwPaM aCpyPam( *pNd );
138 2 : aCpyPam.SetMark();
139 :
140 : // then until the end of the nodes array
141 2 : aCpyPam.GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
142 2 : pCntntNd = aCpyPam.GetCntntNode();
143 2 : aCpyPam.GetPoint()->nContent.Assign(
144 4 : pCntntNd, (pCntntNd) ? pCntntNd->Len() : 0);
145 :
146 2 : aStt = pGDoc->GetNodes().GetEndOfExtras();
147 2 : pCntntNd = pGDoc->GetNodes().GoNext( &aStt );
148 4 : SwPosition aInsPos( aStt, SwIndex( pCntntNd ));
149 2 : pMyDoc->getIDocumentContentOperations().CopyRange( aCpyPam, aInsPos, false );
150 :
151 4 : nRet = rBlock.PutDoc();
152 : }
153 : }
154 4 : EndAllAction();
155 4 : return nRet;
156 : }
157 :
158 : /// copy all selections to the doc
159 4 : bool SwEditShell::_CopySelToDoc( SwDoc* pInsDoc, SwNodeIndex* pSttNd )
160 : {
161 : OSL_ENSURE( pInsDoc, "no Ins.Document" );
162 :
163 4 : SwNodes& rNds = pInsDoc->GetNodes();
164 :
165 4 : SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
166 4 : SwCntntNode *const pContentNode = aIdx.GetNode().GetCntntNode();
167 : SwPosition aPos( aIdx,
168 8 : SwIndex(pContentNode, (pContentNode) ? pContentNode->Len() : 0));
169 :
170 : // Should the index be reset to start?
171 4 : if( pSttNd )
172 : {
173 0 : *pSttNd = aPos.nNode;
174 0 : (*pSttNd)--;
175 : }
176 :
177 4 : bool bRet = false;
178 8 : SET_CURR_SHELL( this );
179 :
180 4 : pInsDoc->getIDocumentFieldsAccess().LockExpFlds();
181 :
182 4 : if( IsTableMode() )
183 : {
184 : // Copy parts of a table: create a table with the width of the original one and copy the
185 : // selected boxes. The sizes are corrected on a percentage basis.
186 :
187 : // search boxes using the layout
188 : SwTableNode* pTblNd;
189 0 : SwSelBoxes aBoxes;
190 0 : GetTblSel( *this, aBoxes );
191 0 : if( !aBoxes.empty() && 0 != (pTblNd = (SwTableNode*)aBoxes[0]
192 0 : ->GetSttNd()->FindTableNode() ))
193 : {
194 : // check if the table name can be copied
195 0 : bool bCpyTblNm = aBoxes.size() == pTblNd->GetTable().GetTabSortBoxes().size();
196 0 : if( bCpyTblNm )
197 : {
198 0 : const OUString rTblName = pTblNd->GetTable().GetFrmFmt()->GetName();
199 0 : const SwFrmFmts& rTblFmts = *pInsDoc->GetTblFrmFmts();
200 0 : for( sal_uInt16 n = rTblFmts.size(); n; )
201 0 : if( rTblFmts[ --n ]->GetName() == rTblName )
202 : {
203 0 : bCpyTblNm = false;
204 0 : break;
205 0 : }
206 : }
207 0 : bRet = pInsDoc->InsCopyOfTbl( aPos, aBoxes, 0, bCpyTblNm, false );
208 : }
209 : else
210 0 : bRet = false;
211 : }
212 : else
213 : {
214 4 : bool bColSel = _GetCrsr()->IsColumnSelection();
215 4 : if( bColSel && pInsDoc->IsClipBoard() )
216 0 : pInsDoc->SetColumnSelection( true );
217 4 : bool bSelectAll = StartsWithTable() && ExtendedSelectedAll(/*bFootnotes =*/ false);
218 : {
219 8 : FOREACHPAM_START(GetCrsr())
220 :
221 4 : if( !PCURCRSR->HasMark() )
222 : {
223 0 : SwCntntNode *const pNd = PCURCRSR->GetCntntNode();
224 0 : if (0 != pNd &&
225 0 : ( bColSel || !pNd->GetTxtNode() ) )
226 : {
227 0 : PCURCRSR->SetMark();
228 0 : PCURCRSR->Move( fnMoveForward, fnGoCntnt );
229 0 : bRet = GetDoc()->getIDocumentContentOperations().CopyRange( *PCURCRSR, aPos, false )
230 0 : || bRet;
231 0 : PCURCRSR->Exchange();
232 0 : PCURCRSR->DeleteMark();
233 : }
234 : }
235 : else
236 : {
237 : // Make a copy, so that in case we need to adjust the selection
238 : // for the purpose of copying, our shell cursor is not touched.
239 : // (Otherwise we would have to restore it.)
240 4 : SwPaM aPaM(*PCURCRSR);
241 4 : if (bSelectAll)
242 : // Selection starts at the first para of the first cell,
243 : // but we want to copy the table and the start node before
244 : // the first cell as well.
245 2 : aPaM.Start()->nNode = aPaM.Start()->nNode.GetNode().FindTableNode()->GetIndex();
246 4 : bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, false ) || bRet;
247 : }
248 :
249 4 : FOREACHPAM_END()
250 : }
251 : }
252 :
253 4 : pInsDoc->getIDocumentFieldsAccess().UnlockExpFlds();
254 4 : if( !pInsDoc->getIDocumentFieldsAccess().IsExpFldsLocked() )
255 0 : pInsDoc->getIDocumentFieldsAccess().UpdateExpFlds(NULL, true);
256 :
257 : // set the saved Node position back to the correct Node
258 4 : if( bRet && pSttNd )
259 0 : ++(*pSttNd);
260 :
261 8 : return bRet;
262 : }
263 :
264 : /** Get text in a Selection
265 : *
266 : * @return sal_False if the selected area is too big for being copied into the string buffer
267 : */
268 2 : bool SwEditShell::GetSelectedText( OUString &rBuf, int nHndlParaBrk )
269 : {
270 2 : GetCrsr(); // creates all cursors if needed
271 2 : if( IsSelOnePara() )
272 : {
273 0 : rBuf = GetSelTxt();
274 0 : if( GETSELTXT_PARABRK_TO_BLANK == nHndlParaBrk )
275 : {
276 0 : rBuf = rBuf.replaceAll(OUString(0x0a), " ");
277 : }
278 0 : else if( IsSelFullPara() &&
279 : GETSELTXT_PARABRK_TO_ONLYCR != nHndlParaBrk )
280 : {
281 : #ifdef _WIN32
282 : rBuf += "\015\012";
283 : #else
284 0 : rBuf += "\012";
285 : #endif
286 : }
287 : }
288 2 : else if( IsSelection() )
289 : {
290 2 : SvMemoryStream aStream;
291 : #ifdef OSL_BIGENDIAN
292 : aStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
293 : #else
294 2 : aStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
295 : #endif
296 4 : WriterRef xWrt;
297 2 : SwReaderWriter::GetWriter( OUString(FILTER_TEXT), OUString(), xWrt );
298 2 : if( xWrt.Is() )
299 : {
300 : // write selected areas into a ASCII document
301 2 : SwWriter aWriter( aStream, *this);
302 2 : xWrt->SetShowProgress( false );
303 :
304 2 : switch( nHndlParaBrk )
305 : {
306 : case GETSELTXT_PARABRK_TO_BLANK:
307 0 : xWrt->bASCII_ParaAsBlanc = true;
308 0 : xWrt->bASCII_NoLastLineEnd = true;
309 0 : break;
310 :
311 : case GETSELTXT_PARABRK_TO_ONLYCR:
312 2 : xWrt->bASCII_ParaAsCR = true;
313 2 : xWrt->bASCII_NoLastLineEnd = true;
314 2 : break;
315 : }
316 :
317 : //JP 09.05.00: write as UNICODE ! (and not as ANSI)
318 2 : SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() );
319 2 : aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
320 2 : xWrt->SetAsciiOptions( aAsciiOpt );
321 2 : xWrt->bUCS2_WithStartChar = false;
322 :
323 2 : if (!IsError(aWriter.Write(xWrt)))
324 : {
325 2 : aStream.WriteUInt16( '\0' );
326 :
327 2 : const sal_Unicode *p = (sal_Unicode*)aStream.GetBuffer();
328 2 : if (p)
329 2 : rBuf = OUString(p);
330 : else
331 : {
332 0 : sal_Size nLen = aStream.GetSize();
333 0 : rtl_uString *pStr = rtl_uString_alloc(nLen / sizeof( sal_Unicode ));
334 0 : aStream.Seek( 0 );
335 0 : aStream.ResetError();
336 : //endian specific?, yipes!
337 0 : aStream.Read(pStr->buffer, nLen);
338 0 : rBuf = OUString(pStr, SAL_NO_ACQUIRE);
339 : }
340 2 : }
341 2 : }
342 : }
343 :
344 2 : return true;
345 270 : }
346 :
347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|