1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 //-----------------------------------------------------------------------------
32 
33 #include <vcl/msgbox.hxx>
34 
35 #include "conflictsdlg.hxx"
36 #include "conflictsdlg.hrc"
37 #include "scresid.hxx"
38 #include "viewdata.hxx"
39 #include "dbfunc.hxx"
40 
41 
42 //=============================================================================
43 // struct ScConflictsListEntry
44 //=============================================================================
45 
46 bool ScConflictsListEntry::HasSharedAction( sal_uLong nSharedAction ) const
47 {
48     ScChangeActionList::const_iterator aEnd = maSharedActions.end();
49     for ( ScChangeActionList::const_iterator aItr = maSharedActions.begin(); aItr != aEnd; ++aItr )
50     {
51         if ( *aItr == nSharedAction )
52         {
53             return true;
54         }
55     }
56 
57     return false;
58 }
59 
60 bool ScConflictsListEntry::HasOwnAction( sal_uLong nOwnAction ) const
61 {
62     ScChangeActionList::const_iterator aEnd = maOwnActions.end();
63     for ( ScChangeActionList::const_iterator aItr = maOwnActions.begin(); aItr != aEnd; ++aItr )
64     {
65         if ( *aItr == nOwnAction )
66         {
67             return true;
68         }
69     }
70 
71     return false;
72 }
73 
74 
75 //=============================================================================
76 // class ScConflictsListHelper
77 //=============================================================================
78 
79 //UNUSED2008-05  bool ScConflictsListHelper::HasSharedAction( ScConflictsList& rConflictsList, sal_uLong nSharedAction )
80 //UNUSED2008-05  {
81 //UNUSED2008-05      ScConflictsList::const_iterator aEnd = rConflictsList.end();
82 //UNUSED2008-05      for ( ScConflictsList::const_iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
83 //UNUSED2008-05      {
84 //UNUSED2008-05          if ( aItr->HasSharedAction( nSharedAction ) )
85 //UNUSED2008-05          {
86 //UNUSED2008-05              return true;
87 //UNUSED2008-05          }
88 //UNUSED2008-05      }
89 //UNUSED2008-05
90 //UNUSED2008-05      return false;
91 //UNUSED2008-05  }
92 
93 bool ScConflictsListHelper::HasOwnAction( ScConflictsList& rConflictsList, sal_uLong nOwnAction )
94 {
95     ScConflictsList::const_iterator aEnd = rConflictsList.end();
96     for ( ScConflictsList::const_iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
97     {
98         if ( aItr->HasOwnAction( nOwnAction ) )
99         {
100             return true;
101         }
102     }
103 
104     return false;
105 }
106 
107 ScConflictsListEntry* ScConflictsListHelper::GetSharedActionEntry( ScConflictsList& rConflictsList, sal_uLong nSharedAction )
108 {
109     ScConflictsList::iterator aEnd = rConflictsList.end();
110     for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
111     {
112         if ( aItr->HasSharedAction( nSharedAction ) )
113         {
114             return &(*aItr);
115         }
116     }
117 
118     return NULL;
119 }
120 
121 ScConflictsListEntry* ScConflictsListHelper::GetOwnActionEntry( ScConflictsList& rConflictsList, sal_uLong nOwnAction )
122 {
123     ScConflictsList::iterator aEnd = rConflictsList.end();
124     for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
125     {
126         if ( aItr->HasOwnAction( nOwnAction ) )
127         {
128             return &(*aItr);
129         }
130     }
131 
132     return NULL;
133 }
134 
135 void ScConflictsListHelper::Transform_Impl( ScChangeActionList& rActionList, ScChangeActionMergeMap* pMergeMap )
136 {
137     if ( !pMergeMap )
138     {
139         return;
140     }
141 
142     for ( ScChangeActionList::iterator aItr = rActionList.begin(); aItr != rActionList.end(); )
143     {
144         ScChangeActionMergeMap::iterator aItrMap = pMergeMap->find( *aItr );
145         if ( aItrMap != pMergeMap->end() )
146         {
147             *aItr = aItrMap->second;
148             aItr++;
149         }
150         else
151         {
152             aItr = rActionList.erase( aItr );
153             DBG_ERROR( "ScConflictsListHelper::Transform_Impl: erased action from conflicts list!" );
154         }
155     }
156 }
157 
158 void ScConflictsListHelper::TransformConflictsList( ScConflictsList& rConflictsList,
159     ScChangeActionMergeMap* pSharedMap, ScChangeActionMergeMap* pOwnMap )
160 {
161     ScConflictsList::iterator aEnd = rConflictsList.end();
162     for ( ScConflictsList::iterator aItr = rConflictsList.begin(); aItr != aEnd; ++aItr )
163     {
164         if ( pSharedMap )
165         {
166             ScConflictsListHelper::Transform_Impl( aItr->maSharedActions, pSharedMap );
167         }
168 
169         if ( pOwnMap )
170         {
171             ScConflictsListHelper::Transform_Impl( aItr->maOwnActions, pOwnMap );
172         }
173     }
174 }
175 
176 
177 //=============================================================================
178 // class ScConflictsFinder
179 //=============================================================================
180 
181 ScConflictsFinder::ScConflictsFinder( ScChangeTrack* pTrack, sal_uLong nStartShared, sal_uLong nEndShared,
182         sal_uLong nStartOwn, sal_uLong nEndOwn, ScConflictsList& rConflictsList )
183     :mpTrack( pTrack )
184     ,mnStartShared( nStartShared )
185     ,mnEndShared( nEndShared )
186     ,mnStartOwn( nStartOwn )
187     ,mnEndOwn( nEndOwn )
188     ,mrConflictsList( rConflictsList )
189 {
190 }
191 
192 ScConflictsFinder::~ScConflictsFinder()
193 {
194 }
195 
196 bool ScConflictsFinder::DoActionsIntersect( const ScChangeAction* pAction1, const ScChangeAction* pAction2 )
197 {
198     if ( pAction1 && pAction2 && pAction1->GetBigRange().Intersects( pAction2->GetBigRange() ) )
199     {
200         return true;
201     }
202     return false;
203 }
204 
205 ScConflictsListEntry* ScConflictsFinder::GetIntersectingEntry( const ScChangeAction* pAction ) const
206 {
207     ScConflictsList::iterator aEnd = mrConflictsList.end();
208     for ( ScConflictsList::iterator aItr = mrConflictsList.begin(); aItr != aEnd; ++aItr )
209     {
210         ScChangeActionList::const_iterator aEndShared = aItr->maSharedActions.end();
211         for ( ScChangeActionList::const_iterator aItrShared = aItr->maSharedActions.begin(); aItrShared != aEndShared; ++aItrShared )
212         {
213             if ( DoActionsIntersect( mpTrack->GetAction( *aItrShared ), pAction ) )
214             {
215                 return &(*aItr);
216             }
217         }
218 
219         ScChangeActionList::const_iterator aEndOwn = aItr->maOwnActions.end();
220         for ( ScChangeActionList::const_iterator aItrOwn = aItr->maOwnActions.begin(); aItrOwn != aEndOwn; ++aItrOwn )
221         {
222             if ( DoActionsIntersect( mpTrack->GetAction( *aItrOwn ), pAction ) )
223             {
224                 return &(*aItr);
225             }
226         }
227     }
228 
229     return NULL;
230 }
231 
232 ScConflictsListEntry* ScConflictsFinder::GetEntry( sal_uLong nSharedAction, const ScChangeActionList& rOwnActions )
233 {
234     // try to get a list entry which already contains the shared action
235     ScConflictsListEntry* pEntry = ScConflictsListHelper::GetSharedActionEntry( mrConflictsList, nSharedAction );
236     if ( pEntry )
237     {
238         return pEntry;
239     }
240 
241     // try to get a list entry for which the shared action intersects with any
242     // other action of this entry
243     pEntry = GetIntersectingEntry( mpTrack->GetAction( nSharedAction ) );
244     if ( pEntry )
245     {
246         pEntry->maSharedActions.push_back( nSharedAction );
247         return pEntry;
248     }
249 
250     // try to get a list entry for which any of the own actions intersects with
251     // any other action of this entry
252     ScChangeActionList::const_iterator aEnd = rOwnActions.end();
253     for ( ScChangeActionList::const_iterator aItr = rOwnActions.begin(); aItr != aEnd; ++aItr )
254     {
255         pEntry = GetIntersectingEntry( mpTrack->GetAction( *aItr ) );
256         if ( pEntry )
257         {
258             pEntry->maSharedActions.push_back( nSharedAction );
259             return pEntry;
260         }
261     }
262 
263     // if no entry was found, create a new one
264     ScConflictsListEntry aEntry;
265     aEntry.meConflictAction = SC_CONFLICT_ACTION_NONE;
266     aEntry.maSharedActions.push_back( nSharedAction );
267     mrConflictsList.push_back( aEntry );
268     return &(mrConflictsList.back());
269 }
270 
271 bool ScConflictsFinder::Find()
272 {
273     if ( !mpTrack )
274     {
275         return false;
276     }
277 
278     bool bReturn = false;
279     ScChangeAction* pSharedAction = mpTrack->GetAction( mnStartShared );
280     while ( pSharedAction && pSharedAction->GetActionNumber() <= mnEndShared )
281     {
282         ScChangeActionList aOwnActions;
283         ScChangeAction* pOwnAction = mpTrack->GetAction( mnStartOwn );
284         while ( pOwnAction && pOwnAction->GetActionNumber() <= mnEndOwn )
285         {
286             if ( DoActionsIntersect( pSharedAction, pOwnAction ) )
287             {
288                 aOwnActions.push_back( pOwnAction->GetActionNumber() );
289             }
290             pOwnAction = pOwnAction->GetNext();
291         }
292 
293         if ( aOwnActions.size() )
294         {
295             ScConflictsListEntry* pEntry = GetEntry( pSharedAction->GetActionNumber(), aOwnActions );;
296             ScChangeActionList::iterator aEnd = aOwnActions.end();
297             for ( ScChangeActionList::iterator aItr = aOwnActions.begin(); aItr != aEnd; ++aItr )
298             {
299                 if ( pEntry && !ScConflictsListHelper::HasOwnAction( mrConflictsList, *aItr ) )
300                 {
301                     pEntry->maOwnActions.push_back( *aItr );
302                 }
303             }
304             bReturn = true;
305         }
306 
307         pSharedAction = pSharedAction->GetNext();
308     }
309 
310     return bReturn;
311 }
312 
313 //=============================================================================
314 // class ScConflictsResolver
315 //=============================================================================
316 
317 ScConflictsResolver::ScConflictsResolver( ScChangeTrack* pTrack, ScConflictsList& rConflictsList )
318     :mpTrack ( pTrack )
319     ,mrConflictsList ( rConflictsList )
320 {
321     DBG_ASSERT( mpTrack, "ScConflictsResolver CTOR: mpTrack is null!" );
322 }
323 
324 ScConflictsResolver::~ScConflictsResolver()
325 {
326 }
327 
328 void ScConflictsResolver::HandleAction( ScChangeAction* pAction, bool bIsSharedAction,
329     bool bHandleContentAction, bool bHandleNonContentAction )
330 {
331     if ( !mpTrack || !pAction )
332     {
333         return;
334     }
335 
336     if ( bIsSharedAction )
337     {
338         ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetSharedActionEntry(
339             mrConflictsList, pAction->GetActionNumber() );
340         if ( pConflictEntry )
341         {
342             ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
343             if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
344             {
345                 if ( pAction->GetType() == SC_CAT_CONTENT )
346                 {
347                     if ( bHandleContentAction )
348                     {
349                         mpTrack->Reject( pAction );
350                     }
351                 }
352                 else
353                 {
354                     if ( bHandleNonContentAction )
355                     {
356                         mpTrack->Reject( pAction );
357                     }
358                 }
359             }
360             else if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_OTHER )
361             {
362                 if ( pAction->GetType() == SC_CAT_CONTENT )
363                 {
364                     if ( bHandleContentAction )
365                     {
366                         // do nothing
367                         //mpTrack->SelectContent( pAction );
368                     }
369                 }
370                 else
371                 {
372                     if ( bHandleNonContentAction )
373                     {
374                         // do nothing
375                         //mpTrack->Accept( pAction );
376                     }
377                 }
378             }
379         }
380     }
381     else
382     {
383         ScConflictsListEntry* pConflictEntry = ScConflictsListHelper::GetOwnActionEntry(
384             mrConflictsList, pAction->GetActionNumber() );
385         if ( pConflictEntry )
386         {
387             ScConflictAction eConflictAction = pConflictEntry->meConflictAction;
388             if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_MINE )
389             {
390                 if ( pAction->GetType() == SC_CAT_CONTENT )
391                 {
392                     if ( bHandleContentAction )
393                     {
394                         // do nothing
395                         //mpTrack->SelectContent( pAction );
396                     }
397                 }
398                 else
399                 {
400                     if ( bHandleNonContentAction )
401                     {
402                         // do nothing
403                         //mpTrack->Accept( pAction );
404                     }
405                 }
406             }
407             else if ( eConflictAction == SC_CONFLICT_ACTION_KEEP_OTHER )
408             {
409                 if ( pAction->GetType() == SC_CAT_CONTENT )
410                 {
411                     if ( bHandleContentAction )
412                     {
413                         mpTrack->Reject( pAction );
414                     }
415                 }
416                 else
417                 {
418                     if ( bHandleNonContentAction )
419                     {
420                         mpTrack->Reject( pAction );
421                     }
422                 }
423             }
424         }
425     }
426 }
427 
428 
429 //=============================================================================
430 // class ScConflictsListBox
431 //=============================================================================
432 
433 //UNUSED2008-05  ScConflictsListBox::ScConflictsListBox( Window* pParent, WinBits nBits )
434 //UNUSED2008-05      :SvxRedlinTable( pParent, nBits )
435 //UNUSED2008-05  {
436 //UNUSED2008-05  }
437 
438 ScConflictsListBox::ScConflictsListBox( Window* pParent, const ResId& rResId )
439     :SvxRedlinTable( pParent, rResId )
440 {
441 }
442 
443 ScConflictsListBox::~ScConflictsListBox()
444 {
445 }
446 
447 //UNUSED2008-05  sal_uLong ScConflictsListBox::GetRootEntryPos( const SvLBoxEntry* pRootEntry ) const
448 //UNUSED2008-05  {
449 //UNUSED2008-05      sal_uLong nPos = 0;
450 //UNUSED2008-05      SvLBoxEntry* pEntry = GetRootLevelParent( First() );
451 //UNUSED2008-05      while ( pEntry )
452 //UNUSED2008-05      {
453 //UNUSED2008-05          if ( pEntry == pRootEntry )
454 //UNUSED2008-05          {
455 //UNUSED2008-05              return nPos;
456 //UNUSED2008-05          }
457 //UNUSED2008-05          pEntry = NextSibling( pEntry );
458 //UNUSED2008-05          ++nPos;
459 //UNUSED2008-05      }
460 //UNUSED2008-05      return 0xffffffff;
461 //UNUSED2008-05  }
462 
463 
464 //=============================================================================
465 // class ScConflictsDlg
466 //=============================================================================
467 
468 ScConflictsDlg::ScConflictsDlg( Window* pParent, ScViewData* pViewData, ScDocument* pSharedDoc, ScConflictsList& rConflictsList )
469     :ModalDialog( pParent, ScResId( RID_SCDLG_CONFLICTS ) )
470     ,maFtConflicts      ( this, ScResId( FT_CONFLICTS ) )
471     ,maLbConflicts      ( this, ScResId( LB_CONFLICTS ) )
472     ,maBtnKeepMine      ( this, ScResId( BTN_KEEPMINE ) )
473     ,maBtnKeepOther     ( this, ScResId( BTN_KEEPOTHER ) )
474     ,maFlConflicts      ( this, ScResId( FL_CONFLICTS ) )
475     ,maBtnKeepAllMine   ( this, ScResId( BTN_KEEPALLMINE ) )
476     ,maBtnKeepAllOthers ( this, ScResId( BTN_KEEPALLOTHERS ) )
477     ,maBtnCancel        ( this, ScResId( BTN_CANCEL ) )
478     ,maBtnHelp          ( this, ScResId( BTN_HELP ) )
479     ,maStrTitleConflict ( ScResId( STR_TITLE_CONFLICT ) )
480     ,maStrTitleAuthor   ( ScResId( STR_TITLE_AUTHOR ) )
481     ,maStrTitleDate     ( ScResId( STR_TITLE_DATE ) )
482     ,maStrUnknownUser   ( ScResId( STR_UNKNOWN_USER ) )
483     ,mpViewData         ( pViewData )
484     ,mpOwnDoc           ( NULL )
485     ,mpOwnTrack         ( NULL )
486     ,mpSharedDoc        ( pSharedDoc )
487     ,mpSharedTrack      ( NULL )
488     ,mrConflictsList    ( rConflictsList )
489     ,maDialogSize       ( GetSizePixel() )
490     ,mbInSelectHdl      ( false )
491     ,mbInDeselectHdl    ( false )
492 {
493     DBG_ASSERT( mpViewData, "ScConflictsDlg CTOR: mpViewData is null!" );
494     mpOwnDoc = ( mpViewData ? mpViewData->GetDocument() : NULL );
495     DBG_ASSERT( mpOwnDoc, "ScConflictsDlg CTOR: mpOwnDoc is null!" );
496     mpOwnTrack = ( mpOwnDoc ? mpOwnDoc->GetChangeTrack() : NULL );
497     DBG_ASSERT( mpOwnTrack, "ScConflictsDlg CTOR: mpOwnTrack is null!" );
498     DBG_ASSERT( mpSharedDoc, "ScConflictsDlg CTOR: mpSharedDoc is null!" );
499     mpSharedTrack = ( mpSharedDoc ? mpSharedDoc->GetChangeTrack() : NULL );
500     DBG_ASSERT( mpSharedTrack, "ScConflictsDlg CTOR: mpSharedTrack is null!" );
501 
502     FreeResource();
503 
504     SetMinOutputSizePixel( maDialogSize );
505 
506     long nTabs[] = { 3, 10, 216, 266 };
507     maLbConflicts.SetTabs( nTabs );
508 
509     String aTab( sal_Unicode( '\t' ) );
510     String aHeader( maStrTitleConflict );
511     aHeader += aTab;
512     aHeader += maStrTitleAuthor;
513     aHeader += aTab;
514     aHeader += maStrTitleDate;
515     maLbConflicts.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER );
516 
517     maLbConflicts.SetStyle( maLbConflicts.GetStyle() | WB_HASLINES | WB_CLIPCHILDREN | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL );
518     maLbConflicts.SetSelectionMode( MULTIPLE_SELECTION );
519     maLbConflicts.SetHighlightRange();
520 
521     maSelectionTimer.SetTimeout( 100 );
522     maSelectionTimer.SetTimeoutHdl( LINK( this, ScConflictsDlg, UpdateSelectionHdl ) );
523 
524     maLbConflicts.SetSelectHdl( LINK( this, ScConflictsDlg, SelectHandle ) );
525     maLbConflicts.SetDeselectHdl( LINK( this, ScConflictsDlg, DeselectHandle ) );
526 
527     maBtnKeepMine.SetClickHdl( LINK( this, ScConflictsDlg, KeepMineHandle ) );
528     maBtnKeepOther.SetClickHdl( LINK( this, ScConflictsDlg, KeepOtherHandle ) );
529     maBtnKeepAllMine.SetClickHdl( LINK( this, ScConflictsDlg, KeepAllMineHandle ) );
530     maBtnKeepAllOthers.SetClickHdl( LINK( this, ScConflictsDlg, KeepAllOthersHandle ) );
531 
532     UpdateView();
533 
534     SvLBoxEntry* pEntry = maLbConflicts.First();
535     if ( pEntry != NULL )
536     {
537         maLbConflicts.Select( pEntry );
538     }
539 }
540 
541 ScConflictsDlg::~ScConflictsDlg()
542 {
543 }
544 
545 String ScConflictsDlg::GetConflictString( const ScConflictsListEntry& rConflictEntry )
546 {
547     String aString;
548     if ( mpOwnTrack )
549     {
550         const ScChangeAction* pAction = mpOwnTrack->GetAction( rConflictEntry.maOwnActions[ 0 ] );
551         if ( pAction && mpOwnDoc )
552         {
553             SCTAB nTab = pAction->GetBigRange().MakeRange().aStart.Tab();
554             mpOwnDoc->GetName( nTab, aString );
555         }
556     }
557     return aString;
558 }
559 
560 String ScConflictsDlg::GetActionString( const ScChangeAction* pAction, ScDocument* pDoc )
561 {
562     String aString;
563 
564     DBG_ASSERT( pAction, "ScConflictsDlg::GetActionString(): pAction is null!" );
565     DBG_ASSERT( pDoc, "ScConflictsDlg::GetActionString(): pDoc is null!" );
566     if ( pAction && pDoc )
567     {
568         String aDesc;
569         pAction->GetDescription( aDesc, pDoc, sal_True, false );
570         aString += aDesc;
571         aString += '\t';
572 
573         String aUser = pAction->GetUser();
574         aUser.EraseLeadingAndTrailingChars();
575         if ( aUser.Len() == 0 )
576         {
577             aUser = maStrUnknownUser;
578         }
579         aString += aUser;
580         aString += '\t';
581 
582         DateTime aDateTime = pAction->GetDateTime();
583         aString += ScGlobal::pLocaleData->getDate( aDateTime );
584         aString += ' ';
585         aString += ScGlobal::pLocaleData->getTime( aDateTime, sal_False );
586         aString += '\t';
587     }
588 
589     return aString;
590 }
591 
592 void ScConflictsDlg::HandleListBoxSelection( bool bSelectHandle )
593 {
594     SvLBoxEntry* pSelEntry = maLbConflicts.GetCurEntry();
595     if ( !pSelEntry )
596     {
597         pSelEntry = maLbConflicts.FirstSelected();
598     }
599     if ( !pSelEntry )
600     {
601         return;
602     }
603 
604     SvLBoxEntry* pRootEntry = maLbConflicts.GetRootLevelParent( pSelEntry );
605     if ( pRootEntry )
606     {
607         if ( bSelectHandle )
608         {
609             maLbConflicts.SelectAll( sal_False );
610         }
611         if ( !maLbConflicts.IsSelected( pRootEntry ) )
612         {
613             maLbConflicts.Select( pRootEntry );
614         }
615         SvLBoxEntry* pEntry = maLbConflicts.FirstChild( pRootEntry );
616         while ( pEntry )
617         {
618             if ( !maLbConflicts.IsSelected( pEntry ) )
619             {
620                 maLbConflicts.Select( pEntry );
621             }
622             pEntry = maLbConflicts.NextSibling( pEntry );
623         }
624     }
625 }
626 
627 IMPL_LINK( ScConflictsDlg, SelectHandle, SvxRedlinTable*, EMPTYARG )
628 {
629     if ( mbInSelectHdl || mbInDeselectHdl )
630     {
631         return 0;
632     }
633 
634     mbInSelectHdl = true;
635     HandleListBoxSelection( true );
636     maSelectionTimer.Start();
637     mbInSelectHdl = false;
638 
639     return 0;
640 }
641 
642 IMPL_LINK( ScConflictsDlg, DeselectHandle, SvxRedlinTable*, EMPTYARG )
643 {
644     if ( mbInDeselectHdl || mbInSelectHdl )
645     {
646         return 0;
647     }
648 
649     mbInDeselectHdl = true;
650     HandleListBoxSelection( false );
651     mbInDeselectHdl = false;
652 
653     return 0;
654 }
655 
656 IMPL_LINK( ScConflictsDlg, UpdateSelectionHdl, Timer*, EMPTYARG )
657 {
658     if ( !mpViewData || !mpOwnDoc )
659     {
660         return 0;
661     }
662 
663     ScTabView* pTabView = mpViewData->GetView();
664     pTabView->DoneBlockMode();
665     sal_Bool bContMark = sal_False;
666     SvLBoxEntry* pEntry = maLbConflicts.FirstSelected();
667     while ( pEntry )
668     {
669         if ( pEntry != maLbConflicts.GetRootLevelParent( pEntry ) )
670         {
671             RedlinData* pUserData = static_cast< RedlinData* >( pEntry->GetUserData() );
672             if  ( pUserData )
673             {
674                 ScChangeAction* pAction = static_cast< ScChangeAction* >( pUserData->pData );
675                 if ( pAction && ( pAction->GetType() != SC_CAT_DELETE_TABS ) &&
676                      ( pAction->IsClickable() || pAction->IsVisible() ) )
677                 {
678                     const ScBigRange& rBigRange = ( static_cast< const ScChangeAction* >( pAction ) )->GetBigRange();
679                     if ( rBigRange.IsValid( mpOwnDoc ) )
680                     {
681                         sal_Bool bSetCursor = !maLbConflicts.NextSelected( pEntry );
682                         pTabView->MarkRange( rBigRange.MakeRange(), bSetCursor, bContMark );
683                         bContMark = sal_True;
684                     }
685                 }
686             }
687         }
688         pEntry = maLbConflicts.NextSelected( pEntry );
689     }
690 
691     return 0;
692 }
693 
694 void ScConflictsDlg::SetConflictAction( SvLBoxEntry* pRootEntry, ScConflictAction eConflictAction )
695 {
696     RedlinData* pUserData = static_cast< RedlinData* >( pRootEntry ? pRootEntry->GetUserData() : NULL );
697     ScConflictsListEntry* pConflictEntry = static_cast< ScConflictsListEntry* >( pUserData ? pUserData->pData : NULL );
698     if ( pConflictEntry )
699     {
700         pConflictEntry->meConflictAction = eConflictAction;
701     }
702 }
703 
704 void ScConflictsDlg::KeepHandler( bool bMine )
705 {
706     SvLBoxEntry* pEntry = maLbConflicts.FirstSelected();
707     SvLBoxEntry* pRootEntry = ( pEntry ? maLbConflicts.GetRootLevelParent( pEntry ) : NULL );
708     if ( !pRootEntry )
709     {
710         return;
711     }
712     SetPointer( Pointer( POINTER_WAIT ) );
713     ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
714     SetConflictAction( pRootEntry, eConflictAction );
715     maLbConflicts.RemoveEntry( pRootEntry );
716     SetPointer( Pointer( POINTER_ARROW ) );
717     if ( maLbConflicts.GetEntryCount() == 0 )
718     {
719         EndDialog( RET_OK );
720     }
721 }
722 
723 void ScConflictsDlg::KeepAllHandler( bool bMine )
724 {
725     SvLBoxEntry* pEntry = maLbConflicts.First();
726     SvLBoxEntry* pRootEntry = ( pEntry ? maLbConflicts.GetRootLevelParent( pEntry ) : NULL );
727     if ( !pRootEntry )
728     {
729         return;
730     }
731     SetPointer( Pointer( POINTER_WAIT ) );
732     ScConflictAction eConflictAction = ( bMine ? SC_CONFLICT_ACTION_KEEP_MINE : SC_CONFLICT_ACTION_KEEP_OTHER );
733     while ( pRootEntry )
734     {
735         SetConflictAction( pRootEntry, eConflictAction );
736         pRootEntry = maLbConflicts.NextSibling( pRootEntry );
737     }
738     maLbConflicts.SetUpdateMode( sal_False );
739     maLbConflicts.Clear();
740     maLbConflicts.SetUpdateMode( sal_True );
741     SetPointer( Pointer( POINTER_ARROW ) );
742     EndDialog( RET_OK );
743 }
744 
745 IMPL_LINK( ScConflictsDlg, KeepMineHandle, void*, EMPTYARG )
746 {
747     KeepHandler( true );
748 
749     return 0;
750 }
751 
752 IMPL_LINK( ScConflictsDlg, KeepOtherHandle, void*, EMPTYARG )
753 {
754     KeepHandler( false );
755 
756     return 0;
757 }
758 
759 IMPL_LINK( ScConflictsDlg, KeepAllMineHandle, void*, EMPTYARG )
760 {
761     KeepAllHandler( true );
762 
763     return 0;
764 }
765 
766 IMPL_LINK( ScConflictsDlg, KeepAllOthersHandle, void*, EMPTYARG )
767 {
768     KeepAllHandler( false );
769 
770     return 0;
771 }
772 
773 void lcl_MoveControlX( Window& rWindow, long nDelta )
774 {
775     Point aPos( rWindow.GetPosPixel() );
776     aPos.X() += nDelta;
777     rWindow.SetPosPixel( aPos );
778 }
779 
780 void lcl_MoveControlY( Window& rWindow, long nDelta )
781 {
782     Point aPos( rWindow.GetPosPixel() );
783     aPos.Y() += nDelta;
784     rWindow.SetPosPixel( aPos );
785 }
786 
787 void lcl_ChangeControlWidth( Window& rWindow, long nDelta )
788 {
789     Size aSize( rWindow.GetSizePixel() );
790     aSize.Width() += nDelta;
791     rWindow.SetSizePixel( aSize );
792 }
793 
794 void lcl_ChangeControlHeight( Window& rWindow, long nDelta )
795 {
796     Size aSize( rWindow.GetSizePixel() );
797     aSize.Height() += nDelta;
798     rWindow.SetSizePixel( aSize );
799 }
800 
801 void ScConflictsDlg::Resize()
802 {
803     Size aSize( GetSizePixel() );
804     long nDeltaWidth = aSize.Width() - maDialogSize.Width();
805     long nDeltaHeight = aSize.Height() - maDialogSize.Height();
806     maDialogSize = aSize;
807 
808     lcl_ChangeControlWidth( maFtConflicts, nDeltaWidth );
809 
810     lcl_ChangeControlWidth( maLbConflicts, nDeltaWidth );
811     lcl_ChangeControlHeight( maLbConflicts, nDeltaHeight );
812 
813     lcl_MoveControlX( maBtnKeepMine, nDeltaWidth / 2 );
814     lcl_MoveControlY( maBtnKeepMine, nDeltaHeight );
815 
816     lcl_MoveControlX( maBtnKeepOther, nDeltaWidth / 2 );
817     lcl_MoveControlY( maBtnKeepOther, nDeltaHeight );
818 
819     lcl_MoveControlY( maFlConflicts, nDeltaHeight );
820     lcl_ChangeControlWidth( maFlConflicts, nDeltaWidth );
821 
822     lcl_MoveControlX( maBtnKeepAllMine, nDeltaWidth );
823     lcl_MoveControlY( maBtnKeepAllMine, nDeltaHeight );
824 
825     lcl_MoveControlX( maBtnKeepAllOthers, nDeltaWidth );
826     lcl_MoveControlY( maBtnKeepAllOthers, nDeltaHeight );
827 
828     lcl_MoveControlX( maBtnCancel, nDeltaWidth );
829     lcl_MoveControlY( maBtnCancel, nDeltaHeight );
830 
831     lcl_MoveControlX( maBtnHelp, nDeltaWidth );
832     lcl_MoveControlY( maBtnHelp, nDeltaHeight );
833 }
834 
835 void ScConflictsDlg::UpdateView()
836 {
837     ScConflictsList::iterator aEndItr = mrConflictsList.end();
838     for ( ScConflictsList::iterator aItr = mrConflictsList.begin(); aItr != aEndItr; ++aItr )
839     {
840         ScConflictsListEntry* pConflictEntry = &(*aItr);
841         if ( pConflictEntry && pConflictEntry->meConflictAction == SC_CONFLICT_ACTION_NONE )
842         {
843             RedlinData* pRootUserData = new RedlinData();
844             pRootUserData->pData = static_cast< void* >( pConflictEntry );
845             SvLBoxEntry* pRootEntry = maLbConflicts.InsertEntry( GetConflictString( *aItr ), pRootUserData );
846 
847             ScChangeActionList::const_iterator aEndShared = aItr->maSharedActions.end();
848             for ( ScChangeActionList::const_iterator aItrShared = aItr->maSharedActions.begin(); aItrShared != aEndShared; ++aItrShared )
849             {
850                 ScChangeAction* pAction = mpSharedTrack->GetAction( *aItrShared );
851                 if ( pAction )
852                 {
853                     // only display shared top content entries
854                     if ( pAction->GetType() == SC_CAT_CONTENT )
855                     {
856                         ScChangeActionContent* pNextContent = ( dynamic_cast< ScChangeActionContent* >( pAction ) )->GetNextContent();
857                         if ( pNextContent && aItr->HasSharedAction( pNextContent->GetActionNumber() ) )
858                         {
859                             continue;
860                         }
861                     }
862 
863                     String aString( GetActionString( pAction, mpSharedDoc ) );
864                     maLbConflicts.InsertEntry( aString, static_cast< RedlinData* >( NULL ), pRootEntry );
865                 }
866             }
867 
868             ScChangeActionList::const_iterator aEndOwn = aItr->maOwnActions.end();
869             for ( ScChangeActionList::const_iterator aItrOwn = aItr->maOwnActions.begin(); aItrOwn != aEndOwn; ++aItrOwn )
870             {
871                 ScChangeAction* pAction = mpOwnTrack->GetAction( *aItrOwn );
872                 if ( pAction )
873                 {
874                     // only display own top content entries
875                     if ( pAction->GetType() == SC_CAT_CONTENT )
876                     {
877                         ScChangeActionContent* pNextContent = ( dynamic_cast< ScChangeActionContent* >( pAction ) )->GetNextContent();
878                         if ( pNextContent && aItr->HasOwnAction( pNextContent->GetActionNumber() ) )
879                         {
880                             continue;
881                         }
882                     }
883 
884                     String aString( GetActionString( pAction, mpOwnDoc ) );
885                     RedlinData* pUserData = new RedlinData();
886                     pUserData->pData = static_cast< void* >( pAction );
887                     maLbConflicts.InsertEntry( aString, pUserData, pRootEntry );
888                 }
889             }
890 
891             maLbConflicts.Expand( pRootEntry );
892         }
893     }
894 }
895