/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: dinfdlg.cxx,v $ * $Revision: 1.46 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sfx2.hxx" #include #include #include #include #include #include #ifndef _UNOTOOLS_PROCESSFACTORY_HXX #include #endif #include #include #include #include #include #include #include #ifndef _COM_SUN_STAR_SECURITY_DOCUMENTSIGNATURESINFORMATION_HPP_ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "sfxresid.hxx" #include "dinfedt.hxx" #include #include #include //#include "exptypes.hxx" #include "helper.hxx" #include #include #include #include #include "dinfdlg.hrc" #include "sfxlocal.hrc" #include using namespace ::com::sun::star; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::ui::dialogs; using namespace ::com::sun::star::uno; // The number of user defined fields handled by the dialog // There are exactly 4. No more, no less. #define FOUR 4 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 USHORT HI_NAME = 1; const USHORT HI_TYPE = 2; const USHORT HI_VALUE = 3; const USHORT HI_ACTION = 4; //------------------------------------------------------------------------ String CreateSizeText( ULONG nSize, BOOL bExtraBytes = TRUE, BOOL bSmartExtraBytes = FALSE ); String CreateSizeText( ULONG nSize, BOOL bExtraBytes, BOOL bSmartExtraBytes ) { String aUnitStr = ' '; aUnitStr += String( SfxResId(STR_BYTES) ); ULONG nSize1 = nSize; ULONG nSize2 = nSize1; ULONG nMega = 1024 * 1024; ULONG nGiga = nMega * 1024; double fSize = nSize; int nDec = 0; BOOL bGB = 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 = TRUE; fSize /= nGiga; nDec = 3; } const LocaleDataWrapper& rLocaleWrapper = SvtSysLocale().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, TRUE, 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() , bHasTemplate( sal_True ) , bDeleteUserData( sal_False ) , bIsUseUserData( sal_True ) { } //------------------------------------------------------------------------ SfxDocumentInfoItem::SfxDocumentInfoItem( const String& rFile, const uno::Reference& i_xDocProps, const uno::Reference& i_xDocInfo, 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() ) , bHasTemplate( TRUE ) , bDeleteUserData( sal_False ) , bIsUseUserData( bIs ) { for (sal_Int16 i = 0; i < FOUR; ++i) { m_UserDefinedFieldTitles[i] = i_xDocInfo->getUserFieldName(i); m_UserDefinedFieldValues[i] = i_xDocInfo->getUserFieldValue(i); } 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) ) 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() ) , bHasTemplate( rItem.bHasTemplate ) , bDeleteUserData( rItem.bDeleteUserData ) , bIsUseUserData( rItem.bIsUseUserData ) { for (size_t i = 0; i < FOUR; ++i) { m_UserDefinedFieldTitles[i] = rItem.getUserDefinedFieldTitle(i); m_UserDefinedFieldValues[i] = rItem.getUserDefinedFieldValue(i); } 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(rItem)); bool bEqual = m_aCustomProperties.size() == rInfoItem.m_aCustomProperties.size(); if ( bEqual ) { for ( sal_uInt32 i = 0; i < m_aCustomProperties.size(); i++ ) { bEqual = *m_aCustomProperties[i] == *rInfoItem.m_aCustomProperties[i]; if ( !bEqual ) break; } } return bEqual != false && 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 && std::equal(m_UserDefinedFieldTitles, m_UserDefinedFieldTitles+FOUR, rInfoItem.m_UserDefinedFieldTitles) && std::equal(m_UserDefinedFieldValues, m_UserDefinedFieldValues+FOUR, rInfoItem.m_UserDefinedFieldValues); } //------------------------------------------------------------------------ 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& i_xDocProps, const uno::Reference& i_xDocInfo) 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()); for ( sal_Int16 i = 0; i < FOUR; ++i ) { i_xDocInfo->setUserFieldName(i, getUserDefinedFieldTitle(i)); i_xDocInfo->setUserFieldValue(i, getUserDefinedFieldValue(i)); } 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 ) 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" ); } } //------------------------------------------------------------------------ BOOL SfxDocumentInfoItem::IsDeleteUserData() const { return bDeleteUserData; } void SfxDocumentInfoItem::SetDeleteUserData( BOOL bSet ) { bDeleteUserData = bSet; } BOOL SfxDocumentInfoItem::IsUseUserData() const { return bIsUseUserData; } void SfxDocumentInfoItem::SetUseUserData( BOOL bSet ) { bIsUseUserData = 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 ); } ::rtl::OUString SfxDocumentInfoItem::getUserDefinedFieldTitle(size_t i_ix) const { DBG_ASSERT(i_ix < FOUR, "SfxDocumentInfoItem: invalid index"); return m_UserDefinedFieldTitles[i_ix]; } ::rtl::OUString SfxDocumentInfoItem::getUserDefinedFieldValue(size_t i_ix) const { DBG_ASSERT(i_ix < FOUR, "SfxDocumentInfoItem: invalid index"); return m_UserDefinedFieldValues[i_ix]; } void SfxDocumentInfoItem::setUserDefinedFieldTitle(size_t i_ix, ::rtl::OUString i_val) { DBG_ASSERT(i_ix < FOUR, "SfxDocumentInfoItem: invalid index"); m_UserDefinedFieldTitles[i_ix] = i_val; } void SfxDocumentInfoItem::setUserDefinedFieldValue(size_t i_ix, ::rtl::OUString i_val) { DBG_ASSERT(i_ix < FOUR, "SfxDocumentInfoItem: invalid index"); m_UserDefinedFieldValues[i_ix] = i_val; } sal_Bool SfxDocumentInfoItem::QueryValue( Any& rVal, BYTE nMemberId ) const { String aValue; sal_Int32 nValue = 0; sal_Bool bValue = sal_False; BOOL bField = FALSE; BOOL bIsInt = FALSE; BOOL bIsString = 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 = TRUE; nValue = getAutoloadDelay(); break; case MID_DOCINFO_AUTOLOADURL: bIsString = TRUE; aValue = getAutoloadURL(); break; case MID_DOCINFO_DEFAULTTARGET: bIsString = TRUE; aValue = getDefaultTarget(); break; case MID_DOCINFO_DESCRIPTION: bIsString = TRUE; aValue = getDescription(); break; case MID_DOCINFO_KEYWORDS: bIsString = TRUE; aValue = getKeywords(); break; case MID_DOCINFO_SUBJECT: bIsString = TRUE; aValue = getSubject(); break; case MID_DOCINFO_TITLE: bIsString = TRUE; aValue = getTitle(); break; case MID_DOCINFO_FIELD1: case MID_DOCINFO_FIELD2: case MID_DOCINFO_FIELD3: case MID_DOCINFO_FIELD4: bField = TRUE; // no break here case MID_DOCINFO_FIELD1TITLE: case MID_DOCINFO_FIELD2TITLE: case MID_DOCINFO_FIELD3TITLE: case MID_DOCINFO_FIELD4TITLE: { bIsString = TRUE; USHORT nSub = MID_DOCINFO_FIELD1TITLE; if ( bField ) { nSub = MID_DOCINFO_FIELD1; } if ( bField ) { DBG_ASSERT( nMemberId == MID_DOCINFO_FIELD1 || nMemberId == MID_DOCINFO_FIELD2 || nMemberId == MID_DOCINFO_FIELD3 || nMemberId == MID_DOCINFO_FIELD4, "SfxDocumentInfoItem:Anpassungsfehler" ); aValue = getUserDefinedFieldValue( nMemberId - nSub ); } else { DBG_ASSERT( nMemberId == MID_DOCINFO_FIELD1TITLE || nMemberId == MID_DOCINFO_FIELD2TITLE || nMemberId == MID_DOCINFO_FIELD3TITLE || nMemberId == MID_DOCINFO_FIELD4TITLE, "SfxDocumentInfoItem:Anpassungsfehler" ); aValue = getUserDefinedFieldTitle( nMemberId - nSub ); } 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, BYTE 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; case MID_DOCINFO_FIELD1TITLE: case MID_DOCINFO_FIELD2TITLE: case MID_DOCINFO_FIELD3TITLE: case MID_DOCINFO_FIELD4TITLE: { bRet = (rVal >>= aValue); if ( bRet ) setUserDefinedFieldTitle( nMemberId - MID_DOCINFO_FIELD1TITLE, String(aValue)); break; } case MID_DOCINFO_FIELD1: case MID_DOCINFO_FIELD2: case MID_DOCINFO_FIELD3: case MID_DOCINFO_FIELD4: { bRet = (rVal >>= aValue); if ( bRet ) setUserDefinedFieldValue( nMemberId - MID_DOCINFO_FIELD1, String(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); } //------------------------------------------------------------------------ BOOL SfxDocumentDescPage::FillItemSet(SfxItemSet &rSet) { // Pruefung, ob eine Aenderung vorliegt const BOOL bTitleMod = aTitleEd.IsModified(); const BOOL bThemeMod = aThemaEd.IsModified(); const BOOL bKeywordsMod = aKeywordsEd.IsModified(); const BOOL bCommentMod = aCommentEd.IsModified(); if( !( bTitleMod || bThemeMod || bKeywordsMod || bCommentMod ) ) { return 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, TRUE, &pItem ) ) pInfo = pInfoItem; else if ( pItem ) pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem *)pItem ); if ( !pInfo ) { DBG_ERRORFILE( "SfxDocumentDescPage::FillItemSet(): no item found" ); return 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 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, FALSE ); if ( pROItem && pROItem->GetValue() ) { aTitleEd.SetReadOnly( TRUE ); aThemaEd.SetReadOnly( TRUE ); aKeywordsEd.SetReadOnly( TRUE ); aCommentEd.SetReadOnly( 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 ( FALSE ), bHandleDelete ( FALSE ) { 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 ); } } //------------------------------------------------------------------------ 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 = 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->GetLastCommitReadStorage_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 = TRUE; aUseUserDataCB.Show(); aDeleteBtn.Show(); } //------------------------------------------------------------------------ BOOL SfxDocumentPage::FillItemSet( SfxItemSet& rSet ) { BOOL bRet = 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, TRUE, &pItem ) ) { SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem; 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 = TRUE; } } if ( bHandleDelete ) { const SfxItemSet* pExpSet = GetTabDialog()->GetExampleSet(); const SfxPoolItem* pItem; if ( pExpSet && SFX_ITEM_SET == pExpSet->GetItemState( SID_DOCINFO, TRUE, &pItem ) ) { SfxDocumentInfoItem* pInfoItem = (SfxDocumentInfoItem*)pItem; BOOL bUseAuthor = bEnableUseUserData && aUseUserDataCB.IsChecked(); SfxDocumentInfoItem newItem( *pInfoItem ); newItem.resetUserData( bUseAuthor ? SvtUserOptions().GetFullName() : String() ); pInfoItem->SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() ); newItem.SetUseUserData( STATE_CHECK == aUseUserDataCB.GetState() ); newItem.SetDeleteUserData( TRUE ); rSet.Put( newItem ); bRet = TRUE; } } if ( aNameED.IsModified() && aNameED.GetText().Len() ) { rSet.Put( SfxStringItem( ID_FILETP_TITLE, aNameED.GetText() ) ); bRet = TRUE; } if ( /* aReadOnlyCB.IsModified() */ TRUE ) { rSet.Put( SfxBoolItem( ID_FILETP_READONLY, aReadOnlyCB.IsChecked() ) ); bRet = 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) == '[' ) { USHORT 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, 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( TRUE ); } else { DBG_ASSERT( pItem->IsA( TYPE( SfxStringItem ) ), "SfxDocumentPage: erwartet" ); aName = ( ( SfxStringItem* ) pItem )->GetValue(); } aNameED.SetText( aName ); aNameED.ClearModifyFlag(); // determine RO-Flag if ( SFX_ITEM_UNKNOWN == rSet.GetItemState( ID_FILETP_READONLY, 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, 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 BOOL bIsUseUserData = 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( bIsUseUserData ) { const Time aT( nTime/3600, (nTime%3600)/60, nTime%60 ); aTimeLogValFt.SetText( aLocaleWrapper.getDuration( aT ) ); aDocNoValFt.SetText( String::CreateFromInt32( pInfoItem->getEditingCycles() ) ); } TriState eState = (TriState)bIsUseUserData; if ( STATE_DONTKNOW == eState ) aUseUserDataCB.EnableTriState( TRUE ); aUseUserDataCB.SetState( eState ); aUseUserDataCB.SaveValue(); aUseUserDataCB.Enable( bEnableUseUserData ); bHandleDelete = 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( USHORT nPos = ( USHORT ) 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( TRUE ); EnableReload( FALSE ); EnableForward( FALSE ); break; case S_NoUpdate: EnableNoUpdate( FALSE ); if( eNewState == S_Reload ) EnableReload( TRUE ); else EnableForward( TRUE ); break; case S_Reload: EnableReload( FALSE ); if( eNewState == S_NoUpdate ) EnableNoUpdate( TRUE ); else EnableForward( TRUE ); break; case S_Forward: EnableForward( FALSE ); if( eNewState == S_NoUpdate ) EnableNoUpdate( TRUE ); else EnableReload( TRUE ); break; default: DBG_ERROR( "*SfxInternetPage::SetState(): unhandled state!" ); } eState = eNewState; } //------------------------------------------------------------------------ void SfxInternetPage::EnableNoUpdate( BOOL bEnable ) { if( bEnable ) aRBNoAutoUpdate.Check(); } //------------------------------------------------------------------------ void SfxInternetPage::EnableReload( BOOL bEnable ) { aFTEvery.Enable( bEnable ); aNFReload.Enable( bEnable ); aFTReloadSeconds.Enable( bEnable ); if( bEnable ) aRBReloadUpdate.Check(); } //------------------------------------------------------------------------ void SfxInternetPage::EnableForward( 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; } //------------------------------------------------------------------------ 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, TRUE, &pItem ) ) pInfo = pInfoItem; else if ( pItem ) pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem*)pItem ); if ( !pInfo ) { DBG_ERRORFILE( "SfxInternetPage::FillItemSet(): no item found" ); return FALSE; } DBG_ASSERT( eState != S_Init, "*SfxInternetPage::FillItemSet(): state init is not acceptable at this point!" ); BOOL bEnableReload = FALSE; ::std::auto_ptr< String > aURL( NULL ); ::std::auto_ptr< String > aFrame( NULL ); ULONG nDelay = 0; switch( eState ) { case S_NoUpdate: break; case S_Reload: bEnableReload = TRUE; aURL = ::std::auto_ptr< String >( new String() ); aFrame = ::std::auto_ptr< String >( new String() ); nDelay = static_cast(aNFReload.GetValue()); break; case S_Forward: DBG_ASSERT( aEDForwardURL.GetText().Len(), "+SfxInternetPage::FillItemSet(): empty URL should be not possible for forward option!" ); bEnableReload = 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(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 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, 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, 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; } //------------------------------------------------------------------------ SfxDocumentUserPage::SfxDocumentUserPage( Window* pParent, const SfxItemSet& rItemSet ) : SfxTabPage( pParent, SfxResId( TP_DOCINFOUSER ), rItemSet ), bLabelModified ( FALSE ), aInfo1Ft ( this, SfxResId( FT_INFO1 ) ), aInfo1Ed ( this, SfxResId( ED_INFO1 ) ), aInfo2Ft ( this, SfxResId( FT_INFO2 ) ), aInfo2Ed ( this, SfxResId( ED_INFO2 ) ), aInfo3Ft ( this, SfxResId( FT_INFO3 ) ), aInfo3Ed ( this, SfxResId( ED_INFO3 ) ), aInfo4Ft ( this, SfxResId( FT_INFO4 ) ), aInfo4Ed ( this, SfxResId( ED_INFO4 ) ), aEditLabelBtn ( this, SfxResId( BTN_EDITLABEL ) ), pInfoItem ( NULL ) { FreeResource(); //increase button width in case of long labels Size aButtonSize = aEditLabelBtn.GetOutputSizePixel(); sal_Int32 nTextWidth = aEditLabelBtn.GetTextWidth(aEditLabelBtn.GetText()); //add some additional space sal_Int32 nDiff = nTextWidth + 4 - aButtonSize.Width(); if( nDiff > 0) { Point aPos(aEditLabelBtn.GetPosPixel()); aPos.X() -= nDiff; aButtonSize.Width() += nDiff; aEditLabelBtn.SetPosSizePixel(aPos, aButtonSize); } aEditLabelBtn.SetClickHdl( LINK( this, SfxDocumentUserPage, EditLabelHdl ) ); } //------------------------------------------------------------------------ IMPL_LINK( SfxDocumentUserPage, EditLabelHdl, PushButton *, pPushButton ) { (void)pPushButton; //unused SfxDocInfoEditDlg* pDlg = new SfxDocInfoEditDlg( this ); pDlg->SetText1( GetLabelText_Impl( &aInfo1Ft ) ); pDlg->SetText2( GetLabelText_Impl( &aInfo2Ft ) ); pDlg->SetText3( GetLabelText_Impl( &aInfo3Ft ) ); pDlg->SetText4( GetLabelText_Impl( &aInfo4Ft ) ); if ( RET_OK == pDlg->Execute() ) { SetLabelText_Impl( &aInfo1Ft, pDlg->GetText1() ); SetLabelText_Impl( &aInfo2Ft, pDlg->GetText2() ); SetLabelText_Impl( &aInfo3Ft, pDlg->GetText3() ); SetLabelText_Impl( &aInfo4Ft, pDlg->GetText4() ); bLabelModified = TRUE; } delete pDlg; return 0; } //------------------------------------------------------------------------ String SfxDocumentUserPage::GetLabelText_Impl( FixedText* pLabel ) { DBG_ASSERT( pLabel, "SfxDocumentUserPage::SetLabelText_Impl(): invalid label" ); String aLabel = pLabel->GetText(); aLabel.Erase( 0, aLabel.Search( ' ' ) + 1 ); return aLabel; } //------------------------------------------------------------------------ void SfxDocumentUserPage::SetLabelText_Impl( FixedText* pLabel, const String& rNewLabel ) { String aLabel( '~' ); sal_Int32 nNumber = 0; if ( &aInfo1Ft == pLabel ) nNumber = 1; else if ( &aInfo2Ft == pLabel ) nNumber = 2; else if ( &aInfo3Ft == pLabel ) nNumber = 3; else if ( &aInfo4Ft == pLabel ) nNumber = 4; DBG_ASSERT( nNumber > 0, "SfxDocumentUserPage::SetLabelText_Impl(): wrong label" ); aLabel += String::CreateFromInt32( nNumber ); aLabel += String( DEFINE_CONST_UNICODE(": ") ); aLabel += rNewLabel; DBG_ASSERT( pLabel, "SfxDocumentUserPage::SetLabelText_Impl(): invalid label" ); pLabel->SetText( aLabel ); } //------------------------------------------------------------------------ SfxTabPage* SfxDocumentUserPage::Create( Window* pParent, const SfxItemSet& rItemSet ) { return new SfxDocumentUserPage(pParent, rItemSet); } //------------------------------------------------------------------------ BOOL SfxDocumentUserPage::FillItemSet( SfxItemSet& rSet ) { const BOOL bMod = bLabelModified || aInfo1Ed.IsModified() || aInfo2Ed.IsModified() || aInfo3Ed.IsModified() || aInfo4Ed.IsModified(); if ( !bMod ) return FALSE; 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, TRUE, &pItem ) ) pInfo = pInfoItem; else if ( pItem ) pInfo = new SfxDocumentInfoItem( *(const SfxDocumentInfoItem*)pItem ); if ( !pInfo ) { DBG_ERRORFILE( "SfxDocumentUserPage::FillItemSet(): no item found" ); return FALSE; } if ( bLabelModified || aInfo1Ed.IsModified() ) { XubString aTitle = GetLabelText_Impl( &aInfo1Ft ); pInfo->setUserDefinedFieldTitle( 0, aTitle ); pInfo->setUserDefinedFieldValue( 0, aInfo1Ed.GetText() ); } if ( bLabelModified || aInfo2Ed.IsModified() ) { XubString aTitle = GetLabelText_Impl( &aInfo2Ft ); pInfo->setUserDefinedFieldTitle( 1, aTitle ); pInfo->setUserDefinedFieldValue( 1, aInfo2Ed.GetText() ); } if ( bLabelModified || aInfo3Ed.IsModified() ) { XubString aTitle = GetLabelText_Impl( &aInfo3Ft ); pInfo->setUserDefinedFieldTitle( 2, aTitle ); pInfo->setUserDefinedFieldValue( 2, aInfo3Ed.GetText() ); } if ( bLabelModified || aInfo4Ed.IsModified() ) { XubString aTitle = GetLabelText_Impl( &aInfo4Ft ); pInfo->setUserDefinedFieldTitle( 3, aTitle ); pInfo->setUserDefinedFieldValue( 3, aInfo4Ed.GetText() ); } rSet.Put( *pInfo ); if ( pInfo != pInfoItem ) delete pInfo; return bMod; } //------------------------------------------------------------------------ void SfxDocumentUserPage::Reset(const SfxItemSet &rSet) { pInfoItem = &(SfxDocumentInfoItem&)rSet.Get( SID_DOCINFO ); SetLabelText_Impl( &aInfo1Ft, pInfoItem->getUserDefinedFieldTitle(0) ); aInfo1Ed.SetText( pInfoItem->getUserDefinedFieldValue(0) ); SetLabelText_Impl( &aInfo2Ft, pInfoItem->getUserDefinedFieldTitle(1) ); aInfo2Ed.SetText( pInfoItem->getUserDefinedFieldValue(1) ); SetLabelText_Impl( &aInfo3Ft, pInfoItem->getUserDefinedFieldTitle(2) ); aInfo3Ed.SetText( pInfoItem->getUserDefinedFieldValue(2) ); SetLabelText_Impl( &aInfo4Ft, pInfoItem->getUserDefinedFieldTitle(3) ); aInfo4Ed.SetText( pInfoItem->getUserDefinedFieldValue(3) ); bLabelModified = FALSE; SFX_ITEMSET_ARG( &rSet, pROItem, SfxBoolItem, SID_DOC_READONLY, FALSE ); if ( pROItem && pROItem->GetValue() ) { aInfo1Ed.SetReadOnly( TRUE ); aInfo2Ed.SetReadOnly( TRUE ); aInfo3Ed.SetReadOnly( TRUE ); aInfo4Ed.SetReadOnly( TRUE ); aEditLabelBtn.Disable(); } } //------------------------------------------------------------------------ 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, 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, FALSE, &pItem ) ) { // Dateiname String aFile( pInfoItem->GetValue() ); #ifdef WIN if ( aFile.Len() <= 8 ) { String sTmp( SfxResId( STR_NONAME ) ); USHORT nLen = Min( (USHORT)8, sTmp.Len() ); if ( sTmp.Copy( 0, nLen ).Lower() == aFile.Copy( 0, nLen ).Lower() ) { aFile = pInfoItem->GetValue(); } } #endif 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: 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); } // ----------------------------------------------------------------------- void SfxDocumentInfoDialog::PageCreated( USHORT 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 ); } 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_aYesNoButton ( pParent, SfxResId( SFX_WIN_PROPERTY_YESNO ) ), m_aRemoveButton ( pParent, SfxResId( SFX_PB_PROPERTY_REMOVE ), this ), m_bIsRemoved ( false ), m_bTypeLostFocus( false ) { 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_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_aYesNoButton ( this, SfxResId( SFX_WIN_PROPERTY_YESNO ) ), m_aRemoveButton ( this, SfxResId( SFX_PB_PROPERTY_REMOVE ) ), 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 ) ); } 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(); BOOL bBooleanType = ( CUSTOM_TYPE_BOOLEAN == nType ); pLine->m_aValueEdit.Show( !bBooleanType ); pLine->m_aYesNoButton.Show( bBooleanType ); 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_aYesNoButton, &pLine->m_aRemoveButton, NULL }; Window** pCurrent = pWindows; while ( *pCurrent ) { Point aPos = (*pCurrent)->GetPosPixel(); aPos.Y() -= nDelta; (*pCurrent)->SetPosPixel( aPos ); pCurrent++; } } } 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 ) != 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_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; USHORT 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 ) { aSize = m_aYesNoButton.GetSizePixel(); aPos = m_aYesNoButton.GetPosPixel(); aSize.Width() = nWidth; aPos.X() = aRect.getX() + ( nOffset / 2 ); m_aYesNoButton.SetPosSizePixel( aPos, aSize ); } pCurrent++; } m_nLineHeight = ( m_aRemoveButton.GetPosPixel().Y() * 2 ) + m_aRemoveButton.GetSizePixel().Height(); } USHORT CustomPropertiesWindow::GetVisibleLineCount() const { USHORT 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 ) ); pNewLine->m_aTypeBox.SetLoseFocusHdl( LINK( this, CustomPropertiesWindow, BoxLoseFocusHdl ) ); long nPos = GetVisibleLineCount() * GetLineHeight(); m_aCustomPropertiesLines.push_back( pNewLine ); Window* pWindows[] = { &m_aNameBox, &m_aTypeBox, &m_aValueEdit, &m_aYesNoButton, &m_aRemoveButton, NULL }; Window* pNewWindows[] = { &pNewLine->m_aNameBox, &pNewLine->m_aTypeBox, &pNewLine->m_aValueEdit, &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; (*pNewCurrent)->SetPosSizePixel( aPos, aSize ); (*pNewCurrent)->Show(); pCurrent++; pNewCurrent++; } double nTmpValue = 0; bool bTmpValue = false; ::rtl::OUString sTmpValue; util::DateTime aTmpDate; 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 ); nType = CUSTOM_TYPE_NUMBER; } else if ( rAny >>= bTmpValue ) { sValue = ( bTmpValue ? rLocaleWrapper.getTrueWord() : rLocaleWrapper.getFalseWord() ); nType = CUSTOM_TYPE_BOOLEAN; } else if ( rAny >>= sTmpValue ) { sValue = String( sTmpValue ); nType = CUSTOM_TYPE_TEXT; } else if ( rAny >>= aTmpDate ) { DateFormat eFormat = rLocaleWrapper.getDateFormat(); sal_Unicode cDateSep = rLocaleWrapper.getDateSep().GetChar(0); switch ( eFormat ) { case MDY : { sValue = String::CreateFromInt32( aTmpDate.Month ); sValue += cDateSep; sValue += String::CreateFromInt32( aTmpDate.Day ); sValue += cDateSep; if ( aTmpDate.Year < 10 ) sValue += '0'; sValue += String::CreateFromInt32( aTmpDate.Year ); break; } case DMY : { sValue = String::CreateFromInt32( aTmpDate.Day ); sValue += cDateSep; sValue += String::CreateFromInt32( aTmpDate.Month ); sValue += cDateSep; if ( aTmpDate.Year < 10 ) sValue += '0'; sValue += String::CreateFromInt32( aTmpDate.Year ); break; } case YMD : { if ( aTmpDate.Year < 10 ) sValue += '0'; sValue += String::CreateFromInt32( aTmpDate.Year ); sValue += cDateSep; sValue += String::CreateFromInt32( aTmpDate.Month ); sValue += cDateSep; sValue += String::CreateFromInt32( aTmpDate.Day ); break; } } nType = CUSTOM_TYPE_DATE; } if ( nType != CUSTOM_TYPE_UNKNOWN ) { if ( CUSTOM_TYPE_BOOLEAN == nType ) { if ( bTmpValue ) pNewLine->m_aYesNoButton.CheckYes(); else pNewLine->m_aYesNoButton.CheckNo(); } else pNewLine->m_aValueEdit.SetText( sValue ); 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(); } void CustomPropertiesWindow::DoScroll( sal_Int32 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_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 ); 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_DATE == nType ) { const LocaleDataWrapper& rLocaleWrapper = SvtSysLocale().GetLocaleData(); DateFormat eFormat = rLocaleWrapper.getDateFormat(); sal_Unicode cDateSep = rLocaleWrapper.getDateSep().GetChar(0); String sValue( pLine->m_aValueEdit.GetText() ); if ( sValue.GetTokenCount( cDateSep ) == 3 ) { xub_StrLen nTokenDay = STRING_NOTFOUND; xub_StrLen nTokenMonth = STRING_NOTFOUND; xub_StrLen nTokenYear = STRING_NOTFOUND; switch ( eFormat ) { case MDY : { nTokenDay = 1; nTokenMonth = 0; nTokenYear = 2; break; } case DMY : { nTokenDay = 0; nTokenMonth = 1; nTokenYear = 2; break; } case YMD : { nTokenDay = 2; nTokenMonth = 1; nTokenYear = 0; break; } } if ( nTokenDay != STRING_NOTFOUND ) { util::DateTime aDateTime( 0, 0, 0, 0, sal_uInt16( sValue.GetToken( nTokenDay, cDateSep ).ToInt32() ), sal_uInt16( sValue.GetToken( nTokenMonth, cDateSep ).ToInt32() ), sal_uInt16( sValue.GetToken( nTokenYear, cDateSep ).ToInt32() ) ); aPropertiesSeq[i].Value <<= makeAny( aDateTime ); } } } 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_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; } void CustomPropertiesControl::AddLine( const ::rtl::OUString& sName, Any& rAny ) { m_aPropertiesWin.AddLine( sName, rAny ); m_aVertScroll.SetRangeMax( m_aPropertiesWin.GetVisibleLineCount() + 1 ); } // class SfxCustomPropertiesPage ----------------------------------------- SfxCustomPropertiesPage::SfxCustomPropertiesPage( Window* pParent, const SfxItemSet& rItemSet ) : SfxTabPage( pParent, SfxResId( TP_CUSTOMPROPERTIES ), rItemSet ), m_aPropertiesFT ( this, SfxResId( FT_PROPERTIES ) ), m_aPropertiesCtrl ( this, SfxResId( CTRL_PROPERTIES ) ), m_aAddBtn ( this, SfxResId( BTN_ADD ) ) { FreeResource(); m_aAddBtn.SetClickHdl( LINK( this, SfxCustomPropertiesPage, AddHdl ) ); } IMPL_LINK( SfxCustomPropertiesPage, AddHdl, PushButton*, EMPTYARG ) { Any aAny; m_aPropertiesCtrl.AddLine( ::rtl::OUString(), aAny ); return 0; } BOOL SfxCustomPropertiesPage::FillItemSet( SfxItemSet& rSet ) { BOOL bModified = FALSE; const SfxPoolItem* pItem = NULL; SfxDocumentInfoItem* pInfo = NULL; bool bMustDelete = false; if ( GetTabDialog() && GetTabDialog()->GetExampleSet() ) { if( SFX_ITEM_SET != GetTabDialog()->GetExampleSet()->GetItemState( SID_DOCINFO, 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 = 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 ); } } 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 ); }