xref: /trunk/main/sw/source/ui/misc/redlndlg.cxx (revision efeef26f)
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