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