LibreOffice Module sw (master)  1
edtox.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/util/SearchAlgorithms2.hpp>
21 #include <com/sun/star/util/SearchFlags.hpp>
24 #include <i18nutil/searchopt.hxx>
25 #include <svl/fstathelper.hxx>
26 #include <osl/thread.h>
27 #include <unotools/textsearch.hxx>
28 #include <unotools/syslocale.hxx>
29 
30 #include <sfx2/docfile.hxx>
31 
32 #include <xmloff/odffields.hxx>
33 
34 #include <editeng/unolingu.hxx>
35 
36 #include <swtypes.hxx>
37 #include <editsh.hxx>
38 #include <doc.hxx>
39 #include <IDocumentUndoRedo.hxx>
40 #include <pam.hxx>
41 #include <viewopt.hxx>
42 #include <ndtxt.hxx>
43 #include <swundo.hxx>
44 #include <txttxmrk.hxx>
45 #include <edimp.hxx>
46 #include <tox.hxx>
47 #include <doctxm.hxx>
48 #include <docary.hxx>
49 #include <mdiexp.hxx>
50 #include <strings.hrc>
51 #include <bookmrk.hxx>
52 
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::i18n;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::util;
57 
58 // Add/delete listing markers to a document
59 
60 void SwEditShell::Insert(const SwTOXMark& rMark)
61 {
62  bool bInsAtPos = rMark.IsAlternativeText();
64  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
65  {
66  const SwPosition *pStt = rPaM.Start(),
67  *pEnd = rPaM.End();
68  if( bInsAtPos )
69  {
70  SwPaM aTmp( *pStt );
72  }
73  else if( *pEnd != *pStt )
74  {
76  rPaM, rMark, SetAttrMode::DONTEXPAND );
77  }
78 
79  }
80  EndAllAction();
81 }
82 
84 {
85  SET_CURR_SHELL( this );
87 
88  mxDoc->DeleteTOXMark( pMark );
89 
90  EndAllAction();
91 }
92 
95 {
96  SwDoc::GetCurTOXMark( *GetCursor()->Start(), rMarks );
97 }
98 
100 {
101  OSL_ENSURE( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) != nullptr, "no TOXBaseSection!" );
102  const SwTOXBaseSection& rTOXSect = static_cast<const SwTOXBaseSection&>(rTOXBase);
103  return rTOXSect.IsProtect();
104 }
105 
106 void SwEditShell::SetTOXBaseReadonly(const SwTOXBase& rTOXBase, bool bReadonly)
107 {
108  OSL_ENSURE( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) != nullptr, "no TOXBaseSection!" );
109  const SwTOXBaseSection& rTOXSect = static_cast<const SwTOXBaseSection&>(rTOXBase);
110  const_cast<SwTOXBase&>(rTOXBase).SetProtected(bReadonly);
111  OSL_ENSURE( rTOXSect.SwSection::GetType() == TOX_CONTENT_SECTION, "not a TOXContentSection" );
112 
113  SwSectionData aSectionData(rTOXSect);
114  aSectionData.SetProtectFlag(bReadonly);
115  UpdateSection( GetSectionFormatPos( *rTOXSect.GetFormat() ), aSectionData );
116 }
117 
119 {
120  return GetDoc()->GetDefaultTOXBase( eTyp, bCreate );
121 }
122 
124 {
125  GetDoc()->SetDefaultTOXBase(rBase);
126 }
127 
129 void SwEditShell::InsertTableOf( const SwTOXBase& rTOX, const SfxItemSet* pSet )
130 {
131  SET_CURR_SHELL( this );
132  StartAllAction();
133 
134  SwDocShell* pDocSh = GetDoc()->GetDocShell();
135  ::StartProgress( STR_STATSTR_TOX_INSERT, 0, 0, pDocSh );
136 
137  // Insert listing
138  const SwTOXBaseSection* pTOX = mxDoc->InsertTableOf(
139  *GetCursor()->GetPoint(), rTOX, pSet, true, GetLayout() );
140  OSL_ENSURE(pTOX, "No current TOX");
141 
142  // start formatting
143  CalcLayout();
144 
145  // insert page numbering
146  const_cast<SwTOXBaseSection*>(pTOX)->UpdatePageNum();
147 
148  pTOX->SetPosAtStartEnd( *GetCursor()->GetPoint() );
149 
150  // Fix for empty listing
152  ::EndProgress( pDocSh );
153  EndAllAction();
154 }
155 
157 void SwEditShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
158 {
159  assert(dynamic_cast<const SwTOXBaseSection*>(&rTOX) && "no TOXBaseSection!");
160  SwTOXBaseSection& rTOXSect = static_cast<SwTOXBaseSection&>(const_cast<SwTOXBase&>(rTOX));
161  if (rTOXSect.GetFormat()->GetSectionNode())
162  {
163  SwDoc* pMyDoc = GetDoc();
164  SwDocShell* pDocSh = pMyDoc->GetDocShell();
165 
166  bool bInIndex = &rTOX == GetCurTOX();
167  SET_CURR_SHELL( this );
168  StartAllAction();
169 
170  ::StartProgress( STR_STATSTR_TOX_UPDATE, 0, 0, pDocSh );
171 
173 
174  // create listing stub
175  rTOXSect.Update(pSet, GetLayout());
176 
177  // correct Cursor
178  if( bInIndex )
179  rTOXSect.SetPosAtStartEnd(*GetCursor()->GetPoint());
180 
181  // start formatting
182  CalcLayout();
183 
184  // insert page numbering
185  rTOXSect.UpdatePageNum();
186 
188 
189  ::EndProgress( pDocSh );
190  EndAllAction();
191  }
192 }
193 
196 {
197  return SwDoc::GetCurTOX( *GetCursor()->GetPoint() );
198 }
199 
200 bool SwEditShell::DeleteTOX( const SwTOXBase& rTOXBase, bool bDelNodes )
201 {
202  return GetDoc()->DeleteTOX( rTOXBase, bDelNodes );
203 }
204 
205 // manage types of listings
206 
207 const SwTOXType* SwEditShell::GetTOXType(TOXTypes eTyp, sal_uInt16 nId) const
208 {
209  return mxDoc->GetTOXType(eTyp, nId);
210 }
211 
212 // manage keys for the alphabetical index
213 
214 void SwEditShell::GetTOIKeys( SwTOIKeyType eTyp, std::vector<OUString>& rArr ) const
215 {
216  GetDoc()->GetTOIKeys( eTyp, rArr, *GetLayout() );
217 }
218 
219 sal_uInt16 SwEditShell::GetTOXCount() const
220 {
221  const SwSectionFormats& rFormats = GetDoc()->GetSections();
222  sal_uInt16 nRet = 0;
223  for( auto n = rFormats.size(); n; )
224  {
225  const SwSection* pSect = rFormats[ --n ]->GetSection();
226  if( TOX_CONTENT_SECTION == pSect->GetType() &&
227  pSect->GetFormat()->GetSectionNode() )
228  ++nRet;
229  }
230  return nRet;
231 }
232 
233 const SwTOXBase* SwEditShell::GetTOX( sal_uInt16 nPos ) const
234 {
235  const SwSectionFormats& rFormats = GetDoc()->GetSections();
236  sal_uInt16 nCnt {0};
237  for( const SwSectionFormat *pFormat : rFormats )
238  {
239  const SwSection* pSect = pFormat->GetSection();
240  if( TOX_CONTENT_SECTION == pSect->GetType() &&
241  pSect->GetFormat()->GetSectionNode() &&
242  nCnt++ == nPos )
243  {
244  OSL_ENSURE( dynamic_cast<const SwTOXBaseSection*>( pSect) != nullptr, "no TOXBaseSection!" );
245  return static_cast<const SwTOXBaseSection*>(pSect);
246  }
247  }
248  return nullptr;
249 }
250 
252 void SwEditShell::SetUpdateTOX( bool bFlag )
253 {
254  GetDoc()->SetUpdateTOX( bFlag );
255 }
256 
258 {
259  return GetDoc()->IsUpdateTOX();
260 }
261 
262 OUString const & SwEditShell::GetTOIAutoMarkURL() const
263 {
264  return GetDoc()->GetTOIAutoMarkURL();
265 }
266 
267 void SwEditShell::SetTOIAutoMarkURL(const OUString& rSet)
268 {
269  GetDoc()->SetTOIAutoMarkURL(rSet);
270 }
271 
273 {
274  StartAllAction();
275  bool bDoesUndo = DoesUndo();
276  DoUndo(false);
277  //1. remove all automatic generated index entries if AutoMarkURL has a
278  // length and the file exists
279  //2. load file
280  //3. select all occurrences of the searched words
281  //4. apply index entries
282 
283  OUString sAutoMarkURL(GetDoc()->GetTOIAutoMarkURL());
284  if( !sAutoMarkURL.isEmpty() && FStatHelper::IsDocument( sAutoMarkURL ))
285  {
286  //1.
287  const SwTOXType* pTOXType = GetTOXType(TOX_INDEX, 0);
288 
289  SwTOXMarks aMarks;
290  SwTOXMark::InsertTOXMarks( aMarks, *pTOXType );
291  for( SwTOXMark* pMark : aMarks )
292  {
293  if(pMark->IsAutoGenerated() && pMark->GetTextTOXMark())
294  // mba: test iteration; objects are deleted in iteration
295  DeleteTOXMark(pMark);
296  }
297 
298  //2.
299  SfxMedium aMedium( sAutoMarkURL, StreamMode::STD_READ );
300  SvStream& rStrm = *aMedium.GetInStream();
301  Push();
302  rtl_TextEncoding eChrSet = ::osl_getThreadTextEncoding();
303 
304  // SearchOptions to be used in loop below
305  sal_Int32 const nLEV_Other = 2; // -> changedChars;
306  sal_Int32 const nLEV_Longer = 3;
307  sal_Int32 const nLEV_Shorter = 1;
308 
309  i18nutil::SearchOptions2 aSearchOpt(
310  SearchAlgorithms_ABSOLUTE,
311  SearchFlags::LEV_RELAXED,
312  "", "",
313  SvtSysLocale().GetLanguageTag().getLocale(),
314  nLEV_Other, nLEV_Longer, nLEV_Shorter,
315  TransliterationFlags::NONE,
316  SearchAlgorithms2::ABSOLUTE,
317  '\\' );
318 
319  while (rStrm.good())
320  {
321  OString aRdLine;
322  rStrm.ReadLine( aRdLine );
323 
324  // # -> comment
325  // ; -> delimiter between entries ->
326  // Format: TextToSearchFor;AlternativeString;PrimaryKey;SecondaryKey;CaseSensitive;WordOnly
327  // Leading and trailing blanks are ignored
328  if( !aRdLine.isEmpty() && '#' != aRdLine[0] )
329  {
330  OUString sLine(OStringToOUString(aRdLine, eChrSet));
331 
332  sal_Int32 nTokenPos = 0;
333  OUString sToSelect( sLine.getToken(0, ';', nTokenPos ) );
334  if( !sToSelect.isEmpty() )
335  {
336  OUString sAlternative = sLine.getToken(0, ';', nTokenPos);
337  OUString sPrimary = sLine.getToken(0, ';', nTokenPos);
338  OUString sSecondary = sLine.getToken(0, ';', nTokenPos);
339  OUString sCase = sLine.getToken(0, ';', nTokenPos);
340  OUString sWordOnly = sLine.getToken(0, ';', nTokenPos);
341 
342  //3.
343  bool bCaseSensitive = !sCase.isEmpty() && sCase != "0";
344  bool bWordOnly = !sWordOnly.isEmpty() && sWordOnly != "0";
345 
346  if (!bCaseSensitive)
347  {
348  aSearchOpt.transliterateFlags |=
349  TransliterationFlags::IGNORE_CASE;
350  }
351  else
352  {
353  aSearchOpt.transliterateFlags &=
354  ~TransliterationFlags::IGNORE_CASE;
355  }
356  if ( bWordOnly)
357  aSearchOpt.searchFlag |= SearchFlags::NORM_WORD_ONLY;
358  else
359  aSearchOpt.searchFlag &= ~SearchFlags::NORM_WORD_ONLY;
360 
361  aSearchOpt.searchString = sToSelect;
362 
363  KillPams();
364  bool bCancel;
365 
366  // todo/mba: assuming that notes shouldn't be searched
367  sal_uLong nRet = Find_Text(aSearchOpt, false/*bSearchInNotes*/, SwDocPositions::Start, SwDocPositions::End, bCancel,
369 
370  if(nRet)
371  {
372  SwTOXMark* pTmpMark = new SwTOXMark(pTOXType);
373  if( !sPrimary.isEmpty() )
374  {
375  pTmpMark->SetPrimaryKey( sPrimary );
376  if( !sSecondary.isEmpty() )
377  pTmpMark->SetSecondaryKey( sSecondary );
378  }
379  if( !sAlternative.isEmpty() )
380  pTmpMark->SetAlternativeText(sAlternative);
381  pTmpMark->SetMainEntry(false);
382  pTmpMark->SetAutoGenerated(true);
383  //4.
384  SwEditShell::Insert(*pTmpMark);
385  }
386  }
387  }
388  }
389  KillPams();
391  }
392  DoUndo(bDoesUndo);
393  EndAllAction();
394 }
395 
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
TOXTypes
Definition: toxe.hxx:39
SVL_DLLPUBLIC bool IsDocument(const OUString &rURL)
void KillPams()
Definition: crsrsh.cxx:1010
bool IsAlternativeText() const
Definition: tox.hxx:545
sal_uLong Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, bool bReplace=false)
Definition: crsrsh.cxx:3336
size_t GetSectionFormatPos(const SwSectionFormat &) const
Definition: edsect.cxx:136
Marks a position in the document model.
Definition: pam.hxx:35
const OUString & GetTOIAutoMarkURL() const
Definition: doc.hxx:945
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:185
SwDocShell * GetDocShell()
Definition: doc.hxx:1340
void InsertTableOf(const SwTOXBase &rTOX, const SfxItemSet *pSet=nullptr)
Insert content table. Renew if required.
Definition: edtox.cxx:129
static SwTOXBase * GetCurTOX(const SwPosition &rPos)
Get current table of contents.
Definition: doctxm.cxx:449
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, bool bExpandCharToPara=false)=0
Insert an attribute.
void UpdateTableOf(const SwTOXBase &rTOX, const SfxItemSet *pSet=nullptr)
update tables of content
Definition: edtox.cxx:157
sal_uIntPtr sal_uLong
std::vector< SwTOXMark * > SwTOXMarks
Definition: tox.hxx:44
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
Definition: doc.hxx:185
static void InsertTOXMarks(SwTOXMarks &aMarks, const SwTOXType &rType)
Definition: tox.cxx:188
void SetTOIAutoMarkURL(const OUString &rSet)
Definition: edtox.cxx:267
bool IsUpdateTOX() const
Definition: doc.hxx:943
void EndProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:88
SwSectionFormat * GetFormat()
Definition: section.hxx:337
OUString const & GetTOIAutoMarkURL() const
AutoMark file.
Definition: edtox.cxx:262
void DoUndo(bool bOn=true)
Undo.
Definition: edws.cxx:199
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:347
void EndAllAction()
Definition: edws.cxx:96
static bool IsTOXBaseReadonly(const SwTOXBase &rTOXBase)
Definition: edtox.cxx:99
Array of Undo-history.
Definition: docary.hxx:299
void UpdateSection(size_t const nSect, SwSectionData &, SfxItemSet const *const =nullptr)
Definition: edsect.cxx:156
void StartProgress(const char *pMessResId, long nStartValue, long nEndValue, SwDocShell *pDocShell)
Definition: mainwn.cxx:48
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:174
void DeleteTOXMark(SwTOXMark const *pMark)
Definition: edtox.cxx:83
SwSectionNode * GetSectionNode()
Definition: section.cxx:1007
bool ReadLine(OString &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
SwTOIKeyType
Definition: toxe.hxx:30
const SwTOXBase * GetTOX(sal_uInt16 nPos) const
Definition: edtox.cxx:233
void SetTOIAutoMarkURL(const OUString &rSet)
Definition: doc.hxx:946
SwRect maVisArea
The modern version of VisArea.
Definition: viewsh.hxx:172
bool DeleteTOX(const SwTOXBase &rTOXBase, bool bDelNodes)
Delete table of contents.
Definition: doctxm.cxx:525
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
const SwTOXBase * GetCurTOX() const
Get current listing before or at the Cursor.
Definition: edtox.cxx:195
void SetAlternativeText(const OUString &rAlt)
Definition: tox.hxx:548
TransliterationFlags
bool IsUpdateTOX() const
Definition: edtox.cxx:257
void UpdatePageNum()
Calculate PageNumber and insert after formatting.
Definition: doctxm.cxx:1599
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void GetTOIKeys(SwTOIKeyType eTyp, std::vector< OUString > &rArr) const
Key for managing index.
Definition: edtox.cxx:214
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
const SwTOXBase * GetDefaultTOXBase(TOXTypes eTyp, bool bCreate=false)
Definition: edtox.cxx:118
void SetPrimaryKey(const OUString &rStr)
Definition: tox.hxx:568
bool IsProtect() const
Definition: section.cxx:354
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2143
TransliterationFlags transliterateFlags
bool SetPosAtStartEnd(SwPosition &rPos) const
Definition: doctxm.cxx:756
void SetUpdateTOX(bool bFlag)
Definition: doc.hxx:942
All (only in non-body and selections).
sal_uInt16 GetTOXCount() const
Definition: edtox.cxx:219
size_t size() const
Definition: docary.hxx:91
#define SET_CURR_SHELL(shell)
Definition: swtypes.hxx:101
void GetTOIKeys(SwTOIKeyType eTyp, std::vector< OUString > &rArr, SwRootFrame const &rLayout) const
Definition: doctxm.cxx:91
ring_container GetRingContainer()
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:551
void SetAutoGenerated(bool bSet)
Definition: tox.hxx:130
void SetDefaultTOXBase(const SwTOXBase &rBase)
Definition: edtox.cxx:123
void SetTOXBaseReadonly(const SwTOXBase &rTOXBase, bool bReadonly)
Definition: edtox.cxx:106
SvStream * GetInStream()
void Update(const SfxItemSet *pAttr=nullptr, SwRootFrame const *pLayout=nullptr, const bool _bNewTOX=false)
Collect table of contents content.
Definition: doctxm.cxx:771
static sal_uInt16 GetCurTOXMark(const SwPosition &rPos, SwTOXMarks &)
Get current table of contents Mark.
Definition: doctxm.cxx:122
void SetUpdateTOX(bool bFlag)
After reading file update all content tables.
Definition: edtox.cxx:252
void SetSecondaryKey(const OUString &rStr)
Definition: tox.hxx:574
const SwTOXType * GetTOXType(TOXTypes eTyp, sal_uInt16 nId) const
Definition: edtox.cxx:207
virtual void CalcLayout() override
To enable set up of StartActions and EndActions.
Definition: edws.cxx:107
void GetCurTOXMarks(SwTOXMarks &rMarks) const
Get all marks at current SPoint.
Definition: edtox.cxx:94
bool good() const
void Insert(sal_Unicode, bool bOnlyCurrCursor=false)
Edit (all selected ranges).
Definition: editsh.cxx:68
void ApplyAutoMark()
Definition: edtox.cxx:272
SectionType GetType() const
Definition: section.hxx:171
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2165
bool DoesUndo() const
Definition: edws.cxx:202
void SetDefaultTOXBase(const SwTOXBase &rBase)
Definition: doctxm.cxx:504
void StartAllAction()
For all views of this document.
Definition: edws.cxx:85
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2072
SwSectionFormats & GetSections()
Definition: doc.hxx:1326
void SetMainEntry(bool bSet)
Definition: tox.hxx:133
bool DeleteTOX(const SwTOXBase &rTOXBase, bool bDelNodes)
Definition: edtox.cxx:200
const SwTOXBase * GetDefaultTOXBase(TOXTypes eTyp, bool bCreate)
Definition: doctxm.cxx:478