blob: f02cff628589ca655f54524ed07d66ab33dfae9e [file] [log] [blame]
/**************************************************************
*
* 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 <unotools/localedatawrapper.hxx>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <svl/stritem.hxx>
#include <svl/itemset.hxx>
#include <unotools/useroptions.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <tools/datetime.hxx>
#define _SVSTDARR_STRINGSDTOR
#include <svl/svstdarr.hxx>
#include "versdlg.hrc"
#include "versdlg.hxx"
#include <sfx2/viewfrm.hxx>
#include "sfx2/sfxresid.hxx"
#include <sfx2/docfile.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/sfxsids.hrc>
#include <sfx2/dispatch.hxx>
#include <sfx2/request.hxx>
#include <sfx2/sfxuno.hxx>
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;
}