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