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