xref: /AOO41X/main/sw/source/ui/misc/redlndlg.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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 #define _SVSTDARR_STRINGSSORTDTOR
29 #define _SVSTDARR_USHORTSSORT
30 #define _SVSTDARR_USHORTS
31 
32 
33 #include <redline.hxx>
34 #include <tools/datetime.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <svl/svstdarr.hxx>
37 #include <svl/eitem.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <svx/ctredlin.hxx>
41 #include <svx/postattr.hxx>
42 #include <swtypes.hxx>
43 #include <wrtsh.hxx>
44 #include <view.hxx>
45 #include <swmodule.hxx>
46 #ifndef _REDLNDLG_HXX
47 #define _REDLNACCEPTDLG
48 #include <redlndlg.hxx>
49 #endif
50 #include <swwait.hxx>
51 #include <uitool.hxx>
52 
53 #include <helpid.h>
54 #include <cmdid.h>
55 #include <misc.hrc>
56 #include <redlndlg.hrc>
57 #include <shells.hrc>
58 
59 // -> #111827#
60 #include <comcore.hrc>
61 #include <swundo.hxx>
62 #include <SwRewriter.hxx>
63 // <- #111827#
64 
65 #include <vector>
66 #include <svx/svxdlg.hxx>
67 #include <svx/dialogs.hrc>
68 
69 #include <unomid.h>
70 
71 #include <docsh.hxx>
72 
73 #include <IDocumentRedlineAccess.hxx>
74 
75 /*------------------------------------------------------------------------
76     Beschreibung:
77 ------------------------------------------------------------------------*/
78 
79 SFX_IMPL_MODELESSDIALOG( SwRedlineAcceptChild, FN_REDLINE_ACCEPT )
80 
81 SV_IMPL_PTRARR(SwRedlineDataParentArr, SwRedlineDataParentPtr)
82 SV_IMPL_OP_PTRARR_SORT(SwRedlineDataParentSortArr, SwRedlineDataParentPtr)
83 SV_IMPL_PTRARR(SwRedlineDataChildArr, SwRedlineDataChildPtr)
84 SV_IMPL_PTRARR(SvLBoxEntryArr, SvLBoxEntryPtr)
85 
86 static sal_uInt16 nSortMode = 0xffff;
87 static sal_Bool   bSortDir = sal_True;
88 
89 /*------------------------------------------------------------------------
90     Beschreibung:
91 ------------------------------------------------------------------------*/
92 
93 SwRedlineAcceptChild::SwRedlineAcceptChild( Window* _pParent,
94                                             sal_uInt16 nId,
95                                             SfxBindings* pBindings,
96                                             SfxChildWinInfo* pInfo ) :
97     SwChildWinWrapper( _pParent, nId )
98 {
99     pWindow = new SwModelessRedlineAcceptDlg( pBindings, this, _pParent);
100 
101     ((SwModelessRedlineAcceptDlg *)pWindow)->Initialize(pInfo);
102 }
103 
104 /*--------------------------------------------------------------------
105     Beschreibung: Nach Dok-Wechsel Dialog neu initialisieren
106  --------------------------------------------------------------------*/
107 
108 sal_Bool SwRedlineAcceptChild::ReInitDlg(SwDocShell *pDocSh)
109 {
110     sal_Bool bRet;
111 
112     if ((bRet = SwChildWinWrapper::ReInitDlg(pDocSh)) == sal_True)  // Sofort aktualisieren, Dok-Wechsel
113         ((SwModelessRedlineAcceptDlg*)GetWindow())->Activate();
114 
115     return bRet;
116 }
117 
118 /*------------------------------------------------------------------------
119     Beschreibung:
120 ------------------------------------------------------------------------*/
121 
122 SwModelessRedlineAcceptDlg::SwModelessRedlineAcceptDlg( SfxBindings* _pBindings,
123                                                         SwChildWinWrapper* pChild,
124                                                         Window *_pParent) :
125     SfxModelessDialog(_pBindings, pChild, _pParent, SW_RES(DLG_REDLINE_ACCEPT)),
126     pChildWin       (pChild)
127 {
128     pImplDlg = new SwRedlineAcceptDlg(this);
129 
130     FreeResource();
131 }
132 
133 /*--------------------------------------------------------------------
134     Beschreibung:
135  --------------------------------------------------------------------*/
136 
137 void SwModelessRedlineAcceptDlg::Activate()
138 {
139     SwView *pView = ::GetActiveView();
140 
141     if (!pView) // Kann passieren, wenn man auf eine andere App umschaltet, wenn
142         return; // vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug)
143 
144     SwDocShell *pDocSh = pView->GetDocShell();
145 
146     if (pChildWin->GetOldDocShell() != pDocSh)
147     {   // Dok-Wechsel
148         SwWait aWait( *pDocSh, sal_False );
149         SwWrtShell* pSh = pView->GetWrtShellPtr();
150 
151         pChildWin->SetOldDocShell(pDocSh);  // Rekursion vermeiden (durch Modified-Hdl)
152 
153         sal_Bool bMod = pSh->IsModified();
154         SfxBoolItem aShow(FN_REDLINE_SHOW, sal_True);
155         pSh->GetView().GetViewFrame()->GetDispatcher()->Execute(
156             FN_REDLINE_SHOW, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD, &aShow, 0L);
157         if (!bMod)
158             pSh->ResetModified();
159         pImplDlg->Init();
160 
161         return;
162     }
163 
164     pImplDlg->Activate();
165 }
166 
167 /*--------------------------------------------------------------------
168     Beschreibung:
169  --------------------------------------------------------------------*/
170 
171 void SwModelessRedlineAcceptDlg::Initialize(SfxChildWinInfo *pInfo)
172 {
173     String aStr;
174     if (pInfo != NULL)
175         pImplDlg->Initialize(pInfo->aExtraString);
176 
177     SfxModelessDialog::Initialize(pInfo);
178 }
179 
180 /*--------------------------------------------------------------------
181     Beschreibung:
182  --------------------------------------------------------------------*/
183 
184 void SwModelessRedlineAcceptDlg::FillInfo(SfxChildWinInfo& rInfo) const
185 {
186     SfxModelessDialog::FillInfo(rInfo);
187     pImplDlg->FillInfo(rInfo.aExtraString);
188 }
189 
190 /*------------------------------------------------------------------------
191     Beschreibung:
192 ------------------------------------------------------------------------*/
193 
194 void SwModelessRedlineAcceptDlg::Resize()
195 {
196     pImplDlg->Resize();
197     SfxModelessDialog::Resize();
198 }
199 
200 /*------------------------------------------------------------------------
201     Beschreibung:
202 ------------------------------------------------------------------------*/
203 
204 SwModelessRedlineAcceptDlg::~SwModelessRedlineAcceptDlg()
205 {
206     delete pImplDlg;
207 }
208 
209 /*------------------------------------------------------------------------
210     Beschreibung:
211 ------------------------------------------------------------------------*/
212 
213 SwRedlineAcceptDlg::SwRedlineAcceptDlg(Dialog *pParent, sal_Bool bAutoFmt) :
214     pParentDlg      (pParent),
215     aTabPagesCTRL   (pParent, SW_RES(CTRL_TABPAGES)),
216     aPopup          (SW_RES(MN_REDLINE_POPUP)),
217     sInserted       (SW_RES(STR_REDLINE_INSERTED)),
218     sDeleted        (SW_RES(STR_REDLINE_DELETED)),
219     sFormated       (SW_RES(STR_REDLINE_FORMATED)),
220     sTableChgd      (SW_RES(STR_REDLINE_TABLECHG)),
221     sFmtCollSet     (SW_RES(STR_REDLINE_FMTCOLLSET)),
222     sAutoFormat     (SW_RES(STR_REDLINE_AUTOFMT)),
223     bOnlyFormatedRedlines( sal_False ),
224     bHasReadonlySel ( sal_False ),
225     bRedlnAutoFmt   (bAutoFmt),
226     bInhibitActivate( false )
227 {
228     aTabPagesCTRL.SetHelpId(HID_REDLINE_CTRL);
229     pTPView = aTabPagesCTRL.GetViewPage();
230     pTable = pTPView->GetTableControl();
231 
232     pTPView->InsertWriterHeader();
233     pTPView->SetAcceptClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptHdl));
234     pTPView->SetAcceptAllClickHdl(LINK(this, SwRedlineAcceptDlg, AcceptAllHdl));
235     pTPView->SetRejectClickHdl(LINK(this, SwRedlineAcceptDlg, RejectHdl));
236     pTPView->SetRejectAllClickHdl(LINK(this, SwRedlineAcceptDlg, RejectAllHdl));
237     pTPView->SetUndoClickHdl(LINK(this, SwRedlineAcceptDlg, UndoHdl));
238 
239     aTabPagesCTRL.GetFilterPage()->SetReadyHdl(LINK(this, SwRedlineAcceptDlg, FilterChangedHdl));
240 
241     ListBox *pActLB = aTabPagesCTRL.GetFilterPage()->GetLbAction();
242     pActLB->InsertEntry(sInserted);
243     pActLB->InsertEntry(sDeleted);
244     pActLB->InsertEntry(sFormated);
245     pActLB->InsertEntry(sTableChgd);
246 
247     if (HasRedlineAutoFmt())
248     {
249         pActLB->InsertEntry(sFmtCollSet);
250         pActLB->InsertEntry(sAutoFormat);
251         pTPView->ShowUndo(sal_True);
252         pTPView->DisableUndo();     // Noch gibts keine UNDO-Events
253     }
254 
255     pActLB->SelectEntryPos(0);
256 
257     pTable->SetStyle(pTable->GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
258     pTable->SetNodeDefaultImages();
259     pTable->SetSelectionMode(MULTIPLE_SELECTION);
260     pTable->SetHighlightRange(1);
261 
262     static long aStaticTabs[]=
263     {
264         4,10,70,120,170
265     };
266 
267     pTable->SetTabs(aStaticTabs);
268 
269     // Minimalgroesse setzen
270     Size aMinSz(aTabPagesCTRL.GetMinSizePixel());
271     Point aPos(aTabPagesCTRL.GetPosPixel());
272 
273     aMinSz.Width() += (aPos.X() * 2 - 1);
274     aMinSz.Height() += (aPos.Y() * 2 - 1);
275     pParentDlg->SetMinOutputSizePixel(aMinSz);
276 
277     if (pParentDlg->GetOutputSizePixel().Width() < aMinSz.Width())
278         pParentDlg->SetOutputSizePixel(Size(aMinSz.Width(), pParentDlg->GetOutputSizePixel().Height()));
279     if (pParentDlg->GetOutputSizePixel().Height() < aMinSz.Height())
280         pParentDlg->SetOutputSizePixel(Size(pParentDlg->GetOutputSizePixel().Width(), aMinSz.Height()));
281 
282     pTable->SortByCol(nSortMode, bSortDir);
283 
284     aOldSelectHdl = pTable->GetSelectHdl();
285     aOldDeselectHdl = pTable->GetDeselectHdl();
286     pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
287     pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl));
288     pTable->SetCommandHdl(LINK(this, SwRedlineAcceptDlg, CommandHdl));
289 
290     // Flackern der Buttons vermeiden:
291     aDeselectTimer.SetTimeout(100);
292     aDeselectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
293 
294     // Mehrfachselektion der selben Texte vermeiden:
295     aSelectTimer.SetTimeout(100);
296     aSelectTimer.SetTimeoutHdl(LINK(this, SwRedlineAcceptDlg, GotoHdl));
297 }
298 
299 /*------------------------------------------------------------------------
300     Beschreibung:
301 ------------------------------------------------------------------------*/
302 
303 SwRedlineAcceptDlg::~SwRedlineAcceptDlg()
304 {
305 }
306 
307 /*------------------------------------------------------------------------
308     Beschreibung:
309 ------------------------------------------------------------------------*/
310 
311 void SwRedlineAcceptDlg::Init(sal_uInt16 nStart)
312 {
313     SwWait aWait( *::GetActiveView()->GetDocShell(), sal_False );
314     pTable->SetUpdateMode(sal_False);
315     aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count());
316 
317     if (nStart)
318         RemoveParents(nStart, aRedlineParents.Count() - 1);
319     else
320     {
321         pTable->Clear();
322         aRedlineChilds.DeleteAndDestroy(0, aRedlineChilds.Count());
323         aRedlineParents.DeleteAndDestroy(nStart, aRedlineParents.Count() - nStart);
324     }
325 
326     // Parents einfuegen
327     InsertParents(nStart);
328     InitAuthors();
329 
330     pTable->SetUpdateMode(sal_True);
331     // #i69618# this moves the list box to the right position, visually
332     SvLBoxEntry* pSelEntry = pTable->FirstSelected();
333     if( pSelEntry )
334         pTable->MakeVisible( pSelEntry, sal_True ); //#i70937#, force the scroll
335 }
336 
337 /*------------------------------------------------------------------------
338     Beschreibung:
339 ------------------------------------------------------------------------*/
340 
341 void SwRedlineAcceptDlg::InitAuthors()
342 {
343     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
344 
345     SvxTPFilter *pFilterPage = aTabPagesCTRL.GetFilterPage();
346 
347     String sAuthor;
348     SvStringsSortDtor aStrings;
349     String sOldAuthor(pFilterPage->GetSelectedAuthor());
350     pFilterPage->ClearAuthors();
351 
352     String sParent;
353     sal_uInt16 nCount = pSh->GetRedlineCount();
354 
355     bOnlyFormatedRedlines = sal_True;
356     bHasReadonlySel = sal_False;
357     sal_Bool bIsNotFormated = sal_False;
358     sal_uInt16 i;
359 
360     // Autoren ermitteln
361     for ( i = 0; i < nCount; i++)
362     {
363         const SwRedline& rRedln = pSh->GetRedline(i);
364 
365         if( bOnlyFormatedRedlines && nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType() )
366             bOnlyFormatedRedlines = sal_False;
367 
368 //JP 27.9.2001: make no sense if we handle readonly sections
369 //      if( !bHasReadonlySel && rRedln.HasReadonlySel() )
370 //          bHasReadonlySel = sal_True;
371 
372         String *pAuthor = new String(rRedln.GetAuthorString());
373         if (!aStrings.Insert(pAuthor))
374             delete pAuthor;
375 
376         for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++)
377         {
378             pAuthor = new String(rRedln.GetAuthorString(nStack));
379             if (!aStrings.Insert(pAuthor))
380                 delete pAuthor;
381         }
382     }
383 
384     for (i = 0; i < aStrings.Count(); i++)
385         pFilterPage->InsertAuthor(*aStrings[i]);
386 
387     if (pFilterPage->SelectAuthor(sOldAuthor) == LISTBOX_ENTRY_NOTFOUND && aStrings.Count())
388         pFilterPage->SelectAuthor(*aStrings[0]);
389 
390     sal_Bool bEnable = pTable->GetEntryCount() != 0 && !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength();
391     sal_Bool bSel = pTable->FirstSelected() != 0;
392 
393     SvLBoxEntry* pSelEntry = pTable->FirstSelected();
394     while (pSelEntry)
395     {
396         sal_uInt16 nPos = GetRedlinePos(*pSelEntry);
397         const SwRedline& rRedln = pSh->GetRedline( nPos );
398 
399         bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();
400         pSelEntry = pTable->NextSelected(pSelEntry);
401     }
402 
403     pTPView->EnableAccept( bEnable && bSel );
404     pTPView->EnableReject( bEnable && bIsNotFormated && bSel );
405     pTPView->EnableAcceptAll( bEnable && !bHasReadonlySel );
406     pTPView->EnableRejectAll( bEnable && !bHasReadonlySel &&
407                                 !bOnlyFormatedRedlines );
408 }
409 
410 /*------------------------------------------------------------------------
411     Beschreibung:
412 ------------------------------------------------------------------------*/
413 
414 String SwRedlineAcceptDlg::GetRedlineText( const SwRedline& rRedln,
415                                         DateTime &rDateTime, sal_uInt16 nStack)
416 {
417     String sEntry(GetActionText(rRedln, nStack));
418     sEntry += '\t';
419     sEntry += rRedln.GetAuthorString(nStack);
420     sEntry += '\t';
421 
422     const DateTime &rDT = rRedln.GetTimeStamp(nStack);
423     rDateTime = rDT;
424 
425     sEntry += GetAppLangDateTimeString( rDT );
426     sEntry += '\t';
427 
428     sEntry += rRedln.GetComment(nStack);
429 
430     return sEntry;
431 }
432 
433 /*------------------------------------------------------------------------
434     Beschreibung:
435 ------------------------------------------------------------------------*/
436 
437 const String &SwRedlineAcceptDlg::GetActionText(const SwRedline& rRedln, sal_uInt16 nStack)
438 {
439     switch( rRedln.GetType(nStack) )
440     {
441         case nsRedlineType_t::REDLINE_INSERT:   return sInserted;
442         case nsRedlineType_t::REDLINE_DELETE:   return sDeleted;
443         case nsRedlineType_t::REDLINE_FORMAT:   return sFormated;
444         case nsRedlineType_t::REDLINE_TABLE:    return sTableChgd;
445         case nsRedlineType_t::REDLINE_FMTCOLL:  return sFmtCollSet;
446         default:;//prevent warning
447     }
448 
449     return aEmptyStr;
450 }
451 
452 /*------------------------------------------------------------------------
453     Beschreibung:
454 ------------------------------------------------------------------------*/
455 
456 void SwRedlineAcceptDlg::Resize()
457 {
458     Size aSz(pParentDlg->GetOutputSizePixel());
459 
460     Point aPos(aTabPagesCTRL.GetPosPixel());
461 
462     aSz.Width() -= (aPos.X() * 2 - 1);
463     aSz.Height() -= (aPos.Y() * 2 - 1);
464 
465     aTabPagesCTRL.SetOutputSizePixel(aSz);
466 }
467 
468 /*--------------------------------------------------------------------
469     Beschreibung: Nach Aktivierung neu initialisieren
470  --------------------------------------------------------------------*/
471 
472 void SwRedlineAcceptDlg::Activate()
473 {
474     // prevent update if flag is set (#102547#)
475     if( bInhibitActivate )
476         return;
477 
478     SwView *pView = ::GetActiveView();
479     SwWait aWait( *pView->GetDocShell(), sal_False );
480 
481     aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count());
482 
483     if (!pView) // Kann passieren, wenn man auf eine andere App umschaltet, wenn
484         return; // vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug)
485 
486 /*  if (HasRedlineAutoFmt())
487     {
488         Init();
489         return;
490     }*/
491 
492     // Hat sich was geaendert?
493     SwWrtShell* pSh = pView->GetWrtShellPtr();
494     sal_uInt16 nCount = pSh->GetRedlineCount();
495 
496     // Anzahl und Pointer ueberpruefen
497     SwRedlineDataParent *pParent = 0;
498     sal_uInt16 i;
499 
500     for ( i = 0; i < nCount; i++)
501     {
502         const SwRedline& rRedln = pSh->GetRedline(i);
503 
504         if (i >= aRedlineParents.Count())
505         {
506             // Neue Eintraege wurden angehaengt
507             Init(i);
508             return;
509         }
510 
511         pParent = aRedlineParents[i];
512         if (&rRedln.GetRedlineData() != pParent->pData)
513         {
514             // Redline-Parents wurden eingefuegt, geaendert oder geloescht
515             if ((i = CalcDiff(i, sal_False)) == USHRT_MAX)
516                 return;
517             continue;
518         }
519 
520         const SwRedlineData *pRedlineData = rRedln.GetRedlineData().Next();
521         const SwRedlineDataChild *pBackupData = pParent->pNext;
522 
523         if (!pRedlineData && pBackupData)
524         {
525             // Redline-Childs wurden geloescht
526             if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
527                 return;
528             continue;
529         }
530         else
531         {
532             while (pRedlineData)
533             {
534                 if (pRedlineData != pBackupData->pChild)
535                 {
536                     // Redline-Childs wurden eingefuegt, geaendert oder geloescht
537                     if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
538                         return;
539                     continue;
540                 }
541                 if (pBackupData)
542                     pBackupData = pBackupData->pNext;
543                 pRedlineData = pRedlineData->Next();
544             }
545         }
546     }
547 
548     if (nCount != aRedlineParents.Count())
549     {
550         // Redlines wurden am Ende geloescht
551         Init(nCount);
552         return;
553     }
554 
555     // Kommentar ueberpruefen
556     for (i = 0; i < nCount; i++)
557     {
558         const SwRedline& rRedln = pSh->GetRedline(i);
559         pParent = aRedlineParents[i];
560 
561         if(!rRedln.GetComment().Equals(pParent->sComment))
562         {
563             if (pParent->pTLBParent)
564             {
565                 // Nur Kommentar aktualisieren
566                 String sComment(rRedln.GetComment());
567                 sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
568                 pTable->SetEntryText(sComment, pParent->pTLBParent, 3);
569             }
570             pParent->sComment = rRedln.GetComment();
571         }
572     }
573 
574     InitAuthors();
575 }
576 
577 /* -----------------05.06.98 13:06-------------------
578  *
579  * --------------------------------------------------*/
580 
581 sal_uInt16 SwRedlineAcceptDlg::CalcDiff(sal_uInt16 nStart, sal_Bool bChild)
582 {
583     if (!nStart)
584     {
585         Init();
586         return USHRT_MAX;
587     }
588 
589     pTable->SetUpdateMode(sal_False);
590     SwView *pView   = ::GetActiveView();
591     SwWrtShell* pSh = pView->GetWrtShellPtr();
592     sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;
593     SwRedlineDataParent *pParent = aRedlineParents[nStart];
594     const SwRedline& rRedln = pSh->GetRedline(nStart);
595 
596     if (bChild)     // Sollte eigentlich nie vorkommen, aber sicher ist sicher...
597     {
598         // Alle Childs des Eintrags wegwerfen und neu initialisieren
599         SwRedlineDataChildPtr pBackupData = (SwRedlineDataChildPtr)pParent->pNext;
600         SwRedlineDataChildPtr pNext;
601 
602         while (pBackupData)
603         {
604             pNext = (SwRedlineDataChildPtr)pBackupData->pNext;
605             if (pBackupData->pTLBChild)
606                 pTable->RemoveEntry(pBackupData->pTLBChild);
607 
608             aRedlineChilds.DeleteAndDestroy(aRedlineChilds.GetPos(pBackupData), 1);
609             pBackupData = pNext;
610         }
611         pParent->pNext = 0;
612 
613         // Neue Childs einfuegen
614         InsertChilds(pParent, rRedln, nAutoFmt);
615 
616         pTable->SetUpdateMode(sal_True);
617         return nStart;
618     }
619 
620     // Wurden Eintraege geloescht?
621     const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
622     sal_uInt16 i;
623     for ( i = nStart + 1; i < aRedlineParents.Count(); i++)
624     {
625         if (aRedlineParents[i]->pData == pRedlineData)
626         {
627             // Eintraege von nStart bis i-1 entfernen
628             RemoveParents(nStart, i - 1);
629             pTable->SetUpdateMode(sal_True);
630             return nStart - 1;
631         }
632     }
633 
634     // Wurden Eintraege eingefuegt?
635     sal_uInt16 nCount = pSh->GetRedlineCount();
636     pRedlineData = aRedlineParents[nStart]->pData;
637 
638     for (i = nStart + 1; i < nCount; i++)
639     {
640         if (&pSh->GetRedline(i).GetRedlineData() == pRedlineData)
641         {
642             // Eintraege von nStart bis i-1 einfuegen
643             InsertParents(nStart, i - 1);
644             pTable->SetUpdateMode(sal_True);
645             return nStart - 1;
646         }
647     }
648 
649     pTable->SetUpdateMode(sal_True);
650     Init(nStart);   // Alle Eintraege bis zum Ende abgleichen
651     return USHRT_MAX;
652 }
653 
654 /* -----------------05.06.98 13:57-------------------
655  *
656  * --------------------------------------------------*/
657 
658 void SwRedlineAcceptDlg::InsertChilds(SwRedlineDataParent *pParent, const SwRedline& rRedln, const sal_uInt16 nAutoFmt)
659 {
660     String sChild;
661     SwRedlineDataChild *pLastRedlineChild = 0;
662     const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
663     sal_Bool bAutoFmt = (rRedln.GetRealType() & nAutoFmt) != 0;
664 
665     const String *pAction = &GetActionText(rRedln);
666     sal_Bool bValidParent = !sFilterAction.Len() || sFilterAction == *pAction;
667     bValidParent = bValidParent && pTable->IsValidEntry(&rRedln.GetAuthorString(), &rRedln.GetTimeStamp(), &rRedln.GetComment());
668     if (nAutoFmt)
669     {
670         sal_uInt16 nPos;
671 
672         if (pParent->pData->GetSeqNo() && !aUsedSeqNo.Insert(pParent, nPos))    // Gibts schon
673         {
674             if (pParent->pTLBParent)
675             {
676                 pTable->SetEntryText(sAutoFormat, aUsedSeqNo[nPos]->pTLBParent, 0);
677                 pTable->RemoveEntry(pParent->pTLBParent);
678                 pParent->pTLBParent = 0;
679             }
680             return;
681         }
682         bValidParent = bValidParent && bAutoFmt;
683     }
684     sal_Bool bValidTree = bValidParent;
685 
686     for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++)
687     {
688         pRedlineData = pRedlineData->Next();
689 
690         SwRedlineDataChildPtr pRedlineChild = new SwRedlineDataChild;
691         pRedlineChild->pChild = pRedlineData;
692         aRedlineChilds.Insert(pRedlineChild, aRedlineChilds.Count());
693 
694         if ( pLastRedlineChild )
695             pLastRedlineChild->pNext = pRedlineChild;
696         else
697             pParent->pNext = pRedlineChild;
698 
699         pAction = &GetActionText(rRedln, nStack);
700         sal_Bool bValidChild = !sFilterAction.Len() || sFilterAction == *pAction;
701         bValidChild = bValidChild && pTable->IsValidEntry(&rRedln.GetAuthorString(nStack), &rRedln.GetTimeStamp(nStack), &rRedln.GetComment());
702         if (nAutoFmt)
703             bValidChild = bValidChild && bAutoFmt;
704         bValidTree |= bValidChild;
705 
706         if (bValidChild)
707         {
708             RedlinData *pData = new RedlinData;
709             pData->pData = pRedlineChild;
710             pData->bDisabled = sal_True;
711             sChild = GetRedlineText(rRedln, pData->aDateTime, nStack);
712 
713             SvLBoxEntry* pChild = pTable->InsertEntry(sChild, pData, pParent->pTLBParent);
714 
715             pRedlineChild->pTLBChild = pChild;
716             if (!bValidParent)
717                 pTable->Expand(pParent->pTLBParent);
718         }
719         else
720             pRedlineChild->pTLBChild = 0;
721 
722         pLastRedlineChild = pRedlineChild;
723     }
724 
725     if (pLastRedlineChild)
726         pLastRedlineChild->pNext = 0;
727 
728     if (!bValidTree && pParent->pTLBParent)
729     {
730         pTable->RemoveEntry(pParent->pTLBParent);
731         pParent->pTLBParent = 0;
732         if (nAutoFmt)
733             aUsedSeqNo.Remove(pParent);
734     }
735 }
736 
737 /* -----------------05.06.98 15:20-------------------
738  *
739  * --------------------------------------------------*/
740 
741 void SwRedlineAcceptDlg::RemoveParents(sal_uInt16 nStart, sal_uInt16 nEnd)
742 {
743     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
744     sal_uInt16 nCount = pSh->GetRedlineCount();
745 
746     SvLBoxEntryArr aLBoxArr;
747 
748     // Wegen Bug der TLB, die bei Remove den SelectHandler IMMER ruft:
749     pTable->SetSelectHdl(aOldSelectHdl);
750     pTable->SetDeselectHdl(aOldDeselectHdl);
751     sal_Bool bChildsRemoved = sal_False;
752     pTable->SelectAll(sal_False);
753 
754     // Hinter dem letzten Eintrag Cursor setzen, da sonst Performance-Problem in TLB.
755     // TLB wuerde sonst bei jedem Remove den Cursor erneut umsetzen (teuer)
756     sal_uInt16 nPos = Min((sal_uInt16)nCount, (sal_uInt16)aRedlineParents.Count());
757     SvLBoxEntry *pCurEntry = NULL;
758     while( ( pCurEntry == NULL ) && ( nPos > 0 ) )
759     {
760         --nPos;
761         pCurEntry = aRedlineParents[nPos]->pTLBParent;
762     }
763 
764     if (pCurEntry)
765         pTable->SetCurEntry(pCurEntry);
766 
767     SvLBoxTreeList* pModel = pTable->GetModel();
768 
769     for (sal_uInt16 i = nStart; i <= nEnd; i++)
770     {
771         if (!bChildsRemoved && aRedlineParents[i]->pNext)
772         {
773             SwRedlineDataChildPtr pChildPtr = (SwRedlineDataChildPtr)aRedlineParents[i]->pNext;
774             sal_uInt16 nChildPos = aRedlineChilds.GetPos(pChildPtr);
775 
776             if (nChildPos != USHRT_MAX)
777             {
778                 sal_uInt16 nChilds = 0;
779 
780                 while (pChildPtr)
781                 {
782                     pChildPtr = (SwRedlineDataChildPtr)pChildPtr->pNext;
783                     nChilds++;
784                 }
785 
786                 aRedlineChilds.DeleteAndDestroy(nChildPos, nChilds);
787                 bChildsRemoved = sal_True;
788             }
789         }
790         SvLBoxEntry *pEntry = aRedlineParents[i]->pTLBParent;
791         if (pEntry)
792         {
793             long nIdx = aLBoxArr.Count() - 1L;
794             sal_uLong nAbsPos = pModel->GetAbsPos(pEntry);
795             while (nIdx >= 0 &&
796                     pModel->GetAbsPos(aLBoxArr[ static_cast< sal_uInt16 >(nIdx) ]) > nAbsPos)
797                 nIdx--;
798             aLBoxArr.Insert( pEntry, static_cast< sal_uInt16 >(++nIdx) );
799         }
800     }
801 
802     // TLB von hinten abraeumen
803     long nIdx = (long)aLBoxArr.Count() - 1L;
804     while (nIdx >= 0)
805         pTable->RemoveEntry(aLBoxArr[ static_cast< sal_uInt16 >(nIdx--) ]);
806 
807     pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
808     pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl));
809     // Durch Remove wurde leider wieder dauernd von der TLB selektiert...
810     pTable->SelectAll(sal_False);
811 
812     aRedlineParents.DeleteAndDestroy( nStart, nEnd - nStart + 1);
813 }
814 
815 /* -----------------05.06.98 15:20-------------------
816  *
817  * --------------------------------------------------*/
818 
819 void SwRedlineAcceptDlg::InsertParents(sal_uInt16 nStart, sal_uInt16 nEnd)
820 {
821     SwView *pView   = ::GetActiveView();
822     SwWrtShell* pSh = pView->GetWrtShellPtr();
823     sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;
824 
825     String sParent;
826     sal_uInt16 nCount = pSh->GetRedlineCount();
827     nEnd = Min((sal_uInt16)nEnd, (sal_uInt16)(nCount - 1)); // Handelt auch nEnd=USHRT_MAX (bis zum Ende) ab
828 
829     if (nEnd == USHRT_MAX)
830         return;     // Keine Redlines im Dokument
831 
832     RedlinData *pData;
833     SvLBoxEntry *pParent;
834     SwRedlineDataParentPtr pRedlineParent;
835     const SwRedline* pCurrRedline;
836     if( !nStart && !pTable->FirstSelected() )
837     {
838         pCurrRedline = pSh->GetCurrRedline();
839         if( !pCurrRedline )
840         {
841             pSh->SwCrsrShell::Push();
842             if( 0 == (pCurrRedline = pSh->SelNextRedline()))
843                 pCurrRedline = pSh->SelPrevRedline();
844             pSh->SwCrsrShell::Pop( sal_False );
845         }
846     }
847     else
848         pCurrRedline = 0;
849 
850     for (sal_uInt16 i = nStart; i <= nEnd; i++)
851     {
852         const SwRedline& rRedln = pSh->GetRedline(i);
853         const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
854 
855         pRedlineParent = new SwRedlineDataParent;
856         pRedlineParent->pData    = pRedlineData;
857         pRedlineParent->pNext    = 0;
858         String sComment(rRedln.GetComment());
859         sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
860         pRedlineParent->sComment = sComment;
861         aRedlineParents.Insert(pRedlineParent, i);
862 
863         pData = new RedlinData;
864         pData->pData = pRedlineParent;
865         pData->bDisabled = sal_False;
866 
867         sParent = GetRedlineText(rRedln, pData->aDateTime);
868         pParent = pTable->InsertEntry(sParent, pData, 0, i);
869         if( pCurrRedline == &rRedln )
870         {
871             pTable->SetCurEntry( pParent );
872             pTable->Select( pParent );
873             pTable->MakeVisible( pParent );
874         }
875 
876         pRedlineParent->pTLBParent = pParent;
877 
878         InsertChilds(pRedlineParent, rRedln, nAutoFmt);
879     }
880 }
881 
882 /* -----------------05.06.98 13:06-------------------
883  *
884  * --------------------------------------------------*/
885 
886 void SwRedlineAcceptDlg::CallAcceptReject( sal_Bool bSelect, sal_Bool bAccept )
887 {
888     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
889     SvLBoxEntry* pEntry = bSelect ? pTable->FirstSelected() : pTable->First();
890     sal_uLong nPos = LONG_MAX;
891 
892     typedef std::vector<SvLBoxEntry*> ListBoxEntries_t;
893     ListBoxEntries_t aRedlines;
894 
895     // don't activate
896     DBG_ASSERT( bInhibitActivate == false,
897                 "recursive call of CallAcceptReject?");
898     bInhibitActivate = true;
899 
900     // collect redlines-to-be-accepted/rejected in aRedlines vector
901     while( pEntry )
902     {
903         if( !pTable->GetParent( pEntry ) )
904         {
905             if( bSelect && LONG_MAX == nPos )
906                 nPos = pTable->GetModel()->GetAbsPos( pEntry );
907 
908             RedlinData *pData = (RedlinData *)pEntry->GetUserData();
909 
910             if( !pData->bDisabled )
911                 aRedlines.push_back( pEntry );
912         }
913 
914         pEntry = bSelect ? pTable->NextSelected(pEntry) : pTable->Next(pEntry);
915     }
916 
917     sal_Bool (SwEditShell:: *FnAccRej)( sal_uInt16 ) = &SwEditShell::AcceptRedline;
918     if( !bAccept )
919         FnAccRej = &SwEditShell::RejectRedline;
920 
921     SwWait aWait( *pSh->GetView().GetDocShell(), sal_True );
922     pSh->StartAction();
923 
924     // #111827#
925     if (aRedlines.size() > 1)
926     {
927         String aTmpStr;
928         {
929             SwRewriter aRewriter;
930             aRewriter.AddRule(UNDO_ARG1,
931                               String::CreateFromInt32(aRedlines.size()));
932             aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES)));
933         }
934 
935         SwRewriter aRewriter;
936         aRewriter.AddRule(UNDO_ARG1, aTmpStr);
937 
938         pSh->StartUndo(bAccept? UNDO_ACCEPT_REDLINE : UNDO_REJECT_REDLINE,
939                        &aRewriter);
940     }
941 
942     // accept/reject the the redlines in aRedlines. The absolute
943     // position may change during the process (e.g. when two redlines
944     // are merged in result of another one being deleted), so the
945     // position must be resolved late and checked before using it.
946     // (cf #102547#)
947     ListBoxEntries_t::iterator aEnd = aRedlines.end();
948     for( ListBoxEntries_t::iterator aIter = aRedlines.begin();
949          aIter != aEnd;
950          aIter++ )
951     {
952         sal_uInt16 nPosition = GetRedlinePos( **aIter );
953         if( nPosition != USHRT_MAX )
954             (pSh->*FnAccRej)( nPosition );
955     }
956 
957     // #111827#
958     if (aRedlines.size() > 1)
959     {
960         pSh->EndUndo();
961     }
962 
963     pSh->EndAction();
964 
965     bInhibitActivate = false;
966     Activate();
967 
968     if( ULONG_MAX != nPos && pTable->GetEntryCount() )
969     {
970         if( nPos >= pTable->GetEntryCount() )
971             nPos = pTable->GetEntryCount() - 1;
972         pEntry = pTable->GetEntry( nPos );
973         if( !pEntry && nPos-- )
974             pEntry = pTable->GetEntry( nPos );
975         if( pEntry )
976         {
977             pTable->Select( pEntry );
978             pTable->MakeVisible( pEntry );
979             pTable->SetCurEntry(pEntry);
980         }
981     }
982     pTPView->EnableUndo();
983 }
984 
985 /*--------------------------------------------------------------------
986     Beschreibung:
987  --------------------------------------------------------------------*/
988 
989 sal_uInt16 SwRedlineAcceptDlg::GetRedlinePos( const SvLBoxEntry& rEntry ) const
990 {
991     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
992     return pSh->FindRedlineOfData( *((SwRedlineDataParent*)((RedlinData *)
993                                     rEntry.GetUserData())->pData)->pData );
994 }
995 
996 /*--------------------------------------------------------------------
997     Beschreibung:
998  --------------------------------------------------------------------*/
999 
1000 IMPL_LINK( SwRedlineAcceptDlg, AcceptHdl, void*, EMPTYARG)
1001 {
1002     CallAcceptReject( sal_True, sal_True );
1003     return 0;
1004 }
1005 
1006 /*--------------------------------------------------------------------
1007     Beschreibung:
1008  --------------------------------------------------------------------*/
1009 
1010 IMPL_LINK( SwRedlineAcceptDlg, AcceptAllHdl, void*, EMPTYARG )
1011 {
1012     CallAcceptReject( sal_False, sal_True );
1013     return 0;
1014 }
1015 
1016 /*--------------------------------------------------------------------
1017     Beschreibung:
1018  --------------------------------------------------------------------*/
1019 
1020 IMPL_LINK( SwRedlineAcceptDlg, RejectHdl, void*, EMPTYARG )
1021 {
1022     CallAcceptReject( sal_True, sal_False );
1023     return 0;
1024 }
1025 
1026 /*--------------------------------------------------------------------
1027     Beschreibung:
1028  --------------------------------------------------------------------*/
1029 
1030 IMPL_LINK( SwRedlineAcceptDlg, RejectAllHdl, void*, EMPTYARG )
1031 {
1032     CallAcceptReject( sal_False, sal_False );
1033     return 0;
1034 }
1035 
1036 /*--------------------------------------------------------------------
1037     Beschreibung:
1038  --------------------------------------------------------------------*/
1039 
1040 IMPL_LINK( SwRedlineAcceptDlg, UndoHdl, void*, EMPTYARG )
1041 {
1042     SwView * pView = ::GetActiveView();
1043     pView->GetViewFrame()->GetDispatcher()->
1044                 Execute(SID_UNDO, SFX_CALLMODE_SYNCHRON);
1045     pTPView->EnableUndo(pView->GetSlotState(SID_UNDO) != 0);
1046 
1047     Activate();
1048 
1049     return 0;
1050 }
1051 
1052 /*--------------------------------------------------------------------
1053     Beschreibung:
1054  --------------------------------------------------------------------*/
1055 
1056 IMPL_LINK( SwRedlineAcceptDlg, FilterChangedHdl, void*, EMPTYARG )
1057 {
1058     SvxTPFilter *pFilterTP = aTabPagesCTRL.GetFilterPage();
1059 
1060     if (pFilterTP->IsAction())
1061         sFilterAction = pFilterTP->GetLbAction()->GetSelectEntry();
1062     else
1063         sFilterAction = aEmptyStr;
1064 
1065     Init();
1066 
1067     return 0;
1068 }
1069 
1070 /*--------------------------------------------------------------------
1071     Beschreibung:
1072  --------------------------------------------------------------------*/
1073 
1074 IMPL_LINK( SwRedlineAcceptDlg, DeselectHdl, void*, EMPTYARG )
1075 {
1076     // Flackern der Buttons vermeiden:
1077     aDeselectTimer.Start();
1078 
1079     return 0;
1080 }
1081 
1082 /*--------------------------------------------------------------------
1083     Beschreibung:
1084  --------------------------------------------------------------------*/
1085 
1086 IMPL_LINK( SwRedlineAcceptDlg, SelectHdl, void*, EMPTYARG )
1087 {
1088     aDeselectTimer.Stop();
1089     aSelectTimer.Start();
1090 
1091     return 0;
1092 }
1093 
1094 /*--------------------------------------------------------------------
1095     Beschreibung:
1096  --------------------------------------------------------------------*/
1097 
1098 IMPL_LINK( SwRedlineAcceptDlg, GotoHdl, void*, EMPTYARG )
1099 {
1100     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
1101     aSelectTimer.Stop();
1102 
1103     sal_Bool bIsNotFormated = sal_False;
1104     sal_Bool bSel = sal_False;
1105 //  sal_Bool bReadonlySel = sal_False;
1106 
1107     //#98883# don't select redlines while the dialog is not focussed
1108     //#107938# But not only ask pTable if it has the focus. To move
1109     //         the selection to the selected redline any child of pParentDlg
1110     //         may the focus.
1111     SvLBoxEntry* pSelEntry = 0;
1112 
1113     if (pParentDlg->HasChildPathFocus())
1114         pSelEntry = pTable->FirstSelected();
1115 
1116     if( pSelEntry )
1117     {
1118         SvLBoxEntry* pActEntry = pSelEntry;
1119         pSh->StartAction();
1120         pSh->EnterStdMode();
1121         pSh->SetCareWin(pParentDlg);
1122 
1123         while (pSelEntry)
1124         {
1125             if (pTable->GetParent(pSelEntry))
1126             {
1127                 pActEntry = pTable->GetParent(pSelEntry);
1128 
1129                 if (pTable->IsSelected(pActEntry))
1130                 {
1131                     pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
1132                     continue;   // Nicht zweimal selektieren
1133                 }
1134             }
1135             else
1136                 bSel = sal_True;
1137 
1138             // #98864# find the selected redline (ignore, if the redline is already gone)
1139             sal_uInt16 nPos = GetRedlinePos(*pActEntry);
1140             if( nPos != USHRT_MAX )
1141             {
1142 
1143                 const SwRedline& rRedln = pSh->GetRedline( nPos );
1144                 bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();
1145 
1146 //JP 27.9.2001: make no sense if we handle readonly sections
1147 //          if( !bReadonlySel && rRedln.HasReadonlySel() )
1148 //              bReadonlySel = sal_True;
1149 
1150                 if (pSh->GotoRedline(nPos, sal_True))
1151                 {
1152                     pSh->SetInSelect();
1153                     pSh->EnterAddMode();
1154                 }
1155             }
1156 
1157             pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
1158         }
1159 
1160         pSh->LeaveAddMode();
1161         pSh->EndAction();
1162         pSh->SetCareWin(NULL);
1163     }
1164     sal_Bool bEnable = !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength();
1165     pTPView->EnableAccept( bEnable && bSel /*&& !bReadonlySel*/ );
1166     pTPView->EnableReject( bEnable && bSel && bIsNotFormated /*&& !bReadonlySel*/ );
1167     pTPView->EnableRejectAll( bEnable && !bOnlyFormatedRedlines && !bHasReadonlySel );
1168 
1169     return 0;
1170 }
1171 
1172 /*--------------------------------------------------------------------
1173     Beschreibung:
1174  --------------------------------------------------------------------*/
1175 
1176 IMPL_LINK( SwRedlineAcceptDlg, CommandHdl, void*, EMPTYARG )
1177 {
1178     const CommandEvent aCEvt(pTable->GetCommandEvent());
1179 
1180     switch ( aCEvt.GetCommand() )
1181     {
1182         case COMMAND_CONTEXTMENU:
1183         {
1184             SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
1185             SvLBoxEntry* pEntry = pTable->FirstSelected();
1186             const SwRedline *pRed = 0;
1187 
1188             if (pEntry)
1189             {
1190                 SvLBoxEntry* pTopEntry = pEntry;
1191 
1192                 if (pTable->GetParent(pEntry))
1193                     pTopEntry = pTable->GetParent(pEntry);
1194 
1195                 sal_uInt16 nPos = GetRedlinePos(*pTopEntry);
1196 
1197                 // Bei geschuetzten Bereichen kommentieren disablen
1198                 if ((pRed = pSh->GotoRedline(nPos, sal_True)) != 0)
1199                 {
1200                     if( pSh->IsCrsrPtAtEnd() )
1201                         pSh->SwapPam();
1202                     pSh->SetInSelect();
1203                 }
1204             }
1205 
1206             aPopup.EnableItem( MN_EDIT_COMMENT, pEntry && pRed &&
1207                                             !pTable->GetParent(pEntry) &&
1208                                             !pTable->NextSelected(pEntry)
1209 //JP 27.9.2001: make no sense if we handle readonly sections
1210 //                                          && pRed->HasReadonlySel()
1211                                             );
1212 
1213             aPopup.EnableItem( MN_SUB_SORT, pTable->First() != 0 );
1214             sal_uInt16 nColumn = pTable->GetSortedCol();
1215             if (nColumn == 0xffff)
1216                 nColumn = 4;
1217 
1218             PopupMenu *pSubMenu = aPopup.GetPopupMenu(MN_SUB_SORT);
1219             if (pSubMenu)
1220             {
1221                 for (sal_uInt16 i = MN_SORT_ACTION; i < MN_SORT_ACTION + 5; i++)
1222                     pSubMenu->CheckItem(i, sal_False);
1223 
1224                 pSubMenu->CheckItem(nColumn + MN_SORT_ACTION);
1225             }
1226 
1227             sal_uInt16 nRet = aPopup.Execute(pTable, aCEvt.GetMousePosPixel());
1228 
1229             switch( nRet )
1230             {
1231                 case MN_EDIT_COMMENT:
1232                 {
1233                     String sComment;
1234                     if (pEntry)
1235                     {
1236                         if (pTable->GetParent(pEntry))
1237                             pEntry = pTable->GetParent(pEntry);
1238 
1239                         sal_uInt16 nPos = GetRedlinePos(*pEntry);
1240                         const SwRedline &rRedline = pSh->GetRedline(nPos);
1241 
1242 
1243                         /* enable again once we have redline comments in the margin
1244                         sComment = rRedline.GetComment();
1245                         if ( sComment == String(::rtl::OUString::createFromAscii("")) )
1246                             GetActiveView()->GetDocShell()->Broadcast(SwRedlineHint(&rRedline,SWREDLINE_INSERTED));
1247                         const_cast<SwRedline&>(rRedline).Broadcast(SwRedlineHint(&rRedline,SWREDLINE_FOCUS));
1248                         */
1249 
1250                         sComment = rRedline.GetComment();
1251                         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1252                         DBG_ASSERT(pFact, "Dialogdiet fail!");
1253                         ::DialogGetRanges fnGetRange = pFact->GetDialogGetRangesFunc( RID_SVXDLG_POSTIT );
1254                         DBG_ASSERT(fnGetRange, "Dialogdiet fail! GetRanges()");
1255                         SfxItemSet aSet( pSh->GetAttrPool(), fnGetRange() );
1256 
1257                         aSet.Put(SvxPostItTextItem(sComment.ConvertLineEnd(), SID_ATTR_POSTIT_TEXT));
1258                         aSet.Put(SvxPostItAuthorItem(rRedline.GetAuthorString(), SID_ATTR_POSTIT_AUTHOR));
1259 
1260                         aSet.Put(SvxPostItDateItem( GetAppLangDateTimeString(
1261                                     rRedline.GetRedlineData().GetTimeStamp() ),
1262                                     SID_ATTR_POSTIT_DATE ));
1263 
1264                         AbstractSvxPostItDialog* pDlg = pFact->CreateSvxPostItDialog( pParentDlg, aSet, sal_False );
1265                         DBG_ASSERT(pDlg, "Dialogdiet fail!");
1266 
1267                         pDlg->HideAuthor();
1268 
1269                         sal_uInt16 nResId = 0;
1270                         switch( rRedline.GetType() )
1271                         {
1272                         case nsRedlineType_t::REDLINE_INSERT:
1273                             nResId = STR_REDLINE_INSERTED;
1274                             break;
1275                         case nsRedlineType_t::REDLINE_DELETE:
1276                             nResId = STR_REDLINE_DELETED;
1277                             break;
1278                         case nsRedlineType_t::REDLINE_FORMAT:
1279                             nResId = STR_REDLINE_FORMATED;
1280                             break;
1281                         case nsRedlineType_t::REDLINE_TABLE:
1282                             nResId = STR_REDLINE_TABLECHG;
1283                             break;
1284                         default:;//prevent warning
1285                         }
1286                         String sTitle(SW_RES(STR_REDLINE_COMMENT));
1287                         if( nResId )
1288                             sTitle += SW_RESSTR( nResId );
1289                         pDlg->SetText(sTitle);
1290 
1291                         pSh->SetCareWin(pDlg->GetWindow());
1292 
1293                         if ( pDlg->Execute() == RET_OK )
1294                         {
1295                             const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
1296                             String sMsg(((const SvxPostItTextItem&)pOutSet->Get(SID_ATTR_POSTIT_TEXT)).GetValue());
1297 
1298                             // Kommentar einfuegen bzw aendern
1299                             pSh->SetRedlineComment(sMsg);
1300                             sMsg.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
1301                             pTable->SetEntryText(sMsg, pEntry, 3);
1302                         }
1303 
1304                         delete pDlg;
1305                         pSh->SetCareWin(NULL);
1306                     }
1307 
1308                 }
1309                 break;
1310 
1311             case MN_SORT_ACTION:
1312             case MN_SORT_AUTHOR:
1313             case MN_SORT_DATE:
1314             case MN_SORT_COMMENT:
1315             case MN_SORT_POSITION:
1316                 {
1317                     bSortDir = sal_True;
1318                     if (nRet - MN_SORT_ACTION == 4 && pTable->GetSortedCol() == 0xffff)
1319                         break;  // Haben wir schon
1320 
1321                     nSortMode = nRet - MN_SORT_ACTION;
1322                     if (nSortMode == 4)
1323                         nSortMode = 0xffff; // unsortiert bzw sortiert nach Position
1324 
1325                     if (pTable->GetSortedCol() == nSortMode)
1326                         bSortDir = !pTable->GetSortDirection();
1327 
1328                     SwWait aWait( *::GetActiveView()->GetDocShell(), sal_False );
1329                     pTable->SortByCol(nSortMode, bSortDir);
1330                     if (nSortMode == 0xffff)
1331                         Init();             // Alles neu fuellen
1332                 }
1333                 break;
1334             }
1335         }
1336         break;
1337     }
1338 
1339     return 0;
1340 }
1341 
1342 /*--------------------------------------------------------------------
1343     Beschreibung:
1344  --------------------------------------------------------------------*/
1345 
1346 void SwRedlineAcceptDlg::Initialize(const String& rExtraData)
1347 {
1348     if (rExtraData.Len())
1349     {
1350         sal_uInt16 nPos = rExtraData.Search(C2S("AcceptChgDat:"));
1351 
1352         // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
1353         // er nicht vorhanden ist, liegt eine "altere Version vor
1354         if (nPos != STRING_NOTFOUND)
1355         {
1356             sal_uInt16 n1 = rExtraData.Search('(', nPos);
1357             if (n1 != STRING_NOTFOUND)
1358             {
1359                 sal_uInt16 n2 = rExtraData.Search(')', n1);
1360                 if (n2 != STRING_NOTFOUND)
1361                 {
1362                     // Alignment-String herausschneiden
1363                     String aStr = rExtraData.Copy(nPos, n2 - nPos + 1);
1364                     aStr.Erase(0, n1 - nPos + 1);
1365 
1366                     if (aStr.Len())
1367                     {
1368                         sal_uInt16 nCount = static_cast< sal_uInt16 >(aStr.ToInt32());
1369 
1370                         for (sal_uInt16 i = 0; i < nCount; i++)
1371                         {
1372                             sal_uInt16 n3 = aStr.Search(';');
1373                             aStr.Erase(0, n3 + 1);
1374                             pTable->SetTab(i, aStr.ToInt32(), MAP_PIXEL);
1375                         }
1376                     }
1377                 }
1378             }
1379         }
1380     }
1381 }
1382 
1383 /*--------------------------------------------------------------------
1384     Beschreibung:
1385  --------------------------------------------------------------------*/
1386 
1387 void SwRedlineAcceptDlg::FillInfo(String &rExtraData) const
1388 {
1389     rExtraData.AppendAscii("AcceptChgDat:(");
1390 
1391     sal_uInt16  nCount = pTable->TabCount();
1392 
1393     rExtraData += String::CreateFromInt32(nCount);
1394     rExtraData += ';';
1395     for(sal_uInt16 i = 0; i < nCount; i++)
1396     {
1397         rExtraData += String::CreateFromInt32( pTable->GetTab(i) );
1398         rExtraData += ';';
1399     }
1400     rExtraData += ')';
1401 }
1402