xref: /AOO41X/main/sw/source/core/edit/edtox.cxx (revision 69a743679e823ad8f875be547552acb607b8ada5)
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 #include <com/sun/star/util/SearchOptions.hpp>
28 #include <com/sun/star/util/SearchFlags.hpp>
29 #include <com/sun/star/i18n/TransliterationModules.hpp>
30 
31 #include <tools/urlobj.hxx>
32 
33 #include <svl/fstathelper.hxx>
34 
35 #include <svtools/txtcmp.hxx>
36 
37 #include <sfx2/docfile.hxx>
38 
39 #include <xmloff/odffields.hxx>
40 
41 #include <editeng/unolingu.hxx>
42 
43 #include <swtypes.hxx>
44 #include <editsh.hxx>
45 #include <doc.hxx>
46 #include <IDocumentUndoRedo.hxx>
47 #include <pam.hxx>
48 #include <viewopt.hxx>
49 #include <ndtxt.hxx>
50 #include <errhdl.hxx>
51 #include <swundo.hxx>
52 #include <txttxmrk.hxx>
53 #include <edimp.hxx>
54 #include <tox.hxx>
55 #include <doctxm.hxx>
56 #include <docary.hxx>
57 #include <mdiexp.hxx>
58 #include <statstr.hrc>
59 #include <bookmrk.hxx>
60 
61 
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::i18n;
64 using namespace ::com::sun::star::lang;
65 using namespace ::com::sun::star::util;
66 
67 /*--------------------------------------------------------------------
68      Beschreibung: Verzeichnismarkierung ins Dokument einfuegen/loeschen
69  --------------------------------------------------------------------*/
70 
71 
Insert(const SwTOXMark & rMark)72 void SwEditShell::Insert(const SwTOXMark& rMark)
73 {
74     sal_Bool bInsAtPos = rMark.IsAlternativeText();
75     StartAllAction();
76     FOREACHPAM_START(this)
77 
78         const SwPosition *pStt = PCURCRSR->Start(),
79                          *pEnd = PCURCRSR->End();
80         if( bInsAtPos )
81         {
82             SwPaM aTmp( *pStt );
83             GetDoc()->InsertPoolItem( aTmp, rMark, 0 );
84         }
85         else if( *pEnd != *pStt )
86         {
87             GetDoc()->InsertPoolItem(
88                 *PCURCRSR, rMark, nsSetAttrMode::SETATTR_DONTEXPAND );
89         }
90 
91     FOREACHPAM_END()
92     EndAllAction();
93 }
94 
95 
96 
DeleteTOXMark(SwTOXMark * pMark)97 void SwEditShell::DeleteTOXMark( SwTOXMark* pMark )
98 {
99     SET_CURR_SHELL( this );
100     StartAllAction();
101 
102     pDoc->DeleteTOXMark( pMark );
103 
104     EndAllAction();
105 }
106 
107 
108 /*--------------------------------------------------------------------
109      Beschreibung: Alle Verzeichnismarkierungen am SPoint zusammensuchen
110  --------------------------------------------------------------------*/
111 
GetCurTOXMarks(SwTOXMarks & rMarks) const112 sal_uInt16 SwEditShell::GetCurTOXMarks(SwTOXMarks& rMarks) const
113 {
114     return GetDoc()->GetCurTOXMark( *GetCrsr()->Start(), rMarks );
115 }
116 
117 /* -----------------01.09.99 16:05-------------------
118 
119  --------------------------------------------------*/
IsTOXBaseReadonly(const SwTOXBase & rTOXBase) const120 sal_Bool SwEditShell::IsTOXBaseReadonly(const SwTOXBase& rTOXBase) const
121 {
122     ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
123     const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
124     return  rTOXSect.IsProtect();
125 }
126 /* -----------------18.10.99 15:53-------------------
127 
128  --------------------------------------------------*/
SetTOXBaseReadonly(const SwTOXBase & rTOXBase,sal_Bool bReadonly)129 void SwEditShell::SetTOXBaseReadonly(const SwTOXBase& rTOXBase, sal_Bool bReadonly)
130 {
131     ASSERT( rTOXBase.ISA( SwTOXBaseSection ), "no TOXBaseSection!" );
132     const SwTOXBaseSection& rTOXSect = (const SwTOXBaseSection&)rTOXBase;
133     ((SwTOXBase&)rTOXBase).SetProtected(bReadonly);
134     ASSERT( rTOXSect.SwSection::GetType() == TOX_CONTENT_SECTION, "not a TOXContentSection" );
135 
136     SwSectionData aSectionData(rTOXSect);
137     aSectionData.SetProtectFlag(bReadonly);
138     UpdateSection( GetSectionFmtPos( *rTOXSect.GetFmt()  ), aSectionData, 0 );
139 }
140 
141 /* -----------------02.09.99 07:47-------------------
142 
143  --------------------------------------------------*/
GetDefaultTOXBase(TOXTypes eTyp,sal_Bool bCreate)144 const SwTOXBase*    SwEditShell::GetDefaultTOXBase( TOXTypes eTyp, sal_Bool bCreate )
145 {
146     return GetDoc()->GetDefaultTOXBase( eTyp, bCreate );
147 }
148 /* -----------------02.09.99 08:05-------------------
149 
150  --------------------------------------------------*/
SetDefaultTOXBase(const SwTOXBase & rBase)151 void    SwEditShell::SetDefaultTOXBase(const SwTOXBase& rBase)
152 {
153     GetDoc()->SetDefaultTOXBase(rBase);
154 }
155 
156 /*--------------------------------------------------------------------
157      Beschreibung: Verzeichnis einfuegen, und Inhalt erzeugen
158  --------------------------------------------------------------------*/
159 
InsertTableOf(const SwTOXBase & rTOX,const SfxItemSet * pSet)160 void SwEditShell::InsertTableOf( const SwTOXBase& rTOX, const SfxItemSet* pSet )
161 {
162     SET_CURR_SHELL( this );
163     StartAllAction();
164 
165     SwDocShell* pDocSh = GetDoc()->GetDocShell();
166     ::StartProgress( STR_STATSTR_TOX_INSERT, 0, 0, pDocSh );
167     ::SetProgressText( STR_STATSTR_TOX_INSERT, pDocSh );
168 
169     // Einfuegen des Verzeichnisses
170     const SwTOXBaseSection* pTOX = pDoc->InsertTableOf(
171                                         *GetCrsr()->GetPoint(), rTOX, pSet, sal_True );
172     ASSERT(pTOX, "Kein aktuelles Verzeichnis");
173 
174     // Formatierung anstossen
175     CalcLayout();
176 
177     // Seitennummern eintragen
178     ((SwTOXBaseSection*)pTOX)->UpdatePageNum();
179 
180     pTOX->SetPosAtStartEnd( *GetCrsr()->GetPoint() );
181 
182     // Fix fuer leere Verzeichnisse
183     InvalidateWindows( aVisArea );
184     ::EndProgress( pDocSh );
185     EndAllAction();
186 }
187 
188 /*--------------------------------------------------------------------
189      Beschreibung: Verzeichnisinhalt erneuern
190  --------------------------------------------------------------------*/
191 
UpdateTableOf(const SwTOXBase & rTOX,const SfxItemSet * pSet)192 sal_Bool SwEditShell::UpdateTableOf( const SwTOXBase& rTOX, const SfxItemSet* pSet )
193 {
194     sal_Bool bRet = sal_False;
195 
196     ASSERT( rTOX.ISA( SwTOXBaseSection ),  "keine TOXBaseSection!" );
197     SwTOXBaseSection* pTOX = (SwTOXBaseSection*)&rTOX;
198     ASSERT(pTOX, "Keine aktuelles Verzeichnis");
199     const SwSectionNode* pSectNd;
200     if( pTOX && 0 != ( pSectNd = pTOX->GetFmt()->GetSectionNode() ) )
201     {
202         SwDoc* pMyDoc = GetDoc();
203         SwDocShell* pDocSh = pMyDoc->GetDocShell();
204 
205         sal_Bool bInIndex = pTOX == GetCurTOX();
206         SET_CURR_SHELL( this );
207         StartAllAction();
208 
209         ::StartProgress( STR_STATSTR_TOX_UPDATE, 0, 0, pDocSh );
210         ::SetProgressText( STR_STATSTR_TOX_UPDATE, pDocSh );
211 
212         pMyDoc->GetIDocumentUndoRedo().StartUndo(UNDO_TOXCHANGE, NULL);
213 
214         // Verzeichnisrumpf erzeugen
215         pTOX->Update(pSet);
216 
217         // Cursor korrigieren
218         if( bInIndex )
219             pTOX->SetPosAtStartEnd( *GetCrsr()->GetPoint() );
220 
221         // Formatierung anstossen
222         CalcLayout();
223 
224         // Seitennummern eintragen
225         pTOX->UpdatePageNum();
226 
227         pMyDoc->GetIDocumentUndoRedo().EndUndo(UNDO_TOXCHANGE, NULL);
228 
229         ::EndProgress( pDocSh );
230         EndAllAction();
231     }
232     return bRet;
233 }
234 
235 /*--------------------------------------------------------------------
236      Beschreibung: Aktuelles Verzeichnis vor oder in dem der Cursor
237                                    steht
238  --------------------------------------------------------------------*/
239 
GetCurTOX() const240 const SwTOXBase* SwEditShell::GetCurTOX() const
241 {
242     return GetDoc()->GetCurTOX( *GetCrsr()->GetPoint() );
243 }
244 
DeleteTOX(const SwTOXBase & rTOXBase,sal_Bool bDelNodes)245 sal_Bool SwEditShell::DeleteTOX( const SwTOXBase& rTOXBase, sal_Bool bDelNodes )
246 {
247     return GetDoc()->DeleteTOX( (SwTOXBase&)rTOXBase, bDelNodes );
248 }
249 
250 /*--------------------------------------------------------------------
251      Beschreibung: Typen der Verzeichnisse verwalten
252  --------------------------------------------------------------------*/
253 
GetTOXType(TOXTypes eTyp,sal_uInt16 nId) const254 const SwTOXType* SwEditShell::GetTOXType(TOXTypes eTyp, sal_uInt16 nId) const
255 {
256     return pDoc->GetTOXType(eTyp, nId);
257 }
258 
259 /*--------------------------------------------------------------------
260      Beschreibung: Schluessel fuer Stichwortverzeichnisse verwalten
261  --------------------------------------------------------------------*/
262 
GetTOIKeys(SwTOIKeyType eTyp,SvStringsSort & rArr) const263 sal_uInt16 SwEditShell::GetTOIKeys( SwTOIKeyType eTyp, SvStringsSort& rArr ) const
264 {
265     return GetDoc()->GetTOIKeys( eTyp, rArr );
266 }
267 
268 
GetTOXCount() const269 sal_uInt16 SwEditShell::GetTOXCount() const
270 {
271     const SwSectionFmts& rFmts = GetDoc()->GetSections();
272     sal_uInt16 nRet = 0;
273     for( sal_uInt16 n = rFmts.Count(); n; )
274     {
275         const SwSection* pSect = rFmts[ --n ]->GetSection();
276         if( TOX_CONTENT_SECTION == pSect->GetType() &&
277             pSect->GetFmt()->GetSectionNode() )
278             ++nRet;
279     }
280     return nRet;
281 }
282 
283 
GetTOX(sal_uInt16 nPos) const284 const SwTOXBase* SwEditShell::GetTOX( sal_uInt16 nPos ) const
285 {
286     const SwSectionFmts& rFmts = GetDoc()->GetSections();
287     for( sal_uInt16 n = 0, nCnt = 0; n < rFmts.Count(); ++n )
288     {
289         const SwSection* pSect = rFmts[ n ]->GetSection();
290         if( TOX_CONTENT_SECTION == pSect->GetType() &&
291             pSect->GetFmt()->GetSectionNode() &&
292             nCnt++ == nPos )
293         {
294             ASSERT( pSect->ISA( SwTOXBaseSection ), "keine TOXBaseSection!" );
295             return (SwTOXBaseSection*)pSect;
296         }
297     }
298     return 0;
299 }
300 
301 
302     // nach einlesen einer Datei alle Verzeichnisse updaten
SetUpdateTOX(sal_Bool bFlag)303 void SwEditShell::SetUpdateTOX( sal_Bool bFlag )
304 {
305     GetDoc()->SetUpdateTOX( bFlag );
306 }
307 
308 
IsUpdateTOX() const309 sal_Bool SwEditShell::IsUpdateTOX() const
310 {
311     return GetDoc()->IsUpdateTOX();
312 }
313 
314 /* -----------------26.08.99 13:49-------------------
315 
316  --------------------------------------------------*/
GetTOIAutoMarkURL() const317 const String&   SwEditShell::GetTOIAutoMarkURL() const
318 {
319     return GetDoc()->GetTOIAutoMarkURL();
320 }
321 /* -----------------26.08.99 13:49-------------------
322 
323  --------------------------------------------------*/
SetTOIAutoMarkURL(const String & rSet)324 void SwEditShell::SetTOIAutoMarkURL(const String& rSet)
325 {
326     GetDoc()->SetTOIAutoMarkURL(rSet);
327 }
328 /* -----------------26.08.99 09:29-------------------
329 
330  --------------------------------------------------*/
ApplyAutoMark()331 void SwEditShell::ApplyAutoMark()
332 {
333     StartAllAction();
334     sal_Bool bDoesUndo = DoesUndo();
335     DoUndo(sal_False);
336     //1. remove all automatic generated index entries if AutoMarkURL has a
337     //   length and the file exists
338     //2. load file
339     //3. select all occurrences of the searched words
340     //4. apply index entries
341 
342     String sAutoMarkURL(GetDoc()->GetTOIAutoMarkURL());
343     if( sAutoMarkURL.Len() && FStatHelper::IsDocument( sAutoMarkURL ))
344     {
345         //1.
346         const SwTOXType* pTOXType = GetTOXType(TOX_INDEX, 0);
347 
348         SwTOXMarks aMarks;
349         SwTOXMark::InsertTOXMarks( aMarks, *pTOXType );
350         for( sal_uInt16 nMark=0; nMark<aMarks.Count(); nMark++ )
351         {
352             SwTOXMark* pMark = aMarks[nMark];
353             if(pMark->IsAutoGenerated() && pMark->GetTxtTOXMark())
354                 // mba: test iteration; objects are deleted in iteration
355                 DeleteTOXMark(pMark);
356         }
357 
358         //2.
359         SfxMedium aMedium( sAutoMarkURL, STREAM_STD_READ, sal_True );
360         SvStream& rStrm = *aMedium.GetInStream();
361         const String sZero('0');
362         Push();
363         rtl_TextEncoding eChrSet = ::gsl_getSystemTextEncoding();
364 
365         //
366         // SearchOptions to be used in loop below
367         //
368         //SearchAlgorithms eSrchType    = SearchAlgorithms_ABSOLUTE;
369         //OUString aSrchStr = rText;
370         sal_Bool bCaseSensitive = sal_True;
371         sal_Bool bWordOnly      = sal_False;
372         sal_Bool bSrchInSel     = sal_False;
373         sal_Bool bLEV_Relaxed   = sal_True;
374         sal_Int32 nLEV_Other    = 2;    //  -> changedChars;
375         sal_Int32 nLEV_Longer   = 3;    //! -> deletedChars;
376         sal_Int32 nLEV_Shorter  = 1;    //! -> insertedChars;
377         sal_Int32 nTransliterationFlags = 0;
378         //
379         sal_Int32 nSrchFlags = 0;
380         if (!bCaseSensitive)
381         {
382             nSrchFlags |= SearchFlags::ALL_IGNORE_CASE;
383             nTransliterationFlags |= TransliterationModules_IGNORE_CASE;
384         }
385         if ( bWordOnly)
386             nSrchFlags |= SearchFlags::NORM_WORD_ONLY;
387         if ( bLEV_Relaxed)
388             nSrchFlags |= SearchFlags::LEV_RELAXED;
389         if ( bSrchInSel)
390             nSrchFlags |= (SearchFlags::REG_NOT_BEGINOFLINE |
391                             SearchFlags::REG_NOT_ENDOFLINE );
392         //
393         rtl::OUString sEmpty;
394         SearchOptions aSearchOpt(
395                             SearchAlgorithms_ABSOLUTE, nSrchFlags,
396                             sEmpty, sEmpty,
397                             SvxCreateLocale( LANGUAGE_SYSTEM ),
398                             nLEV_Other, nLEV_Longer, nLEV_Shorter,
399                             nTransliterationFlags );
400 
401         while( !rStrm.GetError() && !rStrm.IsEof() )
402         {
403             ByteString aRdLine;
404             rStrm.ReadLine( aRdLine );
405 
406             // # -> comment
407             // ; -> delimiter between entries ->
408             // Format: TextToSearchFor;AlternativeString;PrimaryKey;SecondaryKey;CaseSensitive;WordOnly
409             // Leading and trailing blanks are ignored
410             if( aRdLine.Len() && '#' != aRdLine.GetChar(0) )
411             {
412                 String sLine( aRdLine, eChrSet );
413 
414                 xub_StrLen nTokenPos = 0;
415                 String sToSelect( sLine.GetToken(0, ';', nTokenPos ) );
416                 if( sToSelect.Len() )
417                 {
418                     String sAlternative = sLine.GetToken(0, ';', nTokenPos);
419                     String sPrimary     = sLine.GetToken(0, ';', nTokenPos);
420                     String sSecondary   = sLine.GetToken(0, ';', nTokenPos);
421                     String sCase        = sLine.GetToken(0, ';', nTokenPos);
422                     String sWordOnly    = sLine.GetToken(0, ';', nTokenPos);
423 
424                     //3.
425                     bCaseSensitive  = sCase.Len() && sCase != sZero;
426                     bWordOnly       = sWordOnly.Len() && sWordOnly != sZero;
427                     //
428                     if (!bCaseSensitive)
429                     {
430                         //nSrchFlags |= SearchFlags::ALL_IGNORE_CASE;
431                         aSearchOpt.transliterateFlags |=
432                                      TransliterationModules_IGNORE_CASE;
433                     }
434                     else
435                     {
436                         //aSearchOpt.searchFlag &= ~SearchFlags::ALL_IGNORE_CASE;
437                         aSearchOpt.transliterateFlags &=
438                                     ~TransliterationModules_IGNORE_CASE;
439                     }
440                     if ( bWordOnly)
441                         aSearchOpt.searchFlag |=  SearchFlags::NORM_WORD_ONLY;
442                     else
443                         aSearchOpt.searchFlag &= ~SearchFlags::NORM_WORD_ONLY;
444                     //
445                     aSearchOpt.searchString = sToSelect;
446 
447                     KillPams();
448                     sal_Bool bCancel;
449 
450                     // todo/mba: assuming that notes shouldn't be searched
451                     sal_Bool bSearchInNotes = sal_False;
452                     sal_uLong nRet = Find( aSearchOpt,  bSearchInNotes, DOCPOS_START, DOCPOS_END, bCancel,
453                                     (FindRanges)(FND_IN_SELALL|FND_IN_BODYONLY),
454                                     sal_False );
455 
456                     if(nRet)
457                     {
458                         SwTOXMark* pTmpMark = new SwTOXMark(pTOXType);
459                         if( sPrimary.Len() )
460                         {
461                             pTmpMark->SetPrimaryKey( sPrimary );
462                             if( sSecondary.Len() )
463                                 pTmpMark->SetSecondaryKey( sSecondary );
464                         }
465                         if(sAlternative.Len())
466                             pTmpMark->SetAlternativeText(sAlternative);
467                         pTmpMark->SetMainEntry(sal_False);
468                         pTmpMark->SetAutoGenerated(sal_True);
469                         //4.
470                         SwEditShell::Insert(*pTmpMark);
471                     }
472                 }
473             }
474         }
475         KillPams();
476         Pop(sal_False);
477     }
478     DoUndo(bDoesUndo);
479     EndAllAction();
480 }
481 
482 
483 
484