/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include #ifndef _UNOTOOLS_PROCESSFACTORY_HXX #include #endif #include #include #include #include #include #include #include #include #define _SVSTDARR_STRINGSDTOR #include #include "versdlg.hrc" #include "versdlg.hxx" #include #include "sfx2/sfxresid.hxx" #include #include #include #include #include #include using namespace com::sun::star; // ************************************************************************** struct SfxVersionInfo { String aName; String aComment; String aAuthor; DateTime aCreationDate; SfxVersionInfo(); SfxVersionInfo( const SfxVersionInfo& rInfo ) { *this = rInfo; } SfxVersionInfo& operator=( const SfxVersionInfo &rInfo ) { aName = rInfo.aName; aComment = rInfo.aComment; aAuthor = rInfo.aAuthor; aCreationDate = rInfo.aCreationDate; return *this; } }; DECLARE_LIST( _SfxVersionTable, SfxVersionInfo* ) class SfxVersionTableDtor : public _SfxVersionTable { public: SfxVersionTableDtor( const sal_uInt16 nInitSz=0, const sal_uInt16 nReSz=1 ) : _SfxVersionTable( nInitSz, nReSz ) {} SfxVersionTableDtor( const SfxVersionTableDtor &rCpy ) : _SfxVersionTable( rCpy ) { *this = rCpy; } SfxVersionTableDtor( const uno::Sequence < util::RevisionTag >& rInfo ); ~SfxVersionTableDtor() { DelDtor(); } SfxVersionTableDtor& operator=( const SfxVersionTableDtor &rCpy ); void DelDtor(); SvStream& Read( SvStream & ); SvStream& Write( SvStream & ) const; SvStringsDtor* GetVersions() const; }; SfxVersionTableDtor::SfxVersionTableDtor( const uno::Sequence < util::RevisionTag >& rInfo ) { for ( sal_Int32 n=0; n<(sal_Int32)rInfo.getLength(); n++ ) { SfxVersionInfo* pInfo = new SfxVersionInfo; pInfo->aName = rInfo[n].Identifier; pInfo->aComment = rInfo[n].Comment; pInfo->aAuthor = rInfo[n].Author; Date aDate ( rInfo[n].TimeStamp.Day, rInfo[n].TimeStamp.Month, rInfo[n].TimeStamp.Year ); Time aTime ( rInfo[n].TimeStamp.Hours, rInfo[n].TimeStamp.Minutes, rInfo[n].TimeStamp.Seconds, rInfo[n].TimeStamp.HundredthSeconds ); pInfo->aCreationDate = DateTime( aDate, aTime ); Insert( pInfo, Count() ); } } void SfxVersionTableDtor::DelDtor() { SfxVersionInfo* pTmp = First(); while( pTmp ) { delete pTmp; pTmp = Next(); } Clear(); } SfxVersionTableDtor& SfxVersionTableDtor::operator=( const SfxVersionTableDtor& rTbl ) { DelDtor(); SfxVersionInfo* pTmp = ((SfxVersionTableDtor&)rTbl).First(); while( pTmp ) { SfxVersionInfo *pNew = new SfxVersionInfo( *pTmp ); Insert( pNew, LIST_APPEND ); pTmp = ((SfxVersionTableDtor&)rTbl).Next(); } return *this; } //---------------------------------------------------------------- //---------------------------------------------------------------- //---------------------------------------------------------------- SfxVersionInfo::SfxVersionInfo() { } static String ConvertDateTime_Impl(const DateTime& rTime, const LocaleDataWrapper& rWrapper) { const String pDelim ( DEFINE_CONST_UNICODE( ", ")); String aStr(rWrapper.getDate(rTime)); aStr += pDelim; aStr += rWrapper.getTime(rTime, sal_True, sal_False); return aStr; } SvStringsDtor* SfxVersionTableDtor::GetVersions() const { SvStringsDtor *pList = new SvStringsDtor; SfxVersionInfo* pInfo = ((SfxVersionTableDtor*) this)->First(); LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); while ( pInfo ) { String *pString = new String( pInfo->aComment ); (*pString) += DEFINE_CONST_UNICODE( "; " ); (*pString) += ConvertDateTime_Impl( pInfo->aCreationDate, aLocaleWrapper ); pList->Insert( pString, pList->Count() ); pInfo = ((SfxVersionTableDtor*) this)->Next(); } return pList; } // Achtung im Code wird dieses Array direkt (0, 1, ...) indiziert static long nTabs_Impl[] = { 3, // Number of Tabs 0, 62, 124 }; void SfxVersionsTabListBox_Impl::KeyInput( const KeyEvent& rKeyEvent ) { const KeyCode& rCode = rKeyEvent.GetKeyCode(); switch ( rCode.GetCode() ) { case KEY_RETURN : case KEY_ESCAPE : case KEY_TAB : Window::GetParent()->KeyInput( rKeyEvent ); break; default: SvTabListBox::KeyInput( rKeyEvent ); break; } } SfxVersionsTabListBox_Impl::SfxVersionsTabListBox_Impl( Window* pParent, const ResId& rResId ) : SvTabListBox( pParent, rResId ) { } SfxVersionDialog::SfxVersionDialog ( SfxViewFrame* pVwFrame, sal_Bool bIsSaveVersionOnClose ) : SfxModalDialog( NULL, SfxResId( DLG_VERSIONS ) ) , aNewGroup( this, SfxResId( GB_NEWVERSIONS ) ) , aSaveButton( this, SfxResId( PB_SAVE ) ) , aSaveCheckBox( this, SfxResId( CB_SAVEONCLOSE ) ) , aExistingGroup( this, SfxResId( GB_OLDVERSIONS ) ) , aDateTimeText( this, SfxResId( FT_DATETIME ) ) , aSavedByText( this, SfxResId( FT_SAVEDBY ) ) , aCommentText( this, SfxResId( FT_COMMENTS ) ) , aVersionBox( this, SfxResId( TLB_VERSIONS ) ) , aCloseButton( this, SfxResId( PB_CLOSE ) ) , aOpenButton( this, SfxResId( PB_OPEN ) ) , aViewButton( this, SfxResId( PB_VIEW ) ) , aDeleteButton( this, SfxResId( PB_DELETE ) ) , aCompareButton( this, SfxResId( PB_COMPARE ) ) , aHelpButton( this, SfxResId( PB_HELP ) ) , pViewFrame( pVwFrame ) , mpTable( NULL ) , mpLocaleWrapper( NULL ) , mbIsSaveVersionOnClose( bIsSaveVersionOnClose ) { FreeResource(); Link aClickLink = LINK( this, SfxVersionDialog, ButtonHdl_Impl ); aViewButton.SetClickHdl ( aClickLink ); aSaveButton.SetClickHdl ( aClickLink ); aDeleteButton.SetClickHdl ( aClickLink ); aCompareButton.SetClickHdl ( aClickLink ); aOpenButton.SetClickHdl ( aClickLink ); aSaveCheckBox.SetClickHdl ( aClickLink ); aVersionBox.SetSelectHdl( LINK( this, SfxVersionDialog, SelectHdl_Impl ) ); aVersionBox.SetDoubleClickHdl( LINK( this, SfxVersionDialog, DClickHdl_Impl ) ); aVersionBox.GrabFocus(); aVersionBox.SetStyle( aVersionBox.GetStyle() | WB_HSCROLL | WB_CLIPCHILDREN ); aVersionBox.SetSelectionMode( SINGLE_SELECTION ); aVersionBox.SetTabs( &nTabs_Impl[0], MAP_APPFONT ); aVersionBox.Resize(); // OS: Hack fuer richtige Selektion RecalcDateColumn(); // set dialog title (filename or docinfo title) String sText = GetText(); ( sText += ' ' ) += pViewFrame->GetObjectShell()->GetTitle(); SetText( sText ); Init_Impl(); } String ConvertWhiteSpaces_Impl( const String& rText ) { // converted linebreaks and tabs to blanks; it's necessary for the display String sConverted; const sal_Unicode* pChars = rText.GetBuffer(); while ( *pChars ) { switch ( *pChars ) { case '\n' : case '\t' : sConverted += ' '; break; default: sConverted += *pChars; } ++pChars; } return sConverted; } void SfxVersionDialog::Init_Impl() { SfxObjectShell *pObjShell = pViewFrame->GetObjectShell(); SfxMedium* pMedium = pObjShell->GetMedium(); uno::Sequence < util::RevisionTag > aVersions = pMedium->GetVersionList( true ); delete mpTable; mpTable = new SfxVersionTableDtor( aVersions ); { for ( sal_uInt16 n = 0; n < mpTable->Count(); ++n ) { SfxVersionInfo *pInfo = mpTable->GetObject(n); String aEntry = ConvertDateTime_Impl( pInfo->aCreationDate, *mpLocaleWrapper ); aEntry += '\t'; aEntry += pInfo->aAuthor; aEntry += '\t'; aEntry += ConvertWhiteSpaces_Impl( pInfo->aComment ); SvLBoxEntry *pEntry = aVersionBox.InsertEntry( aEntry ); pEntry->SetUserData( pInfo ); } } aSaveCheckBox.Check( mbIsSaveVersionOnClose ); sal_Bool bEnable = !pObjShell->IsReadOnly(); aSaveButton.Enable( bEnable ); aSaveCheckBox.Enable( bEnable ); aOpenButton.Disable(); aViewButton.Disable(); aDeleteButton.Disable(); aCompareButton.Disable(); SelectHdl_Impl( &aVersionBox ); } SfxVersionDialog::~SfxVersionDialog () { delete mpTable; delete mpLocaleWrapper; } void SfxVersionDialog::Open_Impl() { SfxObjectShell *pObjShell = pViewFrame->GetObjectShell(); SvLBoxEntry *pEntry = aVersionBox.FirstSelected(); sal_uIntPtr nPos = aVersionBox.GetModel()->GetRelPos( pEntry ); SfxInt16Item aItem( SID_VERSION, (short)nPos+1 ); SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_blank") ); SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") ); SfxStringItem aFile( SID_FILE_NAME, pObjShell->GetMedium()->GetName() ); uno::Sequence< beans::NamedValue > aEncryptionData; if ( GetEncryptionData_Impl( pObjShell->GetMedium()->GetItemSet(), aEncryptionData ) ) { // there is a password, it should be used during the opening SfxUnoAnyItem aEncryptionDataItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ); pViewFrame->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aFile, &aItem, &aTarget, &aReferer, &aEncryptionDataItem, 0L ); } else pViewFrame->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_ASYNCHRON, &aFile, &aItem, &aTarget, &aReferer, 0L ); Close(); } void SfxVersionDialog::RecalcDateColumn() { // recalculate the datetime column width DateTime aNow; mpLocaleWrapper = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); String sDateTime = ConvertDateTime_Impl( aNow, *mpLocaleWrapper ); long nWidth = aVersionBox.GetTextWidth( sDateTime ); nWidth += 15; // a little offset long nTab = aVersionBox.GetTab(1); if ( nWidth > nTab ) { // resize columns long nDelta = nWidth - nTab; aVersionBox.SetTab( 1, nTab + nDelta, MAP_PIXEL ); nTab = aVersionBox.GetTab(2); aVersionBox.SetTab( 2, nTab + nDelta, MAP_PIXEL ); // resize and move header Size aSize = aDateTimeText.GetSizePixel(); aSize.Width() += nDelta; aDateTimeText.SetSizePixel( aSize ); Point aPos = aSavedByText.GetPosPixel(); aPos.X() += nDelta; aSavedByText.SetPosPixel( aPos ); aPos = aCommentText.GetPosPixel(); aPos.X() += nDelta; aCommentText.SetPosPixel( aPos ); } } IMPL_LINK( SfxVersionDialog, DClickHdl_Impl, Control*, EMPTYARG ) { Open_Impl(); return 0L; } IMPL_LINK( SfxVersionDialog, SelectHdl_Impl, Control*, EMPTYARG ) { bool bEnable = ( aVersionBox.FirstSelected() != NULL ); SfxObjectShell* pObjShell = pViewFrame->GetObjectShell(); aDeleteButton.Enable( bEnable!= false && !pObjShell->IsReadOnly() ); aOpenButton.Enable( bEnable!= false ); aViewButton.Enable( bEnable!= false ); const SfxPoolItem *pDummy=NULL; SfxItemState eState = pViewFrame->GetDispatcher()->QueryState( SID_DOCUMENT_MERGE, pDummy ); eState = pViewFrame->GetDispatcher()->QueryState( SID_DOCUMENT_COMPARE, pDummy ); aCompareButton.Enable( bEnable!= false && eState >= SFX_ITEM_AVAILABLE ); return 0L; } IMPL_LINK( SfxVersionDialog, ButtonHdl_Impl, Button*, pButton ) { SfxObjectShell *pObjShell = pViewFrame->GetObjectShell(); SvLBoxEntry *pEntry = aVersionBox.FirstSelected(); if ( pButton == &aSaveCheckBox ) { mbIsSaveVersionOnClose = aSaveCheckBox.IsChecked(); } else if ( pButton == &aSaveButton ) { SfxVersionInfo aInfo; aInfo.aAuthor = SvtUserOptions().GetFullName(); SfxViewVersionDialog_Impl* pDlg = new SfxViewVersionDialog_Impl( this, aInfo, sal_True ); short nRet = pDlg->Execute(); if ( nRet == RET_OK ) { SfxStringItem aComment( SID_DOCINFO_COMMENTS, aInfo.aComment ); pObjShell->SetModified( sal_True ); const SfxPoolItem* aItems[2]; aItems[0] = &aComment; aItems[1] = NULL; pViewFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, aItems, 0 ); aVersionBox.SetUpdateMode( sal_False ); aVersionBox.Clear(); Init_Impl(); aVersionBox.SetUpdateMode( sal_True ); } delete pDlg; } if ( pButton == &aDeleteButton && pEntry ) { pObjShell->GetMedium()->RemoveVersion_Impl( ((SfxVersionInfo*) pEntry->GetUserData())->aName ); pObjShell->SetModified( sal_True ); aVersionBox.SetUpdateMode( sal_False ); aVersionBox.Clear(); Init_Impl(); aVersionBox.SetUpdateMode( sal_True ); } else if ( pButton == &aOpenButton && pEntry ) { Open_Impl(); } else if ( pButton == &aViewButton && pEntry ) { SfxVersionInfo* pInfo = (SfxVersionInfo*) pEntry->GetUserData(); SfxViewVersionDialog_Impl* pDlg = new SfxViewVersionDialog_Impl( this, *pInfo, sal_False ); pDlg->Execute(); delete pDlg; } else if ( pEntry && pButton == &aCompareButton ) { SfxAllItemSet aSet( pObjShell->GetPool() ); sal_uIntPtr nPos = aVersionBox.GetModel()->GetRelPos( pEntry ); aSet.Put( SfxInt16Item( SID_VERSION, (short)nPos+1 ) ); aSet.Put( SfxStringItem( SID_FILE_NAME, pObjShell->GetMedium()->GetName() ) ); SfxItemSet* pSet = pObjShell->GetMedium()->GetItemSet(); SFX_ITEMSET_ARG( pSet, pFilterItem, SfxStringItem, SID_FILTER_NAME, sal_False ); SFX_ITEMSET_ARG( pSet, pFilterOptItem, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False ); if ( pFilterItem ) aSet.Put( *pFilterItem ); if ( pFilterOptItem ) aSet.Put( *pFilterOptItem ); pViewFrame->GetDispatcher()->Execute( SID_DOCUMENT_COMPARE, SFX_CALLMODE_ASYNCHRON, aSet ); Close(); } return 0L; } SfxViewVersionDialog_Impl::SfxViewVersionDialog_Impl ( Window *pParent, SfxVersionInfo& rInfo, sal_Bool bEdit ) : SfxModalDialog( pParent, SfxResId( DLG_COMMENTS ) ) , aDateTimeText( this, SfxResId( FT_DATETIME ) ) , aSavedByText( this, SfxResId( FT_SAVEDBY ) ) , aEdit( this, SfxResId( ME_VERSIONS ) ) , aOKButton( this, SfxResId( PB_OK ) ) , aCancelButton( this, SfxResId( PB_CANCEL ) ) , aCloseButton( this, SfxResId( PB_CLOSE ) ) , aHelpButton( this, SfxResId( PB_HELP ) ) , pInfo( &rInfo ) { FreeResource(); LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); aDateTimeText.SetText( aDateTimeText.GetText().Append(ConvertDateTime_Impl( pInfo->aCreationDate, aLocaleWrapper )) ); aSavedByText.SetText( aSavedByText.GetText().Append(pInfo->aAuthor) ); aEdit.SetText( rInfo.aComment ); aCloseButton.SetClickHdl ( LINK( this, SfxViewVersionDialog_Impl, ButtonHdl ) ); aOKButton.SetClickHdl ( LINK( this, SfxViewVersionDialog_Impl, ButtonHdl ) ); aEdit.GrabFocus(); if ( !bEdit ) { aOKButton.Hide(); aCancelButton.Hide(); aEdit.SetReadOnly( sal_True ); } else aCloseButton.Hide(); } IMPL_LINK( SfxViewVersionDialog_Impl, ButtonHdl, Button*, pButton ) { if ( pButton == &aCloseButton ) { EndDialog( RET_CANCEL ); } else if ( pButton == &aOKButton ) { pInfo->aComment = aEdit.GetText(); EndDialog( RET_OK ); } return 0L; }