xref: /trunk/main/sw/source/core/edit/edglss.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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