1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27
28 #include <osl/endian.h>
29 #include <hintids.hxx>
30 #include <svl/urihelper.hxx>
31 #include <tools/cachestr.hxx>
32 #include <doc.hxx>
33 #include <pam.hxx>
34 #include <docary.hxx>
35 #include <editsh.hxx>
36 #include <edimp.hxx>
37 #include <frmfmt.hxx>
38 #include <swundo.hxx> // fuer die UndoIds
39 #include <ndtxt.hxx>
40 #include <swtable.hxx> // fuers kopieren von Tabellen
41 #include <shellio.hxx> // SwTextBlocks
42 #include <acorrect.hxx>
43 #include <swerror.h> // SwTextBlocks
44
45 /******************************************************************************
46 * jetzt mit einem verkappten Reader/Writer/Dokument
47 ******************************************************************************/
48
InsertGlossary(SwTextBlocks & rGlossary,const String & rStr)49 void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const String& rStr )
50 {
51 StartAllAction();
52 GetDoc()->InsertGlossary( rGlossary, rStr, *GetCrsr(), this );
53 EndAllAction();
54 }
55
56
57 /******************************************************************************
58 * aktuelle Selektion zum Textbaustein machen und ins
59 * Textbausteindokument einfuegen, einschliesslich Vorlagen
60 ******************************************************************************/
61
62
MakeGlossary(SwTextBlocks & rBlks,const String & rName,const String & rShortName,sal_Bool bSaveRelFile,const String * pOnlyTxt)63 sal_uInt16 SwEditShell::MakeGlossary( SwTextBlocks& rBlks, const String& rName, const String& rShortName,
64 sal_Bool bSaveRelFile, const String* pOnlyTxt )
65 {
66 SwDoc* pGDoc = rBlks.GetDoc();
67
68 String sBase;
69 if(bSaveRelFile)
70 {
71 INetURLObject aURL( rBlks.GetFileName() );
72 sBase = aURL.GetMainURL( INetURLObject::NO_DECODE );
73 }
74 rBlks.SetBaseURL( sBase );
75
76 sal_uInt16 nRet;
77
78 if( pOnlyTxt )
79 nRet = rBlks.PutText( rShortName, rName, *pOnlyTxt );
80 else
81 {
82 rBlks.ClearDoc();
83 if( rBlks.BeginPutDoc( rShortName, rName ) )
84 {
85 rBlks.GetDoc()->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
86 _CopySelToDoc( pGDoc );
87 rBlks.GetDoc()->SetRedlineMode_intern( (RedlineMode_t)0 );
88 nRet = rBlks.PutDoc();
89 }
90 else
91 nRet = (sal_uInt16) -1;
92 }
93
94 return nRet;
95 }
96
SaveGlossaryDoc(SwTextBlocks & rBlock,const String & rName,const String & rShortName,sal_Bool bSaveRelFile,sal_Bool bOnlyTxt)97 sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock,
98 const String& rName,
99 const String& rShortName,
100 sal_Bool bSaveRelFile,
101 sal_Bool bOnlyTxt )
102 {
103 StartAllAction();
104
105 SwDoc* pGDoc = rBlock.GetDoc();
106 SwDoc* pMyDoc = GetDoc();
107
108 String sBase;
109 if(bSaveRelFile)
110 {
111 INetURLObject aURL( rBlock.GetFileName() );
112 sBase = aURL.GetMainURL( INetURLObject::NO_DECODE );
113 }
114 rBlock.SetBaseURL( sBase );
115 sal_uInt16 nRet = USHRT_MAX;
116
117 if( bOnlyTxt )
118 {
119 KillPams();
120
121 SwPaM* pCrsr = GetCrsr();
122
123 SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
124 SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt );
125 const SwNode* pNd = pCntntNd->FindTableNode();
126 if( !pNd )
127 pNd = pCntntNd;
128
129 pCrsr->GetPoint()->nNode = *pNd;
130 if( pNd == pCntntNd )
131 pCrsr->GetPoint()->nContent.Assign( pCntntNd, 0 );
132 pCrsr->SetMark();
133
134 // dann bis zum Ende vom Nodes Array
135 pCrsr->GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
136 pCntntNd = pCrsr->GetCntntNode();
137 if( pCntntNd )
138 pCrsr->GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
139
140 String sBuf;
141 if( GetSelectedText( sBuf, GETSELTXT_PARABRK_TO_ONLYCR ) && sBuf.Len() )
142 nRet = rBlock.PutText( rShortName, rName, sBuf );
143 }
144 else
145 {
146 rBlock.ClearDoc();
147 if( rBlock.BeginPutDoc( rShortName, rName ) )
148 {
149 SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 );
150 SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt );
151 const SwNode* pNd = pCntntNd->FindTableNode();
152 if( !pNd ) pNd = pCntntNd;
153 SwPaM aCpyPam( *pNd );
154 aCpyPam.SetMark();
155
156 // dann bis zum Ende vom Nodes Array
157 aCpyPam.GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1;
158 pCntntNd = aCpyPam.GetCntntNode();
159 aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
160
161 aStt = pGDoc->GetNodes().GetEndOfExtras();
162 pCntntNd = pGDoc->GetNodes().GoNext( &aStt );
163 SwPosition aInsPos( aStt, SwIndex( pCntntNd ));
164 pMyDoc->CopyRange( aCpyPam, aInsPos, false );
165
166 nRet = rBlock.PutDoc();
167 }
168 }
169 EndAllAction();
170 return nRet;
171 }
172
173 /******************************************************************************
174 * kopiere alle Selectionen und das Doc
175 ******************************************************************************/
176
177
_CopySelToDoc(SwDoc * pInsDoc,SwNodeIndex * pSttNd)178 sal_Bool SwEditShell::_CopySelToDoc( SwDoc* pInsDoc, SwNodeIndex* pSttNd )
179 {
180 ASSERT( pInsDoc, "kein Ins.Dokument" );
181
182 SwNodes& rNds = pInsDoc->GetNodes();
183
184 SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
185 SwCntntNode * pNd = aIdx.GetNode().GetCntntNode();
186 SwPosition aPos( aIdx, SwIndex( pNd, pNd->Len() ));
187
188 // soll der Index auf Anfang returnt werden ?
189 if( pSttNd )
190 {
191 *pSttNd = aPos.nNode;
192 (*pSttNd)--;
193 }
194
195 sal_Bool bRet = sal_False;
196 SET_CURR_SHELL( this );
197
198 pInsDoc->LockExpFlds();
199
200 if( IsTableMode() )
201 {
202 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite
203 // von der Originalen an und kopiere die selectierten Boxen.
204 // Die Groessen werden prozentual korrigiert.
205
206 // lasse ueber das Layout die Boxen suchen
207 SwTableNode* pTblNd;
208 SwSelBoxes aBoxes;
209 GetTblSel( *this, aBoxes );
210 if( aBoxes.Count() && 0 != (pTblNd = (SwTableNode*)aBoxes[0]
211 ->GetSttNd()->FindTableNode() ))
212 {
213 // teste ob der TabellenName kopiert werden kann
214 sal_Bool bCpyTblNm = aBoxes.Count() == pTblNd->GetTable().GetTabSortBoxes().Count();
215 if( bCpyTblNm )
216 {
217 const String& rTblName = pTblNd->GetTable().GetFrmFmt()->GetName();
218 const SwFrmFmts& rTblFmts = *pInsDoc->GetTblFrmFmts();
219 for( sal_uInt16 n = rTblFmts.Count(); n; )
220 if( rTblFmts[ --n ]->GetName() == rTblName )
221 {
222 bCpyTblNm = sal_False;
223 break;
224 }
225 }
226 bRet = pInsDoc->InsCopyOfTbl( aPos, aBoxes, 0, bCpyTblNm, sal_False );
227 }
228 else
229 bRet = sal_False;
230 }
231 else
232 {
233 bool bColSel = _GetCrsr()->IsColumnSelection();
234 if( bColSel && pInsDoc->IsClipBoard() )
235 pInsDoc->SetColumnSelection( true );
236 {
237 FOREACHPAM_START(this)
238
239 if( !PCURCRSR->HasMark() )
240 {
241 if( 0 != (pNd = PCURCRSR->GetCntntNode()) &&
242 ( bColSel || !pNd->GetTxtNode() ) )
243 {
244 PCURCRSR->SetMark();
245 PCURCRSR->Move( fnMoveForward, fnGoCntnt );
246 bRet = GetDoc()->CopyRange( *PCURCRSR, aPos, false )
247 || bRet;
248 PCURCRSR->Exchange();
249 PCURCRSR->DeleteMark();
250 }
251 }
252 else
253 {
254 bRet = GetDoc()->CopyRange( *PCURCRSR, aPos, false ) || bRet;
255 }
256
257 FOREACHPAM_END()
258 }
259 }
260
261 pInsDoc->UnlockExpFlds();
262 if( !pInsDoc->IsExpFldsLocked() )
263 pInsDoc->UpdateExpFlds(NULL, true);
264
265 // die gemerkte Node-Position wieder auf den richtigen Node
266 if( bRet && pSttNd )
267 (*pSttNd)++;
268
269
270 return bRet;
271 }
272
273 /*------------------------------------------------------------------------
274 Beschreibung: Text innerhalb der Selektion erfragen
275 Returnwert: liefert sal_False, wenn der selektierte Bereich
276 zu gross ist, um in den Stringpuffer kopiert zu werden.
277 ------------------------------------------------------------------------*/
278
GetSelectedText(String & rBuf,int nHndlParaBrk)279 sal_Bool SwEditShell::GetSelectedText( String &rBuf, int nHndlParaBrk )
280 {
281 sal_Bool bRet = sal_False;
282 GetCrsr(); // ggfs. alle Cursor erzeugen lassen
283 if( IsSelOnePara() )
284 {
285 rBuf = GetSelTxt();
286 if( GETSELTXT_PARABRK_TO_BLANK == nHndlParaBrk )
287 {
288 xub_StrLen nPos = 0;
289 while( STRING_NOTFOUND !=
290 ( nPos = rBuf.SearchAndReplace( 0x0a, ' ', nPos )) )
291 ;
292 }
293 else if( IsSelFullPara() &&
294 GETSELTXT_PARABRK_TO_ONLYCR != nHndlParaBrk )
295 {
296 #if defined(UNX)
297 rBuf += '\012';
298 #else
299 rBuf += String::CreateFromAscii(
300 RTL_CONSTASCII_STRINGPARAM( "\015\012" ));
301 #endif
302 }
303 bRet = sal_True;
304 }
305 else if( IsSelection() )
306 {
307 SvCacheStream aStream(20480);
308 #ifdef OSL_BIGENDIAN
309 aStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
310 #else
311 aStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
312 #endif
313 WriterRef xWrt;
314 SwReaderWriter::GetWriter( String::CreateFromAscii( FILTER_TEXT ), String(), xWrt );
315 if( xWrt.Is() )
316 {
317 // Selektierte Bereiche in ein ASCII Dokument schreiben
318 SwWriter aWriter( aStream, *this);
319 xWrt->SetShowProgress( sal_False );
320
321 switch( nHndlParaBrk )
322 {
323 case GETSELTXT_PARABRK_TO_BLANK:
324 xWrt->bASCII_ParaAsBlanc = sal_True;
325 xWrt->bASCII_NoLastLineEnd = sal_True;
326 break;
327
328 case GETSELTXT_PARABRK_TO_ONLYCR:
329 xWrt->bASCII_ParaAsCR = sal_True;
330 xWrt->bASCII_NoLastLineEnd = sal_True;
331 break;
332 }
333
334 //JP 09.05.00: write as UNICODE ! (and not as ANSI)
335 SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() );
336 aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 );
337 xWrt->SetAsciiOptions( aAsciiOpt );
338 xWrt->bUCS2_WithStartChar = sal_False;
339
340 long lLen;
341 if( !IsError( aWriter.Write( xWrt ) ) &&
342 STRING_MAXLEN > (( lLen = aStream.GetSize() )
343 / sizeof( sal_Unicode )) + 1 )
344 {
345 aStream << (sal_Unicode)'\0';
346
347 const sal_Unicode *p = (sal_Unicode*)aStream.GetBuffer();
348 if( p )
349 rBuf = p;
350 else
351 {
352 sal_Unicode* pStrBuf = rBuf.AllocBuffer( xub_StrLen(
353 ( lLen / sizeof( sal_Unicode ))) );
354 aStream.Seek( 0 );
355 aStream.ResetError();
356 aStream.Read( pStrBuf, lLen );
357 pStrBuf[ lLen / sizeof( sal_Unicode ) ] = '\0';
358 }
359 }
360 }
361 }
362
363 return sal_True;
364 }
365
366
367
368
369
370