xref: /AOO41X/main/sw/source/ui/misc/redlndlg.cxx (revision 8ef2f12b1aeba1404ab3c221e6e26281826cc4fc)
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 
SwRedlineAcceptChild(Window * _pParent,sal_uInt16 nId,SfxBindings * pBindings,SfxChildWinInfo * pInfo)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 
ReInitDlg(SwDocShell * pDocSh)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 
SwModelessRedlineAcceptDlg(SfxBindings * _pBindings,SwChildWinWrapper * pChild,Window * _pParent)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 
Activate()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, 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 
Initialize(SfxChildWinInfo * pInfo)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 
FillInfo(SfxChildWinInfo & rInfo) const184 void SwModelessRedlineAcceptDlg::FillInfo(SfxChildWinInfo& rInfo) const
185 {
186     SfxModelessDialog::FillInfo(rInfo);
187     pImplDlg->FillInfo(rInfo.aExtraString);
188 }
189 
190 /*------------------------------------------------------------------------
191     Beschreibung:
192 ------------------------------------------------------------------------*/
193 
Resize()194 void SwModelessRedlineAcceptDlg::Resize()
195 {
196     pImplDlg->Resize();
197     SfxModelessDialog::Resize();
198 }
199 
200 /*------------------------------------------------------------------------
201     Beschreibung:
202 ------------------------------------------------------------------------*/
203 
~SwModelessRedlineAcceptDlg()204 SwModelessRedlineAcceptDlg::~SwModelessRedlineAcceptDlg()
205 {
206     delete pImplDlg;
207 }
208 
209 /*------------------------------------------------------------------------
210     Beschreibung:
211 ------------------------------------------------------------------------*/
212 
SwRedlineAcceptDlg(Dialog * pParent,sal_Bool bAutoFmt)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 
~SwRedlineAcceptDlg()303 SwRedlineAcceptDlg::~SwRedlineAcceptDlg()
304 {
305 }
306 
307 /*------------------------------------------------------------------------
308     Beschreibung:
309 ------------------------------------------------------------------------*/
310 
Init(sal_uInt16 nStart)311 void SwRedlineAcceptDlg::Init(sal_uInt16 nStart)
312 {
313     SwWait aWait( *::GetActiveView()->GetDocShell(), 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 
InitAuthors()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     const sal_uInt16 nRedlineCount = 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 < nRedlineCount; 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     {
394         SvLBoxEntry* pSelEntry = pTable->FirstSelected();
395         while (pSelEntry)
396         {
397             const sal_uInt16 nPos = GetRedlinePos(*pSelEntry);
398             if ( nPos < nRedlineCount )
399             {
400                 const SwRedline& rRedln = pSh->GetRedline( nPos );
401                 bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();
402             }
403             pSelEntry = pTable->NextSelected(pSelEntry);
404         }
405     }
406 
407     pTPView->EnableAccept( bEnable && bSel );
408     pTPView->EnableReject( bEnable && bIsNotFormated && bSel );
409     pTPView->EnableAcceptAll( bEnable && !bHasReadonlySel );
410     pTPView->EnableRejectAll( bEnable && !bHasReadonlySel &&
411                                 !bOnlyFormatedRedlines );
412 }
413 
414 /*------------------------------------------------------------------------
415     Beschreibung:
416 ------------------------------------------------------------------------*/
417 
GetRedlineText(const SwRedline & rRedln,DateTime & rDateTime,sal_uInt16 nStack)418 String SwRedlineAcceptDlg::GetRedlineText( const SwRedline& rRedln,
419                                         DateTime &rDateTime, sal_uInt16 nStack)
420 {
421     String sEntry(GetActionText(rRedln, nStack));
422     sEntry += '\t';
423     sEntry += rRedln.GetAuthorString(nStack);
424     sEntry += '\t';
425 
426     const DateTime &rDT = rRedln.GetTimeStamp(nStack);
427     rDateTime = rDT;
428 
429     sEntry += GetAppLangDateTimeString( rDT );
430     sEntry += '\t';
431 
432     sEntry += rRedln.GetComment(nStack);
433 
434     return sEntry;
435 }
436 
437 /*------------------------------------------------------------------------
438     Beschreibung:
439 ------------------------------------------------------------------------*/
440 
GetActionText(const SwRedline & rRedln,sal_uInt16 nStack)441 const String &SwRedlineAcceptDlg::GetActionText(const SwRedline& rRedln, sal_uInt16 nStack)
442 {
443     switch( rRedln.GetType(nStack) )
444     {
445         case nsRedlineType_t::REDLINE_INSERT:   return sInserted;
446         case nsRedlineType_t::REDLINE_DELETE:   return sDeleted;
447         case nsRedlineType_t::REDLINE_FORMAT:   return sFormated;
448         case nsRedlineType_t::REDLINE_TABLE:    return sTableChgd;
449         case nsRedlineType_t::REDLINE_FMTCOLL:  return sFmtCollSet;
450         default:;//prevent warning
451     }
452 
453     return aEmptyStr;
454 }
455 
456 /*------------------------------------------------------------------------
457     Beschreibung:
458 ------------------------------------------------------------------------*/
459 
Resize()460 void SwRedlineAcceptDlg::Resize()
461 {
462     Size aSz(pParentDlg->GetOutputSizePixel());
463 
464     Point aPos(aTabPagesCTRL.GetPosPixel());
465 
466     aSz.Width() -= (aPos.X() * 2 - 1);
467     aSz.Height() -= (aPos.Y() * 2 - 1);
468 
469     aTabPagesCTRL.SetOutputSizePixel(aSz);
470 }
471 
472 /*--------------------------------------------------------------------
473     Beschreibung: Nach Aktivierung neu initialisieren
474  --------------------------------------------------------------------*/
475 
Activate()476 void SwRedlineAcceptDlg::Activate()
477 {
478     // prevent update if flag is set (#102547#)
479     if( bInhibitActivate )
480         return;
481 
482     SwView *pView = ::GetActiveView();
483     SwWait aWait( *pView->GetDocShell(), false );
484 
485     aUsedSeqNo.Remove((sal_uInt16)0, aUsedSeqNo.Count());
486 
487     if (!pView) // Kann passieren, wenn man auf eine andere App umschaltet, wenn
488         return; // vorher eine Listbox im Dialog den Focus hatte (eigentlich THs Bug)
489 
490 /*  if (HasRedlineAutoFmt())
491     {
492         Init();
493         return;
494     }*/
495 
496     // Hat sich was geaendert?
497     SwWrtShell* pSh = pView->GetWrtShellPtr();
498     sal_uInt16 nCount = pSh->GetRedlineCount();
499 
500     // Anzahl und Pointer ueberpruefen
501     SwRedlineDataParent *pParent = 0;
502     sal_uInt16 i;
503 
504     for ( i = 0; i < nCount; i++)
505     {
506         const SwRedline& rRedln = pSh->GetRedline(i);
507 
508         if (i >= aRedlineParents.Count())
509         {
510             // Neue Eintraege wurden angehaengt
511             Init(i);
512             return;
513         }
514 
515         pParent = aRedlineParents[i];
516         if (&rRedln.GetRedlineData() != pParent->pData)
517         {
518             // Redline-Parents wurden eingefuegt, geaendert oder geloescht
519             if ((i = CalcDiff(i, sal_False)) == USHRT_MAX)
520                 return;
521             continue;
522         }
523 
524         const SwRedlineData *pRedlineData = rRedln.GetRedlineData().Next();
525         const SwRedlineDataChild *pBackupData = pParent->pNext;
526 
527         if (!pRedlineData && pBackupData)
528         {
529             // Redline-Childs wurden geloescht
530             if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
531                 return;
532             continue;
533         }
534         else
535         {
536             while (pRedlineData)
537             {
538                 if (pRedlineData != pBackupData->pChild)
539                 {
540                     // Redline-Childs wurden eingefuegt, geaendert oder geloescht
541                     if ((i = CalcDiff(i, sal_True)) == USHRT_MAX)
542                         return;
543                     continue;
544                 }
545                 if (pBackupData)
546                     pBackupData = pBackupData->pNext;
547                 pRedlineData = pRedlineData->Next();
548             }
549         }
550     }
551 
552     if (nCount != aRedlineParents.Count())
553     {
554         // Redlines wurden am Ende geloescht
555         Init(nCount);
556         return;
557     }
558 
559     // Kommentar ueberpruefen
560     for (i = 0; i < nCount; i++)
561     {
562         const SwRedline& rRedln = pSh->GetRedline(i);
563         pParent = aRedlineParents[i];
564 
565         if(!rRedln.GetComment().Equals(pParent->sComment))
566         {
567             if (pParent->pTLBParent)
568             {
569                 // Nur Kommentar aktualisieren
570                 String sComment(rRedln.GetComment());
571                 sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
572                 pTable->SetEntryText(sComment, pParent->pTLBParent, 3);
573             }
574             pParent->sComment = rRedln.GetComment();
575         }
576     }
577 
578     InitAuthors();
579 }
580 
581 /* -----------------05.06.98 13:06-------------------
582  *
583  * --------------------------------------------------*/
584 
CalcDiff(sal_uInt16 nStart,sal_Bool bChild)585 sal_uInt16 SwRedlineAcceptDlg::CalcDiff(sal_uInt16 nStart, sal_Bool bChild)
586 {
587     if (!nStart)
588     {
589         Init();
590         return USHRT_MAX;
591     }
592 
593     pTable->SetUpdateMode(sal_False);
594     SwView *pView   = ::GetActiveView();
595     SwWrtShell* pSh = pView->GetWrtShellPtr();
596     sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;
597     SwRedlineDataParent *pParent = aRedlineParents[nStart];
598     const SwRedline& rRedln = pSh->GetRedline(nStart);
599 
600     if (bChild)     // Sollte eigentlich nie vorkommen, aber sicher ist sicher...
601     {
602         // Alle Childs des Eintrags wegwerfen und neu initialisieren
603         SwRedlineDataChildPtr pBackupData = (SwRedlineDataChildPtr)pParent->pNext;
604         SwRedlineDataChildPtr pNext;
605 
606         while (pBackupData)
607         {
608             pNext = (SwRedlineDataChildPtr)pBackupData->pNext;
609             if (pBackupData->pTLBChild)
610                 pTable->RemoveEntry(pBackupData->pTLBChild);
611 
612             aRedlineChilds.DeleteAndDestroy(aRedlineChilds.GetPos(pBackupData), 1);
613             pBackupData = pNext;
614         }
615         pParent->pNext = 0;
616 
617         // Neue Childs einfuegen
618         InsertChilds(pParent, rRedln, nAutoFmt);
619 
620         pTable->SetUpdateMode(sal_True);
621         return nStart;
622     }
623 
624     // Wurden Eintraege geloescht?
625     const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
626     sal_uInt16 i;
627     for ( i = nStart + 1; i < aRedlineParents.Count(); i++)
628     {
629         if (aRedlineParents[i]->pData == pRedlineData)
630         {
631             // Eintraege von nStart bis i-1 entfernen
632             RemoveParents(nStart, i - 1);
633             pTable->SetUpdateMode(sal_True);
634             return nStart - 1;
635         }
636     }
637 
638     // Wurden Eintraege eingefuegt?
639     sal_uInt16 nCount = pSh->GetRedlineCount();
640     pRedlineData = aRedlineParents[nStart]->pData;
641 
642     for (i = nStart + 1; i < nCount; i++)
643     {
644         if (&pSh->GetRedline(i).GetRedlineData() == pRedlineData)
645         {
646             // Eintraege von nStart bis i-1 einfuegen
647             InsertParents(nStart, i - 1);
648             pTable->SetUpdateMode(sal_True);
649             return nStart - 1;
650         }
651     }
652 
653     pTable->SetUpdateMode(sal_True);
654     Init(nStart);   // Alle Eintraege bis zum Ende abgleichen
655     return USHRT_MAX;
656 }
657 
658 /* -----------------05.06.98 13:57-------------------
659  *
660  * --------------------------------------------------*/
661 
InsertChilds(SwRedlineDataParent * pParent,const SwRedline & rRedln,const sal_uInt16 nAutoFmt)662 void SwRedlineAcceptDlg::InsertChilds(SwRedlineDataParent *pParent, const SwRedline& rRedln, const sal_uInt16 nAutoFmt)
663 {
664     String sChild;
665     SwRedlineDataChild *pLastRedlineChild = 0;
666     const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
667     sal_Bool bAutoFmt = (rRedln.GetRealType() & nAutoFmt) != 0;
668 
669     const String *pAction = &GetActionText(rRedln);
670     sal_Bool bValidParent = !sFilterAction.Len() || sFilterAction == *pAction;
671     bValidParent = bValidParent && pTable->IsValidEntry(&rRedln.GetAuthorString(), &rRedln.GetTimeStamp(), &rRedln.GetComment());
672     if (nAutoFmt)
673     {
674         sal_uInt16 nPos;
675 
676         if (pParent->pData->GetSeqNo() && !aUsedSeqNo.Insert(pParent, nPos))    // Gibts schon
677         {
678             if (pParent->pTLBParent)
679             {
680                 pTable->SetEntryText(sAutoFormat, aUsedSeqNo[nPos]->pTLBParent, 0);
681                 pTable->RemoveEntry(pParent->pTLBParent);
682                 pParent->pTLBParent = 0;
683             }
684             return;
685         }
686         bValidParent = bValidParent && bAutoFmt;
687     }
688     sal_Bool bValidTree = bValidParent;
689 
690     for (sal_uInt16 nStack = 1; nStack < rRedln.GetStackCount(); nStack++)
691     {
692         pRedlineData = pRedlineData->Next();
693 
694         SwRedlineDataChildPtr pRedlineChild = new SwRedlineDataChild;
695         pRedlineChild->pChild = pRedlineData;
696         aRedlineChilds.Insert(pRedlineChild, aRedlineChilds.Count());
697 
698         if ( pLastRedlineChild )
699             pLastRedlineChild->pNext = pRedlineChild;
700         else
701             pParent->pNext = pRedlineChild;
702 
703         pAction = &GetActionText(rRedln, nStack);
704         sal_Bool bValidChild = !sFilterAction.Len() || sFilterAction == *pAction;
705         bValidChild = bValidChild && pTable->IsValidEntry(&rRedln.GetAuthorString(nStack), &rRedln.GetTimeStamp(nStack), &rRedln.GetComment());
706         if (nAutoFmt)
707             bValidChild = bValidChild && bAutoFmt;
708         bValidTree |= bValidChild;
709 
710         if (bValidChild)
711         {
712             RedlinData *pData = new RedlinData;
713             pData->pData = pRedlineChild;
714             pData->bDisabled = sal_True;
715             sChild = GetRedlineText(rRedln, pData->aDateTime, nStack);
716 
717             SvLBoxEntry* pChild = pTable->InsertEntry(sChild, pData, pParent->pTLBParent);
718 
719             pRedlineChild->pTLBChild = pChild;
720             if (!bValidParent)
721                 pTable->Expand(pParent->pTLBParent);
722         }
723         else
724             pRedlineChild->pTLBChild = 0;
725 
726         pLastRedlineChild = pRedlineChild;
727     }
728 
729     if (pLastRedlineChild)
730         pLastRedlineChild->pNext = 0;
731 
732     if (!bValidTree && pParent->pTLBParent)
733     {
734         pTable->RemoveEntry(pParent->pTLBParent);
735         pParent->pTLBParent = 0;
736         if (nAutoFmt)
737             aUsedSeqNo.Remove(pParent);
738     }
739 }
740 
741 /* -----------------05.06.98 15:20-------------------
742  *
743  * --------------------------------------------------*/
744 
RemoveParents(sal_uInt16 nStart,sal_uInt16 nEnd)745 void SwRedlineAcceptDlg::RemoveParents(sal_uInt16 nStart, sal_uInt16 nEnd)
746 {
747     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
748     sal_uInt16 nCount = pSh->GetRedlineCount();
749 
750     SvLBoxEntryArr aLBoxArr;
751 
752     // Wegen Bug der TLB, die bei Remove den SelectHandler IMMER ruft:
753     pTable->SetSelectHdl(aOldSelectHdl);
754     pTable->SetDeselectHdl(aOldDeselectHdl);
755     sal_Bool bChildsRemoved = sal_False;
756     pTable->SelectAll(sal_False);
757 
758     // Hinter dem letzten Eintrag Cursor setzen, da sonst Performance-Problem in TLB.
759     // TLB wuerde sonst bei jedem Remove den Cursor erneut umsetzen (teuer)
760     sal_uInt16 nPos = Min((sal_uInt16)nCount, (sal_uInt16)aRedlineParents.Count());
761     SvLBoxEntry *pCurEntry = NULL;
762     while( ( pCurEntry == NULL ) && ( nPos > 0 ) )
763     {
764         --nPos;
765         pCurEntry = aRedlineParents[nPos]->pTLBParent;
766     }
767 
768     if (pCurEntry)
769         pTable->SetCurEntry(pCurEntry);
770 
771     SvLBoxTreeList* pModel = pTable->GetModel();
772 
773     for (sal_uInt16 i = nStart; i <= nEnd; i++)
774     {
775         if (!bChildsRemoved && aRedlineParents[i]->pNext)
776         {
777             SwRedlineDataChildPtr pChildPtr = (SwRedlineDataChildPtr)aRedlineParents[i]->pNext;
778             sal_uInt16 nChildPos = aRedlineChilds.GetPos(pChildPtr);
779 
780             if (nChildPos != USHRT_MAX)
781             {
782                 sal_uInt16 nChilds = 0;
783 
784                 while (pChildPtr)
785                 {
786                     pChildPtr = (SwRedlineDataChildPtr)pChildPtr->pNext;
787                     nChilds++;
788                 }
789 
790                 aRedlineChilds.DeleteAndDestroy(nChildPos, nChilds);
791                 bChildsRemoved = sal_True;
792             }
793         }
794         SvLBoxEntry *pEntry = aRedlineParents[i]->pTLBParent;
795         if (pEntry)
796         {
797             long nIdx = aLBoxArr.Count() - 1L;
798             sal_uLong nAbsPos = pModel->GetAbsPos(pEntry);
799             while (nIdx >= 0 &&
800                     pModel->GetAbsPos(aLBoxArr[ static_cast< sal_uInt16 >(nIdx) ]) > nAbsPos)
801                 nIdx--;
802             aLBoxArr.Insert( pEntry, static_cast< sal_uInt16 >(++nIdx) );
803         }
804     }
805 
806     // TLB von hinten abraeumen
807     long nIdx = (long)aLBoxArr.Count() - 1L;
808     while (nIdx >= 0)
809         pTable->RemoveEntry(aLBoxArr[ static_cast< sal_uInt16 >(nIdx--) ]);
810 
811     pTable->SetSelectHdl(LINK(this, SwRedlineAcceptDlg, SelectHdl));
812     pTable->SetDeselectHdl(LINK(this, SwRedlineAcceptDlg, DeselectHdl));
813     // Durch Remove wurde leider wieder dauernd von der TLB selektiert...
814     pTable->SelectAll(sal_False);
815 
816     aRedlineParents.DeleteAndDestroy( nStart, nEnd - nStart + 1);
817 }
818 
819 /* -----------------05.06.98 15:20-------------------
820  *
821  * --------------------------------------------------*/
822 
InsertParents(sal_uInt16 nStart,sal_uInt16 nEnd)823 void SwRedlineAcceptDlg::InsertParents(sal_uInt16 nStart, sal_uInt16 nEnd)
824 {
825     SwView *pView   = ::GetActiveView();
826     SwWrtShell* pSh = pView->GetWrtShellPtr();
827     sal_uInt16 nAutoFmt = HasRedlineAutoFmt() ? nsRedlineType_t::REDLINE_FORM_AUTOFMT : 0;
828 
829     String sParent;
830     const sal_uInt16 nCount = pSh->GetRedlineCount();
831     nEnd = Min((sal_uInt16)nEnd, (sal_uInt16)(nCount - 1)); // Handelt auch nEnd=USHRT_MAX (bis zum Ende) ab
832 
833     if (nEnd == USHRT_MAX)
834         return;     // Keine Redlines im Dokument
835 
836     RedlinData *pData;
837     SvLBoxEntry *pParent;
838     SwRedlineDataParentPtr pRedlineParent;
839     const SwRedline* pCurrRedline;
840     if( !nStart && !pTable->FirstSelected() )
841     {
842         pCurrRedline = pSh->GetCurrRedline();
843         if( !pCurrRedline )
844         {
845             pSh->SwCrsrShell::Push();
846             if( 0 == (pCurrRedline = pSh->SelNextRedline()))
847                 pCurrRedline = pSh->SelPrevRedline();
848             pSh->SwCrsrShell::Pop( sal_False );
849         }
850     }
851     else
852         pCurrRedline = 0;
853 
854     for (sal_uInt16 i = nStart; i <= nEnd; i++)
855     {
856         const SwRedline& rRedln = pSh->GetRedline(i);
857         const SwRedlineData *pRedlineData = &rRedln.GetRedlineData();
858 
859         pRedlineParent = new SwRedlineDataParent;
860         pRedlineParent->pData    = pRedlineData;
861         pRedlineParent->pNext    = 0;
862         String sComment(rRedln.GetComment());
863         sComment.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
864         pRedlineParent->sComment = sComment;
865         aRedlineParents.Insert(pRedlineParent, i);
866 
867         pData = new RedlinData;
868         pData->pData = pRedlineParent;
869         pData->bDisabled = sal_False;
870 
871         sParent = GetRedlineText(rRedln, pData->aDateTime);
872         pParent = pTable->InsertEntry(sParent, pData, 0, i);
873         if( pCurrRedline == &rRedln )
874         {
875             pTable->SetCurEntry( pParent );
876             pTable->Select( pParent );
877             pTable->MakeVisible( pParent );
878         }
879 
880         pRedlineParent->pTLBParent = pParent;
881 
882         InsertChilds(pRedlineParent, rRedln, nAutoFmt);
883     }
884 }
885 
886 /* -----------------05.06.98 13:06-------------------
887  *
888  * --------------------------------------------------*/
889 
CallAcceptReject(sal_Bool bSelect,sal_Bool bAccept)890 void SwRedlineAcceptDlg::CallAcceptReject( sal_Bool bSelect, sal_Bool bAccept )
891 {
892     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
893     SvLBoxEntry* pEntry = bSelect ? pTable->FirstSelected() : pTable->First();
894     sal_uLong nPos = LONG_MAX;
895 
896     typedef std::vector<SvLBoxEntry*> ListBoxEntries_t;
897     ListBoxEntries_t aRedlines;
898 
899     // don't activate
900     DBG_ASSERT( bInhibitActivate == false,
901                 "recursive call of CallAcceptReject?");
902     bInhibitActivate = true;
903 
904     // collect redlines-to-be-accepted/rejected in aRedlines vector
905     while( pEntry )
906     {
907         if( !pTable->GetParent( pEntry ) )
908         {
909             if( bSelect && LONG_MAX == nPos )
910                 nPos = pTable->GetModel()->GetAbsPos( pEntry );
911 
912             RedlinData *pData = (RedlinData *)pEntry->GetUserData();
913 
914             if( !pData->bDisabled )
915                 aRedlines.push_back( pEntry );
916         }
917 
918         pEntry = bSelect ? pTable->NextSelected(pEntry) : pTable->Next(pEntry);
919     }
920 
921     sal_Bool (SwEditShell:: *FnAccRej)( sal_uInt16 ) = &SwEditShell::AcceptRedline;
922     if( !bAccept )
923         FnAccRej = &SwEditShell::RejectRedline;
924 
925     SwWait aWait( *pSh->GetView().GetDocShell(), true );
926     pSh->StartAction();
927 
928     // #111827#
929     if (aRedlines.size() > 1)
930     {
931         String aTmpStr;
932         {
933             SwRewriter aRewriter;
934             aRewriter.AddRule(UNDO_ARG1,
935                               String::CreateFromInt32(aRedlines.size()));
936             aTmpStr = aRewriter.Apply(String(SW_RES(STR_N_REDLINES)));
937         }
938 
939         SwRewriter aRewriter;
940         aRewriter.AddRule(UNDO_ARG1, aTmpStr);
941 
942         pSh->StartUndo(bAccept? UNDO_ACCEPT_REDLINE : UNDO_REJECT_REDLINE,
943                        &aRewriter);
944     }
945 
946     // accept/reject the the redlines in aRedlines. The absolute
947     // position may change during the process (e.g. when two redlines
948     // are merged in result of another one being deleted), so the
949     // position must be resolved late and checked before using it.
950     // (cf #102547#)
951     ListBoxEntries_t::iterator aEnd = aRedlines.end();
952     for( ListBoxEntries_t::iterator aIter = aRedlines.begin();
953          aIter != aEnd;
954          aIter++ )
955     {
956         const sal_uInt16 nPosition = GetRedlinePos( **aIter );
957         if( nPosition != USHRT_MAX )
958             (pSh->*FnAccRej)( nPosition );
959     }
960 
961     // #111827#
962     if (aRedlines.size() > 1)
963     {
964         pSh->EndUndo();
965     }
966 
967     pSh->EndAction();
968 
969     bInhibitActivate = false;
970     Activate();
971 
972     if( ULONG_MAX != nPos && pTable->GetEntryCount() )
973     {
974         if( nPos >= pTable->GetEntryCount() )
975             nPos = pTable->GetEntryCount() - 1;
976         pEntry = pTable->GetEntry( nPos );
977         if( !pEntry && nPos-- )
978             pEntry = pTable->GetEntry( nPos );
979         if( pEntry )
980         {
981             pTable->Select( pEntry );
982             pTable->MakeVisible( pEntry );
983             pTable->SetCurEntry(pEntry);
984         }
985     }
986     pTPView->EnableUndo();
987 }
988 
989 /*--------------------------------------------------------------------
990     Beschreibung:
991  --------------------------------------------------------------------*/
992 
GetRedlinePos(const SvLBoxEntry & rEntry) const993 sal_uInt16 SwRedlineAcceptDlg::GetRedlinePos( const SvLBoxEntry& rEntry ) const
994 {
995     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
996     return pSh->FindRedlineOfData( *((SwRedlineDataParent*)((RedlinData *)
997                                     rEntry.GetUserData())->pData)->pData );
998 }
999 
1000 /*--------------------------------------------------------------------
1001     Beschreibung:
1002  --------------------------------------------------------------------*/
1003 
IMPL_LINK(SwRedlineAcceptDlg,AcceptHdl,void *,EMPTYARG)1004 IMPL_LINK( SwRedlineAcceptDlg, AcceptHdl, void*, EMPTYARG)
1005 {
1006     CallAcceptReject( sal_True, sal_True );
1007     return 0;
1008 }
1009 
1010 /*--------------------------------------------------------------------
1011     Beschreibung:
1012  --------------------------------------------------------------------*/
1013 
IMPL_LINK(SwRedlineAcceptDlg,AcceptAllHdl,void *,EMPTYARG)1014 IMPL_LINK( SwRedlineAcceptDlg, AcceptAllHdl, void*, EMPTYARG )
1015 {
1016     CallAcceptReject( sal_False, sal_True );
1017     return 0;
1018 }
1019 
1020 /*--------------------------------------------------------------------
1021     Beschreibung:
1022  --------------------------------------------------------------------*/
1023 
IMPL_LINK(SwRedlineAcceptDlg,RejectHdl,void *,EMPTYARG)1024 IMPL_LINK( SwRedlineAcceptDlg, RejectHdl, void*, EMPTYARG )
1025 {
1026     CallAcceptReject( sal_True, sal_False );
1027     return 0;
1028 }
1029 
1030 /*--------------------------------------------------------------------
1031     Beschreibung:
1032  --------------------------------------------------------------------*/
1033 
IMPL_LINK(SwRedlineAcceptDlg,RejectAllHdl,void *,EMPTYARG)1034 IMPL_LINK( SwRedlineAcceptDlg, RejectAllHdl, void*, EMPTYARG )
1035 {
1036     CallAcceptReject( sal_False, sal_False );
1037     return 0;
1038 }
1039 
1040 /*--------------------------------------------------------------------
1041     Beschreibung:
1042  --------------------------------------------------------------------*/
1043 
IMPL_LINK(SwRedlineAcceptDlg,UndoHdl,void *,EMPTYARG)1044 IMPL_LINK( SwRedlineAcceptDlg, UndoHdl, void*, EMPTYARG )
1045 {
1046     SwView * pView = ::GetActiveView();
1047     pView->GetViewFrame()->GetDispatcher()->
1048                 Execute(SID_UNDO, SFX_CALLMODE_SYNCHRON);
1049     pTPView->EnableUndo(pView->GetSlotState(SID_UNDO) != 0);
1050 
1051     Activate();
1052 
1053     return 0;
1054 }
1055 
1056 /*--------------------------------------------------------------------
1057     Beschreibung:
1058  --------------------------------------------------------------------*/
1059 
IMPL_LINK(SwRedlineAcceptDlg,FilterChangedHdl,void *,EMPTYARG)1060 IMPL_LINK( SwRedlineAcceptDlg, FilterChangedHdl, void*, EMPTYARG )
1061 {
1062     SvxTPFilter *pFilterTP = aTabPagesCTRL.GetFilterPage();
1063 
1064     if (pFilterTP->IsAction())
1065         sFilterAction = pFilterTP->GetLbAction()->GetSelectEntry();
1066     else
1067         sFilterAction = aEmptyStr;
1068 
1069     Init();
1070 
1071     return 0;
1072 }
1073 
1074 /*--------------------------------------------------------------------
1075     Beschreibung:
1076  --------------------------------------------------------------------*/
1077 
IMPL_LINK(SwRedlineAcceptDlg,DeselectHdl,void *,EMPTYARG)1078 IMPL_LINK( SwRedlineAcceptDlg, DeselectHdl, void*, EMPTYARG )
1079 {
1080     // Flackern der Buttons vermeiden:
1081     aDeselectTimer.Start();
1082 
1083     return 0;
1084 }
1085 
1086 /*--------------------------------------------------------------------
1087     Beschreibung:
1088  --------------------------------------------------------------------*/
1089 
IMPL_LINK(SwRedlineAcceptDlg,SelectHdl,void *,EMPTYARG)1090 IMPL_LINK( SwRedlineAcceptDlg, SelectHdl, void*, EMPTYARG )
1091 {
1092     aDeselectTimer.Stop();
1093     aSelectTimer.Start();
1094 
1095     return 0;
1096 }
1097 
1098 /*--------------------------------------------------------------------
1099     Beschreibung:
1100  --------------------------------------------------------------------*/
1101 
IMPL_LINK(SwRedlineAcceptDlg,GotoHdl,void *,EMPTYARG)1102 IMPL_LINK( SwRedlineAcceptDlg, GotoHdl, void*, EMPTYARG )
1103 {
1104     SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
1105     aSelectTimer.Stop();
1106 
1107     sal_Bool bIsNotFormated = sal_False;
1108     sal_Bool bSel = sal_False;
1109 
1110     //#98883# don't select redlines while the dialog is not focussed
1111     //#107938# But not only ask pTable if it has the focus. To move
1112     //         the selection to the selected redline any child of pParentDlg
1113     //         may the focus.
1114     SvLBoxEntry* pSelEntry = 0;
1115 
1116     if (pParentDlg->HasChildPathFocus())
1117         pSelEntry = pTable->FirstSelected();
1118 
1119     if( pSelEntry )
1120     {
1121         SvLBoxEntry* pActEntry = pSelEntry;
1122         pSh->StartAction();
1123         pSh->EnterStdMode();
1124         pSh->SetCareWin(pParentDlg);
1125 
1126         while (pSelEntry)
1127         {
1128             if (pTable->GetParent(pSelEntry))
1129             {
1130                 pActEntry = pTable->GetParent(pSelEntry);
1131 
1132                 if (pTable->IsSelected(pActEntry))
1133                 {
1134                     pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
1135                     continue;   // Nicht zweimal selektieren
1136                 }
1137             }
1138             else
1139                 bSel = sal_True;
1140 
1141             // #98864# find the selected redline (ignore, if the redline is already gone)
1142             const sal_uInt16 nPos = GetRedlinePos(*pActEntry);
1143             if ( nPos < pSh->GetRedlineCount() )
1144             {
1145 
1146                 const SwRedline& rRedln = pSh->GetRedline( nPos );
1147                 bIsNotFormated |= nsRedlineType_t::REDLINE_FORMAT != rRedln.GetType();
1148 
1149                 if (pSh->GotoRedline(nPos, sal_True))
1150                 {
1151                     pSh->SetInSelect();
1152                     pSh->EnterAddMode();
1153                 }
1154             }
1155 
1156             pSelEntry = pActEntry = pTable->NextSelected(pSelEntry);
1157         }
1158 
1159         pSh->LeaveAddMode();
1160         pSh->EndAction();
1161         pSh->SetCareWin(NULL);
1162     }
1163     sal_Bool bEnable = !pSh->getIDocumentRedlineAccess()->GetRedlinePassword().getLength();
1164     pTPView->EnableAccept( bEnable && bSel /*&& !bReadonlySel*/ );
1165     pTPView->EnableReject( bEnable && bSel && bIsNotFormated /*&& !bReadonlySel*/ );
1166     pTPView->EnableRejectAll( bEnable && !bOnlyFormatedRedlines && !bHasReadonlySel );
1167 
1168     return 0;
1169 }
1170 
1171 /*--------------------------------------------------------------------
1172     Beschreibung:
1173  --------------------------------------------------------------------*/
1174 
IMPL_LINK(SwRedlineAcceptDlg,CommandHdl,void *,EMPTYARG)1175 IMPL_LINK( SwRedlineAcceptDlg, CommandHdl, void*, EMPTYARG )
1176 {
1177     const CommandEvent aCEvt(pTable->GetCommandEvent());
1178 
1179     switch ( aCEvt.GetCommand() )
1180     {
1181         case COMMAND_CONTEXTMENU:
1182         {
1183             SwWrtShell* pSh = ::GetActiveView()->GetWrtShellPtr();
1184             SvLBoxEntry* pEntry = pTable->FirstSelected();
1185             const SwRedline *pRed = 0;
1186 
1187             if (pEntry)
1188             {
1189                 SvLBoxEntry* pTopEntry = pEntry;
1190 
1191                 if (pTable->GetParent(pEntry))
1192                     pTopEntry = pTable->GetParent(pEntry);
1193 
1194                 const sal_uInt16 nPos = GetRedlinePos(*pTopEntry);
1195 
1196                 // Bei geschuetzten Bereichen kommentieren disablen
1197                 if ((pRed = pSh->GotoRedline(nPos, sal_True)) != 0)
1198                 {
1199                     if( pSh->IsCrsrPtAtEnd() )
1200                         pSh->SwapPam();
1201                     pSh->SetInSelect();
1202                 }
1203             }
1204 
1205             aPopup.EnableItem( MN_EDIT_COMMENT, pEntry && pRed &&
1206                                             !pTable->GetParent(pEntry) &&
1207                                             !pTable->NextSelected(pEntry)
1208 //JP 27.9.2001: make no sense if we handle readonly sections
1209 //                                          && pRed->HasReadonlySel()
1210                                             );
1211 
1212             aPopup.EnableItem( MN_SUB_SORT, pTable->First() != 0 );
1213             sal_uInt16 nColumn = pTable->GetSortedCol();
1214             if (nColumn == 0xffff)
1215                 nColumn = 4;
1216 
1217             PopupMenu *pSubMenu = aPopup.GetPopupMenu(MN_SUB_SORT);
1218             if (pSubMenu)
1219             {
1220                 for (sal_uInt16 i = MN_SORT_ACTION; i < MN_SORT_ACTION + 5; i++)
1221                     pSubMenu->CheckItem(i, sal_False);
1222 
1223                 pSubMenu->CheckItem(nColumn + MN_SORT_ACTION);
1224             }
1225 
1226             sal_uInt16 nRet = aPopup.Execute(pTable, aCEvt.GetMousePosPixel());
1227 
1228             switch( nRet )
1229             {
1230             case MN_EDIT_COMMENT:
1231                 {
1232                     String sComment;
1233                     if (pEntry)
1234                     {
1235                         if (pTable->GetParent(pEntry))
1236                             pEntry = pTable->GetParent(pEntry);
1237 
1238                         const sal_uInt16 nPos = GetRedlinePos(*pEntry);
1239                         if ( nPos >= pSh->GetRedlineCount() )
1240                         {
1241                             break;
1242                         }
1243                         const SwRedline &rRedline = pSh->GetRedline(nPos);
1244 
1245 
1246                         /* enable again once we have redline comments in the margin
1247                         sComment = rRedline.GetComment();
1248                         if ( sComment == String(::rtl::OUString::createFromAscii("")) )
1249                         GetActiveView()->GetDocShell()->Broadcast(SwRedlineHint(&rRedline,SWREDLINE_INSERTED));
1250                         const_cast<SwRedline&>(rRedline).Broadcast(SwRedlineHint(&rRedline,SWREDLINE_FOCUS));
1251                         */
1252 
1253                         sComment = rRedline.GetComment();
1254                         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1255                         DBG_ASSERT(pFact, "Dialogdiet fail!");
1256                         ::DialogGetRanges fnGetRange = pFact->GetDialogGetRangesFunc( RID_SVXDLG_POSTIT );
1257                         DBG_ASSERT(fnGetRange, "Dialogdiet fail! GetRanges()");
1258                         SfxItemSet aSet( pSh->GetAttrPool(), fnGetRange() );
1259 
1260                         aSet.Put(SvxPostItTextItem(sComment.ConvertLineEnd(), SID_ATTR_POSTIT_TEXT));
1261                         aSet.Put(SvxPostItAuthorItem(rRedline.GetAuthorString(), SID_ATTR_POSTIT_AUTHOR));
1262 
1263                         aSet.Put(SvxPostItDateItem( GetAppLangDateTimeString(
1264                             rRedline.GetRedlineData().GetTimeStamp() ),
1265                             SID_ATTR_POSTIT_DATE ));
1266 
1267                         AbstractSvxPostItDialog* pDlg = pFact->CreateSvxPostItDialog( pParentDlg, aSet, sal_False );
1268                         DBG_ASSERT(pDlg, "Dialogdiet fail!");
1269 
1270                         pDlg->HideAuthor();
1271 
1272                         sal_uInt16 nResId = 0;
1273                         switch( rRedline.GetType() )
1274                         {
1275                         case nsRedlineType_t::REDLINE_INSERT:
1276                             nResId = STR_REDLINE_INSERTED;
1277                             break;
1278                         case nsRedlineType_t::REDLINE_DELETE:
1279                             nResId = STR_REDLINE_DELETED;
1280                             break;
1281                         case nsRedlineType_t::REDLINE_FORMAT:
1282                             nResId = STR_REDLINE_FORMATED;
1283                             break;
1284                         case nsRedlineType_t::REDLINE_TABLE:
1285                             nResId = STR_REDLINE_TABLECHG;
1286                             break;
1287                         default:;//prevent warning
1288                         }
1289                         String sTitle(SW_RES(STR_REDLINE_COMMENT));
1290                         if( nResId )
1291                             sTitle += SW_RESSTR( nResId );
1292                         pDlg->SetText(sTitle);
1293 
1294                         pSh->SetCareWin(pDlg->GetWindow());
1295 
1296                         if ( pDlg->Execute() == RET_OK )
1297                         {
1298                             const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
1299                             String sMsg(((const SvxPostItTextItem&)pOutSet->Get(SID_ATTR_POSTIT_TEXT)).GetValue());
1300 
1301                             // Kommentar einfuegen bzw aendern
1302                             pSh->SetRedlineComment(sMsg);
1303                             sMsg.SearchAndReplaceAll((sal_Unicode)_LF,(sal_Unicode)' ');
1304                             pTable->SetEntryText(sMsg, pEntry, 3);
1305                         }
1306 
1307                         delete pDlg;
1308                         pSh->SetCareWin(NULL);
1309                     }
1310 
1311                 }
1312                 break;
1313 
1314             case MN_SORT_ACTION:
1315             case MN_SORT_AUTHOR:
1316             case MN_SORT_DATE:
1317             case MN_SORT_COMMENT:
1318             case MN_SORT_POSITION:
1319                 {
1320                     bSortDir = sal_True;
1321                     if (nRet - MN_SORT_ACTION == 4 && pTable->GetSortedCol() == 0xffff)
1322                         break;  // Haben wir schon
1323 
1324                     nSortMode = nRet - MN_SORT_ACTION;
1325                     if (nSortMode == 4)
1326                         nSortMode = 0xffff; // unsortiert bzw sortiert nach Position
1327 
1328                     if (pTable->GetSortedCol() == nSortMode)
1329                         bSortDir = !pTable->GetSortDirection();
1330 
1331                     SwWait aWait( *::GetActiveView()->GetDocShell(), false );
1332                     pTable->SortByCol(nSortMode, bSortDir);
1333                     if (nSortMode == 0xffff)
1334                         Init();             // Alles neu fuellen
1335                 }
1336                 break;
1337             }
1338         }
1339         break;
1340     }
1341 
1342     return 0;
1343 }
1344 
1345 /*--------------------------------------------------------------------
1346     Beschreibung:
1347  --------------------------------------------------------------------*/
1348 
Initialize(const String & rExtraData)1349 void SwRedlineAcceptDlg::Initialize(const String& rExtraData)
1350 {
1351     if (rExtraData.Len())
1352     {
1353         sal_uInt16 nPos = rExtraData.Search(C2S("AcceptChgDat:"));
1354 
1355         // Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
1356         // er nicht vorhanden ist, liegt eine "altere Version vor
1357         if (nPos != STRING_NOTFOUND)
1358         {
1359             sal_uInt16 n1 = rExtraData.Search('(', nPos);
1360             if (n1 != STRING_NOTFOUND)
1361             {
1362                 sal_uInt16 n2 = rExtraData.Search(')', n1);
1363                 if (n2 != STRING_NOTFOUND)
1364                 {
1365                     // Alignment-String herausschneiden
1366                     String aStr = rExtraData.Copy(nPos, n2 - nPos + 1);
1367                     aStr.Erase(0, n1 - nPos + 1);
1368 
1369                     if (aStr.Len())
1370                     {
1371                         sal_uInt16 nCount = static_cast< sal_uInt16 >(aStr.ToInt32());
1372 
1373                         for (sal_uInt16 i = 0; i < nCount; i++)
1374                         {
1375                             sal_uInt16 n3 = aStr.Search(';');
1376                             aStr.Erase(0, n3 + 1);
1377                             pTable->SetTab(i, aStr.ToInt32(), MAP_PIXEL);
1378                         }
1379                     }
1380                 }
1381             }
1382         }
1383     }
1384 }
1385 
1386 /*--------------------------------------------------------------------
1387     Beschreibung:
1388  --------------------------------------------------------------------*/
1389 
FillInfo(String & rExtraData) const1390 void SwRedlineAcceptDlg::FillInfo(String &rExtraData) const
1391 {
1392     rExtraData.AppendAscii("AcceptChgDat:(");
1393 
1394     sal_uInt16  nCount = pTable->TabCount();
1395 
1396     rExtraData += String::CreateFromInt32(nCount);
1397     rExtraData += ';';
1398     for(sal_uInt16 i = 0; i < nCount; i++)
1399     {
1400         rExtraData += String::CreateFromInt32( pTable->GetTab(i) );
1401         rExtraData += ';';
1402     }
1403     rExtraData += ')';
1404 }
1405