blob: 123c8f28fec624f1cb0c15099edf5e5963417991 [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 <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <svl/eitem.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/filedlghelper.hxx>
#include <unotools/localedatawrapper.hxx>
#include <unotools/cmdoptions.hxx>
#include <comphelper/processfactory.hxx>
#include <svl/urihelper.hxx>
#include <unotools/useroptions.hxx>
#include <svtools/imagemgr.hxx>
#include <tools/datetime.hxx>
#include <memory>
#include <comphelper/string.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/security/DocumentSignatureInformation.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <unotools/localedatawrapper.hxx>
#include <unotools/syslocale.hxx>
#include <rtl/math.hxx>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XPropertyContainer.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Time.hpp>
#include <com/sun/star/util/Duration.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <vcl/timer.hxx>
#include "sfx2/dinfdlg.hxx"
#include "sfx2/securitypage.hxx"
#include "sfxresid.hxx"
#include "dinfedt.hxx"
#include <sfx2/frame.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/request.hxx>
//#include "exptypes.hxx"
#include "helper.hxx"
#include <sfx2/objsh.hxx>
#include <sfx2/docfile.hxx>
#include <comphelper/storagehelper.hxx>
#include <sfx2/sfx.hrc>
#include "dinfdlg.hrc"
#include "sfxlocal.hrc"
#include <dialog.hrc>
#include <vcl/help.hxx>
#include <algorithm>
using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ui::dialogs;
using namespace ::com::sun::star::uno;
struct CustomProperty
{
::rtl::OUString m_sName;
com::sun::star::uno::Any m_aValue;
CustomProperty( const ::rtl::OUString& sName,
const com::sun::star::uno::Any& rValue ) :
m_sName( sName ), m_aValue( rValue ) {}
inline bool operator==( const CustomProperty& rProp )
{ return m_sName.equals( rProp.m_sName ) && m_aValue == rProp.m_aValue; }
};
static
bool operator==(const util::DateTime &i_rLeft, const util::DateTime &i_rRight)
{
return i_rLeft.Year == i_rRight.Year
&& i_rLeft.Month == i_rRight.Month
&& i_rLeft.Day == i_rRight.Day
&& i_rLeft.Hours == i_rRight.Hours
&& i_rLeft.Minutes == i_rRight.Minutes
&& i_rLeft.Seconds == i_rRight.Seconds
&& i_rLeft.HundredthSeconds == i_rRight.HundredthSeconds;
}
// STATIC DATA -----------------------------------------------------------
TYPEINIT1_AUTOFACTORY(SfxDocumentInfoItem, SfxStringItem);
const sal_uInt16 HI_NAME = 1;
const sal_uInt16 HI_TYPE = 2;
const sal_uInt16 HI_VALUE = 3;
const sal_uInt16 HI_ACTION = 4;
static const char DOCUMENT_SIGNATURE_MENU_CMD[] = "Signature";
//------------------------------------------------------------------------
String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes = sal_True, sal_Bool bSmartExtraBytes = sal_False );
String CreateSizeText( sal_uIntPtr nSize, sal_Bool bExtraBytes, sal_Bool bSmartExtraBytes )
{
String aUnitStr = ' ';
aUnitStr += String( SfxResId(STR_BYTES) );
sal_uIntPtr nSize1 = nSize;
sal_uIntPtr nSize2 = nSize1;
sal_uIntPtr nMega = 1024 * 1024;
sal_uIntPtr nGiga = nMega * 1024;
double fSize = nSize;
int nDec = 0;
sal_Bool bGB = sal_False;
if ( nSize1 >= 10000 && nSize1 < nMega )
{
nSize1 /= 1024;
aUnitStr = ' ';
aUnitStr += String( SfxResId(STR_KB) );
fSize /= 1024;
nDec = 0;
}
else if ( nSize1 >= nMega && nSize1 < nGiga )
{
nSize1 /= nMega;
aUnitStr = ' ';
aUnitStr += String( SfxResId(STR_MB) );
fSize /= nMega;
nDec = 2;
}
else if ( nSize1 >= nGiga )
{
nSize1 /= nGiga;
aUnitStr = ' ';
aUnitStr += String( SfxResId(STR_GB) );
bGB = sal_True;
fSize /= nGiga;
nDec = 3;
}
const SvtSysLocale aSysLocale;
const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
String aSizeStr( rLocaleWrapper.getNum( nSize1, 0 ) );
aSizeStr += aUnitStr;
if ( bExtraBytes && ( nSize1 < nSize2 ) )
{
aSizeStr = ::rtl::math::doubleToUString( fSize,
rtl_math_StringFormat_F, nDec,
rLocaleWrapper.getNumDecimalSep().GetChar(0) );
aSizeStr += aUnitStr;
aSizeStr += DEFINE_CONST_UNICODE(" (");
aSizeStr += rLocaleWrapper.getNum( nSize2, 0 );
aSizeStr += ' ';
aSizeStr += String( SfxResId(STR_BYTES) );
aSizeStr += ')';
}
else if ( bGB && bSmartExtraBytes )
{
nSize1 = nSize / nMega;
aSizeStr = DEFINE_CONST_UNICODE(" (");
aSizeStr += rLocaleWrapper.getNum( nSize1, 0 );
aSizeStr += aUnitStr;
aSizeStr += ')';
}
return aSizeStr;
}
String ConvertDateTime_Impl( const String& rName,
const util::DateTime& uDT, const LocaleDataWrapper& rWrapper )
{
Date aD(uDT.Day, uDT.Month, uDT.Year);
Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds);
const String pDelim ( DEFINE_CONST_UNICODE( ", "));
String aStr( rWrapper.getDate( aD ) );
aStr += pDelim;
aStr += rWrapper.getTime( aT, sal_True, sal_False );
String aAuthor = rName;
aAuthor.EraseLeadingChars();
if ( aAuthor.Len() )
{
aStr += pDelim;
aStr += aAuthor;
}
return aStr;
}
//------------------------------------------------------------------------
SfxDocumentInfoItem::SfxDocumentInfoItem()
: SfxStringItem()
, m_AutoloadDelay(0)
, m_AutoloadURL()
, m_isAutoloadEnabled(sal_False)
, m_DefaultTarget()
, m_TemplateName()
, m_Author()
, m_CreationDate()
, m_ModifiedBy()
, m_ModificationDate()
, m_PrintedBy()
, m_PrintDate()
, m_EditingCycles(0)
, m_EditingDuration(0)
, m_Description()
, m_Keywords()
, m_Subject()
, m_Title()
, m_bHasTemplate( sal_True )
, m_bDeleteUserData( sal_False )
, m_bUseUserData( sal_True )
{
}
//------------------------------------------------------------------------
SfxDocumentInfoItem::SfxDocumentInfoItem( const String& rFile,
const uno::Reference<document::XDocumentProperties>& i_xDocProps,
sal_Bool bIs )
: SfxStringItem( SID_DOCINFO, rFile )
, m_AutoloadDelay( i_xDocProps->getAutoloadSecs() )
, m_AutoloadURL( i_xDocProps->getAutoloadURL() )
, m_isAutoloadEnabled( (m_AutoloadDelay > 0) || m_AutoloadURL.getLength() )
, m_DefaultTarget( i_xDocProps->getDefaultTarget() )
, m_TemplateName( i_xDocProps->getTemplateName() )
, m_Author( i_xDocProps->getAuthor() )
, m_CreationDate( i_xDocProps->getCreationDate() )
, m_ModifiedBy( i_xDocProps->getModifiedBy() )
, m_ModificationDate( i_xDocProps->getModificationDate() )
, m_PrintedBy( i_xDocProps->getPrintedBy() )
, m_PrintDate( i_xDocProps->getPrintDate() )
, m_EditingCycles( i_xDocProps->getEditingCycles() )
, m_EditingDuration( i_xDocProps->getEditingDuration() )
, m_Description( i_xDocProps->getDescription() )
, m_Keywords( ::comphelper::string::convertCommaSeparated(
i_xDocProps->getKeywords()) )
, m_Subject( i_xDocProps->getSubject() )
, m_Title( i_xDocProps->getTitle() )
, m_bHasTemplate( sal_True )
, m_bDeleteUserData( sal_False )
, m_bUseUserData( bIs )
{
try
{
Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
if ( xContainer.is() )
{
Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
const Sequence< beans::Property > lProps = xSet->getPropertySetInfo()->getProperties();
const beans::Property* pProps = lProps.getConstArray();
sal_Int32 nCount = lProps.getLength();
for ( sal_Int32 i = 0; i < nCount; ++i )
{
// "fix" property? => not a custom property => ignore it!
if (!(pProps[i].Attributes &
::com::sun::star::beans::PropertyAttribute::REMOVABLE))
{
DBG_ASSERT(false, "non-removable user-defined property?");
continue;
}
uno::Any aValue = xSet->getPropertyValue(pProps[i].Name);
CustomProperty* pProp = new CustomProperty( pProps[i].Name, aValue );
m_aCustomProperties.push_back( pProp );
}
}
}
catch ( Exception& ) {}
}
//------------------------------------------------------------------------
SfxDocumentInfoItem::SfxDocumentInfoItem( const SfxDocumentInfoItem& rItem )
: SfxStringItem( rItem )
, m_AutoloadDelay( rItem.getAutoloadDelay() )
, m_AutoloadURL( rItem.getAutoloadURL() )
, m_isAutoloadEnabled( rItem.isAutoloadEnabled() )
, m_DefaultTarget( rItem.getDefaultTarget() )
, m_TemplateName( rItem.getTemplateName() )
, m_Author( rItem.getAuthor() )
, m_CreationDate( rItem.getCreationDate() )
, m_ModifiedBy( rItem.getModifiedBy() )
, m_ModificationDate( rItem.getModificationDate() )
, m_PrintedBy( rItem.getPrintedBy() )
, m_PrintDate( rItem.getPrintDate() )
, m_EditingCycles( rItem.getEditingCycles() )
, m_EditingDuration( rItem.getEditingDuration() )
, m_Description( rItem.getDescription() )
, m_Keywords( rItem.getKeywords() )
, m_Subject( rItem.getSubject() )
, m_Title( rItem.getTitle() )
, m_bHasTemplate( rItem.m_bHasTemplate )
, m_bDeleteUserData( rItem.m_bDeleteUserData )
, m_bUseUserData( rItem.m_bUseUserData )
{
for ( sal_uInt32 i = 0; i < rItem.m_aCustomProperties.size(); i++ )
{
CustomProperty* pProp = new CustomProperty( rItem.m_aCustomProperties[i]->m_sName,
rItem.m_aCustomProperties[i]->m_aValue );
m_aCustomProperties.push_back( pProp );
}
}
//------------------------------------------------------------------------
SfxDocumentInfoItem::~SfxDocumentInfoItem()
{
ClearCustomProperties();
}
//------------------------------------------------------------------------
SfxPoolItem* SfxDocumentInfoItem::Clone( SfxItemPool * ) const
{
return new SfxDocumentInfoItem( *this );
}
//------------------------------------------------------------------------
int SfxDocumentInfoItem::operator==( const SfxPoolItem& rItem) const
{
if (!(rItem.Type() == Type() && SfxStringItem::operator==(rItem))) {
return false;
}
const SfxDocumentInfoItem& rInfoItem(
static_cast<const SfxDocumentInfoItem&>(rItem));
return
m_AutoloadDelay == rInfoItem.m_AutoloadDelay &&
m_AutoloadURL == rInfoItem.m_AutoloadURL &&
m_isAutoloadEnabled == rInfoItem.m_isAutoloadEnabled &&
m_DefaultTarget == rInfoItem.m_DefaultTarget &&
m_Author == rInfoItem.m_Author &&
m_CreationDate == rInfoItem.m_CreationDate &&
m_ModifiedBy == rInfoItem.m_ModifiedBy &&
m_ModificationDate == rInfoItem.m_ModificationDate &&
m_PrintedBy == rInfoItem.m_PrintedBy &&
m_PrintDate == rInfoItem.m_PrintDate &&
m_EditingCycles == rInfoItem.m_EditingCycles &&
m_EditingDuration == rInfoItem.m_EditingDuration &&
m_Description == rInfoItem.m_Description &&
m_Keywords == rInfoItem.m_Keywords &&
m_Subject == rInfoItem.m_Subject &&
m_Title == rInfoItem.m_Title &&
m_aCustomProperties.size() == rInfoItem.m_aCustomProperties.size() &&
std::equal(m_aCustomProperties.begin(), m_aCustomProperties.end(),
rInfoItem.m_aCustomProperties.begin());
}
//------------------------------------------------------------------------
void SfxDocumentInfoItem::resetUserData(const ::rtl::OUString & i_rAuthor)
{
setAuthor(i_rAuthor);
DateTime now;
setCreationDate( util::DateTime(
now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
now.GetDay(), now.GetMonth(), now.GetYear() ) );
setModifiedBy(::rtl::OUString());
setPrintedBy(::rtl::OUString());
setModificationDate(util::DateTime());
setPrintDate(util::DateTime());
setEditingDuration(0);
setEditingCycles(1);
}
//------------------------------------------------------------------------
void SfxDocumentInfoItem::UpdateDocumentInfo(
const uno::Reference<document::XDocumentProperties>& i_xDocProps,
bool i_bDoNotUpdateUserDefined) const
{
if (isAutoloadEnabled()) {
i_xDocProps->setAutoloadSecs(getAutoloadDelay());
i_xDocProps->setAutoloadURL(getAutoloadURL());
} else {
i_xDocProps->setAutoloadSecs(0);
i_xDocProps->setAutoloadURL(::rtl::OUString());
}
i_xDocProps->setDefaultTarget(getDefaultTarget());
// i_xDocProps->setTemplateName(getTemplateName());
i_xDocProps->setAuthor(getAuthor());
i_xDocProps->setCreationDate(getCreationDate());
i_xDocProps->setModifiedBy(getModifiedBy());
i_xDocProps->setModificationDate(getModificationDate());
i_xDocProps->setPrintedBy(getPrintedBy());
i_xDocProps->setPrintDate(getPrintDate());
i_xDocProps->setEditingCycles(getEditingCycles());
i_xDocProps->setEditingDuration(getEditingDuration());
i_xDocProps->setDescription(getDescription());
i_xDocProps->setKeywords(
::comphelper::string::convertCommaSeparated(getKeywords()));
i_xDocProps->setSubject(getSubject());
i_xDocProps->setTitle(getTitle());
// this is necessary in case of replaying a recorded macro:
// in this case, the macro may contain the 4 old user-defined DocumentInfo
// fields, but not any of the DocumentInfo properties;
// as a consequence, most of the UserDefined properties of the
// DocumentProperties would be summarily deleted here, which does not
// seem like a good idea.
if (i_bDoNotUpdateUserDefined)
return;
try
{
Reference< beans::XPropertyContainer > xContainer = i_xDocProps->getUserDefinedProperties();
Reference < beans::XPropertySet > xSet( xContainer, UNO_QUERY );
Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
const Sequence< beans::Property > lProps = xSetInfo->getProperties();
const beans::Property* pProps = lProps.getConstArray();
sal_Int32 nCount = lProps.getLength();
for ( sal_Int32 j = 0; j < nCount; ++j )
{
if ((pProps[j].Attributes &
::com::sun::star::beans::PropertyAttribute::REMOVABLE))
{
xContainer->removeProperty( pProps[j].Name );
}
}
for ( sal_uInt32 k = 0; k < m_aCustomProperties.size(); ++k )
{
try
{
xContainer->addProperty( m_aCustomProperties[k]->m_sName,
beans::PropertyAttribute::REMOVABLE, m_aCustomProperties[k]->m_aValue );
}
catch ( Exception& )
{
DBG_ERRORFILE( "SfxDocumentInfoItem::updateDocumentInfo(): exception while adding custom properties" );
}
}
}
catch ( Exception& )
{
DBG_ERRORFILE( "SfxDocumentInfoItem::updateDocumentInfo(): exception while removing custom properties" );
}
}
//------------------------------------------------------------------------
sal_Bool SfxDocumentInfoItem::IsDeleteUserData() const
{
return m_bDeleteUserData;
}
void SfxDocumentInfoItem::SetDeleteUserData( sal_Bool bSet )
{
m_bDeleteUserData = bSet;
}
sal_Bool SfxDocumentInfoItem::IsUseUserData() const
{
return m_bUseUserData;
}
void SfxDocumentInfoItem::SetUseUserData( sal_Bool bSet )
{
m_bUseUserData = bSet;
}
std::vector< CustomProperty* > SfxDocumentInfoItem::GetCustomProperties() const
{
std::vector< CustomProperty* > aRet;
for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
{
CustomProperty* pProp = new CustomProperty( m_aCustomProperties[i]->m_sName,
m_aCustomProperties[i]->m_aValue );
aRet.push_back( pProp );
}
return aRet;
}
void SfxDocumentInfoItem::ClearCustomProperties()
{
for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ )
delete m_aCustomProperties[i];
m_aCustomProperties.clear();
}
void SfxDocumentInfoItem::AddCustomProperty( const ::rtl::OUString& sName, const Any& rValue )
{
CustomProperty* pProp = new CustomProperty( sName, rValue );
m_aCustomProperties.push_back( pProp );
}
sal_Bool SfxDocumentInfoItem::QueryValue( Any& rVal, sal_uInt8 nMemberId ) const
{
String aValue;
sal_Int32 nValue = 0;
sal_Bool bValue = sal_False;
sal_Bool bIsInt = sal_False;
sal_Bool bIsString = sal_False;
nMemberId &= ~CONVERT_TWIPS;
switch ( nMemberId )
{
case MID_DOCINFO_USEUSERDATA:
bValue = IsUseUserData();
break;
case MID_DOCINFO_DELETEUSERDATA:
bValue = IsDeleteUserData();
break;
case MID_DOCINFO_AUTOLOADENABLED:
bValue = isAutoloadEnabled();
break;
case MID_DOCINFO_AUTOLOADSECS:
bIsInt = sal_True;
nValue = getAutoloadDelay();
break;
case MID_DOCINFO_AUTOLOADURL:
bIsString = sal_True;
aValue = getAutoloadURL();
break;
case MID_DOCINFO_DEFAULTTARGET:
bIsString = sal_True;
aValue = getDefaultTarget();
break;
case MID_DOCINFO_DESCRIPTION:
bIsString = sal_True;
aValue = getDescription();
break;
case MID_DOCINFO_KEYWORDS:
bIsString = sal_True;
aValue = getKeywords();
break;
case MID_DOCINFO_SUBJECT:
bIsString = sal_True;
aValue = getSubject();
break;
case MID_DOCINFO_TITLE:
bIsString = sal_True;
aValue = getTitle();
break;
default:
DBG_ERROR("Wrong MemberId!");
return sal_False;
}
if ( bIsString )
rVal <<= ::rtl::OUString( aValue );
else if ( bIsInt )
rVal <<= nValue;
else
rVal <<= bValue;
return sal_True;
}
sal_Bool SfxDocumentInfoItem::PutValue( const Any& rVal, sal_uInt8 nMemberId )
{
::rtl::OUString aValue;
sal_Int32 nValue=0;
sal_Bool bValue = sal_False;
sal_Bool bRet = sal_False;
nMemberId &= ~CONVERT_TWIPS;
switch ( nMemberId )
{
case MID_DOCINFO_USEUSERDATA:
bRet = (rVal >>= bValue);
if ( bRet )
SetUseUserData( bValue );
break;
case MID_DOCINFO_DELETEUSERDATA:
// QUESTION: deleting user data was done here; seems to be superfluous!
bRet = (rVal >>= bValue);
if ( bRet )
SetDeleteUserData( bValue );
break;
case MID_DOCINFO_AUTOLOADENABLED:
bRet = (rVal >>= bValue);
if ( bRet )
setAutoloadEnabled(bValue);
break;
case MID_DOCINFO_AUTOLOADSECS:
bRet = (rVal >>= nValue);
if ( bRet )
setAutoloadDelay(nValue);
break;
case MID_DOCINFO_AUTOLOADURL:
bRet = (rVal >>= aValue);
if ( bRet )
setAutoloadURL(aValue);
break;
case MID_DOCINFO_DEFAULTTARGET:
bRet = (rVal >>= aValue);
if ( bRet )
setDefaultTarget(aValue);
break;
case MID_DOCINFO_DESCRIPTION:
bRet = (rVal >>= aValue);
if ( bRet )
setDescription(aValue);
break;
case MID_DOCINFO_KEYWORDS:
bRet = (rVal >>= aValue);
if ( bRet )
setKeywords(aValue);
break;
case MID_DOCINFO_SUBJECT:
bRet = (rVal >>= aValue);
if ( bRet )
setSubject(aValue);
break;
case MID_DOCINFO_TITLE:
bRet = (rVal >>= aValue);
if ( bRet )
setTitle(aValue);
break;
default:
DBG_ERROR("Wrong MemberId!");
return sal_False;
}
return bRet;
}
//------------------------------------------------------------------------
SfxDocumentDescPage::SfxDocumentDescPage( Window * pParent, const SfxItemSet& rItemSet ) :
SfxTabPage( pParent, SfxResId( TP_DOCINFODESC ), rItemSet ),
aTitleFt ( this, SfxResId( FT_TITLE ) ),
aTitleEd ( this, SfxResId( ED_TITLE ) ),
aThemaFt ( this, SfxResId( FT_THEMA ) ),
aThemaEd ( this, SfxResId( ED_THEMA ) ),
aKeywordsFt ( this, SfxResId( FT_KEYWORDS ) ),
aKeywordsEd ( this, SfxResId( ED_KEYWORDS ) ),
aCommentFt ( this, SfxResId( FT_COMMENT ) ),
aCommentEd ( this, SfxResId( ED_COMMENT ) ),
pInfoItem ( NULL )
{
FreeResource();
}
//------------------------------------------------------------------------
SfxTabPage *SfxDocumentDescPage::Create(Window *pParent, const SfxItemSet &rItemSet)
{
return new SfxDocumentDescPage(pParent, rItemSet);
}
//------------------------------------------------------------------------
sal_Bool SfxDocumentDescPage::FillItemSet(SfxItemSet &rSet)
{
// Pruefung, ob eine Aenderung vorliegt
const sal_Bool bTitleMod = aTitleEd.IsModified();
const sal_Bool bThemeMod = aThemaEd.IsModified();
const sal_Bool bKeywordsMod = aKeywordsEd.IsModified();
const sal_Bool bCommentMod = aCommentEd.IsModified();
if( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) )
{
return sal_False;
}
// Erzeugung der Ausgabedaten
const SfxPoolItem* pItem = NULL;
SfxDocumentInfoItem* pInfo = NULL;
SfxTabDialog* pDlg = GetTabDialog();
const SfxItemSet* pExSet = NULL;
if ( pDlg )
pExSet = pDlg->GetExampleSet();
if ( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
pInfo = pInfoItem;
else if ( pItem )
pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem *)pItem );
if ( !pInfo )
{
DBG_ERRORFILE( "SfxDocumentDescPage::FillItemSet(): no item found" );
return sal_False;
}
if( bTitleMod )
{
pInfo->setTitle( aTitleEd.GetText() );
}
if( bThemeMod )
{
pInfo->setSubject( aThemaEd.GetText() );
}
if( bKeywordsMod )
{
pInfo->setKeywords( aKeywordsEd.GetText() );
}
if( bCommentMod )
{
pInfo->setDescription( aCommentEd.GetText() );
}
rSet.Put( SfxDocumentInfoItem( *pInfo ) );
if( pInfo != pInfoItem )
{
delete pInfo;
}
return sal_True;
}
//------------------------------------------------------------------------
void SfxDocumentDescPage::Reset(const SfxItemSet &rSet)
{
pInfoItem = &(SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
aTitleEd.SetText( pInfoItem->getTitle() );
aThemaEd.SetText( pInfoItem->getSubject() );
aKeywordsEd.SetText( pInfoItem->getKeywords() );
aCommentEd.SetText( pInfoItem->getDescription() );
SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
if ( pROItem && pROItem->GetValue() )
{
aTitleEd.SetReadOnly( sal_True );
aThemaEd.SetReadOnly( sal_True );
aKeywordsEd.SetReadOnly( sal_True );
aCommentEd.SetReadOnly( sal_True );
}
}
//------------------------------------------------------------------------
namespace
{
String GetDateTimeString( sal_Int32 _nDate, sal_Int32 _nTime )
{
LocaleDataWrapper aWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
Date aDate( _nDate );
Time aTime( _nTime );
String aStr( aWrapper.getDate( aDate ) );
aStr.AppendAscii( ", " );
aStr += aWrapper.getTime( aTime );
return aStr;
}
// copy from xmlsecurity/source/dialog/resourcemanager.cxx
String GetContentPart( const String& _rRawString, const String& _rPartId )
{
String s;
xub_StrLen nContStart = _rRawString.Search( _rPartId );
if( nContStart != STRING_NOTFOUND )
{
nContStart = nContStart + _rPartId.Len();
++nContStart; // now it's start of content, directly after Id
xub_StrLen nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart );
s = String( _rRawString, nContStart, nContEnd - nContStart );
}
return s;
}
}
SfxDocumentPage::SfxDocumentPage( Window* pParent, const SfxItemSet& rItemSet ) :
SfxTabPage( pParent, SfxResId( TP_DOCINFODOC ), rItemSet ),
aBmp1 ( this, SfxResId( BMP_FILE_1 ) ),
aNameED ( this, SfxResId( ED_FILE_NAME ) ),
aLine1FL ( this, SfxResId( FL_FILE_1 ) ),
aTypeFT ( this, SfxResId( FT_FILE_TYP ) ),
aShowTypeFT ( this, SfxResId( FT_FILE_SHOW_TYP ) ),
aReadOnlyCB ( this, SfxResId( CB_FILE_READONLY ) ),
aFileFt ( this, SfxResId( FT_FILE ) ),
aFileValFt ( this, SfxResId( FT_FILE_VAL ) ),
aSizeFT ( this, SfxResId( FT_FILE_SIZE ) ),
aShowSizeFT ( this, SfxResId( FT_FILE_SHOW_SIZE ) ),
aLine2FL ( this, SfxResId( FL_FILE_2 ) ),
aCreateFt ( this, SfxResId( FT_CREATE ) ),
aCreateValFt ( this, SfxResId( FT_CREATE_VAL ) ),
aChangeFt ( this, SfxResId( FT_CHANGE ) ),
aChangeValFt ( this, SfxResId( FT_CHANGE_VAL ) ),
aSignedFt ( this, SfxResId( FT_SIGNED ) ),
aSignedValFt ( this, SfxResId( FT_SIGNED_VAL ) ),
aSignatureBtn ( this, SfxResId( BTN_SIGNATURE ) ),
aPrintFt ( this, SfxResId( FT_PRINT ) ),
aPrintValFt ( this, SfxResId( FT_PRINT_VAL ) ),
aTimeLogFt ( this, SfxResId( FT_TIMELOG ) ),
aTimeLogValFt ( this, SfxResId( FT_TIMELOG_VAL ) ),
aDocNoFt ( this, SfxResId( FT_DOCNO ) ),
aDocNoValFt ( this, SfxResId( FT_DOCNO_VAL ) ),
aUseUserDataCB ( this, SfxResId( CB_USE_USERDATA ) ),
aDeleteBtn ( this, SfxResId( BTN_DELETE ) ),
aLine3FL ( this, SfxResId( FL_FILE_3 ) ),
aTemplFt ( this, SfxResId( FT_TEMPL ) ),
aTemplValFt ( this, SfxResId( FT_TEMPL_VAL ) ),
aUnknownSize ( SfxResId( STR_UNKNOWNSIZE ) ),
aMultiSignedStr ( SfxResId( STR_MULTSIGNED ) ),
bEnableUseUserData ( sal_False ),
bHandleDelete ( sal_False )
{
aNameED.SetAccessibleName(String(SfxResId(EDIT_FILE_NAME)));
FreeResource();
ImplUpdateSignatures();
aDeleteBtn.SetClickHdl( LINK( this, SfxDocumentPage, DeleteHdl ) );
aSignatureBtn.SetClickHdl( LINK( this, SfxDocumentPage, SignatureHdl ) );
// if the button text is too wide, then broaden it
const long nOffset = 12;
String sText = aSignatureBtn.GetText();
long nTxtW = aSignatureBtn.GetTextWidth( sText );
if ( sText.Search( '~' ) == STRING_NOTFOUND )
nTxtW += nOffset;
long nBtnW = aSignatureBtn.GetSizePixel().Width();
if ( nTxtW >= nBtnW )
{
long nDelta = Max( nTxtW - nBtnW, nOffset/3 );
Size aNewSize = aSignatureBtn.GetSizePixel();
aNewSize.Width() += nDelta;
aSignatureBtn.SetSizePixel( aNewSize );
aDeleteBtn.SetSizePixel( aNewSize );
// and give them a new position
Point aNewPos = aSignatureBtn.GetPosPixel();
aNewPos.X() -= nDelta;
aSignatureBtn.SetPosPixel( aNewPos );
aNewPos = aDeleteBtn.GetPosPixel();
aNewPos.X() -= nDelta;
aDeleteBtn.SetPosPixel( aNewPos );
aNewSize = aSignedValFt.GetSizePixel();
aNewSize.Width() -= nDelta;
aSignedValFt.SetSizePixel( aNewSize );
aNewSize = aUseUserDataCB.GetSizePixel();
aNewSize.Width() -= nDelta;
aUseUserDataCB.SetSizePixel( aNewSize );
}
// See i96288
// Check if the document signature command is enabled
// on the main list enable/disable the pushbutton accordingly
SvtCommandOptions aCmdOptions;
if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED,
rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( DOCUMENT_SIGNATURE_MENU_CMD ) ) ) )
aSignatureBtn.Disable();
}
//------------------------------------------------------------------------
IMPL_LINK( SfxDocumentPage, DeleteHdl, PushButton*, EMPTYARG )
{
String aName;
if ( bEnableUseUserData && aUseUserDataCB.IsChecked() )
aName = SvtUserOptions().GetFullName();
LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
DateTime now;
util::DateTime uDT(
now.Get100Sec(), now.GetSec(), now.GetMin(), now.GetHour(),
now.GetDay(), now.GetMonth(), now.GetYear() );
aCreateValFt.SetText( ConvertDateTime_Impl( aName, uDT, aLocaleWrapper ) );
XubString aEmpty;
aChangeValFt.SetText( aEmpty );
aPrintValFt.SetText( aEmpty );
const Time aTime( 0 );
aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aTime ) );
aDocNoValFt.SetText( '1' );
bHandleDelete = sal_True;
return 0;
}
IMPL_LINK( SfxDocumentPage, SignatureHdl, PushButton*, EMPTYARG )
{
SfxObjectShell* pDoc = SfxObjectShell::Current();
if( pDoc )
{
pDoc->SignDocumentContent();
ImplUpdateSignatures();
}
return 0;
}
void SfxDocumentPage::ImplUpdateSignatures()
{
SfxObjectShell* pDoc = SfxObjectShell::Current();
if( pDoc )
{
SfxMedium* pMedium = pDoc->GetMedium();
if ( pMedium && pMedium->GetName().Len() && pMedium->GetStorage().is() )
{
Reference< security::XDocumentDigitalSignatures > xD(
comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ) ), uno::UNO_QUERY );
if( xD.is() )
{
String s;
Sequence< security::DocumentSignatureInformation > aInfos;
aInfos = xD->verifyDocumentContentSignatures( pMedium->GetZipStorageToSign_Impl(),
uno::Reference< io::XInputStream >() );
if( aInfos.getLength() > 1 )
{
s = aMultiSignedStr;
}
else if( aInfos.getLength() == 1 )
{
String aCN_Id( String::CreateFromAscii( "CN" ) );
const security::DocumentSignatureInformation& rInfo = aInfos[ 0 ];
s = GetDateTimeString( rInfo.SignatureDate, rInfo.SignatureTime );
s.AppendAscii( ", " );
s += GetContentPart( rInfo.Signer->getSubjectName(), aCN_Id );
}
aSignedValFt.SetText( s );
}
}
}
}
//------------------------------------------------------------------------
SfxTabPage* SfxDocumentPage::Create( Window* pParent, const SfxItemSet& rItemSet )
{
return new SfxDocumentPage( pParent, rItemSet );
}
//------------------------------------------------------------------------
void SfxDocumentPage::EnableUseUserData()
{
bEnableUseUserData = sal_True;
aUseUserDataCB.Show();
aDeleteBtn.Show();
}
//------------------------------------------------------------------------
sal_Bool SfxDocumentPage::FillItemSet( SfxItemSet& rSet )
{
sal_Bool bRet = sal_False;
if ( !bHandleDelete && bEnableUseUserData &&
aUseUserDataCB.GetState() != aUseUserDataCB.GetSavedValue() &&
GetTabDialog() && GetTabDialog()->GetExampleSet() )
{
const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
const SfxPoolItem* pItem;
if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
{
SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
sal_Bool bUseData = ( STATE_CHECK == aUseUserDataCB.GetState() );
pInfoItem->SetUseUserData( bUseData );
/*
if ( !bUseData )
{
// "Benutzerdaten verwenden" ausgeschaltet ->
// den Benutzer aus den Stamps l"oschen
String aEmptyUser;
aInfo.SetCreated(
SfxStamp( aEmptyUser, aInfo.GetCreated().GetTime() ) );
aInfo.SetChanged(
SfxStamp( aEmptyUser, aInfo.GetChanged().GetTime() ) );
aInfo.SetPrinted(
SfxStamp( aEmptyUser, aInfo.GetPrinted().GetTime() ) );
}
*/
rSet.Put( SfxDocumentInfoItem( *pInfoItem ) );
bRet = sal_True;
}
}
if ( bHandleDelete )
{
const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet();
const SfxPoolItem* pItem;
if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
{
SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem;
sal_Bool bUseAuthor = bEnableUseUserData && aUseUserDataCB.IsChecked();
SfxDocumentInfoItem newItem( *pInfoItem );
newItem.resetUserData( bUseAuthor
? SvtUserOptions().GetFullName()
: ::rtl::OUString() );
pInfoItem->SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
newItem.SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() );
newItem.SetDeleteUserData( sal_True );
rSet.Put( newItem );
bRet = sal_True;
}
}
if ( aNameED.IsModified() && aNameED.GetText().Len() )
{
rSet.Put( SfxStringItem( ID_FILETP_TITLE, aNameED.GetText() ) );
bRet = sal_True;
}
if ( /* aReadOnlyCB.IsModified() */ sal_True )
{
rSet.Put( SfxBoolItem( ID_FILETP_READONLY, aReadOnlyCB.IsChecked() ) );
bRet = sal_True;
}
return bRet;
}
//------------------------------------------------------------------------
void SfxDocumentPage::Reset( const SfxItemSet& rSet )
{
// Bestimmung der Dokumentinformationen
const SfxDocumentInfoItem *pInfoItem =
&(const SfxDocumentInfoItem &)rSet.Get(SID_DOCINFO);
// template data
if ( pInfoItem->HasTemplate() )
{
aTemplValFt.SetText( pInfoItem->getTemplateName() );
}
else
{
aTemplFt.Hide();
aTemplValFt.Hide();
}
// determine file name
String aFile( pInfoItem->GetValue() );
String aFactory( aFile );
if ( aFile.Len() > 2 && aFile.GetChar(0) == '[' )
{
sal_uInt16 nPos = aFile.Search( ']' );
aFactory = aFile.Copy( 1, nPos-1 );
aFile = aFile.Copy( nPos+1 );
}
// determine name
String aName;
const SfxPoolItem* pItem = 0;
if ( SFX_ITEM_SET != rSet.GetItemState( ID_FILETP_TITLE, sal_False, &pItem ) )
{
INetURLObject aURL(aFile);
aName = aURL.GetName( INetURLObject::DECODE_WITH_CHARSET );
if ( !aName.Len() || aURL.GetProtocol() == INET_PROT_PRIVATE )
aName = String( SfxResId( STR_NONAME ) );
aNameED.SetReadOnly( sal_True );
}
else
{
DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ), "SfxDocumentPage:<SfxStringItem> erwartet" );
aName = ( ( SfxStringItem* ) pItem )->GetValue();
}
aNameED.SetText( aName );
aNameED.ClearModifyFlag();
// determine RO-Flag
if ( SFX_ITEM_UNKNOWN == rSet.GetItemState( ID_FILETP_READONLY, sal_False, &pItem )
|| !pItem )
aReadOnlyCB.Hide();
else
aReadOnlyCB.Check( ( (SfxBoolItem*)pItem )->GetValue() );
// determine context symbol
INetURLObject aURL;
aURL.SetSmartProtocol( INET_PROT_FILE );
aURL.SetSmartURL( aFactory);
const String& rMainURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
aBmp1.SetImage( SvFileInformationManager::GetImage( aURL, sal_True ) );
// determine size and type
String aSizeText( aUnknownSize );
if ( aURL.GetProtocol() == INET_PROT_FILE )
aSizeText = CreateSizeText( SfxContentHelper::GetSize( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
aShowSizeFT.SetText( aSizeText );
String aDescription = SvFileInformationManager::GetDescription( INetURLObject(rMainURL) );
if ( aDescription.Len() == 0 )
aDescription = String( SfxResId( STR_SFX_NEWOFFICEDOC ) );
aShowTypeFT.SetText( aDescription );
// determine location
aURL.SetSmartURL( aFile);
if ( aURL.GetProtocol() == INET_PROT_FILE )
{
INetURLObject aPath( aURL );
aPath.setFinalSlash();
aPath.removeSegment();
// we know it's a folder -> don't need the final slash, but it's better for WB_PATHELLIPSIS
aPath.removeFinalSlash();
String aText( aPath.PathToFileName() ); //! (pb) MaxLen?
aFileValFt.SetText( aText );
}
else if ( aURL.GetProtocol() != INET_PROT_PRIVATE )
aFileValFt.SetText( aURL.GetPartBeforeLastName() );
// handle access data
sal_Bool m_bUseUserData = pInfoItem->IsUseUserData();
LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
aCreateValFt.SetText( ConvertDateTime_Impl( pInfoItem->getAuthor(),
pInfoItem->getCreationDate(), aLocaleWrapper ) );
util::DateTime aTime( pInfoItem->getModificationDate() );
// if ( aTime.IsValid() )
if ( aTime.Month > 0 )
aChangeValFt.SetText( ConvertDateTime_Impl(
pInfoItem->getModifiedBy(), aTime, aLocaleWrapper ) );
aTime = pInfoItem->getPrintDate();
// if ( aTime.IsValid())
if ( aTime.Month > 0 )
aPrintValFt.SetText( ConvertDateTime_Impl( pInfoItem->getPrintedBy(),
aTime, aLocaleWrapper ) );
const long nTime = pInfoItem->getEditingDuration();
if ( m_bUseUserData )
{
const Time aT( nTime/3600, (nTime%3600)/60, nTime%60 );
aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aT ) );
aDocNoValFt.SetText( String::CreateFromInt32(
pInfoItem->getEditingCycles() ) );
}
TriState eState = (TriState)m_bUseUserData;
if ( STATE_DONTKNOW == eState )
aUseUserDataCB.EnableTriState( sal_True );
aUseUserDataCB.SetState( eState );
aUseUserDataCB.SaveValue();
aUseUserDataCB.Enable( bEnableUseUserData );
bHandleDelete = sal_False;
aDeleteBtn.Enable( bEnableUseUserData );
}
//------------------------------------------------------------------------
SfxInternetPage::SfxInternetPage( Window* pParent, const SfxItemSet& rItemSet ) :
SfxTabPage( pParent, SfxResId( TP_DOCINFORELOAD ), rItemSet ),
aRBNoAutoUpdate ( this, SfxResId( RB_NOAUTOUPDATE ) ),
aRBReloadUpdate ( this, SfxResId( RB_RELOADUPDATE ) ),
aRBForwardUpdate ( this, SfxResId( RB_FORWARDUPDATE ) ),
aFTEvery ( this, SfxResId( FT_EVERY ) ),
aNFReload ( this, SfxResId( ED_RELOAD ) ),
aFTReloadSeconds ( this, SfxResId( FT_RELOADSECS ) ),
aFTAfter ( this, SfxResId( FT_AFTER ) ),
aNFAfter ( this, SfxResId( ED_FORWARD ) ),
aFTAfterSeconds ( this, SfxResId( FT_FORWARDSECS ) ),
aFTURL ( this, SfxResId( FT_URL ) ),
aEDForwardURL ( this, SfxResId( ED_URL ) ),
aPBBrowseURL ( this, SfxResId( PB_BROWSEURL ) ),
aFTFrame ( this, SfxResId( FT_FRAME ) ),
aCBFrame ( this, SfxResId( CB_FRAME ) ),
aForwardErrorMessg ( SfxResId( STR_FORWARD_ERRMSSG ) ),
pInfoItem ( NULL ),
pFileDlg ( NULL ),
eState ( S_Init )
{
FreeResource();
pInfoItem = &( SfxDocumentInfoItem& ) rItemSet.Get( SID_DOCINFO );
TargetList aList;
SfxViewFrame* pFrame = SfxViewFrame::Current();
if( pFrame )
{
pFrame = pFrame->GetTopViewFrame();
if( pFrame )
{
pFrame->GetTargetList( aList );
String* pObj;
for( sal_uInt16 nPos = ( sal_uInt16 ) aList.Count() ; nPos ; )
{
pObj = aList.GetObject( --nPos );
aCBFrame.InsertEntry( *pObj );
delete pObj;
}
}
}
aRBNoAutoUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlNoUpdate ) );
aRBReloadUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlReload ) );
aRBForwardUpdate.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlForward ) );
aPBBrowseURL.SetClickHdl( LINK( this, SfxInternetPage, ClickHdlBrowseURL ) );
aForwardErrorMessg.SearchAndReplaceAscii( "%PLACEHOLDER%", aRBForwardUpdate.GetText() );
ChangeState( S_NoUpdate );
}
//------------------------------------------------------------------------
SfxInternetPage::~SfxInternetPage()
{
delete pFileDlg;
}
//------------------------------------------------------------------------
void SfxInternetPage::ChangeState( STATE eNewState )
{
DBG_ASSERT( eNewState != S_Init, "*SfxInternetPage::ChangeState(): new state init is supposed to not work here!" );
if( eState == eNewState )
return;
switch( eState )
{
case S_Init:
EnableNoUpdate( sal_True );
EnableReload( sal_False );
EnableForward( sal_False );
break;
case S_NoUpdate:
EnableNoUpdate( sal_False );
if( eNewState == S_Reload )
EnableReload( sal_True );
else
EnableForward( sal_True );
break;
case S_Reload:
EnableReload( sal_False );
if( eNewState == S_NoUpdate )
EnableNoUpdate( sal_True );
else
EnableForward( sal_True );
break;
case S_Forward:
EnableForward( sal_False );
if( eNewState == S_NoUpdate )
EnableNoUpdate( sal_True );
else
EnableReload( sal_True );
break;
default:
DBG_ERROR( "*SfxInternetPage::SetState(): unhandled state!" );
}
eState = eNewState;
}
//------------------------------------------------------------------------
void SfxInternetPage::EnableNoUpdate( sal_Bool bEnable )
{
if( bEnable )
aRBNoAutoUpdate.Check();
}
//------------------------------------------------------------------------
void SfxInternetPage::EnableReload( sal_Bool bEnable )
{
aFTEvery.Enable( bEnable );
aNFReload.Enable( bEnable );
aFTReloadSeconds.Enable( bEnable );
if( bEnable )
aRBReloadUpdate.Check();
}
//------------------------------------------------------------------------
void SfxInternetPage::EnableForward( sal_Bool bEnable )
{
aFTAfter.Enable( bEnable );
aNFAfter.Enable( bEnable );
aFTAfterSeconds.Enable( bEnable );
aFTURL.Enable( bEnable );
aEDForwardURL.Enable( bEnable );
aPBBrowseURL.Enable( bEnable );
aFTFrame.Enable( bEnable );
aCBFrame.Enable( bEnable );
if( bEnable )
aRBForwardUpdate.Check();
}
//------------------------------------------------------------------------
IMPL_LINK( SfxInternetPage, ClickHdlNoUpdate, Control*, pCtrl )
{
(void)pCtrl; //unused
ChangeState( S_NoUpdate );
return 0;
}
//------------------------------------------------------------------------
IMPL_LINK( SfxInternetPage, ClickHdlReload, Control*, pCtrl )
{
(void)pCtrl; //unused
ChangeState( S_Reload );
return 0;
}
//------------------------------------------------------------------------
IMPL_LINK( SfxInternetPage, ClickHdlForward, Control*, pCtrl )
{
(void)pCtrl; //unused
ChangeState( S_Forward );
return 0;
}
//------------------------------------------------------------------------
IMPL_LINK( SfxInternetPage, ClickHdlBrowseURL, PushButton*, EMPTYARG )
{
if ( !pFileDlg )
pFileDlg = new sfx2::FileDialogHelper( TemplateDescription::FILEOPEN_SIMPLE, WB_OPEN );
pFileDlg->SetDisplayDirectory( aEDForwardURL.GetText() );
pFileDlg->StartExecuteModal( LINK( this, SfxInternetPage, DialogClosedHdl ) );
return 0;
}
//------------------------------------------------------------------------
IMPL_LINK( SfxInternetPage, DialogClosedHdl, sfx2::FileDialogHelper*, EMPTYARG )
{
DBG_ASSERT( pFileDlg, "SfxInternetPage::DialogClosedHdl(): no file dialog" );
if ( ERRCODE_NONE == pFileDlg->GetError() )
aEDForwardURL.SetText( pFileDlg->GetPath() );
return 0;
}
//------------------------------------------------------------------------
sal_Bool SfxInternetPage::FillItemSet( SfxItemSet& rSet )
{
const SfxPoolItem* pItem = NULL;
SfxDocumentInfoItem* pInfo = NULL;
SfxTabDialog* pDlg = GetTabDialog();
const SfxItemSet* pExSet = NULL;
if( pDlg )
pExSet = pDlg->GetExampleSet();
if( pExSet && SFX_ITEM_SET != pExSet->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
pInfo = pInfoItem;
else if ( pItem )
pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem*)pItem );
if ( !pInfo )
{
DBG_ERRORFILE( "SfxInternetPage::FillItemSet(): no item found" );
return sal_False;
}
DBG_ASSERT( eState != S_Init, "*SfxInternetPage::FillItemSet(): state init is not acceptable at this point!" );
sal_Bool bEnableReload = sal_False;
::std::auto_ptr< String > aURL( NULL );
::std::auto_ptr< String > aFrame( NULL );
sal_uIntPtr nDelay = 0;
switch( eState )
{
case S_NoUpdate:
break;
case S_Reload:
bEnableReload = sal_True;
aURL = ::std::auto_ptr< String >( new String() );
aFrame = ::std::auto_ptr< String >( new String() );
nDelay = static_cast<sal_uIntPtr>(aNFReload.GetValue());
break;
case S_Forward:
DBG_ASSERT( aEDForwardURL.GetText().Len(), "+SfxInternetPage::FillItemSet(): empty URL should be not possible for forward option!" );
bEnableReload = sal_True;
aURL = ::std::auto_ptr< String >( new String( URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), aEDForwardURL.GetText(), URIHelper::GetMaybeFileHdl(), true ) ) );
aFrame = ::std::auto_ptr< String >( new String( aCBFrame.GetText() ) );
nDelay = static_cast<sal_uIntPtr>(aNFAfter.GetValue());
break;
default:
break;
}
pInfo->setAutoloadEnabled( bEnableReload );
if( bEnableReload )
{
pInfo->setAutoloadURL( *aURL.get() );
pInfo->setDefaultTarget( *aFrame.get() );
pInfo->setAutoloadDelay( nDelay );
}
rSet.Put( *pInfo );
if( pInfo != pInfoItem )
delete pInfo;
return sal_True;
}
//------------------------------------------------------------------------
SfxTabPage *SfxInternetPage::Create( Window* pParent, const SfxItemSet& rItemSet )
{
return new SfxInternetPage(pParent, rItemSet);
}
//------------------------------------------------------------------------
void SfxInternetPage::Reset( const SfxItemSet& rSet )
{
pInfoItem = &( SfxDocumentInfoItem& ) rSet.Get( SID_DOCINFO );
SFX_ITEMSET_ARG( &rSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
if ( pURLItem )
aBaseURL = pURLItem->GetValue();
STATE eNewState = S_NoUpdate;
if( pInfoItem->isAutoloadEnabled() )
{
const String& rURL = pInfoItem->getAutoloadURL();
if( rURL.Len() )
{
aNFAfter.SetValue( pInfoItem->getAutoloadDelay() );
aEDForwardURL.SetText( rURL );
aCBFrame.SetText( pInfoItem->getDefaultTarget() );
eNewState = S_Forward;
}
else
{
aNFReload.SetValue( pInfoItem->getAutoloadDelay() );
eNewState = S_Reload;
}
}
ChangeState( eNewState );
// #102907# ------------------------
SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, sal_False );
if ( pROItem && pROItem->GetValue() )
{
aRBNoAutoUpdate.Disable();
aRBReloadUpdate.Disable();
aRBForwardUpdate.Disable();
aNFReload.Disable();
aNFAfter.Disable();
aEDForwardURL.Disable();
aPBBrowseURL.Disable();
aCBFrame.Disable();
aFTEvery.Disable();
aFTReloadSeconds.Disable();
aFTAfter.Disable();
aFTAfterSeconds.Disable();
aFTURL.Disable();
aFTFrame.Disable();
}
}
//------------------------------------------------------------------------
int SfxInternetPage::DeactivatePage( SfxItemSet* /*pSet*/ )
{
int nRet = LEAVE_PAGE;
if( eState == S_Forward && !aEDForwardURL.GetText().Len() )
{
ErrorBox aErrBox( this, WB_OK, aForwardErrorMessg );
aErrBox.Execute();
nRet = KEEP_PAGE;
}
return nRet;
}
//------------------------------------------------------------------------
SfxDocumentInfoDialog::SfxDocumentInfoDialog( Window* pParent,
const SfxItemSet& rItemSet ) :
SfxTabDialog( 0, pParent, SfxResId( SID_DOCINFO ), &rItemSet )
{
FreeResource();
const SfxDocumentInfoItem* pInfoItem =
&(const SfxDocumentInfoItem &)rItemSet.Get( SID_DOCINFO );
#ifdef DBG_UTIL
SFX_ITEMSET_ARG( &rItemSet, pURLItem, SfxStringItem, SID_BASEURL, sal_False );
DBG_ASSERT( pURLItem, "No BaseURL provided for InternetTabPage!" );
#endif
// Bestimmung des Titels
const SfxPoolItem* pItem = 0;
String aTitle( GetText() );
if ( SFX_ITEM_SET !=
rItemSet.GetItemState( SID_EXPLORER_PROPS_START, sal_False, &pItem ) )
{
// Dateiname
String aFile( pInfoItem->GetValue() );
INetURLObject aURL;
aURL.SetSmartProtocol( INET_PROT_FILE );
aURL.SetSmartURL( aFile);
if ( INET_PROT_PRIV_SOFFICE != aURL.GetProtocol() )
{
String aLastName( aURL.GetLastName() );
if ( aLastName.Len() )
aTitle += aLastName;
else
aTitle += aFile;
}
else
aTitle += String( SfxResId( STR_NONAME ) );
}
else
{
DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ),
"SfxDocumentInfoDialog:<SfxStringItem> erwartet" );
aTitle += ( ( SfxStringItem* ) pItem )->GetValue();
}
SetText( aTitle );
// Eigenschaftenseiten
AddTabPage(TP_DOCINFODESC, SfxDocumentDescPage::Create, 0);
AddTabPage(TP_DOCINFODOC, SfxDocumentPage::Create, 0);
AddTabPage(TP_CUSTOMPROPERTIES, SfxCustomPropertiesPage::Create, 0);
AddTabPage(TP_DOCINFORELOAD, SfxInternetPage::Create, 0);
AddTabPage(TP_DOCINFOSECURITY, SfxSecurityPage::Create, 0);
}
// -----------------------------------------------------------------------
void SfxDocumentInfoDialog::PageCreated( sal_uInt16 nId, SfxTabPage &rPage )
{
if ( TP_DOCINFODOC == nId )
( (SfxDocumentPage&)rPage ).EnableUseUserData();
}
// class CustomPropertiesYesNoButton -------------------------------------
CustomPropertiesYesNoButton::CustomPropertiesYesNoButton( Window* pParent, const ResId& rResId ) :
Control( pParent, rResId ),
m_aYesButton( this, ResId( RB_PROPERTY_YES, *rResId.GetResMgr() ) ),
m_aNoButton ( this, ResId( RB_PROPERTY_NO, *rResId.GetResMgr() ) )
{
FreeResource();
Wallpaper aWall( Color( COL_TRANSPARENT ) );
SetBackground( aWall );
SetBorderStyle( WINDOW_BORDER_MONO );
CheckNo();
m_aYesButton.SetBackground( aWall );
m_aNoButton.SetBackground( aWall );
}
class DurationDialog_Impl : public ModalDialog
{
FixedLine aDurationFL;
OKButton aOKPB;
CancelButton aCancelPB;
HelpButton aHelpPB;
CheckBox aNegativeCB;
FixedText aYearFT;
NumericField aYearNF;
FixedText aMonthFT;
NumericField aMonthNF;
FixedText aDayFT;
NumericField aDayNF;
FixedText aHourFT;
NumericField aHourNF;
FixedText aMinuteFT;
NumericField aMinuteNF;
FixedText aSecondFT;
NumericField aSecondNF;
FixedText aMSecondFT;
NumericField aMSecondNF;
public:
DurationDialog_Impl( Window* pParent, const util::Duration& rDuration );
~DurationDialog_Impl();
util::Duration GetDuration() const;
};
/*-- 20.11.2009 15:40:46---------------------------------------------------
-----------------------------------------------------------------------*/
DurationDialog_Impl::DurationDialog_Impl(
Window* pParent, const util::Duration& rDuration)
: ModalDialog( pParent, SfxResId( RID_EDIT_DURATIONS ) ),
aDurationFL(this, SfxResId( FL_DURATION )),
aOKPB( this, SfxResId( PB_OK )),
aCancelPB( this, SfxResId( PB_CANCEL )),
aHelpPB( this, SfxResId( PB_HELP )),
aNegativeCB(this, SfxResId( CB_NEGATIVE )),
aYearFT( this, SfxResId( FT_YEAR )),
aYearNF( this, SfxResId( ED_YEAR )),
aMonthFT( this, SfxResId( FT_MONTH )),
aMonthNF( this, SfxResId( ED_MONTH )),
aDayFT( this, SfxResId( FT_DAY )),
aDayNF( this, SfxResId( ED_DAY )),
aHourFT( this, SfxResId( FT_HOUR )),
aHourNF( this, SfxResId( ED_HOUR )),
aMinuteFT( this, SfxResId( FT_MINUTE )),
aMinuteNF( this, SfxResId( ED_MINUTE )),
aSecondFT( this, SfxResId( FT_SECOND )),
aSecondNF( this, SfxResId( ED_SECOND )),
aMSecondFT( this, SfxResId( FT_MSECOND )),
aMSecondNF( this, SfxResId( ED_MSECOND ))
{
FreeResource();
aNegativeCB.Check(rDuration.Negative);
aYearNF.SetValue(rDuration.Years);
aMonthNF.SetValue(rDuration.Months );
aDayNF.SetValue(rDuration.Days );
aHourNF.SetValue(rDuration.Hours );
aMinuteNF.SetValue(rDuration.Minutes);
aSecondNF.SetValue(rDuration.Seconds);
aMSecondNF.SetValue(rDuration.MilliSeconds);
}
/*-- 20.11.2009 16:08:55---------------------------------------------------
-----------------------------------------------------------------------*/
DurationDialog_Impl::~DurationDialog_Impl()
{
}
/*-- 20.11.2009 15:41:47---------------------------------------------------
-----------------------------------------------------------------------*/
util::Duration DurationDialog_Impl::GetDuration() const
{
util::Duration aRet;
aRet.Negative = aNegativeCB.IsChecked();
aRet.Years = aYearNF.GetValue();
aRet.Months = aMonthNF.GetValue( );
aRet.Days = aDayNF.GetValue( );
aRet.Hours = aHourNF.GetValue( );
aRet.Minutes = aMinuteNF.GetValue();
aRet.Seconds = aSecondNF.GetValue();
aRet.MilliSeconds = aMSecondNF.GetValue();
return aRet;
}
/*-- 20.11.2009 15:30:58---------------------------------------------------
-----------------------------------------------------------------------*/
CustomPropertiesDurationField::CustomPropertiesDurationField( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
Edit( pParent, rResId ), m_pLine( pLine )
{
SetDuration( util::Duration(false, 0, 0, 0, 0, 0, 0, 0) );
}
/*-- 23.11.2009 08:46:02---------------------------------------------------
-----------------------------------------------------------------------*/
CustomPropertiesDurationField::~CustomPropertiesDurationField()
{
}
/*-- 23.11.2009 09:23:35---------------------------------------------------
-----------------------------------------------------------------------*/
void CustomPropertiesDurationField::RequestHelp( const HelpEvent& rHEvt )
{
if( rHEvt.GetMode() & HELPMODE_QUICK )
{
Size aSize( GetSizePixel() );
Rectangle aItemRect( rHEvt.GetMousePosPixel(), aSize );
if(Help::IsBalloonHelpEnabled())
Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), GetText() );
else
Help::ShowQuickHelp( this, aItemRect, GetText(),
QUICKHELP_LEFT|QUICKHELP_VCENTER );
}
}
/*-- 20.11.2009 15:30:58---------------------------------------------------
-----------------------------------------------------------------------*/
void CustomPropertiesDurationField::SetDuration( const util::Duration& rDuration )
{
m_aDuration = rDuration;
String sText(rDuration.Negative ? '-' : '+');
sText += m_pLine->m_sDurationFormat;
sText.SearchAndReplace(String::CreateFromAscii( "%1"), String::CreateFromInt32( rDuration.Years ) );
sText.SearchAndReplace(String::CreateFromAscii( "%2"), String::CreateFromInt32( rDuration.Months ) );
sText.SearchAndReplace(String::CreateFromAscii( "%3"), String::CreateFromInt32( rDuration.Days ) );
sText.SearchAndReplace(String::CreateFromAscii( "%4"), String::CreateFromInt32( rDuration.Hours ) );
sText.SearchAndReplace(String::CreateFromAscii( "%5"), String::CreateFromInt32( rDuration.Minutes) );
sText.SearchAndReplace(String::CreateFromAscii( "%6"), String::CreateFromInt32( rDuration.Seconds) );
SetText( sText );
}
/*-- 23.11.2009 08:51:15---------------------------------------------------
-----------------------------------------------------------------------*/
CustomPropertiesEditButton::CustomPropertiesEditButton( Window* pParent, const ResId& rResId, CustomPropertyLine* pLine ) :
PushButton( pParent, rResId ), m_pLine( pLine )
{
SetClickHdl( LINK( this, CustomPropertiesEditButton, ClickHdl ));
}
/*-- 23.11.2009 08:51:15---------------------------------------------------
-----------------------------------------------------------------------*/
CustomPropertiesEditButton::~CustomPropertiesEditButton()
{
}
/*-- 23.11.2009 08:47:37---------------------------------------------------
-----------------------------------------------------------------------*/
IMPL_LINK( CustomPropertiesEditButton, ClickHdl, PushButton*, EMPTYARG )
{
DurationDialog_Impl* pDurationDlg = new DurationDialog_Impl( this, m_pLine->m_aDurationField.GetDuration() );
if( RET_OK == pDurationDlg->Execute() )
m_pLine->m_aDurationField.SetDuration( pDurationDlg->GetDuration() );
delete pDurationDlg;
return 1;
}
//--------------------------------------------------------------------------
void CustomPropertiesYesNoButton::Resize()
{
const long nWidth = GetSizePixel().Width();
const long n3Width = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
const long nNewWidth = ( nWidth / 2 ) - n3Width - 2;
Size aSize = m_aYesButton.GetSizePixel();
const long nDelta = aSize.Width() - nNewWidth;
aSize.Width() = nNewWidth;
m_aYesButton.SetSizePixel( aSize );
Point aPos = m_aNoButton.GetPosPixel();
aPos.X() -= nDelta;
m_aNoButton.SetPosSizePixel( aPos, aSize );
}
// struct CustomPropertyLine ---------------------------------------------
CustomPropertyLine::CustomPropertyLine( Window* pParent ) :
m_aNameBox ( pParent, SfxResId( SFX_CB_PROPERTY_NAME ) ),
m_aTypeBox ( pParent, SfxResId( SFX_LB_PROPERTY_TYPE ), this ),
m_aValueEdit ( pParent, SfxResId( SFX_ED_PROPERTY_VALUE ), this ),
m_aDateField ( pParent, SfxResId( SFX_FLD_DATE), this),
m_aTimeField ( pParent, SfxResId( SFX_FLD_TIME), this),
m_sDurationFormat( SfxResId( SFX_ST_DURATION_FORMAT )),
m_aDurationField( pParent, SfxResId( SFX_FLD_DURATION), this),
m_aEditButton( pParent, SfxResId( SFX_PB_EDIT ), this),
m_aYesNoButton ( pParent, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
m_aRemoveButton ( pParent, SfxResId( SFX_PB_PROPERTY_REMOVE ), this ),
m_bIsRemoved ( false ),
m_bTypeLostFocus( false )
{
m_aTimeField.SetExtFormat( EXTTIMEF_24H_LONG );
m_aDateField.SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );
m_aRemoveButton.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE ), BMP_COLOR_NORMAL );
m_aRemoveButton.SetModeImage( SfxResId( SFX_IMG_PROPERTY_REMOVE_HC ), BMP_COLOR_HIGHCONTRAST );
}
void CustomPropertyLine::SetRemoved()
{
DBG_ASSERT( !m_bIsRemoved, "CustomPropertyLine::SetRemoved(): line already removed" );
m_bIsRemoved = true;
m_aNameBox.Hide();
m_aTypeBox.Hide();
m_aValueEdit.Hide();
m_aDateField.Hide();
m_aTimeField.Hide();
m_aDurationField.Hide();
m_aEditButton.Hide();
m_aYesNoButton.Hide();
m_aRemoveButton.Hide();
}
// class CustomPropertiesWindow ------------------------------------------
CustomPropertiesWindow::CustomPropertiesWindow( Window* pParent, const ResId& rResId ) :
Window( pParent, rResId ),
m_aNameBox ( this, SfxResId( SFX_CB_PROPERTY_NAME ) ),
m_aTypeBox ( this, SfxResId( SFX_LB_PROPERTY_TYPE ) ),
m_aValueEdit ( this, SfxResId( SFX_ED_PROPERTY_VALUE ) ),
m_aDateField ( this, SfxResId( SFX_FLD_DATE) ),
m_aTimeField ( this, SfxResId( SFX_FLD_TIME) ),
m_aDurationField( this, SfxResId( SFX_FLD_DURATION) ),
m_aEditButton( this, SfxResId( SFX_PB_EDIT )),
m_aYesNoButton ( this, SfxResId( SFX_WIN_PROPERTY_YESNO ) ),
m_aRemoveButton ( this, SfxResId( SFX_PB_PROPERTY_REMOVE ) ),
m_nScrollPos (0),
m_aNumberFormatter( ::comphelper::getProcessServiceFactory(),
Application::GetSettings().GetLanguage() )
{
m_aEditLoseFocusTimer.SetTimeout( 300 );
m_aEditLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, EditTimeoutHdl ) );
m_aBoxLoseFocusTimer.SetTimeout( 300 );
m_aBoxLoseFocusTimer.SetTimeoutHdl( LINK( this, CustomPropertiesWindow, BoxTimeoutHdl ) );
ResMgr* pResMgr = rResId.GetResMgr();
m_aNameBox.SetAccessibleName( String( ResId( STR_HEADER_NAME, *pResMgr ) ) );
m_aTypeBox.SetAccessibleName( String( ResId( STR_HEADER_TYPE, *pResMgr ) ) );
m_aValueEdit.SetAccessibleName( String( ResId( STR_HEADER_VALUE, *pResMgr ) ) );
}
CustomPropertiesWindow::~CustomPropertiesWindow()
{
m_aEditLoseFocusTimer.Stop();
m_aBoxLoseFocusTimer.Stop();
ClearAllLines();
}
IMPL_LINK( CustomPropertiesWindow, TypeHdl, CustomPropertiesTypeBox*, pBox )
{
sal_Int64 nType = sal_Int64( (long)pBox->GetEntryData( pBox->GetSelectEntryPos() ) );
CustomPropertyLine* pLine = pBox->GetLine();
pLine->m_aValueEdit.Show( (CUSTOM_TYPE_TEXT == nType) || (CUSTOM_TYPE_NUMBER == nType) );
pLine->m_aDateField.Show( (CUSTOM_TYPE_DATE == nType) || (CUSTOM_TYPE_DATETIME == nType) );
pLine->m_aTimeField.Show( CUSTOM_TYPE_DATETIME == nType );
pLine->m_aDurationField.Show( CUSTOM_TYPE_DURATION == nType );
pLine->m_aEditButton.Show( CUSTOM_TYPE_DURATION == nType );
pLine->m_aYesNoButton.Show( CUSTOM_TYPE_BOOLEAN == nType );
//adjust positions of date and time controls
if( nType == CUSTOM_TYPE_DATE )
{
pLine->m_aDateField.SetPosSizePixel(pLine->m_aValueEdit.GetPosPixel(), pLine->m_aValueEdit.GetSizePixel());
}
else if( nType == CUSTOM_TYPE_DATETIME)
{
const long nPosY( pLine->m_aDateField.GetPosPixel().Y() );
pLine->m_aDateField.SetPosPixel( ::Point( m_nDatePosX, nPosY ) );
pLine->m_aTimeField.SetPosPixel( ::Point( m_nTimePosX, nPosY ) );
}
return 0;
}
IMPL_LINK( CustomPropertiesWindow, RemoveHdl, CustomPropertiesRemoveButton*, pButton )
{
CustomPropertyLine* pLine = pButton->GetLine();
std::vector< CustomPropertyLine* >::iterator pFound =
std::find( m_aCustomPropertiesLines.begin(), m_aCustomPropertiesLines.end(), pLine );
if ( pFound != m_aCustomPropertiesLines.end() )
{
pLine = *pFound;
pLine->SetRemoved();
std::vector< CustomPropertyLine* >::iterator pIter = pFound + 1;
const long nDelta = GetLineHeight();
for ( ; pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
pLine = *pIter;
if ( pLine->m_bIsRemoved )
continue;
Window* pWindows[] = { &pLine->m_aNameBox,
&pLine->m_aTypeBox,
&pLine->m_aValueEdit,
&pLine->m_aDateField,
&pLine->m_aTimeField,
&pLine->m_aDurationField,
&pLine->m_aEditButton,
&pLine->m_aYesNoButton,
&pLine->m_aRemoveButton, NULL };
Window** pCurrent = pWindows;
while ( *pCurrent )
{
Point aPos = (*pCurrent)->GetPosPixel();
aPos.Y() -= nDelta;
(*pCurrent)->SetPosPixel( aPos );
pCurrent++;
}
}
}
m_aRemovedHdl.Call(0);
return 0;
}
IMPL_LINK( CustomPropertiesWindow, EditLoseFocusHdl, CustomPropertiesEdit*, pEdit )
{
if ( pEdit )
{
CustomPropertyLine* pLine = pEdit->GetLine();
if ( !pLine->m_bTypeLostFocus )
{
m_pCurrentLine = pLine;
m_aEditLoseFocusTimer.Start();
}
else
pLine->m_bTypeLostFocus = false;
}
return 0;
}
IMPL_LINK( CustomPropertiesWindow, BoxLoseFocusHdl, CustomPropertiesTypeBox*, pBox )
{
if ( pBox )
{
m_pCurrentLine = pBox->GetLine();
m_aBoxLoseFocusTimer.Start();
}
return 0;
}
IMPL_LINK( CustomPropertiesWindow, EditTimeoutHdl, Timer*, EMPTYARG )
{
ValidateLine( m_pCurrentLine, false );
return 0;
}
IMPL_LINK( CustomPropertiesWindow, BoxTimeoutHdl, Timer*, EMPTYARG )
{
ValidateLine( m_pCurrentLine, true );
return 0;
}
bool CustomPropertiesWindow::IsLineValid( CustomPropertyLine* pLine ) const
{
bool bIsValid = true;
pLine->m_bTypeLostFocus = false;
sal_Int64 nType = sal_Int64(
(long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
String sValue = pLine->m_aValueEdit.GetText();
if ( sValue.Len() == 0 )
return true;
double fDummy = 0.0;
sal_uInt32 nIndex = 0xFFFFFFFF;
if ( CUSTOM_TYPE_NUMBER == nType )
nIndex = const_cast< SvNumberFormatter& >(
m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
else if ( CUSTOM_TYPE_DATE == nType )
nIndex = const_cast< SvNumberFormatter& >(
m_aNumberFormatter).GetFormatIndex( NF_DATE_SYS_DDMMYYYY );
if ( nIndex != 0xFFFFFFFF )
{
sal_uInt32 nTemp = nIndex;
bIsValid = const_cast< SvNumberFormatter& >(
m_aNumberFormatter ).IsNumberFormat( sValue, nIndex, fDummy ) != sal_False;
if ( bIsValid && nTemp != nIndex )
// sValue is a number but the format doesn't match the index
bIsValid = false;
}
return bIsValid;
}
void CustomPropertiesWindow::ValidateLine( CustomPropertyLine* pLine, bool bIsFromTypeBox )
{
if ( !IsLineValid( pLine ) )
{
if ( bIsFromTypeBox ) // LoseFocus of TypeBox
pLine->m_bTypeLostFocus = true;
Window* pParent = GetParent()->GetParent();
if ( QueryBox( pParent, SfxResId( SFX_QB_WRONG_TYPE ) ).Execute() == RET_OK )
pLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)CUSTOM_TYPE_TEXT ) );
else
pLine->m_aValueEdit.GrabFocus();
}
}
void CustomPropertiesWindow::InitControls( HeaderBar* pHeaderBar, const ScrollBar* pScrollBar )
{
DBG_ASSERT( pHeaderBar, "CustomPropertiesWindow::InitControls(): invalid headerbar" );
DBG_ASSERT( pScrollBar, "CustomPropertiesWindow::InitControls(): invalid scrollbar" );
m_aNameBox.Hide();
m_aTypeBox.Hide();
m_aValueEdit.Hide();
m_aDateField.Hide();
m_aTimeField.Hide();
m_aDurationField.Hide();
m_aEditButton.Hide();
m_aYesNoButton.Hide();
m_aRemoveButton.Hide();
const long nOffset = 4;
const long nScrollBarWidth = pScrollBar->GetSizePixel().Width();
const long nButtonWidth = m_aRemoveButton.GetSizePixel().Width() + nScrollBarWidth + nOffset;
long nTypeWidth = m_aTypeBox.CalcMinimumSize().Width() + ( 2 * nOffset );
long nFullWidth = pHeaderBar->GetSizePixel().Width();
long nItemWidth = ( nFullWidth - nTypeWidth - nButtonWidth ) / 2;
pHeaderBar->SetItemSize( HI_NAME, nItemWidth );
pHeaderBar->SetItemSize( HI_TYPE, nTypeWidth );
pHeaderBar->SetItemSize( HI_VALUE, nItemWidth );
pHeaderBar->SetItemSize( HI_ACTION, nButtonWidth );
Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, &m_aRemoveButton, NULL };
Window** pCurrent = pWindows;
sal_uInt16 nPos = 0;
while ( *pCurrent )
{
Rectangle aRect = pHeaderBar->GetItemRect( pHeaderBar->GetItemId( nPos++ ) );
Size aSize = (*pCurrent)->GetSizePixel();
Point aPos = (*pCurrent)->GetPosPixel();
long nWidth = aRect.getWidth() - nOffset;
if ( *pCurrent == &m_aRemoveButton )
nWidth -= pScrollBar->GetSizePixel().Width();
aSize.Width() = nWidth;
aPos.X() = aRect.getX() + ( nOffset / 2 );
(*pCurrent)->SetPosSizePixel( aPos, aSize );
if ( *pCurrent == &m_aValueEdit )
{
Point aDurationPos( aPos );
m_aDurationField.SetPosPixel( aDurationPos );
Size aDurationSize(aSize);
aDurationSize.Width() -= (m_aEditButton.GetSizePixel().Width() + 3 );
m_aDurationField.SetSizePixel(aDurationSize);
aDurationPos.X() = aPos.X() - m_aEditButton.GetSizePixel().Width() + aSize.Width();
m_aEditButton.SetPosPixel(aDurationPos);
aSize = m_aYesNoButton.GetSizePixel();
aPos = m_aYesNoButton.GetPosPixel();
aSize.Width() = nWidth;
aPos.X() = aRect.getX() + ( nOffset / 2 );
m_aYesNoButton.SetPosSizePixel( aPos, aSize );
aSize.Width() /= 2;
aSize.Width() -= 2;
m_aDateField.SetPosSizePixel( aPos, aSize );
aPos.X() += aSize.Width() + 4;
m_aTimeField.SetPosSizePixel( aPos, aSize );
}
pCurrent++;
}
m_nLineHeight =
( m_aRemoveButton.GetPosPixel().Y() * 2 ) + m_aRemoveButton.GetSizePixel().Height();
m_nDatePosX = m_aDateField.GetPosPixel().X();
m_nTimePosX = m_aTimeField.GetPosPixel().X();
}
sal_uInt16 CustomPropertiesWindow::GetVisibleLineCount() const
{
sal_uInt16 nCount = 0;
std::vector< CustomPropertyLine* >::const_iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
CustomPropertyLine* pLine = *pIter;
if ( !pLine->m_bIsRemoved )
nCount++;
}
return nCount;
}
void CustomPropertiesWindow::AddLine( const ::rtl::OUString& sName, Any& rAny )
{
CustomPropertyLine* pNewLine = new CustomPropertyLine( this );
pNewLine->m_aTypeBox.SetSelectHdl( LINK( this, CustomPropertiesWindow, TypeHdl ) );
pNewLine->m_aRemoveButton.SetClickHdl( LINK( this, CustomPropertiesWindow, RemoveHdl ) );
pNewLine->m_aValueEdit.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, EditLoseFocusHdl ) );
//add lose focus handlers of date/time fields
pNewLine->m_aTypeBox.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) );
pNewLine->m_aNameBox.SetAccessibleName(m_aNameBox.GetAccessibleName());
pNewLine->m_aTypeBox.SetAccessibleName(m_aTypeBox.GetAccessibleName());
pNewLine->m_aValueEdit.SetAccessibleName(m_aValueEdit.GetAccessibleName());
long nPos = GetVisibleLineCount() * GetLineHeight();
m_aCustomPropertiesLines.push_back( pNewLine );
Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit,
&m_aDateField, &m_aTimeField,
&m_aDurationField, &m_aEditButton,
&m_aYesNoButton, &m_aRemoveButton, NULL };
Window* pNewWindows[] =
{ &pNewLine->m_aNameBox, &pNewLine->m_aTypeBox, &pNewLine->m_aValueEdit,
&pNewLine->m_aDateField, &pNewLine->m_aTimeField,
&pNewLine->m_aDurationField, &pNewLine->m_aEditButton,
&pNewLine->m_aYesNoButton, &pNewLine->m_aRemoveButton, NULL };
Window** pCurrent = pWindows;
Window** pNewCurrent = pNewWindows;
while ( *pCurrent )
{
Size aSize = (*pCurrent)->GetSizePixel();
Point aPos = (*pCurrent)->GetPosPixel();
aPos.Y() += nPos;
aPos.Y() += m_nScrollPos;
(*pNewCurrent)->SetPosSizePixel( aPos, aSize );
(*pNewCurrent)->Show();
pCurrent++;
pNewCurrent++;
}
double nTmpValue = 0;
bool bTmpValue = false;
::rtl::OUString sTmpValue;
util::DateTime aTmpDateTime;
util::Date aTmpDate;
util::Duration aTmpDuration;
SvtSysLocale aSysLocale;
const LocaleDataWrapper& rLocaleWrapper = aSysLocale.GetLocaleData();
pNewLine->m_aNameBox.SetText( sName );
sal_Int32 nType = CUSTOM_TYPE_UNKNOWN;
String sValue;
if ( rAny >>= nTmpValue )
{
sal_uInt32 nIndex = m_aNumberFormatter.GetFormatIndex( NF_NUMBER_SYSTEM );
m_aNumberFormatter.GetInputLineString( nTmpValue, nIndex, sValue );
pNewLine->m_aValueEdit.SetText( sValue );
nType = CUSTOM_TYPE_NUMBER;
}
else if ( rAny >>= bTmpValue )
{
sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() );
nType = CUSTOM_TYPE_BOOLEAN;
}
else if ( rAny >>= sTmpValue )
{
pNewLine->m_aValueEdit.SetText( sTmpValue );
nType = CUSTOM_TYPE_TEXT;
}
else if ( rAny >>= aTmpDate )
{
nType = CUSTOM_TYPE_DATE;
pNewLine->m_aDateField.SetDate( Date( aTmpDate.Day, aTmpDate.Month, aTmpDate.Year ) );
}
else if ( rAny >>= aTmpDuration )
{
nType = CUSTOM_TYPE_DURATION;
pNewLine->m_aDurationField.SetDuration( aTmpDuration );
}
else if ( rAny >>= aTmpDateTime )
{
pNewLine->m_aDateField.SetDate( Date( aTmpDateTime.Day, aTmpDateTime.Month, aTmpDateTime.Year ) );
pNewLine->m_aTimeField.SetTime( Time( aTmpDateTime.Hours, aTmpDateTime.Minutes, aTmpDateTime.Seconds, aTmpDateTime.HundredthSeconds ) );
nType = CUSTOM_TYPE_DATETIME;
}
if ( nType != CUSTOM_TYPE_UNKNOWN )
{
if ( CUSTOM_TYPE_BOOLEAN == nType )
{
if ( bTmpValue )
pNewLine->m_aYesNoButton.CheckYes();
else
pNewLine->m_aYesNoButton.CheckNo();
}
pNewLine->m_aTypeBox.SelectEntryPos( m_aTypeBox.GetEntryPos( (void*)nType ) );
}
TypeHdl( &pNewLine->m_aTypeBox );
pNewLine->m_aNameBox.GrabFocus();
}
bool CustomPropertiesWindow::AreAllLinesValid() const
{
bool bRet = true;
std::vector< CustomPropertyLine* >::const_iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
CustomPropertyLine* pLine = *pIter;
if ( !IsLineValid( pLine ) )
{
bRet = false;
break;
}
}
return bRet;
}
void CustomPropertiesWindow::ClearAllLines()
{
std::vector< CustomPropertyLine* >::iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
CustomPropertyLine* pLine = *pIter;
pLine->SetRemoved();
delete pLine;
}
m_aCustomPropertiesLines.clear();
m_nScrollPos = 0;
}
void CustomPropertiesWindow::DoScroll( sal_Int32 nNewPos )
{
m_nScrollPos += nNewPos;
std::vector< CustomPropertyLine* >::iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
CustomPropertyLine* pLine = *pIter;
if ( pLine->m_bIsRemoved )
continue;
Window* pWindows[] = { &pLine->m_aNameBox,
&pLine->m_aTypeBox,
&pLine->m_aValueEdit,
&pLine->m_aDurationField,
&pLine->m_aEditButton,
&pLine->m_aDateField,
&pLine->m_aTimeField,
&pLine->m_aYesNoButton,
&pLine->m_aRemoveButton, NULL };
Window** pCurrent = pWindows;
while ( *pCurrent )
{
Point aPos = (*pCurrent)->GetPosPixel();
aPos.Y() += nNewPos;
(*pCurrent)->SetPosPixel( aPos );
pCurrent++;
}
}
}
bool CustomPropertiesWindow::DoesCustomPropertyExist( const String& rName ) const
{
bool bRet = false;
std::vector< CustomPropertyLine* >::const_iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter )
{
CustomPropertyLine* pLine = *pIter;
if ( !pLine->m_bIsRemoved && pLine->m_aNameBox.GetText() == rName )
{
bRet = true;
break;
}
}
return bRet;
}
Sequence< beans::PropertyValue > CustomPropertiesWindow::GetCustomProperties() const
{
Sequence< beans::PropertyValue > aPropertiesSeq( m_aCustomPropertiesLines.size() );
sal_Int32 i = 0;
std::vector< CustomPropertyLine* >::const_iterator pIter;
for ( pIter = m_aCustomPropertiesLines.begin();
pIter != m_aCustomPropertiesLines.end(); ++pIter, ++i )
{
CustomPropertyLine* pLine = *pIter;
if ( pLine->m_bIsRemoved )
continue;
String sPropertyName = pLine->m_aNameBox.GetText();
if ( sPropertyName.Len() > 0 )
{
aPropertiesSeq[i].Name = sPropertyName;
sal_Int64 nType = sal_Int64(
(long)pLine->m_aTypeBox.GetEntryData( pLine->m_aTypeBox.GetSelectEntryPos() ) );
if ( CUSTOM_TYPE_NUMBER == nType )
{
double nValue = 0;
sal_uInt32 nIndex = const_cast< SvNumberFormatter& >(
m_aNumberFormatter ).GetFormatIndex( NF_NUMBER_SYSTEM );
sal_Bool bIsNum = const_cast< SvNumberFormatter& >( m_aNumberFormatter ).
IsNumberFormat( pLine->m_aValueEdit.GetText(), nIndex, nValue );
if ( bIsNum )
aPropertiesSeq[i].Value <<= makeAny( nValue );
}
else if ( CUSTOM_TYPE_BOOLEAN == nType )
{
bool bValue = pLine->m_aYesNoButton.IsYesChecked();
aPropertiesSeq[i].Value <<= makeAny( bValue );
}
else if ( CUSTOM_TYPE_DATETIME == nType )
{
Date aTmpDate = pLine->m_aDateField.GetDate();
Time aTmpTime = pLine->m_aTimeField.GetTime();
util::DateTime aDateTime(aTmpTime.Get100Sec(), aTmpTime.GetSec(), aTmpTime.GetMin(), aTmpTime.GetHour(),
aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear() );
aPropertiesSeq[i].Value <<= aDateTime;
}
else if ( CUSTOM_TYPE_DURATION == nType )
{
aPropertiesSeq[i].Value <<= pLine->m_aDurationField.GetDuration();
}
else if ( CUSTOM_TYPE_DATE == nType )
{
Date aTmpDate = pLine->m_aDateField.GetDate();
util::Date aDate(aTmpDate.GetDay(), aTmpDate.GetMonth(), aTmpDate.GetYear());
aPropertiesSeq[i].Value <<= aDate;
}
else
{
::rtl::OUString sValue( pLine->m_aValueEdit.GetText() );
aPropertiesSeq[i].Value <<= makeAny( sValue );
}
}
}
return aPropertiesSeq;
}
// class CustomPropertiesControl -----------------------------------------
CustomPropertiesControl::CustomPropertiesControl( Window* pParent, const ResId& rResId ) :
Control( pParent, rResId ),
m_aHeaderBar ( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER ),
m_aPropertiesWin( this, ResId( WIN_PROPERTIES, *rResId.GetResMgr() ) ),
m_aVertScroll ( this, ResId( SB_VERTICAL, *rResId.GetResMgr() ) ),
m_bIsInitialized( false ),
m_nThumbPos ( 0 )
{
m_aPropertiesWin.SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
m_aVertScroll.EnableDrag();
m_aVertScroll.Show();
long nWidth = GetOutputSizePixel().Width();
m_aHeaderBar.SetPosSizePixel( Point(), Size( nWidth, m_aVertScroll.GetPosPixel().Y() ) );
const HeaderBarItemBits nHeadBits = HIB_VCENTER | HIB_FIXED | HIB_FIXEDPOS | HIB_LEFT;
nWidth = nWidth / 4;
ResMgr* pResMgr = rResId.GetResMgr();
m_aHeaderBar.InsertItem( HI_NAME, String( ResId( STR_HEADER_NAME, *pResMgr ) ), nWidth, nHeadBits );
m_aHeaderBar.InsertItem( HI_TYPE, String( ResId( STR_HEADER_TYPE, *pResMgr ) ), nWidth, nHeadBits );
m_aHeaderBar.InsertItem( HI_VALUE, String( ResId( STR_HEADER_VALUE, *pResMgr ) ), nWidth, nHeadBits );
m_aHeaderBar.InsertItem( HI_ACTION, String( ResId( STR_HEADER_ACTION, *pResMgr ) ), nWidth, nHeadBits );
m_aHeaderBar.Show();
FreeResource();
XubString sTEST = m_aHeaderBar.GetItemText( HI_NAME );
m_aPropertiesWin.InitControls( &m_aHeaderBar, &m_aVertScroll );
m_aPropertiesWin.SetRemovedHdl( LINK( this, CustomPropertiesControl, RemovedHdl ) );
m_aVertScroll.SetRangeMin( 0 );
sal_Int32 nScrollOffset = m_aPropertiesWin.GetLineHeight();
sal_Int32 nVisibleEntries = m_aPropertiesWin.GetSizePixel().Height() / nScrollOffset;
m_aVertScroll.SetRangeMax( nVisibleEntries );
m_aVertScroll.SetPageSize( nVisibleEntries - 1 );
m_aVertScroll.SetVisibleSize( nVisibleEntries );
Point aPos = m_aHeaderBar.GetPosPixel();
Size aSize = m_aHeaderBar.GetSizePixel();
aPos = m_aVertScroll.GetPosPixel();
aSize = m_aVertScroll.GetSizePixel();
Link aScrollLink = LINK( this, CustomPropertiesControl, ScrollHdl );
m_aVertScroll.SetScrollHdl( aScrollLink );
// m_aVertScroll.SetEndScrollHdl( aScrollLink );
}
CustomPropertiesControl::~CustomPropertiesControl()
{
}
void CustomPropertiesControl::Initialize()
{
}
IMPL_LINK( CustomPropertiesControl, ScrollHdl, ScrollBar*, pScrollBar )
{
sal_Int32 nOffset = m_aPropertiesWin.GetLineHeight();
nOffset *= ( m_nThumbPos - pScrollBar->GetThumbPos() );
m_nThumbPos = pScrollBar->GetThumbPos();
m_aPropertiesWin.DoScroll( nOffset );
return 0;
}
IMPL_LINK( CustomPropertiesControl, RemovedHdl, void*, EMPTYARG )
{
m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
if ( m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
m_aVertScroll.DoScrollAction ( SCROLL_LINEUP );
return 0;
}
void CustomPropertiesControl::AddLine( const ::rtl::OUString& sName, Any& rAny, bool bInteractive )
{
m_aPropertiesWin.AddLine( sName, rAny );
m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 );
if ( bInteractive && m_aPropertiesWin.GetOutputSizePixel().Height() < m_aPropertiesWin.GetVisibleLineCount() * m_aPropertiesWin.GetLineHeight() )
m_aVertScroll.DoScroll( m_aPropertiesWin.GetVisibleLineCount() + 1 );
}
// class SfxCustomPropertiesPage -----------------------------------------
SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window* pParent, const SfxItemSet& rItemSet ) :
SfxTabPage( pParent, SfxResId( TP_CUSTOMPROPERTIES ), rItemSet ),
m_aPropertiesCtrl ( this, SfxResId( CTRL_PROPERTIES ) ),
m_aAddBtn ( this, SfxResId( BTN_ADD ) ),
m_aPropertiesFT ( this, SfxResId( FT_PROPERTIES ) )
{
FreeResource();
m_aAddBtn.SetClickHdl( LINK( this, SfxCustomPropertiesPage, AddHdl ) );
}
IMPL_LINK( SfxCustomPropertiesPage, AddHdl, PushButton*, EMPTYARG )
{
Any aAny;
m_aPropertiesCtrl.AddLine( ::rtl::OUString(), aAny, true );
return 0;
}
sal_Bool SfxCustomPropertiesPage::FillItemSet( SfxItemSet& rSet )
{
sal_Bool bModified = sal_False;
const SfxPoolItem* pItem = NULL;
SfxDocumentInfoItem* pInfo = NULL;
bool bMustDelete = false;
if ( GetTabDialog() && GetTabDialog()->GetExampleSet() )
{
if( SFX_ITEM_SET !=
GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, sal_True, &pItem ) )
pInfo = &( SfxDocumentInfoItem& )rSet.Get( SID_DOCINFO );
else
{
bMustDelete = true;
pInfo = new SfxDocumentInfoItem( *( const SfxDocumentInfoItem* ) pItem );
}
}
if ( pInfo )
{
pInfo->ClearCustomProperties();
Sequence< beans::PropertyValue > aPropertySeq = m_aPropertiesCtrl.GetCustomProperties();
sal_Int32 i = 0, nCount = aPropertySeq.getLength();
for ( ; i < nCount; ++i )
{
if ( aPropertySeq[i].Name.getLength() > 0 )
pInfo->AddCustomProperty( aPropertySeq[i].Name, aPropertySeq[i].Value );
}
}
bModified = sal_True; //!!!
if ( bModified )
rSet.Put( *pInfo );
if ( bMustDelete )
delete pInfo;
return bModified;
}
void SfxCustomPropertiesPage::Reset( const SfxItemSet& rItemSet )
{
m_aPropertiesCtrl.ClearAllLines();
const SfxDocumentInfoItem* pInfoItem = &(const SfxDocumentInfoItem &)rItemSet.Get(SID_DOCINFO);
std::vector< CustomProperty* > aCustomProps = pInfoItem->GetCustomProperties();
for ( sal_uInt32 i = 0; i < aCustomProps.size(); i++ )
{
m_aPropertiesCtrl.AddLine( aCustomProps[i]->m_sName, aCustomProps[i]->m_aValue, false );
}
}
int SfxCustomPropertiesPage::DeactivatePage( SfxItemSet* /*pSet*/ )
{
int nRet = LEAVE_PAGE;
if ( !m_aPropertiesCtrl.AreAllLinesValid() )
nRet = KEEP_PAGE;
return nRet;
}
SfxTabPage* SfxCustomPropertiesPage::Create( Window* pParent, const SfxItemSet& rItemSet )
{
return new SfxCustomPropertiesPage( pParent, rItemSet );
}