xref: /AOO41X/main/sfx2/source/dialog/versdlg.cxx (revision d119d52d53d0b2180f2ae51341d882123be2af2b)
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_sfx2.hxx"
26 #include <unotools/localedatawrapper.hxx>
27 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
28 #include <comphelper/processfactory.hxx>
29 #endif
30 #include <svl/eitem.hxx>
31 #include <svl/intitem.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/itemset.hxx>
34 #include <unotools/useroptions.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <vcl/svapp.hxx>
37 #include <tools/datetime.hxx>
38 
39 #define _SVSTDARR_STRINGSDTOR
40 #include <svl/svstdarr.hxx>
41 
42 #include "versdlg.hrc"
43 #include "versdlg.hxx"
44 #include <sfx2/viewfrm.hxx>
45 #include "sfx2/sfxresid.hxx"
46 #include <sfx2/docfile.hxx>
47 #include <sfx2/objsh.hxx>
48 #include <sfx2/sfxsids.hrc>
49 #include <sfx2/dispatch.hxx>
50 #include <sfx2/request.hxx>
51 
52 #include <sfx2/sfxuno.hxx>
53 
54 using namespace com::sun::star;
55 
56 // **************************************************************************
57 struct SfxVersionInfo
58 {
59     String                  aName;
60     String                  aComment;
61     String                  aAuthor;
62     DateTime                aCreationDate;
63 
64                             SfxVersionInfo();
SfxVersionInfoSfxVersionInfo65                             SfxVersionInfo( const SfxVersionInfo& rInfo )
66                             { *this = rInfo; }
67 
operator =SfxVersionInfo68     SfxVersionInfo&         operator=( const SfxVersionInfo &rInfo )
69                             {
70                                 aName = rInfo.aName;
71                                 aComment = rInfo.aComment;
72                                 aAuthor = rInfo.aAuthor;
73                                 aCreationDate = rInfo.aCreationDate;
74                                 return *this;
75                             }
76 };
77 DECLARE_LIST( _SfxVersionTable, SfxVersionInfo* )
78 class SfxVersionTableDtor : public _SfxVersionTable
79 {
80 public:
SfxVersionTableDtor(const sal_uInt16 nInitSz=0,const sal_uInt16 nReSz=1)81                             SfxVersionTableDtor( const sal_uInt16 nInitSz=0, const sal_uInt16 nReSz=1 )
82                                 : _SfxVersionTable( nInitSz, nReSz )
83                             {}
84 
SfxVersionTableDtor(const SfxVersionTableDtor & rCpy)85                             SfxVersionTableDtor( const SfxVersionTableDtor &rCpy ) :
86                                 _SfxVersionTable( rCpy )
87                             { *this = rCpy; }
88 
89                             SfxVersionTableDtor( const uno::Sequence < util::RevisionTag >& rInfo );
90 
~SfxVersionTableDtor()91                             ~SfxVersionTableDtor()
92                             { DelDtor(); }
93 
94     SfxVersionTableDtor&    operator=( const SfxVersionTableDtor &rCpy );
95     void                    DelDtor();
96     SvStream&               Read( SvStream & );
97     SvStream&               Write( SvStream & ) const;
98     SvStringsDtor*          GetVersions() const;
99 };
100 
SfxVersionTableDtor(const uno::Sequence<util::RevisionTag> & rInfo)101 SfxVersionTableDtor::SfxVersionTableDtor( const uno::Sequence < util::RevisionTag >& rInfo )
102 {
103     for ( sal_Int32 n=0; n<(sal_Int32)rInfo.getLength(); n++ )
104     {
105         SfxVersionInfo* pInfo = new SfxVersionInfo;
106         pInfo->aName = rInfo[n].Identifier;
107         pInfo->aComment = rInfo[n].Comment;
108         pInfo->aAuthor = rInfo[n].Author;
109 
110         Date aDate ( rInfo[n].TimeStamp.Day, rInfo[n].TimeStamp.Month, rInfo[n].TimeStamp.Year );
111         Time aTime ( rInfo[n].TimeStamp.Hours, rInfo[n].TimeStamp.Minutes, rInfo[n].TimeStamp.Seconds, rInfo[n].TimeStamp.HundredthSeconds );
112 
113         pInfo->aCreationDate = DateTime( aDate, aTime );
114         Insert( pInfo, Count() );
115     }
116 }
117 
DelDtor()118 void SfxVersionTableDtor::DelDtor()
119 {
120     SfxVersionInfo* pTmp = First();
121     while( pTmp )
122     {
123         delete pTmp;
124         pTmp = Next();
125     }
126     Clear();
127 }
128 
operator =(const SfxVersionTableDtor & rTbl)129 SfxVersionTableDtor& SfxVersionTableDtor::operator=( const SfxVersionTableDtor& rTbl )
130 {
131     DelDtor();
132     SfxVersionInfo* pTmp = ((SfxVersionTableDtor&)rTbl).First();
133     while( pTmp )
134     {
135         SfxVersionInfo *pNew = new SfxVersionInfo( *pTmp );
136         Insert( pNew, LIST_APPEND );
137         pTmp = ((SfxVersionTableDtor&)rTbl).Next();
138     }
139     return *this;
140 }
141 
142 //----------------------------------------------------------------
143 //----------------------------------------------------------------
144 //----------------------------------------------------------------
SfxVersionInfo()145 SfxVersionInfo::SfxVersionInfo()
146 {
147 }
148 
ConvertDateTime_Impl(const DateTime & rTime,const LocaleDataWrapper & rWrapper)149 static String ConvertDateTime_Impl(const DateTime& rTime, const LocaleDataWrapper& rWrapper)
150 {
151      const String pDelim ( DEFINE_CONST_UNICODE( ", "));
152      String aStr(rWrapper.getDate(rTime));
153      aStr += pDelim;
154      aStr += rWrapper.getTime(rTime, sal_True, sal_False);
155      return aStr;
156 }
157 
GetVersions() const158 SvStringsDtor* SfxVersionTableDtor::GetVersions() const
159 {
160     SvStringsDtor *pList = new SvStringsDtor;
161     SfxVersionInfo* pInfo = ((SfxVersionTableDtor*) this)->First();
162     LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
163     while ( pInfo )
164     {
165         String *pString = new String( pInfo->aComment );
166         (*pString) += DEFINE_CONST_UNICODE( "; " );
167         (*pString) += ConvertDateTime_Impl( pInfo->aCreationDate, aLocaleWrapper );
168         pList->Insert( pString, pList->Count() );
169         pInfo = ((SfxVersionTableDtor*) this)->Next();
170     }
171 
172     return pList;
173 }
174 
175 // Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert
176 static long nTabs_Impl[] =
177 {
178     3, // Number of Tabs
179     0, 62, 124
180 };
181 
KeyInput(const KeyEvent & rKeyEvent)182 void SfxVersionsTabListBox_Impl::KeyInput( const KeyEvent& rKeyEvent )
183 {
184     const KeyCode& rCode = rKeyEvent.GetKeyCode();
185     switch ( rCode.GetCode() )
186     {
187         case KEY_RETURN :
188         case KEY_ESCAPE :
189         case KEY_TAB :
190             Window::GetParent()->KeyInput( rKeyEvent );
191             break;
192         default:
193             SvTabListBox::KeyInput( rKeyEvent );
194             break;
195     }
196 }
197 
SfxVersionsTabListBox_Impl(Window * pParent,const ResId & rResId)198 SfxVersionsTabListBox_Impl::SfxVersionsTabListBox_Impl( Window* pParent, const ResId& rResId )
199     : SvTabListBox( pParent, rResId )
200 {
201 }
202 
SfxVersionDialog(SfxViewFrame * pVwFrame,sal_Bool bIsSaveVersionOnClose)203 SfxVersionDialog::SfxVersionDialog ( SfxViewFrame* pVwFrame, sal_Bool bIsSaveVersionOnClose )
204     : SfxModalDialog( NULL, SfxResId( DLG_VERSIONS ) )
205     , aNewGroup( this, SfxResId( GB_NEWVERSIONS ) )
206     , aSaveButton( this, SfxResId( PB_SAVE ) )
207     , aSaveCheckBox( this, SfxResId( CB_SAVEONCLOSE ) )
208     , aExistingGroup( this, SfxResId( GB_OLDVERSIONS ) )
209     , aDateTimeText( this, SfxResId( FT_DATETIME ) )
210     , aSavedByText( this, SfxResId( FT_SAVEDBY ) )
211     , aCommentText( this, SfxResId( FT_COMMENTS ) )
212     , aVersionBox( this, SfxResId( TLB_VERSIONS ) )
213     , aCloseButton( this, SfxResId( PB_CLOSE ) )
214     , aOpenButton( this, SfxResId( PB_OPEN ) )
215     , aViewButton( this, SfxResId( PB_VIEW ) )
216     , aDeleteButton( this, SfxResId( PB_DELETE ) )
217     , aCompareButton( this, SfxResId( PB_COMPARE ) )
218     , aHelpButton( this, SfxResId( PB_HELP ) )
219     , pViewFrame( pVwFrame )
220     , mpTable( NULL )
221     , mpLocaleWrapper( NULL )
222     , mbIsSaveVersionOnClose( bIsSaveVersionOnClose )
223 {
224     FreeResource();
225 
226     Link aClickLink = LINK( this, SfxVersionDialog, ButtonHdl_Impl );
227     aViewButton.SetClickHdl ( aClickLink );
228     aSaveButton.SetClickHdl ( aClickLink );
229     aDeleteButton.SetClickHdl ( aClickLink );
230     aCompareButton.SetClickHdl ( aClickLink );
231     aOpenButton.SetClickHdl ( aClickLink );
232     aSaveCheckBox.SetClickHdl ( aClickLink );
233 
234     aVersionBox.SetSelectHdl( LINK( this, SfxVersionDialog, SelectHdl_Impl ) );
235     aVersionBox.SetDoubleClickHdl( LINK( this, SfxVersionDialog, DClickHdl_Impl ) );
236 
237     aVersionBox.GrabFocus();
238     aVersionBox.SetStyle( aVersionBox.GetStyle() | WB_HSCROLL | WB_CLIPCHILDREN );
239     aVersionBox.SetSelectionMode( SINGLE_SELECTION );
240     aVersionBox.SetTabs( &nTabs_Impl[0], MAP_APPFONT );
241     aVersionBox.Resize();   // OS: Hack fuer richtige Selektion
242     RecalcDateColumn();
243 
244     // set dialog title (filename or docinfo title)
245     String sText = GetText();
246     ( sText += ' ' ) += pViewFrame->GetObjectShell()->GetTitle();
247     SetText( sText );
248 
249     Init_Impl();
250 }
251 
ConvertWhiteSpaces_Impl(const String & rText)252 String ConvertWhiteSpaces_Impl( const String& rText )
253 {
254     // converted linebreaks and tabs to blanks; it's necessary for the display
255     String sConverted;
256     const sal_Unicode* pChars = rText.GetBuffer();
257     while ( *pChars )
258     {
259         switch ( *pChars )
260         {
261             case '\n' :
262             case '\t' :
263                 sConverted += ' ';
264                 break;
265 
266             default:
267                 sConverted += *pChars;
268         }
269 
270         ++pChars;
271     }
272 
273     return sConverted;
274 }
275 
Init_Impl()276 void SfxVersionDialog::Init_Impl()
277 {
278     SfxObjectShell *pObjShell = pViewFrame->GetObjectShell();
279     SfxMedium* pMedium = pObjShell->GetMedium();
280     uno::Sequence < util::RevisionTag > aVersions = pMedium->GetVersionList( true );
281     delete mpTable;
282     mpTable = new SfxVersionTableDtor( aVersions );
283     {
284         for ( sal_uInt16 n = 0; n < mpTable->Count(); ++n )
285         {
286             SfxVersionInfo *pInfo = mpTable->GetObject(n);
287             String aEntry = ConvertDateTime_Impl( pInfo->aCreationDate, *mpLocaleWrapper );
288             aEntry += '\t';
289             aEntry += pInfo->aAuthor;
290             aEntry += '\t';
291             aEntry += ConvertWhiteSpaces_Impl( pInfo->aComment );
292             SvLBoxEntry *pEntry = aVersionBox.InsertEntry( aEntry );
293             pEntry->SetUserData( pInfo );
294         }
295     }
296 
297     aSaveCheckBox.Check( mbIsSaveVersionOnClose );
298 
299     sal_Bool bEnable = !pObjShell->IsReadOnly();
300     aSaveButton.Enable( bEnable );
301     aSaveCheckBox.Enable( bEnable );
302 
303     aOpenButton.Disable();
304     aViewButton.Disable();
305     aDeleteButton.Disable();
306     aCompareButton.Disable();
307 
308     SelectHdl_Impl( &aVersionBox );
309 }
310 
~SfxVersionDialog()311 SfxVersionDialog::~SfxVersionDialog ()
312 {
313     delete mpTable;
314     delete mpLocaleWrapper;
315 }
316 
Open_Impl()317 void SfxVersionDialog::Open_Impl()
318 {
319     SfxObjectShell *pObjShell = pViewFrame->GetObjectShell();
320 
321     SvLBoxEntry *pEntry = aVersionBox.FirstSelected();
322     sal_uIntPtr nPos = aVersionBox.GetModel()->GetRelPos( pEntry );
323     SfxInt16Item aItem( SID_VERSION, (short)nPos+1 );
324     SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_blank") );
325     SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") );
326     SfxStringItem aFile( SID_FILE_NAME, pObjShell->GetMedium()->GetName() );
327 
328     uno::Sequence< beans::NamedValue > aEncryptionData;
329     if ( GetEncryptionData_Impl( pObjShell->GetMedium()->GetItemSet(), aEncryptionData ) )
330     {
331         // there is a password, it should be used during the opening
332         SfxUnoAnyItem aEncryptionDataItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) );
333         pViewFrame->GetDispatcher()->Execute(
334             SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aFile, &aItem, &aTarget, &aReferer, &aEncryptionDataItem, 0L );
335     }
336     else
337         pViewFrame->GetDispatcher()->Execute(
338             SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aFile, &aItem, &aTarget, &aReferer, 0L );
339 
340     Close();
341 }
342 
RecalcDateColumn()343 void SfxVersionDialog::RecalcDateColumn()
344 {
345     // recalculate the datetime column width
346     DateTime aNow;
347     mpLocaleWrapper = new LocaleDataWrapper(
348         ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
349     String sDateTime = ConvertDateTime_Impl( aNow, *mpLocaleWrapper );
350     long nWidth = aVersionBox.GetTextWidth( sDateTime );
351     nWidth += 15; // a little offset
352     long nTab = aVersionBox.GetTab(1);
353     if ( nWidth > nTab )
354     {
355         // resize columns
356         long nDelta = nWidth - nTab;
357         aVersionBox.SetTab( 1, nTab + nDelta, MAP_PIXEL );
358         nTab = aVersionBox.GetTab(2);
359         aVersionBox.SetTab( 2, nTab + nDelta, MAP_PIXEL );
360 
361         // resize and move header
362         Size aSize = aDateTimeText.GetSizePixel();
363         aSize.Width() += nDelta;
364         aDateTimeText.SetSizePixel( aSize );
365         Point aPos = aSavedByText.GetPosPixel();
366         aPos.X() += nDelta;
367         aSavedByText.SetPosPixel( aPos );
368         aPos = aCommentText.GetPosPixel();
369         aPos.X() += nDelta;
370         aCommentText.SetPosPixel( aPos );
371     }
372 }
373 
IMPL_LINK(SfxVersionDialog,DClickHdl_Impl,Control *,EMPTYARG)374 IMPL_LINK( SfxVersionDialog, DClickHdl_Impl, Control*, EMPTYARG )
375 {
376     Open_Impl();
377     return 0L;
378 }
379 
IMPL_LINK(SfxVersionDialog,SelectHdl_Impl,Control *,EMPTYARG)380 IMPL_LINK( SfxVersionDialog, SelectHdl_Impl, Control*, EMPTYARG )
381 {
382     bool bEnable = ( aVersionBox.FirstSelected() != NULL );
383     SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
384     aDeleteButton.Enable( bEnable!= false && !pObjShell->IsReadOnly() );
385     aOpenButton.Enable( bEnable!= false );
386     aViewButton.Enable( bEnable!= false );
387 
388     const SfxPoolItem *pDummy=NULL;
389     SfxItemState eState = pViewFrame->GetDispatcher()->QueryState( SID_DOCUMENT_MERGE, pDummy );
390     eState = pViewFrame->GetDispatcher()->QueryState( SID_DOCUMENT_COMPARE, pDummy );
391     aCompareButton.Enable( bEnable!= false && eState >= SFX_ITEM_AVAILABLE );
392 
393     return 0L;
394 }
395 
IMPL_LINK(SfxVersionDialog,ButtonHdl_Impl,Button *,pButton)396 IMPL_LINK( SfxVersionDialog, ButtonHdl_Impl, Button*, pButton )
397 {
398     SfxObjectShell *pObjShell = pViewFrame->GetObjectShell();
399     SvLBoxEntry *pEntry = aVersionBox.FirstSelected();
400 
401     if ( pButton == &aSaveCheckBox )
402     {
403         mbIsSaveVersionOnClose = aSaveCheckBox.IsChecked();
404     }
405     else if ( pButton == &aSaveButton )
406     {
407         SfxVersionInfo aInfo;
408         aInfo.aAuthor = SvtUserOptions().GetFullName();
409         SfxViewVersionDialog_Impl* pDlg = new SfxViewVersionDialog_Impl( this, aInfo, sal_True );
410         short nRet = pDlg->Execute();
411         if ( nRet == RET_OK )
412         {
413             SfxStringItem aComment( SID_DOCINFO_COMMENTS, aInfo.aComment );
414             pObjShell->SetModified( sal_True );
415             const SfxPoolItem* aItems[2];
416             aItems[0] = &aComment;
417             aItems[1] = NULL;
418             pViewFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, aItems, 0 );
419             aVersionBox.SetUpdateMode( sal_False );
420             aVersionBox.Clear();
421             Init_Impl();
422             aVersionBox.SetUpdateMode( sal_True );
423         }
424 
425         delete pDlg;
426     }
427     if ( pButton == &aDeleteButton && pEntry )
428     {
429         pObjShell->GetMedium()->RemoveVersion_Impl( ((SfxVersionInfo*) pEntry->GetUserData())->aName );
430         pObjShell->SetModified( sal_True );
431         aVersionBox.SetUpdateMode( sal_False );
432         aVersionBox.Clear();
433         Init_Impl();
434         aVersionBox.SetUpdateMode( sal_True );
435     }
436     else if ( pButton == &aOpenButton && pEntry )
437     {
438         Open_Impl();
439     }
440     else if ( pButton == &aViewButton && pEntry )
441     {
442         SfxVersionInfo* pInfo = (SfxVersionInfo*) pEntry->GetUserData();
443         SfxViewVersionDialog_Impl* pDlg = new SfxViewVersionDialog_Impl( this, *pInfo, sal_False );
444         pDlg->Execute();
445         delete pDlg;
446     }
447     else if ( pEntry && pButton == &aCompareButton )
448     {
449         SfxAllItemSet aSet( pObjShell->GetPool() );
450         sal_uIntPtr nPos = aVersionBox.GetModel()->GetRelPos( pEntry );
451         aSet.Put( SfxInt16Item( SID_VERSION, (short)nPos+1 ) );
452         aSet.Put( SfxStringItem( SID_FILE_NAME, pObjShell->GetMedium()->GetName() ) );
453 
454         SfxItemSet* pSet = pObjShell->GetMedium()->GetItemSet();
455         SFX_ITEMSET_ARG( pSet, pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False );
456         SFX_ITEMSET_ARG( pSet, pFilterOptItem, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False );
457         if ( pFilterItem )
458             aSet.Put( *pFilterItem );
459         if ( pFilterOptItem )
460             aSet.Put( *pFilterOptItem );
461 
462         pViewFrame->GetDispatcher()->Execute( SID_DOCUMENT_COMPARE, SFX_CALLMODE_ASYNCHRON, aSet );
463         Close();
464     }
465 
466     return 0L;
467 }
468 
SfxViewVersionDialog_Impl(Window * pParent,SfxVersionInfo & rInfo,sal_Bool bEdit)469 SfxViewVersionDialog_Impl::SfxViewVersionDialog_Impl ( Window *pParent, SfxVersionInfo& rInfo, sal_Bool bEdit )
470     : SfxModalDialog( pParent, SfxResId( DLG_COMMENTS ) )
471     , aDateTimeText( this, SfxResId( FT_DATETIME ) )
472     , aSavedByText( this, SfxResId( FT_SAVEDBY ) )
473     , aEdit( this, SfxResId( ME_VERSIONS ) )
474     , aOKButton( this, SfxResId( PB_OK ) )
475     , aCancelButton( this, SfxResId( PB_CANCEL ) )
476     , aCloseButton( this, SfxResId( PB_CLOSE ) )
477     , aHelpButton( this, SfxResId( PB_HELP ) )
478     , pInfo( &rInfo )
479 {
480     FreeResource();
481 
482     LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
483     aDateTimeText.SetText( aDateTimeText.GetText().Append(ConvertDateTime_Impl( pInfo->aCreationDate, aLocaleWrapper )) );
484     aSavedByText.SetText( aSavedByText.GetText().Append(pInfo->aAuthor) );
485     aEdit.SetText( rInfo.aComment );
486 
487     aCloseButton.SetClickHdl ( LINK( this, SfxViewVersionDialog_Impl, ButtonHdl ) );
488     aOKButton.SetClickHdl ( LINK( this, SfxViewVersionDialog_Impl, ButtonHdl ) );
489 
490     aEdit.GrabFocus();
491     if ( !bEdit )
492     {
493         aOKButton.Hide();
494         aCancelButton.Hide();
495         aEdit.SetReadOnly( sal_True );
496     }
497     else
498         aCloseButton.Hide();
499 }
500 
IMPL_LINK(SfxViewVersionDialog_Impl,ButtonHdl,Button *,pButton)501 IMPL_LINK( SfxViewVersionDialog_Impl, ButtonHdl, Button*, pButton )
502 {
503     if ( pButton == &aCloseButton )
504     {
505         EndDialog( RET_CANCEL );
506     }
507     else if ( pButton == &aOKButton )
508     {
509         pInfo->aComment = aEdit.GetText();
510         EndDialog( RET_OK );
511     }
512 
513     return 0L;
514 }
515 
516