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