diff options
author | Philipp Lohmann [pl] <Philipp.Lohmann@Sun.COM> | 2010-01-14 19:11:13 +0100 |
---|---|---|
committer | Philipp Lohmann [pl] <Philipp.Lohmann@Sun.COM> | 2010-01-14 19:11:13 +0100 |
commit | 0dc15d0bc9adb9dcd2a1a5deea3f952b8a4e6689 (patch) | |
tree | 1fe24b3ce25cdfece23f43d4663f1adff67b6a1d /svl | |
parent | 64e8661d76db6b02396d82b7d1f28dd3088a334f (diff) | |
parent | 8765a3bf9f2926a50d0f644e4263782269abe023 (diff) |
rebase to DEV300_m69
Diffstat (limited to 'svl')
266 files changed, 81201 insertions, 0 deletions
diff --git a/svl/inc/PasswordHelper.hxx b/svl/inc/PasswordHelper.hxx new file mode 100644 index 000000000000..c915ebe3854a --- /dev/null +++ b/svl/inc/PasswordHelper.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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: PasswordHelper.hxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_PASSWORDHELPER_HXX +#define _SVTOOLS_PASSWORDHELPER_HXX + +#include "svl/svldllapi.h" +#include "sal/types.h" +#include "com/sun/star/uno/Sequence.hxx" + +class String; + +class SvPasswordHelper +{ + static void GetHashPassword(com::sun::star::uno::Sequence <sal_Int8>& rPassHash, const sal_Char* pPass, sal_uInt32 nLen); + static void GetHashPasswordLittleEndian(com::sun::star::uno::Sequence<sal_Int8>& rPassHash, const String& sPass); + static void GetHashPasswordBigEndian(com::sun::star::uno::Sequence<sal_Int8>& rPassHash, const String& sPass); + +public: + SVL_DLLPUBLIC static void GetHashPassword(com::sun::star::uno::Sequence<sal_Int8>& rPassHash, const String& sPass); + /** + Use this method to compare a given string with another given Hash value. + This is necessary, because in older versions exists different hashs of the same string. They were endian dependent. + We need this to handle old files. This method will compare against big and little endian. See #101326# + */ + SVL_DLLPUBLIC static bool CompareHashPassword(const com::sun::star::uno::Sequence<sal_Int8>& rOldPassHash, const String& sNewPass); +}; + +#endif + diff --git a/svl/inc/adrparse.hxx b/svl/inc/adrparse.hxx new file mode 100644 index 000000000000..a317e27b2779 --- /dev/null +++ b/svl/inc/adrparse.hxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * 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: adrparse.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _ADRPARSE_HXX +#define _ADRPARSE_HXX + +#include "svl/svldllapi.h" +#include <tools/list.hxx> +#include <tools/string.hxx> + +//============================================================================ +struct SvAddressEntry_Impl +{ + UniString m_aAddrSpec; + UniString m_aRealName; + + SvAddressEntry_Impl() {}; + SvAddressEntry_Impl(UniString const & rTheAddrSpec, + UniString const & rTheRealName): + m_aAddrSpec(rTheAddrSpec), m_aRealName(rTheRealName) {} +}; + +//============================================================================ +DECLARE_LIST(SvAddressList_Impl, SvAddressEntry_Impl *) + +//============================================================================ +class SVL_DLLPUBLIC SvAddressParser +{ + friend class SvAddressParser_Impl; + + SvAddressEntry_Impl m_aFirst; + SvAddressList_Impl m_aRest; + bool m_bHasFirst; + +public: + SvAddressParser(UniString const & rInput); + + ~SvAddressParser(); + + sal_Int32 Count() const { return m_bHasFirst ? m_aRest.Count() + 1 : 0; } + + inline UniString const & GetEmailAddress(sal_Int32 nIndex) const; + + inline UniString const &GetRealName(sal_Int32 nIndex) const; + + /** Create an RFC 822 <mailbox> (i.e., 'e-mail address'). + + @param rPhrase Either an empty string (the <mailbox> will have no + <phrase> an will be of the form <addr-spec>), or some text that will + become the <phrase> part of a <phrase route-addr> form <mailbox>. Non + US-ASCII characters within the text are put into a <qouted-string> + verbatim, so the result may actually not be a valid RFC 822 <mailbox>, + but a more human-readable representation. + + @param rAddrSpec A valid RFC 822 <addr-spec>. (An RFC 822 <mailbox> + including a <route> cannot be created by this method.) + + @param rMailbox If this method returns true, this parameter returns + the created RFC 822 <mailbox> (rather, a more human-readable + representation thereof). Otherwise, this parameter is not modified. + + @return True, if rAddrSpec is a valid RFC 822 <addr-spec>. + */ + static bool createRFC822Mailbox(String const & rPhrase, + String const & rAddrSpec, + String & rMailbox); +}; + +inline UniString const & SvAddressParser::GetEmailAddress(sal_Int32 nIndex) + const +{ + return nIndex == 0 ? m_aFirst.m_aAddrSpec : + m_aRest.GetObject(nIndex - 1)->m_aAddrSpec; +} + +inline UniString const & SvAddressParser::GetRealName(sal_Int32 nIndex) const +{ + return nIndex == 0 ? m_aFirst.m_aRealName : + m_aRest.GetObject(nIndex - 1)->m_aRealName; +} + +#endif // _ADRPARSE_HXX + diff --git a/svl/inc/broadcast.hxx b/svl/inc/broadcast.hxx new file mode 100644 index 000000000000..e80a2e446ebf --- /dev/null +++ b/svl/inc/broadcast.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * 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: broadcast.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVT_BROADCAST_HXX +#define _SVT_BROADCAST_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> + +class SvtListener; +class SfxHint; +class SvtListenerBase; + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SvtBroadcaster +{ +friend class SvtListener; +friend class SvtListenerBase; +friend class SvtListenerIter; + SvtListenerBase* pRoot; + + const SvtBroadcaster& operator=(const SvtBroadcaster &); // verboten + +protected: + void Forward( SvtBroadcaster& rBC, + const SfxHint& rHint ); + virtual void ListenersGone(); + +public: + TYPEINFO(); + + SvtBroadcaster(); + SvtBroadcaster( const SvtBroadcaster &rBC ); + virtual ~SvtBroadcaster(); + + void Broadcast( const SfxHint &rHint ); + + BOOL HasListeners() const { return 0 != pRoot; } +}; + + +#endif + diff --git a/svl/inc/cntnrsrt.hxx b/svl/inc/cntnrsrt.hxx new file mode 100644 index 000000000000..13553f7f16fd --- /dev/null +++ b/svl/inc/cntnrsrt.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * 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: cntnrsrt.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CNTRSRT_HXX +#define _CNTRSRT_HXX + +#if 0 +*********************************************************************** +* +* Hier folgt die Beschreibung fuer die exportierten Makros: +* +* DECLARE_CONTAINER_SORT( ClassName, Type ) +* IMPL_CONTAINER_SORT( ClassName, Type, SortFunc ) +* +* Definiert eine von Container abgeleitete Klasse "ClassName", +* in der die Elemente des Typs "Type" sortiert enthalten sind. +* Dazu muss einer Funktion "SortFunc" definiert sein, die als +* Paramter zwei "const Type&" erwartet und 0 zurueckgibt, wenn +* beide gleich sind, -1 wenn der erste Paramter kleiner ist als +* der zweite und +1 wenn der erste Paramter groesser ist als +* der zweite. +* +* Die Zugriffs-Methoden entsprechen in etwa denen der Container- +* Klasse, mit Ausnahme von Insert, DeleteAndDestroy und Seek_Entry, +* der den SV-Pointer-Arrays entsprechen. +* +* DECLARE_CONTAINER_SORT_DEL( ClassName, Type ) +* IMPL_CONTAINER_SORT( ClassName, Type, SortFunc ) +* +* Wie DECLARE_CONTAINER_SORT, nur dass beim Aufruf des Destruktors +* alle im Conatiner vorhandenen Objekte geloescht werden. +* +#endif + +#include <tools/contnr.hxx> + +#define DECLARE_CONTAINER_SORT_COMMON( ClassName, Type ) \ + ClassName( const ClassName& ); \ + ClassName& operator =( const ClassName& ); \ +public: \ + using Container::Count; \ + \ + ClassName( USHORT InitSize, USHORT ReSize ) : \ + Container( CONTAINER_MAXBLOCKSIZE, InitSize, ReSize ) {} \ + \ + BOOL Insert( Type* pObj ); \ + \ + Type *Remove( ULONG nPos ) \ + { return (Type *)Container::Remove( nPos ); } \ + \ + Type *Remove( Type* pObj ); \ + \ + void DeleteAndDestroy( ULONG nPos ) \ + { \ + Type *pObj = Remove( nPos ); \ + if( pObj ) \ + delete pObj; \ + } \ + \ + void DeleteAndDestroy() \ + { while( Count() ) DeleteAndDestroy( 0 ); } \ + \ + Type* GetObject( ULONG nPos ) const \ + { return (Type *)Container::GetObject( nPos ); } \ + \ + Type* operator[]( ULONG nPos ) const \ + { return GetObject(nPos); } \ + \ + BOOL Seek_Entry( const Type *pObj, ULONG* pPos ) const; \ + \ + ULONG GetPos( const Type* pObj ) const; \ + + +#define DECLARE_CONTAINER_SORT( ClassName, Type ) \ +class ClassName : private Container \ +{ \ + DECLARE_CONTAINER_SORT_COMMON( ClassName, Type ) \ + ~ClassName() {} \ +}; \ + + +#define DECLARE_CONTAINER_SORT_DEL( ClassName, Type ) \ +class ClassName : private Container \ +{ \ + DECLARE_CONTAINER_SORT_COMMON( ClassName, Type ) \ + ~ClassName() { DeleteAndDestroy(); } \ +}; \ + + +#define IMPL_CONTAINER_SORT( ClassName, Type, SortFunc ) \ +BOOL ClassName::Insert( Type *pObj ) \ +{ \ + ULONG nPos; \ + BOOL bExist = Seek_Entry( pObj, &nPos ); \ + if( !bExist ) \ + Container::Insert( pObj, nPos ); \ + return !bExist; \ +} \ + \ +Type *ClassName::Remove( Type* pObj ) \ +{ \ + ULONG nPos; \ + if( Seek_Entry( pObj, &nPos ) ) \ + return Remove( nPos ); \ + else \ + return 0; \ +} \ + \ +ULONG ClassName::GetPos( const Type* pObj ) const \ +{ \ + ULONG nPos; \ + if( Seek_Entry( pObj, &nPos ) ) \ + return nPos; \ + else \ + return CONTAINER_ENTRY_NOTFOUND; \ +} \ + \ +BOOL ClassName::Seek_Entry( const Type* pObj, ULONG* pPos ) const \ +{ \ + register ULONG nO = Count(), \ + nM, \ + nU = 0; \ + if( nO > 0 ) \ + { \ + nO--; \ + while( nU <= nO ) \ + { \ + nM = nU + ( nO - nU ) / 2; \ + int nCmp = SortFunc( *GetObject(nM), *pObj ); \ + \ + if( 0 == nCmp ) \ + { \ + if( pPos ) *pPos = nM; \ + return TRUE; \ + } \ + else if( nCmp < 0 ) \ + nU = nM + 1; \ + else if( nM == 0 ) \ + { \ + if( pPos ) *pPos = nU; \ + return FALSE; \ + } \ + else \ + nO = nM - 1; \ + } \ + } \ + if( pPos ) *pPos = nU; \ + return FALSE; \ +} \ + +#endif diff --git a/svl/inc/cntwids.hrc b/svl/inc/cntwids.hrc new file mode 100644 index 000000000000..fcb9f855453b --- /dev/null +++ b/svl/inc/cntwids.hrc @@ -0,0 +1,509 @@ +/************************************************************************* + * + * 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: cntwids.hrc,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CNTWIDS_HRC +#define _CNTWIDS_HRC + +#ifndef OLD_CHAOS +#define TF_NEW_TABPAGES +#define CNT_COOL_ABO +#endif + +//========================================================================= +// ARGS, MSG, ALL, FOLDER, BOXALL, BOXEXT +//========================================================================= + +#define WID_CHAOS_START 500 + +//FUNC MSG +#define WID_MARK_THREAD_MARKED (499) +#define WID_MARK_THREAD_UNMARKED (498) + +// ARGS +#define WID_DUMMY_ARG1 (WID_CHAOS_START + 0) +#define WID_FACTORY_NO (WID_CHAOS_START + 1) +#define WID_FACTORY_NAME (WID_CHAOS_START + 2) +#define WID_NEWS_XREF (WID_CHAOS_START + 3) +#define WID_CREATION_FLAGS (WID_CHAOS_START + 4) +#define WID_FACTORY_HELP_ID (WID_CHAOS_START + 5) + +//FUNC MSG +#define WID_MSG_START (WID_CHAOS_START + 6) +#define WID_MAIL_REPLY (WID_CHAOS_START + 6) +#define WID_POST_REPLY (WID_CHAOS_START + 7) +#define WID_FORWARD (WID_CHAOS_START + 8) +#define WID_MARK_THREAD_READ (WID_CHAOS_START + 9) +#define WID_HIDE_THREAD (WID_CHAOS_START + 10) +#define WID_HIDE_AUTHOR (WID_CHAOS_START + 11) +#define WID_HIDE_SUBJECT (WID_CHAOS_START + 12) +#define WID_RESEND_MSG (WID_CHAOS_START + 13) +#define WID_MARK_THREAD_UNREAD (WID_CHAOS_START + 14) + +//PROP MSG +#define WID_PRIORITY (WID_CHAOS_START + 15) +#define WID_RULE_APPLIED (WID_CHAOS_START + 16) +#define WID_MSG_LOCK (WID_CHAOS_START + 17) +#define WID_SEEN_STATUS (WID_CHAOS_START + 18) +#define WID_REPLY_TO (WID_CHAOS_START + 19) +#define WID_IN_REPLY_TO (WID_CHAOS_START + 20) + +#define WID_MESSAGE_ID (WID_CHAOS_START + 21) +#define WID_BCC (WID_CHAOS_START + 22) +#define WID_CC (WID_CHAOS_START + 23) +#define WID_TO (WID_CHAOS_START + 24) +#define WID_FROM (WID_CHAOS_START + 25) +#define WID_TITLE (WID_CHAOS_START + 26) +#define WID_SUBJECT WID_TITLE // only here to prevent panic, should be removed +#define WID_MESSAGEBODY (WID_CHAOS_START + 27) + +#define WID_REFERENCES (WID_CHAOS_START + 28) +#define WID_NEWSGROUPS (WID_CHAOS_START + 29) +#define WID_NEWS_XREFLIST (WID_CHAOS_START + 30) + +#define WID_OUTMSGINTERNALSTATE (WID_CHAOS_START + 31) +#define WID_RECIPIENTLIST (WID_CHAOS_START + 32) +#define WID_MSG_END (WID_CHAOS_START + 32) + +//FUNC ALL +#define WID_ALL_START (WID_CHAOS_START + 33) +#define WID_DEFAULT (WID_CHAOS_START + 33) +#define WID_OPEN (WID_CHAOS_START + 34) +#define WID_DELETE (WID_CHAOS_START + 35) +#define WID_CUT (WID_CHAOS_START + 36) +#define WID_COPY (WID_CHAOS_START + 37) +#define WID_PASTE (WID_CHAOS_START + 38) +#define WID_RENAME (WID_CHAOS_START + 39) + +#define WID_HAS_DATA (WID_CHAOS_START + 40) +#define WID_GETDATA (WID_CHAOS_START + 41) +#define WID_PUTDATA (WID_CHAOS_START + 42) + +//PROP ALL +#define WID_INTERIM_URL (WID_CHAOS_START + 43) +#define WID_CONTENT_TYPE (WID_CHAOS_START + 44) + +#define WID_OWN_URL (WID_CHAOS_START + 45) +#define WID_REAL_URL (WID_CHAOS_START + 46) +#define WID_OBSOLETE_TITLE (WID_CHAOS_START + 47) +#define WID_FLAG_READONLY (WID_CHAOS_START + 48) + +#define WID_REFERED_URL (WID_CHAOS_START + 49) +#define WID_REFERER_COUNT (WID_CHAOS_START + 50) +#define WID_FLAG_IS_FOLDER (WID_CHAOS_START + 51) +#define WID_FLAG_HAS_FOLDER (WID_CHAOS_START + 52) +#define WID_FLAG_IS_MESSAGE (WID_CHAOS_START + 53) +#define WID_FLAG_IS_DOCUMENT (WID_FLAG_IS_MESSAGE) +#define WID_FLAG_HAS_MESSAGES (WID_CHAOS_START + 54) + +#define WID_DATE_CREATED (WID_CHAOS_START + 55) +#define WID_DATE_MODIFIED (WID_CHAOS_START + 56) +#define WID_VIEW_DESCRIPTION (WID_CHAOS_START + 57) +#define WID_IS_READ (WID_CHAOS_START + 58) +#define WID_IS_MARKED (WID_CHAOS_START + 59) +#define WID_ALL_END (WID_CHAOS_START + 59) + +//FUNC FOLDER +#define WID_FOLDER_START (WID_CHAOS_START + 60) +#define WID_SYNCHRONIZE (WID_CHAOS_START + 60) +#define WID_CREATE_NEW (WID_CHAOS_START + 61) +#define WID_INSERT (WID_CHAOS_START + 62) +#define WID_UPDATE (WID_CHAOS_START + 63) +#define WID_IMPORT (WID_CHAOS_START + 64) + +//PROP FOLDER VIEW +#define WID_DUMMY_PROPFOLDERVIEW1 (WID_CHAOS_START + 65) +#define WID_THREADING (WID_CHAOS_START + 66) +#define WID_MSG_COLUMN_INFO /* obsolete */ (WID_CHAOS_START + 67) +#define WID_FLD_COLUMN_INFO /* obsolete */ (WID_CHAOS_START + 68) +#define WID_FOLDERVIEW_MODE (WID_CHAOS_START + 69) +#define WID_MESSAGEVIEW_MODE (WID_CHAOS_START + 70) +#define WID_SENTMESSAGEVIEW_MODE (WID_CHAOS_START + 71) +#define WID_SORTING (WID_CHAOS_START + 72) +#define WID_THREADED (WID_CHAOS_START + 73) +#define WID_FILTERED (WID_CHAOS_START + 74) +#define WID_RULES (WID_CHAOS_START + 75) +#define WID_SUBSCRNEWSGROUPCOUNT (WID_CHAOS_START + 76) +#define WID_FLAG_SUBSCRIBED (WID_CHAOS_START + 77) +#define WID_FLAG_SUPPORTMODE (WID_CHAOS_START + 78) + +//PROP FOLDER DIR +#define WID_DUMMY_FOLDERDIR1 (WID_CHAOS_START + 79) +#define WID_TOTALCONTENTCOUNT (WID_CHAOS_START + 80) +#define WID_NEWSGROUPCOUNT /* ??? */ (WID_CHAOS_START + 81) +#define WID_ARTICLECOUNT /* ??? */ (WID_CHAOS_START + 82) +#define WID_KNOWN_RANGES (WID_CHAOS_START + 83) +#define WID_IMAPFOLDERINFO (WID_CHAOS_START + 84) + +//PROP FOLDER USER +#define WID_DUMMY_FOLDERUSER1 (WID_CHAOS_START + 85) +#define WID_SEENCONTENTCOUNT (WID_CHAOS_START + 86) +#define WID_UNREAD_ARTICLECOUNT (WID_SEENCONTENTCOUNT) +#define WID_SENTCONTENTCOUNT (WID_SEENCONTENTCOUNT) +#define WID_READ_RANGES (WID_CHAOS_START + 87) +#define WID_MARK_RANGES (WID_CHAOS_START + 88) +#define WID_FOLDER_END (WID_CHAOS_START + 88) + +//PROP BOXALL +#define WID_BOXALL_START (WID_CHAOS_START + 89) +// Used for d&d of View Storages... +#define WID_PREPARE_MOVE (WID_CHAOS_START + 89) +#define WID_OUTTRAY_WANTED (WID_CHAOS_START + 90) +#define WID_USERNAME (WID_CHAOS_START + 91) +#define WID_PASSWORD (WID_CHAOS_START + 92) +#define WID_SERVERNAME (WID_CHAOS_START + 93) +#define WID_SERVERPORT (WID_CHAOS_START + 94) +// obsolete +#define WID_MAILSEND_USERNAME (WID_CHAOS_START + 95) +#define WID_MAILSEND_PASSWORD (WID_CHAOS_START + 96) +#define WID_MAILSEND_SERVERNAME (WID_CHAOS_START + 97) +#define WID_NEWSSEND_USERNAME (WID_CHAOS_START + 98) +#define WID_NEWSSEND_PASSWORD (WID_CHAOS_START + 99) +#define WID_NEWSSEND_SERVERNAME (WID_CHAOS_START + 100) +// end obsolete +#define WID_SERVERBASE (WID_CHAOS_START + 101) +// not used +#define WID_SMTP_GATEWAY (WID_CHAOS_START + 102) + +// -> ..._DEFAULT +// obsolete +#define WID_FROM_DEFAULT (WID_CHAOS_START + 103) +// obsolete +#define WID_REPLY_TO_DEFAULT (WID_CHAOS_START + 104) + +#define WID_AUTOUPDATE_INTERVAL (WID_CHAOS_START + 105) +#define WID_UPDATE_ENABLED (WID_CHAOS_START + 106) +#define WID_BOXALL_END (WID_CHAOS_START + 106) + +//PROP BOX RNMGR +#define WID_BOXEXT_START (WID_CHAOS_START + 107) +#define WID_CONNECTION_MODE (WID_CHAOS_START + 107) +#define WID_NEWS_GROUPLIST (WID_CHAOS_START + 108) +#ifdef OLD_CHAOS +#define WID_BOX_CONNECTION_PROP (WID_CHAOS_START + 109) +#else +#define WID_MESSAGE_STOREMODE (WID_CHAOS_START + 109) +#endif +#define WID_DELETE_ON_SERVER (WID_CHAOS_START + 110) + +//PROP BOX USER + +//PROP BOX OUT DIR +#define WID_OUTMSGEXTERNALSTATE (WID_CHAOS_START + 111) + +//PROP RNM +#define WID_RNM_UPDATETIMER_LIST (WID_CHAOS_START + 112) +#define WID_BOXEXT_END (WID_CHAOS_START + 112) + +////////////////////////////////////////////////////////////////////////// +// MISC - Added after initial pool version +////////////////////////////////////////////////////////////////////////// + +// PROP BOX +#define WID_SERVER_RANGES (WID_CHAOS_START + 113) +#define WID_LAST_UPDATE (WID_CHAOS_START + 114) +#define WID_LAST_MSGID (WID_CHAOS_START + 115) +#define WID_LAST_UID (WID_CHAOS_START + 116) + +// FUNC ALL +#define WID_UNDELETE (WID_CHAOS_START + 117) +#define WID_CLOSE (WID_CHAOS_START + 118) +#define WID_REOPEN (WID_CHAOS_START + 119) + +// PROP RNM +#define WID_RNM_FILECONVERSION_LIST (WID_CHAOS_START + 120) + +// PROP FOLDER +#define WID_SHOW_MSGS_HAS_TIMELIMIT (WID_CHAOS_START + 121) +#define WID_SHOW_MSGS_TIMELIMIT (WID_CHAOS_START + 122) +#define WID_STORE_MSGS_HAS_TIMELIMIT (WID_CHAOS_START + 123) +#define WID_STORE_MSGS_TIMELIMIT (WID_CHAOS_START + 124) + +// PROP BOX +#define WID_MSG_COLUMN_WIDTHS /* obsolete */(WID_CHAOS_START + 125) + +#ifdef OLD_CHAOS + +#define WID_CHAOS_END (WID_CHAOS_START + 125) + +#else + +////////////////////////////////////////////////////////////////////////// +// WID's added after SO 4.0 release ( SUPD > 364 ) +////////////////////////////////////////////////////////////////////////// + +// PROP ALL +#define WID_PROPERTYLIST (WID_CHAOS_START + 126) + +// PROP BOXALL +#define WID_BOXALL_START2 (WID_CHAOS_START + 127) +#define WID_SEND_PUBLIC_PROT_ID (WID_CHAOS_START + 127) +#define WID_SEND_PRIVATE_PROT_ID (WID_CHAOS_START + 128) +#define WID_SEND_PUBLIC_OUTBOXPROPS (WID_CHAOS_START + 129) +#define WID_SEND_PRIVATE_OUTBOXPROPS (WID_CHAOS_START + 130) +#define WID_SEND_SERVERNAME (WID_CHAOS_START + 131) +#define WID_SEND_USERNAME (WID_CHAOS_START + 132) +#define WID_SEND_PASSWORD (WID_CHAOS_START + 133) +#define WID_SEND_REPLY_TO_DEFAULT (WID_CHAOS_START + 134) +#define WID_SEND_FROM_DEFAULT (WID_CHAOS_START + 135) +#define WID_VIM_POPATH (WID_CHAOS_START + 136) +#define WID_SEND_VIM_POPATH (WID_CHAOS_START + 137) +#define WID_PURGE (WID_CHAOS_START + 138) +#define WID_CLEAN_CACHE (WID_CHAOS_START + 139) +#define WID_SEARCH (WID_CHAOS_START + 140) +#define WID_JOURNAL (WID_CHAOS_START + 141) +#define WID_LOCALBASE (WID_CHAOS_START + 142) +#define WID_BOXALL_END2 (WID_CHAOS_START + 142) + +// PROP DOCUMENT +#define WID_DOCUMENT_HEADER (WID_CHAOS_START + 143) +#define WID_DOCUMENT_BODY (WID_CHAOS_START + 144) +#define WID_DOCUMENT_SIZE (WID_CHAOS_START + 145) + +// PROP ALL +#define WID_SIZE WID_DOCUMENT_SIZE + +// PROP PROJECT +#define WID_PRJ_MEDIUM (WID_CHAOS_START + 146) +#define WID_PRJ_FILENAMECONVENTION (WID_CHAOS_START + 147) + +// PROP FSYS +#define WID_FSYS_DISKSPACE_LEFT (WID_CHAOS_START + 148) +#define WID_TRANSFER (WID_CHAOS_START + 149) + +// PROP ALL +#define WID_KEYWORDS (WID_CHAOS_START + 150) +#define WID_IS_PROTECTED (WID_CHAOS_START + 151) + +// PROP SEARCH +#define WID_SEARCH_CRITERIA (WID_CHAOS_START + 152) +#define WID_SEARCH_LOCATIONS (WID_CHAOS_START + 153) +#define WID_SEARCH_RECURSIVE (WID_CHAOS_START + 154) +#define WID_SEARCH_FOLDER_VIEW (WID_CHAOS_START + 155) +#define WID_SEARCH_DOCUMENT_VIEW (WID_CHAOS_START + 156) + +// PROP Channel +#define WID_SCHEDULE_RANGE (WID_CHAOS_START + 157) +#define WID_ALLOWED_SCHEDULE_RANGE (WID_CHAOS_START + 158) +#define WID_TARGET_URL (WID_CHAOS_START + 159) +#define WID_FREQUENCY (WID_CHAOS_START + 160) + +// PROP HTTP +#define WID_HTTP_CONNECTION_LIMIT (WID_CHAOS_START + 161) +#define WID_HTTP_COOKIE_MANAGER (WID_CHAOS_START + 162) + +// PROP Channel +#define WID_COLUMN_NEXT_UPD (WID_CHAOS_START + 163) +#define WID_CRAWL_STATUS (WID_CHAOS_START + 164) +#define WID_CRAWL_LEVEL (WID_CHAOS_START + 165) +#define WID_CRAWL_MODE (WID_CHAOS_START + 166) +// WID_CRAWL_MAX_VOLUME shall be removed in the future! +// --> WID_SIZE_LIMIT +#define WID_CRAWL_MAX_VOLUME (WID_CHAOS_START + 167) +#define WID_CRAWL_IMAGE (WID_CHAOS_START + 168) +#define WID_CRAWL_LINK_OUT (WID_CHAOS_START + 169) +#define WID_NOTIFICATION_MODE (WID_CHAOS_START + 170) +#define WID_NOTIFICATION_ADDRESS (WID_CHAOS_START + 171) + +// PROP BOXALL +#define WID_ACCOUNT (WID_CHAOS_START + 172) + +// PROP FSYS +#define WID_FSYS_KIND (WID_CHAOS_START + 173) +#define WID_FSYS_FLAGS (WID_CHAOS_START + 174) + +// PROP FOLDER +#define WID_VIEWDATA /* obsolete */ (WID_CHAOS_START + 175) + +// PROP FSYS +#define WID_WHO_IS_MASTER (WID_CHAOS_START + 176) + +// FUNC HTTP +#define WID_HTTP_POST (WID_CHAOS_START + 177) + +// PROP ALL +#define WID_SUPPORTED_FUNCS (WID_CHAOS_START + 178) +#define WID_SIZE_LIMIT (WID_CHAOS_START + 179) + +// PROP FOLDER +#define WID_MARKED_DOCUMENT_COUNT (WID_CHAOS_START + 180) +#define WID_FOLDER_COUNT (WID_CHAOS_START + 181) + +// PROP FSYS +#define WID_FSYS_SHOW_HIDDEN (WID_CHAOS_START + 182) + +// TRASHCAN +#define WID_TRASHCAN_START (WID_CHAOS_START + 183) +#define WID_TRASHCAN_EMPTY_TRASH (WID_CHAOS_START + 183) +#define WID_TRASHCAN_FLAG_AUTODELETE (WID_CHAOS_START + 184) +#define WID_TRASHCAN_FLAG_CONFIRMEMPTY (WID_CHAOS_START + 185) +#define WID_TRASHCAN_DUMMY1 (WID_CHAOS_START + 186) +#define WID_TRASHCAN_DUMMY2 (WID_CHAOS_START + 187) +#define WID_TRASHCAN_END (WID_CHAOS_START + 187) + +// TRASH +#define WID_TRASH_START (WID_CHAOS_START + 188) +#define WID_TRASH_RESTORE (WID_CHAOS_START + 188) +#define WID_TRASH_ORIGIN (WID_CHAOS_START + 189) +#define WID_TRASH_DUMMY2 (WID_CHAOS_START + 190) +#define WID_TRASH_END (WID_CHAOS_START + 190) + +// PROP ALL +#define WID_TARGET_FRAMES (WID_CHAOS_START + 191) + +// FUNC FOLDER +#define WID_EXPORT (WID_CHAOS_START + 192) + +// COMPONENT +#define WID_COMPONENT_COMMAND (WID_CHAOS_START + 193) +#define WID_COMPONENT_MENU (WID_CHAOS_START + 194) + +// PROP Channel +#define WID_HREF (WID_CHAOS_START + 195) + +// PROP FOLDER (VIEW) +#define WID_VIEW_START (WID_CHAOS_START + 196) +#define WID_VIEW_COLS_BEAMER (WID_CHAOS_START + 196) +#define WID_VIEW_COLS_FILEDLG (WID_CHAOS_START + 197) +#define WID_VIEW_COLS_FLDWIN (WID_CHAOS_START + 198) +#define WID_VIEW_MODE_FLDWIN (WID_CHAOS_START + 199) +#define WID_VIEW_LAYOUT_FLDWIN (WID_CHAOS_START + 200) +#define WID_VIEW_ICON_POS_FLDWIN (WID_CHAOS_START + 201) +#define WID_VIEW_SORT_BEAMER (WID_CHAOS_START + 202) +#define WID_VIEW_SORT_FILEDLG (WID_CHAOS_START + 203) +#define WID_VIEW_SORT_FLDWIN_DETAILS (WID_CHAOS_START + 204) +#define WID_VIEW_SORT_FLDWIN_ICON (WID_CHAOS_START + 205) +#define WID_VIEW_WINDOW_POS_FLDWIN (WID_CHAOS_START + 206) +#define WID_VIEW_END (WID_CHAOS_START + 206) + +// PROP ALL +#define WID_IS_INVALID (WID_CHAOS_START + 207) + +// PROP Channel +#define WID_VIEW_TIPHELP (WID_CHAOS_START + 208) +#define WID_PUBLISHER_SCHEDULE (WID_CHAOS_START + 209) +#define WID_GETMODE (WID_CHAOS_START + 210) +#define WID_READ_OFFLINE (WID_CHAOS_START + 211) + +// PROP ALL +#define WID_ALL_START2 (WID_CHAOS_START + 212) +#define WID_REAL_NAME (WID_CHAOS_START + 212) +#define WID_FLAG_UPDATE_ON_OPEN (WID_CHAOS_START + 213) +#define WID_ACTION_LIST (WID_CHAOS_START + 214) +#define WID_EDIT_STRING (WID_CHAOS_START + 215) +#define WID_SET_AS_DEFAULT (WID_CHAOS_START + 216) +#define WID_ALL_END2 (WID_CHAOS_START + 216) + +// PROP FOLDER (VIEW) +#define WID_VIEW2_START (WID_CHAOS_START + 217) +#define WID_VIEW2_FLD_PIC (WID_CHAOS_START + 217) +#define WID_FLAG_EXPANDED (WID_CHAOS_START + 218) +#define WID_CHILD_DEFAULTS (WID_CHAOS_START + 219) +#define WID_VIEW2_END (WID_CHAOS_START + 219) + +// PROP HTTP +#define WID_HTTP_KEEP_EXPIRED (WID_CHAOS_START + 220) +#define WID_HTTP_VERIFY_MODE (WID_CHAOS_START + 221) +#define WID_HTTP_NOCACHE_LIST (WID_CHAOS_START + 222) +#define WID_HTTP_REFERER (WID_CHAOS_START + 223) + +// PROP FSYS +#define WID_FSYS_START (WID_CHAOS_START + 224) +#define WID_FSYS_VALUE_FOLDER (WID_CHAOS_START + 224) +#define WID_FSYS_SHOW_EXTENSION (WID_CHAOS_START + 225) +#define WID_VALUE_ADDED_MODE (WID_CHAOS_START + 226) +#define WID_FSYS_DUMMY3 (WID_CHAOS_START + 227) +#define WID_FSYS_DUMMY4 (WID_CHAOS_START + 228) +#define WID_FSYS_END (WID_CHAOS_START + 228) + +// FUNC HTTP +#define WID_HTTP_GET_COOKIE (WID_CHAOS_START + 229) +#define WID_HTTP_SET_COOKIE (WID_CHAOS_START + 230) + +// PROP HTTP +#define WID_HTTP_COOKIE (WID_CHAOS_START + 231) +#define WID_HTTP_DUMMY_1 (WID_CHAOS_START + 232) + +////////////////////////////////////////////////////////////////////////// +// WID's added after SO 5.0 release ( SUPD > 505 ) +////////////////////////////////////////////////////////////////////////// + +// PROP FOLDER +#define WID_FOLDER_START2 (WID_CHAOS_START + 233) +#define WID_USER_SORT_CRITERIUM (WID_CHAOS_START + 233) +#define WID_HEADER_CONFIG (WID_CHAOS_START + 234) +#define WID_GROUPVIEW_CONFIG (WID_CHAOS_START + 235) +#define WID_FLD_WEBVIEW_TEMPLATE (WID_CHAOS_START + 236) +// eigene Iconpositionen fuer den Explorer, da er noch +// keinen eigenen View-Storage hat +#define WID_VIEW_ICON_POS_GRPWIN (WID_CHAOS_START + 237) +#define WID_FOLDER_END2 (WID_CHAOS_START + 237) + +// PROP ALL +#define WID_SHOW_IN_EXPLORER (WID_CHAOS_START + 238) + +// PROP FOLDER (VIEW) +#define WID_VIEW3_START (WID_CHAOS_START + 239) +#define WID_FLD_FONT (WID_CHAOS_START + 239) +#define WID_FLD_WEBVIEW_USE_GLOBAL (WID_CHAOS_START + 240) +#define WID_VIEW3_DUMMY2 (WID_CHAOS_START + 241) +#define WID_VIEW3_DUMMY3 (WID_CHAOS_START + 242) +#define WID_VIEW3_END (WID_CHAOS_START + 242) + +// PROP FTP +#define WID_FTP_ACCOUNT (WID_CHAOS_START + 243) + +// PROP FOLDER +#define WID_STORE_MARKED (WID_CHAOS_START + 244) + +// REPLICATION ( Currently only here to have file compatibility between +// SO51 Client and SO51 Server, for which the functionality +// first shall be implemented ). +#define WID_REPLICATION_1 (WID_CHAOS_START + 245) +#define WID_REPLICATION_2 (WID_CHAOS_START + 246) +#define WID_REPLICATION_3 (WID_CHAOS_START + 247) +#define WID_REPLICATION_4 (WID_CHAOS_START + 248) +#define WID_REPLICATION_5 (WID_CHAOS_START + 249) + +// PROP SEARCH +#define WID_SEARCH_INDIRECTIONS (WID_CHAOS_START + 250) + +// PROP ALL +#define WID_SEND_FORMATS (WID_CHAOS_START + 251) +#define WID_SEND_COPY_TARGET (WID_CHAOS_START + 252) + +// FUNC ALL +#define WID_TRANSFER_RESULT (WID_CHAOS_START + 253) + +// END +#define WID_CHAOS_END (WID_CHAOS_START + 253) + +#endif /* OLD_CHAOS */ + +#endif /* !_CNTWIDS_HRC */ diff --git a/svl/inc/converter.hxx b/svl/inc/converter.hxx new file mode 100644 index 000000000000..d012a56e7416 --- /dev/null +++ b/svl/inc/converter.hxx @@ -0,0 +1,46 @@ +/************************************************************************* + * + * 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: converter.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SV_CONVERTER_HXX_ +#define _SV_CONVERTER_HXX_ + +#include "svl/svldllapi.h" +#include <tools/solar.h> + +class SvDbaseConverter +{ +public: + SVL_DLLPUBLIC static INT32 ConvertPrecisionToDbase(INT32 _nLen, INT32 _nScale); + SVL_DLLPUBLIC static INT32 ConvertPrecisionToOdbc(INT32 _nLen, INT32 _nScale); +}; + +#endif //_CONVERTER_HXX_ + + + diff --git a/svl/inc/filenotation.hxx b/svl/inc/filenotation.hxx new file mode 100644 index 000000000000..c74c6c39c803 --- /dev/null +++ b/svl/inc/filenotation.hxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * 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: filenotation.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_FILENOTATION_HXX +#define SVTOOLS_FILENOTATION_HXX + +#include "svl/svldllapi.h" +#include <rtl/ustring.hxx> + +//......................................................................... +namespace svt +{ +//......................................................................... + + //===================================================================== + //= OFileNotation + //===================================================================== + class SVL_DLLPUBLIC OFileNotation + { + protected: + ::rtl::OUString m_sSystem; + ::rtl::OUString m_sFileURL; + + public: + enum NOTATION + { + N_SYSTEM, + N_URL + }; + + OFileNotation( const ::rtl::OUString& _rUrlOrPath ); + OFileNotation( const ::rtl::OUString& _rUrlOrPath, NOTATION _eInputNotation ); + + ::rtl::OUString get(NOTATION _eOutputNotation); + + private: + SVL_DLLPRIVATE void construct( const ::rtl::OUString& _rUrlOrPath ); + SVL_DLLPRIVATE bool implInitWithSystemNotation( const ::rtl::OUString& _rSystemPath ); + SVL_DLLPRIVATE bool implInitWithURLNotation( const ::rtl::OUString& _rURL ); + }; + +//......................................................................... +} // namespace svt +//......................................................................... + +#endif // SVTOOLS_FILENOTATION_HXX + diff --git a/svl/inc/folderrestriction.hxx b/svl/inc/folderrestriction.hxx new file mode 100644 index 000000000000..82fb4e1efef5 --- /dev/null +++ b/svl/inc/folderrestriction.hxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * 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: folderrestriction.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_FOLDER_RESTRICTION_HXX +#define SVTOOLS_FOLDER_RESTRICTION_HXX + +#include "svl/svldllapi.h" +#include <tools/string.hxx> + +#ifndef INCLUDED_VECTOR +#include <vector> +#define INCLUDED_VECTOR +#endif + +//........................................................................ +namespace svt +{ +//........................................................................ + + /** retrieves a list of folders which's access is not restricted. + + <p>Note that this is not meant as security feature, but only as + method to restrict some UI presentation, such as browsing + in the file open dialog.</p> + */ + SVL_DLLPUBLIC void getUnrestrictedFolders( ::std::vector< String >& _rFolders ); + +//........................................................................ +} // namespace svt +//........................................................................ + +#endif // SVTOOLS_FOLDER_RESTRICTION_HXX diff --git a/svl/inc/fstathelper.hxx b/svl/inc/fstathelper.hxx new file mode 100644 index 000000000000..1e613782b4e6 --- /dev/null +++ b/svl/inc/fstathelper.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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: fstathelper.hxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_FSTATHELPER_HXX +#define _SVTOOLS_FSTATHELPER_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> + +class UniString; +class Date; +class Time; + +namespace FStatHelper { + +/** Return the modified time and date stamp for this URL. + + @param URL the asking URL + + @param pDate if unequal 0, the function set the date stamp + + @param pTime if unequal 0, the function set the time stamp + + @return it was be able to get the date/time stamp +*/ +SVL_DLLPUBLIC sal_Bool GetModifiedDateTimeOfFile( const UniString& rURL, + Date* pDate, Time* pTime ); + +/** Return if under the URL a document exist. This is only a wrapper for the + UCB.IsContent. +*/ +SVL_DLLPUBLIC sal_Bool IsDocument( const UniString& rURL ); + +/** Return if under the URL a folder exist. This is only a wrapper for the + UCB.isFolder. +*/ +SVL_DLLPUBLIC sal_Bool IsFolder( const UniString& rURL ); + +} + +#endif diff --git a/svl/inc/inetdef.hxx b/svl/inc/inetdef.hxx new file mode 100644 index 000000000000..6ea380529147 --- /dev/null +++ b/svl/inc/inetdef.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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: inetdef.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <tools/inetdef.hxx> + diff --git a/svl/inc/inetmsg.hxx b/svl/inc/inetmsg.hxx new file mode 100644 index 000000000000..f011102a79e2 --- /dev/null +++ b/svl/inc/inetmsg.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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: inetmsg.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <tools/inetmsg.hxx> + diff --git a/svl/inc/inetstrm.hxx b/svl/inc/inetstrm.hxx new file mode 100644 index 000000000000..46e15d5e4cf4 --- /dev/null +++ b/svl/inc/inetstrm.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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: inetstrm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <tools/inetstrm.hxx> + diff --git a/svl/inc/instrm.hxx b/svl/inc/instrm.hxx new file mode 100644 index 000000000000..add43d4cc380 --- /dev/null +++ b/svl/inc/instrm.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * 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: instrm.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_INSTRM_HXX +#define SVTOOLS_INSTRM_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/uno/Reference.h> +#include <tools/stream.hxx> + +namespace com { namespace sun { namespace star { namespace io { + class XInputStream; + class XSeekable; +} } } } + +class SvDataPipe_Impl; + +//============================================================================ +class SVL_DLLPUBLIC SvInputStream: public SvStream +{ + com::sun::star::uno::Reference< com::sun::star::io::XInputStream > + m_xStream; + com::sun::star::uno::Reference< com::sun::star::io::XSeekable > + m_xSeekable; + SvDataPipe_Impl * m_pPipe; + ULONG m_nSeekedFrom; + + SVL_DLLPRIVATE bool open(); + + SVL_DLLPRIVATE virtual ULONG GetData(void * pData, ULONG nSize); + + SVL_DLLPRIVATE virtual ULONG PutData(void const *, ULONG); + + SVL_DLLPRIVATE virtual ULONG SeekPos(ULONG nPos); + + SVL_DLLPRIVATE virtual void FlushData(); + + SVL_DLLPRIVATE virtual void SetSize(ULONG); + +public: + SvInputStream( + com::sun::star::uno::Reference< com::sun::star::io::XInputStream > + const & + rTheStream); + + virtual ~SvInputStream(); + + virtual USHORT IsA() const; + + virtual void AddMark(ULONG nPos); + + virtual void RemoveMark(ULONG nPos); +}; + +#endif // SVTOOLS_INSTRM_HXX + diff --git a/svl/inc/listener.hxx b/svl/inc/listener.hxx new file mode 100644 index 000000000000..a121197b1dd0 --- /dev/null +++ b/svl/inc/listener.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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: listener.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVT_LISTENER_HXX +#define _SVT_LISTENER_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> + +class SvtBroadcaster; +class SfxHint; +class SvtListenerBase; + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SvtListener +{ + friend class SvtListenerBase; + SvtListenerBase *pBrdCastLst; + + const SvtListener& operator=(const SvtListener &); // n.i., ist verboten + +public: + TYPEINFO(); + + SvtListener(); + SvtListener( const SvtListener &rCopy ); + virtual ~SvtListener(); + + BOOL StartListening( SvtBroadcaster& rBroadcaster ); + BOOL EndListening( SvtBroadcaster& rBroadcaster ); + void EndListeningAll(); + BOOL IsListening( SvtBroadcaster& rBroadcaster ) const; + + BOOL HasBroadcaster() const { return 0 != pBrdCastLst; } + + virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint ); +}; + + +#endif + diff --git a/svl/inc/listeneriter.hxx b/svl/inc/listeneriter.hxx new file mode 100644 index 000000000000..a2ac5693f741 --- /dev/null +++ b/svl/inc/listeneriter.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * 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: listeneriter.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVT_LISTENERITER_HXX +#define _SVT_LISTENERITER_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> + +class SvtListener; +class SvtListenerBase; +class SvtBroadcaster; + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SvtListenerIter +{ + friend class SvtListenerBase; + + SvtBroadcaster& rRoot; + SvtListenerBase *pAkt, *pDelNext; + + // for the update of all iterator's, if a listener is added or removed + // at the same time. + static SvtListenerIter *pListenerIters; + SvtListenerIter *pNxtIter; + TypeId aSrchId; // fuer First/Next - suche diesen Type + + SVL_DLLPRIVATE static void RemoveListener( SvtListenerBase& rDel, + SvtListenerBase* pNext ); + +public: + SvtListenerIter( SvtBroadcaster& ); + ~SvtListenerIter(); + + const SvtBroadcaster& GetBroadcaster() const { return rRoot; } + SvtBroadcaster& GetBroadcaster() { return rRoot; } + + SvtListener* GoNext(); // to the next + SvtListener* GoPrev(); // to the previous + + SvtListener* GoStart(); // to the start of the list + SvtListener* GoEnd(); // to the end of the list + + SvtListener* GoRoot(); // to the root + SvtListener* GetCurr() const; // returns the current + + int IsChanged() const { return pDelNext != pAkt; } + + SvtListener* First( TypeId nType ); + SvtListener* Next(); +}; + + +#endif + diff --git a/svl/inc/lngmisc.hxx b/svl/inc/lngmisc.hxx new file mode 100644 index 000000000000..55322246f773 --- /dev/null +++ b/svl/inc/lngmisc.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * 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: lngmisc.hxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_LNGMISC_HXX_ +#define _SVTOOLS_LNGMISC_HXX_ + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <sal/types.h> +#include <rtl/ustring.hxx> + +/////////////////////////////////////////////////////////////////////////// + +#define SVT_SOFT_HYPHEN ((sal_Unicode) 0x00AD) +#define SVT_HARD_HYPHEN ((sal_Unicode) 0x2011) + +// the non-breaking space +#define SVT_HARD_SPACE ((sal_Unicode) 0x00A0) + +namespace linguistic +{ + +inline BOOL IsHyphen( sal_Unicode cChar ) +{ + return cChar == SVT_SOFT_HYPHEN || cChar == SVT_HARD_HYPHEN; +} + + +inline BOOL IsControlChar( sal_Unicode cChar ) +{ + return cChar < (sal_Unicode) ' '; +} + + +inline BOOL HasHyphens( const rtl::OUString &rTxt ) +{ + return rTxt.indexOf( SVT_SOFT_HYPHEN ) != -1 || + rTxt.indexOf( SVT_HARD_HYPHEN ) != -1; +} + +SVL_DLLPUBLIC INT32 GetNumControlChars( const rtl::OUString &rTxt ); +SVL_DLLPUBLIC BOOL RemoveHyphens( rtl::OUString &rTxt ); +SVL_DLLPUBLIC BOOL RemoveControlChars( rtl::OUString &rTxt ); + +SVL_DLLPUBLIC BOOL ReplaceControlChars( rtl::OUString &rTxt, sal_Char aRplcChar = ' ' ); + +} // namespace linguistic + +#endif diff --git a/svl/inc/makefile.mk b/svl/inc/makefile.mk new file mode 100644 index 000000000000..9368bce7cde1 --- /dev/null +++ b/svl/inc/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.4 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=.. + +PRJNAME=svl +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/svl/inc/memberid.hrc b/svl/inc/memberid.hrc new file mode 100644 index 000000000000..c917bd993e97 --- /dev/null +++ b/svl/inc/memberid.hrc @@ -0,0 +1,47 @@ +/************************************************************************* + * + * 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: memberid.hrc,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _MEMBERID_HRC +#define _MEMBERID_HRC + +#define SFX_MEMBERID(nUserData) ( ( (nUserData) >> 20 ) & 0xFF ) +#define SFX_SLOTID(nUserData) ( (nUserData) & 0xFFFF ) + +#define MID_X 1 +#define MID_Y 2 +#define MID_RECT_LEFT 3 +#define MID_RECT_TOP 4 +#define MID_WIDTH 5 +#define MID_HEIGHT 6 +#define MID_RECT_RIGHT 7 + + +#endif + diff --git a/svl/inc/nfsymbol.hxx b/svl/inc/nfsymbol.hxx new file mode 100644 index 000000000000..46fe47599359 --- /dev/null +++ b/svl/inc/nfsymbol.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: nfsymbol.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_NFSYMBOL_HXX +#define INCLUDED_SVTOOLS_NFSYMBOL_HXX + +/* ATTENTION! If new types arrive that had its content previously handled as + * SYMBOLTYPE_STRING, they have to be added at several places in zforscan.cxx + * and/or zformat.cxx, and in xmloff/source/style/xmlnumfe.cxx. Mostly these + * are places where already NF_SYMBOLTYPE_STRING together with + * NF_SYMBOLTYPE_CURRENCY or NF_SYMBOLTYPE_DATESEP are used in the same case of + * a switch respectively an if-condition. + */ + +namespace svt { + +/// Number formatter's symbol types of a token, if not key words, which are >0 +enum NfSymbolType +{ + NF_SYMBOLTYPE_STRING = -1, // literal string in output + NF_SYMBOLTYPE_DEL = -2, // special character + NF_SYMBOLTYPE_BLANK = -3, // blank for '_' + NF_SYMBOLTYPE_STAR = -4, // *-character + NF_SYMBOLTYPE_DIGIT = -5, // digit place holder + NF_SYMBOLTYPE_DECSEP = -6, // decimal separator + NF_SYMBOLTYPE_THSEP = -7, // group AKA thousand separator + NF_SYMBOLTYPE_EXP = -8, // exponent E + NF_SYMBOLTYPE_FRAC = -9, // fraction / + NF_SYMBOLTYPE_EMPTY = -10, // deleted symbols + NF_SYMBOLTYPE_FRACBLANK = -11, // delimiter between integer and fraction + NF_SYMBOLTYPE_COMMENT = -12, // comment is following + NF_SYMBOLTYPE_CURRENCY = -13, // currency symbol + NF_SYMBOLTYPE_CURRDEL = -14, // currency symbol delimiter [$] + NF_SYMBOLTYPE_CURREXT = -15, // currency symbol extension -xxx + NF_SYMBOLTYPE_CALENDAR = -16, // calendar ID + NF_SYMBOLTYPE_CALDEL = -17, // calendar delimiter [~] + NF_SYMBOLTYPE_DATESEP = -18, // date separator + NF_SYMBOLTYPE_TIMESEP = -19, // time separator + NF_SYMBOLTYPE_TIME100SECSEP = -20, // time 100th seconds separator + NF_SYMBOLTYPE_PERCENT = -21 // percent % +}; + +} // namespace svt + +#endif // INCLUDED_SVTOOLS_NFSYMBOL_HXX diff --git a/svl/inc/numuno.hxx b/svl/inc/numuno.hxx new file mode 100644 index 000000000000..d243c49a3113 --- /dev/null +++ b/svl/inc/numuno.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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: numuno.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _NUMUNO_HXX +#define _NUMUNO_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <cppuhelper/implbase2.hxx> + +class SvNumberFormatter; +class SvNumFmtSuppl_Impl; + +namespace comphelper +{ + class SharedMutex; +} + +//------------------------------------------------------------------ + +// SvNumberFormatterServiceObj must be registered as service somewhere + +com::sun::star::uno::Reference<com::sun::star::uno::XInterface> SAL_CALL + SvNumberFormatterServiceObj_NewInstance( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory>& rSMgr ); + +//------------------------------------------------------------------ + +// SvNumberFormatsSupplierObj: aggregate to document, +// construct with SvNumberFormatter + +class SVL_DLLPUBLIC SvNumberFormatsSupplierObj : public cppu::WeakAggImplHelper2< + com::sun::star::util::XNumberFormatsSupplier, + com::sun::star::lang::XUnoTunnel> +{ +private: + SvNumFmtSuppl_Impl* pImpl; + +public: + SvNumberFormatsSupplierObj(); + SvNumberFormatsSupplierObj(SvNumberFormatter* pForm); + virtual ~SvNumberFormatsSupplierObj(); + + void SetNumberFormatter(SvNumberFormatter* pNew); + SvNumberFormatter* GetNumberFormatter() const; + + // ueberladen, um Attribute im Dokument anzupassen + virtual void NumberFormatDeleted(sal_uInt32 nKey); + // ueberladen, um evtl. neu zu formatieren + virtual void SettingsChanged(); + + // XNumberFormatsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + getNumberFormatSettings() + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > SAL_CALL + getNumberFormats() + throw(::com::sun::star::uno::RuntimeException); + + // XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< + sal_Int8 >& aIdentifier ) + throw(::com::sun::star::uno::RuntimeException); + + static const com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId(); + static SvNumberFormatsSupplierObj* getImplementation( const com::sun::star::uno::Reference< + com::sun::star::util::XNumberFormatsSupplier> xObj ); + + ::comphelper::SharedMutex& getSharedMutex() const; +}; + +#endif // #ifndef _NUMUNO_HXX + + diff --git a/svl/inc/outstrm.hxx b/svl/inc/outstrm.hxx new file mode 100644 index 000000000000..c01d8f460c58 --- /dev/null +++ b/svl/inc/outstrm.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * 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: outstrm.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_OUTSTRM_HXX +#define SVTOOLS_OUTSTRM_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/uno/Reference.h> +#include <tools/stream.hxx> + +namespace com { namespace sun { namespace star { namespace io { + class XOutputStream; +} } } } + +//============================================================================ +class SVL_DLLPUBLIC SvOutputStream: public SvStream +{ + com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > + m_xStream; + + SVL_DLLPRIVATE virtual ULONG GetData(void *, ULONG); + + SVL_DLLPRIVATE virtual ULONG PutData(void const * pData, ULONG nSize); + + SVL_DLLPRIVATE virtual ULONG SeekPos(ULONG); + + SVL_DLLPRIVATE virtual void FlushData(); + + SVL_DLLPRIVATE virtual void SetSize(ULONG); + +public: + SvOutputStream(com::sun::star::uno::Reference< + com::sun::star::io::XOutputStream > const & + rTheStream); + + virtual ~SvOutputStream(); + + virtual USHORT IsA() const; +}; + +#endif // SVTOOLS_OUTSTRM_HXX + diff --git a/svl/inc/pch/precompiled_svl.cxx b/svl/inc/pch/precompiled_svl.cxx new file mode 100644 index 000000000000..27b37170856c --- /dev/null +++ b/svl/inc/pch/precompiled_svl.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * 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: precompiled_svl.cxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_svl.hxx" + diff --git a/svl/inc/pch/precompiled_svl.hxx b/svl/inc/pch/precompiled_svl.hxx new file mode 100644 index 000000000000..3a813a2db2dd --- /dev/null +++ b/svl/inc/pch/precompiled_svl.hxx @@ -0,0 +1,435 @@ +/************************************************************************* + * + * 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: precompiled_svl.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:05.076676 + +#ifdef PRECOMPILED_HEADERS + +//---MARKER--- +#include "sal/config.h" +#include "sal/types.h" + +#include "com/sun/star/accessibility/AccessibleEventId.hpp" +#include "com/sun/star/accessibility/AccessibleRelationType.hpp" +#include "com/sun/star/accessibility/AccessibleRole.hpp" +#include "com/sun/star/accessibility/AccessibleStateType.hpp" +#include "com/sun/star/accessibility/AccessibleTextType.hpp" +#include "com/sun/star/accessibility/XAccessible.hpp" +#include "com/sun/star/accessibility/XAccessibleContext.hpp" +#include "com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp" +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleEventObject.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> + +#include "com/sun/star/awt/FontWeight.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/beans/XPropertySetInfo.hpp" +#include "com/sun/star/io/XAsyncOutputMonitor.hpp" +#include "com/sun/star/lang/EventObject.hpp" +#include "com/sun/star/lang/Locale.hpp" +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/ucb/Command.hpp" +#include "com/sun/star/ucb/CommandAbortedException.hpp" +#include "com/sun/star/ucb/IllegalIdentifierException.hpp" +#include "com/sun/star/ucb/UnsupportedCommandException.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/ucb/XCommandProcessor.hpp" +#include "com/sun/star/ucb/XContent.hpp" +#include "com/sun/star/ucb/XContentIdentifier.hpp" +#include "com/sun/star/ucb/XContentIdentifierFactory.hpp" +#include "com/sun/star/ucb/XContentProvider.hpp" +#include "com/sun/star/ucb/XContentProviderManager.hpp" +#include "com/sun/star/ui/dialogs/XFilePicker.hpp" +#include "com/sun/star/ui/dialogs/XFolderPicker.hpp" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "com/sun/star/uri/XUriReferenceFactory.hpp" +#include <com/sun/star/awt/KeyEvent.hpp> +#include <com/sun/star/awt/KeyModifier.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/XFocusListener.hpp> +#include <com/sun/star/awt/XImageConsumer.hpp> +#include <com/sun/star/awt/XItemEventBroadcaster.hpp> +#include <com/sun/star/awt/XTextArea.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <com/sun/star/beans/XFastPropertySet.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XPropertiesChangeListener.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/datatransfer/XMimeContentType.hpp> +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp> +#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp> +#include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/document/XViewDataSupplier.hpp> +#include <com/sun/star/embed/Actions.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/EmbedMisc.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/embed/NoVisualAreaSizeException.hpp> +#include <com/sun/star/embed/XActionsApproval.hpp> +#include <com/sun/star/embed/XComponentSupplier.hpp> +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/embed/XExtendedStorageStream.hpp> +#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> +#include <com/sun/star/embed/XStateChangeListener.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/frame/DoubleInitializationException.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XDocumentTemplates.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> +#include <com/sun/star/frame/status/ItemState.hpp> +#include <com/sun/star/frame/status/ItemStatus.hpp> +#include <com/sun/star/frame/status/Visibility.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/i18n/AmPmValue.hpp> +#include <com/sun/star/i18n/CalendarDisplayCode.hpp> +#include <com/sun/star/i18n/CalendarDisplayIndex.hpp> +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> +#include <com/sun/star/i18n/CharacterIteratorMode.hpp> +#include <com/sun/star/i18n/CollatorOptions.hpp> +#include <com/sun/star/i18n/InputSequenceCheckMode.hpp> +#include <com/sun/star/i18n/KNumberFormatType.hpp> +#include <com/sun/star/i18n/KNumberFormatUsage.hpp> +#include <com/sun/star/i18n/NumberFormatCode.hpp> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <com/sun/star/i18n/TransliterationModules.hpp> +#include <com/sun/star/i18n/Weekdays.hpp> +#include <com/sun/star/i18n/WordType.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/i18n/XExtendedCalendar.hpp> +#include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp> +#include <com/sun/star/io/IOException.hpp> +#include <com/sun/star/io/NotConnectedException.hpp> +#include <com/sun/star/io/XActiveDataControl.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XPersist.hpp> +#include <com/sun/star/io/XPersistObject.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/java/InvalidJavaSettingsException.hpp> +#include <com/sun/star/java/JavaDisabledException.hpp> +#include <com/sun/star/java/JavaNotFoundException.hpp> +#include <com/sun/star/java/JavaVMCreationFailureException.hpp> +#include <com/sun/star/java/RestartRequiredException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/packages/NoEncryptionException.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <com/sun/star/sdb/XCompletedConnection.hpp> +#include <com/sun/star/sdbc/SQLWarning.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/sdbc/XDataSource.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#include <com/sun/star/svg/XSVGWriter.hpp> +#include <com/sun/star/system/SystemShellExecuteFlags.hpp> +#include <com/sun/star/system/XProxySettings.hpp> +#include <com/sun/star/system/XSystemShellExecute.hpp> +#include <com/sun/star/task/DocumentPasswordRequest.hpp> +#include <com/sun/star/task/DocumentMSPasswordRequest.hpp> +#include <com/sun/star/task/MasterPasswordRequest.hpp> +#include <com/sun/star/task/NoMasterException.hpp> +#include <com/sun/star/task/PasswordRequestMode.hpp> +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionContinuation.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/task/XInteractionPassword.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <com/sun/star/task/XInteractionRetry.hpp> +#include <com/sun/star/task/XJob.hpp> +#include <com/sun/star/task/XJobExecutor.hpp> +#include <com/sun/star/task/XPasswordContainer.hpp> +#include <com/sun/star/ucb/CommandAbortedException.hpp> +#include <com/sun/star/ucb/ContentCreationException.hpp> +#include <com/sun/star/ucb/FileSystemNotation.hpp> +#include <com/sun/star/ucb/IOErrorCode.hpp> +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/ucb/TransferResult.hpp> +#include <com/sun/star/ucb/XAnyCompareFactory.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/XContentProviderManager.hpp> +#include <com/sun/star/ucb/XDynamicResultSet.hpp> +#include <com/sun/star/ucb/XProgressHandler.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp> +#include <com/sun/star/ui/ImageType.hpp> +#include <com/sun/star/ui/XAcceleratorConfiguration.hpp> +#include <com/sun/star/ui/XImageManager.hpp> +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/XUIConfigurationManager.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Sequence.h> +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/uno/XCurrentContext.hpp> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/uno/XWeak.hpp> +#include <com/sun/star/util/AliasProgrammaticPair.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/util/DateTimeRange.hpp> +#include <com/sun/star/util/SearchAlgorithms.hpp> +#include <com/sun/star/util/SearchFlags.hpp> +#include <com/sun/star/util/SearchOptions.hpp> +#include <com/sun/star/util/SearchResult.hpp> +#include <com/sun/star/util/URL.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/util/XCloseBroadcaster.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/util/XModifyListener.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <com/sun/star/util/XNumberFormats.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/util/XOfficeInstallationDirectories.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/util/XUpdatable.hpp> +#include <com/sun/star/view/XPrintable.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> + +#include <algorithm> +#include <deque> +#include <hash_map> +#include <limits> + +#include <list> +#include <map> +#include <memory> +#include <queue> +#include <set> +#include <stack> +#include <utility> +#include <vector> + + +#include <i18npool/lang.h> +#include <i18npool/mslangid.hxx> + +#include "comphelper/processfactory.hxx" +#include <comphelper/accessibleeventnotifier.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/configurationhelper.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/regpathhelper.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/stl_types.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/types.hxx> +#include <comphelper/uno3.hxx> + +#include "cppuhelper/bootstrap.hxx" +#include "cppuhelper/exc_hlp.hxx" +#include "cppuhelper/factory.hxx" +#include "cppuhelper/interfacecontainer.hxx" +#include "cppuhelper/weakref.hxx" +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/propshlp.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/weakagg.hxx> +#include <cppuhelper/weakref.hxx> + +#include <osl/conditn.hxx> +#include <osl/conditn.hxx> +#include <osl/diagnose.h> +#include <osl/endian.h> +#include <osl/file.h> +#include <osl/file.hxx> +#include <osl/module.h> +#include <osl/module.hxx> +#include <osl/mutex.h> +#include <osl/mutex.hxx> +#include <osl/process.h> +#include <osl/thread.h> +#include <osl/thread.hxx> + +#include <rsc/rscsfx.hxx> + +#include "rtl/crc.h" +#include "rtl/memory.h" +#include "rtl/strbuf.hxx" +#include "rtl/string.h" +#include "rtl/string.hxx" +#include "rtl/textenc.h" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include <rtl/alloc.h> +#include <rtl/byteseq.hxx> +#include <rtl/cipher.h> +#include <rtl/crc.h> +#include <rtl/digest.h> +#include <rtl/logfile.hxx> +#include <rtl/math.hxx> +#include <rtl/memory.h> +#include <rtl/strbuf.hxx> +#include <rtl/string.hxx> +#include <rtl/tencinfo.h> +#include <rtl/textcvt.h> +#include <rtl/textenc.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.h> +#include <rtl/ustring.hxx> +#include <rtl/uuid.h> + +#include "unotools/configitem.hxx" +#include "unotools/configmgr.hxx" + +#include <sot/clsids.hxx> + +#include <tools/inetdef.hxx> + +#include <ucbhelper/commandenvironment.hxx> +#include <ucbhelper/content.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/fileidentifierconverter.hxx> + +#include <uno/mapping.hxx> + +#include <unotools/bootstrap.hxx> +#include <unotools/collatorwrapper.hxx> +#include <unotools/configitem.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/confignode.hxx> +#include <unotools/configpathes.hxx> +#include <unotools/nativenumberwrapper.hxx> +#include <unotools/numberformatcodewrapper.hxx> +#include <unotools/processfactory.hxx> + +#include <vos/mutex.hxx> +#include <vos/process.hxx> +#include <vos/ref.hxx> +#include <vos/refernce.hxx> +#include <vos/security.hxx> +#include <vos/thread.hxx> +#include <vos/timer.hxx> + +//---MARKER--- + +#endif + diff --git a/svl/inc/pickerhelper.hxx b/svl/inc/pickerhelper.hxx new file mode 100644 index 000000000000..e8ef23e145d4 --- /dev/null +++ b/svl/inc/pickerhelper.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: pickerhelper.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PICKERHELPER_HXX +#define _PICKERHELPER_HXX + +#include "svl/svldllapi.h" +#include "sal/types.h" +#include "com/sun/star/uno/Reference.hxx" + +namespace com +{ + namespace sun + { + namespace star + { + namespace ui + { + namespace dialogs + { + class XFilePicker; + class XFolderPicker; + } + } + } + } +} + + +namespace svt +{ + + SVL_DLLPUBLIC void SetDialogHelpId( + ::com::sun::star::uno::Reference < ::com::sun::star::ui::dialogs::XFilePicker > _mxFileDlg, + sal_Int32 _nHelpId ); + + SVL_DLLPUBLIC void SetDialogHelpId( + ::com::sun::star::uno::Reference < ::com::sun::star::ui::dialogs::XFolderPicker > _mxFileDlg, + sal_Int32 _nHelpId ); + +} + +//----------------------------------------------------------------------------- + +#endif diff --git a/svl/inc/pickerhistory.hxx b/svl/inc/pickerhistory.hxx new file mode 100644 index 000000000000..e67729a1bbd8 --- /dev/null +++ b/svl/inc/pickerhistory.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * 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: pickerhistory.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_PICKERHISTORY_HXX +#define SVTOOLS_PICKERHISTORY_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/uno/XInterface.hpp> + +//......................................................................... +namespace svt +{ +//......................................................................... + + // -------------------------------------------------------------------- + SVL_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + GetTopMostFolderPicker( ); + + SVL_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + GetTopMostFilePicker( ); + +//......................................................................... +} // namespace svt +//......................................................................... + +#endif // SVTOOLS_PICKERHISTORY_HXX + diff --git a/svl/inc/pickerhistoryaccess.hxx b/svl/inc/pickerhistoryaccess.hxx new file mode 100644 index 000000000000..210fd9b92139 --- /dev/null +++ b/svl/inc/pickerhistoryaccess.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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: pickerhistoryaccess.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_PICKERHISTORYACCESS_HXX +#define SVTOOLS_PICKERHISTORYACCESS_HXX + +#include "svl/svldllapi.h" + +#ifndef _COM_SUN_STAR_UNO_REFERENX_HXX_ +#include <com/sun/star/uno/Reference.hxx> +#endif + +//......................................................................... +namespace svt +{ +//......................................................................... + + // -------------------------------------------------------------------- + SVL_DLLPUBLIC void addFolderPicker( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxPicker ); + + SVL_DLLPUBLIC void addFilePicker( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxPicker ); + +//......................................................................... +} // namespace svt +//......................................................................... + +#endif // SVTOOLS_PICKERHISTORYACCESS_HXX + diff --git a/svl/inc/poolcach.hxx b/svl/inc/poolcach.hxx new file mode 100644 index 000000000000..21cfec4662a0 --- /dev/null +++ b/svl/inc/poolcach.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * 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: poolcach.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXPOOLCACH_HXX +#define _SFXPOOLCACH_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> + +class SfxItemModifyArr_Impl; +class SfxItemPool; +class SfxItemSet; +class SfxPoolItem; +class SfxSetItem; + +class SVL_DLLPUBLIC SfxItemPoolCache +{ + SfxItemPool *pPool; + SfxItemModifyArr_Impl *pCache; + const SfxItemSet *pSetToPut; + const SfxPoolItem *pItemToPut; + +public: + SfxItemPoolCache( SfxItemPool *pPool, + const SfxPoolItem *pPutItem ); + SfxItemPoolCache( SfxItemPool *pPool, + const SfxItemSet *pPutSet ); + ~SfxItemPoolCache(); + + const SfxSetItem& ApplyTo( const SfxSetItem& rSetItem, BOOL bNew = FALSE ); +}; + + +#endif + diff --git a/svl/inc/strmadpt.hxx b/svl/inc/strmadpt.hxx new file mode 100644 index 000000000000..2fd190f9adef --- /dev/null +++ b/svl/inc/strmadpt.hxx @@ -0,0 +1,138 @@ +/************************************************************************* + * + * 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: strmadpt.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_STRMADPT_HXX +#define SVTOOLS_STRMADPT_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <cppuhelper/weak.hxx> +#include <tools/stream.hxx> + +//============================================================================ +class SVL_DLLPUBLIC SvOutputStreamOpenLockBytes: public SvOpenLockBytes +{ + com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > + m_xOutputStream; + sal_uInt32 m_nPosition; + +public: + TYPEINFO(); + + SvOutputStreamOpenLockBytes( + const com::sun::star::uno::Reference< + com::sun::star::io::XOutputStream > & + rTheOutputStream): + m_xOutputStream(rTheOutputStream), m_nPosition(0) {} + + virtual ErrCode ReadAt(ULONG, void *, ULONG, ULONG *) const; + + virtual ErrCode WriteAt(ULONG nPos, const void * pBuffer, ULONG nCount, + ULONG * pWritten); + + virtual ErrCode Flush() const; + + virtual ErrCode SetSize(ULONG); + + virtual ErrCode Stat(SvLockBytesStat * pStat, SvLockBytesStatFlag) const; + + virtual ErrCode FillAppend(const void * pBuffer, ULONG nCount, + ULONG * pWritten); + + virtual ULONG Tell() const; + + virtual ULONG Seek(ULONG); + + virtual void Terminate(); +}; + +//============================================================================ +class SVL_DLLPUBLIC SvLockBytesInputStream: public cppu::OWeakObject, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable +{ + SvLockBytesRef m_xLockBytes; + sal_Int64 m_nPosition; + bool m_bDone; + +public: + SvLockBytesInputStream(SvLockBytes * pTheLockBytes): + m_xLockBytes(pTheLockBytes), m_nPosition(0), m_bDone(false) {} + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface(const com::sun::star::uno::Type & rType) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL acquire() throw(); + + virtual void SAL_CALL release() throw(); + + virtual sal_Int32 SAL_CALL + readBytes(com::sun::star::uno::Sequence< sal_Int8 > & rData, + sal_Int32 nBytesToRead) + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + readSomeBytes(com::sun::star::uno::Sequence< sal_Int8 > & rData, + sal_Int32 nMaxBytesToRead) + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL skipBytes(sal_Int32 nBytesToSkip) + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL available() + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL closeInput() + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL seek(sal_Int64 nLocation) + throw (com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int64 SAL_CALL getPosition() + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int64 SAL_CALL getLength() + throw (com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); +}; + +#endif // SVTOOLS_STRMADPT_HXX + diff --git a/svl/inc/stylepool.hxx b/svl/inc/stylepool.hxx new file mode 100644 index 000000000000..d69bb928e432 --- /dev/null +++ b/svl/inc/stylepool.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * 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: stylepool.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_SVTOOLS_STYLEPOOL_HXX +#define INCLUDED_SVTOOLS_STYLEPOOL_HXX + +#include <boost/shared_ptr.hpp> +#include <rtl/ustring.hxx> +#include <svl/itemset.hxx> + +class StylePoolImpl; +class StylePoolIterImpl; +class IStylePoolIteratorAccess; + +class SVL_DLLPUBLIC StylePool +{ +private: + StylePoolImpl *pImpl; +public: + typedef boost::shared_ptr<SfxItemSet> SfxItemSet_Pointer_t; + + // --> OD 2008-03-07 #i86923# + explicit StylePool( SfxItemSet* pIgnorableItems = 0 ); + // <-- + + /** Insert a SfxItemSet into the style pool. + + The pool makes a copy of the provided SfxItemSet. + + @param SfxItemSet + the SfxItemSet to insert + + @return a shared pointer to the SfxItemSet + */ + virtual SfxItemSet_Pointer_t insertItemSet( const SfxItemSet& rSet ); + + /** Create an iterator + + The iterator walks through the StylePool + OD 2008-03-07 #i86923# + introduce optional parameter to control, if unused SfxItemsSet are skipped or not + introduce optional parameter to control, if ignorable items are skipped or not + + @attention every change, e.g. destruction, of the StylePool could cause undefined effects. + + @param bSkipUnusedItemSets + input parameter - boolean, indicating if unused SfxItemSets are skipped or not + + @param bSkipIgnorableItems + input parameter - boolean, indicating if ignorable items are skipped or not + + @postcond the iterator "points before the first" SfxItemSet of the pool. + The first StylePoolIterator::getNext() call will deliver the first SfxItemSet. + */ + virtual IStylePoolIteratorAccess* createIterator( const bool bSkipUnusedItemSets = false, + const bool bSkipIgnorableItems = false ); + + /** Returns the number of styles + */ + virtual sal_Int32 getCount() const; + + virtual ~StylePool(); + + static ::rtl::OUString nameOf( SfxItemSet_Pointer_t pSet ); +}; + +class SVL_DLLPUBLIC IStylePoolIteratorAccess +{ +public: + /** Delivers a shared pointer to the next SfxItemSet of the pool + If there is no more SfxItemSet, the delivered share_pointer is empty. + */ + virtual StylePool::SfxItemSet_Pointer_t getNext() = 0; + virtual ::rtl::OUString getName() = 0; + virtual ~IStylePoolIteratorAccess() {}; +}; +#endif diff --git a/svl/inc/svl/aeitem.hxx b/svl/inc/svl/aeitem.hxx new file mode 100644 index 000000000000..446d9b8aeeb7 --- /dev/null +++ b/svl/inc/svl/aeitem.hxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * 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: aeitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _AEITEM_HXX +#define _AEITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/poolitem.hxx> +#include <svl/eitem.hxx> + +class SfxAllEnumValueArr; +class SvUShorts; + +class SVL_DLLPUBLIC SfxAllEnumItem: public SfxEnumItem +{ + SfxAllEnumValueArr* pValues; + SvUShorts* pDisabledValues; + +protected: + USHORT _GetPosByValue( USHORT nValue ) const; + +public: + TYPEINFO(); + SfxAllEnumItem(); + SfxAllEnumItem( USHORT nWhich); + SfxAllEnumItem( USHORT nWhich, USHORT nVal ); + SfxAllEnumItem( USHORT nWhich, USHORT nVal, const XubString &rText ); + SfxAllEnumItem( USHORT nWhich, SvStream &rStream ); + SfxAllEnumItem( const SfxAllEnumItem & ); + ~SfxAllEnumItem(); + + void InsertValue( USHORT nValue ); + void InsertValue( USHORT nValue, const XubString &rText ); + void RemoveValue( USHORT nValue ); + void RemoveAllValues(); + + USHORT GetPosByValue( USHORT nValue ) const; + + virtual USHORT GetValueCount() const; + virtual USHORT GetValueByPos( USHORT nPos ) const; + virtual XubString GetValueTextByPos( USHORT nPos ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nVersion) const; + virtual BOOL IsEnabled( USHORT ) const; + void DisableValue( USHORT ); +}; + +#endif diff --git a/svl/inc/svl/brdcst.hxx b/svl/inc/svl/brdcst.hxx new file mode 100644 index 000000000000..cfa45d5aa89a --- /dev/null +++ b/svl/inc/svl/brdcst.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * 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: brdcst.hxx,v $ + * $Revision: 1.3.60.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXBRDCST_HXX +#define _SFXBRDCST_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> +#include <svl/svarray.hxx> + +class SfxListener; +class SfxHint; + +#ifndef _SFX_BRDCST_CXX +typedef SvPtrarr SfxListenerArr_Impl; +#endif + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxBroadcaster +{ +friend class SfxListener; + + SfxListenerArr_Impl aListeners; + +private: + BOOL AddListener( SfxListener& rListener ); + void RemoveListener( SfxListener& rListener ); + const SfxBroadcaster& operator=(const SfxBroadcaster &); // verboten + +protected: + void Forward(SfxBroadcaster& rBC, const SfxHint& rHint); + virtual void ListenersGone(); + +public: + TYPEINFO(); + + SfxBroadcaster(); + SfxBroadcaster( const SfxBroadcaster &rBC ); + virtual ~SfxBroadcaster(); + + void Broadcast( const SfxHint &rHint ); + void BroadcastDelayed( const SfxHint& rHint ); + void BroadcastInIdle( const SfxHint& rHint ); + + BOOL HasListeners() const; + USHORT GetListenerCount() const { return aListeners.Count(); } + SfxListener* GetListener( USHORT nNo ) const + { return (SfxListener*) aListeners[nNo]; } +}; + +#endif diff --git a/svl/inc/svl/cancel.hxx b/svl/inc/svl/cancel.hxx new file mode 100644 index 000000000000..2808b77d3139 --- /dev/null +++ b/svl/inc/svl/cancel.hxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * 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: cancel.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXCANCEL_HXX +#define _SFXCANCEL_HXX + +#include "svl/svldllapi.h" +#include <tools/string.hxx> +#include <tools/ref.hxx> +#include <svl/brdcst.hxx> +#include <svl/smplhint.hxx> + +class SfxCancellable; + +#ifdef _SFX_CANCEL_CXX +#include <svl/svarray.hxx> + +SV_DECL_PTRARR( SfxCancellables_Impl, SfxCancellable*, 0, 4 ) + +#else + +typedef SvPtrarr SfxCancellables_Impl; + +#endif + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxCancelManager: public SfxBroadcaster +, public SvWeakBase + +/* [Beschreibung] + + An Instanzen dieser Klasse k"onnen nebenl"aufige Prozesse angemeldet + werden, um vom Benutzer abbrechbar zu sein. Werden abbrechbare + Prozesse (Instanzen von <SfxCancellable>) an- oder abgemeldet, wird + dies durch einen <SfxSimpleHint> mit dem Flag SFX_HINT_CANCELLABLE + gebroadcastet. + + SfxCancelManager k"onnen hierarchisch angeordnet werden, so k"onnen + z.B. Dokument-lokale Prozesse getrennt gecancelt werden. + + [Beispiel] + + SfxCancelManager *pMgr = new SfxCancelManager; + StartListening( pMgr ); + pMailSystem->SetCancelManager( pMgr ) +*/ + +{ + SfxCancelManager* _pParent; + SfxCancellables_Impl _aJobs; + +public: + SfxCancelManager( SfxCancelManager *pParent = 0 ); + ~SfxCancelManager(); + + BOOL CanCancel() const; + void Cancel( BOOL bDeep ); + SfxCancelManager* GetParent() const { return _pParent; } + + void InsertCancellable( SfxCancellable *pJob ); + void RemoveCancellable( SfxCancellable *pJob ); + USHORT GetCancellableCount() const + { return _aJobs.Count(); } + SfxCancellable* GetCancellable( USHORT nPos ) const + { return (SfxCancellable*) _aJobs[nPos]; } +}; + +SV_DECL_WEAK( SfxCancelManager ) +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxCancellable + +/* [Beschreibung] + + Instanzen dieser Klasse werden immer an einem Cancel-Manager angemeldet, + der dadurch dem Benutzer signalisieren kann, ob abbrechbare Prozesse + vorhanden sind und der die SfxCancellable-Instanzen auf 'abgebrochen' + setzen kann. + + Die im Ctor "ubergebene <SfxCancelManger>-Instanz mu\s die Instanz + dieser Klasse "uberleben! + + [Beispiel] + + { + SfxCancellable aCancel( pCancelMgr ); + while ( !aCancel && GetData() ) + Reschedule(); + } + +*/ + +{ + SfxCancelManager* _pMgr; + BOOL _bCancelled; + String _aTitle; + +public: + SfxCancellable( SfxCancelManager *pMgr, + const String &rTitle ) + : _pMgr( pMgr ), + _bCancelled( FALSE ), + _aTitle( rTitle ) + { pMgr->InsertCancellable( this ); } + + virtual ~SfxCancellable(); + + void SetManager( SfxCancelManager *pMgr ); + SfxCancelManager* GetManager() const { return _pMgr; } + + virtual void Cancel(); + BOOL IsCancelled() const { return _bCancelled; } + operator BOOL() const { return _bCancelled; } + const String& GetTitle() const { return _aTitle; } +}; + +#endif + diff --git a/svl/inc/svl/cenumitm.hxx b/svl/inc/svl/cenumitm.hxx new file mode 100644 index 000000000000..3d354899cd9d --- /dev/null +++ b/svl/inc/svl/cenumitm.hxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * 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: cenumitm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_CENUMITM_HXX +#define _SVTOOLS_CENUMITM_HXX + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <svl/poolitem.hxx> + +//============================================================================ +DBG_NAMEEX(SfxEnumItemInterface) + +class SVL_DLLPUBLIC SfxEnumItemInterface: public SfxPoolItem +{ +protected: + SfxEnumItemInterface(USHORT which): SfxPoolItem(which) {} + + SfxEnumItemInterface(const SfxEnumItemInterface & rItem): + SfxPoolItem(rItem) {} + +public: + TYPEINFO(); + + virtual int operator ==(const SfxPoolItem & rItem) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any & rVal, BYTE = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any & rVal, BYTE = 0); + + virtual USHORT GetValueCount() const = 0; + + virtual XubString GetValueTextByPos(USHORT nPos) const; + + virtual USHORT GetValueByPos(USHORT nPos) const; + + /// Return the position of some value within this enumeration. + /// + /// @descr This method is implemented using GetValueCount() and + /// GetValueByPos(). Derived classes may replace this with a more + /// efficient implementation. + /// + /// @param nValue Some value. + /// + /// @return The position of nValue within this enumeration, or USHRT_MAX + /// if not included. + virtual USHORT GetPosByValue(USHORT nValue) const; + + virtual BOOL IsEnabled(USHORT nValue) const; + + virtual USHORT GetEnumValue() const = 0; + + virtual void SetEnumValue(USHORT nValue) = 0; + + virtual int HasBoolValue() const; + + virtual BOOL GetBoolValue() const; + + virtual void SetBoolValue(BOOL bValue); +}; + +//============================================================================ +DBG_NAMEEX(CntEnumItem) + +class SVL_DLLPUBLIC CntEnumItem: public SfxEnumItemInterface +{ + USHORT m_nValue; + +protected: + CntEnumItem(USHORT which = 0, USHORT nTheValue = 0): + SfxEnumItemInterface(which), m_nValue(nTheValue) {} + + CntEnumItem(USHORT which, SvStream & rStream); + + CntEnumItem(const CntEnumItem & rItem): + SfxEnumItemInterface(rItem), m_nValue(rItem.m_nValue) {} + +public: + TYPEINFO(); + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual USHORT GetEnumValue() const; + + virtual void SetEnumValue(USHORT nTheValue); + + USHORT GetValue() const { return m_nValue; } + + inline void SetValue(USHORT nTheValue); +}; + +inline void CntEnumItem::SetValue(USHORT nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "CntEnumItem::SetValue(): Pooled item"); + m_nValue = nTheValue; +} + +//============================================================================ +DBG_NAMEEX(CntBoolItem) + +class SVL_DLLPUBLIC CntBoolItem: public SfxPoolItem +{ + BOOL m_bValue; + +public: + TYPEINFO(); + + CntBoolItem(USHORT which = 0, BOOL bTheValue = FALSE): + SfxPoolItem(which), m_bValue(bTheValue) {} + + CntBoolItem(USHORT nWhich, SvStream & rStream); + + CntBoolItem(const CntBoolItem & rItem): + SfxPoolItem(rItem), m_bValue(rItem.m_bValue) {} + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + UniString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, BYTE = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, BYTE = 0); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual USHORT GetValueCount() const; + + virtual UniString GetValueTextByVal(BOOL bTheValue) const; + + BOOL GetValue() const { return m_bValue; } + + void SetValue(BOOL bTheValue) { m_bValue = bTheValue; } +}; + +#endif // _SVTOOLS_CENUMITM_HXX + diff --git a/svl/inc/svl/cintitem.hxx b/svl/inc/svl/cintitem.hxx new file mode 100644 index 000000000000..72421f93e0cb --- /dev/null +++ b/svl/inc/svl/cintitem.hxx @@ -0,0 +1,286 @@ +/************************************************************************* + * + * 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: cintitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_CINTITEM_HXX +#define _SVTOOLS_CINTITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <svl/poolitem.hxx> + +//============================================================================ +DBG_NAMEEX_VISIBILITY(CntByteItem, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC CntByteItem: public SfxPoolItem +{ + BYTE m_nValue; + +public: + TYPEINFO(); + + CntByteItem(USHORT which = 0, BYTE nTheValue = 0): + SfxPoolItem(which), m_nValue(nTheValue) { DBG_CTOR(CntByteItem, 0); } + + CntByteItem(USHORT which, SvStream & rStream); + + CntByteItem(const CntByteItem & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(CntByteItem, 0); } + + virtual ~CntByteItem() { DBG_DTOR(CntByteItem, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual BYTE GetMin() const; + + virtual BYTE GetMax() const; + + virtual SfxFieldUnit GetUnit() const; + + BYTE GetValue() const { return m_nValue; } + + inline void SetValue(BYTE nTheValue); +}; + +inline void CntByteItem::SetValue(BYTE nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "CntByteItem::SetValue(): Pooled item"); + m_nValue = nTheValue; +} + +//============================================================================ +DBG_NAMEEX_VISIBILITY(CntUInt16Item, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC CntUInt16Item: public SfxPoolItem +{ + UINT16 m_nValue; + +public: + TYPEINFO(); + + CntUInt16Item(USHORT which = 0, UINT16 nTheValue = 0): + SfxPoolItem(which), m_nValue(nTheValue) + { DBG_CTOR(CntUInt16Item, 0); } + + CntUInt16Item(USHORT which, SvStream & rStream); + + CntUInt16Item(const CntUInt16Item & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(CntUInt16Item, 0); } + + virtual ~CntUInt16Item() { DBG_DTOR(CntUInt16Item, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual UINT16 GetMin() const; + + virtual UINT16 GetMax() const; + + virtual SfxFieldUnit GetUnit() const; + + INT16 GetValue() const { return m_nValue; } + + inline void SetValue(UINT16 nTheValue); +}; + +inline void CntUInt16Item::SetValue(UINT16 nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "CntUInt16Item::SetValue(): Pooled item"); + m_nValue = nTheValue; +} + +//============================================================================ +DBG_NAMEEX_VISIBILITY(CntInt32Item, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC CntInt32Item: public SfxPoolItem +{ + INT32 m_nValue; + +public: + TYPEINFO(); + + CntInt32Item(USHORT which = 0, INT32 nTheValue = 0): + SfxPoolItem(which), m_nValue(nTheValue) + { DBG_CTOR(CntInt32Item, 0); } + + CntInt32Item(USHORT which, SvStream & rStream); + + CntInt32Item(const CntInt32Item & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(CntInt32Item, 0); } + + virtual ~CntInt32Item() { DBG_DTOR(CntInt32Item, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream &, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual INT32 GetMin() const; + + virtual INT32 GetMax() const; + + virtual SfxFieldUnit GetUnit() const; + + INT32 GetValue() const { return m_nValue; } + + inline void SetValue(INT32 nTheValue); +}; + +inline void CntInt32Item::SetValue(INT32 nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "CntInt32Item::SetValue(): Pooled item"); + m_nValue = nTheValue; +} + +//============================================================================ +DBG_NAMEEX_VISIBILITY(CntUInt32Item, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC CntUInt32Item: public SfxPoolItem +{ + UINT32 m_nValue; + +public: + TYPEINFO(); + + CntUInt32Item(USHORT which = 0, UINT32 nTheValue = 0): + SfxPoolItem(which), m_nValue(nTheValue) + { DBG_CTOR(CntUInt32Item, 0); } + + CntUInt32Item(USHORT nWhich, SvStream & rStream); + + CntUInt32Item(const CntUInt32Item & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(CntUInt32Item, 0); } + + virtual ~CntUInt32Item() { DBG_DTOR(CntUInt32Item, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual UINT32 GetMin() const; + + virtual UINT32 GetMax() const; + + virtual SfxFieldUnit GetUnit() const; + + UINT32 GetValue() const { return m_nValue; } + + inline void SetValue(UINT32 nTheValue); +}; + +inline void CntUInt32Item::SetValue(UINT32 nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "CntUInt32Item::SetValue(): Pooled item"); + m_nValue = nTheValue; +} + +#endif // _SVTOOLS_CINTITEM_HXX + diff --git a/svl/inc/svl/cjkoptions.hxx b/svl/inc/svl/cjkoptions.hxx new file mode 100644 index 000000000000..720ead5422f0 --- /dev/null +++ b/svl/inc/svl/cjkoptions.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * 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: cjkoptions.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVTOOLS_CJKOPTIONS_HXX +#define _SVTOOLS_CJKOPTIONS_HXX + +#include "svl/svldllapi.h" +#include <sal/types.h> +#include <unotools/options.hxx> + +class SvtCJKOptions_Impl; + +// class SvtCJKOptions -------------------------------------------------- + +class SVL_DLLPUBLIC SvtCJKOptions: public utl::detail::Options +{ +private: + SvtCJKOptions_Impl* pImp; + +public: + + enum EOption + { + E_CJKFONT, + E_VERTICALTEXT, + E_ASIANTYPOGRAPHY, + E_JAPANESEFIND, + E_RUBY, + E_CHANGECASEMAP, + E_DOUBLELINES, + E_EMPHASISMARKS, + E_VERTICALCALLOUT, + E_ALL // special one for IsAnyEnabled()/SetAll() functionality + }; + + // bDontLoad is for referencing purposes only + SvtCJKOptions(sal_Bool bDontLoad = sal_False); + virtual ~SvtCJKOptions(); + + sal_Bool IsCJKFontEnabled() const; + sal_Bool IsVerticalTextEnabled() const; + sal_Bool IsAsianTypographyEnabled() const; + sal_Bool IsJapaneseFindEnabled() const; + sal_Bool IsRubyEnabled() const; + sal_Bool IsChangeCaseMapEnabled() const; + sal_Bool IsDoubleLinesEnabled() const; + sal_Bool IsEmphasisMarksEnabled() const; + sal_Bool IsVerticalCallOutEnabled() const; + + void SetAll(sal_Bool bSet); + sal_Bool IsAnyEnabled() const; + sal_Bool IsReadOnly(EOption eOption) const; +}; + +#endif // _SVTOOLS_CJKOPTIONS_HXX + diff --git a/svl/inc/svl/cnclhint.hxx b/svl/inc/svl/cnclhint.hxx new file mode 100644 index 000000000000..a2ce75ac1a4b --- /dev/null +++ b/svl/inc/svl/cnclhint.hxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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: cnclhint.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXCNCLHINT_HXX +#define _SFXCNCLHINT_HXX + +#include <svl/hint.hxx> +#include <svl/cancel.hxx> +#include <tools/rtti.hxx> + +#define SFXCANCELHINT_REMOVED 1 + +class SfxCancelHint: public SfxHint +{ +private: + SfxCancellable* pCancellable; + USHORT nAction; +public: + TYPEINFO(); + SfxCancelHint( SfxCancellable*, USHORT nAction ); + USHORT GetAction() const { return nAction; } + const SfxCancellable& GetCancellable() const { return *pCancellable; } +}; + +#endif diff --git a/svl/inc/svl/cntwall.hxx b/svl/inc/svl/cntwall.hxx new file mode 100644 index 000000000000..dca27f2284e6 --- /dev/null +++ b/svl/inc/svl/cntwall.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * 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: cntwall.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CNTWALL_HXX +#define _CNTWALL_HXX + +#include "svl/svldllapi.h" + +#ifndef SHL_HXX +#include <tools/shl.hxx> +#endif +#include <tools/rtti.hxx> +#include <tools/color.hxx> +#include <svl/poolitem.hxx> + +class SvStream; + +class SVL_DLLPUBLIC CntWallpaperItem : public SfxPoolItem +{ +private: + UniString _aURL; + Color _nColor; + USHORT _nStyle; + +public: + TYPEINFO(); + + CntWallpaperItem( USHORT nWhich ); + CntWallpaperItem( USHORT nWhich, SvStream& rStream, USHORT nVersion ); + CntWallpaperItem( const CntWallpaperItem& rCpy ); + ~CntWallpaperItem(); + + virtual USHORT GetVersion(USHORT) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Create( SvStream&, USHORT nItemVersion ) const; + virtual SvStream& Store( SvStream&, USHORT nItemVersion ) const; + virtual SfxPoolItem* Clone( SfxItemPool* pPool = 0 ) const; + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + + void SetBitmapURL( const UniString& rURL ) { _aURL = rURL; } + void SetColor( Color nColor ) { _nColor = nColor; } + void SetStyle( USHORT nStyle ) { _nStyle = nStyle; } + + const UniString& GetBitmapURL() const { return _aURL; } + Color GetColor() const { return _nColor; } + USHORT GetStyle() const { return _nStyle; } +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif // _CNTWALL_HXX + diff --git a/svl/inc/svl/ctloptions.hxx b/svl/inc/svl/ctloptions.hxx new file mode 100644 index 000000000000..28b2191cad94 --- /dev/null +++ b/svl/inc/svl/ctloptions.hxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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: ctloptions.hxx,v $ + * $Revision: 1.3.164.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVTOOLS_CTLOPTIONS_HXX +#define _SVTOOLS_CTLOPTIONS_HXX + +#include "svl/svldllapi.h" +#include <sal/types.h> +#include <svl/brdcst.hxx> +#include <svl/lstner.hxx> +#include <unotools/options.hxx> + +class SvtCTLOptions_Impl; + +// class SvtCTLOptions -------------------------------------------------------- + +class SVL_DLLPUBLIC SvtCTLOptions : public utl::detail::Options +{ +private: + SvtCTLOptions_Impl* m_pImp; + +public: + + // bDontLoad is for referencing purposes only + SvtCTLOptions( sal_Bool bDontLoad = sal_False ); + virtual ~SvtCTLOptions(); + + void SetCTLFontEnabled( sal_Bool _bEnabled ); + sal_Bool IsCTLFontEnabled() const; + + void SetCTLSequenceChecking( sal_Bool _bEnabled ); + sal_Bool IsCTLSequenceChecking() const; + + void SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingRestricted( void ) const; + + void SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingTypeAndReplace() const; + + enum CursorMovement + { + MOVEMENT_LOGICAL = 0, + MOVEMENT_VISUAL + }; + void SetCTLCursorMovement( CursorMovement _eMovement ); + CursorMovement GetCTLCursorMovement() const; + + enum TextNumerals + { + NUMERALS_ARABIC = 0, + NUMERALS_HINDI, + NUMERALS_SYSTEM, + NUMERALS_CONTEXT + }; + void SetCTLTextNumerals( TextNumerals _eNumerals ); + TextNumerals GetCTLTextNumerals() const; + + enum EOption + { + E_CTLFONT, + E_CTLSEQUENCECHECKING, + E_CTLCURSORMOVEMENT, + E_CTLTEXTNUMERALS, + E_CTLSEQUENCECHECKINGRESTRICTED, + E_CTLSEQUENCECHECKINGTYPEANDREPLACE + }; + sal_Bool IsReadOnly(EOption eOption) const; +}; + +#endif // _SVTOOLS_CTLOPTIONS_HXX + diff --git a/svl/inc/svl/ctypeitm.hxx b/svl/inc/svl/ctypeitm.hxx new file mode 100644 index 000000000000..808596397aa0 --- /dev/null +++ b/svl/inc/svl/ctypeitm.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * 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: ctypeitm.hxx,v $ + * $Revision: 1.3.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVTOOLS_CTYPEITM_HXX +#define _SVTOOLS_CTYPEITM_HXX + +#include <svl/inettype.hxx> +#include <svl/custritm.hxx> + +//========================================================================= + +class CntContentTypeItem : public CntUnencodedStringItem +{ +private: + INetContentType _eType; + XubString _aPresentation; + +public: + TYPEINFO(); + + CntContentTypeItem(); + CntContentTypeItem( USHORT nWhich, const XubString& rType ); + CntContentTypeItem( USHORT nWhich, const INetContentType eType ); + CntContentTypeItem( const CntContentTypeItem& rOrig ); + + virtual SfxPoolItem* Create( SvStream& rStream, + USHORT nItemVersion ) const; + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual int operator==( const SfxPoolItem& rOrig ) const; + + virtual USHORT GetVersion(USHORT) const; + + virtual SfxPoolItem* Clone( SfxItemPool *pPool = NULL ) const; + + void SetValue( const XubString& rNewVal ); + void SetPresentation( const XubString& rNewVal ); + + using SfxPoolItem::Compare; + virtual int Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper* pIntlWrapper = 0 ) const; + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + INetContentType GetEnumValue() const; + + void SetValue( const INetContentType eType ); +}; + +#endif /* !_SVTOOLS_CTYPEITM_HXX */ + diff --git a/svl/inc/svl/custritm.hxx b/svl/inc/svl/custritm.hxx new file mode 100644 index 000000000000..8a3344f6dc0b --- /dev/null +++ b/svl/inc/svl/custritm.hxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * 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: custritm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_CUSTRITM_HXX +#define _SVTOOLS_CUSTRITM_HXX + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <svl/poolitem.hxx> + +//============================================================================ +DBG_NAMEEX_VISIBILITY(CntUnencodedStringItem, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC CntUnencodedStringItem: public SfxPoolItem +{ + XubString m_aValue; + +public: + TYPEINFO(); + + CntUnencodedStringItem(USHORT which = 0): SfxPoolItem(which) + { DBG_CTOR(CntUnencodedStringItem, 0); } + + CntUnencodedStringItem(USHORT which, const XubString & rTheValue): + SfxPoolItem(which), m_aValue(rTheValue) + { DBG_CTOR(CntUnencodedStringItem, 0); } + + CntUnencodedStringItem(const CntUnencodedStringItem & rItem): + SfxPoolItem(rItem), m_aValue(rItem.m_aValue) + { DBG_CTOR(CntUnencodedStringItem, 0); } + + virtual ~CntUnencodedStringItem() { DBG_DTOR(CntUnencodedStringItem, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual int Compare(SfxPoolItem const & rWith, + IntlWrapper const & rIntlWrapper) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue(com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0) const; + + virtual BOOL PutValue(const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0); + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + const XubString & GetValue() const { return m_aValue; } + + inline void SetValue(const XubString & rTheValue); +}; + +inline void CntUnencodedStringItem::SetValue(const XubString & rTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, + "CntUnencodedStringItem::SetValue(): Pooled item"); + m_aValue = rTheValue; +} + +#endif // _SVTOOLS_CUSTRITM_HXX + diff --git a/svl/inc/svl/dateitem.hxx b/svl/inc/svl/dateitem.hxx new file mode 100644 index 000000000000..c66c9a84285d --- /dev/null +++ b/svl/inc/svl/dateitem.hxx @@ -0,0 +1,109 @@ + /************************************************************************* + * + * 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: dateitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _DATETIMEITEM_HXX +#define _DATETIMEITEM_HXX + +#include <tools/rtti.hxx> +#include <tools/datetime.hxx> + +#include <svl/poolitem.hxx> + +class SvStream; + +DBG_NAMEEX(SfxDateTimeItem) + +// class SfxDateTimeItem ------------------------------------------------- + +class SfxDateTimeItem : public SfxPoolItem +{ +private: + DateTime aDateTime; + +public: + TYPEINFO(); + + SfxDateTimeItem( USHORT nWhich ); + SfxDateTimeItem( USHORT nWhich, + const DateTime& rDT ); + SfxDateTimeItem( const SfxDateTimeItem& rCpy ); + + ~SfxDateTimeItem() { + DBG_DTOR(SfxDateTimeItem, 0); } + + virtual int operator==( const SfxPoolItem& ) const; + using SfxPoolItem::Compare; + virtual int Compare( const SfxPoolItem &rWith ) const; + virtual SfxPoolItem* Create( SvStream&, USHORT nItemVersion ) const; + virtual SvStream& Store( SvStream&, USHORT nItemVersion ) const; + virtual SfxPoolItem* Clone( SfxItemPool* pPool = 0 ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * pIntlWrapper = 0 ) + const; + + const DateTime& GetDateTime() const { return aDateTime; } + void SetDateTime( const DateTime& rDT ) { + DBG_ASSERT( GetRefCount() == 0, + "SetDateTime() with pooled item" ); + aDateTime = rDT; } + + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; +}; + +class SfxColumnDateTimeItem : public SfxDateTimeItem +{ +public: + TYPEINFO(); + + SfxColumnDateTimeItem( USHORT nWhich ); + SfxColumnDateTimeItem( USHORT nWhich, + const DateTime& rDT ); + SfxColumnDateTimeItem( const SfxDateTimeItem& rCpy ); + + ~SfxColumnDateTimeItem() {} + + virtual SfxPoolItem* Clone( SfxItemPool* pPool = 0 ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * pIntlWrapper = 0 ) + const; +}; + +#endif + diff --git a/svl/inc/svl/documentlockfile.hxx b/svl/inc/svl/documentlockfile.hxx new file mode 100644 index 000000000000..c62f81bc77ef --- /dev/null +++ b/svl/inc/svl/documentlockfile.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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: documentlockfile.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVT_DOCUMENTLOCKFILE_HXX +#define _SVT_DOCUMENTLOCKFILE_HXX + +#include <svl/svldllapi.h> + +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <svl/lockfilecommon.hxx> + +namespace svt { + +class SVL_DLLPUBLIC DocumentLockFile : public LockFileCommon +{ + // the workaround for automated testing! + static sal_Bool m_bAllowInteraction; + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > OpenStream(); + + void WriteEntryToStream( ::com::sun::star::uno::Sequence< ::rtl::OUString > aEntry, ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xStream ); + +public: + DocumentLockFile( const ::rtl::OUString& aOrigURL, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ); + ~DocumentLockFile(); + + sal_Bool CreateOwnLockFile(); + ::com::sun::star::uno::Sequence< ::rtl::OUString > GetLockData(); + sal_Bool OverwriteOwnLockFile(); + void RemoveFile(); + + // the methods allow to control whether UI interaction regarding the locked document file is allowed + // this is a workaround for automated tests + static void AllowInteraction( sal_Bool bAllow ) { m_bAllowInteraction = bAllow; } + static sal_Bool IsInteractionAllowed() { return m_bAllowInteraction; } +}; + +} + +#endif + diff --git a/svl/inc/svl/eitem.hxx b/svl/inc/svl/eitem.hxx new file mode 100644 index 000000000000..55ed3c47ee33 --- /dev/null +++ b/svl/inc/svl/eitem.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: eitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXENUMITEM_HXX +#define _SFXENUMITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/cenumitm.hxx> + +//============================================================================ +class SVL_DLLPUBLIC SfxEnumItem: public CntEnumItem +{ +protected: + SfxEnumItem(USHORT which = 0, USHORT nValue = 0): + CntEnumItem(which, nValue) {} + + SfxEnumItem(USHORT which, SvStream & rStream): + CntEnumItem(which, rStream) {} + +public: + TYPEINFO(); + +}; + +//============================================================================ +class SVL_DLLPUBLIC SfxBoolItem: public CntBoolItem +{ +public: + TYPEINFO(); + + SfxBoolItem(USHORT which = 0, BOOL bValue = FALSE): + CntBoolItem(which, bValue) {} + + SfxBoolItem(USHORT which, SvStream & rStream): + CntBoolItem(which, rStream) {} + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const + { return new SfxBoolItem(Which(), rStream); } + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxBoolItem(*this); } +}; + +#endif // _SFXENUMITEM_HXX + diff --git a/svl/inc/svl/filerec.hxx b/svl/inc/svl/filerec.hxx new file mode 100644 index 000000000000..d28bb3033b56 --- /dev/null +++ b/svl/inc/svl/filerec.hxx @@ -0,0 +1,1087 @@ +/************************************************************************* + * + * 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: filerec.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXFILEREC_HXX +#define _SFXFILEREC_HXX + +//========================================================================= + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <tools/stream.hxx> +#include <svl/svarray.hxx> + +SV_DECL_VARARR( SfxUINT32s, UINT32, 8, 8 ) + +//------------------------------------------------------------------------ + +#define SFX_BOOL_DONTCARE BOOL(2) // Don't-Care-Wert f"ur BOOLs + +#define SFX_REC_PRETAG_EXT BYTE(0x00) // Pre-Tag f"ur Extended-Records +#define SFX_REC_PRETAG_EOR BYTE(0xFF) // Pre-Tag f"ur End-Of-Records + +#define SFX_REC_TYPE_NONE BYTE(0x00) // unbekannter Record-Typ +#define SFX_REC_TYPE_FIRST BYTE(0x01) +#define SFX_REC_TYPE_SINGLE BYTE(0x01) // Single-Content-Record +#define SFX_REC_TYPE_FIXSIZE BYTE(0x02) // Fix-Size-Multi-Content-Record +#define SFX_REC_TYPE_VARSIZE_RELOC BYTE(0x03) // variable Rec-Size +#define SFX_REC_TYPE_VARSIZE BYTE(0x04) // alt (nicht verschiebbar) +#define SFX_REC_TYPE_MIXTAGS_RELOC BYTE(0x07) // Mixed Tag Content-Record +#define SFX_REC_TYPE_MIXTAGS BYTE(0x08) // alt (nicht verschiebbar) +#define SFX_REC_TYPE_LAST BYTE(0x08) +#define SFX_REC_TYPE_MINI 0x100 // Mini-Record +#define SFX_REC_TYPE_DRAWENG 0x400 // Drawing-Engine-Record +#define SFX_REC_TYPE_EOR 0xF00 // End-Of-Records + +//------------------------------------------------------------------------ + +#define SFX_REC_HEADERSIZE_MINI 4 // Gr"o\se des Mini-Record-Headers +#define SFX_REC_HEADERSIZE_SINGLE 4 // zzgl. HEADERSIZE_MINI => 8 +#define SFX_REC_HEADERSIZE_MULTI 6 // zzgl. HEADERSIZE_SINGLE => 14 + +//------------------------------------------------------------------------ + +#ifndef DBG +#ifdef DBG_UTIL +#define DBG(x) x +#else +#define DBG(x) +#endif +#endif + +//------------------------------------------------------------------------ + +/* [Fileformat] + + Jeder Record beginnt mit einem Byte, dem sogenannten 'Pre-Tag'. + + Ist dieses 'Pre-Tag' == 0x00, dann handelt es sich um einen Extended- + Record, dessen Typ durch ein weiteres Byte an Position 5 n�her + beschrieben wird: + + 0x01: SfxSingleRecord + 0x02: SfxMultiFixRecord + 0x03+0x04: SfxMultiVarRecord + 0x07+0x08: SfxMultiMixRecord + (Alle weiteren Record-Typ-Kennungen sind reserviert.) + + I.d.R. werden File-Formate schon aus Performance-Gr"unden so aufgebaut, + da\s beim Lesen jeweils vorher schon feststeht, welcher Record-Typ + vorliegt. Diese Kennung dient daher hautps"achlich der "Uberpr"ufung + und File-Viewern, die das genaue File-Format (unterhalb der Records) + nicht kennen. + + Der 'SfxMiniRecordReader' verf"ugt dazu auch "uber eine statische + Methode 'ScanRecordType()', mit der festgestellt werden kann, welcher + Record-Typ in dem "ubergebenen Stream zu finden ist. + + Ein 'Pre-Tag' mit dem Wert 0xFF ist als Terminator reserviert. + Terminatoren werden verwendet, um das Suchen nach einem speziellen + Record zu terminieren, d.h. ist er bis dorthin nicht gefunden, wird + auch nicht weitergesucht. + + Bei allen anderen Werten des 'Pre-Tags' (also von 0x01 bis 0xFE) + handelt es sich um einen zum SW3 kompatbilen Record, der hier + 'SfxMiniRecord' genannt wird, er kann daher mit einem <SfxMiniRecordReader> + gelesen werden. + + Beginnt ein Record mit 0x44 k"onnte es sich um einen Drawing-Engine- + Record handeln. Dies ist dann der Fall, wenn die folgenden drei Bytes + die Zeichenkette 'RMD' bzw. 'RVW' ergeben (zusammen mit 'D'==0x44 + ergibt dies die K"urzel f"ur 'DRaw-MoDel' bzw. 'DRaw-VieW'). Records + dieser Art k"onnen von den hier dargestellten Klassen weder gelesen, + noch in irgendeiner Weise interpretiert werden. Einzig die Methode + 'ScanRecordType()' kann sie erkennen - weitere Behandlung obliegt + jedoch der Anwendungsprogrammierung. + + Diese drei Bytes an den Positionen 2 bis 4 enthalten normalerweise + die Gr"o\se des Records ohne Pre-Tag und Gr"o\sen-Bytes selbst, + also die Restgr"o\se nach diesem 4-Byte-Header. + + Struktur des Mini-Records: + + 1 BYTE Pre-Tag + 3 BYTE OffsetToEndOfRec + OffsetToEndOfRec* 1 BYTE Content + + Bei den Extended-Reords folgt auf diesen 4-Byte-Header ein erweiterter + Header, der zun"achst den o.g. Record-Typ, dann eine Versions-Kennung + sowie ein Tag enth"alt, welches den Inhalt kennzeichnet. + + Struktur des Extended-Records: + + 1 BYTE Pre-Tag (==0x00) + 3 BYTE OffsetToEndOfRec + OffsetToEndOfRec* 1 BYTE Content + 1 BYTE Record-Type + 1 BYTE Version + 2 BYTE Tag + ContentSize* 1 BYTE Content + + (ContentSize = OffsetToEndOfRec - 8) + + [Anmerkung] + + Der Aufbau der Records wird wie folgt begr"undet: + + Der SW-Record-Typ war zuerst vorhanden, mu\ste also 1:1 "ubernommen + werden. Zum Gl"uck wurden einige Record-Tags nicht verwendet, (Z.B. + 0x00 und 0xFF). + => 1. Byte 0x00 kann als Kennung f"ur erweiterten Record verwendet werden + => 1. Byte 0xFF kann f"ur besondere Zwecke verwendet werden + + Egal welcher Record-Typ vorliegt, sollte eine Erkennung des Typs, ein + Auslesen des Headers und ein "uberpspringen des Records m"oglich sein, + ohne zu"uck-seeken zu m"ussen und ohne "uberfl"ussige Daten lesen zu + m"ussen. + => die Bytes 2-4 werden bei allen Records als Offset zum Ende des + Records interpretiert, so da\s die Gesamt-Recors-Size sich wie + folgt berechnet: sizeof(UINT32) + OffsetToEndOfRec + + Die Records sollten einfach zu parsen un einheitlich aufgebaut sein. + => Sie bauen aufeinander auf, so ist z.B. der SfxMiniRecord in jedem + anderen enthalten. + + Die Records sollten auch von denen der Drawing Enginge unterscheidbar + sein. Diese beginnen mit 'DRMD' und 'DRVW'. + => Mini-Records mit dem Pre-Tag 'D' d"urfen maximal 4MB gro\s sein, + um nicht in diesen Kennungs-Bereich zu reichen. + + [Erweiterungen] + + Es ist geplant das File-Format so zu erweitern, da\s das High-Nibble + des Record-Typs der erweiterten Records besondere Aufgaben "ubernehmen + soll. Zum Beispiel ist geplant, Record-Contents als 'nur aus Records + bestehend' zu kennzeichnen. Ein File-Viewer k"onnte sich dann automatisch + durch solche Strukturen 'hangeln', ohne Gefahr zu laufen, auf Daten + zu sto\sen, die sich zwar als Records interpretieren lassen, aber + tats"achlis als 'flache' Daten geschrieben wurden. Die m"ogliche + Erweiterung wird schon jetzt insofern vorbereitet, als da\s das + High-Nibble des Typs bei Vergleichen nicht ber"ucksichtigt wird. +*/ + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMiniRecordWriter + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein einfacher Record in einen Stream + geschrieben werden, der sich durch ein BYTE-Tag identifiziert, sowie + seine eigene L"ange speichert und somit auch von "alteren Versionen + bzw. Readern, die diesen Record-Type (Tag) nicht kennen, "ubersprungen + werden kann. Es wird keine Version-Nummer gespeichert. + + Alternativ kann die Gr"o\se fest angegeben werden oder sie wird + automatisch aus der Differenz der Tell()-Angaben vor und nach dem + Streamen des Inhalts ermittelt. + + Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen + neue Versionen die Daten der "alteren immer komplett enthalten, + es d"urfen allenfalls neue Daten hintenan geh"angt werden! + + [Fileformat] + + 1* BYTE Content-Tag (!= 0) + 1* 3-BYTE OffsetToEndOfRec in Bytes + SizeOfContent* BYTE Content + + [Beispiel] + + { + SfxMiniRecordWriter aRecord( pStream, MY_TAG_X ); + *aRecord << aMember1; + *aRecord << aMember2; + } +*/ + +{ +protected: + SvStream* _pStream; // <SvStream>, in dem der Record liegt + UINT32 _nStartPos; // Start-Position des Gesamt-Records im Stream + FASTBOOL _bHeaderOk; /* TRUE, wenn der Header schon geschrieben ist; + bei DBG_UTIL wird SFX_BOOL_DONTCARE ver- + wendet, um die Gr"o\se von Fix-Sized-Records + zu pr"ufen. */ + BYTE _nPreTag; // in den Header zu schreibendes 'Pre-Tag' + +public: + inline SfxMiniRecordWriter( SvStream *pStream, + BYTE nTag ); + inline SfxMiniRecordWriter( SvStream *pStream, BYTE nTag, + UINT32 nSize ); + + inline ~SfxMiniRecordWriter(); + + inline SvStream& operator*() const; + + inline void Reset(); + + UINT32 Close( FASTBOOL bSeekToEndOfRec = TRUE ); + +private: + // not implementend, not allowed + SfxMiniRecordWriter( const SfxMiniRecordWriter& ); + SfxMiniRecordWriter& operator=(const SfxMiniRecordWriter&); +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMiniRecordReader + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein einfacher Record aus einem Stream + gelesen werden, der mit der Klasse <SfxRecordWriter> geschrieben wurde. + + Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes + Format zu kennen. + + [Beispiel] + + { + SfxMiniRecordReader aRecord( pStream ); + switch ( aRecord.GetTag() ) + { + case MY_TAG_X: + *aRecord >> aMember1; + *aRecord >> aMember2; + break; + + ... + } + } +*/ + +{ +protected: + SvStream* _pStream; // <SvStream>, aus dem gelesen wird + UINT32 _nEofRec; // Position direkt hinter dem Record + FASTBOOL _bSkipped; // TRUE: der Record wurde explizit geskippt + BYTE _nPreTag; // aus dem Header gelesenes Pre-Tag + + // Drei-Phasen-Ctor f"ur Subklassen + SfxMiniRecordReader() {} + void Construct_Impl( SvStream *pStream, BYTE nTag ) + { + _pStream = pStream; + _bSkipped = FALSE; + _nPreTag = nTag; + } + inline FASTBOOL SetHeader_Impl( UINT32 nHeader ); + + // als ung"ultig markieren und zur"uck-seeken + void SetInvalid_Impl( UINT32 nRecordStartPos ) + { + _nPreTag = SFX_REC_PRETAG_EOR; + _pStream->Seek( nRecordStartPos ); + } + +public: + static USHORT ScanRecordType( SvStream *pStream ); + + SfxMiniRecordReader( SvStream *pStream ); + SfxMiniRecordReader( SvStream *pStream, BYTE nTag ); + inline ~SfxMiniRecordReader(); + + inline BYTE GetTag() const; + inline FASTBOOL IsValid() const; + + inline SvStream& operator*() const; + + inline void Skip(); + +private: + // not implementend, not allowed + SfxMiniRecordReader( const SfxMiniRecordReader& ); + SfxMiniRecordReader& operator=(const SfxMiniRecordReader&); +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxSingleRecordWriter: public SfxMiniRecordWriter + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben + werden, dessen einziger Inhalt sich durch ein UINT16-Tag und eine + BYTE-Versions-Nummer identifiziert, sowie seine eigene L"ange speichert + und somit auch von "alteren Versionen bzw. Readern, die diesen + Record-Type (Tag) nicht kennen, "ubersprungen werden kann. + + Alternativ kann die Gr"o\se fest angegeben werden oder sie wird + automatisch aus der Differenz der Tell()-Angaben vor und nach dem + Streamen des Inhalts ermittelt. + + Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen + neue Versionen die Daten der "alteren immer komplett enthalten, + es d"urfen allenfalls neue Daten hintenan geh"angt werden! + + [Fileformat] + + 1* BYTE Pre-Tag (!= 0) + 1* 3-BYTE OffsetToEndOfRec in Bytes + 1* BYTE Record-Type (==SFX_REC_TYPE_SINGLE) + 1* BYTE Content-Version + 1* USHORT Content-Tag + SizeOfContent* BYTE Content + + [Beispiel] + + { + SfxSingleRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION ); + *aRecord << aMember1; + *aRecord << aMember2; + } +*/ + +{ +protected: + SfxSingleRecordWriter( BYTE nRecordType, + SvStream *pStream, + UINT16 nTag, BYTE nCurVer ); + +public: + SfxSingleRecordWriter( SvStream *pStream, + UINT16 nTag, BYTE nCurVer ); + SfxSingleRecordWriter( SvStream *pStream, + UINT16 nTag, BYTE nCurVer, + UINT32 nSize ); + + inline void Reset(); + + UINT32 Close( FASTBOOL bSeekToEndOfRec = TRUE ); +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxSingleRecordReader: public SfxMiniRecordReader + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein einfacher Record aus einem Stream + gelesen werden, der mit der Klasse <SfxSingleRecordWriter> geschrieben + wurde. + + Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes + Format zu kennen. + + [Beispiel] + + { + SfxSingleRecordReader aRecord( pStream ); + switch ( aRecord.GetTag() ) + { + case MY_TAG_X: + aRecord >> aMember1; + if ( aRecord.HasVersion(2) ) + *aRecord >> aMember2; + break; + + ... + } + } +*/ + +{ +protected: + UINT16 _nRecordTag; // Art des Gesamt-Inhalts + BYTE _nRecordVer; // Version des Gesamt-Inhalts + BYTE _nRecordType; // Record Type aus dem Header + + // Drei-Phasen-Ctor f"ur Subklassen + SfxSingleRecordReader() {} + void Construct_Impl( SvStream *pStream ) + { + SfxMiniRecordReader::Construct_Impl( + pStream, SFX_REC_PRETAG_EXT ); + } + FASTBOOL FindHeader_Impl( UINT16 nTypes, UINT16 nTag ); + FASTBOOL ReadHeader_Impl( USHORT nTypes ); + +public: + SfxSingleRecordReader( SvStream *pStream ); + SfxSingleRecordReader( SvStream *pStream, USHORT nTag ); + + inline UINT16 GetTag() const; + + inline BYTE GetVersion() const; + inline FASTBOOL HasVersion( USHORT nVersion ) const; +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMultiFixRecordWriter: public SfxSingleRecordWriter + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben + werden, der seine eigene L"ange speichert und somit auch von "alteren + Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen, + "ubersprungen werden kann. + + Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben + Version, die einmalig (stellvertretend f"ur alle) im Header des Records + identifiziert werden. Alle Inhalte haben eine vorher bekannte und + identische L"ange. + + Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen + neue Versionen die Daten der "alteren immer komplett enthalten, + es d"urfen allenfalls neue Daten hinten angeh"angt werden! Hier sind + damit selbstverst"andlich nur die Daten der einzelnen Inhalte gemeint, + die Anzahl der Inhalte ist selbstverst"andlich variabel und sollte + von lesenden Applikationen auch so behandelt werden. + + [Fileformat] + + 1* BYTE Pre-Tag (==0) + 1* 3-BYTE OffsetToEndOfRec in Bytes + 1* BYTE Record-Type (==SFX_REC_TYPE_FIXSIZE) + 1* BYTE Content-Version + 1* UINT16 Content-Tag + 1* UINT16 NumberOfContents + 1* UINT32 SizeOfEachContent + NumberOfContents* ( + SizeOfEachContent BYTE Content + ) + + [Beispiel] + + { + SfxMultiFixRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION ); + for ( USHORT n = 0; n < Count(); ++n ) + { + aRecord.NewContent(); + *aRecord << aMember1[n]; + *aRecord << aMember2[n]; + } + } +*/ + +{ +protected: + UINT32 _nContentStartPos; /* Startposition des jeweiligen + Contents - nur bei DBG_UTIL + und f"ur Subklassen */ + UINT32 _nContentSize; // Gr"o\se jedes Contents + UINT16 _nContentCount; // jeweilige Anzahl der Contents + + SfxMultiFixRecordWriter( BYTE nRecordType, + SvStream *pStream, + UINT16 nTag, BYTE nCurVer, + UINT32 nContentSize ); + +public: + SfxMultiFixRecordWriter( SvStream *pStream, + UINT16 nTag, BYTE nCurVer, + UINT32 nContentSize ); + inline ~SfxMultiFixRecordWriter(); + + inline void NewContent(); + + inline void Reset(); + + UINT32 Close( FASTBOOL bSeekToEndOfRec = TRUE ); +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMultiVarRecordWriter: public SfxMultiFixRecordWriter + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben + werden, der seine eigene L"ange speichert und somit auch von "alteren + Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen, + "ubersprungen werden kann. + + Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben + Version, die einmalig (stellvertretend f"ur alle) im Header des Records + identifiziert werden. Die L"ange f"ur jeden einzelnen Inhalt wird + automatisch berechnet und gespeichert, so da\s auch einzelne Inhalte + "ubersprungen werden k"onnen, ohne sie interpretieren zu m"ussen. + + Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen + neue Versionen die Daten der "alteren immer komplett enthalten, + es d"urfen allenfalls neue Daten hinten angeh"angt werden! + + [Fileformat] + + 1* BYTE Pre-Tag (==0) + 1* 3-BYTE OffsetToEndOfRec in Bytes + 1* BYTE Record-Type (==SFX_FILETYPE_TYPE_VARSIZE) + 1* BYTE Content-Version + 1* USHORT Content-Tag + 1* UINT16 NumberOfContents + 1* UINT32 OffsetToOfsTable + NumberOfContents* ( + ContentSize* BYTE Content + ) + NumberOfContents* UINT32 ContentOfs (je per <<8 verschoben) + + [Beispiel] + + { + SfxMultiVarRecordWriter aRecord( pStream, MY_TAG_X, MY_VERSION ); + for ( USHORT n = 0; n < Count(); ++n ) + { + aRecord.NewContent(); + *aRecord << aMember1[n]; + *aRecord << aMember2[n]; + } + } +*/ + +{ +protected: + SfxUINT32s _aContentOfs; + USHORT _nContentVer; // nur f"ur SfxMultiMixRecordWriter + + SfxMultiVarRecordWriter( BYTE nRecordType, + SvStream *pStream, + USHORT nRecordTag, + BYTE nRecordVer ); + + void FlushContent_Impl(); + +public: + SfxMultiVarRecordWriter( SvStream *pStream, + USHORT nRecordTag, + BYTE nRecordVer ); + virtual ~SfxMultiVarRecordWriter(); + + void NewContent(); + + virtual UINT32 Close( FASTBOOL bSeekToEndOfRec = TRUE ); +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMultiMixRecordWriter: public SfxMultiVarRecordWriter + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein Record in einen Stream geschrieben + werden, der seine eigene L"ange speichert und somit auch von "alteren + Versionen bzw. Readern, die diesen Record-Type (Tag) nicht kennen, + "ubersprungen werden kann. + + Er enth"alt mehrere Inhalte von demselben Typ (Tag) und derselben + Version, die einmalig (stellvertretend f"ur alle) im Header des Records + identifiziert werden. Alle Inhalte haben eine vorher bekannte und + identische L"ange. + + Um Auf- und Abw"artskompatiblit"at gew"ahrleisten zu k"onnen, m"ussen + neue Versionen die Daten der "alteren immer komplett enthalten, + es d"urfen allenfalls neue Daten hinten angeh"angt werden! + + [Fileformat] + + 1* BYTE Pre-Tag (==0) + 1* 3-BYTE OffsetToEndOfRec in Bytes + 1* BYTE Record-Type (==SFX_REC_TYPE_MIXTAGS) + 1* BYTE Content-Version + 1* USHORT Record-Tag + 1* UINT16 NumberOfContents + 1* UINT32 OffsetToOfsTable + NumberOfContents* ( + 1* USHORT Content-Tag + ContentSize* BYTE Content + ) + NumberOfContents* UINT32 ( ContentOfs << 8 + Version ) +*/ + +{ +public: + inline SfxMultiMixRecordWriter( SvStream *pStream, + USHORT nRecordTag, + BYTE nRecordVer ); + + void NewContent( USHORT nTag, BYTE nVersion ); + +// private: geht nicht, da einige Compiler dann auch vorherige privat machen + void NewContent() + { DBG_ERROR( "NewContent() only allowed with args" ); } +}; + +//------------------------------------------------------------------------ + +class SVL_DLLPUBLIC SfxMultiRecordReader: public SfxSingleRecordReader + +/* [Beschreibung] + + Mit Instanzen dieser Klasse kann ein aus mehreren Contents bestehender + Record aus einem Stream gelesen werden, der mit einer der Klassen + <SfxMultiFixRecordWriter>, <SfxMultiVarRecordWriter> oder + <SfxMultiMixRecordWriter> geschrieben wurde. + + Es ist auch m"oglich, den Record oder einzelne Contents zu "uberspringen, + ohne das jeweilis interne Format zu kennen. + + [Beispiel] + + { + SfxMultiRecordReader aRecord( pStream ); + for ( USHORT nRecNo = 0; aRecord.GetContent(); ++nRecNo ) + { + switch ( aRecord.GetTag() ) + { + case MY_TAG_X: + X *pObj = new X; + *aRecord >> pObj.>aMember1; + if ( aRecord.HasVersion(2) ) + *aRecord >> pObj->aMember2; + Append( pObj ); + break; + + ... + } + } + } +*/ + +{ + UINT32 _nStartPos; // Start-Position des Records + UINT32* _pContentOfs; // Offsets der Startpositionen + UINT32 _nContentSize; // Size jedes einzelnen / Tabellen-Pos + UINT16 _nContentCount; // Anzahl der Contents im Record + UINT16 _nContentNo; /* der Index des aktuellen Contents + enth"alt jeweils den Index des + Contents, der beim n"achsten + GetContent() geholt wird */ + UINT16 _nContentTag; // Art-Kennung des aktuellen Contents + BYTE _nContentVer; // Versions-Kennung des akt. Contents + + FASTBOOL ReadHeader_Impl(); + +public: + SfxMultiRecordReader( SvStream *pStream ); + SfxMultiRecordReader( SvStream *pStream, UINT16 nTag ); + ~SfxMultiRecordReader(); + + FASTBOOL GetContent(); + inline UINT16 GetContentTag(); + inline BYTE GetContentVersion() const; + inline FASTBOOL HasContentVersion( USHORT nVersion ) const; + + inline UINT32 ContentCount() const; +}; + +//========================================================================= + +inline SfxMiniRecordWriter::SfxMiniRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + BYTE nTag // Record-Tag zwischen 0x01 und 0xFE +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxMiniRecord' an, dessen Content-Gr"o\se + nicht bekannt ist, sondern nach dam Streamen des Contents errechnet + werden soll. +*/ + +: _pStream( pStream ), + _nStartPos( pStream->Tell() ), + _bHeaderOk(FALSE), + _nPreTag( nTag ) +{ + DBG_ASSERT( _nPreTag != 0xFF, "invalid Tag" ); + DBG( DbgOutf( "SfxFileRec: writing record to %ul", pStream->Tell() ) ); + + pStream->SeekRel( + SFX_REC_HEADERSIZE_MINI ); +} + +//------------------------------------------------------------------------- + +inline SfxMiniRecordWriter::SfxMiniRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + BYTE nTag, // Record-Tag zwischen 0x01 und 0xFE + UINT32 nSize // Gr"o\se der Daten in Bytes +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxMiniRecord' an, dessen Content-Gr"o\se + von vornherein bekannt ist. +*/ + +: _pStream( pStream ), + // _nTag( uninitialized ), + // _nStarPos( uninitialized ), + _bHeaderOk(SFX_BOOL_DONTCARE) +{ + DBG_ASSERT( nTag != 0 && nTag != 0xFF, "invalid Tag" ); + DBG(_nStartPos = pStream->Tell()); + DBG( DbgOutf( "SfxFileRec: writing record to %ul", _nStartPos ) ); + + *pStream << ( ( nTag << 24 ) | nSize ); +} + +//------------------------------------------------------------------------- + +inline SfxMiniRecordWriter::~SfxMiniRecordWriter() + +/* [Beschreibung] + + Der Dtor der Klasse <SfxMiniRecordWriter> schlie\st den Record + automatisch, falls <SfxMiniRecordWriter::Close()> nicht bereits + explizit gerufen wurde. +*/ + +{ + // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden + if ( !_bHeaderOk DBG(||TRUE) ) + Close(); +} + +//------------------------------------------------------------------------- + +inline SvStream& SfxMiniRecordWriter::operator*() const + +/* [Beschreibung] + + Dieser Operator liefert den Stream, in dem der Record liegt. + Der Record darf noch nicht geschlossen worden sein. +*/ + +{ + DBG_ASSERT( !_bHeaderOk, "getting Stream of closed record" ); + return *_pStream; +} + +//------------------------------------------------------------------------- + +inline void SfxMiniRecordWriter::Reset() +{ + _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI ); + _bHeaderOk = FALSE; +} + +//========================================================================= + +inline SfxMiniRecordReader::~SfxMiniRecordReader() + +/* [Beschreibung] + + Der Dtor der Klasse <SfxMiniRecordReader> positioniert den Stream + automatisch auf die Position direkt hinter dem Record, falls nicht + <SfxMiniRecordReader::Skip()> bereits explizit gerufen wurde. +*/ + +{ + // noch nicht explizit ans Ende gesprungen? + if ( !_bSkipped ) + Skip(); +} + +//------------------------------------------------------------------------- + +inline void SfxMiniRecordReader::Skip() + +/* [Beschreibung] + + Mit dieser Methode wird der Stream direkt hinter das Ende des Records + positioniert. +*/ + +{ + _pStream->Seek(_nEofRec); + _bSkipped = TRUE; +} + +//------------------------------------------------------------------------- + +inline BYTE SfxMiniRecordReader::GetTag() const + +/* [Beschreibung] + + Liefert des aus dem Header gelesene Pre-Tag des Records. Dieses kann + auch SFX_REC_PRETAG_EXT oder SFX_REC_PRETAG_EOR sein, im + letzteren Fall ist am Stream der Fehlercode ERRCODE_IO_WRONGFORMAT + gesetzt. SFX_REC_PRETAG_EXT ist g"ultig, da diese extended-Records + nur eine Erweiterung des SfxMiniRecord darstellen. +*/ + +{ + return _nPreTag; +} + +//------------------------------------------------------------------------- + +inline FASTBOOL SfxMiniRecordReader::IsValid() const + +/* [Beschreibung] + + Hiermit kann abgefragt werden, ob der Record erfolgreich aus dem + Stream konstruiert werden konnte, der Header also f"ur diesen Record-Typ + passend war. +*/ + +{ + return _nPreTag != SFX_REC_PRETAG_EOR; +} + +//------------------------------------------------------------------------- + +inline SvStream& SfxMiniRecordReader::operator*() const + +/* [Beschreibung] + + Dieser Operator liefert den Stream in dem der Record liegt. + Die aktuelle Position des Streams mu\s innerhalb des Records liegen. +*/ + +{ + DBG_ASSERT( _pStream->Tell() < _nEofRec, "read behind record" ); + return *_pStream; +} + +//========================================================================= + +inline UINT32 SfxSingleRecordWriter::Close( FASTBOOL bSeekToEndOfRec ) + +// siehe <SfxMiniRecordWriter::Close(FASTBOOL)> + +{ + UINT32 nRet = 0; + + // wurde der Header noch nicht geschrieben? + if ( !_bHeaderOk ) + { + // Basisklassen-Header schreiben + UINT32 nEndPos = SfxMiniRecordWriter::Close( bSeekToEndOfRec ); + + // ggf. ans Ende des eigenen Headers seeken oder hinter Rec bleiben + if ( !bSeekToEndOfRec ) + _pStream->SeekRel( SFX_REC_HEADERSIZE_SINGLE ); + nRet = nEndPos; + } +#ifdef DBG_UTIL + else + // Basisklassen-Header pr"ufen + SfxMiniRecordWriter::Close( bSeekToEndOfRec ); +#endif + + // Record war bereits geschlossen +// nRet = 0; + return nRet; +} + +//------------------------------------------------------------------------- + +inline void SfxSingleRecordWriter::Reset() +{ + _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI + + SFX_REC_HEADERSIZE_SINGLE ); + _bHeaderOk = FALSE; +} + +//========================================================================= + +inline UINT16 SfxSingleRecordReader::GetTag() const + +/* [Beschreibung] + + Liefert des aus dem Header gelesene Tag f"ur den Gesamt-Record. +*/ + +{ + return _nRecordTag; +} + +//------------------------------------------------------------------------- + +inline BYTE SfxSingleRecordReader::GetVersion() const + +/* [Beschreibung] + + Liefert die Version des aus dem Stream gelesenen Records. +*/ + +{ + return _nRecordVer; +} + +//------------------------------------------------------------------------- + +inline FASTBOOL SfxSingleRecordReader::HasVersion( USHORT nVersion ) const + +/* [Beschreibung] + + Stellt fest, ob der aus dem Stream gelese Record in der Version + 'nVersion' oder h"oher vorliegt. +*/ + +{ + return _nRecordVer >= nVersion; +} + +//========================================================================= + +inline SfxMultiFixRecordWriter::~SfxMultiFixRecordWriter() + +/* [Beschreibung] + + Der Dtor der Klasse <SfxMultiFixRecordWriter> schlie\st den Record + automatisch, falls <SfxMutiFixRecordWriter::Close()> nicht bereits + explizit gerufen wurde. +*/ + +{ + // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden + if ( !_bHeaderOk ) + Close(); +} + +//------------------------------------------------------------------------- + +inline void SfxMultiFixRecordWriter::NewContent() + +/* [Beschreibung] + + Mit dieser Methode wird in den Record ein neuer Content eingef"ugt. + Jeder, auch der 1. Record mu\s durch Aufruf dieser Methode eingeleitet + werden. +*/ + +{ + #ifdef DBG_UTIL + ULONG nOldStartPos; + // Startposition des aktuellen Contents merken - Achtung Subklassen! + nOldStartPos = _nContentStartPos; + #endif + _nContentStartPos = _pStream->Tell(); + +#ifdef DBG_UTIL + // ist ein vorhergehender Content vorhanden? + if ( _nContentCount ) + { + // pr"ufen, ob der vorhergehende die Soll-Gr"o\se eingehalten hat + DBG_ASSERT( _nContentStartPos - nOldStartPos == _nContentSize, + "wrong content size detected" ); + } +#endif + + // Anzahl mitz"ahlen + ++_nContentCount; +} + +//========================================================================= + +inline SfxMultiMixRecordWriter::SfxMultiMixRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + USHORT nRecordTag, // Gesamt-Record-Art-Kennung + BYTE nRecordVer // Gesamt-Record-Versions-Kennung +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxMultiMixRecord' an, f"ur dessen Contents + je eine separate Kennung f"ur Art (Tag) und Version gespeichert wird. + Die Gr"o\sen der einzelnen Contents werden automatisch ermittelt. +*/ + +: SfxMultiVarRecordWriter( SFX_REC_TYPE_MIXTAGS, + pStream, nRecordTag, nRecordVer ) +{ +} + +//========================================================================= + +inline void SfxMultiFixRecordWriter::Reset() +{ + _pStream->Seek( _nStartPos + SFX_REC_HEADERSIZE_MINI + + SFX_REC_HEADERSIZE_SINGLE + + SFX_REC_HEADERSIZE_MULTI ); + _bHeaderOk = FALSE; +} + +//========================================================================= + +inline UINT16 SfxMultiRecordReader::GetContentTag() + +/* [Beschreibung] + + Diese Methode liefert die Art-Kennung des zuletzt mit der Methode + <SfxMultiRecordReder::GetContent()> ge"offneten Contents. +*/ + +{ + return _nContentTag; +} + +//------------------------------------------------------------------------- + +inline BYTE SfxMultiRecordReader::GetContentVersion() const + +/* [Beschreibung] + + Diese Methode liefert die Version-Kennung des zuletzt mit der Methode + <SfxMultiRecordReder::GetContent()> ge"offneten Contents. +*/ + +{ + return _nContentVer; +} + +//------------------------------------------------------------------------- + +inline FASTBOOL SfxMultiRecordReader::HasContentVersion( USHORT nVersion ) const + +/* [Beschreibung] + + Diese Methode stellt fest, ob die Version 'nVersion' in der Version des + zuletzt mit der Methode <SfxMultiRecordReder::GetContent()> ge"offneten + Contents enthalten ist. +*/ + +{ + return _nContentVer >= nVersion; +} + +//------------------------------------------------------------------------- + +inline UINT32 SfxMultiRecordReader::ContentCount() const + +/* [Beschreibung] + + Diese Methode liefert die Anzahl im Record befindlichen Contents. +*/ + +{ + return _nContentCount; +} + +#endif + diff --git a/svl/inc/svl/flagitem.hxx b/svl/inc/svl/flagitem.hxx new file mode 100644 index 000000000000..fa056bb00488 --- /dev/null +++ b/svl/inc/svl/flagitem.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * 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: flagitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXFLAGITEM_HXX +#define _SFXFLAGITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <tools/rtti.hxx> +#include <svl/poolitem.hxx> + +class SvStream; + +extern USHORT nSfxFlagVal[16]; + +// ----------------------------------------------------------------------- + +DBG_NAMEEX_VISIBILITY(SfxFlagItem, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC SfxFlagItem: public SfxPoolItem +{ + USHORT nVal; + +public: + TYPEINFO(); + + SfxFlagItem( USHORT nWhich = 0, USHORT nValue = 0 ); + SfxFlagItem( USHORT nWhich, SvStream & ); + SfxFlagItem( const SfxFlagItem& ); + + ~SfxFlagItem() { + DBG_DTOR(SfxFlagItem, 0); } + + virtual BYTE GetFlagCount() const; + virtual XubString GetFlagText( BYTE nFlag ) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nVersion) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion) const; + + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + USHORT GetValue() const { return nVal; } + void SetValue( USHORT nNewVal ) { + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + nVal = nNewVal; + } + int GetFlag( BYTE nFlag ) const { + return ( (nVal & nSfxFlagVal[nFlag]) != 0 ); } + void SetFlag( BYTE nFlag, int bVal ); +}; + +#endif diff --git a/svl/inc/svl/globalnameitem.hxx b/svl/inc/svl/globalnameitem.hxx new file mode 100644 index 000000000000..4422220fe640 --- /dev/null +++ b/svl/inc/svl/globalnameitem.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * 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: globalnameitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _GLOBALNAMEITEM_HXX +#define _GLOBALNAMEITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <tools/rtti.hxx> +#include <tools/globname.hxx> +#include <svl/poolitem.hxx> + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxGlobalNameItem: public SfxPoolItem +{ + SvGlobalName m_aName; + +public: + TYPEINFO(); + SfxGlobalNameItem(); + SfxGlobalNameItem( USHORT nWhich, const SvGlobalName& ); + ~SfxGlobalNameItem(); + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + SvGlobalName GetValue() const { return m_aName; } + + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; +}; + +#endif + diff --git a/svl/inc/svl/hint.hxx b/svl/inc/svl/hint.hxx new file mode 100644 index 000000000000..e2d43ea602ca --- /dev/null +++ b/svl/inc/svl/hint.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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: hint.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXHINT_HXX +#define _SFXHINT_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> + +class SVL_DLLPUBLIC SfxHint +{ +public: + TYPEINFO(); + + virtual ~SfxHint(); +}; + +//-------------------------------------------------------------------- + +#define DECL_PTRHINT(Visibility, Name, Type) \ + class Visibility Name: public SfxHint \ + { \ + Type* pObj; \ + BOOL bIsOwner; \ + \ + public: \ + TYPEINFO(); \ + Name( Type* Object, BOOL bOwnedByHint = FALSE ); \ + ~Name(); \ + \ + Type* GetObject() const { return pObj; } \ + BOOL IsOwner() const { return bIsOwner; } \ + } + +#define IMPL_PTRHINT_AUTODELETE(Name, Type) \ + TYPEINIT1(Name, SfxHint); \ + Name::Name( Type* pObject, BOOL bOwnedByHint ) \ + { pObj = pObject; bIsOwner = bOwnedByHint; } \ + Name::~Name() { if ( bIsOwner ) delete pObj; } + +#define IMPL_PTRHINT(Name, Type) \ + TYPEINIT1(Name, SfxHint); \ + Name::Name( Type* pObject, BOOL bOwnedByHint ) \ + { pObj = pObject; bIsOwner = bOwnedByHint; } \ + Name::~Name() {} + + +#endif + diff --git a/svl/inc/svl/httpcook.hxx b/svl/inc/svl/httpcook.hxx new file mode 100644 index 000000000000..09769396eb11 --- /dev/null +++ b/svl/inc/svl/httpcook.hxx @@ -0,0 +1,155 @@ +/************************************************************************* + * + * 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: httpcook.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_HTTPCOOK_HXX +#define SVTOOLS_HTTPCOOK_HXX + +#include <tools/datetime.hxx> +#include <tools/stream.hxx> +#include <tools/string.hxx> +#include <svl/poolitem.hxx> + +/*======================================================================= + * + *=====================================================================*/ +#define CNTHTTP_COOKIE_FLAG_SECURE 0x01 + +#define CNTHTTP_COOKIE_POLICY_INTERACTIVE 0x00 +#define CNTHTTP_COOKIE_POLICY_ACCEPTED 0x01 +#define CNTHTTP_COOKIE_POLICY_BANNED 0x02 + +#define CNTHTTP_COOKIE_DOMAIN_POLICY 0x10 + +#define CNTHTTP_COOKIE_DOMAIN_ACCEPTED \ + (CNTHTTP_COOKIE_DOMAIN_POLICY | CNTHTTP_COOKIE_POLICY_ACCEPTED) +#define CNTHTTP_COOKIE_DOMAIN_BANNED \ + (CNTHTTP_COOKIE_DOMAIN_POLICY | CNTHTTP_COOKIE_POLICY_BANNED) + +/*======================================================================= + * + * CntHTTPCookie. + * + *=====================================================================*/ +struct CntHTTPCookie +{ + String m_aName; + String m_aValue; + String m_aDomain; + String m_aPath; + DateTime m_aExpires; + USHORT m_nFlags; + USHORT m_nPolicy; + + CntHTTPCookie (void) + : m_aExpires (Date(0), Time(0)), + m_nFlags (0), + m_nPolicy (CNTHTTP_COOKIE_POLICY_INTERACTIVE) + {} + + BOOL replaces (const CntHTTPCookie& rOther) const + { + return ((m_aDomain == rOther.m_aDomain) && + (m_aPath == rOther.m_aPath ) && + (m_aName == rOther.m_aName ) ); + } + + BOOL operator== (const CntHTTPCookie& rOther) const + { + return ((m_aName == rOther.m_aName ) && + (m_aValue == rOther.m_aValue ) && + (m_aDomain == rOther.m_aDomain ) && + (m_aPath == rOther.m_aPath ) && + (m_aExpires == rOther.m_aExpires) && + (m_nFlags == rOther.m_nFlags ) && + (m_nPolicy == rOther.m_nPolicy ) ); + } + + void write (SvStream& rStrm) const + { + SfxPoolItem::writeUnicodeString(rStrm, m_aName); + SfxPoolItem::writeUnicodeString(rStrm, m_aValue); + SfxPoolItem::writeUnicodeString(rStrm, m_aDomain); + SfxPoolItem::writeUnicodeString(rStrm, m_aPath); + + rStrm << m_aExpires.GetDate(); + rStrm << m_aExpires.GetTime(); + + rStrm << m_nFlags; + rStrm << m_nPolicy; + } + + void read (SvStream& rStrm, bool bUnicode) + { + SfxPoolItem::readUnicodeString(rStrm, m_aName, bUnicode); + SfxPoolItem::readUnicodeString(rStrm, m_aValue, bUnicode); + SfxPoolItem::readUnicodeString(rStrm, m_aDomain, bUnicode); + SfxPoolItem::readUnicodeString(rStrm, m_aPath, bUnicode); + + sal_uInt32 nValue = 0; + rStrm >> nValue; + m_aExpires.SetDate (nValue); + rStrm >> nValue; + m_aExpires.SetTime (nValue); + + rStrm >> m_nFlags; + rStrm >> m_nPolicy; + } +}; + +/*======================================================================= + * + * CntHTTPCookieRequest. + * + *=====================================================================*/ +enum CntHTTPCookieRequestType +{ + CNTHTTP_COOKIE_REQUEST_RECV = 0, + CNTHTTP_COOKIE_REQUEST_SEND +}; + +struct CntHTTPCookieRequest +{ + const String& m_rURL; + List& m_rCookieList; + CntHTTPCookieRequestType m_eType; + USHORT m_nRet; + + CntHTTPCookieRequest ( + const String& rURL, + List& rCookieList, + CntHTTPCookieRequestType eType) + : m_rURL (rURL), + m_rCookieList (rCookieList), + m_eType(eType), + m_nRet (CNTHTTP_COOKIE_POLICY_BANNED) {} +}; + +#endif // SVTOOLS_HTTPCOOK_HXX + diff --git a/svl/inc/svl/ilstitem.hxx b/svl/inc/svl/ilstitem.hxx new file mode 100644 index 000000000000..c581f938197f --- /dev/null +++ b/svl/inc/svl/ilstitem.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * 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: ilstitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXILSTITEM_HXX +#define _SFXILSTITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/poolitem.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +class SvULongs; + +class SVL_DLLPUBLIC SfxIntegerListItem : public SfxPoolItem +{ + ::com::sun::star::uno::Sequence < sal_Int32 > m_aList; + +public: + TYPEINFO(); + + SfxIntegerListItem(); + SfxIntegerListItem( USHORT nWhich, const SvULongs& rList ); + SfxIntegerListItem( const SfxIntegerListItem& rItem ); + ~SfxIntegerListItem(); + + ::com::sun::star::uno::Sequence < sal_Int32 > GetSequence() + { return m_aList; } + ::com::sun::star::uno::Sequence < sal_Int32 > GetConstSequence() const + { return SAL_CONST_CAST(SfxIntegerListItem *, this)->GetSequence(); } + + void GetList( SvULongs& rList ) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ); + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const; +}; + +#endif // _SFXINTITEM_HXX + diff --git a/svl/inc/svl/imageitm.hxx b/svl/inc/svl/imageitm.hxx new file mode 100644 index 000000000000..bfd888bdd944 --- /dev/null +++ b/svl/inc/svl/imageitm.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * 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: imageitm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVT_IMAGEITM_HXX +#define _SVT_IMAGEITM_HXX + +#include "svl/svldllapi.h" +#include <svl/intitem.hxx> + +class String; + +struct SfxImageItem_Impl; +class SVL_DLLPUBLIC SfxImageItem : public SfxInt16Item +{ + SfxImageItem_Impl* pImp; +public: + TYPEINFO(); + SfxImageItem( USHORT nWhich = 0, UINT16 nImage = 0 ); + SfxImageItem( USHORT nWhich, const String& rURL ); + SfxImageItem( const SfxImageItem& ); + virtual ~SfxImageItem(); + + virtual SfxPoolItem* Clone( SfxItemPool* pPool = 0 ) const; + virtual int operator==( const SfxPoolItem& ) const; + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const; + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ); + + void SetRotation( long nValue ); + long GetRotation() const; + void SetMirrored( BOOL bSet ); + BOOL IsMirrored() const; + String GetURL() const; +}; + +#endif // _SFX_IMAGEITM_HXX diff --git a/svl/inc/svl/inethist.hxx b/svl/inc/svl/inethist.hxx new file mode 100644 index 000000000000..7d4577897faf --- /dev/null +++ b/svl/inc/svl/inethist.hxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * 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: inethist.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _INETHIST_HXX +#define _INETHIST_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <tools/string.hxx> +#include <tools/urlobj.hxx> +#include <svl/brdcst.hxx> +#include <svl/hint.hxx> + +/*======================================================================== + * + * INetURLHistory interface. + * + *=======================================================================*/ +class INetURLHistory_Impl; +class INetURLHistory : public SfxBroadcaster +{ + struct StaticInstance + { + INetURLHistory * operator()(); + }; + friend INetURLHistory * StaticInstance::operator()(); + + /** Representation. + */ + INetURLHistory_Impl *m_pImpl; + + /** Construction/Destruction. + */ + INetURLHistory (void); + virtual ~INetURLHistory (void); + + /** Implementation. + */ + static void NormalizeUrl_Impl (INetURLObject &rUrl); + + SVL_DLLPUBLIC void PutUrl_Impl (const INetURLObject &rUrl); + SVL_DLLPUBLIC BOOL QueryUrl_Impl (const INetURLObject &rUrl); + + /** Not implemented. + */ + INetURLHistory (const INetURLHistory&); + INetURLHistory& operator= (const INetURLHistory&); + +public: + /** GetOrCreate. + */ + SVL_DLLPUBLIC static INetURLHistory* GetOrCreate (void); + + /** QueryProtocol. + */ + BOOL QueryProtocol (INetProtocol eProto) const + { + return ((eProto == INET_PROT_FILE ) || + (eProto == INET_PROT_FTP ) || + (eProto == INET_PROT_HTTP ) || + (eProto == INET_PROT_HTTPS) ); + } + + /** QueryUrl. + */ + BOOL QueryUrl (const INetURLObject &rUrl) + { + if (QueryProtocol (rUrl.GetProtocol())) + return QueryUrl_Impl (rUrl); + else + return FALSE; + } + + BOOL QueryUrl (const String &rUrl) + { + INetProtocol eProto = + INetURLObject::CompareProtocolScheme (rUrl); + if (QueryProtocol (eProto)) + return QueryUrl_Impl (INetURLObject (rUrl)); + else + return FALSE; + } + + /** PutUrl. + */ + void PutUrl (const INetURLObject &rUrl) + { + if (QueryProtocol (rUrl.GetProtocol())) + PutUrl_Impl (rUrl); + } + + void PutUrl (const String &rUrl) + { + INetProtocol eProto = + INetURLObject::CompareProtocolScheme (rUrl); + if (QueryProtocol (eProto)) + PutUrl_Impl (INetURLObject (rUrl)); + } +}; + +/*======================================================================== + * + * INetURLHistoryHint (broadcasted from PutUrl()). + * + *=======================================================================*/ +DECL_PTRHINT (SVL_DLLPUBLIC, INetURLHistoryHint, const INetURLObject); + +#endif /* _INETHIST_HXX */ + diff --git a/svl/inc/svl/inettype.hxx b/svl/inc/svl/inettype.hxx new file mode 100644 index 000000000000..5f3bfbaab225 --- /dev/null +++ b/svl/inc/svl/inettype.hxx @@ -0,0 +1,479 @@ +/************************************************************************* + * + * 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: inettype.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _INETTYPE_HXX +#define _INETTYPE_HXX + +#include "svl/svldllapi.h" +#include <tools/inetmime.hxx> +#include <com/sun/star/lang/Locale.hpp> + +//============================================================================ +/** Definitions for frequently used media type names. + */ +#define CONTENT_TYPE_STR_APP_OCTSTREAM "application/octet-stream" +#define CONTENT_TYPE_STR_APP_PDF "application/pdf" +#define CONTENT_TYPE_STR_APP_RTF "application/rtf" +#define CONTENT_TYPE_STR_APP_VND_CALC "application/vnd.stardivision.calc" +#define CONTENT_TYPE_STR_APP_VND_CHART "application/vnd.stardivision.chart" +#define CONTENT_TYPE_STR_APP_VND_DRAW "application/vnd.stardivision.draw" +#define CONTENT_TYPE_STR_APP_VND_IMAGE "application/vnd.stardivision.image" +#define CONTENT_TYPE_STR_APP_VND_IMPRESSPACKED \ + "application/vnd.stardivision.impress-packed" +#define CONTENT_TYPE_STR_APP_VND_IMPRESS \ + "application/vnd.stardivision.impress" +#define CONTENT_TYPE_STR_APP_VND_MAIL "application/vnd.stardivision.mail" +#define CONTENT_TYPE_STR_APP_VND_MATH "application/vnd.stardivision.math" +#define CONTENT_TYPE_STR_APP_VND_NEWS "application/vnd.stardivision.news" +#define CONTENT_TYPE_STR_APP_VND_OUTTRAY \ + "application/vnd.stardivision.outtray" +#define CONTENT_TYPE_STR_APP_VND_TEMPLATE \ + "application/vnd.stardivision.template" +#define CONTENT_TYPE_STR_APP_VND_WRITER_GLOBAL \ + "application/vnd.stardivision.writer-global" +#define CONTENT_TYPE_STR_APP_VND_WRITER_WEB \ + "application/vnd.stardivision.writer-web" +#define CONTENT_TYPE_STR_APP_VND_WRITER "application/vnd.stardivision.writer" +#define CONTENT_TYPE_STR_APP_FRAMESET "application/x-frameset" +#define CONTENT_TYPE_STR_APP_GALLERY_THEME "application/x-gallery-theme" +#define CONTENT_TYPE_STR_APP_GALLERY "application/x-gallery" +#define CONTENT_TYPE_STR_APP_JAR "application/x-jar" +#define CONTENT_TYPE_STR_APP_MACRO "application/x-macro" +#define CONTENT_TYPE_STR_APP_MSEXCEL_TEMPL "application/x-msexcel-template" +#define CONTENT_TYPE_STR_APP_MSEXCEL "application/x-msexcel" +#define CONTENT_TYPE_STR_APP_MSPPOINT_TEMPL "application/x-mspowerpoint-template" +#define CONTENT_TYPE_STR_APP_MSPPOINT "application/x-mspowerpoint" +#define CONTENT_TYPE_STR_APP_MSWORD_TEMPL "application/x-msword-template" +#define CONTENT_TYPE_STR_APP_MSWORD "application/x-msword" +#define CONTENT_TYPE_STR_APP_SCHEDULE_EVT "application/x-schedule-event" +#define CONTENT_TYPE_STR_APP_SCHEDULE_FEVT "application/x-schedule-form-event" +#define CONTENT_TYPE_STR_APP_SCHEDULE_FTASK "application/x-schedule-form-task" +#define CONTENT_TYPE_STR_APP_SCHEDULE_TASK "application/x-schedule-task" +#define CONTENT_TYPE_STR_APP_SCHEDULE_CMB "application/x-schedule" +#define CONTENT_TYPE_STR_APP_STARCALC "application/x-starcalc" +#define CONTENT_TYPE_STR_APP_STARCHART "application/x-starchart" +#define CONTENT_TYPE_STR_APP_STARDRAW "application/x-stardraw" +#define CONTENT_TYPE_STR_APP_STARHELP "application/x-starhelp" +#define CONTENT_TYPE_STR_APP_STARIMAGE "application/x-starimage" +#define CONTENT_TYPE_STR_APP_STARIMPRESS "application/x-starimpress" +#define CONTENT_TYPE_STR_APP_STARMAIL_SDM "application/x-starmail-sdm" +#define CONTENT_TYPE_STR_APP_STARMAIL_SMD "application/x-starmail-smd" +#define CONTENT_TYPE_STR_APP_STARMATH "application/x-starmath" +#define CONTENT_TYPE_STR_APP_STARWRITER_GLOB "application/x-starwriter-global" +#define CONTENT_TYPE_STR_APP_STARWRITER "application/x-starwriter" +#define CONTENT_TYPE_STR_APP_CDE_CALENDAR_APP "application/x-sun-ae-file" +#define CONTENT_TYPE_STR_APP_ZIP "application/x-zip-compressed" +#define CONTENT_TYPE_STR_AUDIO_AIFF "audio/aiff" +#define CONTENT_TYPE_STR_AUDIO_BASIC "audio/basic" +#define CONTENT_TYPE_STR_AUDIO_MIDI "audio/midi" +#define CONTENT_TYPE_STR_AUDIO_WAV "audio/wav" +#define CONTENT_TYPE_STR_X_CNT_DOCUMENT ".chaos/document" +#define CONTENT_TYPE_STR_X_CNT_FSYSBOX ".chaos/fsys-box" +#define CONTENT_TYPE_STR_X_CNT_CDROM_VOLUME ".chaos/fsys-cdrom-volume" +#define CONTENT_TYPE_STR_X_CNT_DISK_35 ".chaos/fsys-disk-35" +#define CONTENT_TYPE_STR_X_CNT_DISK_525 ".chaos/fsys-disk-525" +#define CONTENT_TYPE_STR_X_CNT_FSYSFILE ".chaos/fsys-file" +#define CONTENT_TYPE_STR_X_CNT_FIXED_VOLUME ".chaos/fsys-fixed-volume" +#define CONTENT_TYPE_STR_X_CNT_FSYSFOLDER ".chaos/fsys-folder" +#define CONTENT_TYPE_STR_X_CNT_RAM_VOLUME ".chaos/fsys-ram-volume" +#define CONTENT_TYPE_STR_X_CNT_REMOTE_VOLUME ".chaos/fsys-remote-volume" +#define CONTENT_TYPE_STR_X_CNT_REMOVEABLE_VOLUME \ + ".chaos/fsys-removeable-volume" +#define CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFILE ".chaos/fsys-special-file" +#define CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFOLDER ".chaos/fsys-special-folder" +#define CONTENT_TYPE_STR_X_CNT_TAPEDRIVE ".chaos/fsys-tapedrive" +#define CONTENT_TYPE_STR_X_CNT_FSYSURLFILE ".chaos/fsys-urlfile" +#define CONTENT_TYPE_STR_X_CNT_FTPBOX ".chaos/ftp-box" +#define CONTENT_TYPE_STR_X_CNT_FTPFILE ".chaos/ftp-file" +#define CONTENT_TYPE_STR_X_CNT_FTPFOLDER ".chaos/ftp-folder" +#define CONTENT_TYPE_STR_X_CNT_FTPLINK ".chaos/ftp-link" +#define CONTENT_TYPE_STR_X_CNT_HTTPBOX ".chaos/http-box" +#define CONTENT_TYPE_STR_X_CNT_HTTPFILE ".chaos/http-file" +#define CONTENT_TYPE_STR_X_CNT_IMAPBOX ".chaos/imap-box" +#define CONTENT_TYPE_STR_X_CNT_IMAPFOLDER ".chaos/imap-folder" +#define CONTENT_TYPE_STR_X_CNT_MESSAGE ".chaos/message" +#define CONTENT_TYPE_STR_X_CNT_NEWSBOX ".chaos/news-box" +#define CONTENT_TYPE_STR_X_CNT_NEWSGROUP ".chaos/news-group" +#define CONTENT_TYPE_STR_X_CNT_OUTBOX ".chaos/out-box" +#define CONTENT_TYPE_STR_X_CNT_POP3BOX ".chaos/pop3-box" +#define CONTENT_TYPE_STR_X_CNT_PUBLISHBOX ".chaos/publish-box" +#define CONTENT_TYPE_STR_X_CNT_SEARCHBOX ".chaos/search-box" +#define CONTENT_TYPE_STR_X_CNT_SEPARATOR ".chaos/separator" +#define CONTENT_TYPE_STR_X_CNT_BOOKMARK ".chaos/subscribe-bookmark" +#define CONTENT_TYPE_STR_X_CNT_SUBSCRIBEBOX ".chaos/subscribe-box" +#define CONTENT_TYPE_STR_X_CNT_CDFITEM ".chaos/subscribe-cdf-item" +#define CONTENT_TYPE_STR_X_CNT_CDFSUB ".chaos/subscribe-cdf-sub" +#define CONTENT_TYPE_STR_X_CNT_CDF ".chaos/subscribe-cdf" +#define CONTENT_TYPE_STR_X_CNT_STARCHANNEL ".chaos/subscribe-sdc" +#define CONTENT_TYPE_STR_X_CNT_TRASHBOX ".chaos/trash-box" +#define CONTENT_TYPE_STR_X_CNT_TRASH ".chaos/trash-item" +#define CONTENT_TYPE_STR_X_CNT_VIMBBOARDBOX ".chaos/vim-bboardbox" +#define CONTENT_TYPE_STR_X_CNT_VIMBBOARD ".chaos/vim-bboard" +#define CONTENT_TYPE_STR_X_CNT_VIMBOX ".chaos/vim-box" +#define CONTENT_TYPE_STR_X_CNT_VIMINBOX ".chaos/vim-inbox" +#define CONTENT_TYPE_STR_IMAGE_GENERIC "image/generic" +#define CONTENT_TYPE_STR_IMAGE_GIF "image/gif" +#define CONTENT_TYPE_STR_IMAGE_JPEG "image/jpeg" +#define CONTENT_TYPE_STR_IMAGE_PCX "image/pcx" +#define CONTENT_TYPE_STR_IMAGE_PNG "image/png" +#define CONTENT_TYPE_STR_IMAGE_TIFF "image/tiff" +#define CONTENT_TYPE_STR_IMAGE_BMP "image/x-MS-bmp" +#define CONTENT_TYPE_STR_INET_MSG_RFC822 "message/rfc822" +#define CONTENT_TYPE_STR_INET_MULTI_ALTERNATIVE "multipart/alternative" +#define CONTENT_TYPE_STR_INET_MULTI_DIGEST "multipart/digest" +#define CONTENT_TYPE_STR_INET_MULTI_MIXED "multipart/mixed" +#define CONTENT_TYPE_STR_INET_MULTI_PARALLEL "multipart/parallel" +#define CONTENT_TYPE_STR_INET_MULTI_RELATED "multipart/related" +#define CONTENT_TYPE_STR_TEXT_ICALENDAR "text/calendar" +#define CONTENT_TYPE_STR_TEXT_HTML "text/html" +#define CONTENT_TYPE_STR_TEXT_PLAIN "text/plain" +#define CONTENT_TYPE_STR_TEXT_XMLICALENDAR "text/x-icalxml" +#define CONTENT_TYPE_STR_TEXT_URL "text/x-url" +#define CONTENT_TYPE_STR_TEXT_VCALENDAR "text/x-vCalendar" +#define CONTENT_TYPE_STR_TEXT_VCARD "text/x-vCard" +#define CONTENT_TYPE_STR_VIDEO_VDO "video/vdo" +#define CONTENT_TYPE_STR_VIDEO_MSVIDEO "video/x-msvideo" +#define CONTENT_TYPE_STR_X_STARMAIL "x-starmail" +#define CONTENT_TYPE_STR_X_VRML "x-world/x-vrml" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER "application/vnd.sun.xml.writer" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_CALC "application/vnd.sun.xml.calc" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESS "application/vnd.sun.xml.impress" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_DRAW "application/vnd.sun.xml.draw" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_CHART "application/vnd.sun.xml.chart" + +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_MATH "application/vnd.sun.xml.math" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER_GLOBAL "application/vnd.sun.xml.writer-global" +#define CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESSPACKED "application/vnd.sun.xml.impress-packed" + +//============================================================================ +/** Definitions for frequently used media type parameter names. + */ +#define INET_CONTENT_TYPE_PARAMETER_CHARSET "charset" + +//============================================================================ +/** Definitions for matching parts of URIs. + */ +#define INETTYPE_URL_PROT_COMPONENT ".component" +#define INETTYPE_URL_PROT_DATA "data" +#define INETTYPE_URL_PROT_FILE "file" +#define INETTYPE_URL_PROT_HTTP "http" +#define INETTYPE_URL_PROT_HTTPS "https" +#define INETTYPE_URL_PROT_MACRO "macro" +#define INETTYPE_URL_PROT_MAILTO "mailto" +#define INETTYPE_URL_PROT_PRIVATE "private" + +#define INETTYPE_URL_SUB_FACTORY "factory" +#define INETTYPE_URL_SUB_HELPID "helpid" + +#define INETTYPE_URL_SSUB_FRAMESET "frameset" +#define INETTYPE_URL_SSUB_SCALC "scalc" +#define INETTYPE_URL_SSUB_SCHART "schart" +#define INETTYPE_URL_SSUB_SDRAW "sdraw" +#define INETTYPE_URL_SSUB_SIMAGE "simage" +#define INETTYPE_URL_SSUB_SIMPRESS "simpress" +#define INETTYPE_URL_SSUB_SMATH "smath" +#define INETTYPE_URL_SSUB_SS "ss" +#define INETTYPE_URL_SSUB_SWRITER "swriter" + +#define INETTYPE_URL_SSSUB_GLOB "GlobalDocument" +#define INETTYPE_URL_SSSUB_WEB "web" + +#define INETTYPE_URL_SCHED_CMB "cmbview" +#define INETTYPE_URL_SCHED_FORM "formular" +#define INETTYPE_URL_SCHED_EVENT "type=event" +#define INETTYPE_URL_SCHED_TASK "type=task" + +//============================================================================ +enum INetContentType +{ + CONTENT_TYPE_UNKNOWN, + CONTENT_TYPE_APP_OCTSTREAM, + CONTENT_TYPE_APP_PDF, + CONTENT_TYPE_APP_RTF, + CONTENT_TYPE_APP_MSWORD, + CONTENT_TYPE_APP_MSWORD_TEMPL, + CONTENT_TYPE_APP_STARCALC, + CONTENT_TYPE_APP_STARCHART, + CONTENT_TYPE_APP_STARDRAW, + CONTENT_TYPE_APP_STARHELP, + CONTENT_TYPE_APP_STARIMAGE, + CONTENT_TYPE_APP_STARIMPRESS, + CONTENT_TYPE_APP_STARMATH, + CONTENT_TYPE_APP_STARWRITER, + CONTENT_TYPE_APP_ZIP, + CONTENT_TYPE_AUDIO_AIFF, + CONTENT_TYPE_AUDIO_BASIC, + CONTENT_TYPE_AUDIO_MIDI, + CONTENT_TYPE_AUDIO_WAV, + CONTENT_TYPE_IMAGE_GIF, + CONTENT_TYPE_IMAGE_JPEG, + CONTENT_TYPE_IMAGE_PCX, + CONTENT_TYPE_IMAGE_PNG, + CONTENT_TYPE_IMAGE_TIFF, + CONTENT_TYPE_IMAGE_BMP, + CONTENT_TYPE_TEXT_HTML, + CONTENT_TYPE_TEXT_PLAIN, + CONTENT_TYPE_TEXT_URL, + CONTENT_TYPE_TEXT_VCARD, + CONTENT_TYPE_VIDEO_VDO, + CONTENT_TYPE_VIDEO_MSVIDEO, + CONTENT_TYPE_X_CNT_MESSAGE, + CONTENT_TYPE_X_CNT_DOCUMENT, + CONTENT_TYPE_X_CNT_POP3BOX, + CONTENT_TYPE_X_CNT_IMAPBOX, + CONTENT_TYPE_X_CNT_IMAPFOLDER, + CONTENT_TYPE_X_CNT_VIMBOX, + CONTENT_TYPE_X_CNT_VIMINBOX, + CONTENT_TYPE_X_CNT_VIMBBOARDBOX, + CONTENT_TYPE_X_CNT_VIMBBOARD, + CONTENT_TYPE_X_CNT_NEWSBOX, + CONTENT_TYPE_X_CNT_NEWSGROUP, + CONTENT_TYPE_X_CNT_OUTBOX, + CONTENT_TYPE_X_CNT_FTPBOX, + CONTENT_TYPE_X_CNT_FTPFOLDER, + CONTENT_TYPE_X_CNT_FTPFILE, + CONTENT_TYPE_X_CNT_FTPLINK, + CONTENT_TYPE_X_CNT_HTTPBOX, + CONTENT_TYPE_X_CNT_FSYSBOX, + CONTENT_TYPE_X_CNT_FSYSFOLDER, + CONTENT_TYPE_X_CNT_FSYSFILE, + CONTENT_TYPE_X_CNT_FSYSURLFILE, + CONTENT_TYPE_X_CNT_PUBLISHBOX, + CONTENT_TYPE_X_CNT_SEARCHBOX, + CONTENT_TYPE_X_CNT_SUBSCRIBEBOX, + CONTENT_TYPE_X_CNT_BOOKMARK, + CONTENT_TYPE_X_CNT_CDF, + CONTENT_TYPE_X_CNT_CDFSUB, + CONTENT_TYPE_X_CNT_CDFITEM, + CONTENT_TYPE_X_CNT_TRASHBOX, + CONTENT_TYPE_X_CNT_TRASH, + CONTENT_TYPE_X_STARMAIL, + CONTENT_TYPE_X_VRML, + CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME, + CONTENT_TYPE_X_CNT_FIXED_VOLUME, + CONTENT_TYPE_X_CNT_REMOTE_VOLUME, + CONTENT_TYPE_X_CNT_RAM_VOLUME, + CONTENT_TYPE_X_CNT_CDROM_VOLUME, + CONTENT_TYPE_X_CNT_DISK_35, + CONTENT_TYPE_X_CNT_DISK_525, + CONTENT_TYPE_X_CNT_TAPEDRIVE, + CONTENT_TYPE_APP_GALLERY, + CONTENT_TYPE_APP_GALLERY_THEME, + CONTENT_TYPE_X_CNT_STARCHANNEL, + CONTENT_TYPE_X_CNT_SEPARATOR, + CONTENT_TYPE_APP_STARWRITER_GLOB, + CONTENT_TYPE_APP_STARMAIL_SDM, + CONTENT_TYPE_APP_STARMAIL_SMD, + CONTENT_TYPE_APP_VND_CALC, + CONTENT_TYPE_APP_VND_CHART, + CONTENT_TYPE_APP_VND_DRAW, + CONTENT_TYPE_APP_VND_IMAGE, + CONTENT_TYPE_APP_VND_IMPRESS, + CONTENT_TYPE_APP_VND_MAIL, + CONTENT_TYPE_APP_VND_MATH, + CONTENT_TYPE_APP_VND_WRITER, + CONTENT_TYPE_APP_VND_WRITER_GLOBAL, + CONTENT_TYPE_APP_VND_WRITER_WEB, + CONTENT_TYPE_APP_SCHEDULE, + CONTENT_TYPE_APP_SCHEDULE_EVT, + CONTENT_TYPE_APP_SCHEDULE_TASK, + CONTENT_TYPE_APP_SCHEDULE_FORM_EVT, + CONTENT_TYPE_APP_SCHEDULE_FORM_TASK, + CONTENT_TYPE_APP_FRAMESET, + CONTENT_TYPE_APP_MACRO, + CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER, + CONTENT_TYPE_X_CNT_FSYSSPECIALFILE, + CONTENT_TYPE_APP_VND_TEMPLATE, + CONTENT_TYPE_IMAGE_GENERIC, + CONTENT_TYPE_APP_VND_NEWS, + CONTENT_TYPE_APP_VND_OUTTRAY, + CONTENT_TYPE_X_CNT_HTTPFILE, + CONTENT_TYPE_APP_MSEXCEL, + CONTENT_TYPE_APP_MSEXCEL_TEMPL, + CONTENT_TYPE_APP_MSPPOINT, + CONTENT_TYPE_APP_MSPPOINT_TEMPL, + CONTENT_TYPE_TEXT_VCALENDAR, + CONTENT_TYPE_TEXT_ICALENDAR, + CONTENT_TYPE_TEXT_XMLICALENDAR, + CONTENT_TYPE_APP_CDE_CALENDAR_APP, + CONTENT_TYPE_INET_MESSAGE_RFC822, + CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE, + CONTENT_TYPE_INET_MULTIPART_DIGEST, + CONTENT_TYPE_INET_MULTIPART_PARALLEL, + CONTENT_TYPE_INET_MULTIPART_RELATED, + CONTENT_TYPE_INET_MULTIPART_MIXED, + CONTENT_TYPE_APP_VND_IMPRESSPACKED, + CONTENT_TYPE_APP_JAR, + CONTENT_TYPE_APP_VND_SUN_XML_WRITER, + CONTENT_TYPE_APP_VND_SUN_XML_CALC, + CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, + CONTENT_TYPE_APP_VND_SUN_XML_DRAW, + CONTENT_TYPE_APP_VND_SUN_XML_CHART, + CONTENT_TYPE_APP_VND_SUN_XML_MATH, + CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, + CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, + CONTENT_TYPE_LAST = CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED +}; + +//============================================================================ +class SVL_DLLPUBLIC INetContentTypes +{ +public: + static void Uninitialize(); + + static INetContentType RegisterContentType(UniString const & rTypeName, + UniString const & + rPresentation, + UniString const * pExtension + = 0, + UniString const * + pSystemFileType = 0); + + static INetContentType GetContentType(UniString const & rTypeName); + + static UniString GetContentType(INetContentType eTypeID); + + static UniString GetPresentation(INetContentType eTypeID, + const ::com::sun::star::lang::Locale& aLocale); + + static UniString GetExtension(UniString const & rTypeName); + + static INetContentType GetContentType4Extension(UniString const & + rExtension); + + static INetContentType GetContentTypeFromURL(UniString const & rURL); + + static bool GetExtensionFromURL(UniString const & rURL, + UniString & rExtension); + + static INetContentType MapStringToContentType(UniString const & + rPresentation); + + /** Parse the body of an RFC 2045 Content-Type header field. + + @param rMediaType The body of the Content-Type header field. It must + be of the form + + token "/" token *(";" token "=" (token / quoted-string)) + + with intervening linear white space and comments (cf. RFCs 822, 2045). + The RFC 2231 extension are supported. The encoding of rMediaType + should be US-ASCII, but any values in the range 0x80--0xFF are + interpretet 'as appropriate.' + + @param rType Returns the type (the first of the above tokens), in US- + ASCII encoding and converted to lower case. + + @param rSubType Returns the sub type (the second of the above + tokens), in US-ASCII encoding and converted to lower case. + + @param rParameters If not null, returns the parameters as a list of + INetContentTypeParameters (the attributes are in US-ASCII encoding and + converted to lower case, the values are in Unicode encoding). If + null, only the syntax of the parameters is checked, but they are not + returned. + + @return True if the syntax of the field body is correct. If false is + returned, none of the output parameters will be modified! + */ + static bool parse(ByteString const & rMediaType, ByteString & rType, + ByteString & rSubType, + INetContentTypeParameterList * pParameters = 0); + + /** Parse the body of an RFC 2045 Content-Type header field. + + @param rMediaType The body of the Content-Type header field. It must + be of the form + + token "/" token *(";" token "=" (token / quoted-string)) + + with intervening linear white space and comments (cf. RFCs 822, 2045). + The RFC 2231 extension are supported. The encoding of rMediaType + should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF + are interpretet 'as appropriate.' + + @param rType Returns the type (the first of the above tokens), in US- + ASCII encoding and converted to lower case. + + @param rSubType Returns the sub type (the second of the above + tokens), in US-ASCII encoding and converted to lower case. + + @param rParameters If not null, returns the parameters as a list of + INetContentTypeParameters (the attributes are in US-ASCII encoding and + converted to lower case, the values are in Unicode encoding). If + null, only the syntax of the parameters is checked, but they are not + returned. + + @return True if the syntax of the field body is correct. If false is + returned, none of the output parameters will be modified! + */ + static bool parse(UniString const & rMediaType, UniString & rType, + UniString & rSubType, + INetContentTypeParameterList * pParameters = 0); + + /** Append a parameter to the string representation of a MIME media type. + + @param rMediaType The string representation of a MIME media type. + + @param rAttribute The name of the parameter. Must be a valid RFC + 2045 token. + + @param rValue The value of the paramter. Must only consist of US- + ASCII characters. + + @return The string representation of rMediaType with the new + parameter appended. It is not checked whether a parameter with that + name already existed in rMediaType. + */ + static ByteString appendUSASCIIParameter(ByteString const & rMediaType, + ByteString const & rAttribute, + ByteString const & rValue); + + /** Append a parameter to the string representation of a MIME media type. + + @param rMediaType The string representation of a MIME media type. + + @param rAttribute The name of the parameter. Must be a valid RFC + 2045 token. + + @param rValue The value of the paramter. Must only consist of US- + ASCII characters. + + @return The string representation of rMediaType with the new + parameter appended. It is not checked whether a parameter with that + name already existed in rMediaType. + */ + static UniString appendUSASCIIParameter(UniString const & rMediaType, + UniString const & rAttribute, + UniString const & rValue); +}; + +#endif // _INETTYPE_HXX + diff --git a/svl/inc/svl/intitem.hxx b/svl/inc/svl/intitem.hxx new file mode 100644 index 000000000000..7bfa3433c6b6 --- /dev/null +++ b/svl/inc/svl/intitem.hxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * 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: intitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXINTITEM_HXX +#define _SFXINTITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/cintitem.hxx> + +//============================================================================ +class SVL_DLLPUBLIC SfxByteItem: public CntByteItem +{ +public: + TYPEINFO(); + + SfxByteItem(USHORT which = 0, BYTE nValue = 0): + CntByteItem(which, nValue) {} + + SfxByteItem(USHORT which, SvStream & rStream): + CntByteItem(which, rStream) {} + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxByteItem(*this); } +}; + +//============================================================================ +DBG_NAMEEX_VISIBILITY(SfxInt16Item, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC SfxInt16Item: public SfxPoolItem +{ + INT16 m_nValue; + +public: + TYPEINFO(); + + SfxInt16Item(USHORT which = 0, INT16 nTheValue = 0): + SfxPoolItem(which), m_nValue(nTheValue) + { DBG_CTOR(SfxInt16Item, 0); } + + SfxInt16Item(USHORT nWhich, SvStream & rStream); + + SfxInt16Item(const SfxInt16Item & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(SfxInt16Item, 0); } + + virtual ~SfxInt16Item() { DBG_DTOR(SfxInt16Item, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual INT16 GetMin() const; + + virtual INT16 GetMax() const; + + virtual SfxFieldUnit GetUnit() const; + + INT16 GetValue() const { return m_nValue; } + + inline void SetValue(INT16 nTheValue); +}; + +inline void SfxInt16Item::SetValue(INT16 nTheValue) +{ + DBG_ASSERT(GetRefCount() == 0, "SfxInt16Item::SetValue(); Pooled item"); + m_nValue = nTheValue; +} + +//============================================================================ +class SVL_DLLPUBLIC SfxUInt16Item: public CntUInt16Item +{ +public: + TYPEINFO(); + + SfxUInt16Item(USHORT which = 0, UINT16 nValue = 0): + CntUInt16Item(which, nValue) {} + + SfxUInt16Item(USHORT which, SvStream & rStream): + CntUInt16Item(which, rStream) {} + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const + { return new SfxUInt16Item(Which(), rStream); } + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxUInt16Item(*this); } +}; + +//============================================================================ +class SVL_DLLPUBLIC SfxInt32Item: public CntInt32Item +{ +public: + TYPEINFO(); + + SfxInt32Item(USHORT which = 0, INT32 nValue = 0): + CntInt32Item(which, nValue) {} + + SfxInt32Item(USHORT which, SvStream & rStream): + CntInt32Item(which, rStream) {} + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const + { return new SfxInt32Item(Which(), rStream); } + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxInt32Item(*this); } + +}; + +//============================================================================ +class SVL_DLLPUBLIC SfxUInt32Item: public CntUInt32Item +{ +public: + TYPEINFO(); + + SfxUInt32Item(USHORT which = 0, UINT32 nValue = 0): + CntUInt32Item(which, nValue) {} + + SfxUInt32Item(USHORT which, SvStream & rStream): + CntUInt32Item(which, rStream) {} + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const + { return new SfxUInt32Item(Which(), rStream); } + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxUInt32Item(*this); } +}; + +#endif // _SFXINTITEM_HXX + diff --git a/svl/inc/svl/isethint.hxx b/svl/inc/svl/isethint.hxx new file mode 100644 index 000000000000..d08819723f43 --- /dev/null +++ b/svl/inc/svl/isethint.hxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * 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: isethint.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXISETHINT_HXX +#define _SFXISETHINT_HXX + +#include "svl/svldllapi.h" + +#ifndef _HINT_HXX +#include <svl/hint.hxx> +#endif + +class SfxItemSet; + +//-------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxItemSetHint: public SfxHint +{ + SfxItemSet* _pItemSet; + +public: + TYPEINFO(); + + SfxItemSetHint( SfxItemSet *pItemSet ); + SfxItemSetHint( const SfxItemSet &rItemSet ); + virtual ~SfxItemSetHint(); + + const SfxItemSet& GetItemSet() const { return *_pItemSet; } +}; + +#endif + diff --git a/svl/inc/svl/itemiter.hxx b/svl/inc/svl/itemiter.hxx new file mode 100644 index 000000000000..50bbe7902e83 --- /dev/null +++ b/svl/inc/svl/itemiter.hxx @@ -0,0 +1,71 @@ +/************************************************************************* + * + * 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: itemiter.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXITEMITER_HXX +#define _SFXITEMITER_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <svl/itemset.hxx> + +class SfxPoolItem; +class SfxItemSet; +class SfxItemPool; + +class SVL_DLLPUBLIC SfxItemIter +{ + // Item-Feld - Start & Ende + const SfxItemSet& _rSet; + USHORT _nStt, _nEnd, _nAkt; + +public: + SfxItemIter( const SfxItemSet& rSet ); + ~SfxItemIter(); + + // falls es diese gibt, returne sie, sonst 0 + const SfxPoolItem* FirstItem() + { _nAkt = _nStt; + return _rSet._nCount ? *(_rSet._aItems+_nAkt) : 0; } + const SfxPoolItem* LastItem() + { _nAkt = _nEnd; + return _rSet._nCount ? *(_rSet._aItems+_nAkt) : 0; } + const SfxPoolItem* GetCurItem() + { return _rSet._nCount ? *(_rSet._aItems+_nAkt) : 0; } + const SfxPoolItem* NextItem(); + const SfxPoolItem* PrevItem(); + + BOOL IsAtStart() const { return _nAkt == _nStt; } + BOOL IsAtEnd() const { return _nAkt == _nEnd; } + + USHORT GetCurPos() const { return _nAkt; } + USHORT GetFirstPos() const { return _nStt; } + USHORT GetLastPos() const { return _nEnd; } +}; + +#endif diff --git a/svl/inc/svl/itempool.hxx b/svl/inc/svl/itempool.hxx new file mode 100644 index 000000000000..d99f29626d38 --- /dev/null +++ b/svl/inc/svl/itempool.hxx @@ -0,0 +1,306 @@ +/************************************************************************* + * + * 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: itempool.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXITEMPOOL_HXX +#define _SFXITEMPOOL_HXX + +#include "svl/svldllapi.h" + +#ifndef INCLUDED_LIMITS_H +#include <limits.h> +#define INCLUDED_LIMITS_H +#endif +#include <tools/solar.h> +#include <tools/string.hxx> +#include <svl/svarray.hxx> +#include <svl/poolitem.hxx> +#include <vector> + +class SvStream; +class SfxBroadcaster; +struct SfxItemPool_Impl; + +#define SFX_WHICH_MAX 4999 + +DBG_NAMEEX(SfxItemPool) + +//==================================================================== + +#define SFX_ITEM_POOLABLE 0x0001 +#define SFX_ITEM_NOT_POOLABLE 0x0002 + +#define SFX_ITEM_USERFLAG0 0x0100 +#define SFX_ITEM_USERFLAG1 0x0200 +#define SFX_ITEM_USERFLAG2 0x0400 +#define SFX_ITEM_USERFLAG3 0x0800 +#define SFX_ITEM_USERFLAG4 0x1000 +#define SFX_ITEM_USERFLAG5 0x2000 +#define SFX_ITEM_USERFLAG6 0x4000 +#define SFX_ITEM_USERFLAG7 0x8000 +#define SFX_ITEM_USERFLAG8 0x0010 +#define SFX_ITEM_USERFLAG9 0x0020 +#define SFX_ITEM_USERFLAGA 0x0040 +#define SFX_ITEM_USERFLAGB 0x0080 + +//==================================================================== + +struct SfxItemInfo +{ + USHORT _nSID; + USHORT _nFlags; +}; + +//==================================================================== + +class SfxStyleSheetIterator; +struct SfxPoolItemArray_Impl; +class SfxItemPool; + +class SVL_DLLPUBLIC SfxItemPoolUser +{ +public: + virtual void ObjectInDestruction(const SfxItemPool& rSfxItemPool) = 0; +}; + +typedef ::std::vector< SfxItemPoolUser* > SfxItemPoolUserVector; + +class SVL_DLLPUBLIC SfxItemPool + +/* [Beschreibung] + + Die von dieser Klasse abgeleiteten Klassen dienen der Bereitstellung von + Defaults von SfxPoolItems und halten konkrete (konstante) Instanzen, die + dann von mehreren Stellen (i.d.R. eines Dokuments) referenziert werden + k�nnen. + + Dadurch ist jeder Wert nur einmalig gespeichert, was zu wenig Konstruktor + und Destruktor-Aufrufen f�hrt, Vergleiche zwischen Items eines Dokuments + beschleunigt und ein einfaches Laden und Speichern von Attributen + bereitstellt. +*/ + +{ + SVL_DLLPRIVATE void readTheItems(SvStream & rStream, USHORT nCount, USHORT nVersion, + SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** pArr); + + UniString aName; + USHORT nStart, nEnd; + USHORT _nFileFormatVersion; +#ifdef TF_POOLABLE + const SfxItemInfo* pItemInfos; +#else + USHORT* pSlotIds; +#endif + SfxItemPool_Impl* pImp; + SfxPoolItem** ppStaticDefaults; + SfxPoolItem** ppPoolDefaults; + SfxItemPool* pSecondary; + SfxItemPool* pMaster; + USHORT* _pPoolRanges; + FASTBOOL bPersistentRefCounts; + +private: + // ObjectUser section + SfxItemPoolUserVector maSfxItemPoolUsers; + +public: + void AddSfxItemPoolUser(SfxItemPoolUser& rNewUser); + void RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser); + + //--------------------------------------------------------------------- +#ifndef _SFXITEMS_HXX + +friend class SfxPoolWhichMap; + +private: + inline USHORT GetIndex_Impl(USHORT nWhich) const; + inline USHORT GetSize_Impl() const { return nEnd - nStart + 1; } + + SVL_DLLPRIVATE SvStream& Load1_Impl( SvStream &rStream ); + SVL_DLLPRIVATE FASTBOOL IsItemFlag_Impl( USHORT nWhich, USHORT nFlag ) const; + +public: + // fuer dflt. SfxItemSet::CTOR, setze dflt. WhichRanges + void FillItemIdRanges_Impl( USHORT*& pWhichRanges ) const; + const USHORT* GetFrozenIdRanges() const + { return _pPoolRanges; } + FASTBOOL IsVer2_Impl() const; + +#endif + //--------------------------------------------------------------------- + +protected: + static inline void SetRefCount( SfxPoolItem& rItem, ULONG n ); + static inline ULONG AddRef( const SfxPoolItem& rItem, ULONG n = 1 ); + static inline ULONG ReleaseRef( const SfxPoolItem& rItem, ULONG n = 1); + +public: + SfxItemPool( const SfxItemPool &rPool, + BOOL bCloneStaticDefaults = FALSE ); + SfxItemPool( const UniString &rName, + USHORT nStart, USHORT nEnd, +#ifdef TF_POOLABLE + const SfxItemInfo *pItemInfos, +#endif + SfxPoolItem **pDefaults = 0, +#ifndef TF_POOLABLE + USHORT *pSlotIds = 0, +#endif + FASTBOOL bLoadRefCounts = TRUE ); +protected: + virtual ~SfxItemPool(); +public: + static void Free(SfxItemPool* pPool); + + SfxBroadcaster& BC(); + + void SetPoolDefaultItem( const SfxPoolItem& ); + const SfxPoolItem* GetPoolDefaultItem( USHORT nWhich ) const; + void ResetPoolDefaultItem( USHORT nWhich ); + + void SetDefaults( SfxPoolItem **pDefaults ); + void ReleaseDefaults( BOOL bDelete = FALSE ); + static void ReleaseDefaults( SfxPoolItem **pDefaults, USHORT nCount, BOOL bDelete = FALSE ); + + virtual SfxMapUnit GetMetric( USHORT nWhich ) const; + void SetDefaultMetric( SfxMapUnit eNewMetric ); + virtual SfxItemPresentation GetPresentation( const SfxPoolItem& rItem, + SfxItemPresentation ePresentation, + SfxMapUnit ePresentationMetric, + XubString& rText, + const IntlWrapper * pIntlWrapper + = 0 ) const; + virtual SfxItemPool* Clone() const; + UniString const & GetName() const { return aName; } + + virtual const SfxPoolItem& Put( const SfxPoolItem&, USHORT nWhich = 0 ); + virtual void Remove( const SfxPoolItem& ); + virtual const SfxPoolItem& GetDefaultItem( USHORT nWhich ) const; + + const SfxPoolItem* LoadItem( SvStream &rStream, + FASTBOOL bDirect = FALSE, + const SfxItemPool *pRefPool = 0 ); + FASTBOOL StoreItem( SvStream &rStream, + const SfxPoolItem &rItem, + FASTBOOL bDirect = FALSE ) const; + + USHORT GetSurrogate(const SfxPoolItem *) const; + const SfxPoolItem * GetItem(USHORT nWhich, USHORT nSurrogate) const; + USHORT GetItemCount(USHORT nWhich) const; + const SfxPoolItem* LoadSurrogate(SvStream& rStream, + USHORT &rWhich, USHORT nSlotId, + const SfxItemPool* pRefPool = 0 ); + FASTBOOL StoreSurrogate(SvStream& rStream, + const SfxPoolItem *pItem ) const; + + virtual SvStream & Load(SvStream &); + virtual SvStream & Store(SvStream &) const; + int HasPersistentRefCounts() const { + return bPersistentRefCounts; } + void LoadCompleted(); + + USHORT GetFirstWhich() const { return nStart; } + USHORT GetLastWhich() const { return nEnd; } + FASTBOOL IsInRange( USHORT nWhich ) const { + return nWhich >= nStart && + nWhich <= nEnd; } + FASTBOOL IsInVersionsRange( USHORT nWhich ) const; + FASTBOOL IsInStoringRange( USHORT nWhich ) const; + void SetStoringRange( USHORT nFrom, USHORT nTo ); + void SetSecondaryPool( SfxItemPool *pPool ); + SfxItemPool* GetSecondaryPool() const { + return pSecondary; } + SfxItemPool* GetMasterPool() const { + return pMaster; } + void FreezeIdRanges(); + + void Cleanup(); + void Delete(); + +#ifdef TF_POOLABLE + FASTBOOL IsItemFlag( USHORT nWhich, USHORT nFlag ) const; + FASTBOOL IsItemFlag( const SfxPoolItem &rItem, USHORT nFlag ) const + { return IsItemFlag( rItem.Which(), nFlag ); } + void SetItemInfos( const SfxItemInfo *pInfos ) + { pItemInfos = pInfos; } +#else + int HasMap() const { return 0 != pSlotIds; } + void SetMap( USHORT *pNewSlotIds ) + { pSlotIds = pNewSlotIds; } +#endif + USHORT GetWhich( USHORT nSlot, BOOL bDeep = TRUE ) const; + USHORT GetSlotId( USHORT nWhich, BOOL bDeep = TRUE ) const; + USHORT GetTrueWhich( USHORT nSlot, BOOL bDeep = TRUE ) const; + USHORT GetTrueSlotId( USHORT nWhich, BOOL bDeep = TRUE ) const; + + void SetVersionMap( USHORT nVer, + USHORT nOldStart, USHORT nOldEnd, + USHORT *pWhichIdTab ); + USHORT GetNewWhich( USHORT nOldWhich ) const; + USHORT GetVersion() const; + USHORT GetFileFormatVersion() const + { return _nFileFormatVersion; } + void SetFileFormatVersion( USHORT nFileFormatVersion ); + USHORT GetLoadingVersion() const; + FASTBOOL IsCurrentVersionLoading() const; + + static int IsWhich(USHORT nId) { + return nId && nId <= SFX_WHICH_MAX; } + static int IsSlot(USHORT nId) { + return nId && nId > SFX_WHICH_MAX; } + + static const SfxItemPool* GetStoringPool(); + static void SetStoringPool( const SfxItemPool * ); + +private: + const SfxItemPool& operator=(const SfxItemPool &); // n.i.!! +}; + +// --------------- Inline Implementierungen ------------------------------ + +// nur der Pool darf den Referenz-Zaehler manipulieren !!! +inline void SfxItemPool::SetRefCount( SfxPoolItem& rItem, ULONG n ) +{ + rItem.SetRefCount(n); +} + +// nur der Pool darf den Referenz-Zaehler manipulieren !!! +inline ULONG SfxItemPool::AddRef( const SfxPoolItem& rItem, ULONG n ) +{ + return rItem.AddRef(n); +} + +// nur der Pool darf den Referenz-Zaehler manipulieren !!! +inline ULONG SfxItemPool::ReleaseRef( const SfxPoolItem& rItem, ULONG n ) +{ + return rItem.ReleaseRef(n); +} + +#endif diff --git a/svl/inc/svl/itemprop.hxx b/svl/inc/svl/itemprop.hxx new file mode 100644 index 000000000000..873c34785d5f --- /dev/null +++ b/svl/inc/svl/itemprop.hxx @@ -0,0 +1,222 @@ +/************************************************************************* + * + * 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: itemprop.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_ITEMPROP_HXX +#define _SFX_ITEMPROP_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <tools/string.hxx> +#include <svl/itemset.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <vector> +/* -----------------------------21.02.00 11:03-------------------------------- + UNO III - Implementation + ---------------------------------------------------------------------------*/ +#define MAP_CHAR_LEN(cchar) cchar, sizeof(cchar) - 1 + +struct SfxItemPropertyMapEntry +{ + const char* pName; + USHORT nNameLen; + USHORT nWID; + const com::sun::star::uno::Type* pType; + long nFlags; + BYTE nMemberId; + +}; + +struct SfxItemPropertySimpleEntry +{ + USHORT nWID; + const com::sun::star::uno::Type* pType; + long nFlags; + BYTE nMemberId; + + SfxItemPropertySimpleEntry() : + nWID( 0 ), + pType( 0 ), + nFlags( 0 ), + nMemberId( 0 ){} + + SfxItemPropertySimpleEntry(USHORT _nWID, const com::sun::star::uno::Type* _pType, + long _nFlags, BYTE _nMemberId) : + nWID( _nWID ), + pType( _pType ), + nFlags( _nFlags ), + nMemberId( _nMemberId ){} + + SfxItemPropertySimpleEntry( const SfxItemPropertyMapEntry* pMapEntry ) : + nWID( pMapEntry->nWID ), + pType( pMapEntry->pType ), + nFlags( pMapEntry->nFlags ), + nMemberId( pMapEntry->nMemberId ){} + +}; +struct SfxItemPropertyNamedEntry : public SfxItemPropertySimpleEntry +{ + ::rtl::OUString sName; + SfxItemPropertyNamedEntry( const String& rName, const SfxItemPropertySimpleEntry& rSimpleEntry) : + SfxItemPropertySimpleEntry( rSimpleEntry ), + sName( rName ){} + +}; +typedef std::vector< SfxItemPropertyNamedEntry > PropertyEntryVector_t; +class SfxItemPropertyMap_Impl; +class SVL_DLLPUBLIC SfxItemPropertyMap +{ + SfxItemPropertyMap_Impl* m_pImpl; +public: + SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ); + SfxItemPropertyMap( const SfxItemPropertyMap* pSource ); + ~SfxItemPropertyMap(); + + const SfxItemPropertySimpleEntry* getByName( const ::rtl::OUString &rName ) const; + com::sun::star::uno::Sequence< com::sun::star::beans::Property > getProperties() const; + com::sun::star::beans::Property getPropertyByName( const ::rtl::OUString rName ) const + throw( ::com::sun::star::beans::UnknownPropertyException ); + sal_Bool hasPropertyByName( const ::rtl::OUString& rName ) const; + + void mergeProperties( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& rPropSeq ); + PropertyEntryVector_t getPropertyEntries() const; + sal_uInt32 getSize() const; + +}; +/* -----------------------------21.02.00 11:19-------------------------------- + + ---------------------------------------------------------------------------*/ +class SVL_DLLPUBLIC SfxItemPropertySet +{ + SfxItemPropertyMap m_aMap; + mutable com::sun::star::uno::Reference<com::sun::star::beans::XPropertySetInfo> m_xInfo; +protected: + virtual BOOL FillItem(SfxItemSet& rSet, USHORT nWhich, BOOL bGetProperty) const; + +public: + SfxItemPropertySet( const SfxItemPropertyMapEntry *pMap ) : + m_aMap(pMap) {} + virtual ~SfxItemPropertySet(); + + void getPropertyValue( const SfxItemPropertySimpleEntry& rEntry, + const SfxItemSet& rSet, + com::sun::star::uno::Any& rAny) const + throw(::com::sun::star::uno::RuntimeException); + void getPropertyValue( const ::rtl::OUString &rName, + const SfxItemSet& rSet, + com::sun::star::uno::Any& rAny) const + throw(::com::sun::star::uno::RuntimeException, + ::com::sun::star::beans::UnknownPropertyException); + com::sun::star::uno::Any + getPropertyValue( const ::rtl::OUString &rName, + const SfxItemSet& rSet ) const + throw(::com::sun::star::uno::RuntimeException, + ::com::sun::star::beans::UnknownPropertyException); + void setPropertyValue( const SfxItemPropertySimpleEntry& rEntry, + const com::sun::star::uno::Any& aVal, + SfxItemSet& rSet ) const + throw(::com::sun::star::uno::RuntimeException, + com::sun::star::lang::IllegalArgumentException); + void setPropertyValue( const ::rtl::OUString& rPropertyName, + const com::sun::star::uno::Any& aVal, + SfxItemSet& rSet ) const + throw(::com::sun::star::uno::RuntimeException, + com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::beans::UnknownPropertyException); + + com::sun::star::beans::PropertyState + getPropertyState(const ::rtl::OUString& rName, const SfxItemSet& rSet)const + throw(com::sun::star::beans::UnknownPropertyException); + com::sun::star::beans::PropertyState + getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const + throw(); + + com::sun::star::uno::Reference<com::sun::star::beans::XPropertySetInfo> + getPropertySetInfo() const; + const SfxItemPropertyMap* + getPropertyMap() const {return &m_aMap;} + +}; +/* -----------------------------21.02.00 11:09-------------------------------- + + ---------------------------------------------------------------------------*/ +struct SfxItemPropertySetInfo_Impl; +class SVL_DLLPUBLIC SfxItemPropertySetInfo : public + cppu::WeakImplHelper1<com::sun::star::beans::XPropertySetInfo> +{ + SfxItemPropertySetInfo_Impl* m_pImpl; + +public: + SfxItemPropertySetInfo(const SfxItemPropertyMap *pMap ); + SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries ); + virtual ~SfxItemPropertySetInfo(); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL + getProperties( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::beans::Property SAL_CALL + getPropertyByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + hasPropertyByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::uno::RuntimeException); + + const SfxItemPropertyMap* getMap() const; +}; +/* -----------------------------21.02.00 12:01-------------------------------- + + ---------------------------------------------------------------------------*/ +class SVL_DLLPUBLIC SfxExtItemPropertySetInfo: public cppu::WeakImplHelper1<com::sun::star::beans::XPropertySetInfo > +{ + SfxItemPropertyMap aExtMap; +public: + SfxExtItemPropertySetInfo( + const SfxItemPropertyMapEntry *pMap, + const com::sun::star::uno::Sequence<com::sun::star::beans::Property>& rPropSeq ); + virtual ~SfxExtItemPropertySetInfo(); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL + getProperties( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::beans::Property SAL_CALL + getPropertyByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + hasPropertyByName( const ::rtl::OUString& Name ) + throw(::com::sun::star::uno::RuntimeException); +}; + +#endif diff --git a/svl/inc/svl/itemset.hxx b/svl/inc/svl/itemset.hxx new file mode 100644 index 000000000000..a09cfbc2bbb2 --- /dev/null +++ b/svl/inc/svl/itemset.hxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * 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: itemset.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXITEMSET_HXX +#define _SFXITEMSET_HXX + +#include "svl/svldllapi.h" + +#if STLPORT_VERSION<321 +#include <stdarg.h> +#else +#include <cstdarg> // std::va_list and friends +#endif +#include <svl/poolitem.hxx> +#include <tools/rtti.hxx> +#include <tools/solar.h> + +class SfxItemPool; +class SfxPoolItem; +class SvStream; + +typedef SfxPoolItem const** SfxItemArray; + +#define USHORT_ARG int + +#ifdef MI_HATS_REPARIERT +#ifndef DBG +#ifdef DBG_UTILx +#define DBG(s) s +#define _pChildCount(THIS) ( *(USHORT**)SfxPointerServer::GetServer()->GetPointer(THIS) ) +#define _pChildCountCtor ( (*(USHORT**)SfxPointerServer::GetServer()->CreatePointer(this)) = new USHORT ) +#define _pChildCountDtor ( SfxPointerServer::GetServer()->ReleasePointer(this) ) +#else +#define DBG(s) +#endif +#endif +#else +#ifdef DBG +#undef DBG +#endif +#define DBG(s) +#endif + +//======================================================================== + +#define SFX_ITEMSET_GET( rSet, pItem, ItemType, nSlotId, bDeep ) \ + const ItemType *pItem = (const ItemType*) \ + (rSet).GetItem( nSlotId, bDeep, TYPE(ItemType) ) + +//======================================================================== + +class SVL_DLLPUBLIC SfxItemSet +{ + friend class SfxItemIter; + + SfxItemPool* _pPool; // der verwendete Pool + const SfxItemSet* _pParent; // Ableitung + SfxItemArray _aItems; // Item-Feld + USHORT* _pWhichRanges; // Array von Which-Bereichen + USHORT _nCount; // Anzahl Items + + //--------------------------------------------------------------------- +#ifndef _SFXITEMS_HXX + +friend class SfxItemPoolCache; +friend class SfxAllItemSet; +friend const char *DbgCheckItemSet( const void* ); + +private: + SVL_DLLPRIVATE void InitRanges_Impl(const USHORT *nWhichPairTable); + SVL_DLLPRIVATE void InitRanges_Impl(va_list pWhich, USHORT n1, USHORT n2, USHORT n3); + SVL_DLLPRIVATE void InitRanges_Impl(USHORT nWh1, USHORT nWh2); + +public: + SfxItemArray GetItems_Impl() const { return _aItems; } + +#endif + //--------------------------------------------------------------------- + +private: + const SfxItemSet& operator=(const SfxItemSet &); // n.i.!! + +protected: + // Notification-Callback + virtual void Changed( const SfxPoolItem& rOld, const SfxPoolItem& rNew ); + + // direkte Put-Methode + int PutDirect(const SfxPoolItem &rItem); + +public: + SfxItemSet( const SfxItemSet& ); + + SfxItemSet( SfxItemPool&, BOOL bTotalPoolRanges = FALSE ); + SfxItemSet( SfxItemPool&, USHORT nWhich1, USHORT nWhich2 ); + SfxItemSet( SfxItemPool&, USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ... ); + SfxItemSet( SfxItemPool&, const USHORT* nWhichPairTable ); + virtual ~SfxItemSet(); + + virtual SfxItemSet * Clone(BOOL bItems = TRUE, SfxItemPool *pToPool = 0) const; + + // Items erfragen + USHORT Count() const { return _nCount; } + USHORT TotalCount() const; + + virtual const SfxPoolItem& Get( USHORT nWhich, BOOL bSrchInParent = TRUE ) const; + const SfxPoolItem* GetItem( USHORT nWhich, BOOL bSrchInParent = TRUE, + TypeId aItemType = 0 ) const; + + // Which-Wert des Items an der Position nPos erfragen + USHORT GetWhichByPos(USHORT nPos) const; + + // Item-Status erfragen + SfxItemState GetItemState( USHORT nWhich, + BOOL bSrchInParent = TRUE, + const SfxPoolItem **ppItem = 0 ) const; + + virtual void DisableItem(USHORT nWhich); + virtual void InvalidateItem( USHORT nWhich ); + virtual USHORT ClearItem( USHORT nWhich = 0); + virtual void ClearInvalidItems( BOOL bHardDefault = FALSE ); + void InvalidateAllItems(); HACK(via nWhich = 0) + + inline void SetParent( const SfxItemSet* pNew ); + + // Items hinzufuegen, loeschen etc. + virtual const SfxPoolItem* Put( const SfxPoolItem&, USHORT nWhich ); + const SfxPoolItem* Put( const SfxPoolItem& rItem ) + { return Put(rItem, rItem.Which()); } + virtual int Put( const SfxItemSet&, + BOOL bInvalidAsDefault = TRUE ); + void PutExtended( const SfxItemSet&, + SfxItemState eDontCareAs = SFX_ITEM_UNKNOWN, + SfxItemState eDefaultAs = SFX_ITEM_UNKNOWN ); + + virtual int Set( const SfxItemSet&, BOOL bDeep = TRUE ); + + virtual void Intersect( const SfxItemSet& rSet ); + virtual void MergeValues( const SfxItemSet& rSet, BOOL bOverwriteDefaults = FALSE ); + virtual void Differentiate( const SfxItemSet& rSet ); + virtual void MergeValue( const SfxPoolItem& rItem, BOOL bOverwriteDefaults = FALSE ); + + SfxItemPool* GetPool() const { return _pPool; } + const USHORT* GetRanges() const { return _pWhichRanges; } + void SetRanges( const USHORT *pRanges ); + void MergeRange( USHORT nFrom, USHORT nTo ); + const SfxItemSet* GetParent() const { return _pParent; } + + virtual SvStream & Load( SvStream &, FASTBOOL bDirect = FALSE, + const SfxItemPool *pRefPool = 0 ); + virtual SvStream & Store( SvStream &, FASTBOOL bDirect = FALSE ) const; + + virtual int operator==(const SfxItemSet &) const; +}; + +// --------------- Inline Implementierungen ------------------------ + +inline void SfxItemSet::SetParent( const SfxItemSet* pNew ) +{ + DBG( if (_pParent) --*_pChildCount(_pParent) ); + _pParent = pNew; + DBG( if (_pParent) ++*_pChildCount(_pParent) ); +} + +//======================================================================== + +class SVL_DLLPUBLIC SfxAllItemSet: public SfxItemSet + +/* versteht alle Ranges; werden durch das Putten der Items + automatisch angepasst +*/ + +{ + SfxVoidItem aDefault; + USHORT nFree; + +public: + SfxAllItemSet( SfxItemPool &rPool ); + SfxAllItemSet( const SfxItemSet & ); + SfxAllItemSet( const SfxAllItemSet & ); + + virtual SfxItemSet * Clone( BOOL bItems = TRUE, SfxItemPool *pToPool = 0 ) const; + virtual const SfxPoolItem* Put( const SfxPoolItem&, USHORT nWhich ); + const SfxPoolItem* Put( const SfxPoolItem& rItem ) + { return Put(rItem, rItem.Which()); } + virtual int Put( const SfxItemSet&, + BOOL bInvalidAsDefault = TRUE ); +}; + +#endif // #ifndef _SFXITEMSET_HXX + diff --git a/svl/inc/svl/languageoptions.hxx b/svl/inc/svl/languageoptions.hxx new file mode 100644 index 000000000000..0cba5235674a --- /dev/null +++ b/svl/inc/svl/languageoptions.hxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * 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: languageoptions.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX +#define _SVTOOLS_LANGUAGEOPTIONS_HXX + +#include "svl/svldllapi.h" +#include <sal/types.h> +#include <svl/brdcst.hxx> +#include <svl/lstner.hxx> +#include <unotools/configitem.hxx> +#include <unotools/options.hxx> +#include <i18npool/lang.h> + +// class SvtLanguageOptions ---------------------------------------------------- + +// these defines can be ored +#define SCRIPTTYPE_LATIN 0x01 +#define SCRIPTTYPE_ASIAN 0x02 +#define SCRIPTTYPE_COMPLEX 0x04 + +class SvtCJKOptions; +class SvtCTLOptions; + +class SVL_DLLPUBLIC SvtLanguageOptions : public ::utl::detail::Options +{ +private: + SvtCJKOptions* m_pCJKOptions; + SvtCTLOptions* m_pCTLOptions; + +public: + enum EOption + { + // cjk options + E_CJKFONT, + E_VERTICALTEXT, + E_ASIANTYPOGRAPHY, + E_JAPANESEFIND, + E_RUBY, + E_CHANGECASEMAP, + E_DOUBLELINES, + E_EMPHASISMARKS, + E_VERTICALCALLOUT, + E_ALLCJK, + // ctl options + E_CTLFONT, + E_CTLSEQUENCECHECKING, + E_CTLCURSORMOVEMENT, + E_CTLTEXTNUMERALS + }; + + // bDontLoad is for referencing purposes only + SvtLanguageOptions( sal_Bool _bDontLoad = sal_False ); + ~SvtLanguageOptions(); + + // CJK options + sal_Bool IsCJKFontEnabled() const; + sal_Bool IsVerticalTextEnabled() const; + sal_Bool IsAsianTypographyEnabled() const; + sal_Bool IsJapaneseFindEnabled() const; + sal_Bool IsRubyEnabled() const; + sal_Bool IsChangeCaseMapEnabled() const; + sal_Bool IsDoubleLinesEnabled() const; + sal_Bool IsEmphasisMarksEnabled() const; + sal_Bool IsVerticalCallOutEnabled() const; + void SetAll( sal_Bool _bSet ); + sal_Bool IsAnyEnabled() const; + + // CTL options + void SetCTLFontEnabled( sal_Bool _bEnabled ); + sal_Bool IsCTLFontEnabled() const; + + void SetCTLSequenceChecking( sal_Bool _bEnabled ); + sal_Bool IsCTLSequenceChecking() const; + + void SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingRestricted( void ) const; + + void SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingTypeAndReplace() const; + + sal_Bool IsReadOnly(EOption eOption) const; + + // returns for a language the scripttype + static sal_uInt16 GetScriptTypeOfLanguage( sal_uInt16 nLang ); +}; +/** #i42730# Gives access to the Windows 16bit system locale + */ +class SVL_DLLPUBLIC SvtSystemLanguageOptions : public utl::ConfigItem +{ +private: + ::rtl::OUString m_sWin16SystemLocale; + +public: + SvtSystemLanguageOptions(); + ~SvtSystemLanguageOptions(); + + virtual void Commit(); + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& rPropertyNames ); + + LanguageType GetWin16SystemLanguage(); +}; + +#endif // _SVTOOLS_LANGUAGEOPTIONS_HXX + diff --git a/svl/inc/svl/lckbitem.hxx b/svl/inc/svl/lckbitem.hxx new file mode 100644 index 000000000000..77cb63414f4e --- /dev/null +++ b/svl/inc/svl/lckbitem.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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: lckbitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _LCKBITEM_HXX +#define _LCKBITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/solar.h> +#include <tools/rtti.hxx> +#include <tools/stream.hxx> +#include <svl/poolitem.hxx> + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxLockBytesItem : public SfxPoolItem +{ + SvLockBytesRef _xVal; + +public: + TYPEINFO(); + SfxLockBytesItem(); + SfxLockBytesItem( USHORT nWhich, + SvLockBytes *pLockBytes ); + SfxLockBytesItem( USHORT nWhich, SvStream & ); + SfxLockBytesItem( const SfxLockBytesItem& ); + ~SfxLockBytesItem(); + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nItemVersion) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion ) const; + + SvLockBytes* GetValue() const { return _xVal; } + + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; +}; + +#endif + diff --git a/svl/inc/svl/lockfilecommon.hxx b/svl/inc/svl/lockfilecommon.hxx new file mode 100644 index 000000000000..c1e18aac7e14 --- /dev/null +++ b/svl/inc/svl/lockfilecommon.hxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * 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: documentlockfile.hxx,v $ + * + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVT_LOCKFILECOMMON_HXX +#define _SVT_LOCKFILECOMMON_HXX + +#include <svl/svldllapi.h> + +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <osl/mutex.hxx> +#include <tools/urlobj.hxx> + +#define LOCKFILE_OOOUSERNAME_ID 0 +#define LOCKFILE_SYSUSERNAME_ID 1 +#define LOCKFILE_LOCALHOST_ID 2 +#define LOCKFILE_EDITTIME_ID 3 +#define LOCKFILE_USERURL_ID 4 +#define LOCKFILE_ENTRYSIZE 5 + +namespace svt { + +// This is a general implementation that is used in document lock file implementation and in sharing control file implementation +class SVL_DLLPUBLIC LockFileCommon +{ +protected: + ::osl::Mutex m_aMutex; + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + ::rtl::OUString m_aURL; + + + INetURLObject ResolveLinks( const INetURLObject& aDocURL ); + +public: + LockFileCommon( const ::rtl::OUString& aOrigURL, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory, const ::rtl::OUString& aPrefix ); + ~LockFileCommon(); + + static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > ParseList( const ::com::sun::star::uno::Sequence< sal_Int8 >& aBuffer ); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > ParseEntry( const ::com::sun::star::uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& o_nCurPos ); + static ::rtl::OUString ParseName( const ::com::sun::star::uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& o_nCurPos ); + static ::rtl::OUString EscapeCharacters( const ::rtl::OUString& aSource ); + static ::rtl::OUString GetOOOUserName(); + static ::rtl::OUString GetCurrentLocalTime(); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > GenerateOwnEntry(); +}; + +} + +#endif + diff --git a/svl/inc/svl/lstner.hxx b/svl/inc/svl/lstner.hxx new file mode 100644 index 000000000000..c9993834b42a --- /dev/null +++ b/svl/inc/svl/lstner.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * 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: lstner.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXLSTNER_HXX +#define _SFXLSTNER_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> +#include <svl/svarray.hxx> + +class SfxBroadcaster; +class SfxHint; + +#ifndef _SFX_LSTNER_CXX +typedef SvPtrarr SfxBroadcasterArr_Impl; +#endif + +#define SFX_NOTIFY( rBC, rBCT, rHint, rHintT ) \ + Notify( rBC, rHint ) + +//------------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxListener +{ + SfxBroadcasterArr_Impl aBCs; + +private: + const SfxListener& operator=(const SfxListener &); // n.i., ist verboten + +public: + TYPEINFO(); + + SfxListener(); + SfxListener( const SfxListener &rCopy ); + virtual ~SfxListener(); + + BOOL StartListening( SfxBroadcaster& rBroadcaster, BOOL bPreventDups = FALSE ); + BOOL EndListening( SfxBroadcaster& rBroadcaster, BOOL bAllDups = FALSE ); + void EndListening( USHORT nNo ); + void EndListeningAll(); + BOOL IsListening( SfxBroadcaster& rBroadcaster ) const; + + USHORT GetBroadcasterCount() const + { return aBCs.Count(); } + SfxBroadcaster* GetBroadcasterJOE( USHORT nNo ) const + { return (SfxBroadcaster*) aBCs.GetObject(nNo); } + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + +#ifndef _NOTIFY_HXX + void RemoveBroadcaster_Impl( SfxBroadcaster& rBC ); +#endif +}; + +#endif diff --git a/svl/inc/svl/macitem.hxx b/svl/inc/svl/macitem.hxx new file mode 100644 index 000000000000..747b9ec0bf17 --- /dev/null +++ b/svl/inc/svl/macitem.hxx @@ -0,0 +1,212 @@ +/************************************************************************* + * + * 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: macitem.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXMACITEM_HXX +#define _SFXMACITEM_HXX + +// class SvxMacroItem ---------------------------------------------------- + +#include "svl/svldllapi.h" +#include <svl/poolitem.hxx> +#include <tools/rtti.hxx> +#include <tools/debug.hxx> +#include <tools/string.hxx> + +#ifndef _TABLE_HXX +#include <tools/table.hxx> +#endif + +class SvStream; + +#define SVX_MACRO_LANGUAGE_JAVASCRIPT "JavaScript" +#define SVX_MACRO_LANGUAGE_STARBASIC "StarBasic" +#define SVX_MACRO_LANGUAGE_SF "Script" + +DBG_NAMEEX(SvxMacroItem) + +// ----------------------------------------------------------------------- + +//Ein Macro + +enum ScriptType +{ + STARBASIC, + JAVASCRIPT, + EXTENDED_STYPE +}; + +// Basisklasse fuer SjJSbxObject mit virtuellem Destruktor +class SjJSbxObjectBase +{ +public: + virtual ~SjJSbxObjectBase(); + virtual SjJSbxObjectBase* Clone( void ); + //virtual SjJSbxObjectBase& operator=( const SjJSbxObjectBase& rBase ); +}; + +class SjJSbxObject; + +class SVL_DLLPUBLIC SvxMacro +{ + String aMacName; + String aLibName; + // Fuer JavaScript muss ein Function-Objekt gehalten werden + SjJSbxObjectBase* pFunctionObject; + ScriptType eType; + +public: + + SvxMacro( const String &rMacName, const String &rLanguage); + + SvxMacro( const String &rMacName, const String &rLibName, + ScriptType eType); // = STARBASIC entfernt + + SvxMacro( SjJSbxObjectBase* _pFunctionObject, const String &rSource ); + ~SvxMacro(); // noetig fuer pFunctionObject + + const String &GetLibName() const { return aLibName; } + const String &GetMacName() const { return aMacName; } + String GetLanguage()const; + + ScriptType GetScriptType() const { return eType; } + + BOOL HasMacro() const { return aMacName.Len() ? TRUE : FALSE; } + +#ifdef SOLAR_JAVA + // JavaScript-Function-Objekt holen + // ACHTUNG: Implementation in SJ, Source/JScript/sjimpl.cxx + SjJSbxObjectBase* GetFunctionObject( SjJSbxObject* pParent ); +#endif + + SvxMacro& operator=( const SvxMacro& rBase ); +}; + +inline SvxMacro::SvxMacro( const String &rMacName, const String &rLibName, + ScriptType eTyp ) + : aMacName( rMacName ), aLibName( rLibName ), pFunctionObject(NULL), eType( eTyp ) +{} + +inline SvxMacro::SvxMacro( SjJSbxObjectBase* _pFunctionObject, const String &rSource ) + : aMacName( rSource ), pFunctionObject( _pFunctionObject ), eType( JAVASCRIPT ) +{} + +//Macro Table, zerstoert die Pointer im DTor! + +DECLARE_TABLE( _SvxMacroTableDtor, SvxMacro* ) + +#define SVX_MACROTBL_VERSION31 0 +#define SVX_MACROTBL_VERSION40 1 + +#define SVX_MACROTBL_AKTVERSION SVX_MACROTBL_VERSION40 + +class SVL_DLLPUBLIC SvxMacroTableDtor : public _SvxMacroTableDtor +{ +public: + inline SvxMacroTableDtor( const USHORT nInitSz = 0, const USHORT nReSz = 1 ); + inline SvxMacroTableDtor( const SvxMacroTableDtor &rCpy ) : _SvxMacroTableDtor() { *this = rCpy; } + inline ~SvxMacroTableDtor() { DelDtor(); } + SvxMacroTableDtor& operator=( const SvxMacroTableDtor &rCpy ); + + // loescht alle Eintraege + void DelDtor(); + + SvStream& Read( SvStream &, USHORT nVersion = SVX_MACROTBL_AKTVERSION ); + SvStream& Write( SvStream & ) const; + + USHORT GetVersion() const { return SVX_MACROTBL_AKTVERSION; } +}; + +inline SvxMacroTableDtor::SvxMacroTableDtor( const USHORT nInitSz, + const USHORT nReSz) + : _SvxMacroTableDtor( nInitSz, nReSz ) +{} + +/* +[Beschreibung] +Dieses Item beschreibt eine Makro-Tabelle. +*/ + +class SVL_DLLPUBLIC SvxMacroItem: public SfxPoolItem +{ +public: + TYPEINFO(); + + inline SvxMacroItem ( const USHORT nId /*= ITEMID_MACRO*/ ); + + // "pure virtual Methoden" vom SfxPoolItem + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion ) const; + virtual USHORT GetVersion( USHORT nFileFormatVersion ) const; + + inline const SvxMacroTableDtor& GetMacroTable() const { return aMacroTable;} + inline void SetMacroTable( const SvxMacroTableDtor& rTbl ) { aMacroTable = rTbl; } + + inline const SvxMacro& GetMacro( USHORT nEvent ) const; + inline BOOL HasMacro( USHORT nEvent ) const; + void SetMacro( USHORT nEvent, const SvxMacro& ); + inline BOOL DelMacro( USHORT nEvent ); + +private: + SvxMacroTableDtor aMacroTable; + + inline SvxMacroItem( const SvxMacroItem& ); + SvxMacroItem &operator=( const SvxMacroItem & ); +}; + +inline SvxMacroItem::SvxMacroItem( const USHORT nId ) + : SfxPoolItem( nId ) +{} +inline SvxMacroItem::SvxMacroItem( const SvxMacroItem &rCpy ) + : SfxPoolItem( rCpy ), + aMacroTable( rCpy.GetMacroTable() ) +{} + +inline BOOL SvxMacroItem::HasMacro( USHORT nEvent ) const +{ + return aMacroTable.IsKeyValid( nEvent ); +} +inline const SvxMacro& SvxMacroItem::GetMacro( USHORT nEvent ) const +{ + return *(aMacroTable.Get(nEvent)); +} +inline BOOL SvxMacroItem::DelMacro( USHORT nEvent ) +{ + SvxMacro *pMacro = aMacroTable.Remove( nEvent ); + delete pMacro; + return ( pMacro != 0 ); +} + +#endif diff --git a/svl/inc/svl/metitem.hxx b/svl/inc/svl/metitem.hxx new file mode 100644 index 000000000000..5a1e6627542f --- /dev/null +++ b/svl/inc/svl/metitem.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * 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: metitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXMETRICITEM_HXX +#define _SFXMETRICITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/intitem.hxx> + +DBG_NAMEEX_VISIBILITY(SfxMetricItem, SVL_DLLPUBLIC) + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxMetricItem: public SfxInt32Item +{ +public: + TYPEINFO(); + SfxMetricItem( USHORT nWhich = 0, UINT32 nValue = 0 ); + SfxMetricItem( USHORT nWhich, SvStream & ); + SfxMetricItem( const SfxMetricItem& ); + ~SfxMetricItem() { + DBG_DTOR(SfxMetricItem, 0); } + + virtual int ScaleMetrics( long lMult, long lDiv ); + virtual int HasMetrics() const; + +}; + +#endif + diff --git a/svl/inc/svl/nfkeytab.hxx b/svl/inc/svl/nfkeytab.hxx new file mode 100644 index 000000000000..ba8c24f319f6 --- /dev/null +++ b/svl/inc/svl/nfkeytab.hxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * 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: nfkeytab.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_NFKEYTAB_HXX +#define INCLUDED_SVTOOLS_NFKEYTAB_HXX + +#include <tools/string.hxx> + +//! For ImpSvNumberformatScan: first the short symbols, then the long symbols! +//! e.g. first TT then TTTT +//! The internal order is essentially for the format code string scanner! +//! New keywords MUST NOT be inserted, only the NF_KEY_UNUSEDn may be used, +//! NF_KEY_LASTKEYWORD must be adjusted accordingly. Otherwise old versions +//! will fail upon reading these entries. Nevertheless, old versions are NOT +//! able to display those new keywords => blank display. +// +// Note: 2005-09-02: the above applies to the binary file format. +// +// ER 15.12.99: This table is externally only to be used with method +// String SvNumberformat::GetMappedFormatstring( const NfKeywordTable&, const LocaleDataWrapper& ); +// and method +// void SvNumberFormatter::FillKeywordTable( NfKeywordTable&, LanguageType ); +enum NfKeywordIndex +{ + NF_KEY_NONE = 0, + NF_KEY_E, // exponential symbol + NF_KEY_AMPM, // AM/PM + NF_KEY_AP, // a/p + NF_KEY_MI, // minute (!) + NF_KEY_MMI, // minute 02 (!) + NF_KEY_M, // month (!) + NF_KEY_MM, // month 02 (!) + NF_KEY_MMM, // month short name + NF_KEY_MMMM, // month long name + NF_KEY_H, // hour + NF_KEY_HH, // hour 02 + NF_KEY_S, // second + NF_KEY_SS, // second 02 + NF_KEY_Q, // quarter + NF_KEY_QQ, // quarter 02 + NF_KEY_D, // day of month + NF_KEY_DD, // day of month 02 + NF_KEY_DDD, // day of week short + NF_KEY_DDDD, // day of week long + NF_KEY_YY, // year two digits + NF_KEY_YYYY, // year four digits + NF_KEY_NN, // day of week short + NF_KEY_NNNN, // day of week long with separator + NF_KEY_CCC, // currency bank symbol (old version) + NF_KEY_GENERAL, // General / Standard + NF_KEY_LASTOLDKEYWORD = NF_KEY_GENERAL, + NF_KEY_NNN, // day of week long without separator, as of version 6, 10.10.97 + NF_KEY_WW, // week of year, as of version 8, 19.06.98 + NF_KEY_MMMMM, // first letter of month name + NF_KEY_LASTKEYWORD = NF_KEY_MMMMM, + NF_KEY_UNUSED4, + NF_KEY_QUARTER, // was quarter word, not used anymore from SRC631 on (26.04.01) + NF_KEY_TRUE, // boolean true + NF_KEY_FALSE, // boolean false + NF_KEY_BOOLEAN, // boolean + NF_KEY_COLOR, // color + NF_KEY_FIRSTCOLOR, + NF_KEY_BLACK = NF_KEY_FIRSTCOLOR, // you do know colors, don't you? + NF_KEY_BLUE, + NF_KEY_GREEN, + NF_KEY_CYAN, + NF_KEY_RED, + NF_KEY_MAGENTA, + NF_KEY_BROWN, + NF_KEY_GREY, + NF_KEY_YELLOW, + NF_KEY_WHITE, + NF_KEY_LASTCOLOR = NF_KEY_WHITE, + NF_KEY_LASTKEYWORD_SO5 = NF_KEY_LASTCOLOR, + //! Keys from here on can't be saved in SO5 file format and MUST be + //! converted to string which means losing any information. + NF_KEY_AAA, // abbreviated day name from Japanese Xcl, same as DDD or NN English + NF_KEY_AAAA, // full day name from Japanese Xcl, same as DDDD or NNN English + NF_KEY_EC, // E non-gregorian calendar year without preceding 0 + NF_KEY_EEC, // EE non-gregorian calendar year with preceding 0 (two digit) + NF_KEY_G, // abbreviated era name, latin characters M T S or H for Gengou calendar + NF_KEY_GG, // abbreviated era name + NF_KEY_GGG, // full era name + NF_KEY_R, // acts as EE (Xcl) => GR==GEE, GGR==GGEE, GGGR==GGGEE + NF_KEY_RR, // acts as GGGEE (Xcl) + NF_KEY_THAI_T, // Thai T modifier, speciality of Thai Excel, only used with Thai locale and converted to [NatNum1] + NF_KEYWORD_ENTRIES_COUNT +}; + +typedef String NfKeywordTable [NF_KEYWORD_ENTRIES_COUNT]; + +#endif // INCLUDED_SVTOOLS_NFKEYTAB_HXX + diff --git a/svl/inc/svl/nfversi.hxx b/svl/inc/svl/nfversi.hxx new file mode 100644 index 000000000000..23375369ddb3 --- /dev/null +++ b/svl/inc/svl/nfversi.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: nfversi.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef NF_NFVERSI_HXX +#define NF_NFVERSI_HXX + +// file ID's + +#define SV_NUMBERFORMATTER_VERSION_SYSTORE 0x0004 +#define SV_NUMBERFORMATTER_VERSION_KEYWORDS 0x0005 +#define SV_NUMBERFORMATTER_VERSION_NEWSTANDARD 0x0006 +#define SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00 0x0007 +#define SV_NUMBERFORMATTER_VERSION_NF_DATE_WW 0x0008 +#define SV_NUMBERFORMATTER_VERSION_NEW_CURR 0x0009 +#define SV_NUMBERFORMATTER_VERSION_YEAR2000 0x000a +#define SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR 0x000b +#define SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS 0x000c +#define SV_NUMBERFORMATTER_VERSION_CALENDAR 0x000d +#define SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS 0x000e + +#define SV_NUMBERFORMATTER_VERSION 0x000e + +// 1 bis 18.01.96 +// 2 ab 19.01.96, TT.MM.JJJJ dazu +// 3 ab 13.02.96 (nicht emergency) #.##0,00 CCC dazu +// 4 ab 30.07.97 364i speichern, was SYSTEM wirklich war (vorhandenes +// Dummy-Feld wird benutzt, keine File-Format Aenderung) +// 5 ab 07.08.97 nicht-deutsch ist nicht immer englisch +// aeltere nicht-deutsche benutzerdefinierte Formate onLoad +// konvertieren +// 6 ab 17.10.97 neu: Keyword NNN fuer langen Wochentag ohne Separator, +// wird in aelteren Versionen nicht ausgewertet! +// Neue Standard Datumformate, DIN etc. +// 7 ab 25.05.98 StandardFormat [HH]:MM:SS,00 (NF_TIME_HH_MMSS00) fuer +// automatische Eingabe-Erkennung von 100stel Sekunden mit Stunden +// 8 ab 19.06.98 StandardFormat WW (NF_DATE_WW) fuer Kalenderwoche +// 9 ab 17.12.98 neue Waehrungsformate [$DM-xxx] +// A ab 25.01.99 Year2000 speichern/laden +// B ab 12.02.99 Year2000 ist allgemeines TwoDigitYearStart +// C ??.??.?? date/time format of system variables +// D 23.11.00 new calendar +// E 19.01.01 additional formats provided by i18n + +#endif + diff --git a/svl/inc/svl/nranges.hxx b/svl/inc/svl/nranges.hxx new file mode 100644 index 000000000000..e527a456a014 --- /dev/null +++ b/svl/inc/svl/nranges.hxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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: nranges.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifdef MACOSX +// We need an empty block in here. Otherwise, if the #ifndef _SFXNRANGES_HXX +// line is the first line, the Mac OS X version of the gcc preprocessor will +// incorrectly optimize the inclusion process and will never include this file +// a second time +#endif + +#ifndef _SFXNRANGES_HXX + +#ifndef NUMTYPE + +#define NUMTYPE USHORT +#define SfxNumRanges SfxUShortRanges +#include <svl/nranges.hxx> + +#undef NUMTYPE +#define NUMTYPE ULONG +#define SfxNumRanges SfxULongRanges +#include <svl/nranges.hxx> + +#define _SFXNRANGES_HXX + +#else +#include <tools/solar.h> + +//======================================================================== + +#define NUMTYPE_ARG int + +class SfxNumRanges +{ + NUMTYPE* _pRanges; // 0-terminated array of NUMTYPE-pairs + +public: + SfxNumRanges() : _pRanges( 0 ) {} + SfxNumRanges( const SfxNumRanges &rOrig ); + SfxNumRanges( NUMTYPE nWhich1, NUMTYPE nWhich2 ); + SfxNumRanges( NUMTYPE_ARG nWh1, NUMTYPE_ARG nWh2, NUMTYPE_ARG nNull, ... ); + SfxNumRanges( const NUMTYPE* nNumTable ); + ~SfxNumRanges() + { delete [] _pRanges; } + + BOOL operator == ( const SfxNumRanges & ) const; + BOOL operator != ( const SfxNumRanges & rRanges ) const + { return !( *this == rRanges ); } + + SfxNumRanges& operator = ( const SfxNumRanges & ); + + SfxNumRanges& operator += ( const SfxNumRanges & ); + SfxNumRanges& operator -= ( const SfxNumRanges & ); + SfxNumRanges& operator /= ( const SfxNumRanges & ); + + NUMTYPE Count() const; + BOOL IsEmpty() const + { return !_pRanges || 0 == *_pRanges; } + BOOL Contains( NUMTYPE n ) const; + BOOL Intersects( const SfxNumRanges & ) const; + + operator const NUMTYPE* () const + { return _pRanges; } +}; + +#undef NUMTYPE +#undef SfxNumRanges + +#endif + +#endif diff --git a/svl/inc/svl/ondemand.hxx b/svl/inc/svl/ondemand.hxx new file mode 100644 index 000000000000..3369f286b2cd --- /dev/null +++ b/svl/inc/svl/ondemand.hxx @@ -0,0 +1,468 @@ +/************************************************************************* + * + * 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: ondemand.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_ONDEMAND_HXX +#define INCLUDED_SVTOOLS_ONDEMAND_HXX + +#include <unotools/syslocale.hxx> +#include <i18npool/lang.h> +#include <unotools/localedatawrapper.hxx> +#include <unotools/calendarwrapper.hxx> +#include <unotools/collatorwrapper.hxx> +#include <com/sun/star/i18n/CollatorOptions.hpp> +#include <unotools/transliterationwrapper.hxx> +#include <com/sun/star/i18n/TransliterationModules.hpp> +#include <unotools/nativenumberwrapper.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +/* + On demand instanciation and initialization of several i18n wrappers, + helping the number formatter to not perform worse than it already does. + */ + +/** @short + Switch between LANGUAGE_SYSTEM and LANGUAGE_ENGLISH_US and any other + LocaleDataWrapper. + SvNumberformatter uses it upon switching locales. + + @descr + Avoids reloading and analysing of locale data again and again. + + @ATTENTION + If the default ctor is used the init() method MUST be called before + accessing any locale data. The passed parameters Locale and LanguageType + must match each other. + */ + +class OnDemandLocaleDataWrapper +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr; + SvtSysLocale aSysLocale; + LanguageType eCurrentLanguage; + LanguageType eLastAnyLanguage; + const LocaleDataWrapper* pSystem; + const LocaleDataWrapper* pEnglish; + LocaleDataWrapper* pAny; + const LocaleDataWrapper* pCurrent; + bool bInitialized; + +public: + OnDemandLocaleDataWrapper() + : eLastAnyLanguage( LANGUAGE_DONTKNOW ) + , pEnglish(0) + , pAny(0) + , bInitialized(false) + { + pCurrent = pSystem = aSysLocale.GetLocaleDataPtr(); + eCurrentLanguage = LANGUAGE_SYSTEM; + } + OnDemandLocaleDataWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale, + LanguageType eLang + ) + : pEnglish(0) + , pAny(0) + , pCurrent(0) + , bInitialized(false) + { + pSystem = aSysLocale.GetLocaleDataPtr(); + init( rxSMgr, rLocale, eLang ); + } + ~OnDemandLocaleDataWrapper() + { + delete pEnglish; + delete pAny; + } + + bool isInitialized() const { return bInitialized; } + + bool is() const { return pCurrent != NULL; } + + void init( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale, + LanguageType eLang + ) + { + xSMgr = rxSMgr; + changeLocale( rLocale, eLang ); + bInitialized = true; + } + + void changeLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang ) + { + switch ( eLang ) + { + case LANGUAGE_SYSTEM : + pCurrent = pSystem; + break; + case LANGUAGE_ENGLISH_US : + if ( !pEnglish ) + pEnglish = new LocaleDataWrapper( xSMgr, rLocale ); + pCurrent = pEnglish; + break; + default: + if ( !pAny ) + { + pAny = new LocaleDataWrapper( xSMgr, rLocale ); + eLastAnyLanguage = eLang; + } + else if ( eLastAnyLanguage != eLang ) + { + pAny->setLocale( rLocale ); + eLastAnyLanguage = eLang; + } + pCurrent = pAny; + } + eCurrentLanguage = eLang; + } + + LanguageType getCurrentLanguage() const + { return eCurrentLanguage; } + + LocaleDataWrapper* getAnyLocale() + { + if ( !pAny ) + { + pAny = new LocaleDataWrapper( xSMgr, pCurrent->getLocale() ); + eLastAnyLanguage = eCurrentLanguage; + } + else if ( pCurrent != pAny ) + { + pAny->setLocale( pCurrent->getLocale() ); + eLastAnyLanguage = eCurrentLanguage; + } + return pAny; + } + + const LocaleDataWrapper* get() const { return pCurrent; } + const LocaleDataWrapper* operator->() const { return get(); } + const LocaleDataWrapper& operator*() const { return *get(); } +}; + +/** Load a calendar only if it's needed. + SvNumberformatter uses it upon switching locales. + @ATTENTION If the default ctor is used the init() method MUST be called + before accessing the calendar. + */ +class OnDemandCalendarWrapper +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr; + ::com::sun::star::lang::Locale aLocale; + mutable CalendarWrapper* pPtr; + mutable bool bValid; + bool bInitialized; + +public: + OnDemandCalendarWrapper() + : pPtr(0) + , bValid(false) + , bInitialized(false) + {} + OnDemandCalendarWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale + ) + : bValid(false) + , bInitialized(false) + { + init( rxSMgr, rLocale ); + } + ~OnDemandCalendarWrapper() + { + delete pPtr; + } + + bool isInitialized() const { return bInitialized; } + + bool is() const { return pPtr != NULL; } + + void init( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale + ) + { + xSMgr = rxSMgr; + changeLocale( rLocale ); + if ( pPtr ) + { + delete pPtr; + pPtr = NULL; + } + bInitialized = true; + } + + void changeLocale( ::com::sun::star::lang::Locale& rLocale ) + { + bValid = false; + aLocale = rLocale; + } + + CalendarWrapper* get() const + { + if ( !bValid ) + { + if ( !pPtr ) + pPtr = new CalendarWrapper( xSMgr ); + pPtr->loadDefaultCalendar( aLocale ); + bValid = true; + } + return pPtr; + } + + CalendarWrapper* operator->() { return get(); } + CalendarWrapper& operator*() { return *get(); } +}; + +/** Load a collator only if it's needed. + SvNumberformatter uses it upon switching locales. + @ATTENTION If the default ctor is used the init() method MUST be called + before accessing the collator. + */ +class OnDemandCollatorWrapper +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr; + ::com::sun::star::lang::Locale aLocale; + mutable CollatorWrapper* pPtr; + mutable bool bValid; + bool bInitialized; + +public: + OnDemandCollatorWrapper() + : pPtr(0) + , bValid(false) + , bInitialized(false) + {} + OnDemandCollatorWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale + ) + : bValid(false) + , bInitialized(false) + { + init( rxSMgr, rLocale ); + } + ~OnDemandCollatorWrapper() + { + delete pPtr; + } + + bool isInitialized() const { return bInitialized; } + + bool is() const { return pPtr != NULL; } + + void init( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::Locale& rLocale + ) + { + xSMgr = rxSMgr; + changeLocale( rLocale ); + if ( pPtr ) + { + delete pPtr; + pPtr = NULL; + } + bInitialized = true; + } + + void changeLocale( ::com::sun::star::lang::Locale& rLocale ) + { + bValid = false; + aLocale = rLocale; + } + + const CollatorWrapper* get() const + { + if ( !bValid ) + { + if ( !pPtr ) + pPtr = new CollatorWrapper( xSMgr ); + pPtr->loadDefaultCollator( aLocale, ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE ); + bValid = true; + } + return pPtr; + } + + const CollatorWrapper* operator->() const { return get(); } + const CollatorWrapper& operator*() const { return *get(); } +}; + +/** Load a transliteration only if it's needed. + SvNumberformatter uses it upon switching locales. + @ATTENTION If the default ctor is used the init() method MUST be called + before accessing the transliteration. + */ +class OnDemandTransliterationWrapper +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr; + LanguageType eLanguage; + ::com::sun::star::i18n::TransliterationModules nType; + mutable ::utl::TransliterationWrapper* pPtr; + mutable bool bValid; + bool bInitialized; + +public: + OnDemandTransliterationWrapper() + : eLanguage( LANGUAGE_SYSTEM ) + , pPtr(0) + , bValid(false) + , bInitialized(false) + {} + OnDemandTransliterationWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + LanguageType eLang, + ::com::sun::star::i18n::TransliterationModules nTypeP + ) + : bValid(false) + , bInitialized(false) + { + init( rxSMgr, eLang, nTypeP ); + } + ~OnDemandTransliterationWrapper() + { + delete pPtr; + } + + bool isInitialized() const { return bInitialized; } + + bool is() const { return pPtr != NULL; } + + void init( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + LanguageType eLang, + ::com::sun::star::i18n::TransliterationModules nTypeP + ) + { + xSMgr = rxSMgr; + nType = nTypeP; + changeLocale( eLang ); + if ( pPtr ) + { + delete pPtr; + pPtr = NULL; + } + bInitialized = true; + } + + void changeLocale( LanguageType eLang ) + { + bValid = false; + eLanguage = eLang; + } + + const ::utl::TransliterationWrapper* get() const + { + if ( !bValid ) + { + if ( !pPtr ) + pPtr = new ::utl::TransliterationWrapper( xSMgr, nType ); + pPtr->loadModuleIfNeeded( eLanguage ); + bValid = true; + } + return pPtr; + } + + const ::utl::TransliterationWrapper* getForModule( const String& rModule, LanguageType eLang ) const + { + if ( !pPtr ) + pPtr = new ::utl::TransliterationWrapper( xSMgr, nType ); + pPtr->loadModuleByImplName( rModule, eLang ); + bValid = false; // reforce settings change in get() + return pPtr; + } + + const ::utl::TransliterationWrapper* operator->() const { return get(); } + const ::utl::TransliterationWrapper& operator*() const { return *get(); } +}; + +/** Load a native number service wrapper only if it's needed. + SvNumberformatter uses it. + + @ATTENTION + If the default ctor is used the init() method MUST be called + before accessing the native number supplier. + */ +class OnDemandNativeNumberWrapper +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr; + mutable NativeNumberWrapper* pPtr; + bool bInitialized; + +public: + OnDemandNativeNumberWrapper() + : pPtr(0) + , bInitialized(false) + {} + OnDemandNativeNumberWrapper( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr + ) + : pPtr(0) + , bInitialized(false) + { + init( rxSMgr ); + } + ~OnDemandNativeNumberWrapper() + { + delete pPtr; + } + + bool isInitialized() const { return bInitialized; } + + void init( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr + ) + { + xSMgr = rxSMgr; + if ( pPtr ) + { + delete pPtr; + pPtr = NULL; + } + bInitialized = true; + } + + bool is() const { return pPtr != NULL; } + + NativeNumberWrapper* get() const + { + if ( !pPtr ) + pPtr = new NativeNumberWrapper( xSMgr ); + return pPtr; + } + + NativeNumberWrapper* operator->() { return get(); } + NativeNumberWrapper& operator*() { return *get(); } +}; + +#endif // INCLUDED_SVTOOLS_ONDEMAND_HXX + diff --git a/svl/inc/svl/ownlist.hxx b/svl/inc/svl/ownlist.hxx new file mode 100644 index 000000000000..21e9ffa74210 --- /dev/null +++ b/svl/inc/svl/ownlist.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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: ownlist.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _OWNLIST_HXX +#define _OWNLIST_HXX + +#include "svl/svldllapi.h" +#include <tools/stream.hxx> +#include <tools/ownlist.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +namespace com { namespace sun { namespace star { + namespace beans { + struct PropertyValue; + } +}}} + +//========================================================================= +class SvCommand +/* [Beschreibung] + + Enth"alt einen String, welcher das Kommando angibt und eine weiteren + String, der das Argument des Kommandos bildet. W"urde solch ein + Kommando "uber die Kommandozeile angegeben werden, s"ahe es wie folgt + aus: Kommando = Argument. +*/ +{ + String aCommand; + String aArgument; +public: + SvCommand() {} + SvCommand( const String & rCommand, const String & rArg ) + { + aCommand = rCommand; + aArgument = rArg; + } + const String & GetCommand() const { return aCommand; } + const String & GetArgument() const { return aArgument; } + + friend SvStream& operator >> ( SvStream& rStm, SvCommand & rThis ) + { + rStm.ReadByteString( rThis.aCommand, gsl_getSystemTextEncoding() ); + rStm.ReadByteString( rThis.aArgument, gsl_getSystemTextEncoding() ); + return rStm; + } + friend SvStream& operator << ( SvStream& rStm, const SvCommand & rThis ) + { + rStm.WriteByteString( rThis.aCommand, gsl_getSystemTextEncoding() ); + rStm.WriteByteString( rThis.aArgument, gsl_getSystemTextEncoding() ); + return rStm; + } +}; + +//========================================================================= +class SVL_DLLPUBLIC SvCommandList +/* [Beschreibung] + + Die Liste enth"alt Objekte vom Typ SvCommand. Wird ein Objekt + eingef"ugt, dann wird es kopiert und das neue Objekt wird + in die Liste gestellt. +*/ +{ + PRV_SV_DECL_OWNER_LIST(SvCommandList,SvCommand); + SvCommand & Append( const String & rCommand, const String & rArg ); + BOOL AppendCommands( const String & rCmd, USHORT * pEaten ); + String GetCommands() const; + + BOOL FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& ); + void FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& ); + + SVL_DLLPUBLIC friend SvStream& operator >> ( SvStream& rStm, SvCommandList & ); + SVL_DLLPUBLIC friend SvStream& operator << ( SvStream&, const SvCommandList & ); +}; + +#endif // _OWNLIST_HXX diff --git a/svl/inc/svl/poolitem.hxx b/svl/inc/svl/poolitem.hxx new file mode 100644 index 000000000000..1d0a2e982fae --- /dev/null +++ b/svl/inc/svl/poolitem.hxx @@ -0,0 +1,491 @@ +/************************************************************************* + * + * 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: poolitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXPOOLITEM_HXX +#define _SFXPOOLITEM_HXX + +#include "svl/svldllapi.h" +#include <com/sun/star/uno/Any.hxx> + +#define TF_POOLABLE +#include <sal/config.h> +#include <tools/rtti.hxx> +#include <limits.h> +#include <tools/solar.h> +#include <tools/debug.hxx> +#include <tools/string.hxx> +#include <svl/svarray.hxx> +#include <svl/hint.hxx> + +typedef long SfxArgumentError; + +class SbxVariable; +class SbxObject; +class SvStream; +class Color; +class IntlWrapper; + +namespace com { namespace sun { namespace star { namespace uno { class Any; } } } } + +#define SFX_ITEMS_DIRECT 0xffff +#define SFX_ITEMS_NULL 0xfff0 // anstelle StoreSurrogate + +#define SFX_ITEMS_POOLDEFAULT 0xffff +#define SFX_ITEMS_STATICDEFAULT 0xfffe +#define SFX_ITEMS_DELETEONIDLE 0xfffd + +#define SFX_ITEMS_OLD_MAXREF 0xffef +#define SFX_ITEMS_MAXREF 0xfffffffe +#define SFX_ITEMS_SPECIAL 0xffffffff + +#define CONVERT_TWIPS 0x80 //Uno-Konvertierung fuer Massangaben (fuer MemberId) + +// ----------------------------------------------------------------------- + +// UNO3 shortcuts + +// warning, if there is no boolean inside the any this will always return the value false +inline sal_Bool Any2Bool( const ::com::sun::star::uno::Any&rValue ) +{ + sal_Bool nValue = sal_False; + if( rValue.hasValue() ) + { + if( rValue.getValueType() == ::getCppuBooleanType() ) + { + nValue = *(sal_Bool*)rValue.getValue(); + } + else + { + sal_Int32 nNum = 0; + if( rValue >>= nNum ) + nValue = nNum != 0; + } + } + + return nValue; +} + +inline ::com::sun::star::uno::Any Bool2Any( sal_Bool bValue ) +{ + return ::com::sun::star::uno::Any( &bValue, ::getCppuBooleanType() ); +} + +// ----------------------------------------------------------------------- + +//! Notloesung!!! +enum SfxFieldUnit +{ + SFX_FUNIT_NONE, SFX_FUNIT_MM, SFX_FUNIT_CM, SFX_FUNIT_M, SFX_FUNIT_KM, + SFX_FUNIT_TWIP, SFX_FUNIT_POINT, SFX_FUNIT_PICA, + SFX_FUNIT_INCH, SFX_FUNIT_FOOT, SFX_FUNIT_MILE, SFX_FUNIT_CUSTOM +}; + +enum SfxMapUnit +{ + SFX_MAPUNIT_100TH_MM, + SFX_MAPUNIT_10TH_MM, + SFX_MAPUNIT_MM, + SFX_MAPUNIT_CM, + SFX_MAPUNIT_1000TH_INCH, + SFX_MAPUNIT_100TH_INCH, + SFX_MAPUNIT_10TH_INCH, + SFX_MAPUNIT_INCH, + SFX_MAPUNIT_POINT, + SFX_MAPUNIT_TWIP, + SFX_MAPUNIT_PIXEL, + SFX_MAPUNIT_SYSFONT, + SFX_MAPUNIT_APPFONT, + SFX_MAPUNIT_RELATIVE, + SFX_MAPUNIT_ABSOLUTE +}; + +// ----------------------------------------------------------------------- + +enum SfxItemPresentation + +/* [Beschreibung] + + Die Werte dieses Enums bezeichnen den Grad der textuellen + Presentation eines Items nach Aufruf der virtuellen Methode + <SfxPoolItem::GetPresentation()const>. +*/ + +{ + SFX_ITEM_PRESENTATION_NONE, + SFX_ITEM_PRESENTATION_NAMEONLY, + SFX_ITEM_PRESENTATION_NAMELESS, + SFX_ITEM_PRESENTATION_COMPLETE +}; + +// ----------------------------------------------------------------------- + +typedef USHORT SfxItemState; + +#define SFX_ITEM_UNKNOWN 0x0000 + +#define SFX_ITEM_DISABLED 0x0001 +#define SFX_ITEM_READONLY 0x0002 + +#define SFX_ITEM_DONTCARE 0x0010 +#define SFX_ITEM_DEFAULT 0x0020 +#define SFX_ITEM_SET 0x0030 + +// old stuff - dont use!!! +#define SFX_ITEM_AVAILABLE SFX_ITEM_DEFAULT +#define SFX_ITEM_OFF SFX_ITEM_DEFAULT +#define SFX_ITEM_ON SFX_ITEM_SET + +DBG_NAMEEX_VISIBILITY(SfxPoolItem, SVL_DLLPUBLIC) +DBG_NAMEEX(SfxVoidItem) +DBG_NAMEEX(SfxItemHandle) + +class SvXMLUnitConverter; +class SfxItemPool; +class SfxItemSet; + +class String; +namespace rtl +{ + class OUString; +} + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxPoolItem +{ +friend class SfxItemPool; +friend class SfxItemDesruptor_Impl; +friend class SfxItemPoolCache; +friend class SfxItemSet; +friend class SfxVoidItem; + + ULONG nRefCount; // Referenzzaehler + USHORT nWhich; + USHORT nKind; + +private: + inline void SetRefCount( ULONG n ); + inline void SetKind( USHORT n ); +public: + inline ULONG AddRef( ULONG n = 1 ) const; +private: + inline ULONG ReleaseRef( ULONG n = 1 ) const; + SVL_DLLPRIVATE long Delete_Impl(void*); + +#if 0 + // @@@ virtual, but private, and dummy impl. @@@ + virtual void Store( SvStream & ) const; + virtual void GetVersion() const; +#endif + +protected: + SfxPoolItem( USHORT nWhich = 0 ); + SfxPoolItem( const SfxPoolItem& ); + +public: + TYPEINFO(); + virtual ~SfxPoolItem(); + + void SetWhich( USHORT nId ) { + DBG_CHKTHIS(SfxPoolItem, 0); + nWhich = nId; } + USHORT Which() const { + DBG_CHKTHIS(SfxPoolItem, 0); + return nWhich; } + virtual int operator==( const SfxPoolItem& ) const = 0; + int operator!=( const SfxPoolItem& rItem ) const + { return !(*this == rItem); } + virtual int Compare( const SfxPoolItem &rWith ) const; + virtual int Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresentationMetric, + XubString &rText, + const IntlWrapper * pIntlWrapper = 0 ) const; + + virtual USHORT GetVersion( USHORT nFileFormatVersion ) const; + virtual int ScaleMetrics( long lMult, long lDiv ); + virtual int HasMetrics() const; + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ) const; + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, BYTE nMemberId = 0 ); + + virtual SfxPoolItem* Create( SvStream &, USHORT nItemVersion ) const; + virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const = 0; + + ULONG GetRefCount() const { return nRefCount; } + inline USHORT GetKind() const { return nKind; } + + /** Read in a Unicode string from a streamed byte string representation. + + @param rStream Some (input) stream. Its Stream/TargetCharSets must + be set to correct values! + + @param rString On success, returns the reconstructed Unicode string. + + @return True if the string was successfuly read and reconstructed. + */ + static bool readByteString(SvStream & rStream, UniString & rString); + + /** Write a byte string representation of a Unicode string into a stream. + + @param rStream Some (output) stream. Its Stream/TargetCharSets must + be set to correct values! + + @param rString Some Unicode string. + */ + static void writeByteString(SvStream & rStream, + UniString const & rString); + + /** Read in a Unicode string from either a streamed Unicode or byte string + representation. + + @param rStream Some (input) stream. If bUnicode is false, its + Stream/TargetCharSets must be set to correct values! + + @param rString On success, returns the reconstructed Unicode string. + + @param bUnicode Whether to read in a stream Unicode (true) or byte + string (false) representation. + + @return True if the string was successfuly read and reconstructed. + */ + static bool readUnicodeString(SvStream & rStream, UniString & rString, + bool bUnicode); + + /** Write a Unicode string representation of a Unicode string into a + stream. + + @param rStream Some (output) stream. + + @param rString Some Unicode string. + */ + static void writeUnicodeString(SvStream & rStream, + UniString const & rString); + +private: + SfxPoolItem& operator=( const SfxPoolItem& ); // n.i.!! +}; + +// ----------------------------------------------------------------------- + +inline void SfxPoolItem::SetRefCount( ULONG n ) +{ + DBG_CHKTHIS( SfxPoolItem, 0 ); + nRefCount = n; + nKind = 0; +} + +inline void SfxPoolItem::SetKind( USHORT n ) +{ + DBG_CHKTHIS( SfxPoolItem, 0 ); + nRefCount = SFX_ITEMS_SPECIAL; + nKind = n; +} + +inline ULONG SfxPoolItem::AddRef( ULONG n ) const +{ + DBG_CHKTHIS( SfxPoolItem, 0 ); + DBG_ASSERT( nRefCount <= SFX_ITEMS_MAXREF, "AddRef mit nicht-Pool-Item" ); + DBG_ASSERT( ULONG_MAX - nRefCount > n, "AddRef: Referenzzaehler ueberschlaegt sich" ); + return ( ((SfxPoolItem *)this)->nRefCount += n ); +} + +inline ULONG SfxPoolItem::ReleaseRef( ULONG n ) const +{ + DBG_CHKTHIS( SfxPoolItem, 0 ); + DBG_ASSERT( nRefCount <= SFX_ITEMS_MAXREF, "AddRef mit nicht-Pool-Item" ); + DBG_ASSERT( nRefCount >= n, "ReleaseRef: Referenzzaehler ueberschlaegt sich" ); + ((SfxPoolItem *)this)->nRefCount -= n; + return nRefCount; +} + +// ----------------------------------------------------------------------- + +inline int IsPoolDefaultItem(const SfxPoolItem *pItem ) +{ + return pItem && pItem->GetKind() == SFX_ITEMS_POOLDEFAULT; +} + +inline int IsStaticDefaultItem(const SfxPoolItem *pItem ) +{ + return pItem && pItem->GetKind() == SFX_ITEMS_STATICDEFAULT; +} + +inline int IsDefaultItem( const SfxPoolItem *pItem ) +{ + return pItem && pItem->GetKind() >= SFX_ITEMS_STATICDEFAULT; +} + +inline int IsPooledItem( const SfxPoolItem *pItem ) +{ + return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= SFX_ITEMS_MAXREF; +} + +inline int IsInvalidItem(const SfxPoolItem *pItem) +{ + return pItem == (SfxPoolItem *)-1; +} + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxVoidItem: public SfxPoolItem +{ + SfxVoidItem & operator=( const SfxVoidItem& ); // not implemented. +public: + TYPEINFO(); + SfxVoidItem( USHORT nWhich ); + SfxVoidItem( USHORT nWhich, SvStream & ); + SfxVoidItem( const SfxVoidItem& ); + ~SfxVoidItem(); + + virtual int operator==( const SfxPoolItem& ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + + // von sich selbst eine Kopie erzeugen + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + void SetWhich(USHORT nWh) { nWhich = nWh; } +}; + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxSetItem: public SfxPoolItem +{ + SfxItemSet *pSet; + + SfxSetItem & operator=( const SfxSetItem& ); // not implemented. + +public: + TYPEINFO(); + SfxSetItem( USHORT nWhich, SfxItemSet *pSet ); + SfxSetItem( USHORT nWhich, const SfxItemSet &rSet ); + SfxSetItem( const SfxSetItem&, SfxItemPool *pPool = 0 ); + ~SfxSetItem(); + + virtual int operator==( const SfxPoolItem& ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + + // von sich selbst eine Kopie erzeugen + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const = 0; + virtual SfxPoolItem* Create(SvStream &, USHORT nVersion) const = 0; + virtual SvStream& Store(SvStream &, USHORT nVer) const; + + const SfxItemSet& GetItemSet() const + { return *pSet; } + SfxItemSet& GetItemSet() + { return *pSet; } +}; + +// ----------------------------------------------------------------------- + +#if 0 /* @@@ NOT USED @@@ */ +class SfxInvalidItem: public SfxPoolItem +{ +friend class SfxItemSet; + + const SfxPoolItem* pDefaultItem; + +private: + TYPEINFO(); + SfxInvalidItem( USHORT nWhich, const SfxPoolItem &rDefault ); + SfxInvalidItem( const SfxInvalidItem& ); + virtual ~SfxInvalidItem(); + +public: + virtual int operator==( const SfxPoolItem& ) const; + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + const SfxPoolItem* GetDefaultItem() const { return pDefaultItem; } + + // von sich selbst eine Kopie erzeugen + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nVersion) const; + virtual SvStream& Store(SvStream &, USHORT nVer ) const; +}; +#endif /* @@@ NOT USED @@@ */ + +// ----------------------------------------------------------------------- +// Handle Klasse fuer PoolItems + +class SVL_DLLPUBLIC SfxItemHandle +{ + USHORT *pRef; + SfxPoolItem *pItem; +public: + SfxItemHandle( SfxPoolItem& ); + SfxItemHandle( const SfxItemHandle& ); + ~SfxItemHandle(); + + const SfxItemHandle &operator=(const SfxItemHandle &); + const SfxPoolItem &GetItem() const { return *pItem; } +}; + +// ----------------------------------------------------------------------- + +DECL_PTRHINT(SVL_DLLPUBLIC, SfxPoolItemHint, SfxPoolItem); + +// ----------------------------------------------------------------------- + +#if 0 /* @@@ NOT USED @@@ */ +class SfxItemChangedHint: public SfxHint +{ + const SfxPoolItem& _rOld; + const SfxPoolItem& _rNew; + +public: + TYPEINFO(); \ + SfxItemChangedHint( const SfxPoolItem &rOld, + const SfxPoolItem &rNew ) + : _rOld( rOld ), + _rNew( rNew ) + {} + + const SfxPoolItem& GetOldItem() const { return _rOld; } + const SfxPoolItem& GetNewItem() const { return _rNew; } +}; + +#endif /* @@@ NOT USED @@@ */ + +#endif // #ifndef _SFXPOOLITEM_HXX diff --git a/svl/inc/svl/ptitem.hxx b/svl/inc/svl/ptitem.hxx new file mode 100644 index 000000000000..b0deff81e884 --- /dev/null +++ b/svl/inc/svl/ptitem.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * 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: ptitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXPTITEM_HXX +#define _SFXPTITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/poolitem.hxx> +#include <tools/gen.hxx> + +class SvStream; + +DBG_NAMEEX_VISIBILITY(SfxPointItem, SVL_DLLPUBLIC) + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxPointItem: public SfxPoolItem +{ + Point aVal; + +public: + TYPEINFO(); + SfxPointItem(); + SfxPointItem( USHORT nWhich, const Point& rVal ); + SfxPointItem( USHORT nWhich, SvStream & ); + SfxPointItem( const SfxPointItem& ); + ~SfxPointItem() { + DBG_DTOR(SfxPointItem, 0); } + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + + virtual int operator==( const SfxPoolItem& ) const; + + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nItemVersion) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion) const; + + const Point& GetValue() const { return aVal; } + void SetValue( const Point& rNewVal ) { + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + aVal = rNewVal; + } + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); +}; + +#endif diff --git a/svl/inc/svl/rectitem.hxx b/svl/inc/svl/rectitem.hxx new file mode 100644 index 000000000000..1f944bab4102 --- /dev/null +++ b/svl/inc/svl/rectitem.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * 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: rectitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXRECTITEM_HXX +#define _SFXRECTITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <tools/gen.hxx> +#include <svl/poolitem.hxx> + +class SvStream; + +DBG_NAMEEX_VISIBILITY(SfxRectangleItem, SVL_DLLPUBLIC) + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxRectangleItem: public SfxPoolItem +{ + Rectangle aVal; + +public: + TYPEINFO(); + SfxRectangleItem(); + SfxRectangleItem( USHORT nWhich, const Rectangle& rVal ); + SfxRectangleItem( USHORT nWhich, SvStream & ); + SfxRectangleItem( const SfxRectangleItem& ); + ~SfxRectangleItem() { + DBG_DTOR(SfxRectangleItem, 0); } + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nItemVersion) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion) const; + + const Rectangle& GetValue() const { return aVal; } + void SetValue( const Rectangle& rNewVal ) { + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + aVal = rNewVal; + } + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); +}; + +#endif + diff --git a/svl/inc/svl/restrictedpaths.hxx b/svl/inc/svl/restrictedpaths.hxx new file mode 100644 index 000000000000..a3ced1b93019 --- /dev/null +++ b/svl/inc/svl/restrictedpaths.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * 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: restrictedpaths.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_RESTRICTEDPATHS_HXX +#define SVTOOLS_RESTRICTEDPATHS_HXX + +#include <svl/urlfilter.hxx> +#include <svl/svldllapi.h> +#include <tools/string.hxx> + +#include <vector> + +namespace svt +{ + class SVL_DLLPUBLIC RestrictedPaths : public IUrlFilter + { + private: + ::std::vector< String > m_aUnrestrictedURLs; + bool m_bFilterIsEnabled; + + public: + RestrictedPaths(); + virtual ~RestrictedPaths(); + + inline bool hasFilter() const { return !m_aUnrestrictedURLs.empty(); } + inline const ::std::vector< String >& getFilter() const { return m_aUnrestrictedURLs; } + + inline void enableFilter( bool _bEnable ) { m_bFilterIsEnabled = _bEnable; } + inline bool isFilterEnabled() const { return m_bFilterIsEnabled; } + + public: + /** checks URL access permissions + + <p>with the "restriction" feature we have in the file dialog, it's possible that + only certain URLs can be browsed. This method checks whether a given URL belongs + to this set of permitted URLs.</p> + + <p>If no "access restriction" is effective, this method always returns <TRUE/>.</p> + */ + virtual bool isUrlAllowed( const String& _rURL ) const; + + /** checks URL access permissions + + <p>with the "restriction" feature we have in the file dialog, it's possible that + only certain URLs can be browsed. This method checks whether a given URL belongs + to this set of permitted URLs.</p> + + <p>Default behavior allows access to parent folder of a restricted folder (but not to its siblings). + If allowParents is set to <FALSE/> parent folders will be treated as forbidden. + + <p>If no "access restriction" is effective, this method always returns <TRUE/>.</p> + */ + bool isUrlAllowed( const String& _rURL, bool allowParents ) const; + }; + +} // namespace svt + +#endif // SVTOOLS_RESTRICTEDPATHS_HXX diff --git a/svl/inc/svl/rngitem.hxx b/svl/inc/svl/rngitem.hxx new file mode 100644 index 000000000000..d55ba25a06c2 --- /dev/null +++ b/svl/inc/svl/rngitem.hxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * 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: rngitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXRNGITEM_HXX + +#ifndef NUMTYPE + +#define NUMTYPE USHORT +#define SfxXRangeItem SfxRangeItem +#define SfxXRangesItem SfxUShortRangesItem +#include <svl/rngitem.hxx> +#undef NUMTYPE +#undef SfxXRangeItem +#undef SfxXRangesItem + +#ifndef _SFXITEMS_HXX +#define NUMTYPE ULONG +#define SfxXRangeItem SfxULongRangeItem +#define SfxXRangesItem SfxULongRangesItem +#include <svl/rngitem.hxx> +#undef NUMTYPE +#undef SfxXRangeItem +#undef SfxXRangesItem +#endif + +#define _SFXRNGITEM_HXX + +#else +#include "svl/svldllapi.h" +#include <svl/poolitem.hxx> + +class SvStream; + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxXRangeItem : public SfxPoolItem +{ +private: + NUMTYPE nFrom; + NUMTYPE nTo; +public: + TYPEINFO(); + SfxXRangeItem(); + SfxXRangeItem( USHORT nWID, NUMTYPE nFrom, NUMTYPE nTo ); + SfxXRangeItem( USHORT nWID, SvStream &rStream ); + SfxXRangeItem( const SfxXRangeItem& rItem ); + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + inline NUMTYPE& From() { return nFrom; } + inline NUMTYPE From() const { return nFrom; } + inline NUMTYPE& To() { return nTo; } + inline NUMTYPE To() const { return nTo; } + inline BOOL HasRange() const { return nTo>nFrom; } + virtual SfxPoolItem* Create( SvStream &, USHORT nVersion ) const; + virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const; +}; + +// ----------------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxXRangesItem : public SfxPoolItem +{ +private: + NUMTYPE* _pRanges; + +public: + TYPEINFO(); + SfxXRangesItem(); + SfxXRangesItem( USHORT nWID, const NUMTYPE *pRanges ); + SfxXRangesItem( USHORT nWID, SvStream &rStream ); + SfxXRangesItem( const SfxXRangesItem& rItem ); + virtual ~SfxXRangesItem(); + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + inline const NUMTYPE* GetRanges() const { return _pRanges; } + virtual SfxPoolItem* Create( SvStream &, USHORT nVersion ) const; + virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const; +}; + +#endif +#endif diff --git a/svl/inc/svl/sfontitm.hxx b/svl/inc/svl/sfontitm.hxx new file mode 100644 index 000000000000..a12466519d1b --- /dev/null +++ b/svl/inc/svl/sfontitm.hxx @@ -0,0 +1,244 @@ +/************************************************************************* + * + * 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: sfontitm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFONTITM_HXX +#define _SFONTITM_HXX + +#include <tools/color.hxx> +#include <tools/gen.hxx> +#include <i18npool/lang.h> +#include <svl/poolitem.hxx> + +//============================================================================ +class SfxFontItem: public SfxPoolItem +{ + XubString m_aName; + XubString m_aStyleName; + Size m_aSize; + Color m_aColor; + Color m_aFillColor; + rtl_TextEncoding m_nCharSet; + LanguageType m_nLanguage; + sal_Int16 m_nFamily; + sal_Int16 m_nPitch; + sal_Int16 m_nWeight; + sal_Int16 m_nWidthType; + sal_Int16 m_nItalic; + sal_Int16 m_nUnderline; + sal_Int16 m_nStrikeout; + sal_Int16 m_nOrientation; + unsigned m_bWordLine: 1; + unsigned m_bOutline: 1; + unsigned m_bShadow: 1; + unsigned m_bKerning: 1; + unsigned m_bHasFont: 1; + unsigned m_bHasColor: 1; + unsigned m_bHasFillColor: 1; + +public: + TYPEINFO(); + + inline SfxFontItem(USHORT nWhich); + + virtual int operator ==(const SfxPoolItem & rItem) const; + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const + { return new SfxFontItem(*this); } + + sal_Bool hasFont() const { return m_bHasFont; } + + sal_Bool hasColor() const { return m_bHasColor; } + + sal_Bool hasFillColor() const { return m_bHasFillColor; } + + const XubString & getName() const { return m_aName; } + + const XubString & getStyleName() const { return m_aStyleName; } + + const Size & getSize() const { return m_aSize; } + + const Color & getColor() const { return m_aColor; } + + const Color & getFillColor() const { return m_aFillColor; } + + rtl_TextEncoding getCharSet() const { return m_nCharSet; } + + LanguageType getLanguage() const { return m_nLanguage; } + + sal_Int16 getFamily() const { return m_nFamily; } + + sal_Int16 getPitch() const { return m_nPitch; } + + sal_Int16 getWeight() const { return m_nWeight; } + + sal_Int16 getWidthType() const { return m_nWidthType; } + + sal_Int16 getItalic() const { return m_nItalic; } + + sal_Int16 getUnderline() const { return m_nUnderline; } + + sal_Int16 getStrikeout() const { return m_nStrikeout; } + + sal_Int16 getOrientation() const { return m_nOrientation; } + + sal_Bool getWordLine() const { return m_bWordLine; } + + sal_Bool getOutline() const { return m_bOutline; } + + sal_Bool getShadow() const { return m_bShadow; } + + sal_Bool getKerning() const { return m_bKerning; } + + inline void setFont(sal_Int16 nTheFamily, const XubString & rTheName, + const XubString & rTheStyleName, sal_Int16 nThePitch, + rtl_TextEncoding nTheCharSet); + + inline void setWeight(sal_Int16 nTheWeight); + + inline void setItalic(sal_Int16 nTheItalic); + + inline void setHeight(sal_Int32 nHeight); + + inline void setColor(const Color & rTheColor); + + inline void setFillColor(const Color & rTheFillColor); + + inline void setUnderline(sal_Int16 nTheUnderline); + + inline void setStrikeout(sal_Int16 nTheStrikeout); + + inline void setOutline(sal_Bool bTheOutline); + + inline void setShadow(sal_Bool bTheShadow); + + inline void setLanguage(LanguageType nTheLanguage); +}; + +inline SfxFontItem::SfxFontItem(USHORT which): + SfxPoolItem(which), + m_nCharSet(RTL_TEXTENCODING_DONTKNOW), + m_nLanguage(LANGUAGE_DONTKNOW), + m_nFamily(0), // FAMILY_DONTKNOW + m_nPitch(0), // PITCH_DONTKNOW + m_nWeight(0), // WEIGHT_DONTKNOW + m_nWidthType(0), // WIDTH_DONTKNOW + m_nItalic(3), // ITALIC_DONTKNOW + m_nUnderline(4), // UNDERLINE_DONTKNOW + m_nStrikeout(3), // STRIKEOUT_DONTKNOW + m_nOrientation(0), + m_bWordLine(sal_False), + m_bOutline(sal_False), + m_bShadow(sal_False), + m_bKerning(sal_False), + m_bHasFont(sal_False), + m_bHasColor(sal_False), + m_bHasFillColor(sal_False) +{} + +inline void SfxFontItem::setFont(sal_Int16 nTheFamily, + const XubString & rTheName, + const XubString & rTheStyleName, + sal_Int16 nThePitch, + rtl_TextEncoding nTheCharSet) +{ + m_nFamily = nTheFamily; + m_aName = rTheName; + m_aStyleName = rTheStyleName; + m_nPitch = nThePitch; + m_nCharSet = nTheCharSet; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setWeight(sal_Int16 nTheWeight) +{ + m_nWeight = nTheWeight; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setItalic(sal_Int16 nTheItalic) +{ + m_nItalic = nTheItalic; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setHeight(sal_Int32 nHeight) +{ + m_aSize.setHeight(nHeight); + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setColor(const Color & rTheColor) +{ + m_aColor = rTheColor; + m_bHasColor = sal_True; +} + +inline void SfxFontItem::setFillColor(const Color & rTheFillColor) +{ + m_aFillColor = rTheFillColor; + m_bHasFillColor = sal_True; +} + +inline void SfxFontItem::setUnderline(sal_Int16 nTheUnderline) +{ + m_nUnderline = nTheUnderline; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setStrikeout(sal_Int16 nTheStrikeout) +{ + m_nStrikeout = nTheStrikeout; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setOutline(sal_Bool bTheOutline) +{ + m_bOutline = bTheOutline; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setShadow(sal_Bool bTheShadow) +{ + m_bShadow = bTheShadow; + m_bHasFont = sal_True; +} + +inline void SfxFontItem::setLanguage(LanguageType nTheLanguage) +{ + m_nLanguage = nTheLanguage; + m_bHasFont = sal_True; +} + +#endif // _SFONTITM_HXX + diff --git a/svl/inc/svl/sharecontrolfile.hxx b/svl/inc/svl/sharecontrolfile.hxx new file mode 100644 index 000000000000..1febb4e77583 --- /dev/null +++ b/svl/inc/svl/sharecontrolfile.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * 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: sharecontrolfile.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVT_SHARECONTROLFILE_HXX +#define _SVT_SHARECONTROLFILE_HXX + +#include <svl/svldllapi.h> + +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <svl/lockfilecommon.hxx> + +#define SHARED_OOOUSERNAME_ID LOCKFILE_OOOUSERNAME_ID +#define SHARED_SYSUSERNAME_ID LOCKFILE_SYSUSERNAME_ID +#define SHARED_LOCALHOST_ID LOCKFILE_LOCALHOST_ID +#define SHARED_EDITTIME_ID LOCKFILE_EDITTIME_ID +#define SHARED_USERURL_ID LOCKFILE_USERURL_ID +#define SHARED_ENTRYSIZE LOCKFILE_ENTRYSIZE + +namespace svt { + +class SVL_DLLPUBLIC ShareControlFile : public LockFileCommon +{ + ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xInputStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > m_xOutputStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xSeekable; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XTruncate > m_xTruncate; + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > m_aUsersData; + + void OpenStream(); + void Close(); + sal_Bool IsValid() + { + return ( m_xFactory.is() && m_xStream.is() && m_xInputStream.is() && m_xOutputStream.is() && m_xSeekable.is() && m_xTruncate.is() ); + } + +public: + + // The constructor will throw exception in case the stream can not be opened + ShareControlFile( const ::rtl::OUString& aOrigURL, const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory = ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >() ); + ~ShareControlFile(); + + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > > GetUsersData(); + void SetUsersDataAndStore( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::rtl::OUString > >& aUserNames ); + ::com::sun::star::uno::Sequence< ::rtl::OUString > InsertOwnEntry(); + bool HasOwnEntry(); + void RemoveEntry( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aOptionalSpecification = ::com::sun::star::uno::Sequence< ::rtl::OUString >() ); + void RemoveFile(); +}; + +} + +#endif + diff --git a/svl/inc/svl/slstitm.hxx b/svl/inc/svl/slstitm.hxx new file mode 100644 index 000000000000..9b1c0050cf6b --- /dev/null +++ b/svl/inc/svl/slstitm.hxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * 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: slstitm.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXSLSTITM_HXX +#define _SFXSLSTITM_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> +#include <tools/list.hxx> +#include <svl/poolitem.hxx> +#include <com/sun/star/uno/Sequence.h> + +class SfxImpStringList; + +class SVL_DLLPUBLIC SfxStringListItem : public SfxPoolItem +{ +protected: + SfxImpStringList* pImp; + +public: + TYPEINFO(); + + SfxStringListItem(); + SfxStringListItem( USHORT nWhich, const List* pList=NULL ); + SfxStringListItem( USHORT nWhich, SvStream& rStream ); + SfxStringListItem( const SfxStringListItem& rItem ); + ~SfxStringListItem(); + + List * GetList(); + + const List * GetList() const + { return SAL_CONST_CAST(SfxStringListItem *, this)->GetList(); } + +#ifndef TF_POOLABLE + virtual int IsPoolable() const; +#endif + + // String-Separator: \n + virtual void SetString( const XubString& ); + virtual XubString GetString(); + + void SetStringList( const com::sun::star::uno::Sequence< rtl::OUString >& rList ); + void GetStringList( com::sun::star::uno::Sequence< rtl::OUString >& rList ) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create( SvStream &, USHORT nVersion ) const; + virtual SvStream& Store( SvStream &, USHORT nItemVersion ) const; + void Sort( BOOL bAscending = TRUE, List* pParallelList = 0 ); + + virtual BOOL PutValue ( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; +}; +#endif diff --git a/svl/inc/svl/smplhint.hxx b/svl/inc/svl/smplhint.hxx new file mode 100644 index 000000000000..089a86dae3f2 --- /dev/null +++ b/svl/inc/svl/smplhint.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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: smplhint.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXSMPLHINT_HXX +#define _SFXSMPLHINT_HXX + +#include "svl/svldllapi.h" +#include <svl/hint.hxx> +#include <tools/rtti.hxx> + +#define SFX_HINT_DYING 0x00000001 +#define SFX_HINT_NAMECHANGED 0x00000002 +#define SFX_HINT_TITLECHANGED 0x00000004 +#define SFX_HINT_DATACHANGED 0x00000008 +#define SFX_HINT_DOCCHANGED 0x00000010 +#define SFX_HINT_UPDATEDONE 0x00000020 +#define SFX_HINT_DEINITIALIZING 0x00000040 +#define SFX_HINT_MODECHANGED 0x00000080 +#define SFX_HINT_CANCELLABLE 0x00000100 +#define SFX_HINT_DATAAVAILABLE 0x00000200 +#define SFX_HINT_SAVECOMPLETED 0x00000400 +#define SFX_HINT_RELEASEREF 0x00000800 +#define SFX_HINT_COLORS_CHANGED 0x00001000 +#define SFX_HINT_CTL_SETTINGS_CHANGED 0x00002000 +#define SFX_HINT_ACCESSIBILITY_CHANGED 0x00004000 +#define SFX_HINT_VIEWCREATED 0x00008000 +#define SFX_HINT_USER00 0x00010000 +#define SFX_HINT_USER01 0x00020000 +#define SFX_HINT_USER02 0x00040000 +#define SFX_HINT_USER03 0x00080000 +#define SFX_HINT_USER04 0x00100000 +#define SFX_HINT_USER05 0x00200000 +#define SFX_HINT_USER06 0x00400000 +#define SFX_HINT_USER07 0x00800000 +#define SFX_HINT_USER08 0x01000000 +#define SFX_HINT_USER09 0x02000000 +#define SFX_HINT_USER10 0x04000000 +#define SFX_HINT_USER11 0x08000000 +#define SFX_HINT_USER12 0x10000000 +#define SFX_HINT_USER13 0x20000000 +#define SFX_HINT_UNDO_OPTIONS_CHANGED 0x40000000 +#define SFX_HINT_USER_OPTIONS_CHANGED 0x80000000 +#define SFX_HINT_ALL 0xFFFFFFFF + +class SVL_DLLPUBLIC SfxSimpleHint: public SfxHint +{ +private: + ULONG nId; +public: + TYPEINFO(); + SfxSimpleHint( ULONG nId ); + ULONG GetId() const { return nId; } +}; + +//-------------------------------------------------------------------- + +#define DECL_OBJHINT(Name, Type) \ + class Name: public SfxSimpleHint \ + { \ + Type aObj; \ + \ + public: \ + TYPEINFO(); \ + Name( USHORT nId, const Type& rObject ); \ + ~Name(); \ + const Type& GetObject() const { return aObj; } \ + } + +#define IMPL_OBJHINT(Name, Type) \ + TYPEINIT1(Name, SfxSimpleHint); \ + Name::Name( USHORT nID, const Type& rObject ): \ + SfxSimpleHint( nID ), aObj(rObject) \ + { } \ + Name::~Name() {} + +#endif diff --git a/svl/inc/svl/solar.hrc b/svl/inc/svl/solar.hrc new file mode 100644 index 000000000000..96149b89131c --- /dev/null +++ b/svl/inc/svl/solar.hrc @@ -0,0 +1,305 @@ +/************************************************************************* + * + * 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: solar.hrc,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SOLAR_HRC +#define _SOLAR_HRC + +// defines ------------------------------------------------------------------ + +#define CREATERESMGR_NAME( Name ) #Name +#define CREATERESMGR( Name ) ResMgr::CreateResMgr( CREATERESMGR_NAME( Name ) ) + +#define RID_SFX_START 260 +#define RID_SFX_END 9999 + +#define RID_LIB_START 10000 +#define RID_LIB_END 19999 + +#define RID_SVX_START (RID_LIB_START) +#define RID_SVX_END (RID_LIB_START+499) + +#define RID_SBASIC_START (RID_LIB_START+500) +#define RID_SBASIC_END (RID_LIB_START+2999) + +#define RID_BASIC_START (RID_LIB_START+3000) +#define RID_BASIC_END (RID_LIB_START+4499) + +#define RID_UUI_START (RID_LIB_START+4500) +#define RID_UUI_END (RID_LIB_START+4599) + +#define RID_HELP_START (RID_LIB_START+4600) +#define RID_HELP_END (RID_LIB_START+4799) + +#define RID_MAIL_START (RID_LIB_START+4800) +#define RID_MAIL_END (RID_LIB_START+4849) + +#define RID_BASICIDE_START (RID_LIB_START+4850) +#define RID_BASICIDE_END (RID_LIB_START+4949) + +#define RID_SVXITEMS_START (RID_LIB_START+4950) +#define RID_SVXITEMS_END (RID_LIB_START+5599) + +#define RID_SBA_START (RID_LIB_START+5600) +#define RID_SBA_END (RID_LIB_START+5649) + +#define RID_ISETBRW_START (RID_LIB_START+5650) +#define RID_ISETBRW_END (RID_LIB_START+5699) + +#define RID_EXTENSIONS_START (RID_LIB_START+5700) +#define RID_EXTENSIONS_END (RID_LIB_START+5799) + +#define RID_EDIT_START (RID_LIB_START+5800) +#define RID_EDIT_END (RID_LIB_START+5899) + +#define RID_EDIT_START (RID_LIB_START+5800) +#define RID_EDIT_END (RID_LIB_START+5899) + +#define RID_OUTL_START (RID_LIB_START+5900) +#define RID_OUTL_END (RID_LIB_START+5919) + +#define RID_SVTOOLS_START (RID_LIB_START+5920) +#define RID_SVTOOLS_END (RID_LIB_START+5999) + +#define RID_INET_START (RID_LIB_START+6000) +#define RID_INET_END (RID_LIB_START+6059) + +#define RID_SO2_START (RID_LIB_START+6060) +#define RID_SO2_END (RID_LIB_START+6099) + +#define RID_GOODIES_START (RID_LIB_START+6100) +#define RID_GOODIES_END (RID_LIB_START+6149) + +#define RID_SJ_START (RID_LIB_START+6150) +#define RID_SJ_END (RID_LIB_START+6199) + +#define RID_SI_START (RID_LIB_START+6200) +#define RID_SI_END (RID_LIB_START+6399) + +#define RID_DLG_START (RID_LIB_START+6400) +#define RID_DLG_END (RID_LIB_START+6499) + +#define RID_OFA_START (RID_LIB_START+6500) +#define RID_OFA_END (RID_LIB_START+6999) + +#define RID_CHANNEL_START (RID_LIB_START+7000) +#define RID_CHANNEL_END (RID_LIB_START+7499) + +#define RID_CHAOS_START (RID_LIB_START+7500) +#define RID_CHAOS_END (RID_LIB_START+7999) + +#define RID_FORMS_START (RID_LIB_START+8000) +#define RID_FORMS_END (RID_LIB_START+8999) + +#define RID_FORMLAYER_START (RID_LIB_START+9000) +#define RID_FORMLAYER_END (RID_LIB_START+9199) + +#define RID_DBACCESS_START (RID_LIB_START+9200) +#define RID_DBACCESS_END (RID_LIB_START+9699) + +#define RID_MORE_EXTENSIONS_START (RID_LIB_START+9700) +#define RID_MORE_EXTENSIONS_END (RID_LIB_START+9999) + +#define RID_DB_EXTENSIONS_START (RID_LIB_START+10000) +#define RID_DB_EXTENSIONS_END (RID_LIB_START+10199) + +#define RID_FILTER_START (RID_LIB_START+10200) +#define RID_FILTER_END (RID_LIB_START+10299) + +// do *NOT* add more ranges here, RID_LIB_END is (RID_LIB_START + 10000) + +#define RID_APP_START 20000 +#define RID_APP_END 31999 + +#define RID_SW_START (20000) +#define RID_SW_END (25999) + +#define RID_SC_START (26000) +#define RID_SC_END (26999) + +#define RID_SD_START (27000) +#define RID_SD_END (27999) + +#define RID_OBJ_START (30000) +#define RID_OBJ_END (32767) + +#define RID_SIM_START (RID_OBJ_START+ 0) +#define RID_SIM_END (RID_OBJ_START+ 255) + +#define RID_SMA_START (RID_OBJ_START+ 256) +#define RID_SMA_END (RID_OBJ_START+ 511) + +#define RID_SCH_START (RID_OBJ_START+ 512) +#define RID_SCH_END (RID_OBJ_START+ 767) + +#define RID_RPT_START (RID_OBJ_START+768) +#define RID_RPT_END (RID_OBJ_START+1000) + +#define RID_FORMULA_START (RID_OBJ_START+1001) +#define RID_FORMULA_END (RID_OBJ_START+1200) +// Help-Ids -------------------------------------------------------------- + +#define HID_OK_BUTTON 0 +#define HID_CANCEL_BUTTON 0 +#define HID_HELP_BUTTON 0 + +#define HID_START 32768 + +#define HID_SVTOOLS_START (HID_START+200) +#define HID_SVTOOLS_END (HID_START+299) + +#define HID_SFX_START (HID_START+300) +#define HID_SFX_END (HID_START+999) + +#define HID_LIB_START (HID_START+1000) +#define HID_LIB_END (HID_START+19999) + +#define HID_SVX_START (HID_LIB_START) +#define HID_SVX_END (HID_LIB_START+431) + +#define HID_WIZARD_START (HID_LIB_START+432) +#define HID_WIZARD_END (HID_LIB_START+999) +//please note: There is also HID_WIZARD2 below + +// FREE + +#define HID_CUI_START (HID_LIB_START+1100) +#define HID_CUI_END (HID_LIB_START+1699) + +#define HID_OFA_START (HID_LIB_START+1760) +#define HID_OFA_END (HID_LIB_START+1999) + +#define HID_HELP_START (HID_LIB_START+2000) +#define HID_HELP_END (HID_LIB_START+2050) + +#define HID_CHAOS_START (HID_LIB_START+2051) +#define HID_CHAOS_END (HID_LIB_START+2069) + +#define HID_UUI_START (HID_LIB_START+2070) +#define HID_UUI_END (HID_LIB_START+2099) + +#define HID_GOODIES_START (HID_LIB_START+2100) +#define HID_GOODIES_END (HID_LIB_START+2199) + +#define HID_SCHEDULE_START (HID_LIB_START+2200) +#define HID_SCHEDULE_END (HID_LIB_START+3399) + +#define HID_CHANNEL_START (HID_LIB_START+3400) +#define HID_CHANNEL_END (HID_LIB_START+3499) + +#define HID_SBA_START (HID_LIB_START+ 3500) +#define HID_SBA_END (HID_LIB_START+ 3999) + +#define HID_FORMS_START (HID_LIB_START+4000) +#define HID_FORMS_END (HID_LIB_START+4999) + +#define HID_DBACCESS_START (HID_LIB_START+5000) +#define HID_DBACCESS_END (HID_LIB_START+5299) + +#define HID_PORTAL_START (HID_LIB_START+5300) +#define HID_PORTAL_END (HID_LIB_START+5599) + +#define HID_PORTAL_ADMIN_START (HID_LIB_START+5600) +#define HID_PORTAL_ADMIN_END (HID_LIB_START+5999) + +#define HID_SYNCACCESS_START (HID_LIB_START+6000) +#define HID_SYNCACCESS_END (HID_LIB_START+6099) + +#define HID_SVX_EXT0_START (HID_LIB_START+6100) +#define HID_SVX_EXT0_END (HID_LIB_START+6599) + +#define HID_FRAMEWORK_START (HID_LIB_START+6600) +#define HID_FRAMEWORK_END (HID_LIB_START+6999) + +#define HID_WIZARD2_START (HID_LIB_START+7000) +#define HID_WIZARD2_END (HID_LIB_START+8999) + +#define HID_DESKTOP_START (HID_LIB_START+9000) +#define HID_DESKTOP_END (HID_LIB_START+9299) + +#define HID_XMLSECURITY_START (HID_LIB_START+9300) +#define HID_XMLSECURITY_END (HID_LIB_START+9999) + +#define HID_APP_START (HID_START+20000) +#define HID_APP_END (HID_START+29999) + +#define HID_SW_START (HID_START+20000) +#define HID_SW_END (HID_START+24999) + +#define HID_SC_START (HID_START+25000) +#define HID_SC_END (HID_START+26999) + +#define HID_SD_START (HID_START+27000) +#define HID_SD_END (HID_START+27999) + +#define HID_Sa_START (HID_START+28000) +#define HID_Sa_END (HID_START+28999) + +#define HID_Sb_START (HID_START+29000) +#define HID_Sb_END (HID_START+29999) + +#define HID_OBJ_START (HID_START+30000) +#define HID_OBJ_END (HID_START+32767) + +#define HID_CUI3_START (HID_OBJ_START+ 0) +#define HID_CUI3_END (HID_OBJ_START+ 239) + +#define HID_AVMEDIA_START (HID_OBJ_START+ 240) +#define HID_AVMEDIA_END (HID_OBJ_START+ 255) + +#define HID_SMA_START (HID_OBJ_START+ 256) +#define HID_SMA_END (HID_OBJ_START+ 511) + +#define HID_SCH_START (HID_OBJ_START+ 512) +#define HID_SCH_END (HID_OBJ_START+ 767) + +#define HID_BASICIDE_START (HID_OBJ_START+ 768) +#define HID_BASICIDE_END (HID_OBJ_START+1023) + +#define HID_SMA2_START (HID_OBJ_START+1024) +#define HID_SMA2_END (HID_OBJ_START+1280) + +#define HID_FILTER_START (HID_OBJ_START+1281) +#define HID_FILTER_END (HID_OBJ_START+1580) + +#define HID_LICENSING_START (HID_OBJ_START+1581) +#define HID_LICENSING_END (HID_OBJ_START+1680) + +#define HID_RPT_START (HID_OBJ_START+1681) +#define HID_RPT_END (HID_OBJ_START+2080) + +#define HID_FORMULA_START (HID_OBJ_START+2081) +#define HID_FORMULA_END (HID_OBJ_START+2280) + +#define HID_EXTENSIONS_START (HID_OBJ_START+2281) +#define HID_EXTENSIONS_END (HID_OBJ_START+2800) + + +#endif + diff --git a/svl/inc/svl/stritem.hxx b/svl/inc/svl/stritem.hxx new file mode 100644 index 000000000000..21ee9fadd1ec --- /dev/null +++ b/svl/inc/svl/stritem.hxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * 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: stritem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXSTRITEM_HXX +#define _SFXSTRITEM_HXX + +#include "svl/svldllapi.h" +#include <svl/custritm.hxx> + +//============================================================================ +class SVL_DLLPUBLIC SfxStringItem: public CntUnencodedStringItem +{ +public: + TYPEINFO(); + + SfxStringItem() {} + + SfxStringItem(USHORT which, const XubString & rValue): + CntUnencodedStringItem(which, rValue) {} + + SfxStringItem(USHORT nWhich, SvStream & rStream); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; +}; + +#endif // _SFXSTRITEM_HXX + diff --git a/svl/inc/svl/style.hrc b/svl/inc/svl/style.hrc new file mode 100644 index 000000000000..ed4db1bf46d0 --- /dev/null +++ b/svl/inc/svl/style.hrc @@ -0,0 +1,42 @@ +/************************************************************************* + * + * 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: style.hrc,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFX_STYLE_HRC +#define _SFX_STYLE_HRC + +#define SFXSTYLEBIT_AUTO 0x0000 // automatisch; Flags kommen von der Applikation +#define SFXSTYLEBIT_READONLY 0x2000 // benutzte Vorlage (als Suchmaske) +#define SFXSTYLEBIT_USED 0x4000 // benutzte Vorlage (als Suchmaske) +#define SFXSTYLEBIT_USERDEF 0x8000 // benutzerdefinierte Vorlage +#define SFXSTYLEBIT_ALL 0xFFFF // alle Vorlagen + +#endif + + diff --git a/svl/inc/svl/style.hxx b/svl/inc/svl/style.hxx new file mode 100644 index 000000000000..66c130d346dd --- /dev/null +++ b/svl/inc/svl/style.hxx @@ -0,0 +1,400 @@ +/************************************************************************* + * + * 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: style.hxx,v $ + * $Revision: 1.5.60.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXSTYLE_HXX +#define _SFXSTYLE_HXX + +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> + +#include <rtl/ref.hxx> +#include <vector> +#include <comphelper/weak.hxx> +#include <cppuhelper/implbase2.hxx> +#include "svl/svldllapi.h" +#include <rsc/rscsfx.hxx> +#include <tools/string.hxx> +#include <svl/hint.hxx> +#include <svl/lstner.hxx> +#include <svl/brdcst.hxx> +#include <svl/poolitem.hxx> + +#ifndef _SFX_STYLE_HRC +#include <svl/style.hrc> +#endif + +class SfxItemSet; +class SfxItemPool; + +class SfxStyleSheetBasePool; +class SvStream; + +/* +Everyone changing instances of SfxStyleSheetBasePool or SfxStyleSheetBase +mußt broadcast this using <SfxStyleSheetBasePool::GetBroadcaster()> broadcasten. +The class <SfxStyleSheetHint> is used for this, it contains an Action-Id and a +pointer to the <SfxStyleSheetBase>. The actions are: + +#define SFX_STYLESHEET_CREATED // style is created +#define SFX_STYLESHEET_MODIFIED // style is modified +#define SFX_STYLESHEET_CHANGED // style is replaced +#define SFX_STYLESHEET_ERASED // style is deleted + +The following methods already broadcast themself + +SfxStyleSheetHint(SFX_STYLESHEET_MODIFIED) from: + SfxStyleSheetBase::SetName( const String& rName ) + SfxStyleSheetBase::SetParent( const String& rName ) + SfxStyleSheetBase::SetFollow( const String& rName ) + +SfxSimpleHint(SFX_HINT_DYING) from: + SfxStyleSheetBasePool::~SfxStyleSheetBasePool() + +SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) from: + SfxStyleSheetBasePool::Make( const String& rName, + SfxStyleFamily eFam, USHORT mask, USHORT nPos) + +SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *pNew ) from: + SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet ) + +SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) from: + SfxStyleSheetBasePool::Erase( SfxStyleSheetBase* p ) + SfxStyleSheetBasePool::Clear() +*/ + +#define VIRTUAL510 virtual + +class SVL_DLLPUBLIC SfxStyleSheetBase : public comphelper::OWeakTypeObject +{ + friend class SfxStyleSheetBasePool; + +protected: + SfxStyleSheetBasePool& rPool; // zugehoeriger Pool + SfxStyleFamily nFamily; // Familie + + UniString aName, aParent, aFollow; + rtl::OUString maDisplayName; + String aHelpFile; // Name der Hilfedatei + SfxItemSet* pSet; // ItemSet + USHORT nMask; // Flags + + ULONG nHelpId; // Hilfe-ID + + BOOL bMySet; // TRUE: Set loeschen im dtor + + SfxStyleSheetBase(); // do not use! + SfxStyleSheetBase( const UniString&, SfxStyleSheetBasePool&, SfxStyleFamily eFam, USHORT mask ); + SfxStyleSheetBase( const SfxStyleSheetBase& ); + virtual ~SfxStyleSheetBase(); + virtual void Load( SvStream&, USHORT ); + virtual void Store( SvStream& ); + +public: + TYPEINFO(); + + // returns the internal name of this style + virtual const UniString& GetName() const; + + // sets the internal name of this style + virtual BOOL SetName( const UniString& ); + + /** returns the display name of this style, it is used at the user interface. + If the display name is empty, this method returns the internal name. */ + virtual rtl::OUString GetDisplayName() const; + + // sets the display name of this style + virtual void SetDisplayName( const rtl::OUString& ); + + virtual const UniString& GetParent() const; + virtual BOOL SetParent( const UniString& ); + virtual const UniString& GetFollow() const; + virtual BOOL SetFollow( const UniString& ); + virtual BOOL HasFollowSupport() const; // Default TRUE + virtual BOOL HasParentSupport() const; // Default TRUE + virtual BOOL HasClearParentSupport() const; // Default FALSE + virtual BOOL IsUsed() const; // Default TRUE + // Default aus dem Itemset; entweder dem uebergebenen + // oder aus dem per GetItemSet() zurueckgelieferten Set + virtual UniString GetDescription(); + virtual UniString GetDescription( SfxMapUnit eMetric ); + + SfxStyleSheetBasePool& GetPool() { return rPool; } + SfxStyleFamily GetFamily() const { return nFamily; } + USHORT GetMask() const { return nMask; } + void SetMask( USHORT mask) { nMask = mask; } + BOOL IsUserDefined() const + { return BOOL( ( nMask & SFXSTYLEBIT_USERDEF) != 0 ); } + + virtual ULONG GetHelpId( String& rFile ); + virtual void SetHelpId( const String& r, ULONG nId ); + + virtual SfxItemSet& GetItemSet(); + virtual USHORT GetVersion() const; +}; + +//========================================================================= + +typedef std::vector< rtl::Reference< SfxStyleSheetBase > > SfxStyles; + +//========================================================================= + +class SVL_DLLPUBLIC SfxStyleSheetIterator + +/* [Beschreibung] + + Klasse zum Iterieren und Suchen auf einem SfxStyleSheetBasePool. + +*/ + +{ +public: + SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase, + SfxStyleFamily eFam, USHORT n=0xFFFF ); + virtual USHORT GetSearchMask() const; + virtual SfxStyleFamily GetSearchFamily() const; + virtual USHORT Count(); + virtual SfxStyleSheetBase *operator[](USHORT nIdx); + virtual SfxStyleSheetBase* First(); + virtual SfxStyleSheetBase* Next(); + virtual SfxStyleSheetBase* Find(const UniString& rStr); + virtual ~SfxStyleSheetIterator(); + +protected: + + SfxStyleSheetBasePool* pBasePool; + SfxStyleFamily nSearchFamily; + USHORT nMask; + BOOL SearchUsed() const { return bSearchUsed; } + +private: + USHORT GetPos(){return nAktPosition;} + SVL_DLLPRIVATE BOOL IsTrivialSearch(); + SVL_DLLPRIVATE BOOL DoesStyleMatch(SfxStyleSheetBase *pStyle); + + void* pImp; + SfxStyleSheetBase* pAktStyle; + USHORT nAktPosition; + BOOL bSearchUsed; + +friend class SfxStyleSheetBasePool; +}; + +//========================================================================= + +class SfxStyleSheetBasePool_Impl; + +class SVL_DLLPUBLIC SfxStyleSheetBasePool: public SfxBroadcaster, public comphelper::OWeakTypeObject +{ +friend class SfxStyleSheetIterator; +friend class SfxStyleSheetBase; + + SfxStyleSheetBasePool_Impl *pImp; + +private: + SVL_DLLPRIVATE BOOL Load1_Impl( SvStream& ); + SVL_DLLPRIVATE SfxStyleSheetIterator& GetIterator_Impl(); +protected: + String aAppName; + SfxItemPool& rPool; + SfxStyles aStyles; + SfxStyleFamily nSearchFamily; + USHORT nMask; + + SfxStyleSheetBase& Add( SfxStyleSheetBase& ); + void ChangeParent( const UniString&, const UniString&, BOOL bVirtual = TRUE ); + virtual SfxStyleSheetBase* Create( const UniString&, SfxStyleFamily, USHORT ); + virtual SfxStyleSheetBase* Create( const SfxStyleSheetBase& ); + + ~SfxStyleSheetBasePool(); + +public: + SfxStyleSheetBasePool( SfxItemPool& ); + SfxStyleSheetBasePool( const SfxStyleSheetBasePool& ); + + static String GetStreamName(); + + const String& GetAppName() const { return aAppName; } + + SfxItemPool& GetPool(); + const SfxItemPool& GetPool() const; + + virtual SfxStyleSheetIterator* CreateIterator(SfxStyleFamily, USHORT nMask); + virtual USHORT Count(); + virtual SfxStyleSheetBase* operator[](USHORT nIdx); + + virtual SfxStyleSheetBase& Make(const UniString&, + SfxStyleFamily eFam, + USHORT nMask = 0xffff , + USHORT nPos = 0xffff); + + virtual void Replace( + SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget ); + + virtual void Remove( SfxStyleSheetBase* ); + virtual void Insert( SfxStyleSheetBase* ); + + virtual void Clear(); + + SfxStyleSheetBasePool& operator=( const SfxStyleSheetBasePool& ); + SfxStyleSheetBasePool& operator+=( const SfxStyleSheetBasePool& ); + + const SfxStyles& GetStyles(); + virtual SfxStyleSheetBase* First(); + virtual SfxStyleSheetBase* Next(); + virtual SfxStyleSheetBase* Find( const UniString&, SfxStyleFamily eFam, USHORT n=0xFFFF ); + + virtual BOOL SetParent(SfxStyleFamily eFam, + const UniString &rStyle, + const UniString &rParent); + + SfxStyleSheetBase* Find(const UniString& rStr) + { return Find(rStr, nSearchFamily, nMask); } + + void SetSearchMask(SfxStyleFamily eFam, USHORT n=0xFFFF ); + USHORT GetSearchMask() const; + SfxStyleFamily GetSearchFamily() const { return nSearchFamily; } + + BOOL Load( SvStream& ); + BOOL Store( SvStream&, BOOL bUsed = TRUE ); +}; + +//========================================================================= + +class SVL_DLLPUBLIC SfxStyleSheet: public SfxStyleSheetBase, + public SfxListener, public SfxBroadcaster +{ +public: + TYPEINFO(); + + SfxStyleSheet( const UniString&, const SfxStyleSheetBasePool&, SfxStyleFamily, USHORT ); + SfxStyleSheet( const SfxStyleSheet& ); + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + virtual BOOL SetParent( const UniString& ); + +protected: + SfxStyleSheet(); // do not use! + virtual ~SfxStyleSheet(); +}; + +//========================================================================= + +class SVL_DLLPUBLIC SfxStyleSheetPool: public SfxStyleSheetBasePool +{ +protected: + using SfxStyleSheetBasePool::Create; + virtual SfxStyleSheetBase* Create(const UniString&, SfxStyleFamily, USHORT mask); + virtual SfxStyleSheetBase* Create(const SfxStyleSheet &); + +public: + SfxStyleSheetPool( SfxItemPool const& ); + +// virtual BOOL CopyTo(SfxStyleSheetPool &rDest, const String &rSourceName); +}; + +//========================================================================= + +#define SFX_STYLESHEET_CREATED 1 // neu +#define SFX_STYLESHEET_MODIFIED 2 // ver"andert +#define SFX_STYLESHEET_CHANGED 3 // gel"oscht und neu (ausgetauscht) +#define SFX_STYLESHEET_ERASED 4 // gel"oscht +#define SFX_STYLESHEET_INDESTRUCTION 5 // wird gerade entfernt + +#define SFX_STYLESHEETPOOL_CHANGES 1 // Aenderungen, die den Zustand + // des Pools anedern, aber nicht + // ueber die STYLESHEET Hints + // verschickt werden sollen. + +//======================================================================== + +class SVL_DLLPUBLIC SfxStyleSheetPoolHint : public SfxHint +{ + USHORT nHint; + +public: + TYPEINFO(); + + SfxStyleSheetPoolHint(USHORT nArgHint) : nHint(nArgHint){} + USHORT GetHint() const + { return nHint; } +}; + +//========================================================================= + +class SVL_DLLPUBLIC SfxStyleSheetHint: public SfxHint +{ + SfxStyleSheetBase* pStyleSh; + USHORT nHint; + +public: + TYPEINFO(); + + SfxStyleSheetHint( USHORT ); + SfxStyleSheetHint( USHORT, SfxStyleSheetBase& ); + SfxStyleSheetBase* GetStyleSheet() const + { return pStyleSh; } + USHORT GetHint() const + { return nHint; } +}; + +class SVL_DLLPUBLIC SfxStyleSheetHintExtended: public SfxStyleSheetHint +{ + String aName; + +public: + TYPEINFO(); + + SfxStyleSheetHintExtended( + USHORT, const String& rOld ); + SfxStyleSheetHintExtended( + USHORT, const String& rOld, + SfxStyleSheetBase& ); + const String& GetOldName() { return aName; } +}; + +class SVL_DLLPUBLIC SfxUnoStyleSheet : public ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel > +{ +public: + SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, USHORT _nMaske ); + SfxUnoStyleSheet( const SfxStyleSheet& _rSheet ); + + static SfxUnoStyleSheet* getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle ); + + // XUnoTunnel + virtual ::sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& aIdentifier ) throw (::com::sun::star::uno::RuntimeException); + +private: + SfxUnoStyleSheet(); // not implemented + + static const ::com::sun::star::uno::Sequence< ::sal_Int8 >& getIdentifier(); +}; + +#endif + diff --git a/svl/inc/svl/svarray.hxx b/svl/inc/svl/svarray.hxx new file mode 100644 index 000000000000..555b7ad5fe84 --- /dev/null +++ b/svl/inc/svl/svarray.hxx @@ -0,0 +1,1056 @@ +/************************************************************************* + * + * 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: svarray.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVARRAY_HXX +#define _SVARRAY_HXX + +#if 0 +*********************************************************************** +* +* Hier folgt die Beschreibung fuer die exportierten Makros: +* +* SV_DECL_VARARR(nm, AE, IS, GS) +* SV_IMPL_VARARR( nm, AE ) +* definiere/implementiere ein Array das einfache Objecte +* enthaelt. (Sie werden im Speicher verschoben, koennen also +* z.B. keine String sein) +* +* SV_DECL_OBJARR(nm, AE, IS, GS) +* SV_IMPL_OBJARR( nm, AE ) +* definiere/implementiere ein Array das Objecte enthaelt. +* (Hier koennen es auch Strings sein) +* +* +* SV_DECL_PTRARR(nm, AE, IS, GS) +* SV_IMPL_PTRARR(nm, AE) +* definiere/implementiere ein Array das Pointer haelt. Diese +* werden von aussen angelegt und zerstoert. Das IMPL-Makro +* wird nur benoetigt, wenn die DeleteAndDestroy Methode genutzt +* wird, diese loescht dann die Pointer und ruft deren Destruktoren +* +* SV_DECL_PTRARR_DEL(nm, AE, IS, GS) +* SV_IMPL_PTRARR(nm, AE) +* definiere/implementiere ein Array das Pointer haelt. Diese +* werden von aussen angelegt und im Destructor zerstoert. +* +* +* SV_DECL_PTRARR_SORT(nm, AE, IS, GS) +* SV_IMPL_PTRARR_SORT( nm,AE ) +* defieniere/implementiere ein Sort-Array mit Pointern, das nach +* Pointern sortiert ist. Basiert auf einem PTRARR +* +* SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS) +* SV_IMPL_PTRARR_SORT( nm,AE ) +* defieniere/implementiere ein Sort-Array mit Pointern, das nach +* Pointern sortiert ist. Basiert auf einem PTRARR_DEL +* +* SV_DECL_PTRARR_SORT(nm, AE, IS, GS) +* SV_IMPL_OP_PTRARR_SORT( nm,AE ) +* defieniere/implementiere ein Sort-Array mit Pointern, das nach +* Objecten sortiert ist. Basiert auf einem PTRARR. +* Sortierung mit Hilfe der Object-operatoren "<" und "==" +* +* SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS) +* SV_IMPL_OP_PTRARR_SORT( nm,AE ) +* defieniere/implementiere ein Sort-Array mit Pointern, das nach +* Objecten sortiert ist. Basiert auf einem PTRARR_DEL. +* Sortierung mit Hilfe der Object-operatoren "<" und "==" +* +* SV_DECL_VARARR_SORT(nm, AE, IS, GS) +* SV_IMPL_VARARR_SORT( nm,AE ) +* defieniere/implementiere ein Sort-Array mit einfachen Objecten. +* Basiert auf einem VARARR. +* Sortierung mit Hilfe der Object-operatoren "<" und "==" +* +* JP 23.12.94 neu: +* SV_DECL_PTRARR_STACK(nm, AE, IS, GS) +* ein Stack mit einem PtrArray als Grundlage. +* +* JP 09.10.96: vordefinierte Arrays: +* VarArr: SvBools, SvULongs, SvUShorts, SvLongs, SvShorts +* PtrArr: SvStrings, SvStringsDtor +* SortArr: SvStringsSort, SvStringsSortDtor, +* SvStringsISort, SvStringsISortDtor +*********************************************************************** +#endif + +#include "svl/svldllapi.h" + +#ifndef INCLUDED_STRING_H +#include <string.h> // memmove() +#define INCLUDED_STRING_H +#endif + +#ifndef INCLUDED_LIMITS_H +#include <limits.h> // USHRT_MAX +#define INCLUDED_LIMITS_H +#endif +#include <rtl/alloc.h> +#include <tools/solar.h> + +class String; + +#ifndef CONCAT +#define CONCAT(x,y) x##y +#endif + +class DummyType; +inline void* operator new( size_t, DummyType* pPtr ) +{ + return pPtr; +} +inline void operator delete( void*, DummyType* ) {} + +#if defined(PRODUCT) + +#define _SVVARARR_DEF_GET_OP_INLINE( nm, ArrElem ) \ +ArrElem& operator[](USHORT nP) const { return *(pData+nP); }\ +\ +void Insert( const nm * pI, USHORT nP,\ + USHORT nS = 0, USHORT nE = USHRT_MAX )\ +{\ + if( USHRT_MAX == nE ) \ + nE = pI->nA; \ + if( nS < nE ) \ + Insert( (const ArrElem*)pI->pData+nS, (USHORT)nE-nS, nP );\ +} + +#define _SVVARARR_IMPL_GET_OP_INLINE( nm, ArrElem ) + +#else + +#define _SVVARARR_DEF_GET_OP_INLINE( nm,ArrElem )\ +ArrElem& operator[](USHORT nP) const;\ +void Insert( const nm *pI, USHORT nP,\ + USHORT nS = 0, USHORT nE = USHRT_MAX ); + +#define _SVVARARR_IMPL_GET_OP_INLINE( nm, ArrElem )\ +ArrElem& nm::operator[](USHORT nP) const\ +{\ + DBG_ASSERT( pData && nP < nA,"Op[]");\ + return *(pData+nP);\ +}\ +void nm::Insert( const nm *pI, USHORT nP, USHORT nStt, USHORT nE)\ +{\ + DBG_ASSERT(nP<=nA,"Ins,Ar[Start.End]");\ + if( USHRT_MAX == nE ) \ + nE = pI->nA; \ + if( nStt < nE ) \ + Insert( (const ArrElem*)pI->pData+nStt, (USHORT)nE-nStt, nP );\ +} + +#endif + +#define _SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\ +typedef BOOL (*FnForEach_##nm)( const AERef, void* );\ +class vis nm\ +{\ +protected:\ + AE *pData;\ + USHORT nFree;\ + USHORT nA;\ +\ + void _resize(size_t n);\ +\ +public:\ + nm( USHORT= IS, BYTE= GS );\ + ~nm() { rtl_freeMemory( pData ); }\ +\ + _SVVARARR_DEF_GET_OP_INLINE(nm, AE )\ + AERef GetObject(USHORT nP) const { return (*this)[nP]; } \ +\ + void Insert( const AERef aE, USHORT nP );\ + void Insert( const AE *pE, USHORT nL, USHORT nP );\ + void Remove( USHORT nP, USHORT nL = 1 );\ + void Replace( const AERef aE, USHORT nP );\ + void Replace( const AE *pE, USHORT nL, USHORT nP );\ + USHORT Count() const { return nA; }\ + const AE* GetData() const { return (const AE*)pData; }\ +\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, fnForEach, pArgs );\ + }\ +\ + void _ForEach( USHORT nStt, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnCall, void* pArgs = 0 );\ +\ + +#define _SV_DECL_VARARR(nm, AE, IS, GS ) \ +_SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE & ) +#define _SV_DECL_VARARR_PLAIN(nm, AE, IS, GS ) \ +_SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE ) + +#define SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\ +_SV_DECL_VARARR_GEN(nm, AE, IS, GS, AERef, vis )\ +private:\ +nm( const nm& );\ +nm& operator=( const nm& );\ +}; + +#define SV_DECL_VARARR(nm, AE, IS, GS ) \ +SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE &, ) +#define SV_DECL_VARARR_PLAIN(nm, AE, IS, GS ) \ +SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE, ) + +#define SV_DECL_VARARR_VISIBILITY(nm, AE, IS, GS, vis ) \ +SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE &, vis ) + +#define SV_DECL_VARARR_PLAIN_VISIBILITY(nm, AE, IS, GS, vis ) \ +SV_DECL_VARARR_GEN(nm, AE, IS, GS, AE, vis ) + +#define SV_IMPL_VARARR_GEN( nm, AE, AERef )\ +nm::nm( USHORT nInit, BYTE )\ + : pData (0),\ + nFree (nInit),\ + nA (0)\ +{\ + if( nInit )\ + {\ + pData = (AE*)(rtl_allocateMemory(sizeof(AE) * nInit));\ + DBG_ASSERT( pData, "CTOR, allocate");\ + }\ +}\ +\ +void nm::_resize (size_t n)\ +{\ + USHORT nL = ((n < USHRT_MAX) ? USHORT(n) : USHRT_MAX);\ + AE* pE = (AE*)(rtl_reallocateMemory (pData, sizeof(AE) * nL));\ + if ((pE != 0) || (nL == 0))\ + {\ + pData = pE;\ + nFree = nL - nA;\ + }\ +}\ +\ +void nm::Insert( const AERef aE, USHORT nP )\ +{\ + DBG_ASSERT(nP <= nA && nA < USHRT_MAX, "Ins 1");\ + if (nFree < 1)\ + _resize (nA + ((nA > 1) ? nA : 1));\ + if( pData && nP < nA )\ + memmove( pData+nP+1, pData+nP, (nA-nP) * sizeof( AE ));\ + *(pData+nP) = (AE&)aE;\ + ++nA; --nFree;\ +}\ +\ +void nm::Insert( const AE* pE, USHORT nL, USHORT nP )\ +{\ + DBG_ASSERT(nP<=nA && ((long)nA+nL)<USHRT_MAX,"Ins n");\ + if (nFree < nL)\ + _resize (nA + ((nA > nL) ? nA : nL));\ + if( pData && nP < nA )\ + memmove( pData+nP+nL, pData+nP, (nA-nP) * sizeof( AE ));\ + if( pE )\ + memcpy( pData+nP, pE, nL * sizeof( AE ));\ + nA = nA + nL; nFree = nFree - nL;\ +}\ +\ +void nm::Replace( const AERef aE, USHORT nP )\ +{\ + if( nP < nA )\ + *(pData+nP) = (AE&)aE;\ +}\ +\ +void nm::Replace( const AE *pE, USHORT nL, USHORT nP )\ +{\ + if( pE && nP < nA )\ + {\ + if( nP + nL < nA )\ + memcpy( pData + nP, pE, nL * sizeof( AE ));\ + else if( nP + nL < nA + nFree )\ + {\ + memcpy( pData + nP, pE, nL * sizeof( AE ));\ + nP = nP + (nL - nA); \ + nFree = nP;\ + }\ + else \ + {\ + USHORT nTmpLen = nA + nFree - nP; \ + memcpy( pData + nP, pE, nTmpLen * sizeof( AE ));\ + nA = nA + nFree; \ + nFree = 0; \ + Insert( pE + nTmpLen, nL - nTmpLen, nA );\ + }\ + }\ +}\ +\ +void nm::Remove( USHORT nP, USHORT nL )\ +{\ + if( !nL )\ + return;\ + DBG_ASSERT( nP < nA && nP + nL <= nA,"Del");\ + if( pData && nP+1 < nA )\ + memmove( pData+nP, pData+nP+nL, (nA-nP-nL) * sizeof( AE ));\ + nA = nA - nL; nFree = nFree + nL;\ + if (nFree > nA)\ + _resize (nA);\ +}\ +\ +void nm::_ForEach( USHORT nStt, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnCall, void* pArgs )\ +{\ + if( nStt >= nE || nE > nA )\ + return;\ + for( ; nStt < nE && (*fnCall)( *(const AE*)(pData+nStt), pArgs ); nStt++)\ + ;\ +}\ +\ +_SVVARARR_IMPL_GET_OP_INLINE(nm, AE )\ + +#define SV_IMPL_VARARR( nm, AE ) \ +SV_IMPL_VARARR_GEN( nm, AE, AE & ) +#define SV_IMPL_VARARR_PLAIN( nm, AE ) \ +SV_IMPL_VARARR_GEN( nm, AE, AE ) + +#if defined(PRODUCT) + +#define _SVOBJARR_DEF_GET_OP_INLINE( nm,ArrElem )\ +ArrElem& operator[](USHORT nP) const { return *(pData+nP); }\ +\ +void Insert( const nm *pI, USHORT nP,\ + USHORT nS = 0, USHORT nE = USHRT_MAX )\ +{\ + if( USHRT_MAX == nE ) \ + nE = pI->nA; \ + if( nS < nE ) \ + Insert( (const ArrElem*)pI->pData+nS, (USHORT)nE-nS, nP );\ +} + +#define _SVOBJARR_IMPL_GET_OP_INLINE( nm, ArrElem ) + +#else + +#define _SVOBJARR_DEF_GET_OP_INLINE( nm,ArrElem ) \ +ArrElem& operator[](USHORT nP) const;\ +void Insert( const nm *pI, USHORT nP,\ + USHORT nS = 0, USHORT nE = USHRT_MAX ); + +#define _SVOBJARR_IMPL_GET_OP_INLINE( nm, ArrElem )\ +ArrElem& nm::operator[](USHORT nP) const\ +{\ + DBG_ASSERT( pData && nP < nA,"Op[]");\ + return *(pData+nP);\ +}\ +void nm::Insert( const nm *pI, USHORT nP, USHORT nStt, USHORT nE )\ +{\ + DBG_ASSERT( nP <= nA,"Ins,Ar[Start.End]");\ + if( USHRT_MAX == nE ) \ + nE = pI->nA; \ + if( nStt < nE ) \ + Insert( (const ArrElem*)pI->pData+nStt, (USHORT)nE-nStt, nP );\ +} + +#endif + +#define _SV_DECL_OBJARR(nm, AE, IS, GS)\ +typedef BOOL (*FnForEach_##nm)( const AE&, void* );\ +class nm\ +{\ +protected:\ + AE *pData;\ + USHORT nFree;\ + USHORT nA;\ +\ + void _resize(size_t n);\ + void _destroy();\ +\ +public:\ + nm( USHORT= IS, BYTE= GS );\ + ~nm() { _destroy(); }\ +\ + _SVOBJARR_DEF_GET_OP_INLINE(nm,AE)\ + AE& GetObject(USHORT nP) const { return (*this)[nP]; } \ +\ + void Insert( const AE &aE, USHORT nP );\ + void Insert( const AE *pE, USHORT nL, USHORT nP );\ + void Remove( USHORT nP, USHORT nL = 1 );\ + USHORT Count() const { return nA; }\ + const AE* GetData() const { return (const AE*)pData; }\ +\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, fnForEach, pArgs );\ + }\ +\ + void _ForEach( USHORT nStt, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnCall, void* pArgs = 0 );\ +\ + +#define SV_DECL_OBJARR(nm, AE, IS, GS)\ +_SV_DECL_OBJARR(nm, AE, IS, GS)\ +private:\ +nm( const nm& );\ +nm& operator=( const nm& );\ +}; + +#define SV_IMPL_OBJARR( nm, AE )\ +nm::nm( USHORT nInit, BYTE )\ + : pData (0),\ + nFree (nInit),\ + nA (0)\ +{\ + if( nInit )\ + {\ + pData = (AE*)(rtl_allocateMemory(sizeof(AE) * nInit));\ + DBG_ASSERT( pData, "CTOR, allocate");\ + }\ +}\ +\ +void nm::_destroy()\ +{\ + if(pData)\ + {\ + AE* pTmp=pData;\ + for(USHORT n=0; n < nA; n++,pTmp++ )\ + {\ + pTmp->~AE();\ + }\ + rtl_freeMemory(pData);\ + pData = 0;\ + }\ +}\ +\ +void nm::_resize (size_t n)\ +{\ + USHORT nL = ((n < USHRT_MAX) ? USHORT(n) : USHRT_MAX);\ + AE* pE = (AE*)(rtl_reallocateMemory (pData, sizeof(AE) * nL));\ + if ((pE != 0) || (nL == 0))\ + {\ + pData = pE;\ + nFree = nL - nA;\ + }\ +}\ +\ +void nm::Insert( const AE &aE, USHORT nP )\ +{\ + DBG_ASSERT( nP <= nA && nA < USHRT_MAX,"Ins 1");\ + if (nFree < 1)\ + _resize (nA + ((nA > 1) ? nA : 1));\ + if( pData && nP < nA )\ + memmove( pData+nP+1, pData+nP, (nA-nP) * sizeof( AE ));\ + AE* pTmp = pData+nP;\ + new( (DummyType*) pTmp ) AE( (AE&)aE );\ + ++nA; --nFree;\ +}\ +\ +void nm::Insert( const AE* pE, USHORT nL, USHORT nP )\ +{\ + DBG_ASSERT(nP<=nA && ((long)nA+nL) < USHRT_MAX, "Ins n");\ + if (nFree < nL)\ + _resize (nA + ((nA > nL) ? nA : nL));\ + if( pData && nP < nA )\ + memmove( pData+nP+nL, pData+nP, (nA-nP) * sizeof( AE ));\ + if( pE )\ + {\ + AE* pTmp = pData+nP;\ + for( USHORT n = 0; n < nL; n++, pTmp++, pE++)\ + {\ + new( (DummyType*) pTmp ) AE( (AE&)*pE );\ + }\ + }\ + nA = nA + nL; nFree = nFree - nL;\ +}\ +\ +void nm::Remove( USHORT nP, USHORT nL )\ +{\ + if( !nL )\ + return;\ + DBG_ASSERT( nP < nA && nP + nL <= nA,"Del");\ + AE* pTmp=pData+nP;\ + USHORT nCtr = nP;\ + for(USHORT n=0; n < nL; n++,pTmp++,nCtr++)\ + {\ + if( nCtr < nA )\ + pTmp->~AE();\ + }\ + if( pData && nP+1 < nA )\ + memmove( pData+nP, pData+nP+nL, (nA-nP-nL) * sizeof( AE ));\ + nA = nA - nL; nFree = nFree + nL;\ + if (nFree > nA) \ + _resize (nA);\ +}\ +\ +void nm::_ForEach( USHORT nStt, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnCall, void* pArgs )\ +{\ + if( nStt >= nE || nE > nA )\ + return;\ + for( ; nStt < nE && (*fnCall)( *(pData+nStt), pArgs ); nStt++)\ + ;\ +}\ +\ +_SVOBJARR_IMPL_GET_OP_INLINE(nm, AE)\ + +#define _SV_DECL_PTRARR_DEF_GEN( nm, AE, IS, GS, AERef, vis )\ +_SV_DECL_VARARR_GEN( nm, AE, IS, GS, AERef, vis)\ +USHORT GetPos( const AERef aE ) const;\ +}; + +#define _SV_DECL_PTRARR_DEF( nm, AE, IS, GS, vis )\ +_SV_DECL_PTRARR_DEF_GEN( nm, AE, IS, GS, AE &, vis ) +#define _SV_DECL_PTRARR_DEF_PLAIN( nm, AE, IS, GS, vis )\ +_SV_DECL_PTRARR_DEF_GEN( nm, AE, IS, GS, AE, vis ) + +#define SV_DECL_PTRARR_GEN(nm, AE, IS, GS, Base, AERef, VPRef, vis )\ +typedef BOOL (*FnForEach_##nm)( const AERef, void* );\ +class vis nm: public Base \ +{\ +public:\ + nm( USHORT nIni=IS, BYTE nG=GS )\ + : Base(nIni,nG) {}\ + void Insert( const nm *pI, USHORT nP, \ + USHORT nS = 0, USHORT nE = USHRT_MAX ) {\ + Base::Insert((const Base*)pI, nP, nS, nE);\ + }\ + void Insert( const AERef aE, USHORT nP ) {\ + Base::Insert( (const VPRef )aE, nP );\ + }\ + void Insert( const AE *pE, USHORT nL, USHORT nP ) {\ + Base::Insert( (const VoidPtr*)pE, nL, nP );\ + }\ + void Replace( const AERef aE, USHORT nP ) {\ + Base::Replace( (const VPRef)aE, nP );\ + }\ + void Replace( const AE *pE, USHORT nL, USHORT nP ) {\ + Base::Replace( (const VoidPtr*)pE, nL, nP );\ + }\ + void Remove( USHORT nP, USHORT nL = 1) {\ + Base::Remove(nP,nL);\ + }\ + const AE* GetData() const {\ + return (const AE*)Base::GetData();\ + }\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, (FnForEach_##Base)fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, (FnForEach_##Base)fnForEach, pArgs );\ + }\ + AE operator[]( USHORT nP )const { \ + return (AE)Base::operator[](nP); }\ + AE GetObject(USHORT nP) const { \ + return (AE)Base::GetObject(nP); }\ + \ + USHORT GetPos( const AERef aE ) const { \ + return Base::GetPos((const VPRef)aE);\ + }\ + void DeleteAndDestroy( USHORT nP, USHORT nL=1 );\ +private:\ + nm( const nm& );\ + nm& operator=( const nm& );\ +}; + +#define SV_DECL_PTRARR(nm, AE, IS, GS )\ +SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, ) +#define SV_DECL_PTRARR_PLAIN(nm, AE, IS, GS )\ +SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarrPlain, AE, VoidPtr, ) + +#define SV_DECL_PTRARR_VISIBILITY(nm, AE, IS, GS, vis )\ +SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, vis ) +#define SV_DECL_PTRARR_PLAIN_VISIBILITY(nm, AE, IS, GS, vis )\ +SV_DECL_PTRARR_GEN(nm, AE, IS, GS, SvPtrarrPlain, AE, VoidPtr, vis ) + +#define SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, Base, AERef, VPRef, vis )\ +typedef BOOL (*FnForEach_##nm)( const AERef, void* );\ +class vis nm: public Base \ +{\ +public:\ + nm( USHORT nIni=IS, BYTE nG=GS )\ + : Base(nIni,nG) {}\ + ~nm() { DeleteAndDestroy( 0, Count() ); }\ + void Insert( const nm *pI, USHORT nP, \ + USHORT nS = 0, USHORT nE = USHRT_MAX ) {\ + Base::Insert((const Base*)pI, nP, nS, nE);\ + }\ + void Insert( const AERef aE, USHORT nP ) {\ + Base::Insert((const VPRef)aE, nP );\ + }\ + void Insert( const AE *pE, USHORT nL, USHORT nP ) {\ + Base::Insert( (const VoidPtr *)pE, nL, nP );\ + }\ + void Replace( const AERef aE, USHORT nP ) {\ + Base::Replace( (const VPRef)aE, nP );\ + }\ + void Replace( const AE *pE, USHORT nL, USHORT nP ) {\ + Base::Replace( (const VoidPtr*)pE, nL, nP );\ + }\ + void Remove( USHORT nP, USHORT nL = 1) {\ + Base::Remove(nP,nL);\ + }\ + const AE* GetData() const {\ + return (const AE*)Base::GetData();\ + }\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, (FnForEach_##Base)fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, (FnForEach_##Base)fnForEach, pArgs );\ + }\ + AE operator[]( USHORT nP )const { \ + return (AE)Base::operator[](nP); }\ + AE GetObject( USHORT nP )const { \ + return (AE)Base::GetObject(nP); }\ + \ + USHORT GetPos( const AERef aE ) const { \ + return Base::GetPos((const VPRef)aE);\ + } \ + void DeleteAndDestroy( USHORT nP, USHORT nL=1 );\ +private:\ + nm( const nm& );\ + nm& operator=( const nm& );\ +}; + +#define SV_DECL_PTRARR_DEL(nm, AE, IS, GS )\ +SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, ) +#define SV_DECL_PTRARR_DEL_PLAIN(nm, AE, IS, GS )\ +SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarrPlain, AE, VoidPtr, ) + +#define SV_DECL_PTRARR_DEL_VISIBILITY(nm, AE, IS, GS, vis )\ +SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarr, AE &, VoidPtr &, vis) +#define SV_DECL_PTRARR_DEL_PLAIN_VISIBILITY(nm, AE, IS, GS, vis )\ +SV_DECL_PTRARR_DEL_GEN(nm, AE, IS, GS, SvPtrarrPlain, AE, VoidPtr, vis) + +#define SV_IMPL_PTRARR_GEN(nm, AE, Base)\ +void nm::DeleteAndDestroy( USHORT nP, USHORT nL )\ +{ \ + if( nL ) {\ + DBG_ASSERT( nP < nA && nP + nL <= nA,"Del");\ + for( USHORT n=nP; n < nP + nL; n++ ) \ + delete *((AE*)pData+n); \ + Base::Remove( nP, nL ); \ + } \ +} + +#define SV_IMPL_PTRARR(nm, AE )\ +SV_IMPL_PTRARR_GEN(nm, AE, SvPtrarr ) +#define SV_IMPL_PTRARR_PLAIN(nm, AE )\ +SV_IMPL_PTRARR_GEN(nm, AE, SvPtrarrPlain ) + +typedef void* VoidPtr; +_SV_DECL_PTRARR_DEF( SvPtrarr, VoidPtr, 0, 1, SVL_DLLPUBLIC ) +_SV_DECL_PTRARR_DEF_PLAIN( SvPtrarrPlain, VoidPtr, 0, 1, SVL_DLLPUBLIC ) + +// SORTARR - Begin + +#ifdef __MWERKS__ +#define __MWERKS__PRIVATE public +#else +#define __MWERKS__PRIVATE private +#endif + +#define _SORT_CLASS_DEF(nm, AE, IS, GS, vis)\ +typedef BOOL (*FnForEach_##nm)( const AE&, void* );\ +class vis nm : __MWERKS__PRIVATE nm##_SAR \ +{\ +public:\ + nm(USHORT nSize = IS, BYTE nG = GS)\ + : nm##_SAR(nSize,nG) {}\ + void Insert( const nm *pI, USHORT nS=0, USHORT nE=USHRT_MAX );\ + BOOL Insert( const AE& aE );\ + BOOL Insert( const AE& aE, USHORT& rP );\ + void Insert( const AE *pE, USHORT nL );\ + void Remove( USHORT nP, USHORT nL = 1 );\ + void Remove( const AE& aE, USHORT nL = 1 );\ + USHORT Count() const { return nm##_SAR::Count(); }\ + const AE* GetData() const { return (const AE*)pData; }\ +\ +/* Das Ende stehe im DECL-Makro !!! */ + +#define _SV_SEEK_PTR(nm,AE)\ +BOOL nm::Seek_Entry( const AE aE, USHORT* pP ) const\ +{\ + register USHORT nO = nm##_SAR::Count(),\ + nM, \ + nU = 0;\ + if( nO > 0 )\ + {\ + nO--;\ + register long rCmp = (long)aE;\ + while( nU <= nO )\ + {\ + nM = nU + ( nO - nU ) / 2;\ + if( (long)*(pData + nM) == rCmp )\ + {\ + if( pP ) *pP = nM;\ + return TRUE;\ + }\ + else if( (long)*(pData+ nM) < (long)aE )\ + nU = nM + 1;\ + else if( nM == 0 )\ + {\ + if( pP ) *pP = nU;\ + return FALSE;\ + }\ + else\ + nO = nM - 1;\ + }\ + }\ + if( pP ) *pP = nU;\ + return FALSE;\ +} + +#define _SV_SEEK_PTR_TO_OBJECT( nm,AE )\ +BOOL nm::Seek_Entry( const AE aE, USHORT* pP ) const\ +{\ + register USHORT nO = nm##_SAR::Count(),\ + nM, \ + nU = 0;\ + if( nO > 0 )\ + {\ + nO--;\ + while( nU <= nO )\ + {\ + nM = nU + ( nO - nU ) / 2;\ + if( *(*((AE*)pData + nM)) == *(aE) )\ + {\ + if( pP ) *pP = nM;\ + return TRUE;\ + }\ + else if( *(*((AE*)pData + nM)) < *(aE) )\ + nU = nM + 1;\ + else if( nM == 0 )\ + {\ + if( pP ) *pP = nU;\ + return FALSE;\ + }\ + else\ + nO = nM - 1;\ + }\ + }\ + if( pP ) *pP = nU;\ + return FALSE;\ +} + +#define _SV_SEEK_OBJECT( nm,AE )\ +BOOL nm::Seek_Entry( const AE & aE, USHORT* pP ) const\ +{\ + register USHORT nO = nm##_SAR::Count(),\ + nM, \ + nU = 0;\ + if( nO > 0 )\ + {\ + nO--;\ + while( nU <= nO )\ + {\ + nM = nU + ( nO - nU ) / 2;\ + if( *(pData + nM) == aE )\ + {\ + if( pP ) *pP = nM;\ + return TRUE;\ + }\ + else if( *(pData + nM) < aE )\ + nU = nM + 1;\ + else if( nM == 0 )\ + {\ + if( pP ) *pP = nU;\ + return FALSE;\ + }\ + else\ + nO = nM - 1;\ + }\ + }\ + if( pP ) *pP = nU;\ + return FALSE;\ +} + +#define _SV_IMPL_SORTAR_ALG(nm, AE)\ +void nm::Insert( const nm * pI, USHORT nS, USHORT nE )\ +{\ + if( USHRT_MAX == nE )\ + nE = pI->Count();\ + USHORT nP;\ + const AE * pIArr = pI->GetData();\ + for( ; nS < nE; ++nS )\ + {\ + if( ! Seek_Entry( *(pIArr+nS), &nP) )\ + nm##_SAR::Insert( *(pIArr+nS), nP );\ + if( ++nP >= Count() )\ + {\ + nm##_SAR::Insert( pI, nP, nS+1, nE );\ + nS = nE;\ + }\ + }\ +}\ +\ +BOOL nm::Insert( const AE & aE )\ +{\ + USHORT nP;\ + BOOL bExist;\ + bExist = Seek_Entry( aE, &nP );\ + if( ! bExist )\ + nm##_SAR::Insert( aE, nP );\ + return !bExist;\ +}\ +BOOL nm::Insert( const AE & aE, USHORT& rP )\ +{\ + BOOL bExist;\ + bExist = Seek_Entry( aE, &rP );\ + if( ! bExist )\ + nm##_SAR::Insert( aE, rP );\ + return !bExist;\ +}\ +void nm::Insert( const AE* pE, USHORT nL)\ +{\ + USHORT nP;\ + for( USHORT n = 0; n < nL; ++n )\ + if( ! Seek_Entry( *(pE+n), &nP ))\ + nm##_SAR::Insert( *(pE+n), nP );\ +}\ +void nm::Remove( USHORT nP, USHORT nL )\ +{\ + if( nL )\ + nm##_SAR::Remove( nP, nL);\ +}\ +\ +void nm::Remove( const AE &aE, USHORT nL )\ +{\ + USHORT nP;\ + if( nL && Seek_Entry( aE, &nP ) ) \ + nm##_SAR::Remove( nP, nL);\ +}\ + +#if defined(TCPP) + +#define _SORTARR_BLC_CASTS(nm, AE )\ + BOOL Insert( AE &aE ) {\ + return Insert( (const AE&)aE );\ + }\ + USHORT GetPos( AE& aE ) const { \ + return SvPtrarr::GetPos((const VoidPtr&)aE);\ + }\ + void Remove( AE& aE, USHORT nL = 1 ) { \ + Remove( (const AE&) aE, nL );\ + } + +#else + +#define _SORTARR_BLC_CASTS(nm, AE )\ + USHORT GetPos( const AE& aE ) const { \ + return SvPtrarr::GetPos((const VoidPtr&)aE);\ + } + +#endif + +#define _SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\ +SV_DECL_PTRARR_VISIBILITY(nm##_SAR, AE, IS, GS, vis)\ +_SORT_CLASS_DEF(nm, AE, IS, GS, vis)\ + AE operator[](USHORT nP) const {\ + return nm##_SAR::operator[]( nP );\ + }\ + AE GetObject(USHORT nP) const {\ + return nm##_SAR::GetObject( nP );\ + }\ + BOOL Seek_Entry( const AE aE, USHORT* pP = 0 ) const;\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, (FnForEach_SvPtrarr)fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, (FnForEach_SvPtrarr)fnForEach, pArgs );\ + }\ + void DeleteAndDestroy( USHORT nP, USHORT nL=1 ); \ + _SORTARR_BLC_CASTS(nm, AE )\ +\ +/* Das Ende stehe im DECL-Makro !!! */ + +#define _SV_DECL_PTRARR_SORT(nm, AE, IS, GS, vis)\ +_SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\ +private:\ + nm( const nm& );\ + nm& operator=( const nm& );\ +}; + +#define SV_DECL_PTRARR_SORT(nm, AE, IS, GS)\ +_SV_DECL_PTRARR_SORT(nm, AE, IS, GS, ) + +#define SV_DECL_PTRARR_SORT_VISIBILITY(nm, AE, IS, GS, vis)\ +_SV_DECL_PTRARR_SORT(nm, AE, IS, GS, vis) + + +#define _SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, vis)\ +_SV_DECL_PTRARR_SORT_ALG(nm, AE, IS, GS, vis)\ + ~nm() { DeleteAndDestroy( 0, Count() ); }\ +private:\ + nm( const nm& );\ + nm& operator=( const nm& );\ +}; + +#define SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS)\ +_SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, ) + +#define SV_DECL_PTRARR_SORT_DEL_VISIBILITY(nm, AE, IS, GS, vis)\ +_SV_DECL_PTRARR_SORT_DEL(nm, AE, IS, GS, vis) + +#define _SV_DECL_VARARR_SORT(nm, AE, IS, GS, vis)\ +SV_DECL_VARARR_VISIBILITY(nm##_SAR, AE, IS, GS, vis)\ +_SORT_CLASS_DEF(nm, AE, IS, GS, vis) \ + const AE& operator[](USHORT nP) const {\ + return nm##_SAR::operator[]( nP );\ + }\ + const AE& GetObject(USHORT nP) const {\ + return nm##_SAR::GetObject( nP );\ + }\ + BOOL Seek_Entry( const AE & aE, USHORT* pP = 0 ) const;\ + void ForEach( CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( 0, nA, (FnForEach_##nm##_SAR)fnForEach, pArgs );\ + }\ + void ForEach( USHORT nS, USHORT nE, \ + CONCAT( FnForEach_, nm ) fnForEach, void* pArgs = 0 )\ + {\ + _ForEach( nS, nE, (FnForEach_##nm##_SAR)fnForEach, pArgs );\ + }\ +private:\ + nm( const nm& );\ + nm& operator=( const nm& );\ +}; + +#define SV_DECL_VARARR_SORT(nm, AE, IS, GS)\ +_SV_DECL_VARARR_SORT(nm, AE, IS, GS,) + +#define SV_DECL_VARARR_SORT_VISIBILITY(nm, AE, IS, GS, vis)\ +_SV_DECL_VARARR_SORT(nm, AE, IS, GS, vis) + +#define SV_IMPL_PTRARR_SORT( nm,AE )\ +_SV_IMPL_SORTAR_ALG( nm,AE )\ + void nm::DeleteAndDestroy( USHORT nP, USHORT nL ) { \ + if( nL ) {\ + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );\ + for( USHORT n=nP; n < nP + nL; n++ ) \ + delete *((AE*)pData+n); \ + SvPtrarr::Remove( nP, nL ); \ + } \ + } \ +_SV_SEEK_PTR( nm, AE ) + +#define SV_IMPL_OP_PTRARR_SORT( nm,AE )\ +_SV_IMPL_SORTAR_ALG( nm,AE )\ + void nm::DeleteAndDestroy( USHORT nP, USHORT nL ) { \ + if( nL ) {\ + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" );\ + for( USHORT n=nP; n < nP + nL; n++ ) \ + delete *((AE*)pData+n); \ + SvPtrarr::Remove( nP, nL ); \ + } \ + } \ +_SV_SEEK_PTR_TO_OBJECT( nm,AE ) + +#define SV_IMPL_VARARR_SORT( nm,AE )\ +SV_IMPL_VARARR(nm##_SAR, AE)\ +_SV_IMPL_SORTAR_ALG( nm,AE )\ +_SV_SEEK_OBJECT( nm,AE ) + +#define SV_DECL_PTRARR_STACK(nm, AE, IS, GS)\ +class nm: private SvPtrarr \ +{\ +public:\ + nm( USHORT nIni=IS, BYTE nG=GS )\ + : SvPtrarr(nIni,nG) {}\ + void Insert( const nm *pI, USHORT nP,\ + USHORT nS = 0, USHORT nE = USHRT_MAX ) {\ + SvPtrarr::Insert( pI, nP, nS, nE ); \ + }\ + void Remove( USHORT nP, USHORT nL = 1 ) {\ + SvPtrarr::Remove( nP, nL ); \ + }\ + void Push( const AE &aE ) {\ + SvPtrarr::Insert( (const VoidPtr &)aE, SvPtrarr::Count() );\ + }\ + USHORT Count() const { return SvPtrarr::Count(); }\ + AE operator[](USHORT nP) const {\ + return (AE)SvPtrarr::operator[]( nP );\ + }\ + AE GetObject(USHORT nP) const {\ + return (AE)SvPtrarr::GetObject( nP );\ + }\ + AE Pop(){\ + AE pRet = 0;\ + if( SvPtrarr::Count() ){\ + pRet = GetObject( SvPtrarr::Count()-1 );\ + SvPtrarr::Remove(Count()-1);\ + }\ + return pRet;\ + }\ + AE Top() const {\ + AE pRet = 0;\ + if( SvPtrarr::Count() )\ + pRet = GetObject( SvPtrarr::Count()-1 ); \ + return pRet;\ + }\ +}; + +#if defined (C40) || defined (C41) || defined (C42) || defined(C50) || defined(C52) +#define C40_INSERT( c, p, n) Insert( (c const *) p, n ) +#define C40_PUSH( c, p) Push( (c const *) p ) +#define C40_PTR_INSERT( c, p) Insert( (c const *) p ) +#define C40_REMOVE( c, p ) Remove( (c const *) p ) +#define C40_REPLACE( c, p, n) Replace( (c const *) p, n ) +#define C40_PTR_REPLACE( c, p) Replace( (c const *) p ) +#define C40_GETPOS( c, r) GetPos( (c const *)r ) +#else +#if defined WTC || defined ICC || defined HPUX || (defined GCC && __GNUC__ >= 3) || (defined(WNT) && _MSC_VER >= 1400) +#define C40_INSERT( c, p, n ) Insert( (c const *&) p, n ) +#define C40_PUSH( c, p) Push( (c const *&) p ) +#define C40_PTR_INSERT( c, p ) Insert( (c const *&) p ) +#define C40_REMOVE( c, p ) Remove( (c const *&) p ) +#define C40_REPLACE( c, p, n ) Replace( (c const *&) p, n ) +#define C40_PTR_REPLACE( c, p ) Replace( (c const *&) p ) +#define C40_GETPOS( c, r) GetPos( (c const *&) r ) +#else +#define C40_INSERT( c, p, n ) Insert( p, n ) +#define C40_PUSH( c, p) Push( p ) +#define C40_PTR_INSERT( c, p ) Insert( p ) +#define C40_REMOVE( c, p) Remove( p ) +#define C40_REPLACE( c, p, n ) Replace( p, n ) +#define C40_PTR_REPLACE( c, p ) Replace( p ) +#define C40_GETPOS( c, r) GetPos( r ) +#endif +#endif + +#endif //_SVARRAY_HXX diff --git a/svl/inc/svl/svdde.hxx b/svl/inc/svl/svdde.hxx new file mode 100644 index 000000000000..96a1ffa6bf22 --- /dev/null +++ b/svl/inc/svl/svdde.hxx @@ -0,0 +1,483 @@ +/************************************************************************* + * + * 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: svdde.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVDDE_HXX +#define _SVDDE_HXX + +#include "svl/svldllapi.h" +#include <sot/exchange.hxx> +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <tools/link.hxx> + +class DdeString; +class DdeData; +class DdeConnection; +class DdeTransaction; +class DdeLink; +class DdeRequest; +class DdeWarmLink; +class DdeHotLink; +class DdePoke; +class DdeExecute; +class DdeItem; +class DdeTopic; +class DdeService; +class ConvList; +struct DdeDataImp; +struct DdeImp; +class DdeItemImp; + +#ifndef _SVDDE_NOLISTS +DECLARE_LIST( DdeConnections, DdeConnection* ) +DECLARE_LIST( DdeServices, DdeService* ) +DECLARE_LIST( DdeTopics, DdeTopic* ) +DECLARE_LIST( DdeItems, DdeItem* ) +#else +typedef List DdeConnections; +typedef List DdeServices; +typedef List DdeTopics; +typedef List DdeItems; +#endif + +//#if 0 // _SOLAR__PRIVATE +DECLARE_LIST( DdeTransactions, DdeTransaction* ) +DECLARE_LIST( DdeFormats, long ) +//#else +//typedef List DdeTransactions; +//typedef List DdeFormats; +//#endif + +#ifndef STRING_LIST +#define STRING_LIST +DECLARE_LIST( StringList, String * ) +#endif + +// ----------- +// - DdeData - +// ----------- + +class SVL_DLLPUBLIC DdeData +{ + friend class DdeInternal; + friend class DdeService; + friend class DdeConnection; + friend class DdeTransaction; + DdeDataImp* pImp; + +//#if 0 // _SOLAR__PRIVATE + SVL_DLLPRIVATE void Lock(); +//#endif + void SetFormat( ULONG nFmt ); + +public: + DdeData(); + DdeData( const void*, long, ULONG = FORMAT_STRING ); + DdeData( const String& ); + DdeData( const DdeData& ); + ~DdeData(); + + operator const void*() const; + operator long() const; + + ULONG GetFormat() const; + + DdeData& operator = ( const DdeData& ); + + static ULONG GetExternalFormat( ULONG nFmt ); + static ULONG GetInternalFormat( ULONG nFmt ); +}; +// ------------------ +// - DdeServiceList - +// ------------------ + +class DdeServiceList +{ + StringList aServices; + +public: + DdeServiceList( const String* = NULL ); + ~DdeServiceList(); + + StringList& GetServices() { return aServices; } + +private: + DdeServiceList( const DdeServiceList& ); + const DdeServiceList& operator= ( const DdeServiceList& ); +}; + +// ---------------- +// - DdeTopicList - +// ---------------- + +class DdeTopicList +{ + StringList aTopics; + +//#if 0 // _SOLAR__PRIVATE + DECL_LINK( Data, DdeData* ); +//#endif +public: + DdeTopicList( const String& ); + ~DdeTopicList(); + + StringList& GetTopics() { return aTopics; } +}; + +// ------------------ +// - DdeTransaction - +// ------------------ + +class SVL_DLLPUBLIC DdeTransaction +{ +public: + virtual void Data( const DdeData* ); + virtual void Done( BOOL bDataValid ); +protected: + DdeConnection& rDde; + DdeData aDdeData; + DdeString* pName; + short nType; + long nId; + long nTime; + Link aData; + Link aDone; + BOOL bBusy; + + DdeTransaction( DdeConnection&, const String&, long = 0 ); + +public: + virtual ~DdeTransaction(); + + BOOL IsBusy() { return bBusy; } + const String& GetName() const; + + void Execute(); + + void SetDataHdl( const Link& rLink ) { aData = rLink; } + const Link& GetDataHdl() const { return aData; } + + void SetDoneHdl( const Link& rLink ) { aDone = rLink; } + const Link& GetDoneHdl() const { return aDone; } + + void SetFormat( ULONG nFmt ) { aDdeData.SetFormat( nFmt ); } + ULONG GetFormat() const { return aDdeData.GetFormat(); } + + long GetError(); + +private: + friend class DdeInternal; + friend class DdeConnection; + + DdeTransaction( const DdeTransaction& ); + const DdeTransaction& operator= ( const DdeTransaction& ); + +}; + +// ----------- +// - DdeLink - +// ----------- + +class SVL_DLLPUBLIC DdeLink : public DdeTransaction +{ + Link aNotify; + +public: + DdeLink( DdeConnection&, const String&, long = 0 ); + virtual ~DdeLink(); + + void SetNotifyHdl( const Link& rLink ) { aNotify = rLink; } + const Link& GetNotifyHdl() const { return aNotify; } + virtual void Notify(); +}; + +// --------------- +// - DdeWarmLink - +// --------------- + +class SVL_DLLPUBLIC DdeWarmLink : public DdeLink +{ +public: + DdeWarmLink( DdeConnection&, const String&, long = 0 ); +}; + +// -------------- +// - DdeHotLink - +// -------------- + +class SVL_DLLPUBLIC DdeHotLink : public DdeLink +{ +public: + DdeHotLink( DdeConnection&, const String&, long = 0 ); +}; + +// -------------- +// - DdeRequest - +// -------------- + +class SVL_DLLPUBLIC DdeRequest : public DdeTransaction +{ +public: + DdeRequest( DdeConnection&, const String&, long = 0 ); +}; + +// ----------- +// - DdePoke - +// ----------- + +class SVL_DLLPUBLIC DdePoke : public DdeTransaction +{ +public: + DdePoke( DdeConnection&, const String&, const char*, long, + ULONG = FORMAT_STRING, long = 0 ); + DdePoke( DdeConnection&, const String&, const DdeData&, long = 0 ); + DdePoke( DdeConnection&, const String&, const String&, long = 0 ); +}; + +// -------------- +// - DdeExecute - +// -------------- + +class SVL_DLLPUBLIC DdeExecute : public DdeTransaction +{ +public: + DdeExecute( DdeConnection&, const String&, long = 0 ); +}; + +// ----------------- +// - DdeConnection - +// ----------------- + +class SVL_DLLPUBLIC DdeConnection +{ + friend class DdeInternal; + friend class DdeTransaction; + DdeTransactions aTransactions; + DdeString* pService; + DdeString* pTopic; + DdeImp* pImp; + +public: + DdeConnection( const String&, const String& ); + ~DdeConnection(); + + long GetError(); + long GetConvId(); + + static const DdeConnections& GetConnections(); + + BOOL IsConnected(); + + const String& GetServiceName(); + const String& GetTopicName(); + +private: + DdeConnection( const DdeConnection& ); + const DdeConnection& operator= ( const DdeConnection& ); +}; + +// ----------- +// - DdeItem - +// ----------- + +class SVL_DLLPUBLIC DdeItem +{ + friend class DdeInternal; + friend class DdeTopic; + DdeString* pName; + DdeTopic* pMyTopic; + DdeItemImp* pImpData; + + void IncMonitor( ULONG ); + void DecMonitor( ULONG ); + +protected: + BYTE nType; + +public: + DdeItem( const sal_Unicode* ); + DdeItem( const String& ); + DdeItem( const DdeItem& ); + virtual ~DdeItem(); + + const String& GetName() const; + short GetLinks(); + void NotifyClient(); +}; + +// ----------- +// - DdeItem - +// ----------- + +class SVL_DLLPUBLIC DdeGetPutItem : public DdeItem +{ +public: + DdeGetPutItem( const sal_Unicode* p ); + DdeGetPutItem( const String& rStr ); + DdeGetPutItem( const DdeItem& rItem ); + + virtual DdeData* Get( ULONG ); + virtual BOOL Put( const DdeData* ); + virtual void AdviseLoop( BOOL ); // AdviseLoop starten/stoppen +}; + +// ------------ +// - DdeTopic - +// ------------ + +class SVL_DLLPUBLIC DdeTopic +{ + SVL_DLLPRIVATE void _Disconnect( long ); + +public: + virtual void Connect( long ); + virtual void Disconnect( long ); + virtual DdeData* Get( ULONG ); + virtual BOOL Put( const DdeData* ); + virtual BOOL Execute( const String* ); + // evt. ein neues anlegen; return 0 -> es konnte nicht angelegt werden + virtual BOOL MakeItem( const String& rItem ); + + // es wird ein Warm-/Hot-Link eingerichtet. Return-Wert + // besagt ob es geklappt hat + virtual BOOL StartAdviseLoop(); + virtual BOOL StopAdviseLoop(); + +private: + friend class DdeInternal; + friend class DdeService; + friend class DdeItem; + +private: + DdeString* pName; + String aItem; + DdeItems aItems; + Link aConnectLink; + Link aDisconnectLink; + Link aGetLink; + Link aPutLink; + Link aExecLink; + +public: + DdeTopic( const String& ); + virtual ~DdeTopic(); + + const String& GetName() const; + long GetConvId(); + + void SetConnectHdl( const Link& rLink ) { aConnectLink = rLink; } + const Link& GetConnectHdl() const { return aConnectLink; } + void SetDisconnectHdl( const Link& rLink ) { aDisconnectLink = rLink; } + const Link& GetDisconnectHdl() const { return aDisconnectLink; } + void SetGetHdl( const Link& rLink ) { aGetLink = rLink; } + const Link& GetGetHdl() const { return aGetLink; } + void SetPutHdl( const Link& rLink ) { aPutLink = rLink; } + const Link& GetPutHdl() const { return aPutLink; } + void SetExecuteHdl( const Link& rLink ) { aExecLink = rLink; } + const Link& GetExecuteHdl() const { return aExecLink; } + + void NotifyClient( const String& ); + BOOL IsSystemTopic(); + + void InsertItem( DdeItem* ); // fuer eigene Ableitungen! + DdeItem* AddItem( const DdeItem& ); // werden kopiert ! + void RemoveItem( const DdeItem& ); + const String& GetCurItem() { return aItem; } + const DdeItems& GetItems() { return aItems; } + +private: + DdeTopic( const DdeTopic& ); + const DdeTopic& operator= ( const DdeTopic& ); +}; + +// -------------- +// - DdeService - +// -------------- + +class SVL_DLLPUBLIC DdeService +{ + friend class DdeInternal; + +public: + virtual BOOL IsBusy(); + virtual String GetHelp(); + // evt. ein neues anlegen; return 0 -> es konnte nicht angelegt werden + virtual BOOL MakeTopic( const String& rItem ); + +protected: + virtual String Topics(); + virtual String Formats(); + virtual String SysItems(); + virtual String Status(); + virtual String SysTopicGet( const String& ); + virtual BOOL SysTopicExecute( const String* ); + + const DdeTopic* GetSysTopic() const { return pSysTopic; } +private: + DdeTopics aTopics; + DdeFormats aFormats; + DdeTopic* pSysTopic; + DdeString* pName; + ConvList* pConv; + short nStatus; + + SVL_DLLPRIVATE BOOL HasCbFormat( USHORT ); + +public: + DdeService( const String& ); + virtual ~DdeService(); + + const String& GetName() const; + short GetError() { return nStatus; } + + static DdeServices& GetServices(); + DdeTopics& GetTopics() { return aTopics; } + + void AddTopic( const DdeTopic& ); + void RemoveTopic( const DdeTopic& ); + + void AddFormat( ULONG ); + void RemoveFormat( ULONG ); + BOOL HasFormat( ULONG ); + +private: + // DdeService( const DdeService& ); + //int operator= ( const DdeService& ); +}; + +// ------------------ +// - DdeTransaction - +// ------------------ + +inline long DdeTransaction::GetError() +{ + return rDde.GetError(); +} +#endif // _SVDDE_HXX diff --git a/svl/inc/svl/svldata.hxx b/svl/inc/svl/svldata.hxx new file mode 100644 index 000000000000..468e6025cb5a --- /dev/null +++ b/svl/inc/svl/svldata.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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: svldata.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVL_SVLDATA_HXX +#define _SVL_SVLDATA_HXX + +#include <tools/simplerm.hxx> + +class SfxItemPool; + +//============================================================================ +class ImpSvlData +{ +public: + const SfxItemPool * pStoringPool; + void* m_pThreadsafeRMs; + // one SimpleResMgr for each language for which a resource was requested + // (When using the 'non-simple' resmgr, the first request for any language wins, any + // further request for any other language supply the resmgr of the first call. + // For the simple resmgr we have a mgr for each language ever requested). + +private: + ImpSvlData(): + pStoringPool(0), m_pThreadsafeRMs(NULL) + {} + + ~ImpSvlData(); + +public: + SimpleResMgr * GetSimpleRM(const ::com::sun::star::lang::Locale& rLocale); + static ImpSvlData & GetSvlData(); +}; + +//============================================================================ +class SvtSimpleResId +{ + String m_sValue; + +public: + SvtSimpleResId(USHORT nId, const ::com::sun::star::lang::Locale aLocale) : m_sValue(ImpSvlData::GetSvlData().GetSimpleRM(aLocale)->ReadString(nId)) { }; + + operator String () const { return m_sValue; } +}; + + + +#endif // _SVL_SVLDATA_HXX + diff --git a/svl/inc/svl/svldllapi.h b/svl/inc/svl/svldllapi.h new file mode 100644 index 000000000000..29b2ae29100a --- /dev/null +++ b/svl/inc/svl/svldllapi.h @@ -0,0 +1,44 @@ +/************************************************************************* + * + * 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: svldllapi.h,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVLDLLAPI_H +#define INCLUDED_SVLDLLAPI_H + +#include "sal/types.h" + +#if defined(SVL_DLLIMPLEMENTATION) +#define SVL_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define SVL_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif +#define SVL_DLLPRIVATE SAL_DLLPRIVATE + +#endif /* INCLUDED_SVLDLLAPI_H */ + diff --git a/svl/inc/svl/svstdarr.hxx b/svl/inc/svl/svstdarr.hxx new file mode 100644 index 000000000000..869c70e1cac6 --- /dev/null +++ b/svl/inc/svl/svstdarr.hxx @@ -0,0 +1,274 @@ +/************************************************************************* + * + * 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: svstdarr.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if 0 +*********************************************************************** +* +* Die vordefinierte Arrays werden ueber POSITIV-Defines aktiviert: +* (die defines setzen sich aus "_SVSTDARR_" und dem Namen des Array +* ohne "Sv" zusammen) +* +* VarArr: SvBools, SvULongs, SvUShorts, SvLongs, SvShorts +* PtrArr: SvStrings, SvStringsDtor +* SortArr: SvStringsSort, SvStringsSortDtor, +* SvStringsISort, SvStringsISortDtor, +* SvUShortsSort +*********************************************************************** +#endif + +#include "svl/svldllapi.h" +#include <svl/svarray.hxx> + +//#ifdef _SVSTDARR_BOOLS +#ifndef _SVSTDARR_BOOLS_DECL +SV_DECL_VARARR_VISIBILITY( SvBools, BOOL, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BOOLS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTES +#ifndef _SVSTDARR_BYTES_DECL +SV_DECL_VARARR_VISIBILITY( SvBytes, BYTE, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTES_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_ULONGS +#ifndef _SVSTDARR_ULONGS_DECL +SV_DECL_VARARR_VISIBILITY( SvULongs, ULONG, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_ULONGS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_ULONGSSORT +#ifndef _SVSTDARR_ULONGSSORT_DECL +SV_DECL_VARARR_SORT_VISIBILITY( SvULongsSort, ULONG, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_ULONGSSORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_USHORTS +#ifndef _SVSTDARR_USHORTS_DECL +SV_DECL_VARARR_VISIBILITY( SvUShorts, USHORT, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_USHORTS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_USHORTSSORT +#ifndef _SVSTDARR_USHORTSSORT_DECL + +typedef BOOL (*FnForEach_SvUShortsSort)( const USHORT&, void* ); +class SVL_DLLPUBLIC SvUShortsSort : __MWERKS__PRIVATE SvUShorts +{ +public: + SvUShortsSort(BYTE nSize = 1, BYTE nG = 1) + : SvUShorts(nSize,nG) {} + + void Insert( const SvUShortsSort *pI, USHORT nS=0, USHORT nE=USHRT_MAX ); + BOOL Insert( const USHORT aE ); + BOOL Insert( const USHORT aE, USHORT& rP ); + void Insert( const USHORT *pE, USHORT nL ); + // remove ab Pos + void RemoveAt( const USHORT nP, USHORT nL = 1 ); + // remove ab dem Eintrag + void Remove( const USHORT nP, USHORT nL = 1 ); + BOOL Seek_Entry( const USHORT aE, USHORT* pP = 0 ) const; + + USHORT Count() const { return SvUShorts::Count(); } + const USHORT* GetData() const { return (const USHORT*)pData; } + + const USHORT& operator[](USHORT nP) const { + return SvUShorts::operator[]( nP ); + } + const USHORT& GetObject(USHORT nP) const { + return SvUShorts::GetObject( nP ); + } + void ForEach( FnForEach_SvUShortsSort fnForEach, void* pArgs = 0 ) + { + _ForEach( 0, nA, (FnForEach_SvUShorts)fnForEach, pArgs ); + } + void ForEach( USHORT nS, USHORT nE, + FnForEach_SvUShortsSort fnForEach, void* pArgs = 0 ) + { + _ForEach( nS, nE, (FnForEach_SvUShorts)fnForEach, pArgs ); + } +private: + SvUShortsSort( const SvUShortsSort& ); + SvUShortsSort& operator=( const SvUShortsSort& ); +}; + +#define _SVSTDARR_USHORTSSORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_LONGS +#ifndef _SVSTDARR_LONGS_DECL +SV_DECL_VARARR_VISIBILITY( SvLongs, long, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_LONGS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_LONGSSORT +#ifndef _SVSTDARR_LONGSSORT_DECL +SV_DECL_VARARR_SORT_VISIBILITY( SvLongsSort, long, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_LONGSSORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_SHORTS +#ifndef _SVSTDARR_SHORTS_DECL +SV_DECL_VARARR_VISIBILITY( SvShorts, short, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_SHORTS_DECL +#endif +//#endif + +/* + form here all Arrays for Strings, ByteString and then + len of a string (xub_StrLen) +#if (defined(_SVSTDARR_STRINGS) && !defined(_SVSTDARR_STRINGS_DECL)) || \ + (defined(_SVSTDARR_STRINGSDTOR) && !defined(_SVSTDARR_STRINGSDTOR_DECL)) || \ + (defined(_SVSTDARR_STRINGSSORT) && !defined(_SVSTDARR_STRINGSSORT_DECL)) || \ + (defined(_SVSTDARR_STRINGSSORTDTOR) && !defined(_SVSTDARR_STRINGSSORTDTOR_DECL)) || \ + (defined(_SVSTDARR_STRINGSISORT) && !defined(_SVSTDARR_STRINGSISORT_DECL)) || \ + (defined(_SVSTDARR_STRINGSISORTDTOR) && !defined(_SVSTDARR_STRINGSISORTDTOR_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGS) && !defined(_SVSTDARR_BYTESTRINGS_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGSDTOR) && !defined(_SVSTDARR_BYTESTRINGSDTOR_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGSSORT) && !defined(_SVSTDARR_BYTESTRINGSSORT_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGSSORTDTOR) && !defined(_SVSTDARR_BYTESTRINGSSORTDTOR_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGSISORT) && !defined(_SVSTDARR_BYTESTRINGSISORT_DECL)) || \ + (defined(_SVSTDARR_BYTESTRINGSISORTDTOR) && !defined(_SVSTDARR_BYTESTRINGSISORTDTOR_DECL)) || \ + (defined(_SVSTDARR_XUB_STRLEN) && !defined(_SVSTDARR_XUB_STRLEN_DECL)) ||\ + (defined(_SVSTDARR_XUB_STRLENSORT) && !defined(_SVSTDARR_XUB_STRLENSORT_DECL)) +*/ +#include <tools/string.hxx> + +typedef String* StringPtr; +typedef ByteString* ByteStringPtr; + +//#endif + +//#ifdef _SVSTDARR_STRINGS +#ifndef _SVSTDARR_STRINGS_DECL +SV_DECL_PTRARR_VISIBILITY( SvStrings, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_STRINGSDTOR +#ifndef _SVSTDARR_STRINGSDTOR_DECL +SV_DECL_PTRARR_DEL_VISIBILITY( SvStringsDtor, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGSDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_STRINGSSORT +#ifndef _SVSTDARR_STRINGSSORT_DECL +SV_DECL_PTRARR_SORT_VISIBILITY( SvStringsSort, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGSSORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_STRINGSSORTDTOR +#ifndef _SVSTDARR_STRINGSSORTDTOR_DECL +SV_DECL_PTRARR_SORT_DEL_VISIBILITY( SvStringsSortDtor, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGSSORTDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_STRINGSISORT +#ifndef _SVSTDARR_STRINGSISORT_DECL +SV_DECL_PTRARR_SORT_VISIBILITY( SvStringsISort, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGSISORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_STRINGSISORTDTOR +#ifndef _SVSTDARR_STRINGSISORTDTOR_DECL +SV_DECL_PTRARR_SORT_DEL_VISIBILITY( SvStringsISortDtor, StringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_STRINGSISORTDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGS +#ifndef _SVSTDARR_BYTESTRINGS_DECL +SV_DECL_PTRARR_VISIBILITY( SvByteStrings, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGS_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGSDTOR +#ifndef _SVSTDARR_BYTESTRINGSDTOR_DECL +SV_DECL_PTRARR_DEL_VISIBILITY( SvByteStringsDtor, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGSDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGSSORT +#ifndef _SVSTDARR_BYTESTRINGSSORT_DECL +SV_DECL_PTRARR_SORT_VISIBILITY( SvByteStringsSort, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGSSORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGSSORTDTOR +#ifndef _SVSTDARR_BYTESTRINGSSORTDTOR_DECL +SV_DECL_PTRARR_SORT_DEL_VISIBILITY( SvByteStringsSortDtor, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGSSORTDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGSISORT +#ifndef _SVSTDARR_BYTESTRINGSISORT_DECL +SV_DECL_PTRARR_SORT_VISIBILITY( SvByteStringsISort, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGSISORT_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_BYTESTRINGSISORTDTOR +#ifndef _SVSTDARR_BYTESTRINGSISORTDTOR_DECL +SV_DECL_PTRARR_SORT_DEL_VISIBILITY( SvByteStringsISortDtor, ByteStringPtr, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_BYTESTRINGSISORTDTOR_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_XUB_STRLEN +#ifndef _SVSTDARR_XUB_STRLEN_DECL +SV_DECL_VARARR_VISIBILITY( SvXub_StrLens, xub_StrLen, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_XUB_STRLEN_DECL +#endif +//#endif + +//#ifdef _SVSTDARR_XUB_STRLENSORT +#ifndef _SVSTDARR_XUB_STRLENSORT_DECL +SV_DECL_VARARR_SORT_VISIBILITY( SvXub_StrLensSort, xub_StrLen, 1, 1, SVL_DLLPUBLIC ) +#define _SVSTDARR_XUB_STRLENSORT_DECL +#endif +//#endif + diff --git a/svl/inc/svl/svtools.hrc b/svl/inc/svl/svtools.hrc new file mode 100644 index 000000000000..ec3bf093d753 --- /dev/null +++ b/svl/inc/svl/svtools.hrc @@ -0,0 +1,516 @@ +/************************************************************************* + * + * 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: svtools.hrc,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVTOOLS_HRC +#define _SVTOOLS_HRC "$Revision: 1.0" + +#include <vcl/solar.hrc> + +#define RID_SVTOOLS_BITMAP_START (RID_SVTOOLS_START + 0) +#define RID_SVTOOLS_IMAGELIST_START (RID_SVTOOLS_START + 0) + +//............................................................................. +// various unsorted stuff + +#define DLG_EXPORT_PIX (RID_SVTOOLS_START+1) +#define DLG_EXPORT_VEC (RID_SVTOOLS_START+2) +#define DLG_TWAIN_SOURCE (RID_SVTOOLS_START+3) + +#define DLG_SVT_EXPLORERFILE (RID_SVTOOLS_START+4) +#define DLG_SVT_QUERYFOLDERNAME (RID_SVTOOLS_START+5) +#define DLG_SVT_QUERYDELETE (RID_SVTOOLS_START+6) + +#define EXPORT_DIALOG_TITLE (RID_SVTOOLS_START+4) +#define KEY_MODE (RID_SVTOOLS_START+5) +#define KEY_RES (RID_SVTOOLS_START+6) +#define KEY_SIZE (RID_SVTOOLS_START+7) + +#define KEY_COLORS (RID_SVTOOLS_START+9) +#define KEY_RLE_CODING (RID_SVTOOLS_START+10) + +#define STR_SVT_AUTOMATIC_COLOR (RID_SVTOOLS_START+16) + +#define STR_SVT_FILEVIEW_COLUMN_TITLE (RID_SVTOOLS_START + 20) +#define STR_SVT_FILEVIEW_COLUMN_SIZE (RID_SVTOOLS_START + 21) +#define STR_SVT_FILEVIEW_COLUMN_DATE (RID_SVTOOLS_START + 22) +#define STR_SVT_FOLDER (RID_SVTOOLS_START + 23) +#define STR_SVT_FILEVIEW_ERR_MAKEFOLDER (RID_SVTOOLS_START + 24) +#define STR_SVT_BYTES (RID_SVTOOLS_START + 25) +#define STR_SVT_KB (RID_SVTOOLS_START + 26) +#define STR_SVT_MB (RID_SVTOOLS_START + 27) +#define STR_SVT_GB (RID_SVTOOLS_START + 28) +#define STR_FILTERNAME_ALL (RID_SVTOOLS_START + 29) +#define STR_SVT_NEW_FOLDER (RID_SVTOOLS_START + 30) +#define STR_SVT_ALREADYEXISTOVERWRITE (RID_SVTOOLS_START + 31) +#define STR_SVT_FILEVIEW_COLUMN_TYPE (RID_SVTOOLS_START + 32) +#define RID_FILEVIEW_CONTEXTMENU (RID_SVTOOLS_START + 33) +#define RID_FILEOPEN_INVALIDFOLDER (RID_SVTOOLS_START + 34) +#define RID_FILEOPEN_NOTEXISTENTFILE (RID_SVTOOLS_START + 35) +#define STR_SVT_NOREMOVABLEDEVICE (RID_SVTOOLS_START + 36) + +// doc template dialog +#define DLG_DOCTEMPLATE (RID_SVTOOLS_START+50) +#define CTRL_FILEVIEW (RID_SVTOOLS_START+51) +#define STR_SVT_NEWDOC (RID_SVTOOLS_START+52) +#define STR_SVT_MYDOCS (RID_SVTOOLS_START+53) +#define STR_SVT_TEMPLATES (RID_SVTOOLS_START+54) +#define STR_SVT_SAMPLES (RID_SVTOOLS_START+55) +#define TB_SVT_FILEVIEW (RID_SVTOOLS_START+56) +#define TB_SVT_FRAMEWIN (RID_SVTOOLS_START+57) +#define STRARY_SVT_DOCINFO (RID_SVTOOLS_START+58) +#define STR_SVT_NEWDOC_HELP (RID_SVTOOLS_START+63) +#define STR_SVT_MYDOCS_HELP (RID_SVTOOLS_START+64) +#define STR_SVT_TEMPLATES_HELP (RID_SVTOOLS_START+65) +#define STR_SVT_SAMPLES_HELP (RID_SVTOOLS_START+66) + +#define STR_WARNING_ITEM (RID_SVTOOLS_START+90) +#define STR_COLUM_DT_AUTO (RID_SVTOOLS_START+99) + +#define CONFIG_BASIC_FORMAT_START (RID_SVTOOLS_START+102) +#define STR_BASICKEY_FORMAT_ON (RID_SVTOOLS_START+103) +#define STR_BASICKEY_FORMAT_OFF (RID_SVTOOLS_START+104) +#define STR_BASICKEY_FORMAT_YES (RID_SVTOOLS_START+105) +#define STR_BASICKEY_FORMAT_NO (RID_SVTOOLS_START+106) +#define STR_BASICKEY_FORMAT_TRUE (RID_SVTOOLS_START+107) +#define STR_BASICKEY_FORMAT_FALSE (RID_SVTOOLS_START+108) +#define CONFIG_BASIC_FORMAT_END (RID_SVTOOLS_START+109) + +#define STR_INVALIDTRYBUY (RID_SVTOOLS_START+120) +#define STR_OLDTRYBUY (RID_SVTOOLS_START+121) +#define STR_TRYBUY (RID_SVTOOLS_START+122) +#define STR_PVER_LANGUAGECODE (RID_SVTOOLS_START+124) +#define STR_PVER_LONG_LANGUAGECODE (RID_SVTOOLS_START+125) +#define STR_INVALIDPUFF (RID_SVTOOLS_START+126) +#define STR_LIMITEDPUFF (RID_SVTOOLS_START+127) +#define STR_OLDLIMITEDPUFF (RID_SVTOOLS_START+128) +#define RID_REGISTER_DIALOG (RID_SVTOOLS_START+129) +#define STR_BASICKEY_FORMAT_CURRENCY (RID_SVTOOLS_START+130) +#define STR_KEYERR_GENERAL_HELP (RID_SVTOOLS_START+131) +#define STR_KEYERR_INVALID_KEY (RID_SVTOOLS_START+132) +#define STR_KEYERR_INVALID_USERDATA (RID_SVTOOLS_START+133) +#define STR_KEYERR_INVALID_ADDRESSDATA (RID_SVTOOLS_START+134) +#define STR_KEYERR_INVALID_LICENSE (RID_SVTOOLS_START+135) +#define STR_KEYERR_INVALID_LANGUAGE (RID_SVTOOLS_START+136) +#define STR_KEYERR_INVALID_OS (RID_SVTOOLS_START+137) +#define STR_KEYERR_INVALID_NO_CNR (RID_SVTOOLS_START+138) +#define STR_KEYERR_INVALID_CNR (RID_SVTOOLS_START+139) +#define RID_LIMITED_DIALOG (RID_SVTOOLS_START+140) + +#define STR_SVT_MIMETYPE_START (RID_SVTOOLS_START+141) +#define STR_SVT_MIMETYPE_APP_OCTSTREAM (STR_SVT_MIMETYPE_START+0) +#define STR_SVT_MIMETYPE_APP_PDF (STR_SVT_MIMETYPE_START+1) +#define STR_SVT_MIMETYPE_APP_RTF (STR_SVT_MIMETYPE_START+2) +#define STR_SVT_MIMETYPE_APP_MSWORD (STR_SVT_MIMETYPE_START+3) +#define STR_SVT_MIMETYPE_APP_STARCALC (STR_SVT_MIMETYPE_START+4) +#define STR_SVT_MIMETYPE_APP_STARCHART (STR_SVT_MIMETYPE_START+5) +#define STR_SVT_MIMETYPE_APP_STARDRAW (STR_SVT_MIMETYPE_START+6) +#define STR_SVT_MIMETYPE_APP_STARIMAGE (STR_SVT_MIMETYPE_START+7) +#define STR_SVT_MIMETYPE_APP_STARMATH (STR_SVT_MIMETYPE_START+8) +#define STR_SVT_MIMETYPE_APP_STARWRITER (STR_SVT_MIMETYPE_START+9) +#define STR_SVT_MIMETYPE_APP_ZIP (STR_SVT_MIMETYPE_START+10) +#define STR_SVT_MIMETYPE_AUDIO_AIFF (STR_SVT_MIMETYPE_START+11) +#define STR_SVT_MIMETYPE_AUDIO_BASIC (STR_SVT_MIMETYPE_START+12) +#define STR_SVT_MIMETYPE_AUDIO_MIDI (STR_SVT_MIMETYPE_START+13) +#define STR_SVT_MIMETYPE_AUDIO_WAV (STR_SVT_MIMETYPE_START+14) +#define STR_SVT_MIMETYPE_IMAGE_GIF (STR_SVT_MIMETYPE_START+15) +#define STR_SVT_MIMETYPE_IMAGE_JPEG (STR_SVT_MIMETYPE_START+16) +#define STR_SVT_MIMETYPE_IMAGE_PCX (STR_SVT_MIMETYPE_START+17) +#define STR_SVT_MIMETYPE_IMAGE_BMP (STR_SVT_MIMETYPE_START+18) +#define STR_SVT_MIMETYPE_TEXT_HTML (STR_SVT_MIMETYPE_START+19) +#define STR_SVT_MIMETYPE_TEXT_PLAIN (STR_SVT_MIMETYPE_START+20) +#define STR_SVT_MIMETYPE_TEXT_URL (STR_SVT_MIMETYPE_START+21) +#define STR_SVT_MIMETYPE_TEXT_VCARD (STR_SVT_MIMETYPE_START+22) +#define STR_SVT_MIMETYPE_VIDEO_VDO (STR_SVT_MIMETYPE_START+23) +#define STR_SVT_MIMETYPE_VIDEO_MSVIDEO (STR_SVT_MIMETYPE_START+24) +#define STR_SVT_MIMETYPE_X_STARMAIL (STR_SVT_MIMETYPE_START+25) +#define STR_SVT_MIMETYPE_X_VRML (STR_SVT_MIMETYPE_START+26) +#define STR_SVT_MIMETYPE_APP_STARHELP (STR_SVT_MIMETYPE_START+27) +#define STR_SVT_MIMETYPE_APP_STARIMPRESS (STR_SVT_MIMETYPE_START+28) +#define STR_SVT_MIMETYPE_APP_SCHED_CMB (STR_SVT_MIMETYPE_START+29) +#define STR_SVT_MIMETYPE_APP_SCHED_EVT (STR_SVT_MIMETYPE_START+30) +#define STR_SVT_MIMETYPE_APP_SCHED_TASK (STR_SVT_MIMETYPE_START+31) +#define STR_SVT_MIMETYPE_APP_SCHED_TVIEW (STR_SVT_MIMETYPE_START+32) + +#define STR_SVT_MIMETYPE_CNT_MSG (STR_SVT_MIMETYPE_START+33) +#define STR_SVT_MIMETYPE_CNT_DOCUMENT (STR_SVT_MIMETYPE_START+34) +#define STR_SVT_MIMETYPE_CNT_POP3BOX (STR_SVT_MIMETYPE_START+35) +#define STR_SVT_MIMETYPE_CNT_IMAPBOX (STR_SVT_MIMETYPE_START+36) +#define STR_SVT_MIMETYPE_CNT_IMAPFLD (STR_SVT_MIMETYPE_START+37) +#define STR_SVT_MIMETYPE_CNT_VIMBOX (STR_SVT_MIMETYPE_START+38) +#define STR_SVT_MIMETYPE_CNT_VIMINBOX (STR_SVT_MIMETYPE_START+39) +#define STR_SVT_MIMETYPE_CNT_BBBOX (STR_SVT_MIMETYPE_START+40) +#define STR_SVT_MIMETYPE_CNT_VIM_BB (STR_SVT_MIMETYPE_START+41) +#define STR_SVT_MIMETYPE_CNT_NEWSBOX (STR_SVT_MIMETYPE_START+42) +#define STR_SVT_MIMETYPE_CNT_NEWSGRP (STR_SVT_MIMETYPE_START+43) +#define STR_SVT_MIMETYPE_CNT_OUTBOX (STR_SVT_MIMETYPE_START+44) +#define STR_SVT_MIMETYPE_CNT_FTPBOX (STR_SVT_MIMETYPE_START+45) +#define STR_SVT_MIMETYPE_CNT_FTPFLD (STR_SVT_MIMETYPE_START+46) +#define STR_SVT_MIMETYPE_CNT_FTPFILE (STR_SVT_MIMETYPE_START+47) +#define STR_SVT_MIMETYPE_CNT_FTPLINK (STR_SVT_MIMETYPE_START+48) +#define STR_SVT_MIMETYPE_CNT_HTTPBOX (STR_SVT_MIMETYPE_START+49) +#define STR_SVT_MIMETYPE_CNT_FSYSBOX (STR_SVT_MIMETYPE_START+50) +#define STR_SVT_MIMETYPE_CNT_FSYSFLD (STR_SVT_MIMETYPE_START+51) +#define STR_SVT_MIMETYPE_CNT_FSYSFILE (STR_SVT_MIMETYPE_START+52) +#define STR_SVT_MIMETYPE_CNT_FSYSURLFILE (STR_SVT_MIMETYPE_START+53) +#define STR_SVT_MIMETYPE_CNT_PUBLBOX (STR_SVT_MIMETYPE_START+54) +#define STR_SVT_MIMETYPE_CNT_SRCHBOX (STR_SVT_MIMETYPE_START+55) +#define STR_SVT_MIMETYPE_CNT_SUBSCRBOX (STR_SVT_MIMETYPE_START+56) +#define STR_SVT_MIMETYPE_CNT_BOOKMARK (STR_SVT_MIMETYPE_START+57) +#define STR_SVT_MIMETYPE_CNT_CDF (STR_SVT_MIMETYPE_START+58) +#define STR_SVT_MIMETYPE_CNT_CDFSUB (STR_SVT_MIMETYPE_START+59) +#define STR_SVT_MIMETYPE_CNT_CDFITEM (STR_SVT_MIMETYPE_START+60) +#define STR_SVT_MIMETYPE_CNT_STARCHANNEL (STR_SVT_MIMETYPE_START+61) +#define STR_SVT_MIMETYPE_CNT_TRASHBOX (STR_SVT_MIMETYPE_START+62) +#define STR_SVT_MIMETYPE_CNT_TRASH (STR_SVT_MIMETYPE_START+63) +#define STR_SVT_MIMETYPE_CNT_REMOV_VOL (STR_SVT_MIMETYPE_START+64) +#define STR_SVT_MIMETYPE_CNT_FIX_VOL (STR_SVT_MIMETYPE_START+65) +#define STR_SVT_MIMETYPE_CNT_REM_VOL (STR_SVT_MIMETYPE_START+66) +#define STR_SVT_MIMETYPE_CNT_RAM_VOL (STR_SVT_MIMETYPE_START+67) +#define STR_SVT_MIMETYPE_CNT_CDROM (STR_SVT_MIMETYPE_START+68) +#define STR_SVT_MIMETYPE_CNT_DISK_35 (STR_SVT_MIMETYPE_START+69) +#define STR_SVT_MIMETYPE_CNT_DISK_525 (STR_SVT_MIMETYPE_START+70) +#define STR_SVT_MIMETYPE_CNT_TAPEDRIVE (STR_SVT_MIMETYPE_START+71) +#define STR_SVT_MIMETYPE_APP_GAL (STR_SVT_MIMETYPE_START+72) +#define STR_SVT_MIMETYPE_APP_GAL_THEME (STR_SVT_MIMETYPE_START+73) +#define STR_SVT_MIMETYPE_CNT_SEPARATOR (STR_SVT_MIMETYPE_START+74) +#define STR_SVT_MIMETYPE_APP_STARW_GLOB (STR_SVT_MIMETYPE_START+75) +#define STR_SVT_MIMETYPE_APP_SDM (STR_SVT_MIMETYPE_START+76) +#define STR_SVT_MIMETYPE_APP_SMD (STR_SVT_MIMETYPE_START+77) +#define STR_SVT_MIMETYPE_APP_STARW_WEB (STR_SVT_MIMETYPE_START+78) +#define STR_SVT_MIMETYPE_SCHEDULE (STR_SVT_MIMETYPE_START+79) +#define STR_SVT_MIMETYPE_SCHEDULE_EVT (STR_SVT_MIMETYPE_START+80) +#define STR_SVT_MIMETYPE_SCHEDULE_TASK (STR_SVT_MIMETYPE_START+81) +#define STR_SVT_MIMETYPE_SCHEDULE_FEVT (STR_SVT_MIMETYPE_START+82) +#define STR_SVT_MIMETYPE_SCHEDULE_FTASK (STR_SVT_MIMETYPE_START+83) +#define STR_SVT_MIMETYPE_FRAMESET (STR_SVT_MIMETYPE_START+84) +#define STR_SVT_MIMETYPE_MACRO (STR_SVT_MIMETYPE_START+85) +#define STR_SVT_MIMETYPE_CNT_SFSYSFOLDER (STR_SVT_MIMETYPE_START+86) +#define STR_SVT_MIMETYPE_CNT_SFSYSFILE (STR_SVT_MIMETYPE_START+87) +#define STR_SVT_MIMETYPE_APP_TEMPLATE (STR_SVT_MIMETYPE_START+88) +#define STR_SVT_MIMETYPE_IMAGE_GENERIC (STR_SVT_MIMETYPE_START+89) +#define STR_SVT_MIMETYPE_APP_MSEXCEL (STR_SVT_MIMETYPE_START+90) +#define STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL (STR_SVT_MIMETYPE_START+91) +#define STR_SVT_MIMETYPE_APP_MSPPOINT (STR_SVT_MIMETYPE_START+92) +#define STR_SVT_MIMETYPE_TEXT_VCALENDAR (STR_SVT_MIMETYPE_START+93) +#define STR_SVT_MIMETYPE_TEXT_ICALENDAR (STR_SVT_MIMETYPE_START+94) +#define STR_SVT_MIMETYPE_TEXT_XMLICALENDAR (STR_SVT_MIMETYPE_START+95) +#define STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP (STR_SVT_MIMETYPE_START+96) +#define STR_SVT_MIMETYPE_INET_MSG_RFC822 (STR_SVT_MIMETYPE_START+97) +#define STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE (STR_SVT_MIMETYPE_START+98) +#define STR_SVT_MIMETYPE_INET_MULTI_DIGEST (STR_SVT_MIMETYPE_START+99) +#define STR_SVT_MIMETYPE_INET_MULTI_PARALLEL (STR_SVT_MIMETYPE_START+100) +#define STR_SVT_MIMETYPE_INET_MULTI_RELATED (STR_SVT_MIMETYPE_START+101) +#define STR_SVT_MIMETYPE_INET_MULTI_MIXED (STR_SVT_MIMETYPE_START+102) +#define STR_SVT_MIMETYPE_APP_IMPRESSPACKED (STR_SVT_MIMETYPE_START+103) +#define STR_SVT_MIMETYPE_APP_JAR (STR_SVT_MIMETYPE_START+104) +#define STR_SVT_MIMETYPE_IMAGE_PNG (STR_SVT_MIMETYPE_START+105) +#define STR_SVT_MIMETYPE_IMAGE_TIFF (STR_SVT_MIMETYPE_START+106) + +#define STR_SVT_MIMETYPE_APP_SXCALC (STR_SVT_MIMETYPE_START+107) +#define STR_SVT_MIMETYPE_APP_SXCHART (STR_SVT_MIMETYPE_START+108) +#define STR_SVT_MIMETYPE_APP_SXDRAW (STR_SVT_MIMETYPE_START+109) +#define STR_SVT_MIMETYPE_APP_SXMATH (STR_SVT_MIMETYPE_START+110) +#define STR_SVT_MIMETYPE_APP_SXWRITER (STR_SVT_MIMETYPE_START+111) +#define STR_SVT_MIMETYPE_APP_SXIMPRESS (STR_SVT_MIMETYPE_START+112) +#define STR_SVT_MIMETYPE_APP_SXGLOBAL (STR_SVT_MIMETYPE_START+113) +#define STR_SVT_MIMETYPE_APP_SXIPACKED (STR_SVT_MIMETYPE_START+114) +#define STR_SVT_MIMETYPE_END (STR_SVT_MIMETYPE_APP_SXIPACKED) + +#define STR_SVT_PRNDLG_START (STR_SVT_MIMETYPE_END+1) +#define DLG_SVT_PRNDLG_PRNSETUPDLG (STR_SVT_PRNDLG_START+0) +#define DLG_SVT_PRNDLG_PRINTDLG (STR_SVT_PRNDLG_START+1) +#define STR_SVT_PRNDLG_READY (STR_SVT_PRNDLG_START+2) +#define STR_SVT_PRNDLG_PAUSED (STR_SVT_PRNDLG_START+3) +#define STR_SVT_PRNDLG_PENDING (STR_SVT_PRNDLG_START+4) +#define STR_SVT_PRNDLG_BUSY (STR_SVT_PRNDLG_START+5) +#define STR_SVT_PRNDLG_INITIALIZING (STR_SVT_PRNDLG_START+6) +#define STR_SVT_PRNDLG_WAITING (STR_SVT_PRNDLG_START+7) +#define STR_SVT_PRNDLG_WARMING_UP (STR_SVT_PRNDLG_START+8) +#define STR_SVT_PRNDLG_PROCESSING (STR_SVT_PRNDLG_START+9) +#define STR_SVT_PRNDLG_PRINTING (STR_SVT_PRNDLG_START+10) +#define STR_SVT_PRNDLG_OFFLINE (STR_SVT_PRNDLG_START+11) +#define STR_SVT_PRNDLG_ERROR (STR_SVT_PRNDLG_START+12) +#define STR_SVT_PRNDLG_SERVER_UNKNOWN (STR_SVT_PRNDLG_START+13) +#define STR_SVT_PRNDLG_PAPER_JAM (STR_SVT_PRNDLG_START+14) +#define STR_SVT_PRNDLG_PAPER_OUT (STR_SVT_PRNDLG_START+15) +#define STR_SVT_PRNDLG_MANUAL_FEED (STR_SVT_PRNDLG_START+16) +#define STR_SVT_PRNDLG_PAPER_PROBLEM (STR_SVT_PRNDLG_START+17) +#define STR_SVT_PRNDLG_IO_ACTIVE (STR_SVT_PRNDLG_START+18) +#define STR_SVT_PRNDLG_OUTPUT_BIN_FULL (STR_SVT_PRNDLG_START+19) +#define STR_SVT_PRNDLG_TONER_LOW (STR_SVT_PRNDLG_START+20) +#define STR_SVT_PRNDLG_NO_TONER (STR_SVT_PRNDLG_START+21) +#define STR_SVT_PRNDLG_PAGE_PUNT (STR_SVT_PRNDLG_START+22) +#define STR_SVT_PRNDLG_USER_INTERVENTION (STR_SVT_PRNDLG_START+23) +#define STR_SVT_PRNDLG_OUT_OF_MEMORY (STR_SVT_PRNDLG_START+24) +#define STR_SVT_PRNDLG_DOOR_OPEN (STR_SVT_PRNDLG_START+25) +#define STR_SVT_PRNDLG_POWER_SAVE (STR_SVT_PRNDLG_START+26) +#define STR_SVT_PRNDLG_DEFPRINTER (STR_SVT_PRNDLG_START+27) +#define STR_SVT_PRNDLG_JOBCOUNT (STR_SVT_PRNDLG_START+28) +#define STR_SVT_PRNDLG_END (RID_IMG_PRNDLG_NOCOLLATE_HC) + +#define STR_SVT_CALENDAR_START (STR_SVT_PRNDLG_END+1) +#define STR_SVT_CALENDAR_DAY (STR_SVT_CALENDAR_START+0) +#define STR_SVT_CALENDAR_WEEK (STR_SVT_CALENDAR_START+1) +#define STR_SVT_CALENDAR_TODAY (STR_SVT_CALENDAR_START+2) +#define STR_SVT_CALENDAR_NONE (STR_SVT_CALENDAR_START+3) +#define STR_SVT_CALENDAR_END (STR_SVT_CALENDAR_NONE) + +#define STR_SVT_PVER_START (STR_SVT_CALENDAR_END+1) +#define STR_SVT_PVER_INTERNAL (STR_SVT_PVER_START+0) +#define STR_SVT_PVER_PERSONAL_DELUXE (STR_SVT_PVER_START+1) +#define STR_SVT_PVER_PERSONAL (STR_SVT_PVER_START+2) +#define STR_SVT_PVER_PROFESSIONAL (STR_SVT_PVER_START+3) +#define STR_SVT_PVER_BUSINESS (STR_SVT_PVER_START+4) +#define STR_SVT_PVER_ENTERPRICE (STR_SVT_PVER_START+5) +#define STR_SVT_PVER_EDUCATION (STR_SVT_PVER_START+6) +#define STR_SVT_PVER_DEMO (STR_SVT_PVER_START+7) +#define STR_SVT_PVER_BETA (STR_SVT_PVER_START+8) +#define STR_SVT_PVER_OEM (STR_SVT_PVER_START+9) +#define STR_SVT_PVER_NOT_REGISTERED (STR_SVT_PVER_START+10) +#define STR_SVT_PVER_PILOT (STR_SVT_PVER_START+11) +#define STR_SVT_PVER_CAMPUS (STR_SVT_PVER_START+12) +#define STR_SVT_PVER_EVALUATION (STR_SVT_PVER_START+13) +#define STR_SVT_PVER_PARTNER (STR_SVT_PVER_START+14) +#define STR_SVT_PVER_SMALLBUSINESS (STR_SVT_PVER_START+15) +#define STR_SVT_PVER_OEM_PROFESSIONAL (STR_SVT_PVER_START+16) +#define STR_SVT_PVER_END (STR_SVT_PVER_OEM_PROFESSIONAL) + +#define STR_SVT_STYLE_START (STR_SVT_PVER_END+1) +#define STR_SVT_STYLE_LIGHT (STR_SVT_STYLE_START+0) +#define STR_SVT_STYLE_LIGHT_ITALIC (STR_SVT_STYLE_START+1) +#define STR_SVT_STYLE_NORMAL (STR_SVT_STYLE_START+2) +#define STR_SVT_STYLE_NORMAL_ITALIC (STR_SVT_STYLE_START+3) +#define STR_SVT_STYLE_BOLD (STR_SVT_STYLE_START+4) +#define STR_SVT_STYLE_BOLD_ITALIC (STR_SVT_STYLE_START+5) +#define STR_SVT_STYLE_BLACK (STR_SVT_STYLE_START+6) +#define STR_SVT_STYLE_BLACK_ITALIC (STR_SVT_STYLE_START+7) +#define STR_SVT_STYLE_END (STR_SVT_STYLE_BLACK_ITALIC) + +#define STR_SVT_FONTMAP_START (STR_SVT_STYLE_END+1) +#define STR_SVT_FONTMAP_BOTH (STR_SVT_FONTMAP_START+0) +#define STR_SVT_FONTMAP_PRINTERONLY (STR_SVT_FONTMAP_START+1) +#define STR_SVT_FONTMAP_SCREENONLY (STR_SVT_FONTMAP_START+2) +#define STR_SVT_FONTMAP_SIZENOTAVAILABLE (STR_SVT_FONTMAP_START+3) +#define STR_SVT_FONTMAP_STYLENOTAVAILABLE (STR_SVT_FONTMAP_START+4) +#define STR_SVT_FONTMAP_NOTAVAILABLE (STR_SVT_FONTMAP_START+5) +#define STR_SVT_FONTMAP_END (STR_SVT_FONTMAP_NOTAVAILABLE) + +#define STR_SVT_ERRORCONTEXT_START (STR_SVT_FONTMAP_END+1) +#define STR_ERR_HDLMESS (STR_SVT_ERRORCONTEXT_START+0) +#define RID_ERRHDL_CLASS (STR_SVT_ERRORCONTEXT_START+1) +#define RID_ERRCTX (STR_SVT_ERRORCONTEXT_START+2) +#define RID_ERRHDL (STR_SVT_ERRORCONTEXT_START+3) +#define STR_SVT_ERRORCONTEXT_END (RID_ERRHDL) + +#define STR_WIZARDDIALOG_START (STR_SVT_ERRORCONTEXT_END + 1) +#define STR_WIZDLG_FINISH (STR_WIZARDDIALOG_START + 0) +#define STR_WIZDLG_NEXT (STR_WIZARDDIALOG_START + 1) +#define STR_WIZDLG_PREVIOUS (STR_WIZARDDIALOG_START + 2) +#define STR_WIZDLG_ROADMAP_TITLE (STR_WIZARDDIALOG_START + 3) +#define STR_WIZARDDIALOG_END (STR_WIZDLG_ROADMAP_TITLE) + +#define STR_SVT_COLLATE_START (STR_WIZARDDIALOG_END+1) +#define STR_SVT_COLLATE_NORMAL (STR_SVT_COLLATE_START+0) +#define STR_SVT_COLLATE_DICTIONARY (STR_SVT_COLLATE_START+1) +#define STR_SVT_COLLATE_PINYIN (STR_SVT_COLLATE_START+2) +#define STR_SVT_COLLATE_STROKE (STR_SVT_COLLATE_START+3) +#define STR_SVT_COLLATE_RADICAL (STR_SVT_COLLATE_START+4) +#define STR_SVT_COLLATE_CHARSET (STR_SVT_COLLATE_START+5) +#define STR_SVT_COLLATE_ZHUYIN (STR_SVT_COLLATE_START+6) +#define STR_SVT_COLLATE_ALPHANUMERIC (STR_SVT_COLLATE_START+7) +#define STR_SVT_COLLATE_UNICODE (STR_SVT_COLLATE_START+8) +#define STR_SVT_COLLATE_PHONEBOOK (STR_SVT_COLLATE_START+9) +#define STR_SVT_COLLATE_PHONETIC_F (STR_SVT_COLLATE_START+10) +#define STR_SVT_COLLATE_PHONETIC_L (STR_SVT_COLLATE_START+11) +#define STR_SVT_COLLATE_END (STR_SVT_COLLATE_PHONETIC_L) + +#define STR_SVT_FILEPICKER_START (STR_SVT_COLLATE_END+1) +#define STR_SVT_FILEPICKER_AUTO_EXTENSION (STR_SVT_FILEPICKER_START+ 0) +#define STR_SVT_FILEPICKER_PASSWORD (STR_SVT_FILEPICKER_START+ 1) +#define STR_SVT_FILEPICKER_FILTER_OPTIONS (STR_SVT_FILEPICKER_START+ 2) +#define STR_SVT_FILEPICKER_READONLY (STR_SVT_FILEPICKER_START+ 3) +#define STR_SVT_FILEPICKER_INSERT_AS_LINK (STR_SVT_FILEPICKER_START+ 4) +#define STR_SVT_FILEPICKER_SHOW_PREVIEW (STR_SVT_FILEPICKER_START+ 5) +#define STR_SVT_FILEPICKER_PLAY (STR_SVT_FILEPICKER_START+ 6) +#define STR_SVT_FILEPICKER_VERSION (STR_SVT_FILEPICKER_START+ 7) +#define STR_SVT_FILEPICKER_TEMPLATES (STR_SVT_FILEPICKER_START+ 8) +#define STR_SVT_FILEPICKER_IMAGE_TEMPLATE (STR_SVT_FILEPICKER_START+ 9) +#define STR_SVT_FILEPICKER_SELECTION (STR_SVT_FILEPICKER_START+10) +#define STR_SVT_FILEPICKER_FILTER_TITLE (STR_SVT_FILEPICKER_START+11) +#define STR_SVT_FOLDERPICKER_DEFAULT_TITLE (STR_SVT_FILEPICKER_START+12) +#define STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION (STR_SVT_FILEPICKER_START+13) +#define STR_SVT_FILEPICKER_END (STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION) + +// String-Ids for accessibility +#define STR_SVT_ACC_BEGIN (STR_SVT_FILEPICKER_END+1) + // FREE + // FREE +#define STR_SVT_ACC_DESC_TABLISTBOX (STR_SVT_ACC_BEGIN+2) +#define STR_SVT_ACC_DESC_FILEVIEW (STR_SVT_ACC_BEGIN+3) +#define STR_SVT_ACC_DESC_FOLDER (STR_SVT_ACC_BEGIN+4) +#define STR_SVT_ACC_DESC_FILE (STR_SVT_ACC_BEGIN+5) +#define STR_SVT_ACC_EMPTY_FIELD (STR_SVT_ACC_BEGIN+6) +#define STR_SVT_ACC_END (STR_SVT_ACC_EMPTY_FIELD) + +#define STR_SVT_INDEXENTRY_START (STR_SVT_ACC_END + 1) +#define STR_SVT_INDEXENTRY_ALPHANUMERIC (STR_SVT_INDEXENTRY_START+0) +#define STR_SVT_INDEXENTRY_DICTIONARY (STR_SVT_INDEXENTRY_START+1) +#define STR_SVT_INDEXENTRY_PINYIN (STR_SVT_INDEXENTRY_START+2) +#define STR_SVT_INDEXENTRY_RADICAL (STR_SVT_INDEXENTRY_START+3) +#define STR_SVT_INDEXENTRY_STROKE (STR_SVT_INDEXENTRY_START+4) +#define STR_SVT_INDEXENTRY_ZHUYIN (STR_SVT_INDEXENTRY_START+5) +#define STR_SVT_INDEXENTRY_PHONETIC_FS (STR_SVT_INDEXENTRY_START+6) +#define STR_SVT_INDEXENTRY_PHONETIC_FC (STR_SVT_INDEXENTRY_START+7) +#define STR_SVT_INDEXENTRY_PHONETIC_LS (STR_SVT_INDEXENTRY_START+8) +#define STR_SVT_INDEXENTRY_PHONETIC_LC (STR_SVT_INDEXENTRY_START+9) +#define STR_SVT_INDEXENTRY_END (STR_SVT_INDEXENTRY_PHONETIC_LC) + +//String - Ids for Java errors, messages +//These strings come from project desktop +//There was no time for translation, therefore the defines needed to +//remain the same. +#define STR_SVT_JAVAERROR_START (STR_SVT_INDEXENTRY_END + 1) +#define STR_QUESTION_JAVADISABLED (STR_SVT_JAVAERROR_START+0) +#define STR_ERROR_JVMCREATIONFAILED (STR_SVT_JAVAERROR_START+1) +#define STR_WARNING_JAVANOTFOUND (STR_SVT_JAVAERROR_START+2) +#define STR_WARNING_INVALIDJAVASETTINGS (STR_SVT_JAVAERROR_START+3) +#define STR_ERROR_RESTARTREQUIRED (STR_SVT_JAVAERROR_START+4) +#define STR_SVT_JAVAERROR_END (STR_ERROR_RESTARTREQUIRED) + +// String array to match UI language names to LanguageType values and vice versa +#define STR_ARR_SVT_LANGUAGE_TABLE_START (STR_SVT_JAVAERROR_END + 1) +#define STR_ARR_SVT_LANGUAGE_TABLE (STR_ARR_SVT_LANGUAGE_TABLE_START + 0) +#define STR_ARR_SVT_LANGUAGE_TABLE_END (STR_ARR_SVT_LANGUAGE_TABLE) + +//............................................................................. +// dialogs + +#define DLG_EXPORT_JPG_START (RID_SVTOOLS_START+110) +#define DLG_EXPORT_JPG (RID_SVTOOLS_START+111) +#define DLG_EXPORT_JPG_END (RID_SVTOOLS_START+112) + +#define DLG_LOGIN (RID_SVTOOLS_START+113) +#define DLG_ADDRESSBOOKSOURCE (RID_SVTOOLS_START+114) + +#define DLG_REGISTRATION_REQUEST (RID_SVTOOLS_START+115) + +#define DLG_EXPORT_EPNG (RID_SVTOOLS_START+116) +//............................................................................. +// bitmaps + +#define BMP_DEMO_FINGER (RID_SVTOOLS_BITMAP_START + 0) +#define BMP_HELP_AGENT_IMAGE (RID_SVTOOLS_BITMAP_START + 1) +#define BMP_HELP_AGENT_CLOSER (RID_SVTOOLS_BITMAP_START + 2) +#define BMP_PLUGIN (RID_SVTOOLS_BITMAP_START + 3) + +//............................................................................. +// image lists + +#define RID_IMG_EXPANDER (RID_SVTOOLS_IMAGELIST_START + 0) +#define RID_SVTOOLS_IMAGELIST_BIG (RID_SVTOOLS_IMAGELIST_START + 1) +#define RID_SVTOOLS_IMAGELIST_SMALL (RID_SVTOOLS_IMAGELIST_START + 2) +#define RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX (RID_SVTOOLS_IMAGELIST_START + 3) +#define RID_SVTOOLS_IMAGELIST_BIG_HIGHCONTRAST (RID_SVTOOLS_IMAGELIST_START + 4) +#define RID_SVTOOLS_IMAGELIST_SMALL_HIGHCONTRAST (RID_SVTOOLS_IMAGELIST_START + 5) +#define RID_SVTOOLS_IMAGELIST_EDITBWSEBOX_H (RID_SVTOOLS_IMAGELIST_START + 6) +#define RID_FILEPICKER_IMAGES (RID_SVTOOLS_IMAGELIST_START + 7) +#define RID_FILEPICKER_IMAGES_HC (RID_SVTOOLS_IMAGELIST_START + 8) + +//............................................................................. +// error boxes +#define ERRBOX_REG_NOSYSBROWSER ( RID_SVTOOLS_START + 0 ) +#define ERRBOX_CHECK_PLZ ( RID_SVTOOLS_START + 11 ) + +// Java message boxes +//These strings come from project desktop +//There was no time for translation, therefore the defines needed to +//remain the same. +#define QBX_JAVADISABLED (RID_SVTOOLS_START+20) +#define ERRORBOX_JVMCREATIONFAILED (RID_SVTOOLS_START+21) +#define WARNINGBOX_JAVANOTFOUND (RID_SVTOOLS_START+22) +#define WARNINGBOX_INVALIDJAVASETTINGS (RID_SVTOOLS_START+23) +#define ERRORBOX_RESTARTREQUIRED (RID_SVTOOLS_START+24) + +//............................................................................. +// images +#define RID_IMG_TREENODE_COLLAPSED (RID_SVTOOLS_START + 0) +#define RID_IMG_TREENODE_EXPANDED (RID_SVTOOLS_START + 1) +#define RID_IMG_TREENODE_COLLAPSED_HC (RID_SVTOOLS_START + 2) +#define RID_IMG_TREENODE_EXPANDED_HC (RID_SVTOOLS_START + 3) + +#define RID_IMG_PRINTERFONT (RID_SVTOOLS_START + 12) +#define RID_IMG_BITMAPFONT (RID_SVTOOLS_START + 13) +#define RID_IMG_SCALABLEFONT (RID_SVTOOLS_START + 14) +#define RID_IMG_PRINTERFONT_HC (RID_SVTOOLS_START + 15) +#define RID_IMG_BITMAPFONT_HC (RID_SVTOOLS_START + 16) +#define RID_IMG_SCALABLEFONT_HC (RID_SVTOOLS_START + 17) + +#define IMG_SVT_FOLDER (RID_SVTOOLS_START + 40) + +#define IMG_SVT_NEWDOC (RID_SVTOOLS_START + 52) +#define IMG_SVT_MYDOCS (RID_SVTOOLS_START + 53) +#define IMG_SVT_TEMPLATES (RID_SVTOOLS_START + 54) +#define IMG_SVT_SAMPLES (RID_SVTOOLS_START + 55) + +#define IMG_SVT_NEWDOC_HC (RID_SVTOOLS_START + 59) +#define IMG_SVT_MYDOCS_HC (RID_SVTOOLS_START + 60) +#define IMG_SVT_TEMPLATES_HC (RID_SVTOOLS_START + 61) +#define IMG_SVT_SAMPLES_HC (RID_SVTOOLS_START + 62) + +#define IMG_SVT_DOCTEMPLATE_BACK_SMALL (RID_SVTOOLS_START + 70) +#define IMG_SVT_DOCTEMPLATE_BACK_LARGE (RID_SVTOOLS_START + 71) +#define IMG_SVT_DOCTEMPLATE_PREV_SMALL (RID_SVTOOLS_START + 72) +#define IMG_SVT_DOCTEMPLATE_PREV_LARGE (RID_SVTOOLS_START + 73) +#define IMG_SVT_DOCTEMPLATE_PRINT_SMALL (RID_SVTOOLS_START + 74) +#define IMG_SVT_DOCTEMPLATE_PRINT_LARGE (RID_SVTOOLS_START + 75) +#define IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL (RID_SVTOOLS_START + 76) +#define IMG_SVT_DOCTEMPLATE_DOCINFO_LARGE (RID_SVTOOLS_START + 77) +#define IMG_SVT_DOCTEMPLATE_PREVIEW_SMALL (RID_SVTOOLS_START + 78) +#define IMG_SVT_DOCTEMPLATE_PREVIEW_LARGE (RID_SVTOOLS_START + 79) + +#define IMG_SVT_DOCTEMPL_HC_BACK_SMALL (RID_SVTOOLS_START + 80) +#define IMG_SVT_DOCTEMPL_HC_BACK_LARGE (RID_SVTOOLS_START + 81) +#define IMG_SVT_DOCTEMPL_HC_PREV_SMALL (RID_SVTOOLS_START + 82) +#define IMG_SVT_DOCTEMPL_HC_PREV_LARGE (RID_SVTOOLS_START + 83) +#define IMG_SVT_DOCTEMPL_HC_PRINT_SMALL (RID_SVTOOLS_START + 84) +#define IMG_SVT_DOCTEMPL_HC_PRINT_LARGE (RID_SVTOOLS_START + 85) +#define IMG_SVT_DOCTEMPL_HC_DOCINFO_SMALL (RID_SVTOOLS_START + 86) +#define IMG_SVT_DOCTEMPL_HC_DOCINFO_LARGE (RID_SVTOOLS_START + 87) +#define IMG_SVT_DOCTEMPL_HC_PREVIEW_SMALL (RID_SVTOOLS_START + 88) +#define IMG_SVT_DOCTEMPL_HC_PREVIEW_LARGE (RID_SVTOOLS_START + 89) + +#define RID_IMG_PRNDLG_COLLATE (STR_SVT_PRNDLG_START + 29) +#define RID_IMG_PRNDLG_NOCOLLATE (STR_SVT_PRNDLG_START + 30) +#define RID_IMG_PRNDLG_COLLATE_HC (STR_SVT_PRNDLG_START + 31) +#define RID_IMG_PRNDLG_NOCOLLATE_HC (STR_SVT_PRNDLG_START + 32) + +#endif // #ifndef _SVTOOLS_HRC + +// ******************************************************************* EOF + diff --git a/svl/inc/svl/szitem.hxx b/svl/inc/svl/szitem.hxx new file mode 100644 index 000000000000..c4b52d4939c0 --- /dev/null +++ b/svl/inc/svl/szitem.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * 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: szitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFXSZITEM_HXX +#define _SFXSZITEM_HXX + +#include <tools/gen.hxx> + +#include <svl/poolitem.hxx> + +class SfxArguments; +class SvStream; + +DBG_NAMEEX(SfxSizeItem) + +// ----------------------------------------------------------------------- + +class SfxSizeItem : public SfxPoolItem +{ +private: + Size aVal; + +public: + TYPEINFO(); + SfxSizeItem(); + SfxSizeItem( USHORT nWhich, const Size& rVal ); + SfxSizeItem( USHORT nWhich, SvStream & ); + SfxSizeItem( const SfxSizeItem& ); + ~SfxSizeItem() { DBG_DTOR(SfxSizeItem, 0); } + + virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString &rText, + const IntlWrapper * = 0 ) const; + + virtual int operator==( const SfxPoolItem& ) const; + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + + virtual SfxPoolItem* Clone( SfxItemPool *pPool = 0 ) const; + virtual SfxPoolItem* Create(SvStream &, USHORT nItemVersion) const; + virtual SvStream& Store(SvStream &, USHORT nItemVersion) const; + + const Size& GetValue() const { return aVal; } + void SetValue( const Size& rNewVal ) { + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + aVal = rNewVal; } +}; + +#endif + diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx new file mode 100644 index 000000000000..354de8b451c7 --- /dev/null +++ b/svl/inc/svl/undo.hxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * 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: undo.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _UNDO_HXX +#define _UNDO_HXX + +#include "svl/svldllapi.h" +#include <tools/rtti.hxx> +#include <tools/string.hxx> +#include <svl/svarray.hxx> + +//==================================================================== + +class SVL_DLLPUBLIC SfxRepeatTarget +{ +public: + TYPEINFO(); + virtual ~SfxRepeatTarget() = 0; +}; + +//==================================================================== + +class SVL_DLLPUBLIC SfxUndoAction +{ + BOOL bLinked; +public: + TYPEINFO(); + SfxUndoAction(); + virtual ~SfxUndoAction(); + + virtual BOOL IsLinked(); + virtual void SetLinked( BOOL bIsLinked = TRUE ); + virtual void Undo(); + virtual void Redo(); + virtual void Repeat(SfxRepeatTarget&); + virtual BOOL CanRepeat(SfxRepeatTarget&) const; + + virtual BOOL Merge( SfxUndoAction *pNextAction ); + + virtual UniString GetComment() const; + virtual UniString GetRepeatComment(SfxRepeatTarget&) const; + virtual USHORT GetId() const; + +private: + SfxUndoAction& operator=( const SfxUndoAction& ); // n.i.!! +}; + +//======================================================================== + +SV_DECL_PTRARR( SfxUndoActions, SfxUndoAction*, 20, 8 ) + +//==================================================================== + +/** do not make use of this implementation details, unless you + really really have to! */ +struct SVL_DLLPUBLIC SfxUndoArray +{ + SfxUndoActions aUndoActions; + USHORT nMaxUndoActions; + USHORT nCurUndoAction; + SfxUndoArray *pFatherUndoArray; + SfxUndoArray(USHORT nMax=0): + nMaxUndoActions(nMax), nCurUndoAction(0), + pFatherUndoArray(0) {} + ~SfxUndoArray(); +}; + +//========================================================================= + +/** do not make use of this implementation details, unless you + really really have to! */ +class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray + +/* [Beschreibung] + + UndoAction zur Klammerung mehrerer Undos in einer UndoAction. + Diese Actions werden vom SfxUndoManager verwendet. Dort + wird mit < SfxUndoManager::EnterListAction > eine Klammerebene + geoeffnet und mit <SfxUndoManager::LeaveListAction > wieder + geschlossen. Redo und Undo auf SfxListUndoActions wirken + Elementweise. + +*/ +{ + public: + TYPEINFO(); + + SfxListUndoAction( const UniString &rComment, + const UniString rRepeatComment, USHORT Id, SfxUndoArray *pFather); + virtual void Undo(); + virtual void Redo(); + virtual void Repeat(SfxRepeatTarget&); + virtual BOOL CanRepeat(SfxRepeatTarget&) const; + + virtual BOOL Merge( SfxUndoAction *pNextAction ); + + virtual UniString GetComment() const; + virtual UniString GetRepeatComment(SfxRepeatTarget&) const; + virtual USHORT GetId() const; + + void SetComment( const UniString& rComment ); + + private: + + USHORT nId; + UniString aComment, aRepeatComment; + +}; + +//========================================================================= + +class SVL_DLLPUBLIC SfxUndoManager +{ + friend class SfxLinkUndoAction; + + SfxUndoArray *pUndoArray; + SfxUndoArray *pActUndoArray; + SfxUndoArray *pFatherUndoArray; + + bool mbUndoEnabled; +public: + SfxUndoManager( USHORT nMaxUndoActionCount = 20 ); + virtual ~SfxUndoManager(); + + virtual void SetMaxUndoActionCount( USHORT nMaxUndoActionCount ); + virtual USHORT GetMaxUndoActionCount() const; + virtual void Clear(); + + virtual void AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg=FALSE ); + + virtual USHORT GetUndoActionCount() const; + virtual USHORT GetUndoActionId(USHORT nNo=0) const; + virtual UniString GetUndoActionComment( USHORT nNo=0 ) const; + /** returns the nNo'th undo action from the top */ + SfxUndoAction* GetUndoAction( USHORT nNo=0 ) const; + + virtual BOOL Undo( USHORT nCount=1 ); + virtual void Undo( SfxUndoAction &rAction ); + + virtual USHORT GetRedoActionCount() const; + virtual USHORT GetRedoActionId(USHORT nNo=0) const; + virtual UniString GetRedoActionComment( USHORT nNo=0 ) const; + + virtual BOOL Redo( USHORT nCount=1 ); + virtual void Redo( SfxUndoAction &rAction ); + virtual void ClearRedo(); + + virtual USHORT GetRepeatActionCount() const; + virtual UniString GetRepeatActionComment( SfxRepeatTarget &rTarget, USHORT nNo = 0) const; + virtual BOOL Repeat( SfxRepeatTarget &rTarget, USHORT nFrom=0, USHORT nCount=1 ); + virtual void Repeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction ); + virtual BOOL CanRepeat( SfxRepeatTarget &rTarget, USHORT nNo = 0 ) const; + virtual BOOL CanRepeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction ) const; + + virtual void EnterListAction(const UniString &rComment, const UniString& rRepeatComment, USHORT nId=0); + virtual void LeaveListAction(); + + /** clears the redo stack and removes the top undo action */ + void RemoveLastUndoAction(); + + // enables (true) or disables (false) recording of undo actions + // If undo actions are added while undo is disabled, they are deleted. + // Disabling undo does not clear the current undo buffer! + void EnableUndo( bool bEnable ); + + // returns true if undo is currently enabled + // This returns false if undo was disabled using EnableUndo( false ) and + // also during the runtime of the Undo() and Redo() methods. + bool IsUndoEnabled() const { return mbUndoEnabled; } +}; + +//========================================================================= + +class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction + +/* [Beschreibung] + + Die SfxLinkUndoAction dient zur Verbindung zweier SfxUndoManager. Die + im ersten SfxUndoManager eingefuegten SfxUndoAction leiten ihr Undo und Redo + an den zweiten weiter, so dass ein Undo und Redo am ersten + SfxUndoManager wie eine am zweiten wirkt. + + Die SfxLinkUndoAction ist nach dem Einfuegen der SfxUndoAction am + zweiten SfxUndoManager einzufuegen. Waehrend der zweite SfxUndoManager + vom ersten ferngesteuert wird, duerfen an ihm weder Actions eingefuegt werden, + noch darf Undo/Redo aufgerufen werden. + +*/ + +{ +public: + TYPEINFO(); + SfxLinkUndoAction(SfxUndoManager *pManager); + ~SfxLinkUndoAction(); + + virtual void Undo(); + virtual void Redo(); + virtual BOOL CanRepeat(SfxRepeatTarget& r) const; + + virtual void Repeat(SfxRepeatTarget&r); + + virtual UniString GetComment() const; + virtual UniString GetRepeatComment(SfxRepeatTarget&r) const; + virtual USHORT GetId() const; + + SfxUndoAction* GetAction() const { return pAction; } + +protected: + SfxUndoManager *pUndoManager; + SfxUndoAction *pAction; + +}; + +#endif diff --git a/svl/inc/svl/urlfilter.hxx b/svl/inc/svl/urlfilter.hxx new file mode 100644 index 000000000000..6370a75a1fd7 --- /dev/null +++ b/svl/inc/svl/urlfilter.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * 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: urlfilter.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_URL_FILTER_HXX +#define SVTOOLS_URL_FILTER_HXX + +#include <tools/string.hxx> +#include <tools/wldcrd.hxx> +#include <functional> +#include <vector> +/** filters allowed URLs +*/ +class IUrlFilter +{ +public: + virtual bool isUrlAllowed( const String& _rURL ) const = 0; + +protected: + virtual inline ~IUrlFilter() = 0; +}; + +inline IUrlFilter::~IUrlFilter() {} + +struct FilterMatch : public ::std::unary_function< bool, WildCard > +{ +private: + const String& m_rCompareString; +public: + FilterMatch( const String& _rCompareString ) : m_rCompareString( _rCompareString ) { } + + bool operator()( const WildCard& _rMatcher ) + { + return _rMatcher.Matches( m_rCompareString ) ? true : false; + } + + static void createWildCardFilterList(const String& _rFilterList,::std::vector< WildCard >& _rFilters); +}; + +#endif // SVTOOLS_URL_FILTER_HXX diff --git a/svl/inc/svl/visitem.hxx b/svl/inc/svl/visitem.hxx new file mode 100644 index 000000000000..1a3918526def --- /dev/null +++ b/svl/inc/svl/visitem.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * 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: visitem.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SFXVISIBILITYITEM_HXX +#define _SFXVISIBILITYITEM_HXX + +#include "svl/svldllapi.h" +#include <tools/debug.hxx> +#include <svl/poolitem.hxx> +#include <com/sun/star/frame/status/Visibility.hpp> + +//============================================================================ +DBG_NAMEEX_VISIBILITY(SfxVisibilityItem, SVL_DLLPUBLIC) + +class SVL_DLLPUBLIC SfxVisibilityItem: public SfxPoolItem +{ + ::com::sun::star::frame::status::Visibility m_nValue; + +public: + TYPEINFO(); + + SfxVisibilityItem(USHORT which = 0, sal_Bool bVisible = sal_True): + SfxPoolItem(which) + { + m_nValue.bVisible = bVisible; + DBG_CTOR(SfxVisibilityItem, 0); + } + + SfxVisibilityItem(USHORT which, SvStream & rStream); + + SfxVisibilityItem(const SfxVisibilityItem & rItem): + SfxPoolItem(rItem), m_nValue(rItem.m_nValue) + { DBG_CTOR(SfxVisibilityItem, 0); } + + virtual ~SfxVisibilityItem() { DBG_DTOR(SfxVisibilityItem, 0); } + + virtual int operator ==(const SfxPoolItem & rItem) const; + + using SfxPoolItem::Compare; + virtual int Compare(const SfxPoolItem & rWith) const; + + virtual SfxItemPresentation GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper * = 0) + const; + + virtual BOOL QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ) const; + + virtual BOOL PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId = 0 ); + + virtual SfxPoolItem * Create(SvStream & rStream, USHORT) const; + + virtual SvStream & Store(SvStream & rStream, USHORT) const; + + virtual SfxPoolItem * Clone(SfxItemPool * = 0) const; + + virtual USHORT GetValueCount() const; + + virtual UniString GetValueTextByVal(BOOL bTheValue) const; + + BOOL GetValue() const { return m_nValue.bVisible; } + + void SetValue(BOOL bVisible) { m_nValue.bVisible = bVisible; } +}; + +#endif // _SFXVISIBILITYITEM_HXX diff --git a/svl/inc/svl/zforlist.hxx b/svl/inc/svl/zforlist.hxx new file mode 100644 index 000000000000..4e653caf0238 --- /dev/null +++ b/svl/inc/svl/zforlist.hxx @@ -0,0 +1,1014 @@ +/************************************************************************* + * + * 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: zforlist.hxx,v $ + * $Revision: 1.3.148.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ZFORLIST_HXX +#define _ZFORLIST_HXX + +#include "svl/svldllapi.h" +#include <tools/string.hxx> +#ifndef _TABLE_HXX //autogen +#include <tools/table.hxx> +#endif +#include <i18npool/lang.h> +#include <svl/svarray.hxx> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/i18n/NumberFormatCode.hpp> +#include <unotools/localedatawrapper.hxx> +#include <svl/ondemand.hxx> +#include <tools/link.hxx> +#include <svl/nfkeytab.hxx> + +#include <map> + +class Date; +class SvStream; +class Color; +class SvUShorts; +class CharClass; +class CalendarWrapper; + +class ImpSvNumberformatScan; +class ImpSvNumberInputScan; +class SvNumberformat; + +namespace com { namespace sun { namespace star { + namespace lang { + class XMultiServiceFactory; + } +}}} + + +#define SV_COUNTRY_LANGUAGE_OFFSET 5000 // Max count of formats per country/language +#define SV_MAX_ANZ_STANDARD_FORMATE 100 // Max count of builtin default formats per CL + +// Format types +#ifndef NUMBERFORMAT_ALL +// also defined in com/sun/star/util/NumberFormat.hpp +//! => put in single .idl file and include here +#define NUMBERFORMAT_ALL 0x000 /// Just for Output of total list, not a real format type +#define NUMBERFORMAT_DEFINED 0x001 /// Format defined by user +#define NUMBERFORMAT_DATE 0x002 /// Number as date +#define NUMBERFORMAT_TIME 0x004 /// Number as time +#define NUMBERFORMAT_CURRENCY 0x008 /// Number as currency +#define NUMBERFORMAT_NUMBER 0x010 /// Any "normal" number format +#define NUMBERFORMAT_SCIENTIFIC 0x020 /// Number as scientific +#define NUMBERFORMAT_FRACTION 0x040 /// Number as fraction +#define NUMBERFORMAT_PERCENT 0x080 /// Number as percent +#define NUMBERFORMAT_TEXT 0x100 /// Text format +#define NUMBERFORMAT_DATETIME 0x006 /// Number as date and time +#define NUMBERFORMAT_LOGICAL 0x400 /// Number as boolean value +#define NUMBERFORMAT_UNDEFINED 0x800 /// Format undefined yet in analyzing +#endif +#define NUMBERFORMAT_ENTRY_NOT_FOUND (sal_uInt32)(0xffffffff) /// MAX_ULONG + + +/** enum values for <method>SvNumberFormatter::GetFormatIndex</method> + + <p> + Builtin standard formats, order should be also the arrangement in the + dialog list box representation.</p> + + <p> + Date specials:<ul> + <li>SYSTEM: As set in System Regional Settings. + <li>SYS: short/long defined, order and separators from System Regional Settings. + <li>DEF: short/long and order defined, separators from System Regional Settings. + <li>DIN: all settings hard coded as DIN (Deutsche Industrie Norm) and EN (European Norm) require. + <li>all other: hard coded + </ul> + */ +enum NfIndexTableOffset +{ + NF_NUMERIC_START = 0, + + NF_NUMBER_START = NF_NUMERIC_START, + NF_NUMBER_STANDARD = NF_NUMBER_START, // Standard/General + NF_NUMBER_INT, // 0 + NF_NUMBER_DEC2, // 0.00 + NF_NUMBER_1000INT, // #,##0 + NF_NUMBER_1000DEC2, // #,##0.00 + NF_NUMBER_SYSTEM, // #,##0.00 or whatever is set in System Regional Settings + NF_NUMBER_END = NF_NUMBER_SYSTEM, + + NF_SCIENTIFIC_START, + NF_SCIENTIFIC_000E000 = NF_SCIENTIFIC_START, // 0.00E+000 + NF_SCIENTIFIC_000E00, // 0.00E+00 + NF_SCIENTIFIC_END = NF_SCIENTIFIC_000E00, + + NF_PERCENT_START, + NF_PERCENT_INT = NF_PERCENT_START, // 0% + NF_PERCENT_DEC2, // 0.00% + NF_PERCENT_END = NF_PERCENT_DEC2, + + NF_FRACTION_START, + NF_FRACTION_1 = NF_FRACTION_START, // # ?/? + NF_FRACTION_2, // # ??/?? + NF_FRACTION_END = NF_FRACTION_2, + + NF_NUMERIC_END = NF_FRACTION_END, + + NF_CURRENCY_START, + NF_CURRENCY_1000INT = NF_CURRENCY_START,// #,##0 DM + NF_CURRENCY_1000DEC2, // #,##0.00 DM + NF_CURRENCY_1000INT_RED, // #,##0 DM negative in red + NF_CURRENCY_1000DEC2_RED, // #,##0.00 DM negative in red + NF_CURRENCY_1000DEC2_CCC, // #,##0.00 DEM currency abbreviation + NF_CURRENCY_1000DEC2_DASHED, // #,##0.-- DM + NF_CURRENCY_END = NF_CURRENCY_1000DEC2_DASHED, + + NF_DATE_START, + NF_DATE_SYSTEM_SHORT = NF_DATE_START, // 08.10.97 + NF_DATE_SYSTEM_LONG, // Wednesday, 8. October 1997 + NF_DATE_SYS_DDMMYY, // 08.10.97 + NF_DATE_SYS_DDMMYYYY, // 08.10.1997 + NF_DATE_SYS_DMMMYY, // 8. Oct 97 + NF_DATE_SYS_DMMMYYYY, // 8. Oct 1997 + NF_DATE_DIN_DMMMYYYY, // 8. Oct. 1997 DIN + NF_DATE_SYS_DMMMMYYYY, // 8. October 1997 + NF_DATE_DIN_DMMMMYYYY, // 8. October 1997 DIN + NF_DATE_SYS_NNDMMMYY, // Wed, 8. Okt 97 + NF_DATE_DEF_NNDDMMMYY, // Wed 08.Okt 97 + NF_DATE_SYS_NNDMMMMYYYY, // Wed, 8. Oktober 1997 + NF_DATE_SYS_NNNNDMMMMYYYY, // Wednesday, 8. Oktober 1997 + NF_DATE_DIN_MMDD, // 10-08 DIN + NF_DATE_DIN_YYMMDD, // 97-10-08 DIN + NF_DATE_DIN_YYYYMMDD, // 1997-10-08 DIN + NF_DATE_SYS_MMYY, // 10.97 + NF_DATE_SYS_DDMMM, // 08.Oct + NF_DATE_MMMM, // October + NF_DATE_QQJJ, // 4. Quarter 97 + NF_DATE_WW, // week of year + NF_DATE_END = NF_DATE_WW, + + NF_TIME_START, + NF_TIME_HHMM = NF_TIME_START, // HH:MM + NF_TIME_HHMMSS, // HH:MM:SS + NF_TIME_HHMMAMPM, // HH:MM AM/PM + NF_TIME_HHMMSSAMPM, // HH:MM:SS AM/PM + NF_TIME_HH_MMSS, // [HH]:MM:SS + NF_TIME_MMSS00, // MM:SS,00 + NF_TIME_HH_MMSS00, // [HH]:MM:SS,00 + NF_TIME_END = NF_TIME_HH_MMSS00, + + NF_DATETIME_START, + NF_DATETIME_SYSTEM_SHORT_HHMM = NF_DATETIME_START, // 08.10.97 01:23 + NF_DATETIME_SYS_DDMMYYYY_HHMMSS, // 08.10.1997 01:23:45 + NF_DATETIME_END = NF_DATETIME_SYS_DDMMYYYY_HHMMSS, + + NF_BOOLEAN, // BOOLEAN + NF_TEXT, // @ + NF_INDEX_TABLE_ENTRIES +}; + + +// #45717# IsNumberFormat( "98-10-24", 30, x ), YMD Format set with DMY +// International settings doesn't recognize the string as a date. +/** enum values for <method>SvNumberFormatter::SetEvalDateFormat</method> + + <p>How <method>ImpSvNumberInputScan::GetDateRef</method> shall take the + DateFormat order (YMD,DMY,MDY) into account, if called from IsNumberFormat + with a date format to match against. + */ +enum NfEvalDateFormat +{ + /** DateFormat only from International, default. */ + NF_EVALDATEFORMAT_INTL, + + /** DateFormat only from date format passed to function (if any). + If no date format is passed then the DateFormat is taken from International. */ + NF_EVALDATEFORMAT_FORMAT, + + /** First try the DateFormat from International. If it doesn't match a + valid date try the DateFormat from the date format passed. */ + NF_EVALDATEFORMAT_INTL_FORMAT, + + /** First try the DateFormat from the date format passed. If it doesn't + match a valid date try the DateFormat from International. */ + NF_EVALDATEFORMAT_FORMAT_INTL +}; + + +//#if 0 // _SOLAR__PRIVATE +#define _ZFORLIST_DECLARE_TABLE +//#endif +#ifdef _ZFORLIST_DECLARE_TABLE +DECLARE_TABLE (SvNumberFormatTable, SvNumberformat*) +DECLARE_TABLE (SvNumberFormatterIndexTable, sal_uInt32*) +#else +typedef Table SvNumberFormatTable; +typedef Table SvNumberFormatterIndexTable; +#endif + +typedef ::std::map< sal_uInt32, sal_uInt32 > SvNumberFormatterMergeMap; + + +/** Language/country dependent currency entries + */ +class SVL_DLLPUBLIC NfCurrencyEntry +{ + String aSymbol; /// currency symbol + String aBankSymbol; /// currency abbreviation + LanguageType eLanguage; /// language/country value + USHORT nPositiveFormat; /// position of symbol + USHORT nNegativeFormat; /// position of symbol and type and position of negative sign + USHORT nDigits; /// count of decimal digits + sal_Unicode cZeroChar; /// which character is used for zeros as last decimal digits + + /// not implemented, prevent usage + NfCurrencyEntry( const NfCurrencyEntry& ); + /// not implemented, prevent usage + NfCurrencyEntry& operator=( const NfCurrencyEntry& ); + +private: + +//#if 0 // _SOLAR__PRIVATE + // nDecimalFormat := 0, 1, 2 + // #,##0 or #,##0.00 or #,##0.-- are assigned + SVL_DLLPRIVATE void Impl_BuildFormatStringNumChars( String&, + const LocaleDataWrapper&, USHORT nDecimalFormat ) const; +//#endif // __PRIVATE + +public: + + NfCurrencyEntry(); + NfCurrencyEntry( const LocaleDataWrapper& rLocaleData, + LanguageType eLang ); + NfCurrencyEntry( + const ::com::sun::star::i18n::Currency & rCurr, + const LocaleDataWrapper& rLocaleData, + LanguageType eLang ); + ~NfCurrencyEntry() {} + + /// Symbols and language identical + BOOL operator==( const NfCurrencyEntry& r ) const; + + /// Set this format to be the EURo entry, overwrite other settings + void SetEuro(); + BOOL IsEuro() const; + + /** Apply format information (nPositiveFormat, + nNegativeFormat, nDigits, cZeroChar) of another format. */ + void ApplyVariableInformation( const NfCurrencyEntry& ); + + const String& GetSymbol() const { return aSymbol; } + const String& GetBankSymbol() const { return aBankSymbol; } + LanguageType GetLanguage() const { return eLanguage; } + USHORT GetPositiveFormat() const { return nPositiveFormat; } + USHORT GetNegativeFormat() const { return nNegativeFormat; } + USHORT GetDigits() const { return nDigits; } + sal_Unicode GetZeroChar() const { return cZeroChar; } + + /** [$DM-407] (bBank==FALSE) or [$DEM] (bBank==TRUE) + is assigned to rStr, if bBank==FALSE and + bWithoutExtension==TRUE only [$DM] */ + void BuildSymbolString( String& rStr, BOOL bBank, + BOOL bWithoutExtension = FALSE ) const; + + /** #,##0.00 [$DM-407] is assigned to rStr, separators + from rLoc, incl. minus sign but without [RED] */ + void BuildPositiveFormatString( String& rStr, BOOL bBank, + const LocaleDataWrapper&, USHORT nDecimalFormat = 1 ) const; + void BuildNegativeFormatString( String& rStr, BOOL bBank, + const LocaleDataWrapper&, USHORT nDecimalFormat = 1 ) const; + + /** [$DM-407] (or [$DEM] if bBank==TRUE) + is appended/prepended to rStr, incl. minus sign */ + void CompletePositiveFormatString( String& rStr, BOOL bBank, + USHORT nPosiFormat ) const; + void CompleteNegativeFormatString( String& rStr, BOOL bBank, + USHORT nNegaFormat ) const; + + /// rSymStr is appended/prepended to rStr, incl. minus sign + static void CompletePositiveFormatString( String& rStr, + const String& rSymStr, USHORT nPosiFormat ); + static void CompleteNegativeFormatString( String& rStr, + const String& rSymStr, USHORT nNegaFormat ); + + /** Representation of a currency (symbol position and + negative sign) in other language settings */ + static USHORT GetEffectivePositiveFormat( USHORT nIntlFormat, + USHORT nCurrFormat, BOOL bBank ); + static USHORT GetEffectiveNegativeFormat( USHORT nIntlFormat, + USHORT nCurrFormat, BOOL bBank ); + + /// General Unicode Euro symbol + static inline sal_Unicode GetEuroSymbol() { return sal_Unicode(0x20AC); } + /** Platform and CharSet dependent Euro symbol, + needed for import/export */ + static sal_Char GetEuroSymbol( rtl_TextEncoding eTextEncoding ); +}; + +typedef NfCurrencyEntry* NfCurrencyEntryPtr; +SV_DECL_PTRARR_DEL( NfCurrencyTable, NfCurrencyEntryPtr, 128, 1 ) +typedef String* WSStringPtr; +SV_DECL_PTRARR_DEL_VISIBILITY( NfWSStringsDtor, WSStringPtr, 8, 1, SVL_DLLPUBLIC ) + + +class SvNumberFormatterRegistry_Impl; + +class SVL_DLLPUBLIC SvNumberFormatter +{ +public: + + /// Preferred ctor with service manager and language/country enum + SvNumberFormatter( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr, + LanguageType eLang + ); + + /// Depricated ctor without service manager + SvNumberFormatter( LanguageType eLang ); + + ~SvNumberFormatter(); + + /// Set CallBack to ColorTable + void SetColorLink( const Link& rColorTableCallBack ) { aColorLink = rColorTableCallBack; } + /// Do the CallBack to ColorTable + Color* GetUserDefColor(USHORT nIndex); + + /// Change language/country, also input and format scanner + void ChangeIntl( LanguageType eLnge ); + /// Change the reference null date + void ChangeNullDate(USHORT nDay, USHORT nMonth, USHORT nYear); + /// Change standard precision + void ChangeStandardPrec(short nPrec); + /// Set zero value suppression + void SetNoZero(BOOL bNZ) { bNoZero = bNZ; } + + /** The language with which the formatter was initialized (system setting), + NOT the current language after a ChangeIntl() */ + LanguageType GetLanguage() const { return IniLnge; } + + // Determine whether two format types are input compatible or not + BOOL IsCompatible(short eOldType, short eNewType); + + /** Get table of formats of a specific type of a locale. A format FIndex is + tested whether it has the type and locale requested, if it doesn't + match FIndex returns the default format for the type/locale. If no + specific format is to be selected FIndex may be initialized to 0. */ + SvNumberFormatTable& GetEntryTable(short eType, + sal_uInt32& FIndex, + LanguageType eLnge); + + /** Get table of formats of a specific type of a language/country. + FIndex returns the default format of that type. + If the language/country was never touched before new entries are generated */ + SvNumberFormatTable& ChangeCL(short eType, + sal_uInt32& FIndex, + LanguageType eLnge); + + /** Get table of formats of the same type as FIndex; eType and rLnge are + set accordingly. An unknown format is set to Standard/General */ + SvNumberFormatTable& GetFirstEntryTable(short& eType, + sal_uInt32& FIndex, + LanguageType& rLnge); + + /// Delete an entry including the format it is refering to + void DeleteEntry(sal_uInt32 nKey); + + /** Create new entry of a format code string for language/country. + @return + <TRUE/> if string new and ok and inserted. + <FALSE/> if string already exists or an unresolvable parse error + occured, in which case nCheckPos is the error position within rString. + If the error occurs at position 0 or rString is empty nCheckPos + will be 1, so an error in the string is always indicated by + nCheckPos not being zero. + The content of the rString variable can be changed and corrected + by the method. + nType contains the type of the format. + nKey contains the index key of the format. + */ + BOOL PutEntry( String& rString, xub_StrLen& nCheckPos, short& nType, sal_uInt32& nKey, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Same as <method>PutEntry</method> but the format code string is + considered to be of language/country eLnge and is converted to + language/country eNewLnge */ + BOOL PutandConvertEntry( String& rString, xub_StrLen& nCheckPos, + short& nType, sal_uInt32& nKey, + LanguageType eLnge, LanguageType eNewLnge ); + + /** Same as <method>PutandConvertEntry</method> but the format code string + is considered to be of the System language/country eLnge and is + converted to another System language/country eNewLnge. In this case + the automatic currency is converted too. */ + BOOL PutandConvertEntrySystem( String& rString, xub_StrLen& nCheckPos, + short& nType, sal_uInt32& nKey, + LanguageType eLnge, LanguageType eNewLnge ); + + /** Similar to <method>PutEntry</method> and + <method>PutandConvertEntry</method> or + <method>PutandConvertEntrySystem</method>, the format code string + passed is considered to be of language/country eLnge. If + eLnge==LANGUAGE_SYSTEM the format code has to match eSysLnge, and if + eSysLnge is not the current application locale the format code is + converted to the current locale. Additionally, if the format code + represents an old "automatic" currency format, it is converted to the + new default currency format of the eLnge locale. The rString format + code passed as an argument may get adapted in case eLnge was used (or + is LANGUAGE_SYSTEM and eSysLnge is identical); in case it wasn't the + method works on a copy instead, otherwise the resulting string would + not match eSysLnge anymore. + + <p> This method was introduced to handle the legacy currency formats of + the "autotbl.fmt" file used by Calc and Writer and convert them to + fixed currency codes of the actual currency. Note that in the case of + legacy currency formats no special attribution is converted, only the + default currency format of the locale is chosen, and that new fixed + currency codes are of course not converted to other currencies. The + method may also be used as a general method taking, converting and + inserting almost arbitrary format codes. To insert or use, for example, + the default currency format code matching the current locale, the + method could be called with<br/> + + <code> + GetIndexPuttingAndConverting( "0 $", LANGUAGE_SYSTEM, LANGUAGE_ENGLISH_US, ...); + </code> + + @return + The index key of the resulting number format. If the format code + was empty, could not be converted or has errors, the eLnge locale's + standard number format is chosen instead. The index key is + guaranteed to represent some valid number format. If + rNewInserted==FALSE and rCheckPos>0 the format code has errors + and/or could not be converted. + */ + sal_uInt32 GetIndexPuttingAndConverting( String & rString, LanguageType eLnge, + LanguageType eSysLnge, short & rType, + BOOL & rNewInserted, + xub_StrLen & rCheckPos ); + + /** Create a format code string using format nIndex as a template and + applying other settings (passed from the dialog) */ + void GenerateFormat( String& sString, sal_uInt32 nIndex, + LanguageType eLnge = LANGUAGE_DONTKNOW, + BOOL bThousand = FALSE, BOOL IsRed = FALSE, + USHORT nPrecision = 0, USHORT nAnzLeading = 1 ); + + /** Analyze an input string + @return + <TRUE/> if input is a number or is matching a format F_Index + F_Index is set to a matching format if number, the value is + returned in fOutNumber + <FALSE/> if input is not a number + */ + BOOL IsNumberFormat( const String& sString, sal_uInt32& F_Index, double& fOutNumber ); + + /// Format a number according to a format index, return string and color + void GetOutputString( const double& fOutNumber, sal_uInt32 nFIndex, + String& sOutString, Color** ppColor ); + + /** Format a string according to a format index, return string and color. + Formats only if the format code is of type text or the 4th subcode + of a format code is specified, otherwise sOutString will be == "" */ + void GetOutputString( String& sString, sal_uInt32 nFIndex, + String& sOutString, Color** ppColor ); + + /** Format a number according to the standard default format matching + the given format index */ + void GetInputLineString( const double& fOutNumber, + sal_uInt32 nFIndex, String& sOutString ); + + /** Format a number according to a format code string to be scanned. + @return + <FALSE/> if format code contains an error + <TRUE/> else, in which case the string and color are returned. + */ + BOOL GetPreviewString( const String& sFormatString, double fPreviewNumber, + String& sOutString, Color** ppColor, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Same as <method>GetPreviewString</method> but the format code string + may be either language/country eLnge or en_US english US */ + BOOL GetPreviewStringGuess( const String& sFormatString, double fPreviewNumber, + String& sOutString, Color** ppColor, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Test whether the format code string is already present in container + @return + NUMBERFORMAT_ENTRY_NOT_FOUND if not found, else the format index. + */ + sal_uInt32 TestNewString( const String& sFormatString, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /// Whether format index nFIndex is of type text or not + BOOL IsTextFormat(sal_uInt32 nFIndex) const; + /// Whether the 4th string subcode of format index nFIndex is present + BOOL HasTextFormat(sal_uInt32 nFIndex) const; + + /// Load all formats from a stream + BOOL Load( SvStream& rStream ); + /// Save all formats to a stream + BOOL Save( SvStream& rStream ) const; + /// Reset of "Used" flags + void PrepareSave(); + + /// Flag format index as used + void SetFormatUsed(sal_uInt32 nFIndex); + + /// Get additional info of a format index, e.g. for dialog box + void GetFormatSpecialInfo(sal_uInt32 nFormat, BOOL& bThousand, BOOL& IsRed, + USHORT& nPrecision, USHORT& nAnzLeading); + + /// Count of decimals + USHORT GetFormatPrecision( sal_uInt32 nFormat ) const; + + /** Get additional info of a format code string, e.g. for dialog box. + Uses a temporary parse, if possible use only if format code is not + present in container yet, otherwise ineffective. + @return + 0 if format code string parsed without errors, otherwise error + position (like nCheckPos on <method>PutEntry</method>) + */ + sal_uInt32 GetFormatSpecialInfo( const String&, BOOL& bThousand, BOOL& IsRed, + USHORT& nPrecision, USHORT& nAnzLeading, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /// Check if format code string may be deleted by user + BOOL IsUserDefined( const String& sStr, LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Return the format index of the format code string for language/country, + or NUMBERFORMAT_ENTRY_NOT_FOUND */ + sal_uInt32 GetEntryKey( const String& sStr, LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /// Return the format for a format index + const SvNumberformat* GetEntry(sal_uInt32 nKey) const + { return (SvNumberformat*) aFTable.Get(nKey); } + + /// Return the format index of the standard default number format for language/country + sal_uInt32 GetStandardIndex(LanguageType eLnge = LANGUAGE_DONTKNOW); + + /// Return the format index of the default format of a type for language/country + sal_uInt32 GetStandardFormat(short eType, LanguageType eLnge = LANGUAGE_DONTKNOW); + + /** Return the format index of the default format of a type for language/country. + Maybe not the default format but a special builtin format, e.g. for + NF_TIME_HH_MMSS00, if that format is passed in nFIndex. */ + sal_uInt32 GetStandardFormat( sal_uInt32 nFIndex, short eType, LanguageType eLnge ); + + /** Return the format index of the default format of a type for language/country. + Maybe not the default format but a special builtin format, e.g. for + NF_TIME_HH_MMSS00, or NF_TIME_HH_MMSS if fNumber >= 1.0 */ + sal_uInt32 GetStandardFormat( double fNumber, sal_uInt32 nFIndex, short eType, + LanguageType eLnge ); + + /// Whether nFIndex is a special builtin format + BOOL IsSpecialStandardFormat( sal_uInt32 nFIndex, LanguageType eLnge ); + + /// Return the reference date + Date* GetNullDate(); + /// Return the standard decimal precision + short GetStandardPrec(); + /// Return whether zero suppression is switched on + BOOL GetNoZero() { return bNoZero; } + /** Get the type of a format (or NUMBERFORMAT_UNDEFINED if no entry), + but with NUMBERFORMAT_DEFINED masked out */ + short GetType(sal_uInt32 nFIndex); + + /// As the name says + void ClearMergeTable(); + /// Merge in all new entries from rNewTable and return a table of resulting new format indices + SvNumberFormatterIndexTable* MergeFormatter(SvNumberFormatter& rNewTable); + + /// Whether a merge table is present or not + inline BOOL HasMergeFmtTbl() const; + /// Return the new format index for an old format index, if a merge table exists + inline sal_uInt32 GetMergeFmtIndex( sal_uInt32 nOldFmt ) const; + + /** Convert the ugly old tools' Table type bloated with new'ed sal_uInt32 + entries merge table to ::std::map with old index key and new index key. + @ATTENTION! Also clears the old table using ClearMergeTable() */ + SvNumberFormatterMergeMap ConvertMergeTableToMap(); + + /// Return the last used position ever of a language/country combination + USHORT GetLastInsertKey(sal_uInt32 CLOffset); + + /** Return the format index of a builtin format for a specific language/country. + If nFormat is not a builtin format nFormat is returned. */ + sal_uInt32 GetFormatForLanguageIfBuiltIn( sal_uInt32 nFormat, + LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Return the format index for a builtin format of a specific language + @see NfIndexTableOffset + */ + sal_uInt32 GetFormatIndex( NfIndexTableOffset, LanguageType eLnge = LANGUAGE_DONTKNOW ); + + /** Return enum index of a format index of a builtin format, + NF_INDEX_TABLE_ENTRIES if it's not a builtin format. + @see NfIndexTableOffset + */ + NfIndexTableOffset GetIndexTableOffset( sal_uInt32 nFormat ) const; + + /** Set evaluation type and order of input date strings + @see NfEvalDateFormat + */ + void SetEvalDateFormat( NfEvalDateFormat eEDF ) { eEvalDateFormat = eEDF; } + NfEvalDateFormat GetEvalDateFormat() const { return eEvalDateFormat; } + + /** Set TwoDigitYearStart, how the input string scanner handles a two digit year. + Default from VCL: 1930, 30-99 19xx, 00-29 20xx + + <p> Historically (prior to src513e) it was a two digit number determing + until which number the string scanner recognizes a year to be 20xx, + default <= 29 is used by SFX/OfaMiscCfg. + The name Year2000 is kept although the actual functionality is now a + TwoDigitYearStart which might be in any century. + */ + void SetYear2000( USHORT nVal ); + USHORT GetYear2000() const; + static USHORT GetYear2000Default(); + + USHORT ExpandTwoDigitYear( USHORT nYear ) const; + inline static USHORT ExpandTwoDigitYear( USHORT nYear, USHORT nTwoDigitYearStart ); + + /// DEPRICATED: Return first character of the decimal separator of the current language/country + sal_Unicode GetDecSep() const { return GetNumDecimalSep().GetChar(0); } + /// Return the decimal separator of the current language/country + String GetDecimalSep() const { return GetNumDecimalSep(); } + + /// Return the decimal separator matching the locale of the given format + String GetFormatDecimalSep( sal_uInt32 nFormat ) const; + + /// Return a <type>SvPtrArr</type> with pointers to <type>NfCurrencyEntry</type> entries + static const NfCurrencyTable& GetTheCurrencyTable(); + + /** Searches, according to the default locale currency, an entry of the + CurrencyTable which is <bold>not</bold> the first (LANGUAGE_SYSTEM) entry. + @return + <NULL/> if not found + else pointer to <type>NfCurrencyEntry</type> + */ + static const NfCurrencyEntry* MatchSystemCurrency(); + + /** Return a <type>NfCurrencyEntry</type> matching a language/country. + If language/country is LANGUAGE_SYSTEM a <method>MatchSystemCurrency</method> + call is tried to get an entry. If that fails or the corresponding + language/country is not present the entry for LANGUAGE_SYSTEM is returned. + */ + static const NfCurrencyEntry& GetCurrencyEntry( LanguageType ); + + /** Return a <type>NfCurrencyEntry</type> pointer matching a language/country + and currency abbreviation (AKA banking symbol). + This method is meant for the configuration of the default currency. + @return + <NULL/> if not found + else pointer to <type>NfCurrencyEntry</type> + */ + static const NfCurrencyEntry* GetCurrencyEntry( const String& rAbbrev, + LanguageType eLang ); + + /** Return a <type>NfCurrencyEntry</type> pointer matching the symbol + combination of a LegacyOnly currency. Note that this means only that + the currency matching both symbols was once used in the Office, but is + not offered in dialogs anymore. It doesn't even mean that the currency + symbol combination is valid, since the reason for removing it may have + been just that. #i61657# + @return + A matching entry, or else <NULL/>. + */ + static const NfCurrencyEntry* GetLegacyOnlyCurrencyEntry( + const String& rSymbol, const String& rAbbrev ); + + /** Set the default system currency. The combination of abbreviation and + language must match an existent element of theCurrencyTable. If not, + the SYSTEM (current locale) entry becomes the default. + This method is meant for the configuration of the default currency. + */ + static void SetDefaultSystemCurrency( const String& rAbbrev, LanguageType eLang ); + + /** Get all standard formats for a specific currency, formats are + appended to the <type>NfWSStringsDtor</type> list. + @param bBank + <TRUE/>: generate only format strings with currency abbreviation + <FALSE/>: mixed format strings + @return + position of default format + */ + USHORT GetCurrencyFormatStrings( NfWSStringsDtor&, const NfCurrencyEntry&, + BOOL bBank ) const; + + /** Whether nFormat is of type NUMBERFORMAT_CURRENCY and the format code + contains a new SYMBOLTYPE_CURRENCY and if so which one [$xxx-nnn]. + If ppEntry is not NULL and exactly one entry is found, a [$xxx-nnn] is + returned, even if the format code only contains [$xxx] ! + */ + BOOL GetNewCurrencySymbolString( sal_uInt32 nFormat, String& rSymbol, + const NfCurrencyEntry** ppEntry = NULL, BOOL* pBank = NULL ) const; + + /** Look up the corresponding <type>NfCurrencyEntry</type> matching + rSymbol (may be CurrencySymbol or CurrencyAbbreviation) and possibly + a rExtension (being yyy of [$xxx-yyy]) or a given language/country + value. Tries to match a rSymbol with rExtension first, then with + eFormatLanguage, then rSymbol only. This is because a currency entry + might have been constructed using I18N locale data where a used locale + of a currrency format code must not necessarily match the locale of + the locale data itself, e.g. [$HK$-40C] (being "zh_HK" locale) in + zh_CN locale data. Here the rExtension would have the value 0x40c but + eFormatLanguage of the number format would have the value of zh_CN + locale, the value with which the corresponding CurrencyEntry is + constructed. + + @param bFoundBank + Only used for output. + If the return value is not <NULL/> this value is set to <TRUE/> if + the matching entry was found by comparing rSymbol against the + CurrencyAbbreviation (AKA BankSymbol). + If the return value is <NULL/> the value of bFoundBank is undefined. + @param rSymbol + Currency symbol, preferably obtained of a format by a call to + <method>SvNumberformat::GetNewCurrencySymbol()</method> + @param rExtension + Currency extension, preferably obtained of a format by a call to + <method>SvNumberformat::GetNewCurrencySymbol()</method> + @param eFormatLanguage + The language/country value of the format of which rSymbol and + rExtension are obtained (<method>SvNumberformat::GetLanguage()</method>). + @param bOnlyStringLanguage + If <TRUE/> only entries with language/country of rExtension are + checked, no match on eFormatLanguage. If rExtension is empty all + entries are checked. + @return + The matching entry if unique (in which case bFoundBank is set), + else <NULL/>. + */ + static const NfCurrencyEntry* GetCurrencyEntry( BOOL & bFoundBank, + const String& rSymbol, const String& rExtension, + LanguageType eFormatLanguage, BOOL bOnlyStringLanguage = FALSE ); + + /// Get compatibility ("automatic" old style) currency from I18N locale data + void GetCompatibilityCurrency( String& rSymbol, String& rAbbrev ) const; + + /// Fill rList with the language/country codes that have been allocated + void GetUsedLanguages( SvUShorts& rList ); + + /// Fill a <type>NfKeywordIndex</type> table with keywords of a language/country + void FillKeywordTable( NfKeywordTable& rKeywords, LanguageType eLang ); + + /** Return a keyword for a language/country and <type>NfKeywordIndex</type> + for XML import, to generate number format strings. */ + String GetKeyword( LanguageType eLnge, USHORT nIndex ); + + /** Return the GENERAL keyword in proper case ("General") for a + language/country, used in XML import */ + String GetStandardName( LanguageType eLnge ); + + /// Skip a NumberFormatter in stream, Chart needs this + static void SkipNumberFormatterInStream( SvStream& ); + + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager; + ::com::sun::star::lang::Locale aLocale; + SvNumberFormatTable aFTable; // Table of format keys to format entries + Table aDefaultFormatKeys; // Table of default standard to format keys + SvNumberFormatTable* pFormatTable; // For the UI dialog + SvNumberFormatterIndexTable* pMergeTable; // List of indices for merging two formatters + CharClass* pCharClass; // CharacterClassification + OnDemandLocaleDataWrapper xLocaleData; // LocaleData switched between SYSTEM, ENGLISH and other + OnDemandTransliterationWrapper xTransliteration; // Transliteration loaded on demand + OnDemandCalendarWrapper xCalendar; // Calendar loaded on demand + OnDemandNativeNumberWrapper xNatNum; // Native number service loaded on demand + ImpSvNumberInputScan* pStringScanner; // Input string scanner + ImpSvNumberformatScan* pFormatScanner; // Format code string scanner + Link aColorLink; // User defined color table CallBack + sal_uInt32 MaxCLOffset; // Max language/country offset used + sal_uInt32 nDefaultSystemCurrencyFormat; // NewCurrency matching SYSTEM locale + LanguageType IniLnge; // Initialized setting language/country + LanguageType ActLnge; // Current setting language/country + NfEvalDateFormat eEvalDateFormat; // DateFormat evaluation + BOOL bNoZero; // Zero value suppression + + // cached locale data items needed almost any time + String aDecimalSep; + String aThousandSep; + String aDateSep; + +#ifdef _ZFORLIST_CXX // ----- private Methoden ----- + + SVL_DLLPRIVATE static BOOL bCurrencyTableInitialized; + SVL_DLLPRIVATE static USHORT nSystemCurrencyPosition; + SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl* pFormatterRegistry; + + // get the registry, create one if none exists + SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl& GetFormatterRegistry(); + + // called by ctors + SVL_DLLPRIVATE void ImpConstruct( LanguageType eLang ); + + // Changes initialized language/country, clears the entries and generates + // new ones, may ONLY be called by the binary file format load + SVL_DLLPRIVATE void ImpChangeSysCL( LanguageType eLnge, BOOL bLoadingSO5 ); + + // Generate builtin formats provided by i18n behind CLOffset, + // if bLoadingSO5==FALSE also generate additional i18n formats. + SVL_DLLPRIVATE void ImpGenerateFormats( sal_uInt32 CLOffset, BOOL bLoadingSO5 ); + + // Generate additional formats provided by i18n + SVL_DLLPRIVATE void ImpGenerateAdditionalFormats( + sal_uInt32 CLOffset, + NumberFormatCodeWrapper& rNumberFormatCode, + BOOL bAfterLoadingSO5 ); + + SVL_DLLPRIVATE SvNumberformat* ImpInsertFormat( + const ::com::sun::star::i18n::NumberFormatCode& rCode, + sal_uInt32 nPos, + BOOL bAfterLoadingSO5 = FALSE, + sal_Int16 nOrgIndex = 0 ); + // ImpInsertNewStandardFormat for new (since version ...) builtin formats + SVL_DLLPRIVATE SvNumberformat* ImpInsertNewStandardFormat( + const ::com::sun::star::i18n::NumberFormatCode& rCode, + sal_uInt32 nPos, + USHORT nVersion, + BOOL bAfterLoadingSO5 = FALSE, + sal_Int16 nOrgIndex = 0 ); + + // Return CLOffset or (MaxCLOffset + SV_COUNTRY_LANGUAGE_OFFSET) if new language/country + SVL_DLLPRIVATE sal_uInt32 ImpGetCLOffset(LanguageType eLnge) const; + + // Test whether format code already exists, then return index key, + // otherwise NUMBERFORMAT_ENTRY_NOT_FOUND + SVL_DLLPRIVATE sal_uInt32 ImpIsEntry( const String& rString, + sal_uInt32 CLOffset, + LanguageType eLnge ); + + // Create builtin formats for language/country if necessary, return CLOffset + SVL_DLLPRIVATE sal_uInt32 ImpGenerateCL( LanguageType eLnge, BOOL bLoadingSO5 = FALSE ); + + // Build negative currency format, old compatibility style + SVL_DLLPRIVATE void ImpGetNegCurrFormat( String& sNegStr, const String& rCurrSymbol ); + // Build positive currency format, old compatibility style + SVL_DLLPRIVATE void ImpGetPosCurrFormat( String& sPosStr, const String& rCurrSymbol ); + + // Create <type>theCurrencyTable</type> with all <type>NfCurrencyEntry</type> + SVL_DLLPRIVATE static void ImpInitCurrencyTable(); + + // Return the format index of the currency format of the system locale. + // Format is created if not already present. + SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultSystemCurrencyFormat(); + + // Return the format index of the currency format of the current locale. + // Format is created if not already present. + SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultCurrencyFormat(); + + // Return the default format for a given type and current locale. + // May ONLY be called from within GetStandardFormat(). + SVL_DLLPRIVATE sal_uInt32 ImpGetDefaultFormat( short nType ); + + // Return the index in a sequence of format codes matching an enum of + // NfIndexTableOffset. If not found 0 is returned. If the sequence doesn't + // contain any format code elements a default element is created and inserted. + SVL_DLLPRIVATE sal_Int32 ImpGetFormatCodeIndex( + ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode >& rSeq, + const NfIndexTableOffset nTabOff ); + + // Adjust a sequence of format codes to contain only one (THE) default + // instead of multiple defaults for short/medium/long types. + // If there is no medium but a short and a long default the long is taken. + // Return the default index in the sequence. + // Non-PRODUCT version may check locale data for matching defaults in one + // FormatElement group. + SVL_DLLPRIVATE sal_Int32 ImpAdjustFormatCodeDefault( + ::com::sun::star::i18n::NumberFormatCode * pFormatArr, + sal_Int32 nCount, BOOL bCheckCorrectness = TRUE + ); + + // used as a loop body inside of GetNewCurrencySymbolString() and GetCurrencyEntry() +#ifndef DBG_UTIL + inline +#endif + static BOOL ImpLookupCurrencyEntryLoopBody( + const NfCurrencyEntry*& pFoundEntry, BOOL& bFoundBank, + const NfCurrencyEntry* pData, USHORT nPos, const String& rSymbol ); + + // link to be set at <method>SvtSysLocaleOptions::SetCurrencyChangeLink()</method> + DECL_DLLPRIVATE_STATIC_LINK( SvNumberFormatter, CurrencyChangeLink, void* ); + +#endif // _ZFORLIST_CXX + +public: + + // own static mutex, may also be used by internal class SvNumberFormatterRegistry_Impl + static ::osl::Mutex& GetMutex(); + + // called by SvNumberFormatterRegistry_Impl::Notify if the default system currency changes + void ResetDefaultSystemCurrency(); + + // Replace the SYSTEM language/country format codes. Called upon change of + // the user configurable locale. + // Old compatibility codes are replaced, user defined are converted, and + // new format codes are appended. + void ReplaceSystemCL( LanguageType eOldLanguage ); + + inline ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory > + GetServiceManager() const { return xServiceManager; } + + + + //! The following method is not to be used from outside but must be + //! public for the InputScanner. + // return the current FormatScanner + inline const ImpSvNumberformatScan* GetFormatScanner() const { return pFormatScanner; } + + + + //! The following methods are not to be used from outside but must be + //! public for the InputScanner and FormatScanner. + + // return current (!) Locale + inline const ::com::sun::star::lang::Locale& GetLocale() const { return aLocale; } + + // return corresponding Transliteration wrapper + inline const ::utl::TransliterationWrapper* GetTransliteration() const + { return xTransliteration.get(); } + + // return corresponding Transliteration wrapper with loadModuleByImplName() + inline const ::utl::TransliterationWrapper* GetTransliterationForModule( + const String& rModule, LanguageType eLang ) const + { return xTransliteration.getForModule( rModule, eLang ); } + + // return the corresponding CharacterClassification wrapper + inline const CharClass* GetCharClass() const { return pCharClass; } + + // return the corresponding LocaleData wrapper + inline const LocaleDataWrapper* GetLocaleData() const { return xLocaleData.get(); } + + // return the corresponding Calendar wrapper + inline CalendarWrapper* GetCalendar() const { return xCalendar.get(); } + + // return the corresponding NativeNumberSupplier wrapper + inline const NativeNumberWrapper* GetNatNum() const { return xNatNum.get(); } + + // cached locale data items + + // return the corresponding decimal separator + inline const String& GetNumDecimalSep() const { return aDecimalSep; } + + // return the corresponding group (AKA thousand) separator + inline const String& GetNumThousandSep() const { return aThousandSep; } + + // return the corresponding date separator + inline const String& GetDateSep() const { return aDateSep; } + +}; + + +// --------------------------- inline -------------------------------------- + +inline sal_uInt32 SvNumberFormatter::GetMergeFmtIndex( sal_uInt32 nOldFmt ) const +{ + sal_uInt32* pU = (pMergeTable && pMergeTable->Count()) ? (sal_uInt32*)pMergeTable->Get( nOldFmt ) : 0; + return pU ? *pU : nOldFmt; +} + +inline BOOL SvNumberFormatter::HasMergeFmtTbl() const +{ + return pMergeTable && (0 != pMergeTable->Count()); +} + + +// static +inline USHORT SvNumberFormatter::ExpandTwoDigitYear( + USHORT nYear, USHORT nTwoDigitYearStart ) +{ + if ( nYear < 100 ) + { + if ( nYear < (nTwoDigitYearStart % 100) ) + return nYear + (((nTwoDigitYearStart / 100) + 1) * 100); + else + return nYear + ((nTwoDigitYearStart / 100) * 100); + } + return nYear; +} + + + +#endif // _ZFORLIST_HXX diff --git a/svl/inc/svl/zformat.hxx b/svl/inc/svl/zformat.hxx new file mode 100644 index 000000000000..991460015e6d --- /dev/null +++ b/svl/inc/svl/zformat.hxx @@ -0,0 +1,589 @@ +/************************************************************************* + * + * 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: zformat.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ZFORMAT_HXX +#define _ZFORMAT_HXX + +#include "svl/svldllapi.h" +#include <tools/string.hxx> +#include <i18npool/mslangid.hxx> +#include <svl/zforlist.hxx> +#include <svl/nfversi.hxx> +#include <svl/nfkeytab.hxx> + +// We need ImpSvNumberformatScan for the private SvNumberformat definitions. +#ifdef _ZFORMAT_CXX +#include "zforscan.hxx" +#endif + +// If comment field is also in format code string, was used for SUPD versions 371-372 +#define NF_COMMENT_IN_FORMATSTRING 0 + +namespace utl { + class DigitGroupingIterator; +} + +class SvStream; +class Color; + +class ImpSvNumberformatScan; // format code string scanner +class ImpSvNumberInputScan; // input string scanner +class ImpSvNumMultipleWriteHeader; // compatible file format +class ImpSvNumMultipleReadHeader; // compatible file format +class SvNumberFormatter; + +enum SvNumberformatLimitOps +{ + NUMBERFORMAT_OP_NO = 0, // Undefined, no OP + NUMBERFORMAT_OP_EQ = 1, // Operator = + NUMBERFORMAT_OP_NE = 2, // Operator <> + NUMBERFORMAT_OP_LT = 3, // Operator < + NUMBERFORMAT_OP_LE = 4, // Operator <= + NUMBERFORMAT_OP_GT = 5, // Operator > + NUMBERFORMAT_OP_GE = 6 // Operator >= +}; + +// SYSTEM-german to SYSTEM-xxx and vice versa conversion hack onLoad +enum NfHackConversion +{ + NF_CONVERT_NONE, + NF_CONVERT_GERMAN_ENGLISH, + NF_CONVERT_ENGLISH_GERMAN +}; + +struct ImpSvNumberformatInfo // Struct for FormatInfo +{ + String* sStrArray; // Array of symbols + short* nTypeArray; // Array of infos + USHORT nThousand; // Count of group separator sequences + USHORT nCntPre; // Count of digits before decimal point + USHORT nCntPost; // Count of digits after decimal point + USHORT nCntExp; // Count of exponent digits, or AM/PM + short eScannedType; // Type determined by scan + BOOL bThousand; // Has group (AKA thousand) separator + + void Copy( const ImpSvNumberformatInfo& rNumFor, USHORT nAnz ); + void Load(SvStream& rStream, USHORT nAnz); + void Save(SvStream& rStream, USHORT nAnz) const; +}; + +// NativeNumber, represent numbers using CJK or other digits if nNum>0, +// eLang specifies the Locale to use. +class SvNumberNatNum +{ + LanguageType eLang; + BYTE nNum; + BOOL bDBNum :1; // DBNum, to be converted to NatNum + BOOL bDate :1; // Used in date? (needed for DBNum/NatNum mapping) + BOOL bSet :1; // If set, since NatNum0 is possible + +public: + + static BYTE MapDBNumToNatNum( BYTE nDBNum, LanguageType eLang, BOOL bDate ); + static BYTE MapNatNumToDBNum( BYTE nNatNum, LanguageType eLang, BOOL bDate ); + + SvNumberNatNum() : eLang( LANGUAGE_DONTKNOW ), nNum(0), + bDBNum(0), bDate(0), bSet(0) {} + BOOL IsComplete() const { return bSet && eLang != LANGUAGE_DONTKNOW; } + BYTE GetRawNum() const { return nNum; } + BYTE GetNatNum() const { return bDBNum ? MapDBNumToNatNum( nNum, eLang, bDate ) : nNum; } + BYTE GetDBNum() const { return bDBNum ? nNum : MapNatNumToDBNum( nNum, eLang, bDate ); } + LanguageType GetLang() const { return eLang; } + void SetLang( LanguageType e ) { eLang = e; } + void SetNum( BYTE nNumber, BOOL bDBNumber ) + { + nNum = nNumber; + bDBNum = bDBNumber; + bSet = TRUE; + } + BOOL IsSet() const { return bSet; } + void SetDate( BOOL bDateP ) { bDate = (bDateP != 0); } +}; + +class CharClass; + +class ImpSvNumFor // One of four subformats of the format code string +{ +public: + ImpSvNumFor(); // Ctor without filling the Info + ~ImpSvNumFor(); + + void Enlarge(USHORT nAnz); // Init of arrays to the right size + void Load( SvStream& rStream, ImpSvNumberformatScan& rSc, + String& rLoadedColorName); + void Save( SvStream& rStream ) const; + + // if pSc is set, it is used to get the Color pointer + void Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc ); + + // Access to Info; call Enlarge before! + ImpSvNumberformatInfo& Info() { return aI;} + const ImpSvNumberformatInfo& Info() const { return aI; } + + // Get count of substrings (symbols) + USHORT GetnAnz() const { return nAnzStrings;} + + Color* GetColor() const { return pColor; } + void SetColor( Color* pCol, String& rName ) + { pColor = pCol; sColorName = rName; } + const String& GetColorName() const { return sColorName; } + + // new SYMBOLTYPE_CURRENCY in subformat? + BOOL HasNewCurrency() const; + BOOL GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const; + void SaveNewCurrencyMap( SvStream& rStream ) const; + void LoadNewCurrencyMap( SvStream& rStream ); + + // [NatNum1], [NatNum2], ... + void SetNatNumNum( BYTE nNum, BOOL bDBNum ) { aNatNum.SetNum( nNum, bDBNum ); } + void SetNatNumLang( LanguageType eLang ) { aNatNum.SetLang( eLang ); } + void SetNatNumDate( BOOL bDate ) { aNatNum.SetDate( bDate ); } + const SvNumberNatNum& GetNatNum() const { return aNatNum; } + +private: + ImpSvNumberformatInfo aI; // Hilfsstruct fuer die restlichen Infos + String sColorName; // color name + Color* pColor; // pointer to color of subformat + USHORT nAnzStrings; // count of symbols + SvNumberNatNum aNatNum; // DoubleByteNumber + +}; + +class SVL_DLLPUBLIC SvNumberformat +{ +public: + // Ctor for Load + SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge ); + + // Normal ctor + SvNumberformat( String& rString, + ImpSvNumberformatScan* pSc, + ImpSvNumberInputScan* pISc, + xub_StrLen& nCheckPos, + LanguageType& eLan, + BOOL bStand = FALSE ); + + // Copy ctor + SvNumberformat( SvNumberformat& rFormat ); + + // Copy ctor with exchange of format code string scanner (used in merge) + SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc ); + + ~SvNumberformat(); + + /// Get type of format, may include NUMBERFORMAT_DEFINED bit + short GetType() const + { return (nNewStandardDefined && + (nNewStandardDefined <= SV_NUMBERFORMATTER_VERSION)) ? + (eType & ~NUMBERFORMAT_DEFINED) : eType; } + + void SetType(const short eSetType) { eType = eSetType; } + // Standard means the I18N defined standard format of this type + void SetStandard() { bStandard = TRUE; } + BOOL IsStandard() const { return bStandard; } + + // For versions before version nVer it is UserDefined, for newer versions + // it is builtin. nVer of SV_NUMBERFORMATTER_VERSION_... + void SetNewStandardDefined( USHORT nVer ) + { nNewStandardDefined = nVer; eType |= NUMBERFORMAT_DEFINED; } + + USHORT GetNewStandardDefined() const { return nNewStandardDefined; } + BOOL IsAdditionalStandardDefined() const + { return nNewStandardDefined == SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS; } + + LanguageType GetLanguage() const { return eLnge;} + + const String& GetFormatstring() const { return sFormatstring; } + + // Build a format string of application defined keywords + String GetMappedFormatstring( const NfKeywordTable& rKeywords, + const LocaleDataWrapper& rLoc, + BOOL bDontQuote = FALSE ) const; + + void SetUsed(const BOOL b) { bIsUsed = b; } + BOOL GetUsed() const { return bIsUsed; } + BOOL IsStarFormatSupported() const { return bStarFlag; } + void SetStarFormatSupport( BOOL b ) { bStarFlag = b; } + + NfHackConversion Load( SvStream& rStream, ImpSvNumMultipleReadHeader& rHdr, + SvNumberFormatter* pConverter, ImpSvNumberInputScan& rISc ); + void Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const; + + // Load a string which might contain an Euro symbol, + // in fact that could be any string used in number formats. + static void LoadString( SvStream& rStream, String& rStr ); + + BOOL GetOutputString( double fNumber, String& OutString, Color** ppColor ); + BOOL GetOutputString( String& sString, String& OutString, Color** ppColor ); + + // True if type text + BOOL IsTextFormat() const { return (eType & NUMBERFORMAT_TEXT) != 0; } + // True if 4th subformat present + BOOL HasTextFormat() const + { + return (NumFor[3].GetnAnz() > 0) || + (NumFor[3].Info().eScannedType == NUMBERFORMAT_TEXT); + } + + void GetFormatSpecialInfo(BOOL& bThousand, + BOOL& IsRed, + USHORT& nPrecision, + USHORT& nAnzLeading) const; + + /// Count of decimal precision + USHORT GetFormatPrecision() const { return NumFor[0].Info().nCntPost; } + + //! Read/write access on a special USHORT component, may only be used on the + //! standard format 0, 5000, ... and only by the number formatter! + USHORT GetLastInsertKey() const + { return NumFor[0].Info().nThousand; } + void SetLastInsertKey(USHORT nKey) + { NumFor[0].Info().nThousand = nKey; } + + //! Only onLoad: convert from stored to current system language/country + void ConvertLanguage( SvNumberFormatter& rConverter, + LanguageType eConvertFrom, LanguageType eConvertTo, BOOL bSystem = FALSE ); + + // Substring of a subformat code nNumFor (0..3) + // nPos == 0xFFFF => last substring + // bString==TRUE: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY + const String* GetNumForString( USHORT nNumFor, USHORT nPos, + BOOL bString = FALSE ) const; + + // Subtype of a subformat code nNumFor (0..3) + // nPos == 0xFFFF => last substring + // bString==TRUE: first/last SYMBOLTYPE_STRING or SYMBOLTYPE_CURRENCY + short GetNumForType( USHORT nNumFor, USHORT nPos, BOOL bString = FALSE ) const; + + /** If the count of string elements (substrings, ignoring [modifiers] and + so on) in a subformat code nNumFor (0..3) is equal to the given number. + Used by ImpSvNumberInputScan::IsNumberFormatMain() to detect a matched + format. */ + BOOL IsNumForStringElementCountEqual( USHORT nNumFor, USHORT nAllCount, + USHORT nNumCount ) const + { + if ( nNumFor < 4 ) + { + // First try a simple approach. Note that this is called only + // if all MidStrings did match so far, to verify that all + // strings of the format were matched and not just the starting + // sequence, so we don't have to check if GetnAnz() includes + // [modifiers] or anything else if both counts are equal. + USHORT nCnt = NumFor[nNumFor].GetnAnz(); + if ( nAllCount == nCnt ) + return TRUE; + if ( nAllCount < nCnt ) // check ignoring [modifiers] and so on + return ImpGetNumForStringElementCount( nNumFor ) == + (nAllCount - nNumCount); + } + return FALSE; + } + + // Whether the second subformat code is really for negative numbers + // or another limit set. + BOOL IsNegativeRealNegative() const + { + return fLimit1 == 0.0 && fLimit2 == 0.0 && + ( (eOp1 == NUMBERFORMAT_OP_GE && eOp2 == NUMBERFORMAT_OP_NO) || + (eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT) || + (eOp1 == NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO) ); + } + + // Whether the negative format is without a sign or not + BOOL IsNegativeWithoutSign() const; + + // Whether a new SYMBOLTYPE_CURRENCY is contained in the format + BOOL HasNewCurrency() const; + + // Build string from NewCurrency for saving it SO50 compatible + void Build50Formatstring( String& rStr ) const; + + // strip [$-yyy] from all [$xxx-yyy] leaving only xxx's, + // if bQuoteSymbol==TRUE the xxx will become "xxx" + static String StripNewCurrencyDelimiters( const String& rStr, + BOOL bQuoteSymbol ); + + // If a new SYMBOLTYPE_CURRENCY is contained if the format is of type + // NUMBERFORMAT_CURRENCY, and if so the symbol xxx and the extension nnn + // of [$xxx-nnn] are returned + BOOL GetNewCurrencySymbol( String& rSymbol, String& rExtension ) const; + + static BOOL HasStringNegativeSign( const String& rStr ); + + /** + Whether a character at position nPos is somewhere between two matching + cQuote or not. + If nPos points to a cQuote, a TRUE is returned on an opening cQuote, + a FALSE is returned on a closing cQuote. + A cQuote between quotes may be escaped by a cEscIn, a cQuote outside of + quotes may be escaped by a cEscOut. + The default '\0' results in no escapement possible. + Defaults are set right according to the "unlogic" of the Numberformatter + */ + static BOOL IsInQuote( const String& rString, xub_StrLen nPos, + sal_Unicode cQuote = '"', + sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' ); + + /** + Return the position of a matching closing cQuote if the character at + position nPos is between two matching cQuote, otherwise return + STRING_NOTFOUND. + If nPos points to an opening cQuote the position of the matching + closing cQuote is returned. + If nPos points to a closing cQuote nPos is returned. + If nPos points into a part which starts with an opening cQuote but has + no closing cQuote, rString.Len() is returned. + Uses <method>IsInQuote</method> internally, so you don't have to call + that prior to a call of this method. + */ + static xub_StrLen GetQuoteEnd( const String& rString, xub_StrLen nPos, + sal_Unicode cQuote = '"', + sal_Unicode cEscIn = '\0', sal_Unicode cEscOut = '\\' ); + + void SetComment( const String& rStr ) +#if NF_COMMENT_IN_FORMATSTRING + { SetComment( rStr, sFormatstring, sComment ); } +#else + { sComment = rStr; } +#endif + const String& GetComment() const { return sComment; } + + // Erase "{ "..." }" from format subcode string to get the pure comment (old version) + static void EraseCommentBraces( String& rStr ); + // Set comment rStr in format string rFormat and in rComment (old version) + static void SetComment( const String& rStr, String& rFormat, String& rComment ); + // Erase comment at end of rStr to get pure format code string (old version) + static void EraseComment( String& rStr ); + + /** Insert the number of blanks into the string that is needed to simulate + the width of character c for underscore formats */ + static xub_StrLen InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c ); + + /// One of YMD,DMY,MDY if date format + DateFormat GetDateOrder() const; + + /** A coded value of the exact YMD combination used, if date format. + For example: YYYY-MM-DD => ('Y' << 16) | ('M' << 8) | 'D' + or: MM/YY => ('M' << 8) | 'Y' */ + sal_uInt32 GetExactDateOrder() const; + + ImpSvNumberformatScan& ImpGetScan() const { return rScan; } + + // used in XML export + void GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1, + SvNumberformatLimitOps& rOper2, double& rVal2 ) const; + Color* GetColor( USHORT nNumFor ) const; + void GetNumForInfo( USHORT nNumFor, short& rScannedType, + BOOL& bThousand, USHORT& nPrecision, USHORT& nAnzLeading ) const; + + // rAttr.Number not empty if NatNum attributes are to be stored + void GetNatNumXml( + ::com::sun::star::i18n::NativeNumberXmlAttributes& rAttr, + USHORT nNumFor ) const; + + /** @returns <TRUE/> if E,EE,R,RR,AAA,AAAA in format code of subformat + nNumFor (0..3) and <b>no</b> preceding calendar was specified and the + currently loaded calendar is "gregorian". */ + BOOL IsOtherCalendar( USHORT nNumFor ) const + { + if ( nNumFor < 4 ) + return ImpIsOtherCalendar( NumFor[nNumFor] ); + return FALSE; + } + + /** Switches to the first non-"gregorian" calendar, but only if the current + calendar is "gregorian"; original calendar name and date/time returned, + but only if calendar switched and rOrgCalendar was empty. */ + void SwitchToOtherCalendar( String& rOrgCalendar, double& fOrgDateTime ) const; + + /** Switches to the "gregorian" calendar, but only if the current calendar + is non-"gregorian" and rOrgCalendar is not empty. Thus a preceding + ImpSwitchToOtherCalendar() call should have been placed prior to + calling this method. */ + void SwitchToGregorianCalendar( const String& rOrgCalendar, double fOrgDateTime ) const; + + /** Switches to the first specified calendar, if any, in subformat nNumFor + (0..3). Original calendar name and date/time returned, but only if + calendar switched and rOrgCalendar was empty. + + @return + <TRUE/> if a calendar was specified and switched to, + <FALSE/> else. + */ + BOOL SwitchToSpecifiedCalendar( String& rOrgCalendar, double& fOrgDateTime, + USHORT nNumFor ) const + { + if ( nNumFor < 4 ) + return ImpSwitchToSpecifiedCalendar( rOrgCalendar, + fOrgDateTime, NumFor[nNumFor] ); + return FALSE; + } + +private: + ImpSvNumFor NumFor[4]; // Array for the 4 subformats + String sFormatstring; // The format code string + String sComment; // Comment, since number formatter version 6 + double fLimit1; // Value for first condition + double fLimit2; // Value for second condition + ImpSvNumberformatScan& rScan; // Format code scanner + LanguageType eLnge; // Language/country of the format + SvNumberformatLimitOps eOp1; // Operator for first condition + SvNumberformatLimitOps eOp2; // Operator for second condition + USHORT nNewStandardDefined; // new builtin formats as of version 6 + short eType; // Type of format + BOOL bStarFlag; // Take *n format as ESC n + BOOL bStandard; // If this is a default standard format + BOOL bIsUsed; // Flag as used for storing + + SVL_DLLPRIVATE USHORT ImpGetNumForStringElementCount( USHORT nNumFor ) const; + + SVL_DLLPRIVATE BOOL ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const; + + SVL_DLLPRIVATE BOOL ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, + double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const; + +#ifdef _ZFORMAT_CXX // ----- private implementation methods ----- + + const CharClass& rChrCls() const { return rScan.GetChrCls(); } + const LocaleDataWrapper& rLoc() const { return rScan.GetLoc(); } + CalendarWrapper& GetCal() const { return rScan.GetCal(); } + const SvNumberFormatter& GetFormatter() const { return *rScan.GetNumberformatter(); } + + // divide in substrings and color conditions + SVL_DLLPRIVATE short ImpNextSymbol( String& rString, + xub_StrLen& nPos, + String& sSymbol ); + + // read string until ']' and strip blanks (after condition) + SVL_DLLPRIVATE static xub_StrLen ImpGetNumber( String& rString, + xub_StrLen& nPos, + String& sSymbol ); + + // get xxx of "[$-xxx]" as LanguageType, starting at and advancing position nPos + SVL_DLLPRIVATE static LanguageType ImpGetLanguageType( const String& rString, xub_StrLen& nPos ); + + // standard number output + SVL_DLLPRIVATE void ImpGetOutputStandard( double& fNumber, String& OutString ); + // numbers in input line + SVL_DLLPRIVATE void ImpGetOutputInputLine( double fNumber, String& OutString ); + + // check subcondition + // OP undefined => -1 + // else 0 or 1 + SVL_DLLPRIVATE short ImpCheckCondition(double& fNumber, + double& fLimit, + SvNumberformatLimitOps eOp); + + SVL_DLLPRIVATE ULONG ImpGGT(ULONG x, ULONG y); + SVL_DLLPRIVATE ULONG ImpGGTRound(ULONG x, ULONG y); + + // Helper function for number strings + // append string symbols, insert leading 0 or ' ', or ... + SVL_DLLPRIVATE BOOL ImpNumberFill( String& sStr, + double& rNumber, + xub_StrLen& k, + USHORT& j, + USHORT nIx, + short eSymbolType ); + + // Helper function to fill in the integer part and the group (AKA thousand) separators + SVL_DLLPRIVATE BOOL ImpNumberFillWithThousands( String& sStr, + double& rNumber, + xub_StrLen k, + USHORT j, + USHORT nIx, + USHORT nDigCnt ); + // Hilfsfunktion zum Auffuellen der Vor- + // kommazahl auch mit Tausenderpunkt + + // Helper function to fill in the group (AKA thousand) separators + // or to skip additional digits + SVL_DLLPRIVATE void ImpDigitFill( String& sStr, + xub_StrLen nStart, + xub_StrLen& k, + USHORT nIx, + xub_StrLen & nDigitCount, + utl::DigitGroupingIterator & ); + + SVL_DLLPRIVATE BOOL ImpGetDateOutput( double fNumber, + USHORT nIx, + String& OutString ); + SVL_DLLPRIVATE BOOL ImpGetTimeOutput( double fNumber, + USHORT nIx, + String& OutString ); + SVL_DLLPRIVATE BOOL ImpGetDateTimeOutput( double fNumber, + USHORT nIx, + String& OutString ); + + // Switches to the "gregorian" calendar if the current calendar is + // non-"gregorian" and the era is a "Dummy" era of a calendar which doesn't + // know a "before" era (like zh_TW ROC or ja_JP Gengou). If switched and + // rOrgCalendar was "gregorian" the string is emptied. If rOrgCalendar was + // empty the previous calendar name and date/time are returned. + SVL_DLLPRIVATE BOOL ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime ); + + // Append a "G" short era string of the given calendar. In the case of a + // Gengou calendar this is a one character abbreviation, for other + // calendars the XExtendedCalendar::getDisplayString() method is called. + SVL_DLLPRIVATE static void ImpAppendEraG( String& OutString, const CalendarWrapper& rCal, + sal_Int16 nNatNum ); + + SVL_DLLPRIVATE BOOL ImpGetNumberOutput( double fNumber, + USHORT nIx, + String& OutString ); + + SVL_DLLPRIVATE void ImpCopyNumberformat( const SvNumberformat& rFormat ); + + // normal digits or other digits, depending on ImpSvNumFor.aNatNum, + // [NatNum1], [NatNum2], ... + SVL_DLLPRIVATE String ImpGetNatNumString( const SvNumberNatNum& rNum, sal_Int32 nVal, + USHORT nMinDigits = 0 ) const; + + String ImpIntToString( USHORT nIx, sal_Int32 nVal, USHORT nMinDigits = 0 ) const + { + const SvNumberNatNum& rNum = NumFor[nIx].GetNatNum(); + if ( nMinDigits || rNum.IsComplete() ) + return ImpGetNatNumString( rNum, nVal, nMinDigits ); + return String::CreateFromInt32( nVal ); + } + + // transliterate according to NativeNumber + SVL_DLLPRIVATE void ImpTransliterateImpl( String& rStr, const SvNumberNatNum& rNum ) const; + + void ImpTransliterate( String& rStr, const SvNumberNatNum& rNum ) const + { + if ( rNum.IsComplete() ) + ImpTransliterateImpl( rStr, rNum ); + } + +#endif // _ZFORMAT_CXX + +}; + +#endif // _ZFORMAT_HXX diff --git a/svl/inc/urihelper.hxx b/svl/inc/urihelper.hxx new file mode 100644 index 000000000000..8be500e438ce --- /dev/null +++ b/svl/inc/urihelper.hxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * 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: urihelper.hxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_URIHELPER_HXX +#define SVTOOLS_URIHELPER_HXX + +#include "svl/svldllapi.h" +#include "com/sun/star/uno/Reference.hxx" +#include <com/sun/star/uno/RuntimeException.hpp> +#include <rtl/textenc.h> +#include <tools/link.hxx> +#include <tools/solar.h> +#include <tools/urlobj.hxx> + +namespace com { namespace sun { namespace star { + namespace uno { class XComponentContext; } + namespace uri { class XUriReference; } +} } } +namespace rtl { class OUString; } +class ByteString; +class CharClass; +class UniString; + +//============================================================================ +namespace URIHelper { + +/** + @ATT + Calling this function with defaulted arguments rMaybeFileHdl = Link() and + bCheckFileExists = true often leads to results that are not intended: + Whenever the given rTheBaseURIRef is a file URL, the given rTheRelURIRef is + relative, and rTheRelURIRef could also be smart-parsed as a non-file URL + (e.g., the relative URL "foo/bar" can be smart-parsed as "http://foo/bar"), + then SmartRel2Abs called with rMaybeFileHdl = Link() and bCheckFileExists = + true returns the non-file URL interpretation. To avoid this, either pass + some non-null rMaybeFileHdl if you want to check generated file URLs for + existence (see URIHelper::GetMaybeFileHdl), or use bCheckFileExists = false + if you want to generate file URLs without checking for their existence. +*/ +SVL_DLLPUBLIC UniString +SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + ByteString const & rTheRelURIRef, + Link const & rMaybeFileHdl = Link(), + bool bCheckFileExists = true, + bool bIgnoreFragment = false, + INetURLObject::EncodeMechanism eEncodeMechanism + = INetURLObject::WAS_ENCODED, + INetURLObject::DecodeMechanism eDecodeMechanism + = INetURLObject::DECODE_TO_IURI, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8, + bool bRelativeNonURIs = false, + INetURLObject::FSysStyle eStyle = INetURLObject::FSYS_DETECT); + +/** + @ATT + Calling this function with defaulted arguments rMaybeFileHdl = Link() and + bCheckFileExists = true often leads to results that are not intended: + Whenever the given rTheBaseURIRef is a file URL, the given rTheRelURIRef is + relative, and rTheRelURIRef could also be smart-parsed as a non-file URL + (e.g., the relative URL "foo/bar" can be smart-parsed as "http://foo/bar"), + then SmartRel2Abs called with rMaybeFileHdl = Link() and bCheckFileExists = + true returns the non-file URL interpretation. To avoid this, either pass + some non-null rMaybeFileHdl if you want to check generated file URLs for + existence (see URIHelper::GetMaybeFileHdl), or use bCheckFileExists = false + if you want to generate file URLs without checking for their existence. +*/ +SVL_DLLPUBLIC UniString +SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + UniString const & rTheRelURIRef, + Link const & rMaybeFileHdl = Link(), + bool bCheckFileExists = true, + bool bIgnoreFragment = false, + INetURLObject::EncodeMechanism eEncodeMechanism + = INetURLObject::WAS_ENCODED, + INetURLObject::DecodeMechanism eDecodeMechanism + = INetURLObject::DECODE_TO_IURI, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8, + bool bRelativeNonURIs = false, + INetURLObject::FSysStyle eStyle = INetURLObject::FSYS_DETECT); + +//============================================================================ +SVL_DLLPUBLIC void SetMaybeFileHdl(Link const & rTheMaybeFileHdl); + +//============================================================================ +SVL_DLLPUBLIC Link GetMaybeFileHdl(); + +/** + Converts a URI reference to a relative one, ignoring certain differences (for + example, treating file URLs for case-ignoring file systems + case-insensitively). + + @param context a component context; must not be null + + @param baseUriReference a base URI reference + + @param uriReference a URI reference + + @return a URI reference representing the given uriReference relative to the + given baseUriReference; if the given baseUriReference is not an absolute, + hierarchical URI reference, or the given uriReference is not a valid URI + reference, null is returned + + @exception std::bad_alloc if an out-of-memory condition occurs + + @exception com::sun::star::uno::RuntimeException if any error occurs + */ +SVL_DLLPUBLIC com::sun::star::uno::Reference< com::sun::star::uri::XUriReference > +normalizedMakeRelative( + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > + const & context, + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference); + +/** + A variant of normalizedMakeRelative with a simplified interface. + + Internally calls normalizedMakeRelative with the default component context. + + @param baseUriReference a base URI reference, passed to + normalizedMakeRelative + + @param uriReference a URI reference, passed to normalizedMakeRelative + + @return if the XUriReference returnd by normalizedMakeRelative is empty, + uriReference is returned unmodified; otherwise, the result of calling + XUriReference::getUriReference on the XUriReference returnd by + normalizedMakeRelative is returned + + @exception std::bad_alloc if an out-of-memory condition occurs + + @exception com::sun::star::uno::RuntimeException if any error occurs + + @deprecated + No code should rely on the default component context. +*/ +SVL_DLLPUBLIC rtl::OUString simpleNormalizedMakeRelative( + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference); + +//============================================================================ +SVL_DLLPUBLIC UniString +FindFirstURLInText(UniString const & rText, + xub_StrLen & rBegin, + xub_StrLen & rEnd, + CharClass const & rCharClass, + INetURLObject::EncodeMechanism eMechanism + = INetURLObject::WAS_ENCODED, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8, + INetURLObject::FSysStyle eStyle + = INetURLObject::FSYS_DETECT); + +//============================================================================ +/** Remove any password component from both absolute and relative URLs. + + @ATT The current implementation will not remove a password from a + relative URL that has an authority component (e.g., the password is not + removed from the relative ftp URL <//user:password@domain/path>). But + since our functions to translate between absolute and relative URLs never + produce relative URLs with authority components, this is no real problem. + + @ATT For relative URLs (or anything not recognized as an absolute URI), + the current implementation will return the input unmodified, not applying + any translations implied by the encode/decode parameters. + + @param rURI An absolute or relative URI reference. + + @param eEncodeMechanism See the general discussion for INetURLObject set- + methods. + + @param eDecodeMechanism See the general discussion for INetURLObject get- + methods. + + @param eCharset See the general discussion for INetURLObject get- and + set-methods. + + @return The input URI with any password component removed. + */ +SVL_DLLPUBLIC UniString +removePassword(UniString const & rURI, + INetURLObject::EncodeMechanism eEncodeMechanism + = INetURLObject::WAS_ENCODED, + INetURLObject::DecodeMechanism eDecodeMechanism + = INetURLObject::DECODE_TO_IURI, + rtl_TextEncoding eCharset = RTL_TEXTENCODING_UTF8); + +//============================================================================ +/** Query the notational conventions used in the file system provided by some + file content provider. + + @param rFileUrl This file URL determines which file content provider is + used to query the desired information. (The UCB's usual mapping from URLs + to content providers is used.) + + @param bAddConvenienceStyles If true, the return value contains not only + the style bit corresponding to the queried content provider's conventions, + but may also contain additional style bits that make using this function + more convenient in certain situations. Currently, the effect is that + FSYS_UNX is extended with FSYS_VOS, and both FSYS_DOS and FSYS_MAC are + extended with FSYS_VOS and FSYS_UNX (i.e., the---unambiguous---detection + of VOS style and Unix style file system paths is always enabled); also, in + case the content provider's conventions cannot be determined, FSYS_DETECT + is returned instead of FSysStyle(0). + + @return The style bit corresponding to the queried content provider's + conventions, or FSysStyle(0) if these cannot be determined. + */ +SVL_DLLPUBLIC INetURLObject::FSysStyle queryFSysStyle(UniString const & rFileUrl, + bool bAddConvenienceStyles = true) + throw (com::sun::star::uno::RuntimeException); + +} + +#endif // SVTOOLS_URIHELPER_HXX diff --git a/svl/inc/urlbmk.hxx b/svl/inc/urlbmk.hxx new file mode 100644 index 000000000000..d3342b398878 --- /dev/null +++ b/svl/inc/urlbmk.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: urlbmk.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _URLBMK_HXX +#define _URLBMK_HXX + + +#include <tools/string.hxx> + +//========================================================================= + +class INetBookmark + +/* [Beschreibung] + + Diese Klasse stellt ein Bookmark dar, welches aus einer URL und + einem dazuge"horigen Beschreibungstext besteht. + + Es gibt ein eigenes Clipboardformat und Hilfsmethoden zum Kopieren + und Einf"ugen in und aus Clipboard und DragServer. +*/ + +{ + String aUrl; + String aDescr; + +protected: + + void SetURL( const String& rS ) { aUrl = rS; } + void SetDescription( const String& rS ) { aDescr = rS; } + +public: + INetBookmark( const String &rUrl, const String &rDescr ) + : aUrl( rUrl ), aDescr( rDescr ) + {} + INetBookmark() + {} + + const String& GetURL() const { return aUrl; } + const String& GetDescription() const { return aDescr; } +}; + + +#endif + diff --git a/svl/inc/whiter.hxx b/svl/inc/whiter.hxx new file mode 100644 index 000000000000..d2bd7c88d521 --- /dev/null +++ b/svl/inc/whiter.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * 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: whiter.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_WHITER_HXX +#define _SFX_WHITER_HXX + +#include "svl/svldllapi.h" + +#ifndef INCLUDED_LIMITS_H +#include <limits.h> +#define INCLUDED_LIMITS_H +#endif +#include <tools/solar.h> + +class SfxItemSet; + + +// INCLUDE --------------------------------------------------------------- + +class SVL_DLLPUBLIC SfxWhichIter +{ + const USHORT *pRanges, *pStart; + USHORT nOfst, nFrom, nTo; + +public: + SfxWhichIter( const SfxItemSet& rSet, USHORT nFrom = 0, USHORT nTo = USHRT_MAX ); + ~SfxWhichIter(); + + USHORT GetCurWhich() const { return *pRanges + nOfst; } + USHORT NextWhich(); + USHORT PrevWhich(); + + USHORT FirstWhich(); + USHORT LastWhich(); +}; + +#endif diff --git a/svl/inc/xmlement.hxx b/svl/inc/xmlement.hxx new file mode 100644 index 000000000000..ed0e4dafc57a --- /dev/null +++ b/svl/inc/xmlement.hxx @@ -0,0 +1,46 @@ +/************************************************************************* + * + * 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: xmlement.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_XMLEMENT_HXX +#define _SVTOOLS_XMLEMENT_HXX + +#ifndef _SAL_TYPES_H +#include <sal/types.h> +#endif + +struct SvXMLEnumMapEntry +{ + const sal_Char *pName; + sal_uInt16 nValue; +}; + + +#endif // _SVTOOLS_XMLEMENT_HXX + diff --git a/svl/prj/build.lst b/svl/prj/build.lst new file mode 100644 index 000000000000..f2d4bf324d01 --- /dev/null +++ b/svl/prj/build.lst @@ -0,0 +1,22 @@ +sl svl : l10n rsc offuh ucbhelper unotools cppu cppuhelper comphelper sal sot NULL +sl svl usr1 - all svl_mkout NULL +sl svl\inc nmake - all svl_inc NULL +sl svl\unx\source\svdde nmake - u svl_usdde svl_inc NULL +sl svl\unx\source\svdde nmake - p svl_psdde svl_inc NULL +sl svl\source\config nmake - all svl_conf svl_inc NULL +sl svl\source\filepicker nmake - all svl_filepick svl_inc NULL +sl svl\source\filerec nmake - all svl_file svl_inc NULL +sl svl\source\items nmake - all svl__item svl_inc NULL +sl svl\source\memtools nmake - all svl_mem svl_inc NULL +sl svl\source\misc nmake - all svl__misc svl_inc NULL +sl svl\source\notify nmake - all svl_not svl_inc NULL +sl svl\source\numbers nmake - all svl_num svl_inc NULL +sl svl\source\svdde nmake - all svl__dde svl_inc NULL +sl svl\source\svsql nmake - all svl_sql svl_inc NULL +sl svl\source\undo nmake - all svl_undo svl_inc NULL +sl svl\source\uno nmake - all svl_uno svl_inc NULL +sl svl\util nmake - all svl_util svl_usdde.u svl_psdde.p svl_conf svl_filepick svl_file svl__item svl_mem svl__misc svl_not svl_num svl__dde svl_sql svl_undo svl_uno NULL +sl svl\source\fsstor nmake - all svl_fsstor svl_inc NULL +sl svl\source\passwordcontainer nmake - all svl_passcont svl_inc NULL + + diff --git a/svl/prj/d.lst b/svl/prj/d.lst new file mode 100644 index 000000000000..a5c2564e81cd --- /dev/null +++ b/svl/prj/d.lst @@ -0,0 +1,22 @@ +mkdir: %COMMON_DEST%\bin%_EXT%\hid +mkdir: %COMMON_DEST%\res%_EXT% +mkdir: %_DEST%\inc%_EXT%\svl + +..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid +..\%__SRC%\lib\isvl.lib %_DEST%\lib%_EXT%\isvl.lib +..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\* +..\%__SRC%\bin\*.res %_DEST%\bin%_EXT%\* +..\%__SRC%\lib\*.so %_DEST%\lib%_EXT%\* +..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\* + +..\inc\svl\*.hrc %_DEST%\inc%_EXT%\svl\*.hrc +..\inc\svl\*.hxx %_DEST%\inc%_EXT%\svl\*.hxx +..\inc\svl\*.h %_DEST%\inc%_EXT%\svl\*.h +..\inc\*.hrc %_DEST%\inc%_EXT%\svl\*.hrc +..\inc\*.hxx %_DEST%\inc%_EXT%\svl\*.hxx +..\inc\*.h %_DEST%\inc%_EXT%\svl\*.h + +dos: sh -c "if test %OS% = MACOSX; then macosx-create-bundle %_DEST%\bin%_EXT%\bmp=%__PRJROOT%\%__SRC%\bin%_EXT%; fi" + +*.xml %_DEST%\xml%_EXT%\*.xml + diff --git a/svl/qa/complex/ConfigItems/CheckConfigItems.java b/svl/qa/complex/ConfigItems/CheckConfigItems.java new file mode 100644 index 000000000000..6f4d0ba3d945 --- /dev/null +++ b/svl/qa/complex/ConfigItems/CheckConfigItems.java @@ -0,0 +1,186 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CheckConfigItems.java,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:22 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +package complex.ConfigItems; + +import com.sun.star.beans.*; +import com.sun.star.lang.*; +import com.sun.star.uno.*; +import com.sun.star.task.*; + +import complexlib.*; + +import java.lang.*; +import java.util.*; + +//----------------------------------------------- +/** @short todo document me + */ +public class CheckConfigItems extends ComplexTestCase +{ + //------------------------------------------- + // some const + + //------------------------------------------- + // member + + /** points to the global uno service manager. */ + private XMultiServiceFactory m_xSmgr = null; + + /** implements real config item tests in C++. */ + private XJob m_xTest = null; + + //------------------------------------------- + // test environment + + //------------------------------------------- + /** @short A function to tell the framework, + which test functions are available. + + @return All test methods. + @todo Think about selection of tests from outside ... + */ + public String[] getTestMethodNames() + { + return new String[] + { + "checkPicklist", + "checkURLHistory", + "checkHelpBookmarks", + "checkPrintOptions", + "checkAccessibilityOptions", + "checkUserOptions" + }; + } + + //------------------------------------------- + /** @short Create the environment for following tests. + + @descr Use either a component loader from desktop or + from frame + */ + public void before() + throws java.lang.Exception + { + // get uno service manager from global test environment + m_xSmgr = (XMultiServiceFactory)param.getMSF(); + + // TODO register helper service + + // create module manager + m_xTest = (XJob)UnoRuntime.queryInterface( + XJob.class, + m_xSmgr.createInstance("com.sun.star.comp.svl.ConfigItemTest")); + } + + //------------------------------------------- + /** @short close the environment. + */ + public void after() + throws java.lang.Exception + { + // TODO deregister helper service + + m_xTest = null; + m_xSmgr = null; + } + + //------------------------------------------- + /** @todo document me + */ + public void checkPicklist() + throws java.lang.Exception + { + impl_triggerTest("checkPicklist"); + } + + //------------------------------------------- + /** @todo document me + */ + public void checkURLHistory() + throws java.lang.Exception + { + impl_triggerTest("checkURLHistory"); + } + + //------------------------------------------- + /** @todo document me + */ + public void checkHelpBookmarks() + throws java.lang.Exception + { + impl_triggerTest("checkHelpBookmarks"); + } + + //------------------------------------------- + /** @todo document me + */ + public void checkPrintOptions() + throws java.lang.Exception + { + impl_triggerTest("checkPrintOptions"); + } + + //------------------------------------------- + /** @todo document me + */ + public void checkAccessibilityOptions() + throws java.lang.Exception + { + impl_triggerTest("checkAccessibilityOptions"); + } + + //------------------------------------------- + /** @todo document me + */ + public void checkUserOptions() + throws java.lang.Exception + { + impl_triggerTest("checkUserOptions"); + } + + //------------------------------------------- + /** @todo document me + */ + private void impl_triggerTest(String sTest) + throws java.lang.Exception + { + NamedValue[] lArgs = new NamedValue[1]; + lArgs[0] = new NamedValue(); + lArgs[0].Name = "Test"; + lArgs[0].Value = sTest; + m_xTest.execute(lArgs); + } +} diff --git a/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.cxx b/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.cxx new file mode 100644 index 000000000000..d853bf926467 --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.cxx @@ -0,0 +1,400 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibilityOptTest.cxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:23 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "AccessibilityOptTest.hxx" +#include "configitems/accessibilityoptions_const.hxx" + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + +#include <comphelper/configurationhelper.hxx> +#include <unotools/processfactory.hxx> + +namespace css = ::com::sun::star; + +AccessibilityOptTest::AccessibilityOptTest() +{ + m_xCfg = css::uno::Reference< css::container::XNameAccess >( + ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + s_sAccessibility, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY); +} + +AccessibilityOptTest::~AccessibilityOptTest() +{ + if (m_xCfg.is()) + m_xCfg.clear(); +} + +//============================================================================= +//test GetAutoDetectSystemHC() +void AccessibilityOptTest::impl_checkGetAutoDetectSystemHC() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bAutoDetectSystemHC; + sal_Bool bAutoDetectSystemHC_; + + bAutoDetectSystemHC = aAccessibilityOpt.GetAutoDetectSystemHC(); + xSet->setPropertyValue( s_sAutoDetectSystemHC, css::uno::makeAny(bAutoDetectSystemHC ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bAutoDetectSystemHC_ = aAccessibilityOpt.GetAutoDetectSystemHC(); + + if ( bAutoDetectSystemHC_ == bAutoDetectSystemHC )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetAutoDetectSystemHC() error!")), 0); +} + +//============================================================================= +//test GetIsForPagePreviews() +void AccessibilityOptTest::impl_checkGetIsForPagePreviews() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsForPagePreviews ; + sal_Bool bIsForPagePreviews_; + + bIsForPagePreviews = aAccessibilityOpt.GetIsForPagePreviews(); + xSet->setPropertyValue( s_sIsForPagePreviews, css::uno::makeAny(bIsForPagePreviews ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsForPagePreviews_ = aAccessibilityOpt.GetIsForPagePreviews(); + + if ( bIsForPagePreviews_ == bIsForPagePreviews )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsForPagePreviews() error!")), 0); +} + +//============================================================================= +//test impl_checkGetIsHelpTipsDisappear() +void AccessibilityOptTest::impl_checkGetIsHelpTipsDisappear() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsHelpTipsDisappear ; + sal_Bool bIsHelpTipsDisappear_; + + bIsHelpTipsDisappear = aAccessibilityOpt.GetIsHelpTipsDisappear(); + xSet->setPropertyValue( s_sIsHelpTipsDisappear, css::uno::makeAny(bIsHelpTipsDisappear ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsHelpTipsDisappear_ = aAccessibilityOpt.GetIsHelpTipsDisappear(); + + if ( bIsHelpTipsDisappear_ == bIsHelpTipsDisappear )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsHelpTipsDisappear() error!")), 0); +} + +//============================================================================= +//test impl_checkGetIsAllowAnimatedGraphics() +void AccessibilityOptTest::impl_checkGetIsAllowAnimatedGraphics() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAllowAnimatedGraphics ; + sal_Bool bIsAllowAnimatedGraphics_; + + bIsAllowAnimatedGraphics = aAccessibilityOpt.GetIsAllowAnimatedGraphics(); + xSet->setPropertyValue( s_sIsAllowAnimatedGraphics, css::uno::makeAny(bIsAllowAnimatedGraphics ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsAllowAnimatedGraphics_ = aAccessibilityOpt.GetIsAllowAnimatedGraphics(); + + if ( bIsAllowAnimatedGraphics_ == bIsAllowAnimatedGraphics )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsAllowAnimatedGraphics() error!")), 0); +} + +//============================================================================= +//test impl_checkGetIsAllowAnimatedText() +void AccessibilityOptTest::impl_checkGetIsAllowAnimatedText() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAllowAnimatedText ; + sal_Bool bIsAllowAnimatedText_; + + bIsAllowAnimatedText = aAccessibilityOpt.GetIsAllowAnimatedText(); + xSet->setPropertyValue( s_sIsAllowAnimatedText, css::uno::makeAny(bIsAllowAnimatedText ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsAllowAnimatedText_ = aAccessibilityOpt.GetIsAllowAnimatedText(); + + if ( bIsAllowAnimatedText_ == bIsAllowAnimatedText )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsAllowAnimatedText() error!")), 0); +} + +//============================================================================= +//test impl_checkGetIsAutomaticFontColor() +void AccessibilityOptTest::impl_checkGetIsAutomaticFontColor() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAutomaticFontColor ; + sal_Bool bIsAutomaticFontColor_; + + bIsAutomaticFontColor = aAccessibilityOpt.GetIsAutomaticFontColor(); + xSet->setPropertyValue( s_sIsAutomaticFontColor, css::uno::makeAny(bIsAutomaticFontColor ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsAutomaticFontColor_ = aAccessibilityOpt.GetIsAutomaticFontColor(); + + if ( bIsAutomaticFontColor_ == bIsAutomaticFontColor )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsAutomaticFontColor() error!")), 0); +} + +//============================================================================= +//test impl_checkGetIsSystemFont() +void AccessibilityOptTest::impl_checkGetIsSystemFont() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsSystemFont ; + sal_Bool bIsSystemFont_; + + bIsSystemFont = aAccessibilityOpt.GetIsSystemFont(); + xSet->setPropertyValue( s_sIsSystemFont, css::uno::makeAny(bIsSystemFont ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsSystemFont_ = aAccessibilityOpt.GetIsSystemFont(); + + if ( bIsSystemFont_ == bIsSystemFont )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetIsSystemFont() error!")), 0); +} + +//============================================================================= +//test impl_checkGetHelpTipSeconds() +void AccessibilityOptTest::impl_checkGetHelpTipSeconds() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Int16 nHelpTipSeconds ; + sal_Int16 nHelpTipSeconds_; + + nHelpTipSeconds = aAccessibilityOpt.GetHelpTipSeconds(); + xSet->setPropertyValue( s_sHelpTipSeconds, css::uno::makeAny(sal_Int16(nHelpTipSeconds+1)) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + nHelpTipSeconds_ = aAccessibilityOpt.GetHelpTipSeconds(); + + if ( nHelpTipSeconds_ == nHelpTipSeconds )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetHelpTipSeconds() error!")), 0); +} + +//============================================================================= +//test impl_checkIsSelectionInReadonly() +void AccessibilityOptTest::impl_checkIsSelectionInReadonly() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsSelectionInReadonly ; + sal_Bool bIsSelectionInReadonly_; + + bIsSelectionInReadonly = aAccessibilityOpt.IsSelectionInReadonly(); + xSet->setPropertyValue( s_sIsSelectionInReadonly, css::uno::makeAny(bIsSelectionInReadonly ? sal_False:sal_True) ); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + bIsSelectionInReadonly_ = aAccessibilityOpt.IsSelectionInReadonly(); + + if ( bIsSelectionInReadonly_ == bIsSelectionInReadonly )//old config item will not throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsSelectionInReadonly() error!")), 0); +} + +//============================================================================= +//test SetAutoDetectSystemHC() +void AccessibilityOptTest::impl_checkSetAutoDetectSystemHC() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bAutoDetectSystemHC; + sal_Bool bAutoDetectSystemHC_; + + xSet->getPropertyValue(s_sAutoDetectSystemHC) >>= bAutoDetectSystemHC; + aAccessibilityOpt.SetAutoDetectSystemHC( bAutoDetectSystemHC ? sal_False:sal_True ); + xSet->getPropertyValue(s_sAutoDetectSystemHC) >>= bAutoDetectSystemHC_; + + if ( bAutoDetectSystemHC_ == bAutoDetectSystemHC )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetAutoDetectSystemHC() error!")), 0); +} + +//============================================================================= +//test SetIsForPagePreviews() +void AccessibilityOptTest::impl_checkSetIsForPagePreviews() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsForPagePreviews ; + sal_Bool bIsForPagePreviews_; + + xSet->getPropertyValue(s_sIsForPagePreviews) >>= bIsForPagePreviews; + aAccessibilityOpt.SetIsForPagePreviews( bIsForPagePreviews ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsForPagePreviews) >>= bIsForPagePreviews_; + + if ( bIsForPagePreviews_ == bIsForPagePreviews )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsForPagePreviews() error!")), 0); +} + +//============================================================================= +//test impl_checkSetIsHelpTipsDisappear() +void AccessibilityOptTest::impl_checkSetIsHelpTipsDisappear() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsHelpTipsDisappear ; + sal_Bool bIsHelpTipsDisappear_; + + xSet->getPropertyValue(s_sIsHelpTipsDisappear) >>= bIsHelpTipsDisappear; + aAccessibilityOpt.SetIsHelpTipsDisappear( bIsHelpTipsDisappear ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsHelpTipsDisappear) >>= bIsHelpTipsDisappear_; + + if ( bIsHelpTipsDisappear_ == bIsHelpTipsDisappear )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsHelpTipsDisappear() error!")), 0); +} + +//============================================================================= +//test impl_checkSetIsAllowAnimatedGraphics() +void AccessibilityOptTest::impl_checkSetIsAllowAnimatedGraphics() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAllowAnimatedGraphics ; + sal_Bool bIsAllowAnimatedGraphics_; + + xSet->getPropertyValue(s_sIsAllowAnimatedGraphics) >>= bIsAllowAnimatedGraphics; + aAccessibilityOpt.SetIsAllowAnimatedGraphics( bIsAllowAnimatedGraphics ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsAllowAnimatedGraphics) >>= bIsAllowAnimatedGraphics_; + + if ( bIsAllowAnimatedGraphics_ == bIsAllowAnimatedGraphics )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsAllowAnimatedGraphics() error!")), 0); +} + +//============================================================================= +//test impl_checkSetIsAllowAnimatedText() +void AccessibilityOptTest::impl_checkSetIsAllowAnimatedText() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAllowAnimatedText ; + sal_Bool bIsAllowAnimatedText_; + + xSet->getPropertyValue(s_sIsAllowAnimatedText) >>= bIsAllowAnimatedText; + aAccessibilityOpt.SetIsAllowAnimatedText( bIsAllowAnimatedText ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsAllowAnimatedText) >>= bIsAllowAnimatedText_; + + if ( bIsAllowAnimatedText_ == bIsAllowAnimatedText )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsAllowAnimatedText() error!")), 0); +} + +//============================================================================= +//test impl_checkSetIsAutomaticFontColor() +void AccessibilityOptTest::impl_checkSetIsAutomaticFontColor() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsAutomaticFontColor ; + sal_Bool bIsAutomaticFontColor_; + + xSet->getPropertyValue(s_sIsAutomaticFontColor) >>= bIsAutomaticFontColor; + aAccessibilityOpt.SetIsAutomaticFontColor( bIsAutomaticFontColor ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsAutomaticFontColor) >>= bIsAutomaticFontColor_; + + if ( bIsAutomaticFontColor_ == bIsAutomaticFontColor )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsAutomaticFontColor() error!")), 0); +} + +//============================================================================= +//test impl_checkSetIsSystemFont() +void AccessibilityOptTest::impl_checkSetIsSystemFont() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsSystemFont ; + sal_Bool bIsSystemFont_; + + xSet->getPropertyValue(s_sIsSystemFont) >>= bIsSystemFont; + aAccessibilityOpt.SetIsSystemFont( bIsSystemFont ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsSystemFont) >>= bIsSystemFont_; + + if ( bIsSystemFont_ == bIsSystemFont )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetIsSystemFont() error!")), 0); +} + +//============================================================================= +//test impl_checkSetHelpTipSeconds() +void AccessibilityOptTest::impl_checkSetHelpTipSeconds() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Int16 nHelpTipSeconds ; + sal_Int16 nHelpTipSeconds_; + + xSet->getPropertyValue(s_sHelpTipSeconds) >>= nHelpTipSeconds; + aAccessibilityOpt.SetHelpTipSeconds( sal_Int16(nHelpTipSeconds+1) ); + xSet->getPropertyValue(s_sHelpTipSeconds) >>= nHelpTipSeconds_; + + if ( nHelpTipSeconds_ == nHelpTipSeconds )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetHelpTipSeconds() error!")), 0); +} + +//============================================================================= +//test impl_checkSetSelectionInReadonly() +void AccessibilityOptTest::impl_checkSetSelectionInReadonly() +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCfg, css::uno::UNO_QUERY); + sal_Bool bIsSelectionInReadonly ; + sal_Bool bIsSelectionInReadonly_; + + xSet->getPropertyValue(s_sIsSelectionInReadonly) >>= bIsSelectionInReadonly; + aAccessibilityOpt.SetSelectionInReadonly( bIsSelectionInReadonly ? sal_False:sal_True ); + xSet->getPropertyValue(s_sIsSelectionInReadonly) >>= bIsSelectionInReadonly_; + + if ( bIsSelectionInReadonly_ == bIsSelectionInReadonly )//old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetSelectionInReadonly() error!")), 0); +} + +//============================================================================= +void AccessibilityOptTest::impl_checkAccessibilityOptions() +{ + impl_checkGetAutoDetectSystemHC(); + impl_checkGetIsForPagePreviews(); + impl_checkGetIsHelpTipsDisappear(); + impl_checkGetIsAllowAnimatedGraphics(); + impl_checkGetIsAllowAnimatedText(); + impl_checkGetIsAutomaticFontColor(); + impl_checkGetIsSystemFont(); + impl_checkGetHelpTipSeconds(); + impl_checkIsSelectionInReadonly(); + + impl_checkSetAutoDetectSystemHC(); + impl_checkSetIsForPagePreviews(); + impl_checkSetIsHelpTipsDisappear(); + impl_checkSetIsAllowAnimatedGraphics(); + impl_checkSetIsAllowAnimatedText(); + impl_checkSetIsAutomaticFontColor(); + impl_checkSetIsSystemFont(); + impl_checkSetHelpTipSeconds(); + impl_checkSetSelectionInReadonly(); +} diff --git a/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.hxx b/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.hxx new file mode 100644 index 000000000000..58bb58f8c215 --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/AccessibilityOptTest.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibilityOptTest.hxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:23 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SVTOOLS_ACCESSIBILITYOPTTEST_HXX +#define SVTOOLS_ACCESSIBILITYOPTTEST_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <svl/accessibilityoptions.hxx> + +namespace css = ::com::sun::star; + +class AccessibilityOptTest +{ +public: + AccessibilityOptTest(); + ~AccessibilityOptTest(); + + void impl_checkAccessibilityOptions(); + +private: + void impl_checkGetAutoDetectSystemHC(); + void impl_checkGetIsForPagePreviews(); + void impl_checkGetIsHelpTipsDisappear(); + void impl_checkGetIsAllowAnimatedGraphics(); + void impl_checkGetIsAllowAnimatedText(); + void impl_checkGetIsAutomaticFontColor(); + void impl_checkGetIsSystemFont(); + void impl_checkGetHelpTipSeconds(); + void impl_checkIsSelectionInReadonly(); + + void impl_checkSetAutoDetectSystemHC(); + void impl_checkSetIsForPagePreviews(); + void impl_checkSetIsHelpTipsDisappear(); + void impl_checkSetIsAllowAnimatedGraphics(); + void impl_checkSetIsAllowAnimatedText(); + void impl_checkSetIsAutomaticFontColor(); + void impl_checkSetIsSystemFont(); + void impl_checkSetHelpTipSeconds(); + void impl_checkSetSelectionInReadonly(); + +private: + css::uno::Reference< css::container::XNameAccess > m_xCfg; + SvtAccessibilityOptions aAccessibilityOpt; +}; + +#endif // #ifndef SVTOOLS_ACCESSIBILITYOPTTEST_HXX diff --git a/svl/qa/complex/ConfigItems/helper/ConfigItemTest.cxx b/svl/qa/complex/ConfigItems/helper/ConfigItemTest.cxx new file mode 100644 index 000000000000..ad9dda313a5c --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/ConfigItemTest.cxx @@ -0,0 +1,253 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConfigItemTest.cxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:23 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "HistoryOptTest.hxx" +#include "AccessibilityOptTest.hxx" +#include "PrintOptTest.hxx" +#include "UserOptTest.hxx" + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/task/XJob.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implementationentry.hxx> + +//============================================================================= +namespace css = ::com::sun::star; + +namespace svl{ + +//============================================================================= +static const ::rtl::OUString PROP_TEST = ::rtl::OUString::createFromAscii("Test"); +static const ::rtl::OUString TEST_PICKLIST = ::rtl::OUString::createFromAscii("checkPicklist"); +static const ::rtl::OUString TEST_URLHISTORY = ::rtl::OUString::createFromAscii("checkURLHistory"); +static const ::rtl::OUString TEST_HELPBOOKMARKS = ::rtl::OUString::createFromAscii("checkHelpBookmarks"); +static const ::rtl::OUString TEST_ACCESSIBILITYOPTIONS = ::rtl::OUString::createFromAscii("checkAccessibilityOptions"); +static const ::rtl::OUString TEST_PRINTOPTIONS = ::rtl::OUString::createFromAscii("checkPrintOptions"); +static const ::rtl::OUString TEST_USEROPTIONS = ::rtl::OUString::createFromAscii("checkUserOptions"); + +//============================================================================= +class ConfigItemTest : public ::cppu::WeakImplHelper2< css::task::XJob , + css::lang::XServiceInfo > +{ + //------------------------------------------------------------------------- + // interface + public: + explicit ConfigItemTest(const css::uno::Reference< css::uno::XComponentContext >& xContext); + + // css::task::XJob + virtual css::uno::Any SAL_CALL execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments) + throw (css::uno::RuntimeException , + css::lang::IllegalArgumentException, + css::uno::Exception ); + + // css::lang::XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL supportsService(const ::rtl::OUString& sServiceName) + throw (css::uno::RuntimeException); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException); + + //------------------------------------------------------------------------- + // internal + private: + ConfigItemTest(ConfigItemTest &); // not defined + virtual ~ConfigItemTest() {} + void operator=(ConfigItemTest &); // not defined + + //------------------------------------------------------------------------- + // helper for registration ! + public: + static ::rtl::OUString SAL_CALL st_getImplementationName(); + static css::uno::Sequence< ::rtl::OUString > SAL_CALL st_getSupportedServiceNames(); + static css::uno::Reference< css::uno::XInterface > SAL_CALL st_create(const css::uno::Reference< css::uno::XComponentContext >& XContext); + + //------------------------------------------------------------------------- + // member + private: + css::uno::Reference< css::uno::XComponentContext > m_xContext; +}; + +//============================================================================= +ConfigItemTest::ConfigItemTest(const css::uno::Reference< css::uno::XComponentContext >& xContext) + : m_xContext(xContext) +{} + +//============================================================================= +// css::task::XJob +css::uno::Any SAL_CALL ConfigItemTest::execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments) + throw (css::uno::RuntimeException , + css::lang::IllegalArgumentException, + css::uno::Exception ) +{ + ::rtl::OUString sTest; + ::sal_Int32 i = 0; + ::sal_Int32 c = lArguments.getLength(); + for (i=0; i<c; ++i) + { + const css::beans::NamedValue& rArg = lArguments[0]; + if (rArg.Name.equals(PROP_TEST)) + rArg.Value >>= sTest; + } + + if (sTest.equals(TEST_PICKLIST)) + { + HistoryOptTest aOptTest; + aOptTest.checkPicklist(); + } + else if (sTest.equals(TEST_URLHISTORY)) + { + HistoryOptTest aOptTest; + aOptTest.checkURLHistory(); + } + else if (sTest.equals(TEST_HELPBOOKMARKS)) + { + HistoryOptTest aOptTest; + aOptTest.checkHelpBookmarks(); + } + else if (sTest.equals(TEST_ACCESSIBILITYOPTIONS)) + { + AccessibilityOptTest aOptTest; + aOptTest.impl_checkAccessibilityOptions(); + } + else if (sTest.equals(TEST_PRINTOPTIONS)) + { + PrintOptTest aOptTest; + aOptTest.impl_checkPrint(); + } + else if (sTest.equals(TEST_USEROPTIONS)) + { + UserOptTest aOptTest; + aOptTest.impl_checkUserData(); + } + + return css::uno::Any(); +} + +//============================================================================= +// com::sun::star::uno::XServiceInfo +::rtl::OUString SAL_CALL ConfigItemTest::getImplementationName() + throw (css::uno::RuntimeException) +{ + return ConfigItemTest::st_getImplementationName(); +} + +//============================================================================= +// com::sun::star::uno::XServiceInfo +::sal_Bool SAL_CALL ConfigItemTest::supportsService(const ::rtl::OUString& sServiceName) + throw (css::uno::RuntimeException) +{ + css::uno::Sequence< ::rtl::OUString > lServiceNames = ConfigItemTest::st_getSupportedServiceNames(); + for (::sal_Int32 i = 0; i < lServiceNames.getLength(); ++i) + { + if (lServiceNames[i].equals(sServiceName)) + return sal_True; + } + return sal_False; +} + +//============================================================================= +// com::sun::star::uno::XServiceInfo +css::uno::Sequence< ::rtl::OUString > SAL_CALL ConfigItemTest::getSupportedServiceNames() + throw (css::uno::RuntimeException) +{ + return ConfigItemTest::st_getSupportedServiceNames(); +} + +//============================================================================= +::rtl::OUString SAL_CALL ConfigItemTest::st_getImplementationName() +{ + return ::rtl::OUString::createFromAscii("com.sun.star.comp.svl.ConfigItemTest"); +} + +//============================================================================= +css::uno::Sequence< ::rtl::OUString > SAL_CALL ConfigItemTest::st_getSupportedServiceNames() +{ + css::uno::Sequence< ::rtl::OUString > lServices(1); + lServices[0] = ::rtl::OUString::createFromAscii("com.sun.star.test.ConfigItems"); + return lServices; +} + +//============================================================================= +css::uno::Reference< css::uno::XInterface > SAL_CALL ConfigItemTest::st_create(const css::uno::Reference< css::uno::XComponentContext >& xContext) +{ + ConfigItemTest* pObject = new ConfigItemTest(xContext); + css::uno::Reference< css::uno::XInterface > xObject (static_cast< ::cppu::OWeakObject* >(pObject)); + return xObject; +} + +} // namespace svl + +//============================================================================= +static ::cppu::ImplementationEntry const lRegEntries[] = +{ + { + &::svl::ConfigItemTest::st_create, + &::svl::ConfigItemTest::st_getImplementationName, + &::svl::ConfigItemTest::st_getSupportedServiceNames, + &::cppu::createSingleComponentFactory, 0, 0 + }, + + { 0, 0, 0, 0, 0, 0 } +}; + +//============================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment(const char** pEnvTypeName, + uno_Environment** ) +{ + *pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//============================================================================= +extern "C" void * SAL_CALL component_getFactory(const char* sImplName , + void* pServiceManager, + void* pRegistryKey ) +{ + return ::cppu::component_getFactoryHelper(sImplName, pServiceManager, pRegistryKey, lRegEntries); +} + +//============================================================================= +extern "C" sal_Bool SAL_CALL component_writeInfo(void* pServiceManager, + void* pRegistryKey ) +{ + return ::cppu::component_writeInfoHelper(pServiceManager, pRegistryKey, lRegEntries); +} diff --git a/svl/qa/complex/ConfigItems/helper/HistoryOptTest.cxx b/svl/qa/complex/ConfigItems/helper/HistoryOptTest.cxx new file mode 100644 index 000000000000..082328835fca --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/HistoryOptTest.cxx @@ -0,0 +1,806 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: HistoryOptTest.cxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:23 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "HistoryOptTest.hxx" +#include <unotools/historyoptions_const.hxx> + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> + +#include <comphelper/configurationhelper.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <unotools/processfactory.hxx> + +namespace css = ::com::sun::star; + +//============================================================================= +static const ::rtl::OUString MESSAGE_CLEAR_FAILED = ::rtl::OUString::createFromAscii("Clearing the list failed."); +static const ::rtl::OUString MESSAGE_SETSIZE_FAILED = ::rtl::OUString::createFromAscii("Setting a new size for a list failed."); +static const ::rtl::OUString MESSAGE_MISS_HISTORY = ::rtl::OUString::createFromAscii("Could not get config access to history list inside config."); +static const ::rtl::OUString MESSAGE_MISS_ITEMLIST = ::rtl::OUString::createFromAscii("Could not get config access to item list inside config."); +static const ::rtl::OUString MESSAGE_MISS_ORDERLIST = ::rtl::OUString::createFromAscii("Could not get config access to order list inside config."); +static const ::rtl::OUString MESSAGE_MISS_ITEM = ::rtl::OUString::createFromAscii("Could not locate item."); +static const ::rtl::OUString MESSAGE_UNEXPECTED_ITEM = ::rtl::OUString::createFromAscii("Found an unexpected item."); +static const ::rtl::OUString MESSAGE_WRONG_ORDER = ::rtl::OUString::createFromAscii("Wrong order in history list."); + +//============================================================================= +HistoryOptTest::HistoryOptTest() + : m_aConfigItem ( ) + , m_eList (ePICKLIST) + , m_xHistoriesXCU( ) + , m_xCommonXCU ( ) +{ +} + +//============================================================================= +HistoryOptTest::~HistoryOptTest() +{ + m_xHistoriesXCU.clear(); + m_xCommonXCU.clear(); +} + +//============================================================================= +void HistoryOptTest::checkPicklist() +{ + impl_testHistory(ePICKLIST, 4); +} + +//============================================================================= +void HistoryOptTest::checkURLHistory() +{ + impl_testHistory(eHISTORY, 10); +} + +//============================================================================= +void HistoryOptTest::checkHelpBookmarks() +{ + impl_testHistory(eHELPBOOKMARKS, 100); +} + +//============================================================================= +void HistoryOptTest::impl_testHistory(EHistoryType eHistory , + ::sal_Int32 nMaxItems) +{ + try + { + m_eList = eHistory; + ::sal_Int32 c = nMaxItems; + ::sal_Int32 i = 0; + + impl_clearList( ); + impl_setSize (c); + + // a) fill list completely and check if all items could be realy created. + // But dont check its order here! Because every new item will change that order. + for (i=0; i<c; ++i) + { + impl_appendItem(i); + if ( ! impl_existsItem(i)) + throw css::uno::Exception(MESSAGE_MISS_ITEM, 0); + } + + // b) Check order of all items in list now. + // It must be reverse to the item number ... + // item max = index 0 + // item max-1 = index 1 + // ... + for (i=0; i<c; ++i) + { + ::sal_Int32 nExpectedIndex = (c-1)-i; + if ( ! impl_existsItemAtIndex(i, nExpectedIndex)) + throw css::uno::Exception(MESSAGE_WRONG_ORDER, 0); + } + + // c) increase prio of "first" item so it will switch + // to "second" and "second" will switch to "first" :-) + // Check also if all other items was not touched. + ::sal_Int32 nFirstItem = (c-1); + ::sal_Int32 nSecondItem = (c-2); + impl_appendItem(nSecondItem); + + if ( + ( ! impl_existsItemAtIndex(nSecondItem, 0)) || + ( ! impl_existsItemAtIndex(nFirstItem , 1)) + ) + throw css::uno::Exception(MESSAGE_WRONG_ORDER, 0); + + for (i=0; i<nSecondItem; ++i) + { + ::sal_Int32 nExpectedIndex = (c-1)-i; + if ( ! impl_existsItemAtIndex(i, nExpectedIndex)) + throw css::uno::Exception(MESSAGE_WRONG_ORDER, 0); + } + + // d) Check if appending new items will destroy the oldest one. + ::sal_Int32 nNewestItem = c; + ::sal_Int32 nOldestItem = 0; + + impl_appendItem(nNewestItem); + + if ( ! impl_existsItemAtIndex(nNewestItem, 0)) + throw css::uno::Exception(MESSAGE_WRONG_ORDER, 0); + + if (impl_existsItem(nOldestItem)) + throw css::uno::Exception(MESSAGE_UNEXPECTED_ITEM, 0); + + // e) Check if decreasing list size will remove oldest items. + // Note: impl_setSize() will make sure that 3 items exists only. + // Otherwhise it throws an exception. If we further check + // positions of three items no further items must be checked. + // They cant exists :-) + ::sal_Int32 nNewSize = 3; + impl_setSize(nNewSize); + if ( + ( ! impl_existsItemAtIndex(nNewestItem, 0)) || + ( ! impl_existsItemAtIndex(nSecondItem, 1)) || + ( ! impl_existsItemAtIndex(nFirstItem , 2)) + ) + throw css::uno::Exception(MESSAGE_WRONG_ORDER, 0); + + // finaly we should try to clean up all used structures so the same office can be used + // without problems :-) + impl_clearList(); + } + catch (const css::uno::Exception& ex) + { + impl_clearList(); + throw ex; + } + +} + +//============================================================================= +void HistoryOptTest::impl_clearList() +{ + m_aConfigItem.Clear(m_eList); + ::sal_Int32 nCount = m_aConfigItem.GetList(m_eList).getLength(); + + if (nCount != 0) + throw css::uno::Exception(MESSAGE_CLEAR_FAILED, 0); + + css::uno::Reference< css::container::XNameAccess > xList; + xList = impl_getItemList(); + nCount = xList->getElementNames().getLength(); + + if (nCount != 0) + throw css::uno::Exception(MESSAGE_CLEAR_FAILED, 0); + + xList = impl_getOrderList(); + nCount = xList->getElementNames().getLength(); + + if (nCount != 0) + throw css::uno::Exception(MESSAGE_CLEAR_FAILED, 0); +} + +//============================================================================= +void HistoryOptTest::impl_setSize(::sal_Int32 nSize) +{ + m_aConfigItem.SetSize (m_eList, nSize); + + // a) size info returned by GetSize() means "MaxSize" + // so it must match exactly ! + ::sal_Int32 nCheck = m_aConfigItem.GetSize(m_eList); + if (nCheck != nSize) + throw css::uno::Exception(MESSAGE_SETSIZE_FAILED, 0); + + // b) current size of used XCU lists reflects the current state of + // history list and not max size. So it can be less then size ! + css::uno::Reference< css::container::XNameAccess > xList; + xList = impl_getItemList(); + nCheck = xList->getElementNames().getLength(); + if (nCheck > nSize) + throw css::uno::Exception(MESSAGE_SETSIZE_FAILED, 0); + + xList = impl_getOrderList(); + nCheck = xList->getElementNames().getLength(); + if (nCheck > nSize) + throw css::uno::Exception(MESSAGE_SETSIZE_FAILED, 0); +} + +//============================================================================= +void HistoryOptTest::impl_appendItem(::sal_Int32 nItem) +{ + const ::rtl::OUString sURL = impl_createItemURL (nItem); + const ::rtl::OUString sTitle = impl_createItemTitle (nItem); + const ::rtl::OUString sPassword = impl_createItemPassword(nItem); + + m_aConfigItem.AppendItem(m_eList, sURL, ::rtl::OUString(), sTitle, sPassword); +} + +//============================================================================= +::rtl::OUString HistoryOptTest::impl_createItemURL(::sal_Int32 nItem) +{ + ::rtl::OUStringBuffer sURL(256); + sURL.appendAscii("file:///ooo_api_test/non_existing_test_url_"); + sURL.append ((::sal_Int32)nItem ); + sURL.appendAscii(".odt" ); + + return sURL.makeStringAndClear(); +} + +//============================================================================= +::rtl::OUString HistoryOptTest::impl_createItemTitle(::sal_Int32 nItem) +{ + ::rtl::OUStringBuffer sTitle(256); + sTitle.appendAscii("Non Existing Test Item Nr "); + sTitle.append ((::sal_Int32)nItem ); + + return sTitle.makeStringAndClear(); +} + +//============================================================================= +::rtl::OUString HistoryOptTest::impl_createItemPassword(::sal_Int32 nItem) +{ + ::rtl::OUStringBuffer sPassword(256); + sPassword.appendAscii("Password_" ); + sPassword.append ((::sal_Int32)nItem); + + return sPassword.makeStringAndClear(); +} + +//============================================================================= +::sal_Bool HistoryOptTest::impl_existsItem(::sal_Int32 nItem) +{ + const ::rtl::OUString sURL = impl_createItemURL(nItem); + const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > lItems = m_aConfigItem.GetList(m_eList); + const ::sal_Int32 c = lItems.getLength (); + ::sal_Int32 i = 0; + ::sal_Bool bFound = sal_False; + + for (i=0; i<c; ++i) + { + const ::comphelper::SequenceAsHashMap aItem(lItems[i]); + const ::rtl::OUString& sCheck = aItem.getUnpackedValueOrDefault(s_sURL, ::rtl::OUString()); + + bFound = sCheck.equals(sURL); + if (bFound) + break; + } + + if ( ! bFound) + return sal_False; + bFound = sal_False; + + try + { + css::uno::Reference< css::container::XNameAccess > xItemList = impl_getItemList(); + css::uno::Reference< css::container::XNameAccess > xItem ; + xItemList->getByName(sURL) >>= xItem; + + bFound = xItem.is(); + } + catch(const css::container::NoSuchElementException&) + {} + + return bFound; +} + +//============================================================================= +::sal_Bool HistoryOptTest::impl_existsItemAtIndex(::sal_Int32 nItem , + ::sal_Int32 nIndex) +{ + const ::rtl::OUString sURL = impl_createItemURL(nItem); + const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > lItems = m_aConfigItem.GetList(m_eList); + const ::sal_Int32 c = lItems.getLength (); + ::sal_Bool bFound = sal_False; + + if (nIndex >= c) + return sal_False; + + const ::comphelper::SequenceAsHashMap aItem(lItems[nIndex]); + ::rtl::OUString sCheck = aItem.getUnpackedValueOrDefault(s_sURL, ::rtl::OUString()); + + bFound = sCheck.equals(sURL); + if ( ! bFound) + return sal_False; + bFound = sal_False; + + try + { + css::uno::Reference< css::container::XNameAccess > xItemList = impl_getItemList(); + css::uno::Reference< css::container::XNameAccess > xItem ; + xItemList->getByName(sURL) >>= xItem; + + bFound = xItem.is(); + } + catch(const css::container::NoSuchElementException&) + {} + + if ( ! bFound) + return sal_False; + bFound = sal_False; + + try + { + const ::rtl::OUString sOrder = ::rtl::OUString::valueOf(nIndex); + css::uno::Reference< css::container::XNameAccess > xOrderList = impl_getOrderList(); + css::uno::Reference< css::container::XNameAccess > xOrder ; + xOrderList->getByName(sOrder) >>= xOrder; + + if (xOrder.is()) + { + xOrder->getByName(s_sHistoryItemRef) >>= sCheck; + bFound = sCheck.equals(sURL); + } + } + catch(const css::container::NoSuchElementException&) + {} + + return bFound; +} + +//============================================================================= +css::uno::Reference< css::container::XNameAccess > HistoryOptTest::impl_getItemList() +{ + css::uno::Reference< css::container::XNameAccess > xHistory = impl_getNewHistory(); + css::uno::Reference< css::container::XNameAccess > xList ; + xHistory->getByName (s_sItemList) >>= xList; + + if ( ! xList.is()) + throw css::uno::Exception(MESSAGE_MISS_ITEMLIST, 0); + + return xList; +} + +//============================================================================= +css::uno::Reference< css::container::XNameAccess > HistoryOptTest::impl_getOrderList() +{ + css::uno::Reference< css::container::XNameAccess > xHistory = impl_getNewHistory(); + css::uno::Reference< css::container::XNameAccess > xList ; + xHistory->getByName (s_sOrderList) >>= xList; + + if ( ! xList.is()) + throw css::uno::Exception(MESSAGE_MISS_ORDERLIST, 0); + + return xList; +} + +//============================================================================= +css::uno::Reference< css::container::XNameAccess > HistoryOptTest::impl_getNewHistory() +{ + if ( ! m_xHistoriesXCU.is()) + { + m_xHistoriesXCU = css::uno::Reference< css::container::XNameAccess >( + ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + s_sHistories, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY_THROW); + } + + css::uno::Reference< css::container::XNameAccess > xHistory; + + switch (m_eList) + { + case ePICKLIST : + m_xHistoriesXCU->getByName(s_sPickList) >>= xHistory; + break; + + case eHISTORY : + m_xHistoriesXCU->getByName(s_sURLHistory) >>= xHistory; + break; + + case eHELPBOOKMARKS : + m_xHistoriesXCU->getByName(s_sHelpBookmarks) >>= xHistory; + break; + } + + if ( ! xHistory.is()) + throw css::uno::Exception(MESSAGE_MISS_HISTORY, 0); + + return xHistory; +} + +//============================================================================= +css::uno::Reference< css::container::XNameAccess > HistoryOptTest::impl_getOldHistory() +{ + if ( ! m_xCommonXCU.is()) + { + m_xCommonXCU = css::uno::Reference< css::container::XNameAccess >( + ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + s_sCommonHistory, + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY_THROW); + } + + css::uno::Reference< css::container::XNameAccess > xHistory; + + switch (m_eList) + { + case ePICKLIST : + m_xCommonXCU->getByName(s_sPickList) >>= xHistory; + break; + + case eHISTORY : + m_xCommonXCU->getByName(s_sURLHistory) >>= xHistory; + break; + + case eHELPBOOKMARKS : + m_xCommonXCU->getByName(s_sHelpBookmarks) >>= xHistory; + break; + } + + if ( ! xHistory.is()) + throw css::uno::Exception(MESSAGE_MISS_HISTORY, 0); + + return xHistory; +} + +/* +//============================================================================= +// clear the list in XML directly when using the new Histories.xcs +void HistoryOptTest::impl_clearList(const ::rtl::OUString& sList) +{ + css::uno::Reference< css::container::XNameAccess > xListAccess; + css::uno::Reference< css::container::XNameContainer > xItemOrder; + css::uno::Reference< css::beans::XPropertySet > xFirstItem; + css::uno::Sequence< ::rtl::OUString > sFileList; + + if (sList.equalsAscii("PickList")) + m_xCfg->getByName(s_sPickList) >>= xListAccess; + + else if (sList.equalsAscii("URLHistory")) + m_xCfg->getByName(s_sURLHistory) >>= xListAccess; + + else if (sList.equalsAscii("HelpBookmarks")) + m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess; + + if (xListAccess.is()) + { + xListAccess->getByName(s_sItemList) >>= xItemOrder ; + sFileList = xItemOrder->getElementNames(); + for(sal_Int32 i=0; i<sFileList.getLength(); ++i) + xItemOrder->removeByName(sFileList[i]); + + xListAccess->getByName(s_sOrderList) >>= xItemOrder ; + sFileList = xItemOrder->getElementNames(); + for(sal_Int32 j=0; j<sFileList.getLength(); ++j) + xItemOrder->removeByName(sFileList[j]); + + xFirstItem = css::uno::Reference< css::beans::XPropertySet >(xListAccess, css::uno::UNO_QUERY); + xFirstItem->setPropertyValue( s_sFirstItem, css::uno::makeAny((sal_Int32)0) ); + + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } +} + +//============================================================================= +// use configuration API (not ConfigItem!) to verify the results within XML ! +sal_Bool HistoryOptTest::impl_isListEmpty(const ::rtl::OUString& sList) +{ + css::uno::Reference< css::container::XNameAccess > xListAccess; + css::uno::Reference< css::container::XNameAccess > xItemList; + css::uno::Reference< css::container::XNameAccess > xOrderList; + sal_Bool bRet = sal_True; + + if (sList.equalsAscii("PickList")) + m_xCfg->getByName(s_sPickList) >>= xListAccess; + + else if (sList.equalsAscii("URLHistory")) + m_xCfg->getByName(s_sURLHistory) >>= xListAccess; + + else if (sList.equalsAscii("HelpBookmarks")) + m_xCfg->getByName(s_sHelpBookmarks) >>= xListAccess; + + if (xListAccess.is()) + { + xListAccess->getByName(s_sItemList) >>= xItemList; + xListAccess->getByName(s_sOrderList) >>= xOrderList; + + css::uno::Sequence< ::rtl::OUString > sItemList = xItemList->getElementNames(); + css::uno::Sequence< ::rtl::OUString > sOrderList = xOrderList->getElementNames(); + if (sItemList.getLength()!=0 || sOrderList.getLength()!=0) + bRet = sal_False; + } + + return bRet; +} + +//============================================================================= +// append a item: use configuration API (not ConfigItem!) to verify the results within XML ! +void HistoryOptTest::impl_appendItem(const ::rtl::OUString& sList) +{//to do... +} + +//============================================================================= +// test SvtHistoryOptions::GetSize() +void HistoryOptTest::impl_checkGetSize(const ::rtl::OUString& sList) +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCommonXCU, css::uno::UNO_QUERY); + + sal_uInt32 nSize = 0; + sal_uInt32 nSize_ = 0; + + if (sList.equalsAscii("PickList")) + { + nSize = aHistoryOpt.GetSize(ePICKLIST); + + xSet->setPropertyValue(s_sPickListSize, css::uno::makeAny(nSize+1)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + + nSize_ = aHistoryOpt.GetSize(ePICKLIST); + if (nSize_ == nSize) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetSize(ePICKLIST) error!")), 0); + } + + else if (sList.equalsAscii("URLHistory")) + { + nSize = aHistoryOpt.GetSize(eHISTORY); + + xSet->setPropertyValue(s_sURLHistorySize, css::uno::makeAny(nSize+1)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + + nSize_ = aHistoryOpt.GetSize(eHISTORY); + + if (nSize_ == nSize) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetSize(eHISTORY) error!")), 0); + } + + else if (sList.equalsAscii("HelpBookmarks")) + { + nSize = aHistoryOpt.GetSize(eHELPBOOKMARKS); + + xSet->setPropertyValue(s_sHelpBookmarksSize, css::uno::makeAny(nSize+1)); + ::comphelper::ConfigurationHelper::flush(m_xCommonXCU); + + nSize_ = aHistoryOpt.GetSize(eHELPBOOKMARKS); + + if (nSize_ == nSize) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetSize(eHELPBOOKMARKS) error!")), 0); + } +} + +//============================================================================= +// test SvtHistoryOptions::SetSize() +void HistoryOptTest::impl_checkSetSize(const ::rtl::OUString& sList) +{ + css::uno::Reference< css::beans::XPropertySet > xSet(m_xCommonXCU, css::uno::UNO_QUERY); + + sal_uInt32 nSize = 0; + sal_uInt32 nSize_ = 0; + + if (sList.equalsAscii("PickList")) + { + xSet->getPropertyValue(s_sPickListSize) >>= nSize; + aHistoryOpt.SetSize(ePICKLIST, (nSize+1)); + xSet->getPropertyValue(s_sPickListSize) >>= nSize_; + + if (nSize_ == nSize) //old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetSize(ePICKLIST) error!")), 0); + } + + else if (sList.equalsAscii("URLHistory")) + { + xSet->getPropertyValue(s_sURLHistorySize) >>= nSize; + aHistoryOpt.SetSize(eHISTORY, (nSize+1)); + xSet->getPropertyValue(s_sURLHistorySize) >>= nSize_; + + if (nSize_ == nSize) //old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetSize(eHISTORY) error!")), 0); + } + + else if (sList.equalsAscii("HelpBookmarks")) + { + xSet->getPropertyValue(s_sHelpBookmarksSize) >>= nSize; + aHistoryOpt.SetSize(eHELPBOOKMARKS, (nSize+1)); + xSet->getPropertyValue(s_sHelpBookmarksSize) >>= nSize_; + + if (nSize_ == nSize) //old config item will throw error + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SetSize(eHELPBOOKMARKS) error!")), 0); + } +} + +//============================================================================= +// test SvtHistoryOptions::Clear() +void HistoryOptTest::impl_checkClear(const ::rtl::OUString& sList) +{ + if (sList.equalsAscii("PickList")) + { + aHistoryOpt.Clear(ePICKLIST); + if ( !impl_isListEmpty(s_sPickList) ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Clear(ePICKLIST) error!")), 0); + } + + else if (sList.equalsAscii("URLHistory")) + { + aHistoryOpt.Clear(eHISTORY); + if ( !impl_isListEmpty(s_sURLHistory) ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Clear(eHISTORY) error!")), 0); + } + + else if (sList.equalsAscii("HelpBookmarks")) + { + aHistoryOpt.Clear(eHELPBOOKMARKS); + if ( !impl_isListEmpty(s_sHelpBookmarks) ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Clear(eHELPBOOKMARKS) error!")), 0); + } +} + +//============================================================================= +// test SvtHistoryOptions::GetList() +void HistoryOptTest::impl_checkGetList(const ::rtl::OUString& sList) +{ + if (sList.equalsAscii("PickList")) + { + impl_clearList(s_sPickList); + aHistoryOpt.AppendItem( ePICKLIST , + ::rtl::OUString::createFromAscii("file:///c/test1"), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aHistoryList = aHistoryOpt.GetList( ePICKLIST ); + + if ( aHistoryList.getLength()==0 ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetList(ePICKLIST) error!")), 0); + } + + else if (sList.equalsAscii("URLHistory")) + { + impl_clearList(s_sURLHistory); + aHistoryOpt.AppendItem( eHISTORY , + ::rtl::OUString::createFromAscii("file:///c/test1"), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aHistoryList = aHistoryOpt.GetList( eHISTORY ); + + if ( aHistoryList.getLength()==0 ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetList(eHISTORY) error!")), 0); + } + + else if (sList.equalsAscii("HelpBookmarks")) + { + impl_clearList(s_sHelpBookmarks); + aHistoryOpt.AppendItem( eHELPBOOKMARKS , + ::rtl::OUString::createFromAscii("file:///c/test1"), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aHistoryList = aHistoryOpt.GetList( eHELPBOOKMARKS ); + + if ( aHistoryList.getLength()==0 ) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GetList(eHELPBOOKMARKS) error!")), 0); + } +} + +void HistoryOptTest::impl_checkAppendItem(const ::rtl::OUString& sList) +{ + if (sList.equalsAscii("PickList")) + { + impl_clearList(s_sPickList); + sal_Int32 nListSize = aHistoryOpt.GetSize(ePICKLIST); + + for (sal_Int32 i=0; i<nListSize; ++i) + aHistoryOpt.AppendItem( ePICKLIST , + ::rtl::OUString::valueOf(i), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + + aHistoryOpt.AppendItem( ePICKLIST , + ::rtl::OUString::valueOf(nListSize), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + } + + else if (sList.equalsAscii("URLHistory")) + { + impl_clearList(s_sURLHistory); + sal_Int32 nListSize = aHistoryOpt.GetSize(eHISTORY); + + for (sal_Int32 i=0; i<nListSize; ++i) + aHistoryOpt.AppendItem( eHISTORY , + ::rtl::OUString::valueOf(i), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + + aHistoryOpt.AppendItem( eHISTORY , + ::rtl::OUString::valueOf(nListSize), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii(""), + ::rtl::OUString::createFromAscii("") ); + } + + else if (sList.equalsAscii("HelpBookmarks")) + { + //impl_clearList(s_sHelpBookmarks); + //sal_Int32 nListSize = aHistoryOpt.GetSize(eHELPBOOKMARKS); + + //for (sal_Int32 i=0; i<nListSize; ++i) + // aHistoryOpt.AppendItem( eHELPBOOKMARKS , + // ::rtl::OUString::valueOf(i), + // ::rtl::OUString::createFromAscii(""), + // ::rtl::OUString::createFromAscii(""), + // ::rtl::OUString::createFromAscii("") ); + + //aHistoryOpt.AppendItem( eHELPBOOKMARKS , + // ::rtl::OUString::valueOf(nListSize), + // ::rtl::OUString::createFromAscii(""), + // ::rtl::OUString::createFromAscii(""), + // ::rtl::OUString::createFromAscii("") ); + } +} + +//============================================================================= +void HistoryOptTest::impl_checkPicklist() +{ + impl_checkGetSize(s_sPickList); + impl_checkSetSize(s_sPickList); + + impl_checkClear(s_sPickList); + impl_checkGetList(s_sPickList); + impl_checkAppendItem(s_sPickList); +} + +//============================================================================= +void HistoryOptTest::impl_checkURLHistory() +{ + impl_checkGetSize(s_sURLHistory); + impl_checkSetSize(s_sURLHistory); + + impl_checkClear(s_sURLHistory); + impl_checkGetList(s_sURLHistory); + impl_checkAppendItem(s_sURLHistory); +} + +//============================================================================= +void HistoryOptTest::impl_checkHelpBookmarks() +{ + impl_checkGetSize(s_sHelpBookmarks); + impl_checkSetSize(s_sHelpBookmarks); + + impl_checkClear(s_sHelpBookmarks); + impl_checkGetList(s_sHelpBookmarks); + impl_checkAppendItem(s_sHelpBookmarks); +} +*/ diff --git a/svl/qa/complex/ConfigItems/helper/HistoryOptTest.hxx b/svl/qa/complex/ConfigItems/helper/HistoryOptTest.hxx new file mode 100644 index 000000000000..8415d9f989b9 --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/HistoryOptTest.hxx @@ -0,0 +1,211 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: HistoryOptTest.hxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:24 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SVTOOLS_HISTORYOPTTEST_HXX +#define SVTOOLS_HISTORYOPTTEST_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <unotools/historyoptions.hxx> + +namespace css = ::com::sun::star; + +class HistoryOptTest +{ + public: + + HistoryOptTest(); + virtual ~HistoryOptTest(); + + //--------------------------------------------------------------------- + /** unit test of picklist */ + void checkPicklist(); + + //--------------------------------------------------------------------- + /** unit test of URL list */ + void checkURLHistory(); + + //--------------------------------------------------------------------- + /** unit test of Help bookmarks */ + void checkHelpBookmarks(); + + private: + + //--------------------------------------------------------------------- + /** test every well known history list in the same way. + * Only the count of created and tested items can be defined from outside + * e.g. usefull for stress tests. + * + * @param eHistory + * specify the history list for testing. + * + * @param nMaxItems + * max count of new created and tested history items. + */ + void impl_testHistory(EHistoryType eHistory , + ::sal_Int32 nMaxItems); + + //--------------------------------------------------------------------- + /** try to clear the whole list and check the results. + * If list could not be cleared successfully an exception is thrown. + */ + void impl_clearList(); + + //--------------------------------------------------------------------- + /** define a new size for the current list and check the results. + * Note: The given size must match against the defined constraints. + * That must be checked before this method is called. + * + * @param nSize + * the new size. + */ + void impl_setSize(::sal_Int32 nSize); + + //--------------------------------------------------------------------- + /** create a new item (means it's properties using a special schema using the + * item id). + * + * Note: This method does not check if creation was successfully. + * Therefore exists more specialized method impl_existsItem() + * and impl_existsItemAtPosition(). + * + * @param nItem + * id of the item + */ + void impl_appendItem(::sal_Int32 nItem); + + //--------------------------------------------------------------------- + /** check if an entry for given item id realy exists (in memory and xcu file). + * + * @param nItem + * id of the item + * + * @return true if item exists - false otherwise. + */ + ::sal_Bool impl_existsItem(::sal_Int32 nItem); + + //--------------------------------------------------------------------- + /** check if an entry for given item id realy exists (in memory and xcu file). + * Further it checks if the requested item is placed at the also specified + * position inside history list. + * + * @param nItem + * id of the item + * + * @param nIndex + * expected position of item inside history list. + * + * @return true if item exists at right position - false otherwise. + */ + ::sal_Bool impl_existsItemAtIndex(::sal_Int32 nItem , + ::sal_Int32 nIndex); + + //--------------------------------------------------------------------- + /** create an URL suitable for the given item id. + * + * @param nItem + * id of the item + * + * @return the new created URL. + */ + ::rtl::OUString impl_createItemURL(::sal_Int32 nItem); + + //--------------------------------------------------------------------- + /** create a title suitable for the given item id. + * + * @param nItem + * id of the item + * + * @return the new created title. + */ + ::rtl::OUString impl_createItemTitle(::sal_Int32 nItem); + + //--------------------------------------------------------------------- + /** create a password suitable for the given item id. + * + * @param nItem + * id of the item + * + * @return the new created password. + */ + ::rtl::OUString impl_createItemPassword(::sal_Int32 nItem); + + //--------------------------------------------------------------------- + /** returns direct access to the item list inside histories.xcu + * suitable for the current defined list type (m_eList). + * + * @return reference to the item list configuration + */ + css::uno::Reference< css::container::XNameAccess > impl_getItemList(); + + //--------------------------------------------------------------------- + /** returns direct access to the order list inside histories.xcu + * suitable for the current defined list type (m_eList). + * + * @return reference to the order list configuration + */ + css::uno::Reference< css::container::XNameAccess > impl_getOrderList(); + + //--------------------------------------------------------------------- + /** returns direct access to the history list inside histories.xcu + * suitable for the current defined list type (m_eList). + * + * @return reference to the history list configuration + */ + css::uno::Reference< css::container::XNameAccess > impl_getNewHistory(); + + //--------------------------------------------------------------------- + /** returns direct access to the history config inside common.xcu + * suitable for the current defined list type (m_eList). + * + * @return reference to the history configuration + */ + css::uno::Reference< css::container::XNameAccess > impl_getOldHistory(); + + private: + + // the config item which should be tested here + SvtHistoryOptions m_aConfigItem; + + // defines the special list for testing (picklist, history or url list) + EHistoryType m_eList; + + // underlying configuration of the tested config items for cross over checks + css::uno::Reference< css::container::XNameAccess > m_xHistoriesXCU; + + // underlying configuration of the tested config items for cross over checks + css::uno::Reference< css::container::XNameAccess > m_xCommonXCU; +}; + +#endif // #ifndef SVTOOLS_HISTORYOPTTEST_HXX diff --git a/svl/qa/complex/ConfigItems/helper/PrintOptTest.cxx b/svl/qa/complex/ConfigItems/helper/PrintOptTest.cxx new file mode 100644 index 000000000000..69504e4d5d7e --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/PrintOptTest.cxx @@ -0,0 +1,743 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PrintOptTest.cxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:24 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "PrintOptTest.hxx" + +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <unotools/processfactory.hxx> +#include <comphelper/configurationhelper.hxx> + +namespace css = ::com::sun::star; + +// using test only +#define ROOTNODE_PRINTOPTION rtl::OUString::createFromAscii("org.openoffice.Office.Common/Print/Option") +#define PROPERTYNAME_REDUCETRANSPARENCY rtl::OUString::createFromAscii("ReduceTransparency") +#define PROPERTYNAME_REDUCEDTRANSPARENCYMODE rtl::OUString::createFromAscii("ReducedTransparencyMode") +#define PROPERTYNAME_REDUCEGRADIENTS rtl::OUString::createFromAscii("ReduceGradients") +#define PROPERTYNAME_REDUCEDGRADIENTMODE rtl::OUString::createFromAscii("ReducedGradientMode") +#define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT rtl::OUString::createFromAscii("ReducedGradientStepCount") +#define PROPERTYNAME_REDUCEBITMAPS rtl::OUString::createFromAscii("ReduceBitmaps") +#define PROPERTYNAME_REDUCEDBITMAPMODE rtl::OUString::createFromAscii("ReducedBitmapMode") +#define PROPERTYNAME_REDUCEDBITMAPRESOLUTION rtl::OUString::createFromAscii("ReducedBitmapResolution") +#define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY rtl::OUString::createFromAscii("ReducedBitmapIncludesTransparency") +#define PROPERTYNAME_CONVERTTOGREYSCALES rtl::OUString::createFromAscii("ConvertToGreyscales") + +PrintOptTest::PrintOptTest() +{ + m_xCfg = css::uno::Reference< css::container::XNameAccess >( + ::comphelper::ConfigurationHelper::openConfig( + ::utl::getProcessServiceFactory(), + rtl::OUString::createFromAscii("org.openoffice.Office.Common/Print/Option"), + ::comphelper::ConfigurationHelper::E_STANDARD), + css::uno::UNO_QUERY); + + if (m_xCfg.is()) + { + //UniString sTmp = UniString("printer"); + //xub_StrLen nTokenCount = sTmp.GetTokenCount('/'); + //sTmp = sTmp.GetToken(nTokenCount - 1, '/'); + m_xCfg->getByName(rtl::OUString::createFromAscii("Printer")) >>= m_xNode; + } +} + +sal_Int16 PrintOptTest::impl_GetReducedTransparencyMode() const +{ + sal_Int16 nRet = 0; + if (m_xNode.is()) + { + css::uno::Reference< css::beans::XPropertySet > xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nRet; + } + return nRet; +} +void PrintOptTest::impl_SetReducedTransparencyMode(sal_Int16 nMode ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Int16 nUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nUpdate; + if (nUpdate != nMode) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDTRANSPARENCYMODE, css::uno::makeAny(nMode)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Bool PrintOptTest::impl_IsReduceTransparency() const +{ + sal_Bool bRet = sal_False; + if (m_xNode.is()) + { + css::uno::Reference< css::beans::XPropertySet > xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bRet; + } + return bRet; +} +void PrintOptTest::impl_SetReduceTransparency(sal_Bool bState ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Bool bUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bUpdate; + if (bUpdate != bState) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCETRANSPARENCY, css::uno::makeAny(bState)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Bool PrintOptTest::impl_IsReduceGradients() const +{ + sal_Bool bRet = sal_False; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bRet; + } + } + return bRet; +} + +void PrintOptTest::impl_SetReduceGradients(sal_Bool bState ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Bool bUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bUpdate; + if (bUpdate != bState) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEGRADIENTS, css::uno::makeAny(bState)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Int16 PrintOptTest::impl_GetReducedGradientMode() const +{ + sal_Int16 nRet = 0; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nRet; + } + } + return nRet; +} + +void PrintOptTest::impl_SetReducedGradientMode(sal_Int16 nMode ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Int16 nUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nUpdate; + if (nUpdate != nMode) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDGRADIENTMODE, css::uno::makeAny(nMode)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Int16 PrintOptTest::impl_GetReducedGradientStepCount() const +{ + sal_Int16 nRet = 64; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nRet; + } + } + return nRet; +} +void PrintOptTest::impl_SetReducedGradientStepCount(sal_Int16 nStepCount ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Int16 nUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nUpdate; + if (nUpdate != nStepCount) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT, css::uno::makeAny(nStepCount)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Bool PrintOptTest::impl_IsReduceBitmaps() const +{ + sal_Bool bRet = sal_False; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bRet; + } + } + return bRet; +} + +void PrintOptTest::impl_SetReduceBitmaps(sal_Bool bState ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Bool bUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bUpdate; + if (bUpdate != bState) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEBITMAPS, css::uno::makeAny(bState)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Int16 PrintOptTest::impl_GetReducedBitmapMode() const +{ + sal_Int16 nRet = 1; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nRet; + } + } + return nRet; +} + +void PrintOptTest::impl_SetReducedBitmapMode(sal_Int16 nMode ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Int16 nUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nUpdate; + if (nUpdate != nMode) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDBITMAPMODE, css::uno::makeAny(nMode)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Int16 PrintOptTest::impl_GetReducedBitmapResolution() const +{ + sal_Int16 nRet = 3; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nRet; + } + } + return nRet; +} + +void PrintOptTest::impl_SetReducedBitmapResolution(sal_Int16 nResolution ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Int16 nUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nUpdate; + if (nUpdate != nResolution) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDBITMAPRESOLUTION, css::uno::makeAny(nResolution)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Bool PrintOptTest::impl_IsReducedBitmapIncludesTransparency() const +{ + sal_Bool bRet = sal_True; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bRet; + } + } + return bRet; +} + +void PrintOptTest::impl_SetReducedBitmapIncludesTransparency(sal_Bool bState ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Bool bUpdate; + xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bUpdate; + if (bUpdate != bState) + { + xSet->setPropertyValue( PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY, css::uno::makeAny(bState)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + +sal_Bool PrintOptTest::impl_IsConvertToGreyscales() const +{ + sal_Bool bRet = sal_False; + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bRet; + } + } + return bRet; +} + +void PrintOptTest::impl_SetConvertToGreyscales(sal_Bool bState ) +{ + if (m_xNode.is()) + { + css::uno::Reference<css::beans::XPropertySet> xSet(m_xNode, css::uno::UNO_QUERY); + if (xSet.is()) + { + sal_Bool bUpdate; + xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bUpdate; + if (bUpdate != bState) + { + xSet->setPropertyValue( PROPERTYNAME_CONVERTTOGREYSCALES, css::uno::makeAny(bState)); + ::comphelper::ConfigurationHelper::flush(m_xCfg); + } + } + } +} + + +PrintOptTest::~PrintOptTest() +{ +} + +void PrintOptTest::impl_checkPrint() +{ + //test SetReduceTransparency() + sal_Bool bNewValue = sal_False; + sal_Bool bOldValue = sal_False; + bOldValue = PrintOptTest::impl_IsReduceTransparency(); + bNewValue = !bOldValue; + aPrintOpt.SetReduceTransparency(bNewValue) ; + bNewValue = impl_IsReduceTransparency(); + // if(bNewValue != bOldValue) // test the old source + if ( bNewValue == bOldValue ) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReduceTransparency() error!"), + 0); + } + + //test IsReduceTransparemcy() + bNewValue = bOldValue = sal_False; + bOldValue = impl_IsReduceTransparency(); + bNewValue = !bOldValue; + impl_SetReduceTransparency(bNewValue); + bNewValue = aPrintOpt.IsReduceTransparency(); + //if(bNewValue != bOldValue) // test the old source + if(bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsReduceTransparency() error!"), + 0); + } + + // test SetReducedTransparencyMode() + sal_Int16 nOldMode, nNewMode; + nOldMode = nNewMode = 0; + nOldMode = impl_GetReducedTransparencyMode(); + nNewMode = nOldMode + 1; + aPrintOpt.SetReducedTransparencyMode( nNewMode ); + nNewMode = impl_GetReducedTransparencyMode(); + //if(nNewMode != nOldMode) // test the old source + if ( nNewMode == nOldMode ) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReducedTransparencyMode() error!"), + 0); + } + + //test IsReducedTransparencyMode() + nOldMode = nNewMode = 0; + nOldMode = impl_GetReducedTransparencyMode(); + nNewMode = nOldMode + 1; + impl_SetReducedTransparencyMode(nNewMode); + nNewMode = aPrintOpt.GetReducedTransparencyMode(); + //if(nNewMode != nOldMode) // test the old source + if(nNewMode == nOldMode) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsReducedTransparencyMode() error!" + "nOldMode's value is :"), + 0); + } + + // test the SetReduceGradients() + bNewValue = bOldValue = sal_False; + bOldValue = impl_IsReduceGradients(); + bNewValue = !bOldValue; + aPrintOpt.SetReduceGradients(bNewValue); + bNewValue = impl_IsReduceGradients(); + //if (bNewValue != bOldValue) //test the old source + if (bNewValue == bOldValue) //test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReduceGradients() error!"), + 0); + + } + + // test the IsReduceGradients() + bNewValue = bOldValue = sal_False; + bOldValue = impl_IsReduceGradients(); + bNewValue = !bOldValue; + this->impl_SetReduceGradients(bNewValue); + bNewValue = aPrintOpt.IsReduceGradients(); + // if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsReduceGradients() error!"), + 0); + + } + + //test SetRedecedGradientMode() + nOldMode = nNewMode = 0; + nOldMode = this->impl_GetReducedGradientMode(); + nNewMode = nOldMode + 1; + aPrintOpt.SetReducedGradientMode(nNewMode); + nNewMode = this->impl_GetReducedGradientMode(); + //if (nNewMode != nOldMode) // test the old source + if (nNewMode == nOldMode)// test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetRedecedGradientMode() error!"), + 0); + } + + // test GetReducedGradientMode() + nOldMode = nNewMode = 0; + nOldMode = this->impl_GetReducedGradientMode(); + nNewMode = nOldMode + 1; + this->impl_SetReducedGradientMode(nNewMode); + nNewMode = aPrintOpt.GetReducedGradientMode(); + //if (nNewMode != nOldMode) // test the old source + if (nNewMode == nOldMode) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the GetReducedGradientMode() error!"), + 0); + + } + + //test the SetReducedGradientStepCount() + sal_Int16 nNewStepCount; + sal_Int16 nOldStepCount; + nNewStepCount = nOldStepCount = 0; + nOldStepCount = this->impl_GetReducedGradientStepCount(); + nNewStepCount = nOldStepCount + 1; + aPrintOpt.SetReducedGradientStepCount(nNewStepCount); + nNewStepCount = this->impl_GetReducedGradientStepCount(); + // if (nNewStepCount != nOldStepCount) // test the old source + if (nNewStepCount == nOldStepCount) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReducedGradientStepCount() error!"), + 0); + + } + + // test the GetReduceGradientStepCount() + nNewStepCount = nOldStepCount = 0; + nOldStepCount = this->impl_GetReducedGradientStepCount(); + nNewStepCount = nOldStepCount + 1; + this->impl_SetReducedGradientStepCount(nNewStepCount); + nNewStepCount = aPrintOpt.GetReducedGradientStepCount(); + // if (nNewStepCount != nOldStepCount) //test the old source + if (nNewStepCount == nOldStepCount) //test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the GetReduceGradientStepCount() error!"), + 0); + } + + // test the SetReduceBitmaps() + bNewValue = bOldValue = sal_False; + bOldValue = this->impl_IsReduceBitmaps(); + bNewValue = !bOldValue; + aPrintOpt.SetReduceBitmaps(bNewValue); + bNewValue = this->impl_IsReduceBitmaps(); + //if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReduceBitmaps() error!"), + 0); + } + + // test the IsReduceBitmaps() + bNewValue = bOldValue = sal_False; + bOldValue = this->impl_IsReduceBitmaps(); + bNewValue = !bOldValue; + this->impl_SetReduceBitmaps(bNewValue); + bNewValue = aPrintOpt.IsReduceBitmaps(); + //if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsReduceBitmaps() error!"), + 0); + } + + // test the SetReduceBitmap() + nNewMode = nOldMode = 0; + nOldMode = impl_GetReducedBitmapMode(); + nNewMode = nOldMode + 1; + aPrintOpt.SetReducedBitmapMode(nNewMode); + nNewMode = impl_GetReducedBitmapMode(); + //if (nNewMode != nOldMode) // test the old source + if (nNewMode == nOldMode)// test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReduceBitmap() error!"), + 0); + } + + // test the SetReduceBitmapMode() + nNewMode = nOldMode = 0; + nOldMode = this->impl_GetReducedBitmapMode(); + nNewMode = nOldMode + 1; + aPrintOpt.SetReducedBitmapMode(nNewMode); + nNewMode = this->impl_GetReducedBitmapMode(); + //if (nNewMode != nOldMode) // test the old source + if (nNewMode == nOldMode) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReduceBitmapMode() error!"), + 0); + } + + // test the GetReduceBitmapMode() + nNewMode = nOldMode = 0; + nOldMode = this->impl_GetReducedBitmapMode(); + nNewMode = nOldMode + 1; + this->impl_SetReducedBitmapMode(nNewMode); + nNewMode = aPrintOpt.GetReducedBitmapMode(); + //if (nNewMode != nOldMode) // test the old source + if (nNewMode == nOldMode)// test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the GetReduceBitmapMode() error!"), + 0); + + } + + // test the SetReducedBitmapResolution() + sal_Int16 nOldResolution ; + sal_Int16 nNewResolution ; + nNewResolution = nOldResolution = 0; + nOldResolution = impl_GetReducedBitmapResolution(); + nNewResolution = nOldResolution + 1; + aPrintOpt.SetReducedBitmapResolution(nNewResolution); + nNewResolution = impl_GetReducedBitmapResolution(); + //if (nNewResolution != nOldResolution) // test the old source + if (nNewResolution == nOldResolution)// test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReducedBitmapResolution() error!"), + 0); + } + + // test the GetReduceBitmapResolution() + nNewResolution = nOldResolution = 0; + nOldResolution = impl_GetReducedBitmapResolution(); + nNewResolution = nOldResolution + 1; + impl_SetReducedBitmapResolution(nNewResolution); + nNewResolution = impl_GetReducedBitmapResolution(); + //if (nNewResolution != nOldResolution) // test the old source + if (nNewResolution == nOldResolution) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the GetReduceBitmapResolution() error!"), + 0); + } + + // test SetReducedBitmapIncludesTransparency() + bNewValue = bOldValue = sal_False; + bOldValue = impl_IsReducedBitmapIncludesTransparency(); + bNewValue = !bOldValue; + aPrintOpt.SetReducedBitmapIncludesTransparency(bNewValue); + bNewValue = impl_IsReducedBitmapIncludesTransparency(); + //if (bNewValue != bOldValue) // test the new source + if (bNewValue == bOldValue) // test the old source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetReducedBitmapIncludesTransparency() error!"), + 0); + } + + // test the IsReducedBitmapIncludesTransparency() + bNewValue = bOldValue = sal_False; + bOldValue = impl_IsReducedBitmapIncludesTransparency(); + bNewValue = !bOldValue; + impl_SetReducedBitmapIncludesTransparency(bNewValue); + bNewValue = aPrintOpt.IsReducedBitmapIncludesTransparency(); + //if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsReducedBitmapIncludesTransparency() error!"), + 0); + } + + // test the SetConvertToGreyscales() + bNewValue = bOldValue = sal_False; + bOldValue = this->impl_IsConvertToGreyscales(); + bNewValue = !bOldValue; + aPrintOpt.SetConvertToGreyscales(bNewValue); + bNewValue = this->impl_IsConvertToGreyscales(); + //if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the SetConvertToGreyscales() error!"), + 0); + } + + // test the IsConvertToGreyscales() + bNewValue = bOldValue = sal_False; + bOldValue = this->impl_IsConvertToGreyscales(); + bNewValue = !bOldValue; + impl_SetConvertToGreyscales(bNewValue); + bNewValue = aPrintOpt.IsConvertToGreyscales(); + //if (bNewValue != bOldValue) // test the old source + if (bNewValue == bOldValue) // test the new source + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii( + "null com.sun.star.configuration." + "the IsConvertToGreyscales() error!"), + 0); + } +} diff --git a/svl/qa/complex/ConfigItems/helper/PrintOptTest.hxx b/svl/qa/complex/ConfigItems/helper/PrintOptTest.hxx new file mode 100644 index 000000000000..79505a4e6faf --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/PrintOptTest.hxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PrintOptTest.hxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:24 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SVTOOLS_PRINTOPTTEST_HXX +#define SVTOOLS_PRINTOPTTEST_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <svl/printoptions.hxx> + +namespace css = ::com::sun::star; + +class PrintOptTest +{ +public: + + PrintOptTest(); + ~PrintOptTest(); + + void impl_checkPrint(); + +private: //members + + SvtPrinterOptions aPrintOpt; + css::uno::Reference< css::container::XNameAccess > m_xCfg; + css::uno::Reference< css::container::XNameAccess > m_xNode; + +private: // methods + sal_Bool impl_IsReduceTransparency() const ; + void impl_SetReduceTransparency( sal_Bool bState ) ; + + sal_Int16 impl_GetReducedTransparencyMode() const ; + void impl_SetReducedTransparencyMode( sal_Int16 nMode ) ; + + sal_Bool impl_IsReduceGradients() const ; + void impl_SetReduceGradients( sal_Bool bState ) ; + + sal_Int16 impl_GetReducedGradientMode() const ; + void impl_SetReducedGradientMode( sal_Int16 nMode ) ; + + sal_Int16 impl_GetReducedGradientStepCount() const ; + void impl_SetReducedGradientStepCount( sal_Int16 nStepCount ); + + sal_Bool impl_IsReduceBitmaps() const ; + void impl_SetReduceBitmaps( sal_Bool bState ) ; + + sal_Int16 impl_GetReducedBitmapMode() const ; + void impl_SetReducedBitmapMode( sal_Int16 nMode ) ; + + sal_Int16 impl_GetReducedBitmapResolution() const ; + void impl_SetReducedBitmapResolution( sal_Int16 nResolution ) ; + + sal_Bool impl_IsReducedBitmapIncludesTransparency() const ; + void impl_SetReducedBitmapIncludesTransparency( sal_Bool bState ) ; + + sal_Bool impl_IsConvertToGreyscales() const; + void impl_SetConvertToGreyscales( sal_Bool bState ) ; + +}; + +#endif // #ifndef SVTOOLS_PRINTOPTTEST_HXX diff --git a/svl/qa/complex/ConfigItems/helper/UserOptTest.cxx b/svl/qa/complex/ConfigItems/helper/UserOptTest.cxx new file mode 100644 index 000000000000..14ee513ee0cb --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/UserOptTest.cxx @@ -0,0 +1,274 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: UserOptTest.cxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:24 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "UserOptTest.hxx" + +namespace css = ::com::sun::star; + +//============================================================================= +static const ::rtl::OUString MESSAGE_SETCOMPANY_FAILED = ::rtl::OUString::createFromAscii("set company failed") ; +static const ::rtl::OUString MESSAGE_SETFIRSTNAME_FAILED = ::rtl::OUString::createFromAscii("set firstname failed") ; +static const ::rtl::OUString MESSAGE_SETLASTNAME_FAILED = ::rtl::OUString::createFromAscii("set lastname failed") ; +static const ::rtl::OUString MESSAGE_SETID_FAILED = ::rtl::OUString::createFromAscii("set ID failed") ; +static const ::rtl::OUString MESSAGE_SETSTREET_FAILED = ::rtl::OUString::createFromAscii("set street failed") ; +static const ::rtl::OUString MESSAGE_SETCITY_FAILED = ::rtl::OUString::createFromAscii("set city failed") ; +static const ::rtl::OUString MESSAGE_SETSTATE_FAILED = ::rtl::OUString::createFromAscii("set state failed") ; +static const ::rtl::OUString MESSAGE_SETZIP_FAILED = ::rtl::OUString::createFromAscii("set zip failed") ; +static const ::rtl::OUString MESSAGE_SETCOUNTRY_FAILED = ::rtl::OUString::createFromAscii("set country failed") ; +static const ::rtl::OUString MESSAGE_SETPOSITION_FAILED = ::rtl::OUString::createFromAscii("set position failed") ; +static const ::rtl::OUString MESSAGE_SETTITLE_FAILED = ::rtl::OUString::createFromAscii("set title failed") ; +static const ::rtl::OUString MESSAGE_SETTELEPHONEHOME_FAILED = ::rtl::OUString::createFromAscii("set telephonehome failed") ; +static const ::rtl::OUString MESSAGE_SETTELEPHONEWORK_FAILED = ::rtl::OUString::createFromAscii("set telephonework failed") ; +static const ::rtl::OUString MESSAGE_SETFAX_FAILED = ::rtl::OUString::createFromAscii("set fax failed") ; +static const ::rtl::OUString MESSAGE_SETEMAIL_FAILED = ::rtl::OUString::createFromAscii("set email failed") ; +static const ::rtl::OUString MESSAGE_SETCUSTOMERNUMBER_FAILED = ::rtl::OUString::createFromAscii("set customernumber failed"); +static const ::rtl::OUString MESSAGE_SETFATHERSNAME_FAILED = ::rtl::OUString::createFromAscii("set fathersname failed") ; +static const ::rtl::OUString MESSAGE_SETAPARTMENT_FAILED = ::rtl::OUString::createFromAscii("set apartment failed") ; + +//============================================================================= + + +UserOptTest::UserOptTest() + :m_aConfigItem() + ,m_xCfg() +{ +} + +UserOptTest::~UserOptTest() +{ +} + +void UserOptTest::impl_checkUserData() +{ + impl_checkSetCompany( ::rtl::OUString() ); + impl_checkSetFirstName( ::rtl::OUString() ); + impl_checkSetLastName( ::rtl::OUString() ); + impl_checkSetID( ::rtl::OUString() ); + impl_checkSetStreet( ::rtl::OUString() ); + impl_checkSetCity( ::rtl::OUString() ); + impl_checkSetState( ::rtl::OUString() ); + impl_checkSetZip( ::rtl::OUString() ); + impl_checkSetCountry( ::rtl::OUString() ); + impl_checkSetPosition( ::rtl::OUString() ); + impl_checkSetTitle( ::rtl::OUString() ); + impl_checkSetTelephoneHome( ::rtl::OUString() ); + impl_checkSetTelephoneWork( ::rtl::OUString() ); + impl_checkSetFax( ::rtl::OUString() ); + impl_checkSetEmail( ::rtl::OUString() ); + //impl_checkSetCustomerNumber( ::rtl::OUString() ); + impl_checkSetFathersName( ::rtl::OUString() ); + impl_checkSetApartment( ::rtl::OUString() ); + + impl_checkSetCompany( ::rtl::OUString::createFromAscii("RedFlag2000") ); + impl_checkSetFirstName( ::rtl::OUString::createFromAscii("Yan") ); + impl_checkSetLastName( ::rtl::OUString::createFromAscii("Wu") ); + impl_checkSetID( ::rtl::OUString::createFromAscii("wuy") ); + impl_checkSetStreet( ::rtl::OUString::createFromAscii("SouthFifthRing") ); + impl_checkSetCity( ::rtl::OUString::createFromAscii("Beijing") ); + impl_checkSetState( ::rtl::OUString::createFromAscii("Beijing") ); + impl_checkSetZip( ::rtl::OUString::createFromAscii("100176") ); + impl_checkSetCountry( ::rtl::OUString::createFromAscii("China") ); + impl_checkSetPosition( ::rtl::OUString::createFromAscii("Engineer") ); + impl_checkSetTitle( ::rtl::OUString::createFromAscii("Software Engineer") ); + impl_checkSetTelephoneHome( ::rtl::OUString::createFromAscii("010-51570010") ); + impl_checkSetTelephoneWork( ::rtl::OUString::createFromAscii("010-51570010") ); + impl_checkSetFax( ::rtl::OUString::createFromAscii("010-51570010") ); + impl_checkSetEmail( ::rtl::OUString::createFromAscii("wuy@redflag2000.cn") ); + //impl_checkSetCustomerNumber( ::rtl::OUString::createFromAscii("87654321") ); + impl_checkSetFathersName( ::rtl::OUString::createFromAscii("father") ); + impl_checkSetApartment( ::rtl::OUString::createFromAscii("apartment") ); +} + +void UserOptTest::impl_checkSetCompany( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetCompany( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetCompany(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETCOMPANY_FAILED, 0); +} + +void UserOptTest::impl_checkSetFirstName( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetFirstName( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetFirstName(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETFIRSTNAME_FAILED, 0); +} + +void UserOptTest::impl_checkSetLastName( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetLastName( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetLastName(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETLASTNAME_FAILED, 0); +} + +void UserOptTest::impl_checkSetID( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetID( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetID(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETID_FAILED, 0); +} + +void UserOptTest::impl_checkSetStreet( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetStreet( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetStreet(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETSTREET_FAILED, 0); +} + +void UserOptTest::impl_checkSetCity( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetCity( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetCity(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETCITY_FAILED, 0); +} + +void UserOptTest::impl_checkSetState( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetState( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetState(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETSTATE_FAILED, 0); +} + +void UserOptTest::impl_checkSetZip( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetZip( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetZip(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETZIP_FAILED, 0); +} + +void UserOptTest::impl_checkSetCountry( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetCountry( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetCountry(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETCOUNTRY_FAILED, 0); +} + +void UserOptTest::impl_checkSetPosition( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetPosition( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetPosition(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETPOSITION_FAILED, 0); +} + +void UserOptTest::impl_checkSetTitle( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetTitle( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetTitle(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETTITLE_FAILED, 0); +} + +void UserOptTest::impl_checkSetTelephoneHome( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetTelephoneHome( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetTelephoneHome(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETTELEPHONEHOME_FAILED, 0); +} + +void UserOptTest::impl_checkSetTelephoneWork( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetTelephoneWork( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetTelephoneWork(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETTELEPHONEWORK_FAILED, 0); +} + +void UserOptTest::impl_checkSetFax( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetFax( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetFax(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETFAX_FAILED, 0); +} + +void UserOptTest::impl_checkSetEmail( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetEmail( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetEmail(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETEMAIL_FAILED, 0); +} + +void UserOptTest::impl_checkSetCustomerNumber( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetCustomerNumber( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetCustomerNumber(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETCUSTOMERNUMBER_FAILED, 0); +} + +void UserOptTest::impl_checkSetFathersName( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetFathersName( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetFathersName(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETFATHERSNAME_FAILED, 0); +} + +void UserOptTest::impl_checkSetApartment( const ::rtl::OUString& sUserData ) +{ + m_aConfigItem.SetApartment( sUserData ); + + ::rtl::OUString sCheck = m_aConfigItem.GetApartment(); + if ( sCheck != sUserData ) + throw css::uno::Exception(MESSAGE_SETAPARTMENT_FAILED, 0); +} diff --git a/svl/qa/complex/ConfigItems/helper/UserOptTest.hxx b/svl/qa/complex/ConfigItems/helper/UserOptTest.hxx new file mode 100644 index 000000000000..72ff71cafe2d --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/UserOptTest.hxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: UserOptTest.hxx,v $ + * + * $Revision: 1.1.4.2 $ + * + * last change: $Author: as $ $Date: 2008/03/19 11:09:25 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef SVTOOLS_USEROPTTEST_HXX +#define SVTOOLS_USEROPTTEST_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <unotools/useroptions.hxx> + +namespace css = ::com::sun::star; + +class UserOptTest +{ +public: + UserOptTest(); + ~UserOptTest(); + + void impl_checkUserData(); + +private: + void impl_checkSetCompany( const ::rtl::OUString& sUserData ); + void impl_checkSetFirstName( const ::rtl::OUString& sUserData ); + void impl_checkSetLastName( const ::rtl::OUString& sUserData ); + void impl_checkSetID( const ::rtl::OUString& sUserData ); + void impl_checkSetStreet( const ::rtl::OUString& sUserData ); + void impl_checkSetCity( const ::rtl::OUString& sUserData ); + void impl_checkSetState( const ::rtl::OUString& sUserData ); + void impl_checkSetZip( const ::rtl::OUString& sUserData ); + void impl_checkSetCountry( const ::rtl::OUString& sUserData ); + void impl_checkSetPosition( const ::rtl::OUString& sUserData ); + void impl_checkSetTitle( const ::rtl::OUString& sUserData ); + void impl_checkSetTelephoneHome( const ::rtl::OUString& sUserData ); + void impl_checkSetTelephoneWork( const ::rtl::OUString& sUserData ); + void impl_checkSetFax( const ::rtl::OUString& sUserData ); + void impl_checkSetEmail( const ::rtl::OUString& sUserData ); + void impl_checkSetCustomerNumber( const ::rtl::OUString& sUserData ); + void impl_checkSetFathersName( const ::rtl::OUString& sUserData ); + void impl_checkSetApartment( const ::rtl::OUString& sUserData ); + +private: + SvtUserOptions m_aConfigItem; + + css::uno::Reference< css::container::XNameAccess > m_xCfg; +}; + +#endif // #ifndef SVTOOLS_USEROPTTEST_HXX diff --git a/svl/qa/complex/ConfigItems/helper/exports.map b/svl/qa/complex/ConfigItems/helper/exports.map new file mode 100644 index 000000000000..85610ad80888 --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/exports.map @@ -0,0 +1,10 @@ +UDK_3_0_0 { + global: + GetVersionInfo; + component_getImplementationEnvironment; + component_getFactory; + component_writeInfo; + + local: + *; +}; diff --git a/svl/qa/complex/ConfigItems/helper/makefile.mk b/svl/qa/complex/ConfigItems/helper/makefile.mk new file mode 100644 index 000000000000..d41fe6c129c6 --- /dev/null +++ b/svl/qa/complex/ConfigItems/helper/makefile.mk @@ -0,0 +1,81 @@ +#************************************************************************* +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.4.2 $ +# +# last change: $Author: as $ $Date: 2008/03/19 11:09:25 $ +# +# The Contents of this file are made available subject to +# the terms of GNU Lesser General Public License Version 2.1. +# +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2005 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +#************************************************************************* +PRJ=..$/..$/..$/.. + +PRJNAME= svl +TARGET= ConfigItemTest +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS= TRUE +NO_BSYMBOLIC= TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Generate ----------------------------------------------------- + +INCPOST += $(PRJ)$/source$/inc + +# --- light services library ---------------------------------------------------- + +SHL1TARGET= svt_$(TARGET) + +SHL1OBJS= \ + $(SLO)$/UserOptTest.obj \ + $(SLO)$/PrintOptTest.obj \ + $(SLO)$/AccessibilityOptTest.obj \ + $(SLO)$/HistoryOptTest.obj \ + $(SLO)$/ConfigItemTest.obj + +SHL1STDLIBS= \ + $(SVLIB) \ + $(SVLLIB) \ + $(UNOTOOLSLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +#SHL1DEPN= $(SHL1IMPLIBN) $(SHL1TARGETN) + +DEF1NAME= $(SHL1TARGET) + +SHL1VERSIONMAP= exports.map + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/svl/qa/complex/ConfigItems/makefile.mk b/svl/qa/complex/ConfigItems/makefile.mk new file mode 100644 index 000000000000..1291184346bc --- /dev/null +++ b/svl/qa/complex/ConfigItems/makefile.mk @@ -0,0 +1,91 @@ +#************************************************************************* +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.4.2 $ +# +# last change: $Author: as $ $Date: 2008/03/19 11:09:22 $ +# +# The Contents of this file are made available subject to +# the terms of GNU Lesser General Public License Version 2.1. +# +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2005 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +#************************************************************************* +PRJ = ..$/..$/.. +TARGET = CheckConfigItems +PRJNAME = svl +PACKAGE = complex$/ConfigItems + +# --- Settings ----------------------------------------------------- +.INCLUDE: settings.mk + + +#----- compile .java files ----------------------------------------- + +JARFILES = mysql.jar ridl.jar unoil.jar jurt.jar juh.jar jut.jar java_uno.jar \ + OOoRunner.jar + +JAVAFILES = CheckConfigItems.java + +JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +SUBDIRS = helper + +#----- make a jar from compiled files ------------------------------ + +MAXLINELENGTH = 100000 + +JARCLASSDIRS = $(PACKAGE) +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE + +# --- Parameters for the test -------------------------------------- + +# start an office if the parameter is set for the makefile +.IF "$(OFFICE)" == "" +CT_APPEXECCOMMAND = +.ELSE +CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" +.ENDIF + +# test base is java complex +CT_TESTBASE = -TestBase java_complex + +# test looks something like the.full.package.TestName +CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b) + +# start the runner application +CT_APP = org.openoffice.Runner + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +RUN: run + +run: + java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_TEST) + + + diff --git a/svl/qa/complex/passwordcontainer/MasterPasswdHandler.java b/svl/qa/complex/passwordcontainer/MasterPasswdHandler.java new file mode 100644 index 000000000000..bf6159ee38c5 --- /dev/null +++ b/svl/qa/complex/passwordcontainer/MasterPasswdHandler.java @@ -0,0 +1,61 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * + * @author zxf + */ + +package complex.passwordcontainer; + +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.task.XInteractionContinuation; +import com.sun.star.ucb.XInteractionSupplyAuthentication; +import com.sun.star.task.XInteractionRequest; +import com.sun.star.task.XInteractionHandler; +import com.sun.star.task.MasterPasswordRequest; +import com.sun.star.uno.UnoRuntime; + +public class MasterPasswdHandler extends WeakBase + implements XInteractionHandler { + XInteractionHandler m_xHandler; + + public MasterPasswdHandler( XInteractionHandler xHandler ) { + m_xHandler = xHandler; + } + + public void handle( XInteractionRequest xRequest ) { + try { + MasterPasswordRequest aMasterPasswordRequest; + if( xRequest.getRequest() instanceof MasterPasswordRequest ) { + aMasterPasswordRequest = (MasterPasswordRequest)xRequest.getRequest(); + if( aMasterPasswordRequest != null ) { + XInteractionContinuation xContinuations[] = xRequest.getContinuations(); + XInteractionSupplyAuthentication xAuthentication = null; + + for( int i = 0; i < xContinuations.length; ++i ) { + xAuthentication = (XInteractionSupplyAuthentication)UnoRuntime.queryInterface( XInteractionSupplyAuthentication.class, xContinuations[i]); + if( xAuthentication != null ) + break; + } + if( xAuthentication.canSetPassword() ) + xAuthentication.setPassword( "abcdefghijklmnopqrstuvwxyz123456" ); + xAuthentication.select(); + } + } else { + m_xHandler.handle( xRequest ); + } + } catch( Exception e ) { + System.out.println( "MasterPasswordHandler Error: " + e ); + } + } +} + + + + + + + diff --git a/svl/qa/complex/passwordcontainer/PasswordContainerTest.java b/svl/qa/complex/passwordcontainer/PasswordContainerTest.java new file mode 100644 index 000000000000..5da0676f8bb9 --- /dev/null +++ b/svl/qa/complex/passwordcontainer/PasswordContainerTest.java @@ -0,0 +1,36 @@ +/************************************************************************* + * + * 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: PasswordContainerTest.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +public interface PasswordContainerTest { + boolean test(); +} diff --git a/svl/qa/complex/passwordcontainer/PasswordContainerUnitTest.java b/svl/qa/complex/passwordcontainer/PasswordContainerUnitTest.java new file mode 100644 index 000000000000..aee1c9355a3f --- /dev/null +++ b/svl/qa/complex/passwordcontainer/PasswordContainerUnitTest.java @@ -0,0 +1,77 @@ +/************************************************************************* + * + * 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: PasswordContainerUnitTest.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +import complexlib.ComplexTestCase; +import com.sun.star.lang.XMultiServiceFactory; + +public class PasswordContainerUnitTest extends ComplexTestCase { + private XMultiServiceFactory m_xMSF = null; + + public String[] getTestMethodNames() { + return new String[] { + "ExecuteTest01", + "ExecuteTest02", + "ExecuteTest03"}; + } + public String getTestObjectName() { + return "PasswordContainerUnitTest"; + } + + public void before() { + try { + m_xMSF = (XMultiServiceFactory) param.getMSF(); + } catch (Exception e) { + failed ("Cannot create service factory!"); + } + if (m_xMSF == null) { + failed ("Cannot create service factory!"); + } + } + + public void after() { + m_xMSF = null; + } + + public void ExecuteTest01() { + PasswordContainerTest aTest = new Test01(m_xMSF, log); + assure("Test01 failed!", aTest.test()); + } + public void ExecuteTest02() { + PasswordContainerTest aTest = new Test02(m_xMSF, log); + assure("Test02 failed!", aTest.test()); + } + public void ExecuteTest03() { + PasswordContainerTest aTest = new Test03(m_xMSF, log); + assure("Test03 failed!", aTest.test()); + } +} diff --git a/svl/qa/complex/passwordcontainer/Test01.java b/svl/qa/complex/passwordcontainer/Test01.java new file mode 100644 index 000000000000..6de96de05ec9 --- /dev/null +++ b/svl/qa/complex/passwordcontainer/Test01.java @@ -0,0 +1,115 @@ +/************************************************************************* + * + * 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: Test01.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.task.XInteractionHandler; +import com.sun.star.task.XPasswordContainer; +import com.sun.star.task.UrlRecord; +import com.sun.star.task.UserRecord; +import com.sun.star.task.XMasterPasswordHandling; + +import com.sun.star.uno.UnoRuntime; + +import share.LogWriter; + +public class Test01 implements PasswordContainerTest { + XMultiServiceFactory m_xMSF = null; + XPasswordContainer m_xPasswordContainer = null; + TestHelper m_aTestHelper = null; + + public Test01 ( XMultiServiceFactory xMSF, LogWriter aLogWriter ) + { + m_xMSF = xMSF; + m_aTestHelper = new TestHelper (aLogWriter, "Test01: "); + } + + public boolean test() { + final String sURL = "http://www.openoffice.org"; + final String sUserPre = "OOoUser"; + final String sPwdPre = "Password"; + final int iUserNum1 = 10; + final int iUserNum2 = 5; + + UserRecord aInputUserList1[] = new UserRecord[iUserNum1]; + for(int i = 0; i < iUserNum1; i++) { + String sTemp[] = {sPwdPre + "_1_" + i}; // currently one password for one user + aInputUserList1[i] = new UserRecord(sUserPre + "_1_" + i, sTemp); + } + UserRecord aInputUserList2[] = new UserRecord[iUserNum2]; + for(int i = 0; i < iUserNum2; i++) { + String sTemp[] = {sPwdPre + "_2_" + i}; + aInputUserList2[i] = new UserRecord(sUserPre + "_2_" + i, sTemp); + } + try { + Object oPasswordContainer = m_xMSF.createInstance( "com.sun.star.task.PasswordContainer" ); + XPasswordContainer xContainer = (XPasswordContainer)UnoRuntime.queryInterface(XPasswordContainer.class, oPasswordContainer); + Object oHandler = m_xMSF.createInstance( "com.sun.star.task.InteractionHandler" ); + XInteractionHandler xHandler = (XInteractionHandler)UnoRuntime.queryInterface(XInteractionHandler.class, oHandler); + MasterPasswdHandler aMHandler = new MasterPasswdHandler( xHandler ); + + // add a set of users and passwords for the same URL for runtime + for(int i = 0; i < iUserNum1; i++) { + xContainer.add(sURL, aInputUserList1[i].UserName, aInputUserList1[i].Passwords, aMHandler); + } + for (int i = 0; i < iUserNum2; i++) { + xContainer.add(sURL, aInputUserList2[i].UserName, aInputUserList2[i].Passwords, aMHandler); + } + + // remove some of the passwords + for (int i = 0; i < iUserNum1; i++) { + xContainer.remove(sURL, aInputUserList1[i].UserName); + } + + // get the result and check it with the expected one + UrlRecord aRecord = xContainer.find(sURL, aMHandler); + if(!aRecord.Url.equals(sURL)) { + m_aTestHelper.Error("URL mismatch. Got " + aRecord.Url + "; should be " + sURL); + return false; + } + if(!m_aTestHelper.sameLists(aRecord.UserList, aInputUserList2)) { + m_aTestHelper.Error("User list is not the expected"); + return false; + } + + // remove the runtime passwords + aRecord = xContainer.find(sURL, aMHandler); + for(int i = 0; i < aRecord.UserList.length; i++) { + xContainer.remove(sURL, aRecord.UserList[i].UserName); + } + } catch(Exception e) { + m_aTestHelper.Error("Exception: " + e); + return false; + } + return true; + } +} diff --git a/svl/qa/complex/passwordcontainer/Test02.java b/svl/qa/complex/passwordcontainer/Test02.java new file mode 100644 index 000000000000..5d65d8090cf9 --- /dev/null +++ b/svl/qa/complex/passwordcontainer/Test02.java @@ -0,0 +1,159 @@ +/************************************************************************* + * + * 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: Test02.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.task.XPasswordContainer; +import com.sun.star.task.XMasterPasswordHandling; +import com.sun.star.task.XInteractionHandler; +import com.sun.star.task.UrlRecord; +import com.sun.star.task.UserRecord; + +import com.sun.star.uno.UnoRuntime; + +import share.LogWriter; + +public class Test02 implements PasswordContainerTest { + XMultiServiceFactory m_xMSF = null; + XPasswordContainer m_xPasswordContainer = null; + TestHelper m_aTestHelper = null; + + public Test02 ( XMultiServiceFactory xMSF, LogWriter aLogWriter ) + { + m_xMSF = xMSF; + m_aTestHelper = new TestHelper (aLogWriter, "Test02: "); + } + + public boolean test() { + final String sURL = "http://www.openoffice.org"; + final String sUserPre = "OOoUser"; + final String sPwdPre = "Password"; + final int iUserNum1 = 10; + final int iUserNum2 = 5; + + UserRecord aInputUserList1[] = new UserRecord[iUserNum1]; + for(int i = 0; i < iUserNum1; i++) { + String sTemp[] = {sPwdPre + "_1_" + i}; // currently one password for one user + aInputUserList1[i] = new UserRecord(sUserPre + "_1_" + i, sTemp); + } + UserRecord aInputUserList2[] = new UserRecord[iUserNum2]; + for(int i = 0; i < iUserNum2; i++) { + String sTemp[] = {sPwdPre + "_2_" + i}; + aInputUserList2[i] = new UserRecord(sUserPre + "_2_" + i, sTemp); + } + + try { + Object oPasswordContainer = m_xMSF.createInstance("com.sun.star.task.PasswordContainer"); + XPasswordContainer xContainer = (XPasswordContainer)UnoRuntime.queryInterface(XPasswordContainer.class, oPasswordContainer); + Object oHandler = m_xMSF.createInstance("com.sun.star.task.InteractionHandler"); + XInteractionHandler xHandler = (XInteractionHandler)UnoRuntime.queryInterface(XInteractionHandler.class, oHandler); + MasterPasswdHandler aMHandler = new MasterPasswdHandler(xHandler); + XMasterPasswordHandling xMHandling = (XMasterPasswordHandling)UnoRuntime.queryInterface(XMasterPasswordHandling.class, oPasswordContainer); + + // allow the storing of the passwords + xMHandling.allowPersistentStoring(true); + + // add a set of users and passwords for the same URL persistently + for(int i = 0; i < iUserNum1; ++i) { + xContainer.addPersistent(sURL, aInputUserList1[i].UserName, aInputUserList1[i].Passwords, aMHandler); + } + for(int i = 0; i < iUserNum2; ++i) { + xContainer.addPersistent(sURL, aInputUserList2[i].UserName, aInputUserList2[i].Passwords, aMHandler); + } + + // remove some of the passwords + for(int i = 0; i < iUserNum1; ++i) { + xContainer.remove(sURL, aInputUserList1[i].UserName); + } + + // get the result with find() and check it with the expected one + UrlRecord aRecord = xContainer.find(sURL, aMHandler); + if(!aRecord.Url.equals(sURL)) { + m_aTestHelper.Error("URL mismatch. Got " + aRecord.Url + "; should be " + sURL); + return false; + } + if(!m_aTestHelper.sameLists(aRecord.UserList, aInputUserList2)) { + m_aTestHelper.Error("User list is not the expected"); + return false; + } + + // get the result with getAllPersistent() and check + UrlRecord aRecords[] = xContainer.getAllPersistent(aMHandler); + if(!aRecords[0].Url.equals(sURL)) { + m_aTestHelper.Error("URL mismatch"); + return false; + } + if(!m_aTestHelper.sameLists(aRecords[0].UserList, aInputUserList2)) { + m_aTestHelper.Error("User list is not the expected"); + return false; + } + + // remove all the persistent passwords + xContainer.removeAllPersistent(); + + // remove the runtime passwords + for(int i = 0; i < aRecords[0].UserList.length; ++i) { + xContainer.remove(sURL, aRecords[0].UserList[i].UserName); + } + + // disallow the storing of the passwords + xMHandling.allowPersistentStoring(false); + } catch(Exception e) { + m_aTestHelper.Error("Exception: " + e); + return false; + } + return true; + } +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svl/qa/complex/passwordcontainer/Test03.java b/svl/qa/complex/passwordcontainer/Test03.java new file mode 100644 index 000000000000..69de8b88578b --- /dev/null +++ b/svl/qa/complex/passwordcontainer/Test03.java @@ -0,0 +1,122 @@ +/************************************************************************* + * + * 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: Test03.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.task.UrlRecord; +import com.sun.star.task.UserRecord; +import com.sun.star.task.XPasswordContainer; +import com.sun.star.task.XMasterPasswordHandling; +import com.sun.star.task.XInteractionHandler; + + +import com.sun.star.uno.UnoRuntime; +import share.LogWriter; + +public class Test03 implements PasswordContainerTest { + XMultiServiceFactory m_xMSF = null; + XPasswordContainer m_xPasswordContainer = null; + TestHelper m_aTestHelper = null; + + public Test03 ( XMultiServiceFactory xMSF, LogWriter aLogWriter ) + { + m_xMSF = xMSF; + m_aTestHelper = new TestHelper (aLogWriter, "Test03: "); + } + + public boolean test() { + final String sURL = "http://www.openoffice.org"; + final String sUserPre = "OOoUser"; + final String sPwdPre = "Password"; + final int iPersistentUserNum = 10; + final int iRuntimeUserNum = 5; + + UserRecord aInputUserList[] = new UserRecord[iPersistentUserNum+iRuntimeUserNum]; + for(int i = 0; i < iPersistentUserNum; i++) { + String sTemp[] = {sPwdPre + "_1_" + i}; // currently one password for one user + aInputUserList[i] = new UserRecord(sUserPre + "_1_" + i, sTemp); + } + for(int i = 0; i < iRuntimeUserNum; i++) { + String sTemp[] = {sPwdPre + "_2_" + i}; + aInputUserList[i+iPersistentUserNum] = new UserRecord(sUserPre + "_2_" + i, sTemp); + } + + try { + Object oPasswordContainer = m_xMSF.createInstance("com.sun.star.task.PasswordContainer"); + XPasswordContainer xContainer = (XPasswordContainer)UnoRuntime.queryInterface(XPasswordContainer.class, oPasswordContainer); + Object oHandler = m_xMSF.createInstance("com.sun.star.task.InteractionHandler"); + XInteractionHandler xHandler = (XInteractionHandler)UnoRuntime.queryInterface(XInteractionHandler.class, oHandler); + MasterPasswdHandler aMHandler = new MasterPasswdHandler(xHandler); + XMasterPasswordHandling xMHandling = (XMasterPasswordHandling)UnoRuntime.queryInterface(XMasterPasswordHandling.class, oPasswordContainer); + + // allow the storing of the passwords + xMHandling.allowPersistentStoring(true); + + // add a set of users and passwords for the same URL persistently + for(int i = 0; i < iPersistentUserNum; i++) { + xContainer.addPersistent(sURL, aInputUserList[i].UserName, aInputUserList[i].Passwords, aMHandler); + } + + // add a set of users and passwords for the same URL for runtime + for(int i = 0; i < iRuntimeUserNum; i++) { + xContainer.add(sURL, aInputUserList[i+iPersistentUserNum].UserName, aInputUserList[i+iPersistentUserNum].Passwords, aMHandler); + } + + // get the result for the URL and check that it contains persistent and runtime passwords + UrlRecord aRecord = xContainer.find(sURL, aMHandler); + if(!aRecord.Url.equals(sURL)) { + m_aTestHelper.Error("URL mismatch. Got " + aRecord.Url + "; should be " + sURL); + return false; + } + if(!m_aTestHelper.sameLists(aRecord.UserList, aInputUserList)) { + m_aTestHelper.Error("User list is not the expected"); + return false; + } + + // remove all the persistent passwords + xContainer.removeAllPersistent(); + + // remove the runtime passwords + aRecord = xContainer.find(sURL, aMHandler); + for(int i = 0; i < aRecord.UserList.length; i++) { + xContainer.remove(sURL, aRecord.UserList[i].UserName); + } + + // disallow the storing of the passwords + xMHandling.allowPersistentStoring(false); + }catch(Exception e){ + m_aTestHelper.Error("Exception: " + e); + return false; + } + return true; + } +} diff --git a/svl/qa/complex/passwordcontainer/TestHelper.java b/svl/qa/complex/passwordcontainer/TestHelper.java new file mode 100644 index 000000000000..0f83a9ef9963 --- /dev/null +++ b/svl/qa/complex/passwordcontainer/TestHelper.java @@ -0,0 +1,92 @@ +/************************************************************************* + * + * 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: TestHelper.java,v $ + * + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package complex.passwordcontainer; + +import com.sun.star.task.UserRecord; + +import share.LogWriter; + +public class TestHelper { + LogWriter m_aLogWriter; + String m_sTestPrefix; + + public TestHelper( LogWriter aLogWriter, String sTestPrefix ) { + m_aLogWriter = aLogWriter; + m_sTestPrefix = sTestPrefix; + } + + public void Error( String sError ) { + m_aLogWriter.println( m_sTestPrefix + "Error: " + sError ); + } + + public void Message( String sMessage ) { + m_aLogWriter.println( m_sTestPrefix + sMessage ); + } + + public boolean sameLists(UserRecord aUserList1[], UserRecord aUserList2[]) { + // only works when every name is unique within the list containing it + + if(aUserList1.length != aUserList2.length) { + Message("User list lengths: " + aUserList1.length + " <--> " + aUserList2.length + " respectively "); + return false; + } + + for(int i = 0; i < aUserList1.length; i++) { + int j; + for(j = 0; j < aUserList2.length; j++) { + if(!aUserList1[i].UserName.equals(aUserList2[j].UserName)) + continue; + if(aUserList1[i].Passwords[0].equals(aUserList2[j].Passwords[0])) { + break; + } + } + if(j == aUserList2.length) { + for(int k = 0; k < aUserList1.length; k++) { + Message(aUserList1[k].UserName + " <--> " + aUserList2[i].UserName); + } + return false; + } + } + return true; + } +} + + + + + + + + + + + diff --git a/svl/qa/complex/passwordcontainer/makefile.mk b/svl/qa/complex/passwordcontainer/makefile.mk new file mode 100644 index 000000000000..c3ff7538af0f --- /dev/null +++ b/svl/qa/complex/passwordcontainer/makefile.mk @@ -0,0 +1,91 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.2.38.1 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ = ..$/..$/.. +TARGET = PasswordContainerUnitTest +PRJNAME=svl +PACKAGE = complex$/passwordcontainer + +# --- Settings ----------------------------------------------------- +.INCLUDE: settings.mk + + +#----- compile .java files ----------------------------------------- + +JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar + +JAVAFILES =\ + PasswordContainerUnitTest.java\ + PasswordContainerTest.java\ + TestHelper.java\ + Test01.java\ + Test02.java\ + Test03.java\ + MasterPasswdHandler.java + +JAVACLASSFILES = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +#----- make a jar from compiled files ------------------------------ + +MAXLINELENGTH = 100000 + +JARCLASSDIRS = $(PACKAGE) +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE + +# --- Parameters for the test -------------------------------------- + +# start an office if the parameter is set for the makefile +.IF "$(OFFICE)" == "" +CT_APPEXECCOMMAND = +.ELSE +CT_APPEXECCOMMAND = -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" +.ENDIF + +# test base is java complex +CT_TESTBASE = -TestBase java_complex + +# test looks something like the.full.package.TestName +CT_TEST = -o $(PACKAGE:s\$/\.\).$(JAVAFILES:b) + +# start the runner application +CT_APP = org.openoffice.Runner + +# --- Targets ------------------------------------------------------ + +.INCLUDE: target.mk + +RUN: run + +run: + +java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_TEST) + + diff --git a/svl/qa/export.map b/svl/qa/export.map new file mode 100755 index 000000000000..80373c145ac1 --- /dev/null +++ b/svl/qa/export.map @@ -0,0 +1,38 @@ +#************************************************************************* +# +# 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: export.map,v $ +# +# $Revision: 1.4 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +UDK_3_0_0 { + global: + registerAllTestFunction; + + local: + *; +}; diff --git a/svl/qa/makefile.mk b/svl/qa/makefile.mk new file mode 100644 index 000000000000..439277ea62b0 --- /dev/null +++ b/svl/qa/makefile.mk @@ -0,0 +1,103 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.5 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ = .. +PRJNAME=svl +TARGET = qa + +ENABLE_EXCEPTIONS = true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# BEGIN ---------------------------------------------------------------- +# auto generated Target:job by codegen.pl +SHL1OBJS= \ + $(SLO)$/test_URIHelper.obj + +SHL1TARGET= URIHelper +SHL1STDLIBS=\ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(SVLLIB) \ + $(TOOLSLIB) \ + $(UNOTOOLSLIB) \ + $(TESTSHL2LIB) \ + $(CPPUNITLIB) + +SHL1IMPLIB= i$(SHL1TARGET) +DEF1NAME =$(SHL1TARGET) +SHL1VERSIONMAP= export.map +# auto generated Target:job +# END ------------------------------------------------------------------ + +#------------------------------- All object files ------------------------------- +# do this here, so we get right dependencies +# SLOFILES=$(SHL1OBJS) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk +.INCLUDE : _cppunit.mk + +# LLA: old stuff +# USE_DEFFILE = true +# +# .INCLUDE: settings.mk +# +# .IF "$(OS)" == "WNT" +# REGEXP = "s/^[\#].*$$//" +# .ELSE # OS, WNT +# REGEXP = 's/^[\#].*$$//' +# .ENDIF # OS, WNT +# +# SHL1TARGET = URIHelper +# SHL1OBJS = \ +# $(SLO)$/test_URIHelper.obj +# SHL1STDLIBS = \ +# $(CPPULIB) \ +# $(CPPUHELPERLIB) \ +# $(SALLIB) \ +# $(SVTOOLLIB) \ +# $(TOOLSLIB) \ +# $(UNOTOOLSLIB) +# +# DEF1NAME = $(SHL1TARGET) +# DEF1EXPORTFILE = $(MISC)$/$(SHL1TARGET).dxp +# +# .INCLUDE: target.mk +# +# $(MISC)$/$(SHL1TARGET).dxp: sce$/$(SHL1TARGET).sce +# + $(TYPE) $< | sed $(REGEXP) > $@ +# + $(TYPE) $@ | sed "s/^/test_/" > $(MISC)$/$(SHL1TARGET).tst +# + $(TYPE) $(MISC)$/$(SHL1TARGET).tst | sed "/test_./ w $@" diff --git a/svl/qa/test_URIHelper.cxx b/svl/qa/test_URIHelper.cxx new file mode 100644 index 000000000000..3cf6d30d1813 --- /dev/null +++ b/svl/qa/test_URIHelper.cxx @@ -0,0 +1,462 @@ +/************************************************************************* + * + * 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: test_URIHelper.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "sal/config.h" + +#include <cstddef> + +#include "com/sun/star/lang/Locale.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/ucb/Command.hpp" +#include "com/sun/star/ucb/CommandAbortedException.hpp" +#include "com/sun/star/ucb/IllegalIdentifierException.hpp" +#include "com/sun/star/ucb/XCommandProcessor.hpp" +#include "com/sun/star/ucb/XContent.hpp" +#include "com/sun/star/ucb/XContentIdentifier.hpp" +#include "com/sun/star/ucb/XContentProvider.hpp" +#include "com/sun/star/ucb/XContentProviderManager.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "cppuhelper/bootstrap.hxx" +#include "cppuhelper/implbase1.hxx" +#include "cppuhelper/implbase2.hxx" +#include "testshl/simpleheader.hxx" +#include "osl/diagnose.h" +#include "rtl/strbuf.hxx" +#include "rtl/string.h" +#include "rtl/string.hxx" +#include "rtl/textenc.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include "tools/solar.h" +#include "unotools/charclass.hxx" + +#include "urihelper.hxx" + +// This test needs a UNO component context that supports various services (the +// UCB, an UriReferenceFactory, ...), so it is best executed within an OOo +// installation. + +namespace com { namespace sun { namespace star { namespace ucb { + class XCommandEnvironment; + class XContentEventListener; +} } } } + +namespace { + +namespace css = com::sun::star; + +// This class only implements that subset of functionality of a proper +// css::ucb::Content that is known to be needed here: +class Content: + public cppu::WeakImplHelper2< + css::ucb::XContent, css::ucb::XCommandProcessor > +{ +public: + explicit Content( + css::uno::Reference< css::ucb::XContentIdentifier > const & identifier); + + virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL + getIdentifier() throw (css::uno::RuntimeException) { + return m_identifier; + } + + virtual rtl::OUString SAL_CALL getContentType() + throw (css::uno::RuntimeException) + { + return rtl::OUString(); + } + + virtual void SAL_CALL addContentEventListener( + css::uno::Reference< css::ucb::XContentEventListener > const &) + throw (css::uno::RuntimeException) + {} + + virtual void SAL_CALL removeContentEventListener( + css::uno::Reference< css::ucb::XContentEventListener > const &) + throw (css::uno::RuntimeException) + {} + + virtual sal_Int32 SAL_CALL createCommandIdentifier() + throw (css::uno::RuntimeException) + { + return 0; + } + + virtual css::uno::Any SAL_CALL execute( + css::ucb::Command const & command, sal_Int32 commandId, + css::uno::Reference< css::ucb::XCommandEnvironment > const &) + throw ( + css::uno::Exception, css::ucb::CommandAbortedException, + css::uno::RuntimeException); + + virtual void SAL_CALL abort(sal_Int32) throw (css::uno::RuntimeException) {} + +private: + static char const m_prefix[]; + + css::uno::Reference< css::ucb::XContentIdentifier > m_identifier; +}; + +char const Content::m_prefix[] = "test:"; + +Content::Content( + css::uno::Reference< css::ucb::XContentIdentifier > const & identifier): + m_identifier(identifier) +{ + OSL_ASSERT(m_identifier.is()); + rtl::OUString uri(m_identifier->getContentIdentifier()); + if (!uri.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(m_prefix)) + || uri.indexOf('#', RTL_CONSTASCII_LENGTH(m_prefix)) != -1) + { + throw css::ucb::IllegalIdentifierException(); + } +} + +css::uno::Any Content::execute( + css::ucb::Command const & command, sal_Int32, + css::uno::Reference< css::ucb::XCommandEnvironment > const &) + throw ( + css::uno::Exception, css::ucb::CommandAbortedException, + css::uno::RuntimeException) +{ + if (!command.Name.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("getCasePreservingURL"))) + { + throw css::uno::RuntimeException(); + } + // If any non-empty segment starts with anything but '0', '1', or '2', fail; + // otherwise, if the last non-empty segment starts with '1', add a final + // slash, and if the last non-empty segment starts with '2', remove a final + // slash (if any); also, turn the given uri into all-lowercase: + rtl::OUString uri(m_identifier->getContentIdentifier()); + sal_Unicode c = '0'; + for (sal_Int32 i = RTL_CONSTASCII_LENGTH(m_prefix); i != -1;) { + rtl::OUString seg(uri.getToken(0, '/', i)); + if (seg.getLength() > 0) { + c = seg[0]; + if (c < '0' || c > '2') { + throw css::uno::Exception(); + } + } + } + switch (c) { + case '1': + uri += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")); + break; + case '2': + if (uri.getLength() > 0 && uri[uri.getLength() - 1] == '/') { + uri = uri.copy(0, uri.getLength() -1); + } + break; + } + return css::uno::makeAny(uri.toAsciiLowerCase()); +} + +class Provider: public cppu::WeakImplHelper1< css::ucb::XContentProvider > { +public: + virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent( + css::uno::Reference< css::ucb::XContentIdentifier > const & identifier) + throw (css::ucb::IllegalIdentifierException, css::uno::RuntimeException) + { + return new Content(identifier); + } + + virtual sal_Int32 SAL_CALL compareContentIds( + css::uno::Reference< css::ucb::XContentIdentifier > const & id1, + css::uno::Reference< css::ucb::XContentIdentifier > const & id2) + throw (css::uno::RuntimeException) + { + OSL_ASSERT(id1.is() && id2.is()); + return + id1->getContentIdentifier().compareTo(id2->getContentIdentifier()); + } +}; + +class Test: public CppUnit::TestFixture { +public: + virtual void setUp(); + + void finish(); + + void testNormalizedMakeRelative(); + + void testFindFirstURLInText(); + + CPPUNIT_TEST_SUITE(Test); + CPPUNIT_TEST(testNormalizedMakeRelative); + CPPUNIT_TEST(testFindFirstURLInText); + CPPUNIT_TEST(finish); + CPPUNIT_TEST_SUITE_END(); + +private: + static css::uno::Reference< css::uno::XComponentContext > m_context; +}; + +void Test::setUp() { + // For whatever reason, on W32 it does not work to create/destroy a fresh + // component context for each test in Test::setUp/tearDown; therefore, a + // single component context is used for all tests and destroyed in the last + // pseudo-test "finish": + if (!m_context.is()) { + m_context = cppu::defaultBootstrap_InitialComponentContext(); + } +} + +void Test::finish() { + css::uno::Reference< css::lang::XComponent >( + m_context, css::uno::UNO_QUERY_THROW)->dispose(); +} + +void Test::testNormalizedMakeRelative() { + css::uno::Sequence< css::uno::Any > args(2); + args[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local")); + args[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office")); + css::uno::Reference< css::ucb::XContentProviderManager >( + (css::uno::Reference< css::lang::XMultiComponentFactory >( + m_context->getServiceManager(), css::uno::UNO_QUERY_THROW)-> + createInstanceWithArgumentsAndContext( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ucb.UniversalContentBroker")), + args, m_context)), + css::uno::UNO_QUERY_THROW)->registerContentProvider( + new Provider, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("test")), + true); + struct Test { + char const * base; + char const * absolute; + char const * relative; + }; + static Test const tests[] = { + { "hierarchical:/", "mailto:def@a.b.c.", "mailto:def@a.b.c." }, + { "hierarchical:/", "a/b/c", "a/b/c" }, + { "hierarchical:/a", "hierarchical:/a/b/c?d#e", "/a/b/c?d#e" }, + { "hierarchical:/a/", "hierarchical:/a/b/c?d#e", "b/c?d#e" }, + { "test:/0/0/a", "test:/0/b", "../b" }, + { "test:/1/1/a", "test:/1/b", "../b" }, + { "test:/2/2//a", "test:/2/b", "../../b" }, + { "test:/0a/b", "test:/0A/c#f", "c#f" }, + { "file:///usr/bin/nonex1/nonex2", + "file:///usr/bin/nonex1/nonex3/nonex4", "nonex3/nonex4" }, + { "file:///usr/bin/nonex1/nonex2#fragmentA", + "file:///usr/bin/nonex1/nonex3/nonex4#fragmentB", + "nonex3/nonex4#fragmentB" }, + { "file:///usr/nonex1/nonex2", "file:///usr/nonex3", "../nonex3" }, + { "file:///c:/windows/nonex1", "file:///c:/nonex2", "../nonex2" }, +#if defined WNT + { "file:///c:/nonex1/nonex2", "file:///C:/nonex1/nonex3/nonex4", + "nonex3/nonex4" } +#endif + }; + for (std::size_t i = 0; i < sizeof tests / sizeof tests[0]; ++i) { + css::uno::Reference< css::uri::XUriReference > ref( + URIHelper::normalizedMakeRelative( + m_context, rtl::OUString::createFromAscii(tests[i].base), + rtl::OUString::createFromAscii(tests[i].absolute))); + bool ok = tests[i].relative == 0 + ? !ref.is() + : ref.is() && ref->getUriReference().equalsAscii(tests[i].relative); + rtl::OString msg; + if (!ok) { + rtl::OStringBuffer buf; + buf.append('<'); + buf.append(tests[i].base); + buf.append(RTL_CONSTASCII_STRINGPARAM(">, <")); + buf.append(tests[i].absolute); + buf.append(RTL_CONSTASCII_STRINGPARAM(">: ")); + if (ref.is()) { + buf.append('<'); + buf.append( + rtl::OUStringToOString( + ref->getUriReference(), RTL_TEXTENCODING_UTF8)); + buf.append('>'); + } else { + buf.append(RTL_CONSTASCII_STRINGPARAM("none")); + } + buf.append(RTL_CONSTASCII_STRINGPARAM(" instead of ")); + if (tests[i].relative == 0) { + buf.append(RTL_CONSTASCII_STRINGPARAM("none")); + } else { + buf.append('<'); + buf.append(tests[i].relative); + buf.append('>'); + } + msg = buf.makeStringAndClear(); + } + CPPUNIT_ASSERT_MESSAGE(msg.getStr(), ok); + } +} + +void Test::testFindFirstURLInText() { + struct Test { + char const * input; + char const * result; + xub_StrLen begin; + xub_StrLen end; + }; + static Test const tests[] = { + { "...ftp://bla.bla.bla/blubber/...", + "ftp://bla.bla.bla/blubber/", 3, 29 }, + { "..\\ftp://bla.bla.bla/blubber/...", 0, 0, 0 }, + { "..\\ftp:\\\\bla.bla.bla\\blubber/...", + "file://bla.bla.bla/blubber%2F", 7, 29 }, + { "http://sun.com", "http://sun.com/", 0, 14 }, + { "http://sun.com/", "http://sun.com/", 0, 15 }, + { "http://www.xerox.com@www.pcworld.com/go/3990332.htm", 0, 0, 0 }, + { "ftp://www.xerox.com@www.pcworld.com/go/3990332.htm", + "ftp://www.xerox.com@www.pcworld.com/go/3990332.htm", 0, 50 }, + { "Version.1.2.3", 0, 0, 0 }, + { "Version:1.2.3", 0, 0, 0 }, + { "a.b.c", 0, 0, 0 }, + { "file:///a|...", "file:///a:", 0, 10 }, + { "file:///a||...", "file:///a%7C%7C", 0, 11 }, + { "file:///a|/bc#...", "file:///a:/bc", 0, 13 }, + { "file:///a|/bc#de...", "file:///a:/bc#de", 0, 16 }, + { "abc.def.ghi,ftp.xxx.yyy/zzz...", "ftp://ftp.xxx.yyy/zzz", 12, 27 }, + { "abc.def.ghi,Ftp.xxx.yyy/zzz...", "ftp://Ftp.xxx.yyy/zzz", 12, 27 }, + { "abc.def.ghi,www.xxx.yyy...", "http://www.xxx.yyy/", 12, 23 }, + { "abc.def.ghi,wwww.xxx.yyy...", 0, 0, 0 }, + { "abc.def.ghi,wWW.xxx.yyy...", "http://wWW.xxx.yyy/", 12, 23 }, + { "Bla {mailto.me@abc.def.g.h.i}...", + "mailto:%7Bmailto.me@abc.def.g.h.i", 4, 28 }, + { "abc@def@ghi", 0, 0, 0 }, + { "lala@sun.com", "mailto:lala@sun.com", 0, 12 }, + { "1lala@sun.com", "mailto:1lala@sun.com", 0, 13 }, + { "aaa_bbb@xxx.yy", "mailto:aaa_bbb@xxx.yy", 0, 14 }, + { "{a:\\bla/bla/bla...}", "file:///a:/bla/bla/bla", 1, 15 }, + { "#b:/c/d#e#f#", "file:///b:/c/d", 1, 7 }, + { "a:/", "file:///a:/", 0, 3 }, + { ".component:", 0, 0, 0 }, + { ".uno:", 0, 0, 0 }, + { "cid:", 0, 0, 0 }, + { "data:", 0, 0, 0 }, + { "db:", 0, 0, 0 }, + { "file:", 0, 0, 0 }, + { "ftp:", 0, 0, 0 }, + { "http:", 0, 0, 0 }, + { "https:", 0, 0, 0 }, + { "imap:", 0, 0, 0 }, + { "javascript:", 0, 0, 0 }, + { "ldap:", 0, 0, 0 }, + { "macro:", 0, 0, 0 }, + { "mailto:", 0, 0, 0 }, + { "news:", 0, 0, 0 }, + { "out:", 0, 0, 0 }, + { "pop3:", 0, 0, 0 }, + { "private:", 0, 0, 0 }, + { "slot:", 0, 0, 0 }, + { "staroffice.component:", 0, 0, 0 }, + { "staroffice.db:", 0, 0, 0 }, + { "staroffice.factory:", 0, 0, 0 }, + { "staroffice.helpid:", 0, 0, 0 }, + { "staroffice.java:", 0, 0, 0 }, + { "staroffice.macro:", 0, 0, 0 }, + { "staroffice.out:", 0, 0, 0 }, + { "staroffice.pop3:", 0, 0, 0 }, + { "staroffice.private:", 0, 0, 0 }, + { "staroffice.searchfolder:", 0, 0, 0 }, + { "staroffice.slot:", 0, 0, 0 }, + { "staroffice.trashcan:", 0, 0, 0 }, + { "staroffice.uno:", 0, 0, 0 }, + { "staroffice.vim:", 0, 0, 0 }, + { "staroffice:", 0, 0, 0 }, + { "vim:", 0, 0, 0 }, + { "vnd.sun.star.cmd:", 0, 0, 0 }, + { "vnd.sun.star.help:", 0, 0, 0 }, + { "vnd.sun.star.hier:", 0, 0, 0 }, + { "vnd.sun.star.odma:", 0, 0, 0 }, + { "vnd.sun.star.pkg:", 0, 0, 0 }, + { "vnd.sun.star.script:", 0, 0, 0 }, + { "vnd.sun.star.webdav:", 0, 0, 0 }, + { "vnd.sun.star.wfs:", 0, 0, 0 }, + { "generic:path", 0, 0, 0 }, + { "wfs:", 0, 0, 0 } + }; + CharClass charClass( + css::uno::Reference< css::lang::XMultiServiceFactory >( + m_context->getServiceManager(), css::uno::UNO_QUERY_THROW), + com::sun::star::lang::Locale( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")), rtl::OUString())); + for (std::size_t i = 0; i < sizeof tests / sizeof tests[0]; ++i) { + rtl::OUString input(rtl::OUString::createFromAscii(tests[i].input)); + xub_StrLen begin = 0; + xub_StrLen end = static_cast< xub_StrLen >(input.getLength()); + rtl::OUString result( + URIHelper::FindFirstURLInText(input, begin, end, charClass)); + bool ok = tests[i].result == 0 + ? (result.getLength() == 0 && begin == input.getLength() + && end == input.getLength()) + : (result.equalsAscii(tests[i].result) && begin == tests[i].begin + && end == tests[i].end); + rtl::OString msg; + if (!ok) { + rtl::OStringBuffer buf; + buf.append('"'); + buf.append(tests[i].input); + buf.append(RTL_CONSTASCII_STRINGPARAM("\" -> ")); + buf.append(tests[i].result == 0 ? "none" : tests[i].result); + buf.append(RTL_CONSTASCII_STRINGPARAM(" (")); + buf.append(static_cast< sal_Int32 >(tests[i].begin)); + buf.append(RTL_CONSTASCII_STRINGPARAM(", ")); + buf.append(static_cast< sal_Int32 >(tests[i].end)); + buf.append(')'); + buf.append(RTL_CONSTASCII_STRINGPARAM(" != ")); + buf.append(rtl::OUStringToOString(result, RTL_TEXTENCODING_UTF8)); + buf.append(RTL_CONSTASCII_STRINGPARAM(" (")); + buf.append(static_cast< sal_Int32 >(begin)); + buf.append(RTL_CONSTASCII_STRINGPARAM(", ")); + buf.append(static_cast< sal_Int32 >(end)); + buf.append(')'); + msg = buf.makeStringAndClear(); + } + CPPUNIT_ASSERT_MESSAGE(msg.getStr(), ok); + } +} + +css::uno::Reference< css::uno::XComponentContext > Test::m_context; + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests"); + +} + +NOADDITIONAL; diff --git a/svl/source/config/cjkoptions.cxx b/svl/source/config/cjkoptions.cxx new file mode 100644 index 000000000000..c149c91c86f5 --- /dev/null +++ b/svl/source/config/cjkoptions.cxx @@ -0,0 +1,507 @@ +/************************************************************************* + * + * 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: cjkoptions.cxx,v $ + * $Revision: 1.22 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/cjkoptions.hxx> + +#include <svl/languageoptions.hxx> +#include <i18npool/lang.h> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/mutex.hxx> +#include <rtl/instance.hxx> + +#include <itemholder2.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::rtl; + +#define C2U(cChar) OUString::createFromAscii(cChar) +#define CFG_READONLY_DEFAULT sal_False +/* -----------------------------10.04.01 12:39-------------------------------- + + ---------------------------------------------------------------------------*/ +class SvtCJKOptions_Impl : public utl::ConfigItem +{ + sal_Bool bIsLoaded; + sal_Bool bCJKFont; + sal_Bool bVerticalText; + sal_Bool bAsianTypography; + sal_Bool bJapaneseFind; + sal_Bool bRuby; + sal_Bool bChangeCaseMap; + sal_Bool bDoubleLines; + sal_Bool bEmphasisMarks; + sal_Bool bVerticalCallOut; + + sal_Bool bROCJKFont; + sal_Bool bROVerticalText; + sal_Bool bROAsianTypography; + sal_Bool bROJapaneseFind; + sal_Bool bRORuby; + sal_Bool bROChangeCaseMap; + sal_Bool bRODoubleLines; + sal_Bool bROEmphasisMarks; + sal_Bool bROVerticalCallOut; + +public: + SvtCJKOptions_Impl(); + ~SvtCJKOptions_Impl(); + + virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString >& rPropertyNames ); + virtual void Commit(); + void Load(); + + sal_Bool IsLoaded() { return bIsLoaded; } + + sal_Bool IsCJKFontEnabled() const { return bCJKFont; } + sal_Bool IsVerticalTextEnabled() const { return bVerticalText; } + sal_Bool IsAsianTypographyEnabled() const { return bAsianTypography; } + sal_Bool IsJapaneseFindEnabled() const { return bJapaneseFind; } + sal_Bool IsRubyEnabled() const { return bRuby; } + sal_Bool IsChangeCaseMapEnabled() const { return bChangeCaseMap; } + sal_Bool IsDoubleLinesEnabled() const { return bDoubleLines; } + sal_Bool IsEmphasisMarksEnabled() const { return bEmphasisMarks; } + sal_Bool IsVerticalCallOutEnabled() const { return bVerticalCallOut; } + + sal_Bool IsAnyEnabled() const { + return bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind|| + bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut; } + void SetAll(sal_Bool bSet); + sal_Bool IsReadOnly(SvtCJKOptions::EOption eOption) const; +}; +/*-- 10.04.01 12:41:57--------------------------------------------------- + + -----------------------------------------------------------------------*/ +namespace +{ + struct PropertyNames + : public rtl::Static< Sequence<OUString>, PropertyNames > {}; +} + +SvtCJKOptions_Impl::SvtCJKOptions_Impl() : + utl::ConfigItem(C2U("Office.Common/I18N/CJK")), + bIsLoaded(sal_False), + bCJKFont(sal_True), + bVerticalText(sal_True), + bAsianTypography(sal_True), + bJapaneseFind(sal_True), + bRuby(sal_True), + bChangeCaseMap(sal_True), + bDoubleLines(sal_True), + bEmphasisMarks(sal_True), + bVerticalCallOut(sal_True), + bROCJKFont(CFG_READONLY_DEFAULT), + bROVerticalText(CFG_READONLY_DEFAULT), + bROAsianTypography(CFG_READONLY_DEFAULT), + bROJapaneseFind(CFG_READONLY_DEFAULT), + bRORuby(CFG_READONLY_DEFAULT), + bROChangeCaseMap(CFG_READONLY_DEFAULT), + bRODoubleLines(CFG_READONLY_DEFAULT), + bROEmphasisMarks(CFG_READONLY_DEFAULT), + bROVerticalCallOut(CFG_READONLY_DEFAULT) +{ +} +/*-- 10.04.01 12:41:57--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtCJKOptions_Impl::~SvtCJKOptions_Impl() +{ +} +/* -----------------------------20.04.01 14:34-------------------------------- + + ---------------------------------------------------------------------------*/ +void SvtCJKOptions_Impl::SetAll(sal_Bool bSet) +{ + if ( + !bROCJKFont && + !bROVerticalText && + !bROAsianTypography && + !bROJapaneseFind && + !bRORuby && + !bROChangeCaseMap && + !bRODoubleLines && + !bROEmphasisMarks && + !bROVerticalCallOut + ) + { + bCJKFont=bSet; + bVerticalText=bSet; + bAsianTypography=bSet; + bJapaneseFind=bSet; + bRuby=bSet; + bChangeCaseMap=bSet; + bDoubleLines=bSet; + bEmphasisMarks=bSet; + bVerticalCallOut=bSet; + + SetModified(); + Commit(); + NotifyListeners(0); + } +} +/*-- 10.04.01 12:41:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtCJKOptions_Impl::Load() +{ + Sequence<OUString> &rPropertyNames = PropertyNames::get(); + if(!rPropertyNames.getLength()) + { + rPropertyNames.realloc(9); + OUString* pNames = rPropertyNames.getArray(); + + pNames[0] = C2U("CJKFont"); + pNames[1] = C2U("VerticalText"); + pNames[2] = C2U("AsianTypography"); + pNames[3] = C2U("JapaneseFind"); + pNames[4] = C2U("Ruby"); + pNames[5] = C2U("ChangeCaseMap"); + pNames[6] = C2U("DoubleLines"); + pNames[7] = C2U("EmphasisMarks"); + pNames[8] = C2U("VerticalCallOut"); + + EnableNotification( rPropertyNames ); + } + Sequence< Any > aValues = GetProperties(rPropertyNames); + Sequence< sal_Bool > aROStates = GetReadOnlyStates(rPropertyNames); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" ); + DBG_ASSERT( aROStates.getLength() == rPropertyNames.getLength(), "GetReadOnlyStates failed" ); + if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() ) + { + for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ ) + { + if( pValues[nProp].hasValue() ) + { + sal_Bool bValue = *(sal_Bool*)pValues[nProp].getValue(); + switch ( nProp ) + { + case 0: { bCJKFont = bValue; bROCJKFont = pROStates[nProp]; } break; + case 1: { bVerticalText = bValue; bROVerticalText = pROStates[nProp]; } break; + case 2: { bAsianTypography = bValue; bROAsianTypography = pROStates[nProp]; } break; + case 3: { bJapaneseFind = bValue; bROJapaneseFind = pROStates[nProp]; } break; + case 4: { bRuby = bValue; bRORuby = pROStates[nProp]; } break; + case 5: { bChangeCaseMap = bValue; bROChangeCaseMap = pROStates[nProp]; } break; + case 6: { bDoubleLines = bValue; bRODoubleLines = pROStates[nProp]; } break; + case 7: { bEmphasisMarks = bValue; bROEmphasisMarks = pROStates[nProp]; } break; + case 8: { bVerticalCallOut = bValue; bROVerticalCallOut = pROStates[nProp]; } break; + } + } + } + } + + SvtSystemLanguageOptions aSystemLocaleSettings; + LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage(); + sal_uInt16 nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage ); + + sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM); + if ( !bCJKFont && (( nScriptType & SCRIPTTYPE_ASIAN )|| + ((eSystemLanguage != LANGUAGE_SYSTEM) && ( nWinScript & SCRIPTTYPE_ASIAN )))) + { + SetAll(sal_True); + } + bIsLoaded = sal_True; +} +/*-- 10.04.01 12:41:57--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtCJKOptions_Impl::Notify( const Sequence< OUString >& ) +{ + Load(); + NotifyListeners(0); +} +/*-- 10.04.01 12:41:57--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtCJKOptions_Impl::Commit() +{ + Sequence<OUString> &rPropertyNames = PropertyNames::get(); + OUString* pOrgNames = rPropertyNames.getArray(); + sal_Int32 nOrgCount = rPropertyNames.getLength(); + + Sequence< OUString > aNames(nOrgCount); + Sequence< Any > aValues(nOrgCount); + + OUString* pNames = aNames.getArray(); + Any* pValues = aValues.getArray(); + sal_Int32 nRealCount = 0; + + const Type& rType = ::getBooleanCppuType(); + for(int nProp = 0; nProp < nOrgCount; nProp++) + { + switch(nProp) + { + case 0: + { + if (!bROCJKFont) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bCJKFont, rType); + ++nRealCount; + } + } + break; + + case 1: + { + if (!bROVerticalText) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bVerticalText, rType); + ++nRealCount; + } + } + break; + + case 2: + { + if (!bROAsianTypography) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bAsianTypography, rType); + ++nRealCount; + } + } + break; + + case 3: + { + if (!bROJapaneseFind) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bJapaneseFind, rType); + ++nRealCount; + } + } + break; + + case 4: + { + if (!bRORuby) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bRuby, rType); + ++nRealCount; + } + } + break; + + case 5: + { + if (!bROChangeCaseMap) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bChangeCaseMap, rType); + ++nRealCount; + } + } + break; + + case 6: + { + if (!bRODoubleLines) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bDoubleLines, rType); + ++nRealCount; + } + } + break; + + case 7: + { + if (!bROEmphasisMarks) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bEmphasisMarks, rType); + ++nRealCount; + } + } + break; + + case 8: + { + if (!bROVerticalCallOut) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue(&bVerticalCallOut, rType); + ++nRealCount; + } + } + break; + } + } + aNames.realloc(nRealCount); + aValues.realloc(nRealCount); + PutProperties(aNames, aValues); +} +/*-- 13.02.2003 12:12--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtCJKOptions_Impl::IsReadOnly(SvtCJKOptions::EOption eOption) const +{ + sal_Bool bReadOnly = CFG_READONLY_DEFAULT; + switch(eOption) + { + case SvtCJKOptions::E_CJKFONT : bReadOnly = bROCJKFont; break; + case SvtCJKOptions::E_VERTICALTEXT : bReadOnly = bROVerticalText; break; + case SvtCJKOptions::E_ASIANTYPOGRAPHY : bReadOnly = bROAsianTypography; break; + case SvtCJKOptions::E_JAPANESEFIND : bReadOnly = bROJapaneseFind; break; + case SvtCJKOptions::E_RUBY : bReadOnly = bRORuby; break; + case SvtCJKOptions::E_CHANGECASEMAP : bReadOnly = bROChangeCaseMap; break; + case SvtCJKOptions::E_DOUBLELINES : bReadOnly = bRODoubleLines; break; + case SvtCJKOptions::E_EMPHASISMARKS : bReadOnly = bROEmphasisMarks; break; + case SvtCJKOptions::E_VERTICALCALLOUT : bReadOnly = bROVerticalCallOut; break; + case SvtCJKOptions::E_ALL : if (bROCJKFont || bROVerticalText || bROAsianTypography || bROJapaneseFind || bRORuby || bROChangeCaseMap || bRODoubleLines || bROEmphasisMarks || bROVerticalCallOut) + bReadOnly = sal_True; + break; + } + return bReadOnly; +} + +// global ---------------------------------------------------------------- + +static SvtCJKOptions_Impl* pCJKOptions = NULL; +static sal_Int32 nCJKRefCount = 0; +namespace { struct CJKMutex : public rtl::Static< ::osl::Mutex , CJKMutex >{}; } + + +// class SvtCJKOptions -------------------------------------------------- + +SvtCJKOptions::SvtCJKOptions(sal_Bool bDontLoad) +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( CJKMutex::get() ); + if ( !pCJKOptions ) + { + pCJKOptions = new SvtCJKOptions_Impl; + ItemHolder2::holdConfigItem(E_CJKOPTIONS); + } + if( !bDontLoad && !pCJKOptions->IsLoaded()) + pCJKOptions->Load(); + + ++nCJKRefCount; + pImp = pCJKOptions; +} + +// ----------------------------------------------------------------------- + +SvtCJKOptions::~SvtCJKOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( CJKMutex::get() ); + if ( !--nCJKRefCount ) + DELETEZ( pCJKOptions ); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsCJKFontEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsCJKFontEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsVerticalTextEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsVerticalTextEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsAsianTypographyEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsAsianTypographyEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsJapaneseFindEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsJapaneseFindEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsRubyEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsRubyEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsChangeCaseMapEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsChangeCaseMapEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsDoubleLinesEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsDoubleLinesEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsEmphasisMarksEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsEmphasisMarksEnabled(); +} +// ----------------------------------------------------------------------- +sal_Bool SvtCJKOptions::IsVerticalCallOutEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsVerticalCallOutEnabled(); +} +/*-- 20.04.01 14:32:04--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtCJKOptions::SetAll(sal_Bool bSet) +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + pCJKOptions->SetAll(bSet); +} +/*-- 20.04.01 14:32:06--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtCJKOptions::IsAnyEnabled() const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsAnyEnabled(); +} +/*-- 13.02.2003 12:11--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtCJKOptions::IsReadOnly(EOption eOption) const +{ + DBG_ASSERT(pCJKOptions->IsLoaded(), "CJK options not loaded"); + return pCJKOptions->IsReadOnly(eOption); +} + diff --git a/svl/source/config/ctloptions.cxx b/svl/source/config/ctloptions.cxx new file mode 100644 index 000000000000..a776bc4b807c --- /dev/null +++ b/svl/source/config/ctloptions.cxx @@ -0,0 +1,495 @@ +/************************************************************************* + * + * 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: ctloptions.cxx,v $ + * $Revision: 1.18.140.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/ctloptions.hxx> + +#include <svl/languageoptions.hxx> +#include <i18npool/mslangid.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <osl/mutex.hxx> +#include <vos/mutex.hxx> +#include <svl/smplhint.hxx> +#include <rtl/instance.hxx> +#include <unotools/syslocale.hxx> +#include <itemholder2.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +#define ASCII_STR(s) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(s) ) +#define CFG_READONLY_DEFAULT sal_False + +// SvtCJKOptions_Impl ---------------------------------------------------------- + +class SvtCTLOptions_Impl : public utl::ConfigItem +{ +private: + sal_Bool m_bIsLoaded; + sal_Bool m_bCTLFontEnabled; + sal_Bool m_bCTLSequenceChecking; + sal_Bool m_bCTLRestricted; + sal_Bool m_bCTLTypeAndReplace; + SvtCTLOptions::CursorMovement m_eCTLCursorMovement; + SvtCTLOptions::TextNumerals m_eCTLTextNumerals; + + sal_Bool m_bROCTLFontEnabled; + sal_Bool m_bROCTLSequenceChecking; + sal_Bool m_bROCTLRestricted; + sal_Bool m_bROCTLTypeAndReplace; + sal_Bool m_bROCTLCursorMovement; + sal_Bool m_bROCTLTextNumerals; + +public: + SvtCTLOptions_Impl(); + ~SvtCTLOptions_Impl(); + + virtual void Notify( const Sequence< rtl::OUString >& _aPropertyNames ); + virtual void Commit(); + void Load(); + + sal_Bool IsLoaded() { return m_bIsLoaded; } + void SetCTLFontEnabled( sal_Bool _bEnabled ); + sal_Bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; } + + void SetCTLSequenceChecking( sal_Bool _bEnabled ); + sal_Bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;} + + void SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingRestricted( void ) const { return m_bCTLRestricted; } + + void SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ); + sal_Bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; } + + void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ); + SvtCTLOptions::CursorMovement + GetCTLCursorMovement() const { return m_eCTLCursorMovement; } + + void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ); + SvtCTLOptions::TextNumerals + GetCTLTextNumerals() const { return m_eCTLTextNumerals; } + + sal_Bool IsReadOnly(SvtCTLOptions::EOption eOption) const; +}; +//------------------------------------------------------------------------------ +namespace +{ + struct PropertyNames + : public rtl::Static< Sequence< rtl::OUString >, PropertyNames > {}; +} +//------------------------------------------------------------------------------ +sal_Bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const +{ + sal_Bool bReadOnly = CFG_READONLY_DEFAULT; + switch(eOption) + { + case SvtCTLOptions::E_CTLFONT : bReadOnly = m_bROCTLFontEnabled ; break; + case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking ; break; + case SvtCTLOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_bROCTLCursorMovement ; break; + case SvtCTLOptions::E_CTLTEXTNUMERALS : bReadOnly = m_bROCTLTextNumerals ; break; + case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted ; break; + case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break; + default: DBG_ERROR( "SvtCTLOptions_Impl::IsReadOnly() - invalid option" ); + } + return bReadOnly; +} +//------------------------------------------------------------------------------ +SvtCTLOptions_Impl::SvtCTLOptions_Impl() : + + utl::ConfigItem( ASCII_STR("Office.Common/I18N/CTL") ), + + m_bIsLoaded ( sal_False ), + m_bCTLFontEnabled ( sal_False ), + m_bCTLSequenceChecking ( sal_False ), + m_bCTLRestricted ( sal_False ), + m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL ), + m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC ), + + m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT ), + m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ), + m_bROCTLRestricted ( CFG_READONLY_DEFAULT ), + m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT ), + m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT ) +{ +} +//------------------------------------------------------------------------------ +SvtCTLOptions_Impl::~SvtCTLOptions_Impl() +{ + if ( IsModified() == sal_True ) + Commit(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions_Impl::Notify( const Sequence< rtl::OUString >& ) +{ + Load(); + NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions_Impl::Commit() +{ + Sequence< rtl::OUString > &rPropertyNames = PropertyNames::get(); + rtl::OUString* pOrgNames = rPropertyNames.getArray(); + sal_Int32 nOrgCount = rPropertyNames.getLength(); + + Sequence< rtl::OUString > aNames( nOrgCount ); + Sequence< Any > aValues( nOrgCount ); + + rtl::OUString* pNames = aNames.getArray(); + Any* pValues = aValues.getArray(); + sal_Int32 nRealCount = 0; + + const uno::Type& rType = ::getBooleanCppuType(); + + for ( int nProp = 0; nProp < nOrgCount; nProp++ ) + { + switch ( nProp ) + { + case 0: + { + if (!m_bROCTLFontEnabled) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue( &m_bCTLFontEnabled, rType ); + ++nRealCount; + } + } + break; + + case 1: + { + if (!m_bROCTLSequenceChecking) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue( &m_bCTLSequenceChecking, rType ); + ++nRealCount; + } + } + break; + + case 2: + { + if (!m_bROCTLCursorMovement) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount] <<= (sal_Int32)m_eCTLCursorMovement; + ++nRealCount; + } + } + break; + + case 3: + { + if (!m_bROCTLTextNumerals) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount] <<= (sal_Int32)m_eCTLTextNumerals; + ++nRealCount; + } + } + break; + + case 4: + { + if (!m_bROCTLRestricted) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue( &m_bCTLRestricted, rType ); + ++nRealCount; + } + } + break; + case 5: + { + if(!m_bROCTLTypeAndReplace) + { + pNames[nRealCount] = pOrgNames[nProp]; + pValues[nRealCount].setValue( &m_bCTLTypeAndReplace, rType ); + ++nRealCount; + } + } + break; + } + } + aNames.realloc(nRealCount); + aValues.realloc(nRealCount); + PutProperties( aNames, aValues ); + //broadcast changes + NotifyListeners(SFX_HINT_CTL_SETTINGS_CHANGED); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions_Impl::Load() +{ + Sequence< rtl::OUString >& rPropertyNames = PropertyNames::get(); + if ( !rPropertyNames.getLength() ) + { + rPropertyNames.realloc(6); + rtl::OUString* pNames = rPropertyNames.getArray(); + pNames[0] = ASCII_STR("CTLFont"); + pNames[1] = ASCII_STR("CTLSequenceChecking"); + pNames[2] = ASCII_STR("CTLCursorMovement"); + pNames[3] = ASCII_STR("CTLTextNumerals"); + pNames[4] = ASCII_STR("CTLSequenceCheckingRestricted"); + pNames[5] = ASCII_STR("CTLSequenceCheckingTypeAndReplace"); + EnableNotification( rPropertyNames ); + } + Sequence< Any > aValues = GetProperties( rPropertyNames ); + Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames ); + const Any* pValues = aValues.getConstArray(); + const sal_Bool* pROStates = aROStates.getConstArray(); + DBG_ASSERT( aValues.getLength() == rPropertyNames.getLength(), "GetProperties failed" ); + DBG_ASSERT( aROStates.getLength() == rPropertyNames.getLength(), "GetReadOnlyStates failed" ); + if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() ) + { + sal_Bool bValue = sal_False; + sal_Int32 nValue = 0; + + for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ ) + { + if ( pValues[nProp].hasValue() ) + { + if ( pValues[nProp] >>= bValue ) + { + switch ( nProp ) + { + case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break; + case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break; + case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break; + case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break; + } + } + else if ( pValues[nProp] >>= nValue ) + { + switch ( nProp ) + { + case 2: { m_eCTLCursorMovement = (SvtCTLOptions::CursorMovement)nValue; m_bROCTLCursorMovement = pROStates[nProp]; } break; + case 3: { m_eCTLTextNumerals = (SvtCTLOptions::TextNumerals)nValue; m_bROCTLTextNumerals = pROStates[nProp]; } break; + } + } + } + } + } + sal_uInt16 nType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM); + SvtSystemLanguageOptions aSystemLocaleSettings; + LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage(); + sal_uInt16 nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage ); + if( !m_bCTLFontEnabled && (( nType & SCRIPTTYPE_COMPLEX ) || + ((eSystemLanguage != LANGUAGE_SYSTEM) && ( nWinScript & SCRIPTTYPE_COMPLEX ))) ) + { + m_bCTLFontEnabled = sal_True; + sal_uInt16 nLanguage = SvtSysLocale().GetLanguage(); + //enable sequence checking for the appropriate languages + m_bCTLSequenceChecking = m_bCTLRestricted = m_bCTLTypeAndReplace = + (MsLangId::needsSequenceChecking( nLanguage) || + MsLangId::needsSequenceChecking( eSystemLanguage)); + Commit(); + } + m_bIsLoaded = sal_True; +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLFontEnabled( sal_Bool _bEnabled ) +{ + if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled) + { + m_bCTLFontEnabled = _bEnabled; + SetModified(); + NotifyListeners(0); + } +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLSequenceChecking( sal_Bool _bEnabled ) +{ + if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled) + { + SetModified(); + m_bCTLSequenceChecking = _bEnabled; + NotifyListeners(0); + } +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( sal_Bool _bEnabled ) +{ + if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled) + { + SetModified(); + m_bCTLRestricted = _bEnabled; + NotifyListeners(0); + } +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnabled ) +{ + if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled) + { + SetModified(); + m_bCTLTypeAndReplace = _bEnabled; + NotifyListeners(0); + } +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ) +{ + if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement ) + { + SetModified(); + m_eCTLCursorMovement = _eMovement; + NotifyListeners(0); + } +} +//------------------------------------------------------------------------------ +void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ) +{ + if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals ) + { + SetModified(); + m_eCTLTextNumerals = _eNumerals; + NotifyListeners(0); + } +} +// global ---------------------------------------------------------------- + +static SvtCTLOptions_Impl* pCTLOptions = NULL; +static sal_Int32 nCTLRefCount = 0; +namespace { struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {}; } + +// class SvtCTLOptions -------------------------------------------------- + +SvtCTLOptions::SvtCTLOptions( sal_Bool bDontLoad ) +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( CTLMutex::get() ); + if ( !pCTLOptions ) + { + pCTLOptions = new SvtCTLOptions_Impl; + ItemHolder2::holdConfigItem(E_CTLOPTIONS); + } + if( !bDontLoad && !pCTLOptions->IsLoaded() ) + pCTLOptions->Load(); + + ++nCTLRefCount; + m_pImp = pCTLOptions; + m_pImp->AddListener(this); +} + +// ----------------------------------------------------------------------- + +SvtCTLOptions::~SvtCTLOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( CTLMutex::get() ); + + m_pImp->RemoveListener(this); + if ( !--nCTLRefCount ) + DELETEZ( pCTLOptions ); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLFontEnabled( sal_Bool _bEnabled ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLFontEnabled( _bEnabled ); +} +// ----------------------------------------------------------------------------- +sal_Bool SvtCTLOptions::IsCTLFontEnabled() const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->IsCTLFontEnabled(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLSequenceChecking( sal_Bool _bEnabled ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLSequenceChecking(_bEnabled); +} +// ----------------------------------------------------------------------------- +sal_Bool SvtCTLOptions::IsCTLSequenceChecking() const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->IsCTLSequenceChecking(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLSequenceCheckingRestricted(_bEnable); +} +// ----------------------------------------------------------------------------- +sal_Bool SvtCTLOptions::IsCTLSequenceCheckingRestricted( void ) const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->IsCTLSequenceCheckingRestricted(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLSequenceCheckingTypeAndReplace(_bEnable); +} +// ----------------------------------------------------------------------------- +sal_Bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->IsCTLSequenceCheckingTypeAndReplace(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLCursorMovement( _eMovement ); +} +// ----------------------------------------------------------------------------- +SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->GetCTLCursorMovement(); +} +// ----------------------------------------------------------------------------- +void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals ) +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + pCTLOptions->SetCTLTextNumerals( _eNumerals ); +} +// ----------------------------------------------------------------------------- +SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->GetCTLTextNumerals(); +} +// ----------------------------------------------------------------------------- +sal_Bool SvtCTLOptions::IsReadOnly(EOption eOption) const +{ + DBG_ASSERT( pCTLOptions->IsLoaded(), "CTL options not loaded" ); + return pCTLOptions->IsReadOnly(eOption); +} +// ----------------------------------------------------------------------------- + diff --git a/svl/source/config/itemholder2.cxx b/svl/source/config/itemholder2.cxx new file mode 100644 index 000000000000..695c6598140c --- /dev/null +++ b/svl/source/config/itemholder2.cxx @@ -0,0 +1,182 @@ +/************************************************************************* + * + * 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: itemholder2.cxx,v $ + * $Revision: 1.13 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "itemholder2.hxx" + +//----------------------------------------------- +// includes +#include <comphelper/processfactory.hxx> +#include <com/sun/star/lang/XComponent.hpp> + +#include <svl/cjkoptions.hxx> +#include <svl/ctloptions.hxx> +#include <svl/languageoptions.hxx> +#include <unotools/options.hxx> + +#include <tools/debug.hxx> + +//----------------------------------------------- +// namespaces + +namespace css = ::com::sun::star; + +//----------------------------------------------- +// declarations + +//----------------------------------------------- +ItemHolder2::ItemHolder2() + : ItemHolderMutexBase() +{ + try + { + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); + css::uno::Reference< css::lang::XComponent > xCfg( + xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), + css::uno::UNO_QUERY); + if (xCfg.is()) + xCfg->addEventListener(static_cast< css::lang::XEventListener* >(this)); + } +// #i37892 got errorhandling from ConfigManager::GetConfigurationProvider() + catch(css::uno::RuntimeException& rREx) + { + throw rREx; + } +#ifdef DBG_UTIL + catch(css::uno::Exception& rEx) + { + static sal_Bool bMessage = sal_True; + if(bMessage) + { + bMessage = sal_False; + ::rtl::OString sMsg("CreateInstance with arguments exception: "); + sMsg += ::rtl::OString(rEx.Message.getStr(), + rEx.Message.getLength(), + RTL_TEXTENCODING_ASCII_US); + DBG_ERROR(sMsg.getStr()); + } + } +#else + catch(css::uno::Exception&){} +#endif +} + +//----------------------------------------------- +ItemHolder2::~ItemHolder2() +{ + impl_releaseAllItems(); +} + +//----------------------------------------------- +void ItemHolder2::holdConfigItem(EItem eItem) +{ + static ItemHolder2* pHolder = new ItemHolder2(); + pHolder->impl_addItem(eItem); +} + +//----------------------------------------------- +void SAL_CALL ItemHolder2::disposing(const css::lang::EventObject&) + throw(css::uno::RuntimeException) +{ + impl_releaseAllItems(); +} + +//----------------------------------------------- +void ItemHolder2::impl_addItem(EItem eItem) +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + TItems::const_iterator pIt; + for ( pIt = m_lItems.begin(); + pIt != m_lItems.end() ; + ++pIt ) + { + const TItemInfo& rInfo = *pIt; + if (rInfo.eItem == eItem) + return; + } + + TItemInfo aNewItem; + aNewItem.eItem = eItem; + impl_newItem(aNewItem); + if (aNewItem.pItem) + m_lItems.push_back(aNewItem); +} + +//----------------------------------------------- +void ItemHolder2::impl_releaseAllItems() +{ + ::osl::ResettableMutexGuard aLock(m_aLock); + + TItems::iterator pIt; + for ( pIt = m_lItems.begin(); + pIt != m_lItems.end() ; + ++pIt ) + { + TItemInfo& rInfo = *pIt; + impl_deleteItem(rInfo); + } + m_lItems.clear(); +} + +//----------------------------------------------- +void ItemHolder2::impl_newItem(TItemInfo& rItem) +{ + switch(rItem.eItem) + { + case E_CJKOPTIONS : + rItem.pItem = new SvtCJKOptions(); + break; + + case E_CTLOPTIONS : + rItem.pItem = new SvtCTLOptions(); + break; + + case E_LANGUAGEOPTIONS : +// capsulate CTL and CJL options ! rItem.pItem = new SvtLanguageOptions(); + break; + + default: + OSL_ASSERT(false); + break; + } +} + +//----------------------------------------------- +void ItemHolder2::impl_deleteItem(TItemInfo& rItem) +{ + if (rItem.pItem) + { + delete rItem.pItem; + rItem.pItem = 0; + } +} diff --git a/svl/source/config/itemholder2.hxx b/svl/source/config/itemholder2.hxx new file mode 100644 index 000000000000..192df8f746c9 --- /dev/null +++ b/svl/source/config/itemholder2.hxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * 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: itemholder2.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_ +#define INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_ + +//----------------------------------------------- +// includes + +#include <unotools/itemholderbase.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XEventListener.hpp> + +//----------------------------------------------- +// namespaces + +#ifdef css +#error "Cant use css as namespace alias." +#else +#define css ::com::sun::star +#endif + +//----------------------------------------------- +// definitions + +class ItemHolder2 : private ItemHolderMutexBase + , public ::cppu::WeakImplHelper1< css::lang::XEventListener > +{ + //........................................... + // member + private: + + TItems m_lItems; + + //........................................... + // c++ interface + public: + + ItemHolder2(); + virtual ~ItemHolder2(); + static void holdConfigItem(EItem eItem); + + //........................................... + // uno interface + public: + + virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) + throw(css::uno::RuntimeException); + + //........................................... + // helper + private: + + void impl_addItem(EItem eItem); + void impl_releaseAllItems(); + void impl_newItem(TItemInfo& rItem); + void impl_deleteItem(TItemInfo& rItem); +}; + +//----------------------------------------------- +// namespaces + +#undef css + +#endif // INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_ diff --git a/svl/source/config/languageoptions.cxx b/svl/source/config/languageoptions.cxx new file mode 100644 index 000000000000..f16c0b6add49 --- /dev/null +++ b/svl/source/config/languageoptions.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * 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: languageoptions.cxx,v $ + * $Revision: 1.21 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/languageoptions.hxx> +#include <svl/cjkoptions.hxx> +#include <svl/ctloptions.hxx> +#include <i18npool/mslangid.hxx> +#include <vos/mutex.hxx> +#include <osl/mutex.hxx> +#include <rtl/instance.hxx> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <unotools/syslocale.hxx> + +using namespace ::com::sun::star; +// global ---------------------------------------------------------------------- + +namespace { struct ALMutex : public rtl::Static< ::osl::Mutex, ALMutex > {}; } + +// class SvtLanguageOptions ---------------------------------------------------- + +SvtLanguageOptions::SvtLanguageOptions( sal_Bool _bDontLoad ) +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( ALMutex::get() ); + + m_pCJKOptions = new SvtCJKOptions( _bDontLoad ); + m_pCTLOptions = new SvtCTLOptions( _bDontLoad ); + m_pCTLOptions->AddListener(this); + m_pCJKOptions->AddListener(this); +} +//------------------------------------------------------------------------------ +SvtLanguageOptions::~SvtLanguageOptions() +{ + // Global access, must be guarded (multithreading) + ::osl::MutexGuard aGuard( ALMutex::get() ); + + m_pCTLOptions->RemoveListener(this); + m_pCJKOptions->RemoveListener(this); + + delete m_pCJKOptions; + delete m_pCTLOptions; +} +//------------------------------------------------------------------------------ +// CJK options ----------------------------------------------------------------- +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsCJKFontEnabled() const +{ + return m_pCJKOptions->IsCJKFontEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsVerticalTextEnabled() const +{ + return m_pCJKOptions->IsVerticalTextEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsAsianTypographyEnabled() const +{ + return m_pCJKOptions->IsAsianTypographyEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsJapaneseFindEnabled() const +{ + return m_pCJKOptions->IsJapaneseFindEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsRubyEnabled() const +{ + return m_pCJKOptions->IsRubyEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsChangeCaseMapEnabled() const +{ + return m_pCJKOptions->IsChangeCaseMapEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsDoubleLinesEnabled() const +{ + return m_pCJKOptions->IsDoubleLinesEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsEmphasisMarksEnabled() const +{ + return m_pCJKOptions->IsEmphasisMarksEnabled(); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsVerticalCallOutEnabled() const +{ + return m_pCJKOptions->IsVerticalCallOutEnabled(); +} +//------------------------------------------------------------------------------ +void SvtLanguageOptions::SetAll( sal_Bool _bSet ) +{ + m_pCJKOptions->SetAll( _bSet ); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsAnyEnabled() const +{ + return m_pCJKOptions->IsAnyEnabled(); +} +//------------------------------------------------------------------------------ +// CTL options ----------------------------------------------------------------- +//------------------------------------------------------------------------------ +void SvtLanguageOptions::SetCTLFontEnabled( sal_Bool _bEnabled ) +{ + m_pCTLOptions->SetCTLFontEnabled( _bEnabled ); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsCTLFontEnabled() const +{ + return m_pCTLOptions->IsCTLFontEnabled(); +} +//------------------------------------------------------------------------------ +void SvtLanguageOptions::SetCTLSequenceChecking( sal_Bool _bEnabled ) +{ + m_pCTLOptions->SetCTLSequenceChecking( _bEnabled ); +} +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsCTLSequenceChecking() const +{ + return m_pCTLOptions->IsCTLSequenceChecking(); +} +/*-- 26.09.2005 15:48:23--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtLanguageOptions::SetCTLSequenceCheckingRestricted( sal_Bool _bEnable ) +{ + m_pCTLOptions->SetCTLSequenceCheckingRestricted( _bEnable ); +} +/*-- 26.09.2005 15:48:23--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtLanguageOptions::IsCTLSequenceCheckingRestricted( void ) const +{ + return m_pCTLOptions->IsCTLSequenceCheckingRestricted(); +} +/*-- 26.09.2005 15:48:23--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtLanguageOptions::SetCTLSequenceCheckingTypeAndReplace( sal_Bool _bEnable ) +{ + m_pCTLOptions->SetCTLSequenceCheckingTypeAndReplace( _bEnable ); +} +/*-- 26.09.2005 15:48:24--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SvtLanguageOptions::IsCTLSequenceCheckingTypeAndReplace() const +{ + return m_pCTLOptions->IsCTLSequenceCheckingTypeAndReplace(); +} + +//------------------------------------------------------------------------------ +sal_Bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const +{ + sal_Bool bReadOnly = sal_False; + switch(eOption) + { + // cjk options + case SvtLanguageOptions::E_CJKFONT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT ); break; + case SvtLanguageOptions::E_VERTICALTEXT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT ); break; + case SvtLanguageOptions::E_ASIANTYPOGRAPHY : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break; + case SvtLanguageOptions::E_JAPANESEFIND : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND ); break; + case SvtLanguageOptions::E_RUBY : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY ); break; + case SvtLanguageOptions::E_CHANGECASEMAP : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP ); break; + case SvtLanguageOptions::E_DOUBLELINES : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES ); break; + case SvtLanguageOptions::E_EMPHASISMARKS : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS ); break; + case SvtLanguageOptions::E_VERTICALCALLOUT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break; + case SvtLanguageOptions::E_ALLCJK : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL ); break; + // ctl options + case SvtLanguageOptions::E_CTLFONT : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT ); break; + case SvtLanguageOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break; + case SvtLanguageOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT ); break; + case SvtLanguageOptions::E_CTLTEXTNUMERALS : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS ); break; + } + return bReadOnly; +} +/* -----------------30.04.2003 11:03-----------------*/ + +// returns for a language the scripttype +sal_uInt16 SvtLanguageOptions::GetScriptTypeOfLanguage( sal_uInt16 nLang ) +{ + if( LANGUAGE_DONTKNOW == nLang ) + nLang = LANGUAGE_ENGLISH_US; + else if( LANGUAGE_SYSTEM == nLang ) + nLang = SvtSysLocale().GetLanguage(); + + sal_Int16 nScriptType = MsLangId::getScriptType( nLang ); + USHORT nScript; + switch (nScriptType) + { + case ::com::sun::star::i18n::ScriptType::ASIAN: + nScript = SCRIPTTYPE_ASIAN; + break; + case ::com::sun::star::i18n::ScriptType::COMPLEX: + nScript = SCRIPTTYPE_COMPLEX; + break; + default: + nScript = SCRIPTTYPE_LATIN; + } + return nScript; +} +// ----------------------------------------------------------------------------- + + +/*-- 27.10.2005 08:18:01--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtSystemLanguageOptions::SvtSystemLanguageOptions() : + utl::ConfigItem( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("System/L10N") )) +{ + uno::Sequence< rtl::OUString > aPropertyNames(1); + rtl::OUString* pNames = aPropertyNames.getArray(); + pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SystemLocale")); + uno::Sequence< uno::Any > aValues = GetProperties( aPropertyNames ); + + if ( aValues.getLength() ) + { + aValues[0]>>= m_sWin16SystemLocale; + } +} +/*-- 27.10.2005 08:18:01--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtSystemLanguageOptions::~SvtSystemLanguageOptions() +{ +} +/*-- 27.10.2005 08:18:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtSystemLanguageOptions::Commit() +{ + //does nothing +} + +void SvtSystemLanguageOptions::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& ) +{ + // no listeners supported yet +} + +/*-- 27.10.2005 08:36:14--------------------------------------------------- + + -----------------------------------------------------------------------*/ +LanguageType SvtSystemLanguageOptions::GetWin16SystemLanguage() +{ + if( m_sWin16SystemLocale.getLength() == 0 ) + return LANGUAGE_NONE; + return MsLangId::convertIsoStringToLanguage( m_sWin16SystemLocale ); +} + + diff --git a/svl/source/config/makefile.mk b/svl/source/config/makefile.mk new file mode 100644 index 000000000000..82c4ae12828f --- /dev/null +++ b/svl/source/config/makefile.mk @@ -0,0 +1,54 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.61 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=svl +TARGET=config + +ENABLE_EXCEPTIONS := TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/cjkoptions.obj \ + $(SLO)$/ctloptions.obj \ + $(SLO)$/itemholder2.obj \ + $(SLO)$/languageoptions.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/svl/source/filepicker/makefile.mk b/svl/source/filepicker/makefile.mk new file mode 100644 index 000000000000..644c70af0b1a --- /dev/null +++ b/svl/source/filepicker/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.12 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=svl +TARGET=filepicker +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------------- + +SLOFILES =\ + $(SLO)$/pickerhelper.obj \ + $(SLO)$/pickerhistory.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/filepicker/pickerhelper.cxx b/svl/source/filepicker/pickerhelper.cxx new file mode 100644 index 000000000000..cda263338d5d --- /dev/null +++ b/svl/source/filepicker/pickerhelper.cxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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: pickerhelper.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "pickerhelper.hxx" +#include "rtl/ustring.hxx" +#include "com/sun/star/ui/dialogs/XFilePicker.hpp" +#include "com/sun/star/ui/dialogs/XFolderPicker.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/beans/XPropertySetInfo.hpp" +#include "com/sun/star/uno/Any.hxx" +#include "tools/debug.hxx" + +namespace css = com::sun::star; + +using css::uno::Reference; +using rtl::OUString; + +namespace svt +{ + void SetDialogHelpId( + Reference < css::ui::dialogs::XFilePicker > _mxFileDlg, sal_Int32 _nHelpId ) + { + try + { + // does the dialog haver a help URL property? + Reference< css::beans::XPropertySet > xDialogProps( _mxFileDlg, css::uno::UNO_QUERY ); + Reference< css::beans::XPropertySetInfo > xInfo; + if( xDialogProps.is() ) + xInfo = xDialogProps->getPropertySetInfo( ); + + const OUString sHelpURLPropertyName( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" ) ); + + if( xInfo.is() && xInfo->hasPropertyByName( sHelpURLPropertyName ) ) + { // yep + OUString sId( RTL_CONSTASCII_USTRINGPARAM( "HID:" ) ); + sId += OUString::valueOf( _nHelpId ); + xDialogProps->setPropertyValue( sHelpURLPropertyName, css::uno::makeAny( sId ) ); + } + } + catch( const css::uno::Exception& ) + { + DBG_ERROR( "svt::SetDialogHelpId(): caught an exception while setting the help id!" ); + } + } + + void SetDialogHelpId( + Reference< css::ui::dialogs::XFolderPicker > _mxFileDlg, sal_Int32 _nHelpId ) + { + try + { + // does the dialog haver a help URL property? + Reference< css::beans::XPropertySet > xDialogProps( _mxFileDlg, css::uno::UNO_QUERY ); + Reference< css::beans::XPropertySetInfo > xInfo; + if( xDialogProps.is() ) + xInfo = xDialogProps->getPropertySetInfo( ); + + const OUString sHelpURLPropertyName( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" ) ); + + if( xInfo.is() && xInfo->hasPropertyByName( sHelpURLPropertyName ) ) + { // yep + OUString sId( RTL_CONSTASCII_USTRINGPARAM( "HID:" ) ); + sId += OUString::valueOf( _nHelpId ); + xDialogProps->setPropertyValue( sHelpURLPropertyName, css::uno::makeAny( sId ) ); + } + } + catch( const css::uno::Exception& ) + { + DBG_ERROR( "svt::SetDialogHelpId(): caught an exception while setting the help id!" ); + } + } +} + diff --git a/svl/source/filepicker/pickerhistory.cxx b/svl/source/filepicker/pickerhistory.cxx new file mode 100644 index 000000000000..5cc12779f0b5 --- /dev/null +++ b/svl/source/filepicker/pickerhistory.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * 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: pickerhistory.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "pickerhistory.hxx" +#include "pickerhistoryaccess.hxx" +#include <cppuhelper/weakref.hxx> +#include <vector> + +//......................................................................... +namespace svt +{ +//......................................................................... + using namespace ::com::sun::star::uno; + + namespace + { + typedef ::com::sun::star::uno::WeakReference< XInterface > InterfaceAdapter; + typedef ::std::vector< InterfaceAdapter > InterfaceArray; + + // ---------------------------------------------------------------- + InterfaceArray& getFolderPickerHistory() + { + static InterfaceArray s_aHistory; + return s_aHistory; + } + + // ---------------------------------------------------------------- + InterfaceArray& getFilePickerHistory() + { + static InterfaceArray s_aHistory; + return s_aHistory; + } + + // ---------------------------------------------------------------- + void implPushBackPicker( InterfaceArray& _rHistory, const Reference< XInterface >& _rxPicker ) + { + if ( !_rxPicker.is() ) + return; + + //============================================================= + // first, check which of the objects we hold in s_aHistory can be removed + { + InterfaceArray aCleanedHistory; + for ( InterfaceArray::const_iterator aLoop = _rHistory.begin(); + aLoop != _rHistory.end(); + ++aLoop + ) + { + Reference< XInterface > xCurrent( aLoop->get() ); + if ( xCurrent.is() ) + { + if ( aCleanedHistory.empty() ) + // make some room, assume that all interfaces (from here on) are valie + aCleanedHistory.reserve( _rHistory.size() - ( aLoop - _rHistory.begin() ) ); + aCleanedHistory.push_back( InterfaceAdapter( xCurrent ) ); + } + } + _rHistory.swap( aCleanedHistory ); + } + + //============================================================= + // then push_back the picker + _rHistory.push_back( InterfaceAdapter( _rxPicker ) ); + } + + //----------------------------------------------------------------- + Reference< XInterface > implGetTopMostPicker( const InterfaceArray& _rHistory ) + { + Reference< XInterface > xTopMostAlive; + + //============================================================= + // search the first picker which is still alive ... + for ( InterfaceArray::const_reverse_iterator aLoop = _rHistory.rbegin(); + ( aLoop != _rHistory.rend() ) && !xTopMostAlive.is(); + ++aLoop + ) + { + xTopMostAlive = aLoop->get(); + } + + return xTopMostAlive; + } + } + + //--------------------------------------------------------------------- + Reference< XInterface > GetTopMostFolderPicker( ) + { + return implGetTopMostPicker( getFolderPickerHistory() ); + } + + //--------------------------------------------------------------------- + Reference< XInterface > GetTopMostFilePicker( ) + { + return implGetTopMostPicker( getFilePickerHistory() ); + } + + //--------------------------------------------------------------------- + void addFolderPicker( const Reference< XInterface >& _rxPicker ) + { + implPushBackPicker( getFolderPickerHistory(), _rxPicker ); + } + + //--------------------------------------------------------------------- + void addFilePicker( const Reference< XInterface >& _rxPicker ) + { + implPushBackPicker( getFilePickerHistory(), _rxPicker ); + } + +//......................................................................... +} // namespace svt +//......................................................................... + diff --git a/svl/source/filerec/filerec.cxx b/svl/source/filerec/filerec.cxx new file mode 100644 index 000000000000..ac35a748eef7 --- /dev/null +++ b/svl/source/filerec/filerec.cxx @@ -0,0 +1,1019 @@ +/************************************************************************* + * + * 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: filerec.cxx,v $ + * $Revision: 1.13 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/filerec.hxx> +#include <osl/endian.h> + +//======================================================================== + +SV_IMPL_VARARR( SfxUINT32s, UINT32 ); + +//======================================================================== + +/* Die folgenden Makros extrahieren Teilbereiche aus einem UINT32 Wert. + Diese UINT32-Werte werden anstelle der einzelnen Werte gestreamt, + um Calls zu sparen. +*/ + +#define SFX_REC_PRE(n) ( ((n) & 0x000000FF) ) +#define SFX_REC_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 ) +#define SFX_REC_TYP(n) ( ((n) & 0x000000FF) ) +#define SFX_REC_VER(n) ( ((n) & 0x0000FF00) >> 8 ) +#define SFX_REC_TAG(n) ( ((n) & 0xFFFF0000) >> 16 ) + +#define SFX_REC_CONTENT_VER(n) ( ((n) & 0x000000FF) ) +#define SFX_REC_CONTENT_OFS(n) ( ((n) & 0xFFFFFF00) >> 8 ) + +//------------------------------------------------------------------------- + +/* Die folgenden Makros setzen Teilbereiche zu einem UINT32 Wert zusammen. + Diese UINT32-Werte werden anstelle der einzelnen Werte gestreamt, + um Calls zu sparen. +*/ + +#define SFX_REC_MINI_HEADER(nPreTag,nStartPos,nEndPos) \ + ( UINT32(nPreTag) | \ + UINT32(nEndPos-nStartPos-SFX_REC_HEADERSIZE_MINI) << 8 ) + +#define SFX_REC_HEADER(nRecType,nContentTag,nContentVer) \ + ( UINT32(nRecType) | \ + ( UINT32(nContentVer) << 8 ) | \ + ( UINT32(nContentTag) << 16 ) ) + +#define SFX_REC_CONTENT_HEADER(nContentVer,n1StStartPos,nCurStartPos) \ + ( UINT32(nContentVer) | \ + UINT32( nCurStartPos - n1StStartPos ) << 8 ) + +//========================================================================= + +UINT32 SfxMiniRecordWriter::Close +( + FASTBOOL bSeekToEndOfRec /* TRUE (default) + Der Stream wird an das Ende des Records + positioniert. + + FALSE + Der Stream wird an den Anfang des + Contents (also hinter den Header) + positioniert. + */ +) + +/* [Beschreibung] + + Diese Methode schlie\st den Record. Dabei wird haupts"achlich der + Header geschrieben. + + Wurde der Header bereits geschrieben, hat der Aufruf keine Wirkung. + + + [R"uckgabewert] + + UINT32 != 0 + Position im Stream, die direkt hinter dem Record liegt. + 'bSeekToEndOfRecord==TRUE' + => R"uckgabewert == aktuelle Stream-Position nach Aufruf + + == 0 + Der Header war bereits geschrieben worden. +*/ + +{ + // wurde der Header noch nicht geschrieben? + if ( !_bHeaderOk ) + { + // Header an den Anfang des Records schreiben + UINT32 nEndPos = _pStream->Tell(); + _pStream->Seek( _nStartPos ); + *_pStream << SFX_REC_MINI_HEADER( _nPreTag, _nStartPos, nEndPos ); + + // je nachdem ans Ende des Records seeken oder hinter Header bleiben + if ( bSeekToEndOfRec ) + _pStream->Seek( nEndPos ); + + // Header wurde JETZT geschrieben + _bHeaderOk = TRUE; + return nEndPos; + } +#ifdef DBG_UTIL + // mu\s Fix-Size-Record gepr"uft werden? + else if ( SFX_BOOL_DONTCARE == _bHeaderOk ) + { + // Header auslesen, um Soll-Gr"o\se zu bestimmen + UINT32 nEndPos = _pStream->Tell(); + _pStream->Seek( _nStartPos ); + UINT32 nHeader; + *_pStream >> nHeader; + _pStream->Seek( nEndPos ); + + // Soll-Gr"o\se mit Ist-Gr"o\se vergleichen + DBG_ASSERT( nEndPos - SFX_REC_OFS(nHeader) == _nStartPos + sizeof(UINT32), + "fixed record size incorrect" ); + DbgOutf( "SfxFileRec: written record until %ul", nEndPos ); + } +#endif + + // Record war bereits geschlossen + return 0; +} + +//========================================================================= + +USHORT SfxMiniRecordReader::ScanRecordType +( + SvStream* pStream /* <SvStream> an dessen aktueller Position + ein Record liegt, dessen Typ erkannt werden + soll. + */ +) + +/* [Beschreibung] + + Mit dieser statischen Methode kann ermittelt werden, ob sich an der + aktuellen Position in einem Stream ein Record befindet, und der Typ + des Records kann ermittelt werden. + + Die Position im Stream ist nach dem Aufruf aufver"andert. + + + [Anmerkung] + + Die Record-Typen k"onnen zwar (abgesehen vom Drawing-Enginge-Record) + untereinander eindeutig erkannt werden, es besteht jedoch die Gefahr + der Verwechslung von Records mit normalen Daten. File-Formate sollten + darauf R"ucksicht nehmen. Handelt es sich um keinen Record, wird + am wahrscheinlichsten SFX_REC_TYPE_MINI zur"uckgeliefert, da dieser + Typ sich aufgrund seines sparsam kurzen Headers durch die k"urzeste + Kennung auszeichnet. + + + [R"uckgabewert] + + USHORT SFX_REC_TYPE_EOR + An der aktuellen Position des Streams + steht eine End-Of-Records-Kennung. + + SFX_REC_TYPE_MINI + Es handelt sich um einen SW3 kompatiblen + Mini-Record, dessen einzige Kennung sein + 'Mini-Tag' ist. + + SFX_REC_TYPE_SINGLE + Es handelt sich um einen Extended-Record + mit einem einzigen Content, der durch eine + Version und ein Tag n"aher gekennzeichnet + ist. + + SFX_REC_TYPE_FIXSIZE + Es handelt sich um einen Extended-Record + mit mehreren Contents gleicher Gr"o\se, + die gemeinsam durch eine einzige Version + und ein einziges gemeinsames Tag n"aher + gekennzeichnet sind. + + SFX_REC_TYPE_VARSIZE + Es handelt sich um einen Extended-Record + mit mehreren Contents variabler Gr"o\se, + die gemeinsam durch eine einzige Version + und ein einziges gemeinsames Tag n"aher + gekennzeichnet sind. + + SFX_REC_TYPE_MIXTAGS + Es handelt sich um einen Extended-Record + mit mehreren Contents variabler Gr"o\se, + die jeweils durch ein eignes Tag und + eine eigene Versions-Nummer n"aher + gekennzeichnet sind. + + SFX_REC_TYPE_DRAWENG + Es handelt sich wahrscheinlich um einen + Drawing-Engine-Record. Dieser Record-Typ + kann von den Klassen dieser Gruppe nicht + interpretiert werden. +*/ + +{ + // die ersten 4 Bytes als Mini-Header lesen + sal_uInt32 nHeader; + *pStream >> nHeader; + + // k"onnte es sich um einen extended-Record handeln? + USHORT nPreTag = sal::static_int_cast< USHORT >(SFX_REC_PRE(nHeader)); + if ( SFX_REC_PRETAG_EXT == nPreTag ) + { + // die n"achsten 4 Bytes als extended-Header lesen + *pStream >> nHeader; + + // Stream-Position restaurieren + pStream->SeekRel(-8); + + // liegt eine g"ultige Record-Kennung vor? + USHORT nType = sal::static_int_cast< USHORT >(SFX_REC_TYP(nHeader)); + if ( nType >= SFX_REC_TYPE_FIRST && nType <= SFX_REC_TYPE_LAST ) + // entsprechenden extended-Record-Typ zur"uckliefern + return nType; + + // sonst ist der Record-Typ unbekannt + return SFX_REC_TYPE_NONE; + } + + // Stream-Position restaurieren + pStream->SeekRel(-4); + + // liegt eine End-Of-Record-Kennung vor? + if ( SFX_REC_PRETAG_EOR == nPreTag ) + return nPreTag; + + // liegt ein Drawin-Engine-Record vor? + if ( nHeader == UINT32(*"DRMD") || nHeader == UINT32(*"DRVW") ) + return SFX_REC_TYPE_DRAWENG; + + // alle anderen sind grunds"atzlich g"ultige Mini-Records + return SFX_REC_TYPE_MINI; +} + +//------------------------------------------------------------------------- + +FASTBOOL SfxMiniRecordReader::SetHeader_Impl( UINT32 nHeader ) + +/* [Beschreibung] + + Interne Methode zum nachtr"aglichen Verarbeiten eines extern gelesenen + Headers. Falls der Header eine End-Of-Records-Kennung darstellt, + wird am Stream ein Errorcode gesetzt und FALSE zur"uckgeliefert. Im + Fehlerfall wird der Stream jedoch nicht auf den Record-Anfang zur"uck- + gesetzt. +*/ + +{ + FASTBOOL bRet = TRUE; + + // Record-Ende und Pre-Tag aus dem Header ermitteln + _nEofRec = _pStream->Tell() + SFX_REC_OFS(nHeader); + _nPreTag = sal::static_int_cast< BYTE >(SFX_REC_PRE(nHeader)); + + // wenn End-Of-Record-Kennung, dann Fehler + if ( _nPreTag == SFX_REC_PRETAG_EOR ) + { + _pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + bRet = FALSE; + } + return bRet; +} + +//------------------------------------------------------------------------- + +SfxMiniRecordReader::SfxMiniRecordReader +( + SvStream* pStream /* <SvStream>, an dessen aktueller + Position sich ein <SfxMiniRecord> + befindet. + */ +) + +/* [Beschreibung] + + Dieser Ctor liest den Header eines <SfxMiniRecord> ab der aktuellen + Position von 'pStream'. Da grunds"atzlich fast 4-Byte Kombination ein + g"ultiger SfxMiniRecord-Header ist, bleiben die einzig m"oglichen + Fehler der EOF-Status des Streams, und ein SFX_REC_PRETAG_EOR + als Pre-Tag. Ein entsprechender Error-Code (ERRCODE_IO_EOF bzw. + ERRCODE_IO_WRONGFORMAT) ist dann am Stream gesetzt, dessen Position + dann au\serdem unver"andert ist. +*/ + +: _pStream( pStream ), + _bSkipped( FALSE ) +{ + // Header einlesen + UINT32 nStartPos = pStream->Tell(); // um im Fehlerfall zur"uck zu-seeken + DBG( DbgOutf( "SfxFileRec: reading record at %ul", nStartPos ) ); + UINT32 nHeader; + *pStream >> nHeader; + + // Headerdaten extrahieren + SetHeader_Impl( nHeader ); + + // Fehlerbehandlung + if ( pStream->IsEof() ) + _nPreTag = SFX_REC_PRETAG_EOR; + else if ( _nPreTag == SFX_REC_PRETAG_EOR ) + pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + if ( !IsValid() ) + pStream->Seek( nStartPos ); +} + +//------------------------------------------------------------------------- + +SfxMiniRecordReader::SfxMiniRecordReader +( + SvStream* pStream, /* <SvStream>, an dessen aktueller + Position sich ein <SfxMiniRecord> + befindet. + */ + BYTE nTag // Pre-Tag des gew"unschten Records +) + +/* [Beschreibung] + + Dieser Ctor interpretiert 'pStream' ab der aktuellen Position als + eine l"uckenlose Folge von, von dieser Klassen-Gruppe interpretierbaren, + Records. Der in dieser Folge erste als <SfxMiniRecord> interpretierbare + (also ggf. auch ein extended-Record) mit dem PreTag 'nTag' wird ge"offnet + und durch diese Instanz repr"asentiert. + + Wird das Ende des Streams oder die Kennung SFX_REC_PRETAG_EOR + erreicht, bevor ein Record mit dem ge"unschten Pre-Tag gefunden wird, + ist die erzeugte Instanz ung"ultig ('IsValid() == FALSE'). Ein ent- + sprechender Error-Code (ERRCODE_IO_EOF bzw. ERRCODE_IO_WRONGFORMAT) + ist dann am Stream gesetzt, dessen Position ist dann au\serdem unver- + "andert. + + Bei 'nTag==SFX_FILEREC_PRETAG_EOR' wird nicht versucht, einen Record + zu lesen, es wird sofort 'IsValid()' auf FALSE gesetzt und kein Error-Code + am Stream gesetzt. Dies ist dauzu gedacht, ohne 'new' und 'delete' + abw"rtskompatibel SfxMiniRecords einbauen zu k"onnen. Siehe dazu + <SfxItemSet::Load()>. + + + [Anwendungsvorschlag] + + Wird dieser Ctor in einer bereits ausgelieferten Programmversion + verwendet, k"onnen in das File-Format jeweils davor kompatibel neue + Records mit einer anderen Kennung eingef"ugt werden. Diese werden + schlie\slich automatisch "uberlesen. Erkauft wird diese M"oglichkeit + allerdings mit etwas schlechterem Laufzeitverhalten im Vergleich mit + direktem 'drauf-los-lesen', der sich jedoch auf einen Vergleich zweier + Bytes reduziert, falls der gesuchte Record der erste in der Folge ist. +*/ + +: _pStream( pStream ), + _bSkipped( nTag == SFX_REC_PRETAG_EOR ) +{ + // ggf. ignorieren (s.o.) + if ( _bSkipped ) + { + _nPreTag = nTag; + return; + } + + // StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen + UINT32 nStartPos = pStream->Tell(); + + // passenden Record suchen + while(TRUE) + { + // Header lesen + DBG( DbgOutf( "SfxFileRec: searching record at %ul", pStream->Tell() ) ); + UINT32 nHeader; + *pStream >> nHeader; + + // Headerdaten von Basisklasse extrahieren lassen + SetHeader_Impl( nHeader ); + + // ggf. Fehler behandeln + if ( pStream->IsEof() ) + _nPreTag = SFX_REC_PRETAG_EOR; + else if ( _nPreTag == SFX_REC_PRETAG_EOR ) + pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + else + { + // wenn gefunden, dann Schleife abbrechen + if ( _nPreTag == nTag ) + break; + + // sonst skippen und weitersuchen + pStream->Seek( _nEofRec ); + continue; + } + + // Fehler => zur"uck-seeken + pStream->Seek( nStartPos ); + break; + } +} + +//========================================================================= + +SfxSingleRecordWriter::SfxSingleRecordWriter +( + BYTE nRecordType, // f"ur Subklassen + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nContentTag, // Inhalts-Art-Kennung + BYTE nContentVer // Inhalts-Versions-Kennung +) + +/* [Beschreibung] + + Interner Ctor f"ur Subklassen. +*/ + +: SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT ) +{ + // Erweiterten Header hiner den des SfxMiniRec schreiben + *pStream << SFX_REC_HEADER(nRecordType, nContentTag, nContentVer); +} + +//------------------------------------------------------------------------- + +SfxSingleRecordWriter::SfxSingleRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nContentTag, // Inhalts-Art-Kennung + BYTE nContentVer // Inhalts-Versions-Kennung +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxSingleRecord' an, dessen Content-Gr"o\se + nicht bekannt ist, sondern nach dam Streamen des Contents errechnet + werden soll. +*/ + +: SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT ) +{ + // Erweiterten Header hiner den des SfxMiniRec schreiben + *pStream << SFX_REC_HEADER( SFX_REC_TYPE_SINGLE, nContentTag, nContentVer); +} + +//------------------------------------------------------------------------- + +SfxSingleRecordWriter::SfxSingleRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nContentTag, // Inhalts-Art-Kennung + BYTE nContentVer, // Inhalts-Versions-Kennung + UINT32 nContentSize // Gr"o\se des Inhalts in Bytes +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxSingleRecord' an, dessen Content-Gr"o\se + von vornherein bekannt ist. +*/ + +: SfxMiniRecordWriter( pStream, SFX_REC_PRETAG_EXT, + nContentSize + SFX_REC_HEADERSIZE_SINGLE ) +{ + // Erweiterten Header hinter den des SfxMiniRec schreiben + *pStream << SFX_REC_HEADER( SFX_REC_TYPE_SINGLE, nContentTag, nContentVer); +} + +//========================================================================= + +inline FASTBOOL SfxSingleRecordReader::ReadHeader_Impl( USHORT nTypes ) + +/* [Beschreibung] + + Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem + die Basisklasse bereits initialisiert und deren Header gelesen ist. + Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch + nicht zur"uckge-seekt. +*/ + +{ + FASTBOOL bRet; + + // Basisklassen-Header einlesen + UINT32 nHeader=0; + *_pStream >> nHeader; + if ( !SetHeader_Impl( nHeader ) ) + bRet = FALSE; + else + { + // eigenen Header einlesen + *_pStream >> nHeader; + _nRecordVer = sal::static_int_cast< BYTE >(SFX_REC_VER(nHeader)); + _nRecordTag = sal::static_int_cast< UINT16 >(SFX_REC_TAG(nHeader)); + + // falscher Record-Typ? + _nRecordType = sal::static_int_cast< BYTE >(SFX_REC_TYP(nHeader)); + bRet = 0 != ( nTypes & _nRecordType); + } + return bRet; +} + +//------------------------------------------------------------------------- + +SfxSingleRecordReader::SfxSingleRecordReader( SvStream *pStream ) +: SfxMiniRecordReader() +{ + // Startposition merken, um im Fehlerfall zur"uck-seeken zu k"onnen + #ifdef DBG_UTIL + UINT32 nStartPos = pStream->Tell(); + DBG( DbgOutf( "SfxFileRec: reading record at %ul", nStartPos ) ); + #endif + + // Basisklasse initialisieren (nicht via Ctor, da der nur MiniRecs akzept.) + Construct_Impl( pStream ); + + // nur Header mit korrektem Record-Type akzeptieren + if ( !ReadHeader_Impl( SFX_REC_TYPE_SINGLE ) ) + { + // Error-Code setzen und zur"uck-seeken + pStream->SeekRel( - SFX_REC_HEADERSIZE_SINGLE ); + pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + } +} + +//------------------------------------------------------------------------- + +SfxSingleRecordReader::SfxSingleRecordReader( SvStream *pStream, USHORT nTag ) +{ + // StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen + UINT32 nStartPos = pStream->Tell(); + + // richtigen Record suchen, ggf. Error-Code setzen und zur"uck-seeken + Construct_Impl( pStream ); + if ( !FindHeader_Impl( SFX_REC_TYPE_SINGLE, nTag ) ) + { + // Error-Code setzen und zur"uck-seeken + pStream->Seek( nStartPos ); + pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + } +} + +//------------------------------------------------------------------------- + +FASTBOOL SfxSingleRecordReader::FindHeader_Impl +( + UINT16 nTypes, // arithm. Veroderung erlaubter Record-Typen + UINT16 nTag // zu findende Record-Art-Kennung +) + +/* [Beschreibung] + + Interne Methode zum lesen des Headers des ersten Record, der einem + der Typen in 'nTypes' entspricht und mit der Art-Kennung 'nTag' + gekennzeichnet ist. + + Kann ein solcher Record nicht gefunden werden, wird am Stream ein + Errorcode gesetzt, zur"uck-geseekt und FALSE zur"uckgeliefert. +*/ + +{ + // StartPos merken, um im Fehlerfall zur"uck-seeken zu k"onnen + UINT32 nStartPos = _pStream->Tell(); + + // richtigen Record suchen + while ( !_pStream->IsEof() ) + { + // Header lesen + UINT32 nHeader; + DBG( DbgOutf( "SfxFileRec: searching record at %ul", _pStream->Tell() ) ); + *_pStream >> nHeader; + if ( !SetHeader_Impl( nHeader ) ) + // EOR => Such-Schleife abbreichen + break; + + // Extended Record gefunden? + if ( _nPreTag == SFX_REC_PRETAG_EXT ) + { + // Extended Header lesen + *_pStream >> nHeader; + _nRecordTag = sal::static_int_cast< UINT16 >(SFX_REC_TAG(nHeader)); + + // richtigen Record gefunden? + if ( _nRecordTag == nTag ) + { + // gefundener Record-Typ passend? + _nRecordType = sal::static_int_cast< BYTE >( + SFX_REC_TYP(nHeader)); + if ( nTypes & _nRecordType ) + // ==> gefunden + return TRUE; + + // error => Such-Schleife abbrechen + break; + } + } + + // sonst skippen + if ( !_pStream->IsEof() ) + _pStream->Seek( _nEofRec ); + } + + // Fehler setzen und zur"uck-seeken + _pStream->SetError( ERRCODE_IO_WRONGFORMAT ); + _pStream->Seek( nStartPos ); + return FALSE; +} + +//========================================================================= + +SfxMultiFixRecordWriter::SfxMultiFixRecordWriter +( + BYTE nRecordType, // Subklassen Record-Kennung + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nContentTag, // Content-Art-Kennung + BYTE nContentVer, // Content-Versions-Kennung + UINT32 // Gr"o\se jedes einzelnen Contents in Bytes +) + +/* [Beschreibung] + + Interne Methode f"ur Subklassen. +*/ + +: SfxSingleRecordWriter( nRecordType, pStream, nContentTag, nContentVer ), + _nContentCount( 0 ) +{ + // Platz f"ur eigenen Header + pStream->SeekRel( + SFX_REC_HEADERSIZE_MULTI ); +} + +//------------------------------------------------------------------------ + +SfxMultiFixRecordWriter::SfxMultiFixRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nContentTag, // Content-Art-Kennung + BYTE nContentVer, // Content-Versions-Kennung + UINT32 // Gr"o\se jedes einzelnen Contents in Bytes +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxMultiFixRecord' an, dessen Content-Gr"o\se + konstant und von vornherein bekannt ist. +*/ + +: SfxSingleRecordWriter( SFX_REC_TYPE_FIXSIZE, + pStream, nContentTag, nContentVer ), + _nContentCount( 0 ) +{ + // Platz f"ur eigenen Header + pStream->SeekRel( + SFX_REC_HEADERSIZE_MULTI ); +} + +//------------------------------------------------------------------------ + +UINT32 SfxMultiFixRecordWriter::Close( FASTBOOL bSeekToEndOfRec ) + +// siehe <SfxMiniRecordWriter> + +{ + // Header noch nicht geschrieben? + if ( !_bHeaderOk ) + { + // Position hinter Record merken, um sie restaurieren zu k"onnen + UINT32 nEndPos = SfxSingleRecordWriter::Close( FALSE ); + + // gegen"uber SfxSingleRecord erweiterten Header schreiben + *_pStream << _nContentCount; + *_pStream << _nContentSize; + + // je nachdem ans Ende des Records seeken oder hinter Header bleiben + if ( bSeekToEndOfRec ) + _pStream->Seek(nEndPos); + return nEndPos; + } + + // Record war bereits geschlossen + return 0; +} + +//========================================================================= + +SfxMultiVarRecordWriter::SfxMultiVarRecordWriter +( + BYTE nRecordType, // Record-Kennung der Subklasse + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nRecordTag, // Gesamt-Art-Kennung + BYTE nRecordVer // Gesamt-Versions-Kennung +) + +/* [Beschreibung] + + Interner Ctor f"ur Subklassen. +*/ + +: SfxMultiFixRecordWriter( nRecordType, pStream, nRecordTag, nRecordVer, 0 ), + _nContentVer( 0 ) +{ +} + +//------------------------------------------------------------------------- + +SfxMultiVarRecordWriter::SfxMultiVarRecordWriter +( + SvStream* pStream, // Stream, in dem der Record angelegt wird + UINT16 nRecordTag, // Gesamt-Art-Kennung + BYTE nRecordVer // Gesamt-Versions-Kennung +) + +/* [Beschreibung] + + Legt in 'pStream' einen 'SfxMultiVarRecord' an, dessen Content-Gr"o\sen + weder bekannt sind noch identisch sein m"ussen, sondern jeweils nach dem + Streamen jedes einzelnen Contents errechnet werden sollen. + + + [Anmerkung] + + Diese Methode ist nicht inline, da f"ur die Initialisierung eines + <SvULongs>-Members zu viel Code generiert werden w"urde. +*/ + +: SfxMultiFixRecordWriter( SFX_REC_TYPE_VARSIZE, + pStream, nRecordTag, nRecordVer, 0 ), + _nContentVer( 0 ) +{ +} + +//------------------------------------------------------------------------- + +SfxMultiVarRecordWriter::~SfxMultiVarRecordWriter() + +/* [Beschreibung] + + Der Dtor der Klasse <SfxMultiVarRecordWriter> schlie\st den Record + automatisch, falls <SfxMultiVarRecordWriter::Close()> nicht bereits + explizit gerufen wurde. +*/ + +{ + // wurde der Header noch nicht geschrieben oder mu\s er gepr"uft werden + if ( !_bHeaderOk ) + Close(); +} + +//------------------------------------------------------------------------- + +void SfxMultiVarRecordWriter::FlushContent_Impl() + +/* [Beschreibung] + + Interne Methode zum Abschlie\sen eines einzelnen Contents. +*/ + +{ + // Versions-Kennung und Positions-Offset des aktuellen Contents merken; + // das Positions-Offset ist relativ zur Startposition des ersten Contents + _aContentOfs.Insert( + SFX_REC_CONTENT_HEADER(_nContentVer,_nStartPos,_nContentStartPos), + _nContentCount-1 ); +} + +//------------------------------------------------------------------------- + +void SfxMultiVarRecordWriter::NewContent() + +// siehe <SfxMultiFixRecordWriter> + +{ + // schon ein Content geschrieben? + if ( _nContentCount ) + FlushContent_Impl(); + + // neuen Content beginnen + _nContentStartPos = _pStream->Tell(); + ++_nContentCount; +} + +//------------------------------------------------------------------------- + +UINT32 SfxMultiVarRecordWriter::Close( FASTBOOL bSeekToEndOfRec ) + +// siehe <SfxMiniRecordWriter> + +{ + // Header noch nicht geschrieben? + if ( !_bHeaderOk ) + { + // ggf. letzten Content abschlie\sen + if ( _nContentCount ) + FlushContent_Impl(); + + // Content-Offset-Tabelle schreiben + UINT32 nContentOfsPos = _pStream->Tell(); + //! darf man das so einr"ucken? + #if defined(OSL_LITENDIAN) + _pStream->Write( _aContentOfs.GetData(), + sizeof(UINT32)*_nContentCount ); + #else + for ( USHORT n = 0; n < _nContentCount; ++n ) + *_pStream << UINT32(_aContentOfs[n]); + #endif + + // SfxMultiFixRecordWriter::Close() "uberspringen! + UINT32 nEndPos = SfxSingleRecordWriter::Close( FALSE ); + + // eigenen Header schreiben + *_pStream << _nContentCount; + if ( SFX_REC_TYPE_VARSIZE_RELOC == _nPreTag || + SFX_REC_TYPE_MIXTAGS_RELOC == _nPreTag ) + *_pStream << static_cast<UINT32>(nContentOfsPos - ( _pStream->Tell() + sizeof(UINT32) )); + else + *_pStream << nContentOfsPos; + + // ans Ende des Records seeken bzw. am Ende des Headers bleiben + if ( bSeekToEndOfRec ) + _pStream->Seek(nEndPos); + return nEndPos; + } + + // Record war bereits vorher geschlossen + return 0; +} + +//========================================================================= + +void SfxMultiMixRecordWriter::NewContent +( + UINT16 nContentTag, // Kennung f"ur die Art des Contents + BYTE nContentVer // Kennung f"ur die Version des Contents +) + +/* [Beschreibung] + + Mit dieser Methode wird in den Record ein neuer Content eingef"ugt + und dessen Content-Tag sowie dessen Content-Version angegeben. Jeder, + auch der 1. Record mu\s durch Aufruf dieser Methode eingeleitet werden. +*/ + +{ + // ggf. vorherigen Record abschlie\sen + if ( _nContentCount ) + FlushContent_Impl(); + + // Tag vor den Content schreiben, Version und Startposition merken + _nContentStartPos = _pStream->Tell(); + ++_nContentCount; + *_pStream << nContentTag; + _nContentVer = nContentVer; +} + +//========================================================================= + +FASTBOOL SfxMultiRecordReader::ReadHeader_Impl() + +/* [Beschreibung] + + Interne Methode zum Einlesen eines SfxMultiRecord-Headers, nachdem + die Basisklasse bereits initialisiert und deren Header gelesen ist. + Ggf. ist ein Error-Code am Stream gesetzt, im Fehlerfall wird jedoch + nicht zur"uckge-seekt. +*/ + +{ + // eigenen Header lesen + *_pStream >> _nContentCount; + *_pStream >> _nContentSize; // Fix: jedes einzelnen, Var|Mix: Tabellen-Pos. + + // mu\s noch eine Tabelle mit Content-Offsets geladen werden? + if ( _nRecordType != SFX_REC_TYPE_FIXSIZE ) + { + // Tabelle aus dem Stream einlesen + UINT32 nContentPos = _pStream->Tell(); + if ( _nRecordType == SFX_REC_TYPE_VARSIZE_RELOC || + _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC ) + _pStream->SeekRel( + _nContentSize ); + else + _pStream->Seek( _nContentSize ); + _pContentOfs = new UINT32[_nContentCount]; + //! darf man jetzt so einr"ucken + #if defined(OSL_LITENDIAN) + _pStream->Read( _pContentOfs, sizeof(UINT32)*_nContentCount ); + #else + for ( USHORT n = 0; n < _nContentCount; ++n ) + *_pStream >> _pContentOfs[n]; + #endif + _pStream->Seek( nContentPos ); + } + + // Header konnte gelesen werden, wenn am Stream kein Error gesetzt ist + return !_pStream->GetError(); +} + +//------------------------------------------------------------------------- + +SfxMultiRecordReader::SfxMultiRecordReader( SvStream *pStream ) +: _pContentOfs( NULL ), _nContentNo(0) +{ + // Position im Stream merken, um im Fehlerfall zur"uck-seeken zu k"onnen + _nStartPos = pStream->Tell(); + + // Basisklasse konstruieren (normaler Ctor w"urde nur SingleRecs lesen) + SfxSingleRecordReader::Construct_Impl( pStream ); + + // Header der Basisklasse lesen + if ( !SfxSingleRecordReader::ReadHeader_Impl( SFX_REC_TYPE_FIXSIZE | + SFX_REC_TYPE_VARSIZE | SFX_REC_TYPE_VARSIZE_RELOC | + SFX_REC_TYPE_MIXTAGS | SFX_REC_TYPE_MIXTAGS_RELOC ) || + !ReadHeader_Impl() ) + // als ung"ultig markieren und zur"uck-seeken + SetInvalid_Impl( _nStartPos ); +} + +//------------------------------------------------------------------------- + +SfxMultiRecordReader::SfxMultiRecordReader( SvStream *pStream, UINT16 nTag ) +: _nContentNo(0) +{ + // Position im Stream merken, um im Fehlerfall zur"uck-seeken zu k"onnen + _nStartPos = pStream->Tell(); + + // passenden Record suchen und Basisklasse initialisieren + SfxSingleRecordReader::Construct_Impl( pStream ); + if ( SfxSingleRecordReader::FindHeader_Impl( SFX_REC_TYPE_FIXSIZE | + SFX_REC_TYPE_VARSIZE | SFX_REC_TYPE_VARSIZE_RELOC | + SFX_REC_TYPE_MIXTAGS | SFX_REC_TYPE_MIXTAGS_RELOC, + nTag ) ) + { + // eigenen Header dazu-lesen + if ( !ReadHeader_Impl() ) + // nicht lesbar => als ung"ultig markieren und zur"uck-seeken + SetInvalid_Impl( _nStartPos); + } +} + +//------------------------------------------------------------------------- + +SfxMultiRecordReader::~SfxMultiRecordReader() +{ + delete[] _pContentOfs; +} + +//------------------------------------------------------------------------- + +FASTBOOL SfxMultiRecordReader::GetContent() + +/* [Beschreibung] + + Positioniert den Stream an den Anfang des n"chsten bzw. beim 1. Aufruf + auf den Anfang des ersten Contents im Record und liest ggf. dessen + Header ein. + + Liegt laut Record-Header kein Content mehr vor, wird FALSE zur"uck- + gegeben. Trotz einem TRUE-Returnwert kann am Stream ein Fehlercode + gesetzt sein, z.B. falls er unvorhergesehenerweise (kaputtes File) + zuende ist. +*/ + +{ + // noch ein Content vorhanden? + if ( _nContentNo < _nContentCount ) + { + // den Stream an den Anfang des Contents positionieren + UINT32 nOffset = _nRecordType == SFX_REC_TYPE_FIXSIZE + ? _nContentNo * _nContentSize + : SFX_REC_CONTENT_OFS(_pContentOfs[_nContentNo]); + UINT32 nNewPos = _nStartPos + nOffset; + DBG_ASSERT( nNewPos >= _pStream->Tell(), "SfxMultiRecordReader::GetContent() - New position before current, to much data red!" ); + + // #99366#: correct stream pos in every case; + // the if clause was added by MT a long time ago, + // maybe to 'repair' other corrupt documents; but this + // gives errors when writing with 5.1 and reading with current + // versions, so we decided to remove the if clause (KA-05/17/2002) + // if ( nNewPos > _pStream->Tell() ) + _pStream->Seek( nNewPos ); + + // ggf. Content-Header lesen + if ( _nRecordType == SFX_REC_TYPE_MIXTAGS || + _nRecordType == SFX_REC_TYPE_MIXTAGS_RELOC ) + { + _nContentVer = sal::static_int_cast< BYTE >( + SFX_REC_CONTENT_VER(_pContentOfs[_nContentNo])); + *_pStream >> _nContentTag; + } + + // ContentNo weiterz"ahlen + ++_nContentNo; + return TRUE; + } + + return FALSE; +} + + diff --git a/svl/source/filerec/makefile.mk b/svl/source/filerec/makefile.mk new file mode 100644 index 000000000000..c590e38a7ea1 --- /dev/null +++ b/svl/source/filerec/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=filerec + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/filerec.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/fsstor/exports.map b/svl/source/fsstor/exports.map new file mode 100644 index 000000000000..f4ed78b9e970 --- /dev/null +++ b/svl/source/fsstor/exports.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + local: + *; +}; diff --git a/svl/source/fsstor/fsfactory.cxx b/svl/source/fsstor/fsfactory.cxx new file mode 100644 index 000000000000..e47593ba8f8b --- /dev/null +++ b/svl/source/fsstor/fsfactory.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * 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: fsfactory.cxx,v $ + * $Revision: 1.10 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "fsfactory.hxx" +#include "cppuhelper/factory.hxx" +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/io/XSeekable.hpp> + + +#include <ucbhelper/fileidentifierconverter.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/content.hxx> + +#include <unotools/tempfile.hxx> +#include <unotools/ucbhelper.hxx> + +#include "fsstorage.hxx" + + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL FSStorageFactory::impl_staticGetSupportedServiceNames() +{ + uno::Sequence< ::rtl::OUString > aRet(2); + aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory"); + aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.FileSystemStorageFactory"); + return aRet; +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL FSStorageFactory::impl_staticGetImplementationName() +{ + return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.FileSystemStorageFactory"); +} + +//------------------------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::impl_staticCreateSelfInstance( + const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) +{ + return uno::Reference< uno::XInterface >( *new FSStorageFactory( xServiceManager ) ); +} + +//------------------------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::createInstance() + throw ( uno::Exception, + uno::RuntimeException ) +{ + ::rtl::OUString aTempURL; + + aTempURL = ::utl::TempFile( NULL, sal_True ).GetURL(); + + if ( !aTempURL.getLength() ) + throw uno::RuntimeException(); // TODO: can not create tempfile + + ::ucbhelper::Content aResultContent( + aTempURL, uno::Reference< ucb::XCommandEnvironment >() ); + + return uno::Reference< uno::XInterface >( + static_cast< OWeakObject* >( + new FSStorage( aResultContent, + embed::ElementModes::READWRITE, + uno::Sequence< beans::PropertyValue >(), + m_xFactory ) ), + uno::UNO_QUERY ); +} + +//------------------------------------------------------------------------- +uno::Reference< uno::XInterface > SAL_CALL FSStorageFactory::createInstanceWithArguments( + const uno::Sequence< uno::Any >& aArguments ) + throw ( uno::Exception, + uno::RuntimeException ) +{ + // The request for storage can be done with up to three arguments + + // The first argument specifies a source for the storage + // it must be URL. + // The second value is a mode the storage should be open in. + // And the third value is a media descriptor. + + sal_Int32 nArgNum = aArguments.getLength(); + OSL_ENSURE( nArgNum < 4, "Wrong parameter number" ); + + if ( !nArgNum ) + return createInstance(); + + // first try to retrieve storage open mode if any + // by default the storage will be open in readonly mode + sal_Int32 nStorageMode = embed::ElementModes::READ; + if ( nArgNum >= 2 ) + { + if( !( aArguments[1] >>= nStorageMode ) ) + { + OSL_ENSURE( sal_False, "Wrong second argument!\n" ); + throw uno::Exception(); // TODO: Illegal argument + } + // it's allways possible to read written storage in this implementation + nStorageMode |= embed::ElementModes::READ; + } + + // retrieve storage source URL + ::rtl::OUString aURL; + + if ( aArguments[0] >>= aURL ) + { + if ( !aURL.getLength() ) + { + OSL_ENSURE( sal_False, "Empty URL is provided!\n" ); + throw uno::Exception(); // TODO: illegal argument + } + } + else + { + OSL_ENSURE( sal_False, "Wrong first argument!\n" ); + throw uno::Exception(); // TODO: Illegal argument + } + + // retrieve mediadescriptor and set storage properties + uno::Sequence< beans::PropertyValue > aDescr; + uno::Sequence< beans::PropertyValue > aPropsToSet; + + if ( nArgNum >= 3 ) + { + if( aArguments[2] >>= aDescr ) + { + aPropsToSet.realloc(1); + aPropsToSet[0].Name = ::rtl::OUString::createFromAscii( "URL" ); + aPropsToSet[0].Value <<= aURL; + + for ( sal_Int32 nInd = 0, nNumArgs = 1; nInd < aDescr.getLength(); nInd++ ) + { + if ( aDescr[nInd].Name.equalsAscii( "InteractionHandler" ) ) + { + aPropsToSet.realloc( ++nNumArgs ); + aPropsToSet[nNumArgs-1].Name = aDescr[nInd].Name; + aPropsToSet[nNumArgs-1].Value = aDescr[nInd].Value; + break; + } + else + OSL_ENSURE( sal_False, "Unacceptable property, will be ignored!\n" ); + } + } + else + { + OSL_ENSURE( sal_False, "Wrong third argument!\n" ); + throw uno::Exception(); // TODO: Illegal argument + } + } + + // allow to use other ucp's + // if ( !isLocalNotFile_Impl( aURL ) ) + if ( aURL.equalsIgnoreAsciiCaseAsciiL( "vnd.sun.star.pkg", 16 ) + || aURL.equalsIgnoreAsciiCaseAsciiL( "vnd.sun.star.zip", 16 ) + || ::utl::UCBContentHelper::IsDocument( aURL ) ) + { + OSL_ENSURE( sal_False, "File system storages can be based only on file URLs!\n" ); // ??? + throw uno::Exception(); // TODO: illegal argument + } + + if ( ( nStorageMode & embed::ElementModes::WRITE ) && !( nStorageMode & embed::ElementModes::NOCREATE ) ) + FSStorage::MakeFolderNoUI( aURL, sal_False ); + else if ( !::utl::UCBContentHelper::IsFolder( aURL ) ) + throw io::IOException(); // there is no such folder + + ::ucbhelper::Content aResultContent( + aURL, uno::Reference< ucb::XCommandEnvironment >() ); + + // create storage based on source + return uno::Reference< uno::XInterface >( + static_cast< OWeakObject* >( new FSStorage( aResultContent, + nStorageMode, + aPropsToSet, + m_xFactory ) ), + uno::UNO_QUERY ); +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL FSStorageFactory::getImplementationName() + throw ( uno::RuntimeException ) +{ + return impl_staticGetImplementationName(); +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL FSStorageFactory::supportsService( const ::rtl::OUString& ServiceName ) + throw ( uno::RuntimeException ) +{ + uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames(); + + for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ ) + if ( ServiceName.compareTo( aSeq[nInd] ) == 0 ) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL FSStorageFactory::getSupportedServiceNames() + throw ( uno::RuntimeException ) +{ + return impl_staticGetSupportedServiceNames(); +} + +//------------------------------------------------------------------------- + +extern "C" +{ +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( + const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo ( + void * /* pServiceManager */, void * pRegistryKey) +{ + if (pRegistryKey) + { + uno::Reference< registry::XRegistryKey > xRegistryKey ( + reinterpret_cast< registry::XRegistryKey*>(pRegistryKey)); + + uno::Reference< registry::XRegistryKey > xNewKey; + xNewKey = xRegistryKey->createKey( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + + FSStorageFactory::impl_staticGetImplementationName() + + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES"))); + + const uno::Sequence< ::rtl::OUString > aServices ( + FSStorageFactory::impl_staticGetSupportedServiceNames()); + for( sal_Int32 i = 0; i < aServices.getLength(); i++ ) + xNewKey->createKey( aServices.getConstArray()[i] ); + + return sal_True; + } + return sal_False; +} + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( + const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */) +{ + void * pResult = 0; + if (pServiceManager) + { + uno::Reference< lang::XSingleServiceFactory > xFactory; + if (FSStorageFactory::impl_staticGetImplementationName().compareToAscii (pImplementationName) == 0) + { + xFactory = cppu::createOneInstanceFactory ( + reinterpret_cast< lang::XMultiServiceFactory* >(pServiceManager), + FSStorageFactory::impl_staticGetImplementationName(), + FSStorageFactory::impl_staticCreateSelfInstance, + FSStorageFactory::impl_staticGetSupportedServiceNames() ); + } + if (xFactory.is()) + { + xFactory->acquire(); + pResult = xFactory.get(); + } + } + return pResult; +} + +} // extern "C" + diff --git a/svl/source/fsstor/fsstorage.cxx b/svl/source/fsstor/fsstorage.cxx new file mode 100644 index 000000000000..bae02feae1dd --- /dev/null +++ b/svl/source/fsstor/fsstorage.cxx @@ -0,0 +1,1617 @@ +/************************************************************************* + * + * 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: fsstorage.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/ucb/XProgressHandler.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> + +#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_ +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#endif +#include <com/sun/star/ucb/IOErrorCode.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/util/XCloneable.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/io/IOException.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> + + +#ifndef _COMPHELPER_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <comphelper/storagehelper.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/exc_hlp.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/ucbhelper.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <unotools/streamwrap.hxx> +#include <ucbhelper/fileidentifierconverter.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <ucbhelper/content.hxx> + +#include "fsstorage.hxx" +#include "oinputstreamcontainer.hxx" +#include "ostreamcontainer.hxx" + +using namespace ::com::sun::star; + +//========================================================= + +// TODO: move to a standard helper +sal_Bool isLocalFile_Impl( ::rtl::OUString aURL ) +{ + ::rtl::OUString aSystemPath; + ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); + if ( !pBroker ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XContentProviderManager > xManager = + pBroker->getContentProviderManagerInterface(); + try + { + aSystemPath = ::ucbhelper::getSystemPathFromFileURL( xManager, aURL ); + } + catch ( uno::Exception& ) + { + } + + return ( aSystemPath.getLength() != 0 ); +} + + +//========================================================= + +struct FSStorage_Impl +{ + ::rtl::OUString m_aURL; + + ::ucbhelper::Content* m_pContent; + sal_Int32 m_nMode; + + ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners + ::cppu::OTypeCollection* m_pTypeCollection; + + uno::Reference< lang::XMultiServiceFactory > m_xFactory; + + + FSStorage_Impl( const ::rtl::OUString& aURL, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory ) + : m_aURL( aURL ) + , m_pContent( NULL ) + , m_nMode( nMode ) + , m_pListenersContainer( NULL ) + , m_pTypeCollection( NULL ) + , m_xFactory( xFactory ) + { + OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" ); + } + + FSStorage_Impl( const ::ucbhelper::Content& aContent, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory ) + : m_aURL( aContent.getURL() ) + , m_pContent( new ::ucbhelper::Content( aContent ) ) + , m_nMode( nMode ) + , m_pListenersContainer( NULL ) + , m_pTypeCollection( NULL ) + , m_xFactory( xFactory ) + { + OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" ); + } + + ~FSStorage_Impl(); +}; + +//========================================================= + +FSStorage_Impl::~FSStorage_Impl() +{ + if ( m_pListenersContainer ) + delete m_pListenersContainer; + if ( m_pTypeCollection ) + delete m_pTypeCollection; + if ( m_pContent ) + delete m_pContent; +} + +//===================================================== +// FSStorage implementation +//===================================================== + +//----------------------------------------------- +FSStorage::FSStorage( const ::ucbhelper::Content& aContent, + sal_Int32 nMode, + uno::Sequence< beans::PropertyValue >, + uno::Reference< lang::XMultiServiceFactory > xFactory ) +: m_pImpl( new FSStorage_Impl( aContent, nMode, xFactory ) ) +{ + // TODO: use properties + if ( !xFactory.is() ) + throw uno::RuntimeException(); + + GetContent(); +} + +//----------------------------------------------- +FSStorage::~FSStorage() +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_refCount++; // to call dispose + try { + dispose(); + } + catch( uno::RuntimeException& ) + {} + } +} + +//----------------------------------------------- +sal_Bool FSStorage::MakeFolderNoUI( const String& rFolder, sal_Bool ) +{ + INetURLObject aURL( rFolder ); + ::rtl::OUString aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ); + aURL.removeSegment(); + ::ucbhelper::Content aParent; + ::ucbhelper::Content aResultContent; + + if ( ::ucbhelper::Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ), + uno::Reference< ucb::XCommandEnvironment >(), + aParent ) ) + return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent, sal_False ); + + return sal_False; +} + +//----------------------------------------------- +::ucbhelper::Content* FSStorage::GetContent() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_pImpl->m_pContent ) + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + + try + { + m_pImpl->m_pContent = new ::ucbhelper::Content( m_pImpl->m_aURL, xDummyEnv ); + } + catch( uno::Exception& ) + { + } + } + + return m_pImpl->m_pContent; +} + +//----------------------------------------------- +void FSStorage::CopyStreamToSubStream( const ::rtl::OUString& aSourceURL, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewEntryName ) +{ + if ( !xDest.is() ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv ); + uno::Reference< io::XInputStream > xSourceInput = aSourceContent.openStream(); + + if ( !xSourceInput.is() ) + throw io::IOException(); // TODO: error handling + + uno::Reference< io::XStream > xSubStream = xDest->openStreamElement( + aNewEntryName, + embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + if ( !xSubStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XOutputStream > xDestOutput = xSubStream->getOutputStream(); + if ( !xDestOutput.is() ) + throw uno::RuntimeException(); + + ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput, xDestOutput ); + xDestOutput->closeOutput(); +} + +//----------------------------------------------- +void FSStorage::CopyContentToStorage_Impl( ::ucbhelper::Content* pContent, const uno::Reference< embed::XStorage >& xDest ) +{ + if ( !pContent ) + throw uno::RuntimeException(); + + // get list of contents of the Content + // create cursor for access to children + uno::Sequence< ::rtl::OUString > aProps( 2 ); + ::rtl::OUString* pProps = aProps.getArray(); + pProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" ); + pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = pContent->createCursor( aProps, eInclude ); + uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY ); + uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY ); + if ( xResultSet.is() ) + { + // go through the list: insert files as streams, insert folders as substorages using recursion + while ( xResultSet->next() ) + { + ::rtl::OUString aSourceURL( xRow->getString( 1 ) ); + sal_Bool bIsFolder( xRow->getBoolean(2) ); + + // TODO/LATER: not sure whether the entry name must be encoded + ::rtl::OUString aNewEntryName( INetURLObject( aSourceURL ).getName( INetURLObject::LAST_SEGMENT, + true, + INetURLObject::NO_DECODE ) ); + if ( bIsFolder ) + { + uno::Reference< embed::XStorage > xSubStorage = xDest->openStorageElement( aNewEntryName, + embed::ElementModes::READWRITE ); + if ( !xSubStorage.is() ) + throw uno::RuntimeException(); + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv ); + CopyContentToStorage_Impl( &aSourceContent, xSubStorage ); + } + else + { + CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName ); + } + } + } + + uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY ); + if ( xTransact.is() ) + xTransact->commit(); + } + catch( ucb::InteractiveIOException& r ) + { + if ( r.Code == ucb::IOErrorCode_NOT_EXISTING ) + OSL_ENSURE( sal_False, "The folder does not exist!\n" ); + else + throw; + } +} + +//____________________________________________________________________________________________________ +// XInterface +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aReturn; + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<lang::XTypeProvider*> ( this ) + , static_cast<embed::XStorage*> ( this ) + , static_cast<embed::XHierarchicalStorageAccess*> ( this ) + , static_cast<container::XNameAccess*> ( this ) + , static_cast<container::XElementAccess*> ( this ) + , static_cast<lang::XComponent*> ( this ) + , static_cast<beans::XPropertySet*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + + return OWeakObject::queryInterface( rType ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::acquire() throw() +{ + OWeakObject::acquire(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::release() throw() +{ + OWeakObject::release(); +} + +//____________________________________________________________________________________________________ +// XTypeProvider +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes() + throw( uno::RuntimeException ) +{ + if ( m_pImpl->m_pTypeCollection == NULL ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pImpl->m_pTypeCollection == NULL ) + { + m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL ) + , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL ) + , ::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL ) + , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) ); + } + } + + return m_pImpl->m_pTypeCollection->getTypes() ; +} + +//----------------------------------------------- +uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId() + throw( uno::RuntimeException ) +{ + static ::cppu::OImplementationId* pID = NULL ; + + if ( pID == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; + + if ( pID == NULL ) + { + static ::cppu::OImplementationId aID( sal_False ) ; + pID = &aID ; + } + } + + return pID->getImplementationId() ; + +} + +//____________________________________________________________________________________________________ +// XStorage +//____________________________________________________________________________________________________ + +//----------------------------------------------- +void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest ) + throw ( embed::InvalidStorageException, + io::IOException, + lang::IllegalArgumentException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) ) + throw lang::IllegalArgumentException(); // TODO: + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + try + { + CopyContentToStorage_Impl( GetContent(), xDest ); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement( + const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFileURL( m_pImpl->m_aURL ); + aFileURL.Append( aStreamName ); + + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::NOCREATE ) + && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< io::XStream > xResult; + try + { + if ( nOpenMode & embed::ElementModes::WRITE ) + { + if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( + m_pImpl->m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), + uno::UNO_QUERY_THROW ); + xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } + else + { + // TODO: test whether it really works for http and fwp + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), + STREAM_STD_WRITE ); + if ( pStream ) + { + if ( !pStream->GetError() ) + xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) ); + else + delete pStream; + } + } + + if ( !xResult.is() ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) ) + { + uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW ); + xTrunc->truncate(); + } + } + else + { + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) + || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: access denied + + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) ); + } + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement( + const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement( + const ::rtl::OUString& aStorName, sal_Int32 nStorageMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( ( nStorageMode & embed::ElementModes::WRITE ) + && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFolderURL( m_pImpl->m_aURL ); + aFolderURL.Append( aStorName ); + + sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ); + if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< embed::XStorage > xResult; + try + { + if ( nStorageMode & embed::ElementModes::WRITE ) + { + if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists ) + { + ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ); + bFolderExists = + MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :( + } + else if ( !bFolderExists ) + { + bFolderExists = + MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :( + } + } + else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) ) + throw io::IOException(); // TODO: access denied + + if ( !bFolderExists ) + throw io::IOException(); // there is no such folder + + ::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + xResult = uno::Reference< embed::XStorage >( + static_cast< OWeakObject* >( new FSStorage( aResultContent, + nStorageMode, + uno::Sequence< beans::PropertyValue >(), + m_pImpl->m_xFactory ) ), + uno::UNO_QUERY ); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aFileURL( m_pImpl->m_aURL ); + aFileURL.Append( aStreamName ); + + uno::Reference < io::XStream > xTempResult; + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + + xTempResult = uno::Reference < io::XStream >( + m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), + uno::UNO_QUERY_THROW ); + uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream(); + uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream(); + + if ( !xTempOut.is() || !xTempIn.is() ) + throw io::IOException(); + + ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut ); + xTempOut->closeOutput(); + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return xTempResult; +} + +//----------------------------------------------- +uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement( + const ::rtl::OUString&, + const ::rtl::OUString& ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyLastCommitTo( + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + copyToStorage( xTargetStorage ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyStorageElementLastCommitTo( + const ::rtl::OUString& aStorName, + const uno::Reference< embed::XStorage >& xTargetStorage ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ), + uno::UNO_QUERY_THROW ); + xSourceStor->copyToStorage( xTargetStorage ); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw embed::InvalidStorageException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw embed::InvalidStorageException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aElementName ); + + if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) + && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::NoSuchElementException(); // TODO: + + ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aOldURL( m_pImpl->m_aURL ); + aOldURL.Append( aElementName ); + + INetURLObject aNewURL( m_pImpl->m_aURL ); + aNewURL.Append( aNewName ); + + if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) + && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::NoSuchElementException(); // TODO: + + if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) + || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw container::ElementExistException(); // TODO: + + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + + if ( !GetContent()->transferContent( aSourceContent, + ::ucbhelper::InsertOperation_MOVE, + aNewName, + ucb::NameClash::ERROR ) ) + throw io::IOException(); // TODO: error handling + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( container::ElementExistException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +void SAL_CALL FSStorage::copyElementTo( const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !xDest.is() ) + throw uno::RuntimeException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aOwnURL( m_pImpl->m_aURL ); + aOwnURL.Append( aElementName ); + + if ( xDest->hasByName( aNewName ) ) + throw container::ElementExistException(); // TODO: + + try + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + ::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< embed::XStorage > xDestSubStor( + xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ), + uno::UNO_QUERY_THROW ); + + CopyContentToStorage_Impl( &aSourceContent, xDestSubStor ); + } + else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName ); + } + else + throw container::NoSuchElementException(); // TODO: + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( container::ElementExistException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } +} + +//----------------------------------------------- +void SAL_CALL FSStorage::moveElementTo( const ::rtl::OUString& aElementName, + const uno::Reference< embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + container::ElementExistException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + copyElementTo( aElementName, xDest, aNewName ); + + INetURLObject aOwnURL( m_pImpl->m_aURL ); + aOwnURL.Append( aElementName ); + if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: error handling +} + +//____________________________________________________________________________________________________ +// XNameAccess +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName ) + throw ( container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( !aName.getLength() ) + throw lang::IllegalArgumentException(); + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aName ); + + uno::Any aResult; + try + { + if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + aResult <<= openStorageElement( aName, embed::ElementModes::READ ); + } + else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + aResult <<= openStreamElement( aName, embed::ElementModes::READ ); + } + else + throw container::NoSuchElementException(); // TODO: + } + catch( container::NoSuchElementException& ) + { + throw; + } + catch( lang::WrappedTargetException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + return aResult; +} + + +//----------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + uno::Sequence< ::rtl::OUString > aProps( 1 ); + ::rtl::OUString* pProps = aProps.getArray(); + pProps[0] = ::rtl::OUString::createFromAscii( "Title" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + uno::Sequence< ::rtl::OUString > aResult; + sal_Int32 nSize = 0; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude ); + uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY ); + uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY ); + if ( xResultSet.is() ) + { + // go through the list + while ( xResultSet->next() ) + { + ::rtl::OUString aName( xRow->getString( 1 ) ); + aResult.realloc( ++nSize ); + aResult[nSize-1] = aName; + } + } + } + catch( ucb::InteractiveIOException& r ) + { + if ( r.Code == ucb::IOErrorCode_NOT_EXISTING ) + OSL_ENSURE( sal_False, "The folder does not exist!\n" ); + else + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + return aResult; +} + + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + try + { + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + if ( !aName.getLength() ) + throw lang::IllegalArgumentException(); + } + catch( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ), + uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), + uno::UNO_QUERY ), + aCaught ); + } + + INetURLObject aURL( m_pImpl->m_aURL ); + aURL.Append( aName ); + + return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) + || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) ); +} + +//----------------------------------------------- +uno::Type SAL_CALL FSStorage::getElementType() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + // it is a multitype container + return uno::Type(); +} + +//----------------------------------------------- +sal_Bool SAL_CALL FSStorage::hasElements() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + uno::Sequence< ::rtl::OUString > aProps( 1 ); + aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" ); + ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS; + + try + { + uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude ); + return ( xResultSet.is() && xResultSet->next() ); + } + catch( uno::Exception& ) + { + throw uno::RuntimeException(); + } +} + + +//____________________________________________________________________________________________________ +// XDisposable +//____________________________________________________________________________________________________ + +//----------------------------------------------- +void SAL_CALL FSStorage::dispose() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( m_pImpl->m_pListenersContainer ) + { + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) ); + m_pImpl->m_pListenersContainer->disposeAndClear( aSource ); + } + + delete m_pImpl; + m_pImpl = NULL; +} + +//----------------------------------------------- +void SAL_CALL FSStorage::addEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !m_pImpl->m_pListenersContainer ) + m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pImpl->m_pListenersContainer->addInterface( xListener ); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeEventListener( + const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( m_pImpl->m_pListenersContainer ) + m_pImpl->m_pListenersContainer->removeInterface( xListener ); +} + +//____________________________________________________________________________________________________ +// XPropertySet +//____________________________________________________________________________________________________ + +//----------------------------------------------- +uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: + return uno::Reference< beans::XPropertySetInfo >(); +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& ) + throw ( beans::UnknownPropertyException, + beans::PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) ) + throw beans::PropertyVetoException(); // TODO + else + throw beans::UnknownPropertyException(); // TODO +} + + +//----------------------------------------------- +uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( aPropertyName.equalsAscii( "URL" ) ) + return uno::makeAny( m_pImpl->m_aURL ); + else if ( aPropertyName.equalsAscii( "OpenMode" ) ) + return uno::makeAny( m_pImpl->m_nMode ); + + throw beans::UnknownPropertyException(); // TODO +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::addPropertyChangeListener( + const ::rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::removePropertyChangeListener( + const ::rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::addVetoableChangeListener( + const ::rtl::OUString& /*PropertyName*/, + const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + + +//----------------------------------------------- +void SAL_CALL FSStorage::removeVetoableChangeListener( + const ::rtl::OUString& /*PropertyName*/, + const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ ) + throw ( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + //TODO: +} + +//____________________________________________________________________________________________________ +// XHierarchicalStorageAccess +//____________________________________________________________________________________________________ +//----------------------------------------------- +uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( sStreamPath.toChar() == '/' ) + throw lang::IllegalArgumentException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + INetURLObject aBaseURL( m_pImpl->m_aURL ); + if ( !aBaseURL.setFinalSlash() ) + throw uno::RuntimeException(); + + INetURLObject aFileURL = INetURLObject::GetAbsURL( + aBaseURL.GetMainURL( INetURLObject::NO_DECODE ), + sStreamPath ); + + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::NOCREATE ) + && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: + + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any + uno::Reference< io::XStream > xResult; + try + { + if ( nOpenMode & embed::ElementModes::WRITE ) + { + if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( + m_pImpl->m_xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XStream > xStream = + xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ); + + xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) ); + } + else + { + // TODO: test whether it really works for http and fwp + SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), + STREAM_STD_WRITE ); + if ( pStream ) + { + if ( !pStream->GetError() ) + { + uno::Reference< io::XStream > xStream = + uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) ); + xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) ); + } + else + delete pStream; + } + } + + if ( !xResult.is() ) + throw io::IOException(); + + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) ) + { + uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW ); + xTrunc->truncate(); + } + } + else + { + if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) + || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: access denied + + ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv ); + uno::Reference< io::XInputStream > xInStream = aResultContent.openStream(); + xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) ); + } + } + catch( embed::InvalidStorageException& ) + { + throw; + } + catch( lang::IllegalArgumentException& ) + { + throw; + } + catch( packages::WrongPasswordException& ) + { + throw; + } + catch( embed::StorageWrappedTargetException& ) + { + throw; + } + catch( io::IOException& ) + { + throw; + } + catch( uno::RuntimeException& ) + { + throw; + } + catch( uno::Exception& ) + { + uno::Any aCaught( ::cppu::getCaughtException() ); + throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ), + uno::Reference< io::XInputStream >(), + aCaught ); + } + + return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW ); +} + +//----------------------------------------------- +uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + packages::NoEncryptionException, + packages::WrongPasswordException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + throw packages::NoEncryptionException(); +} + +//----------------------------------------------- +void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath ) + throw ( embed::InvalidStorageException, + lang::IllegalArgumentException, + container::NoSuchElementException, + io::IOException, + embed::StorageWrappedTargetException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pImpl ) + throw lang::DisposedException(); + + if ( !GetContent() ) + throw io::IOException(); // TODO: error handling + + // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked + INetURLObject aBaseURL( m_pImpl->m_aURL ); + if ( !aBaseURL.setFinalSlash() ) + throw uno::RuntimeException(); + + INetURLObject aFileURL = INetURLObject::GetAbsURL( + aBaseURL.GetMainURL( INetURLObject::NO_DECODE ), + sStreamPath ); + + if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + { + if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw lang::IllegalArgumentException(); + else + throw container::NoSuchElementException(); // TODO: + } + + if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) ) + throw io::IOException(); // TODO: error handling +} + + diff --git a/svl/source/fsstor/fsstorage.hxx b/svl/source/fsstor/fsstorage.hxx new file mode 100644 index 000000000000..670a6917dd40 --- /dev/null +++ b/svl/source/fsstor/fsstorage.hxx @@ -0,0 +1,340 @@ +/************************************************************************* + * + * 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: fsstorage.hxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __XSTORAGE_HXX_ +#define __XSTORAGE_HXX_ + +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/packages/NoEncryptionException.hpp> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.h> + +#include <ucbhelper/content.hxx> + +struct FSStorage_Impl; +class FSStorage : public ::com::sun::star::lang::XTypeProvider + , public ::com::sun::star::embed::XStorage + , public ::com::sun::star::embed::XHierarchicalStorageAccess + , public ::com::sun::star::beans::XPropertySet + , public ::cppu::OWeakObject +{ + ::osl::Mutex m_aMutex; + FSStorage_Impl* m_pImpl; + +protected: + +public: + + FSStorage( const ::ucbhelper::Content& aContent, + sal_Int32 nMode, + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > xProperties, + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory ); + + virtual ~FSStorage(); + + ::ucbhelper::Content* GetContent(); + + void CopyStreamToSubStream( const ::rtl::OUString& aSourceURL, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest, + const ::rtl::OUString& aNewEntryName ); + + void CopyContentToStorage_Impl( ::ucbhelper::Content* pContent, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest ); + + static sal_Bool MakeFolderNoUI( const String& rFolder, sal_Bool bNewOnly ); + + //____________________________________________________________________________________________________ + // XInterface + //____________________________________________________________________________________________________ + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL acquire() throw(); + + virtual void SAL_CALL release() throw(); + + //____________________________________________________________________________________________________ + // XTypeProvider + //____________________________________________________________________________________________________ + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() + throw( ::com::sun::star::uno::RuntimeException ); + + //____________________________________________________________________________________________________ + // XStorage + //____________________________________________________________________________________________________ + + virtual void SAL_CALL copyToStorage( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openStreamElement( + const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL openEncryptedStreamElement( + const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::NoEncryptionException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL openStorageElement( + const ::rtl::OUString& aStorName, sal_Int32 nStorageMode ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL cloneStreamElement( + const ::rtl::OUString& aStreamName ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > SAL_CALL cloneEncryptedStreamElement( + const ::rtl::OUString& aStreamName, const ::rtl::OUString& aPass ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::NoEncryptionException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL copyLastCommitTo( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xTargetStorage ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL copyStorageElementLastCommitTo( + const ::rtl::OUString& aStorName, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xTargetStorage ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL isStreamElement( const ::rtl::OUString& aElementName ) + throw ( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL isStorageElement( const ::rtl::OUString& aElementName ) + throw ( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removeElement( const ::rtl::OUString& aElementName ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL renameElement( const ::rtl::OUString& rEleName, const ::rtl::OUString& rNewName ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL copyElementTo( const ::rtl::OUString& aElementName, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest, + const ::rtl::OUString& aNewName ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL moveElementTo( const ::rtl::OUString& aElementName, + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xDest, + const ::rtl::OUString& rNewName ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + //____________________________________________________________________________________________________ + // XNameAccess + //____________________________________________________________________________________________________ + + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw ( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Type SAL_CALL getElementType() + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL hasElements() + throw ( ::com::sun::star::uno::RuntimeException ); + + //____________________________________________________________________________________________________ + // XComponent + //____________________________________________________________________________________________________ + + virtual void SAL_CALL dispose() + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL addEventListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removeEventListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) + throw ( ::com::sun::star::uno::RuntimeException ); + + //____________________________________________________________________________________________________ + // XPropertySet + //____________________________________________________________________________________________________ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw ( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL addPropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removePropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL addVetoableChangeListener( + const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw ( ::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + //____________________________________________________________________________________________________ + // XHierarchicalStorageAccess + //____________________________________________________________________________________________________ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream > SAL_CALL openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XExtendedStorageStream > SAL_CALL openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& sStreamName, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::packages::NoEncryptionException, + ::com::sun::star::packages::WrongPasswordException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removeStreamElementByHierarchicalName( const ::rtl::OUString& sElementPath ) + throw ( ::com::sun::star::embed::InvalidStorageException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::io::IOException, + ::com::sun::star::embed::StorageWrappedTargetException, + ::com::sun::star::uno::RuntimeException ); +}; + +#endif + diff --git a/svl/source/fsstor/makefile.mk b/svl/source/fsstor/makefile.mk new file mode 100644 index 000000000000..7f46009750fd --- /dev/null +++ b/svl/source/fsstor/makefile.mk @@ -0,0 +1,70 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=svl +TARGET=fsstorage.uno +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +DLLPRE= + +# --- Files ------------------------------------- + +SLOFILES=\ + $(SLO)$/fsfactory.obj \ + $(SLO)$/fsstorage.obj \ + $(SLO)$/oinputstreamcontainer.obj \ + $(SLO)$/ostreamcontainer.obj + +SHL1TARGET= $(TARGET) +SHL1IMPLIB= i$(TARGET) +SHL1OBJS= $(SLOFILES) +SHL1STDLIBS=\ + $(UNOTOOLSLIB) \ + $(TOOLSLIB) \ + $(COMPHELPERLIB) \ + $(UCBHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1VERSIONMAP=exports.map +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/fsstor/oinputstreamcontainer.cxx b/svl/source/fsstor/oinputstreamcontainer.cxx new file mode 100644 index 000000000000..53be03699ba0 --- /dev/null +++ b/svl/source/fsstor/oinputstreamcontainer.cxx @@ -0,0 +1,350 @@ +/************************************************************************* + * + * 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: oinputstreamcontainer.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "oinputstreamcontainer.hxx" +#include <cppuhelper/typeprovider.hxx> + +using namespace ::com::sun::star; + +//----------------------------------------------- +OFSInputStreamContainer::OFSInputStreamContainer( const uno::Reference< io::XInputStream >& xStream ) +: m_xInputStream( xStream ) +, m_xSeekable( xStream, uno::UNO_QUERY ) +, m_bSeekable( sal_False ) +, m_bDisposed( sal_False ) +, m_pListenersContainer( NULL ) +{ + m_bSeekable = m_xSeekable.is(); +} + +//----------------------------------------------- +OFSInputStreamContainer::~OFSInputStreamContainer() +{ + if ( m_pListenersContainer ) + { + delete m_pListenersContainer; + m_pListenersContainer = NULL; + } +} + +//----------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL OFSInputStreamContainer::getTypes() + throw ( uno::RuntimeException ) +{ + static ::cppu::OTypeCollection* pTypeCollection = NULL ; + + if ( pTypeCollection == NULL ) + { + ::osl::MutexGuard aGuard( m_aMutex ) ; + + if ( pTypeCollection == NULL ) + { + if ( m_bSeekable ) + { + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType(( const uno::Reference< io::XStream >* )NULL ), + ::getCppuType(( const uno::Reference< io::XInputStream >* )NULL ), + ::getCppuType(( const uno::Reference< io::XSeekable >* )NULL ) ); + + pTypeCollection = &aTypeCollection ; + } + else + { + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType(( const uno::Reference< io::XStream >* )NULL ), + ::getCppuType(( const uno::Reference< io::XInputStream >* )NULL ) ); + + pTypeCollection = &aTypeCollection ; + } + } + } + + return pTypeCollection->getTypes() ; + +} + +//----------------------------------------------- +uno::Any SAL_CALL OFSInputStreamContainer::queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + // Attention: + // Don't use mutex or guard in this method!!! Is a method of XInterface. + + uno::Any aReturn; + if ( m_bSeekable ) + aReturn = uno::Any( ::cppu::queryInterface( rType, + static_cast< io::XStream* >( this ), + static_cast< io::XInputStream* >( this ), + static_cast< io::XSeekable* >( this ) ) ); + else + aReturn = uno::Any( ::cppu::queryInterface( rType, + static_cast< io::XStream* >( this ), + static_cast< io::XInputStream* >( this ) ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + + return ::cppu::OWeakObject::queryInterface( rType ) ; +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::acquire() + throw() +{ + ::cppu::OWeakObject::acquire(); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::release() + throw() +{ + ::cppu::OWeakObject::release(); +} + +//----------------------------------------------- +sal_Int32 SAL_CALL OFSInputStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->readBytes( aData, nBytesToRead ); +} + +//----------------------------------------------- +sal_Int32 SAL_CALL OFSInputStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead ); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::skipBytes( sal_Int32 nBytesToSkip ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + m_xInputStream->skipBytes( nBytesToSkip ); +} + +//----------------------------------------------- +sal_Int32 SAL_CALL OFSInputStreamContainer::available( ) + throw ( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->available(); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::closeInput( ) + throw ( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + dispose(); +} + +//----------------------------------------------- +uno::Reference< io::XInputStream > SAL_CALL OFSInputStreamContainer::getInputStream() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + return uno::Reference< io::XInputStream >(); + + return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ), uno::UNO_QUERY ); +} + +//----------------------------------------------- +uno::Reference< io::XOutputStream > SAL_CALL OFSInputStreamContainer::getOutputStream() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + return uno::Reference< io::XOutputStream >(); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::seek( sal_Int64 location ) + throw ( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xSeekable.is() ) + throw uno::RuntimeException(); + + m_xSeekable->seek( location ); +} + +//----------------------------------------------- +sal_Int64 SAL_CALL OFSInputStreamContainer::getPosition() + throw ( io::IOException, + uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xSeekable.is() ) + throw uno::RuntimeException(); + + return m_xSeekable->getPosition(); +} + +//----------------------------------------------- +sal_Int64 SAL_CALL OFSInputStreamContainer::getLength() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xSeekable.is() ) + throw uno::RuntimeException(); + + return m_xSeekable->getLength(); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::dispose( ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xInputStream.is() ) + throw uno::RuntimeException(); + + m_xInputStream->closeInput(); + + if ( m_pListenersContainer ) + { + lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) ); + m_pListenersContainer->disposeAndClear( aSource ); + } + + m_bDisposed = sal_True; +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_pListenersContainer ) + m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pListenersContainer->addInterface( xListener ); +} + +//----------------------------------------------- +void SAL_CALL OFSInputStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( m_pListenersContainer ) + m_pListenersContainer->removeInterface( xListener ); +} + + + diff --git a/svl/source/fsstor/oinputstreamcontainer.hxx b/svl/source/fsstor/oinputstreamcontainer.hxx new file mode 100644 index 000000000000..308f4283b430 --- /dev/null +++ b/svl/source/fsstor/oinputstreamcontainer.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * 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: oinputstreamcontainer.hxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _OINPUTSTREAMCONTAINER_HXX_ +#define _OINPUTSTREAMCONTAINER_HXX_ + +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/embed/XExtendedStorageStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> + + +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/interfacecontainer.h> + +#include <osl/mutex.hxx> + +class OFSInputStreamContainer : public cppu::WeakImplHelper2 < ::com::sun::star::io::XInputStream + ,::com::sun::star::embed::XExtendedStorageStream > + , public ::com::sun::star::io::XSeekable +{ +protected: + ::osl::Mutex m_aMutex; + + ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xInputStream; + ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable; + + sal_Bool m_bSeekable; + + sal_Bool m_bDisposed; + + ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners + +public: + OFSInputStreamContainer( const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream ); + + virtual ~OFSInputStreamContainer(); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XInputStream + virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL available( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + //XStream + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException); + + //XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + //XComponent + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + +}; + +#endif + diff --git a/svl/source/fsstor/ostreamcontainer.cxx b/svl/source/fsstor/ostreamcontainer.cxx new file mode 100644 index 000000000000..dac7c9c31375 --- /dev/null +++ b/svl/source/fsstor/ostreamcontainer.cxx @@ -0,0 +1,570 @@ +/************************************************************************* + * + * 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: ostreamcontainer.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "ostreamcontainer.hxx" + + +using namespace ::com::sun::star; + +//----------------------------------------------- +OFSStreamContainer::OFSStreamContainer( const uno::Reference < io::XStream >& xStream ) +: m_bDisposed( sal_False ) +, m_bInputClosed( sal_False ) +, m_bOutputClosed( sal_False ) +, m_pListenersContainer( NULL ) +, m_pTypeCollection( NULL ) +{ + try + { + m_xStream = xStream; + if ( !m_xStream.is() ) + throw uno::RuntimeException(); + + m_xSeekable = uno::Reference< io::XSeekable >( xStream, uno::UNO_QUERY ); + m_xInputStream = xStream->getInputStream(); + m_xOutputStream = xStream->getOutputStream(); + m_xTruncate = uno::Reference< io::XTruncate >( m_xOutputStream, uno::UNO_QUERY ); + m_xAsyncOutputMonitor = uno::Reference< io::XAsyncOutputMonitor >( m_xOutputStream, uno::UNO_QUERY ); + } + catch( uno::Exception& ) + { + m_xStream = uno::Reference< io::XStream >(); + m_xSeekable = uno::Reference< io::XSeekable >(); + m_xInputStream = uno::Reference< io::XInputStream >(); + m_xOutputStream = uno::Reference< io::XOutputStream >(); + m_xTruncate = uno::Reference< io::XTruncate >(); + m_xAsyncOutputMonitor = uno::Reference< io::XAsyncOutputMonitor >(); + } +} + +//----------------------------------------------- +OFSStreamContainer::~OFSStreamContainer() +{ + if ( m_pListenersContainer ) + { + delete m_pListenersContainer; + m_pListenersContainer = NULL; + } +} + +// XInterface +//----------------------------------------------- +uno::Any SAL_CALL OFSStreamContainer::queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aReturn; + + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<lang::XTypeProvider*> ( this ) + , static_cast<io::XStream*> ( this ) + , static_cast<embed::XExtendedStorageStream*> ( this ) + , static_cast<lang::XComponent*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + + if ( m_xSeekable.is() ) + { + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<io::XSeekable*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + } + + if ( m_xInputStream.is() ) + { + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<io::XInputStream*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + } + if ( m_xOutputStream.is() ) + { + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<io::XOutputStream*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + } + if ( m_xTruncate.is() ) + { + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<io::XTruncate*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + } + if ( m_xAsyncOutputMonitor.is() ) + { + aReturn <<= ::cppu::queryInterface + ( rType + , static_cast<io::XAsyncOutputMonitor*> ( this ) ); + + if ( aReturn.hasValue() == sal_True ) + return aReturn ; + } + + return OWeakObject::queryInterface( rType ); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::acquire() + throw() +{ + OWeakObject::acquire(); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::release() + throw() +{ + OWeakObject::release(); +} + +// XTypeProvider +//----------------------------------------------- +uno::Sequence< uno::Type > SAL_CALL OFSStreamContainer::getTypes() + throw( uno::RuntimeException ) +{ + if ( m_pTypeCollection == NULL ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pTypeCollection == NULL ) + { + ::cppu::OTypeCollection aTypeCollection + ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL ) + , ::getCppuType( ( const uno::Reference< embed::XExtendedStorageStream >* )NULL ) ); + + if ( m_xSeekable.is() ) + aTypeCollection = ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< io::XSeekable >* )NULL ), + aTypeCollection.getTypes() ); + if ( m_xInputStream.is() ) + aTypeCollection = ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< io::XInputStream >* )NULL ), + aTypeCollection.getTypes() ); + + if ( m_xOutputStream.is() ) + aTypeCollection = ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< io::XOutputStream >* )NULL ), + aTypeCollection.getTypes() ); + if ( m_xTruncate.is() ) + aTypeCollection = ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< io::XTruncate >* )NULL ), + aTypeCollection.getTypes() ); + if ( m_xAsyncOutputMonitor.is() ) + aTypeCollection = ::cppu::OTypeCollection + ( ::getCppuType( ( const uno::Reference< io::XAsyncOutputMonitor >* )NULL ), + aTypeCollection.getTypes() ); + + m_pTypeCollection = new ::cppu::OTypeCollection( aTypeCollection ); + } + } + return m_pTypeCollection->getTypes() ; +} + +//----------------------------------------------- +uno::Sequence< sal_Int8 > SAL_CALL OFSStreamContainer::getImplementationId() + throw( uno::RuntimeException ) +{ + static ::cppu::OImplementationId* pID = NULL ; + + if ( pID == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; + + if ( pID == NULL ) + { + static ::cppu::OImplementationId aID( sal_False ) ; + pID = &aID ; + } + } + + return pID->getImplementationId() ; +} + +// XStream +//----------------------------------------------- +uno::Reference< io::XInputStream > SAL_CALL OFSStreamContainer::getInputStream() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() ) + throw uno::RuntimeException(); + + if ( m_xInputStream.is() ) + return uno::Reference< io::XInputStream >( static_cast< io::XInputStream* >( this ) ); + + return uno::Reference< io::XInputStream >(); +} + +//----------------------------------------------- +uno::Reference< io::XOutputStream > SAL_CALL OFSStreamContainer::getOutputStream() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() ) + throw uno::RuntimeException(); + + if ( m_xOutputStream.is() ) + return uno::Reference< io::XOutputStream >( static_cast< io::XOutputStream* >( this ) ); + + return uno::Reference< io::XOutputStream >(); +} + +// XComponent +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::dispose() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() ) + throw uno::RuntimeException(); + + if ( m_xInputStream.is() && !m_bInputClosed ) + { + m_xInputStream->closeInput(); + m_bInputClosed = sal_True; + } + + if ( m_xOutputStream.is() && !m_bOutputClosed ) + { + m_xOutputStream->closeOutput(); + m_bOutputClosed = sal_True; + } + + if ( m_pListenersContainer ) + { + lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>( this ) ); + m_pListenersContainer->disposeAndClear( aSource ); + } + + m_bDisposed = sal_True; +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::addEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_pListenersContainer ) + m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pListenersContainer->addInterface( xListener ); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::removeEventListener( const uno::Reference< lang::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( m_pListenersContainer ) + m_pListenersContainer->removeInterface( xListener ); +} + + +// XSeekable +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::seek( sal_Int64 location ) + throw ( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xSeekable.is() ) + throw uno::RuntimeException(); + + m_xSeekable->seek( location ); +} + +//----------------------------------------------- +sal_Int64 SAL_CALL OFSStreamContainer::getPosition() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xSeekable.is() ) + throw uno::RuntimeException(); + + return m_xSeekable->getPosition(); +} + +//----------------------------------------------- +sal_Int64 SAL_CALL OFSStreamContainer::getLength() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xSeekable.is() ) + throw uno::RuntimeException(); + + return m_xSeekable->getLength(); +} + + +// XInputStream +//----------------------------------------------- +sal_Int32 SAL_CALL OFSStreamContainer::readBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->readBytes( aData, nBytesToRead ); +} + +//----------------------------------------------- +sal_Int32 SAL_CALL OFSStreamContainer::readSomeBytes( uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->readSomeBytes( aData, nMaxBytesToRead ); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::skipBytes( sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xInputStream.is() ) + throw uno::RuntimeException(); + + m_xInputStream->skipBytes( nBytesToSkip ); +} + +//----------------------------------------------- +sal_Int32 SAL_CALL OFSStreamContainer::available() + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xInputStream.is() ) + throw uno::RuntimeException(); + + return m_xInputStream->available(); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::closeInput() + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xInputStream.is() ) + throw uno::RuntimeException(); + + if ( m_xInputStream.is() ) + { + m_xInputStream->closeInput(); + m_bInputClosed = sal_True; + } + + if ( m_bOutputClosed ) + dispose(); +} + +// XOutputStream +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::writeBytes( const uno::Sequence< sal_Int8 >& aData ) + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xOutputStream.is() ) + throw uno::RuntimeException(); + + return m_xOutputStream->writeBytes( aData ); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::flush() + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xOutputStream.is() ) + throw uno::RuntimeException(); + + return m_xOutputStream->flush(); +} + +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::closeOutput() + throw ( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xOutputStream.is() ) + throw uno::RuntimeException(); + + if ( m_xOutputStream.is() ) + { + m_xOutputStream->closeOutput(); + m_bOutputClosed = sal_True; + } + + if ( m_bInputClosed ) + dispose(); +} + + +// XTruncate +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::truncate() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xTruncate.is() ) + throw uno::RuntimeException(); + + m_xTruncate->truncate(); +} + + +// XAsyncOutputMonitor +//----------------------------------------------- +void SAL_CALL OFSStreamContainer::waitForCompletion() + throw ( io::IOException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bDisposed ) + throw lang::DisposedException(); + + if ( !m_xStream.is() || !m_xAsyncOutputMonitor.is() ) + throw uno::RuntimeException(); + + m_xAsyncOutputMonitor->waitForCompletion(); +} + + + diff --git a/svl/source/fsstor/ostreamcontainer.hxx b/svl/source/fsstor/ostreamcontainer.hxx new file mode 100644 index 000000000000..6198587c3d35 --- /dev/null +++ b/svl/source/fsstor/ostreamcontainer.hxx @@ -0,0 +1,128 @@ +/************************************************************************* + * + * 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: ostreamcontainer.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _OSTREAMCONTAINER_HXX_ +#define _OSTREAMCONTAINER_HXX_ + +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/embed/XExtendedStorageStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XTruncate.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XStream.hpp> +#include "com/sun/star/io/XAsyncOutputMonitor.hpp" +#include <cppuhelper/weak.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <osl/mutex.hxx> + +class OFSStreamContainer : public cppu::OWeakObject, + public ::com::sun::star::lang::XTypeProvider, + public ::com::sun::star::embed::XExtendedStorageStream, + public ::com::sun::star::io::XSeekable, + public ::com::sun::star::io::XInputStream, + public ::com::sun::star::io::XOutputStream, + public ::com::sun::star::io::XTruncate, + public ::com::sun::star::io::XAsyncOutputMonitor +{ + ::osl::Mutex m_aMutex; + + ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > m_xStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XSeekable > m_xSeekable; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > m_xInputStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > m_xOutputStream; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XTruncate > m_xTruncate; + ::com::sun::star::uno::Reference< ::com::sun::star::io::XAsyncOutputMonitor > m_xAsyncOutputMonitor; + + sal_Bool m_bDisposed; + sal_Bool m_bInputClosed; + sal_Bool m_bOutputClosed; + + ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners + ::cppu::OTypeCollection* m_pTypeCollection; + +public: + OFSStreamContainer( const ::com::sun::star::uno::Reference < ::com::sun::star::io::XStream >& xStream ); + virtual ~OFSStreamContainer(); + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() + throw( ::com::sun::star::uno::RuntimeException ); + + // XStream + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream( ) throw (::com::sun::star::uno::RuntimeException); + + // XComponent + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XSeekable + virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XInputStream + virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead ) throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL available( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeInput( ) + throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XOutputStream + virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XTruncate + virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XAsyncOutputMonitor + virtual void SAL_CALL waitForCompletion( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + +}; + +#endif + diff --git a/svl/source/inc/fsfactory.hxx b/svl/source/inc/fsfactory.hxx new file mode 100644 index 000000000000..5954ecebabc2 --- /dev/null +++ b/svl/source/inc/fsfactory.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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: fsfactory.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FSFACTORY_HXX_ +#define __FSACTORY_HXX_ + +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase2.hxx> + + +class FSStorage; + +class FSStorageFactory : public ::cppu::WeakImplHelper2< ::com::sun::star::lang::XSingleServiceFactory, + ::com::sun::star::lang::XServiceInfo > +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory; + +public: + FSStorageFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory ) + : m_xFactory( xFactory ) + { + OSL_ENSURE( xFactory.is(), "No service manager is provided!\n" ); + } + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + impl_staticGetSupportedServiceNames(); + + static ::rtl::OUString SAL_CALL impl_staticGetImplementationName(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + impl_staticCreateSelfInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ); + + + // XSingleServiceFactory + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstance() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL createInstanceWithArguments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException); + +}; + +#endif + diff --git a/svl/source/inc/passwordcontainer.hxx b/svl/source/inc/passwordcontainer.hxx new file mode 100644 index 000000000000..a067672f3cf6 --- /dev/null +++ b/svl/source/inc/passwordcontainer.hxx @@ -0,0 +1,429 @@ +/************************************************************************* + * + * 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: passwordcontainer.hxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX +#define INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX + +#include <list> +#include <vector> +#include <map> +#include <com/sun/star/task/XPasswordContainer.hpp> +#include <com/sun/star/task/XUrlContainer.hpp> +#include <com/sun/star/task/PasswordRequestMode.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/task/XMasterPasswordHandling2.hpp> +#include <cppuhelper/implbase5.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/factory.hxx> + +#include <tools/stream.hxx> +#include <unotools/configitem.hxx> +#include <ucbhelper/interactionrequest.hxx> + +#include <rtl/ref.hxx> +#include <osl/mutex.hxx> + +#include "syscreds.hxx" + +#define MEMORY_RECORD 0 +#define PERSISTENT_RECORD 1 + +//---------------------------------------------------------------------------------- + +class NamePassRecord +{ + ::rtl::OUString m_aName; + + // there are two lists of passwords, memory passwords and persistent passwords + sal_Bool m_bHasMemPass; + ::std::vector< ::rtl::OUString > m_aMemPass; + + // persistent passwords are encrypted in one string + sal_Bool m_bHasPersPass; + ::rtl::OUString m_aPersPass; + + void InitArrays( sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList, + sal_Bool bHasPersistentList, const ::rtl::OUString& aPersistentList ) + { + m_bHasMemPass = bHasMemoryList; + if ( bHasMemoryList ) + m_aMemPass = aMemoryList; + + m_bHasPersPass = bHasPersistentList; + if ( bHasPersistentList ) + m_aPersPass = aPersistentList; + } + +public: + + NamePassRecord( const ::rtl::OUString& aName ) + : m_aName( aName ) + , m_bHasMemPass( sal_False ) + , m_bHasPersPass( sal_False ) + { + } + + NamePassRecord( const ::rtl::OUString& aName, const ::std::vector< ::rtl::OUString >& aMemoryList ) + : m_aName( aName ) + , m_bHasMemPass( sal_True ) + , m_aMemPass( aMemoryList ) + , m_bHasPersPass( sal_False ) + { + } + + NamePassRecord( const ::rtl::OUString& aName, const ::rtl::OUString& aPersistentList ) + : m_aName( aName ) + , m_bHasMemPass( sal_False ) + , m_bHasPersPass( sal_True ) + , m_aPersPass( aPersistentList ) + { + } + + NamePassRecord( const ::rtl::OUString& aName, + sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList, + sal_Bool bHasPersistentList, const ::rtl::OUString aPersistentList ) + : m_aName( aName ) + , m_bHasMemPass( bHasMemoryList ) + , m_bHasPersPass( bHasPersistentList ) + { + InitArrays( bHasMemoryList, aMemoryList, bHasPersistentList, aPersistentList ); + } + + NamePassRecord( const NamePassRecord& aRecord ) + : m_aName( aRecord.m_aName ) + , m_bHasMemPass( sal_False ) + , m_bHasPersPass( sal_False ) + { + InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass ); + } + + NamePassRecord& operator=( const NamePassRecord& aRecord ) + { + m_aName = aRecord.m_aName; + + m_aMemPass.clear(); + m_aPersPass = ::rtl::OUString(); + InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass ); + + return *this; + } + + ::rtl::OUString GetUserName() const + { + return m_aName; + } + + sal_Bool HasPasswords( sal_Int8 nStatus ) const + { + if ( nStatus == MEMORY_RECORD ) + return m_bHasMemPass; + if ( nStatus == PERSISTENT_RECORD ) + return m_bHasPersPass; + + return sal_False; + } + + ::std::vector< ::rtl::OUString > GetMemPasswords() const + { + if ( m_bHasMemPass ) + return m_aMemPass; + + return ::std::vector< ::rtl::OUString >(); + } + + ::rtl::OUString GetPersPasswords() const + { + if ( m_bHasPersPass ) + return m_aPersPass; + + return ::rtl::OUString(); + } + + void SetMemPasswords( const ::std::vector< ::rtl::OUString >& aMemList ) + { + m_aMemPass = aMemList; + m_bHasMemPass = sal_True; + } + + void SetPersPasswords( const ::rtl::OUString& aPersList ) + { + m_aPersPass = aPersList; + m_bHasPersPass = sal_True; + } + + void RemovePasswords( sal_Int8 nStatus ) + { + if ( nStatus == MEMORY_RECORD ) + { + m_bHasMemPass = sal_False; + m_aMemPass.clear(); + } + else if ( nStatus == PERSISTENT_RECORD ) + { + m_bHasPersPass = sal_False; + m_aPersPass = ::rtl::OUString(); + } + } + +}; + +//---------------------------------------------------------------------------------- + +typedef ::std::pair< const ::rtl::OUString, ::std::list< NamePassRecord > > PairUrlRecord; +typedef ::std::map< ::rtl::OUString, ::std::list< NamePassRecord > > PassMap; + +//---------------------------------------------------------------------------------- + +class PasswordContainer; + +class StorageItem : public ::utl::ConfigItem { + PasswordContainer* mainCont; + sal_Bool hasEncoded; + ::rtl::OUString mEncoded; +public: + StorageItem( PasswordContainer* point, const ::rtl::OUString& path ) : + ConfigItem( path, CONFIG_MODE_IMMEDIATE_UPDATE ), + mainCont( point ), + hasEncoded( sal_False ) + { + ::com::sun::star::uno::Sequence< ::rtl::OUString > aNode( 1 ); + *aNode.getArray() = path; + *aNode.getArray() += ::rtl::OUString::createFromAscii( "/Store" ); + EnableNotification( aNode ); + } + + PassMap getInfo(); + void update( const ::rtl::OUString& url, const NamePassRecord& rec ); + void remove( const ::rtl::OUString& url, const ::rtl::OUString& rec ); + void clear(); + + sal_Bool getEncodedMP( ::rtl::OUString& aResult ); + void setEncodedMP( const ::rtl::OUString& aResult, sal_Bool bAcceptEnmpty = sal_False ); + void setUseStorage( sal_Bool bUse ); + sal_Bool useStorage(); + + virtual void Notify( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames ); + virtual void Commit(); +}; + +//---------------------------------------------------------------------------------- + +enum PasswordState { + no_password, + entered, + cancelled +}; + +class PasswordContainer : public ::cppu::WeakImplHelper5< + ::com::sun::star::task::XPasswordContainer, + ::com::sun::star::task::XMasterPasswordHandling2, + ::com::sun::star::task::XUrlContainer, + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::lang::XEventListener > +{ +private: + PassMap m_aContainer; + StorageItem* m_pStorageFile; + ::osl::Mutex mMutex; + ::rtl::OUString m_aMasterPasswd; // master password is set when the string is not empty + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mComponent; + SysCredentialsConfig mUrlContainer; + + ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > CopyToUserRecordSequence( + const ::std::list< NamePassRecord >& original, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + ::com::sun::star::task::UserRecord CopyToUserRecord( + const NamePassRecord& aRecord, + sal_Bool& io_bTryToDecode, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ); + + ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > FindUsr( + const ::std::list< NamePassRecord >& userlist, + const ::rtl::OUString& name, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); +bool createUrlRecord( + const PassMap::iterator & rIter, + bool bName, + const ::rtl::OUString & aName, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler, + ::com::sun::star::task::UrlRecord & rRec ) + throw( ::com::sun::star::uno::RuntimeException ); + +::com::sun::star::task::UrlRecord find( + const ::rtl::OUString& aURL, + const ::rtl::OUString& aName, + bool bName, // only needed to support empty user names + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler ) throw(::com::sun::star::uno::RuntimeException); + + ::rtl::OUString GetDefaultMasterPassword(); + + ::rtl::OUString RequestPasswordFromUser( + ::com::sun::star::task::PasswordRequestMode aRMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ); + + ::rtl::OUString GetMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + void UpdateVector( const ::rtl::OUString& url, ::std::list< NamePassRecord >& toUpdate, NamePassRecord& rec, sal_Bool writeFile ) + throw(::com::sun::star::uno::RuntimeException); + + void PrivateAdd( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, + char aMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + ::std::vector< ::rtl::OUString > DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPassword ) + throw(::com::sun::star::uno::RuntimeException); + + ::rtl::OUString EncodePasswords( ::std::vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPassword ) + throw(::com::sun::star::uno::RuntimeException); + +public: + PasswordContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); + ~PasswordContainer(); + + virtual void SAL_CALL add( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL addPersistent( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName, + const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::task::UrlRecord SAL_CALL + find( const ::rtl::OUString& aUrl, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::task::UrlRecord SAL_CALL + findForName( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName, + const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL remove( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removePersistent( const ::rtl::OUString& aUrl, + const ::rtl::OUString& aUserName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeAllPersistent() throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::task::UrlRecord > SAL_CALL + getAllPersistent( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException); + + + // provide factory + static ::rtl::OUString SAL_CALL impl_getStaticImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + impl_getStaticSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > SAL_CALL + impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager ) throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) throw( ::com::sun::star::uno::RuntimeException ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException); + + // XMasterPasswordHandling + virtual ::sal_Bool SAL_CALL authorizateWithMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) + throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL changeMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeMasterPassword() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasMasterPassword( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL allowPersistentStoring( ::sal_Bool bAllow ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isPersistentStoringAllowed( ) throw (::com::sun::star::uno::RuntimeException); + + // XMasterPasswordHandling2 + virtual ::sal_Bool SAL_CALL useDefaultMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isDefaultMasterPasswordUsed( ) throw (::com::sun::star::uno::RuntimeException); + + // XUrlContainer + virtual void SAL_CALL addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL findUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getUrls( ::sal_Bool OnlyPersistent ) throw (::com::sun::star::uno::RuntimeException); + + void Notify(); +}; + +//---------------------------------------------------------------------------------- + +class MasterPasswordRequest_Impl : public ucbhelper::InteractionRequest +{ + ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > m_xAuthSupplier; + +public: + MasterPasswordRequest_Impl( ::com::sun::star::task::PasswordRequestMode Mode ); + + const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & + getAuthenticationSupplier() const { return m_xAuthSupplier; } + +}; + +//---------------------------------------------------------------------------------- + +class RW_SvMemoryStream : public SvMemoryStream { +public: + RW_SvMemoryStream( void* Buf, ULONG Size, StreamMode eMode ): + SvMemoryStream( Buf, Size, eMode){} + + RW_SvMemoryStream( ULONG InitSize=512, ULONG Resize=64 ): + SvMemoryStream( InitSize, Resize ){} + + ULONG getActualSize(){ return nEndOfData; } +}; + + + +#endif // #ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX + diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx new file mode 100644 index 000000000000..0018b403796f --- /dev/null +++ b/svl/source/inc/poolio.hxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * 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: poolio.hxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <svl/brdcst.hxx> + + +#ifndef DELETEZ +#define DELETEZ(pPtr) { delete pPtr; pPtr = 0; } +#endif + + +struct SfxPoolVersion_Impl +{ + USHORT _nVer; + USHORT _nStart, _nEnd; + USHORT* _pMap; + + SfxPoolVersion_Impl( USHORT nVer, USHORT nStart, USHORT nEnd, + USHORT *pMap ) + : _nVer( nVer ), + _nStart( nStart ), + _nEnd( nEnd ), + _pMap( pMap ) + {} + SfxPoolVersion_Impl( const SfxPoolVersion_Impl &rOrig ) + : _nVer( rOrig._nVer ), + _nStart( rOrig._nStart ), + _nEnd( rOrig._nEnd ), + _pMap( rOrig._pMap ) + {} +}; + +SV_DECL_PTRARR( SfxPoolItemArrayBase_Impl, SfxPoolItem*, 0, 5 ) +SV_DECL_PTRARR_DEL( SfxPoolVersionArr_Impl, SfxPoolVersion_Impl*, 0, 2 ) + +struct SfxPoolItemArray_Impl: public SfxPoolItemArrayBase_Impl +{ + USHORT nFirstFree; + + SfxPoolItemArray_Impl (USHORT nInitSize = 0) + : SfxPoolItemArrayBase_Impl( nInitSize ), + nFirstFree( 0 ) + {} +}; + +class SfxStyleSheetIterator; + +struct SfxItemPool_Impl +{ + SfxBroadcaster aBC; + SfxPoolItemArray_Impl** ppPoolItems; + SfxPoolVersionArr_Impl aVersions; + USHORT nVersion; + USHORT nLoadingVersion; + USHORT nInitRefCount; // 1, beim Laden ggf. 2 + USHORT nVerStart, nVerEnd; // WhichRange in Versions + USHORT nStoringStart, nStoringEnd; // zu speichernder Range + BYTE nMajorVer, nMinorVer; // Pool selbst + SfxMapUnit eDefMetric; + FASTBOOL bInSetItem; + FASTBOOL bStreaming; // in Load() bzw. Store() + + SfxItemPool_Impl( USHORT nStart, USHORT nEnd ) + : ppPoolItems (new SfxPoolItemArray_Impl*[ nEnd - nStart + 1]) + { + memset( ppPoolItems, 0, sizeof( SfxPoolItemArray_Impl* ) * ( nEnd - nStart + 1) ); + } + + ~SfxItemPool_Impl() + { + delete[] ppPoolItems; + } + + void DeleteItems() + { + delete[] ppPoolItems; ppPoolItems = 0; + } +}; + +// ----------------------------------------------------------------------- + +// IBM-C-Set mag keine doppelten Defines +#ifdef DBG +# undef DBG +#endif + +#if defined(DBG_UTIL) && defined(MSC) +#define SFX_TRACE(s,p) \ + { \ + ByteString aPtr(RTL_CONSTASCII_STRINGPARAM("0x0000:0x0000")); \ + _snprintf(const_cast< sal_Char *>(aPtr.GetBuffer()), aPtr.Len(), \ + "%lp", p ); \ + aPtr.Insert(s, 0); \ + DbgTrace( aPtr.GetBuffer() ); \ + } +#define DBG(x) x +#else +#define SFX_TRACE(s,p) +#define DBG(x) +#endif + +#define CHECK_FILEFORMAT( rStream, nTag ) \ + { USHORT nFileTag; \ + rStream >> nFileTag; \ + if ( nTag != nFileTag ) \ + { \ + DBG_ERROR( #nTag ); /*! s.u. */ \ + /*! error-code setzen und auswerten! */ \ + (rStream).SetError(SVSTREAM_FILEFORMAT_ERROR); \ + pImp->bStreaming = FALSE; \ + return rStream; \ + } \ + } + +#define CHECK_FILEFORMAT_RELEASE( rStream, nTag, pPointer ) \ + { USHORT nFileTag; \ + rStream >> nFileTag; \ + if ( nTag != nFileTag ) \ + { \ + DBG_ERROR( #nTag ); /*! s.u. */ \ + /*! error-code setzen und auswerten! */ \ + (rStream).SetError(SVSTREAM_FILEFORMAT_ERROR); \ + pImp->bStreaming = FALSE; \ + delete pPointer; \ + return rStream; \ + } \ + } + +#define CHECK_FILEFORMAT2( rStream, nTag1, nTag2 ) \ + { USHORT nFileTag; \ + rStream >> nFileTag; \ + if ( nTag1 != nFileTag && nTag2 != nFileTag ) \ + { \ + DBG_ERROR( #nTag1 ); /*! s.u. */ \ + /*! error-code setzen und auswerten! */ \ + (rStream).SetError(SVSTREAM_FILEFORMAT_ERROR); \ + pImp->bStreaming = FALSE; \ + return rStream; \ + } \ + } + +#define SFX_ITEMPOOL_VER_MAJOR BYTE(2) +#define SFX_ITEMPOOL_VER_MINOR BYTE(0) + +#define SFX_ITEMPOOL_TAG_STARTPOOL_4 USHORT(0x1111) +#define SFX_ITEMPOOL_TAG_STARTPOOL_5 USHORT(0xBBBB) +#define SFX_ITEMPOOL_TAG_ITEMPOOL USHORT(0xAAAA) +#define SFX_ITEMPOOL_TAG_ITEMS USHORT(0x2222) +#define SFX_ITEMPOOL_TAG_ITEM USHORT(0x7777) +#define SFX_ITEMPOOL_TAG_SIZES USHORT(0x3333) +#define SFX_ITEMPOOL_TAG_DEFAULTS USHORT(0x4444) +#define SFX_ITEMPOOL_TAG_VERSIONMAP USHORT(0x5555) +#define SFX_ITEMPOOL_TAG_HEADER USHORT(0x6666) +#define SFX_ITEMPOOL_TAG_ENDPOOL USHORT(0xEEEE) +#define SFX_ITEMPOOL_TAG_TRICK4OLD USHORT(0xFFFF) + +#define SFX_ITEMPOOL_REC BYTE(0x01) +#define SFX_ITEMPOOL_REC_HEADER BYTE(0x10) +#define SFX_ITEMPOOL_REC_VERSIONMAP USHORT(0x0020) +#define SFX_ITEMPOOL_REC_WHICHIDS USHORT(0x0030) +#define SFX_ITEMPOOL_REC_ITEMS USHORT(0x0040) +#define SFX_ITEMPOOL_REC_DEFAULTS USHORT(0x0050) + +#define SFX_ITEMSET_REC BYTE(0x02) + +#define SFX_STYLES_REC BYTE(0x03) +#define SFX_STYLES_REC_HEADER USHORT(0x0010) +#define SFX_STYLES_REC_STYLES USHORT(0x0020) + +//======================================================================== + +inline USHORT SfxItemPool::GetIndex_Impl(USHORT nWhich) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + DBG_ASSERT(nWhich >= nStart && nWhich <= nEnd, "Which-Id nicht im Pool-Bereich"); + return nWhich - nStart; +} + diff --git a/svl/source/items/aeitem.cxx b/svl/source/items/aeitem.cxx new file mode 100644 index 000000000000..55dc818d0160 --- /dev/null +++ b/svl/source/items/aeitem.cxx @@ -0,0 +1,317 @@ +/************************************************************************* + * + * 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: aeitem.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#include <tools/string.hxx> + +#define _SVSTDARR_USHORTS +#include <svl/svstdarr.hxx> +#include <svl/svarray.hxx> +#include <svl/aeitem.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxAllEnumItem) + +TYPEINIT1_AUTOFACTORY(SfxAllEnumItem, SfxEnumItem) + +// ----------------------------------------------------------------------- + +struct SfxAllEnumValue_Impl +{ + USHORT nValue; + XubString aText; +}; + +SV_DECL_PTRARR_DEL(SfxAllEnumValueArr, SfxAllEnumValue_Impl*, 0, 8) +SV_IMPL_PTRARR(SfxAllEnumValueArr, SfxAllEnumValue_Impl*) + +// ----------------------------------------------------------------------- + +SfxAllEnumItem::SfxAllEnumItem() : + SfxEnumItem(), + pValues( 0 ), + pDisabledValues( 0 ) +{ +} + +SfxAllEnumItem::SfxAllEnumItem( USHORT which, USHORT nVal, const XubString &rText ): + SfxEnumItem(which, nVal), + pValues( 0 ), + pDisabledValues( 0 ) +{ + DBG_CTOR(SfxAllEnumItem, 0); + InsertValue( nVal, rText ); +} + +// ----------------------------------------------------------------------- + +SfxAllEnumItem::SfxAllEnumItem(USHORT which, USHORT nVal): + SfxEnumItem(which, nVal), + pValues( 0 ), + pDisabledValues( 0 ) +{ + DBG_CTOR(SfxAllEnumItem, 0); + InsertValue( nVal ); +} + +// ----------------------------------------------------------------------- + +SfxAllEnumItem::SfxAllEnumItem( USHORT which, SvStream &rStream ): + SfxEnumItem(which, rStream), + pValues( 0 ), + pDisabledValues( 0 ) +{ + DBG_CTOR(SfxAllEnumItem, 0); + InsertValue( GetValue() ); +} + +// ----------------------------------------------------------------------- + + +SfxAllEnumItem::SfxAllEnumItem(USHORT which): + SfxEnumItem(which, 0), + pValues( 0 ), + pDisabledValues( 0 ) +{ + DBG_CTOR(SfxAllEnumItem, 0); +} + + +// ----------------------------------------------------------------------- + +SfxAllEnumItem::SfxAllEnumItem(const SfxAllEnumItem &rCopy): + SfxEnumItem(rCopy), + pValues(0), + pDisabledValues( 0 ) +{ + DBG_CTOR(SfxAllEnumItem, 0); + if ( !rCopy.pValues ) + return; + + pValues = new SfxAllEnumValueArr; + + for ( USHORT nPos = 0; nPos < rCopy.pValues->Count(); ++nPos ) + { + SfxAllEnumValue_Impl *pVal = new SfxAllEnumValue_Impl; + pVal->nValue = rCopy.pValues->GetObject(nPos)->nValue; + pVal->aText = rCopy.pValues->GetObject(nPos)->aText; + const SfxAllEnumValue_Impl *pTemp = pVal; + pValues->Insert( pTemp, nPos ); + } + + if( rCopy.pDisabledValues ) + { + pDisabledValues = new SvUShorts; + for ( USHORT nPos = 0; nPos < rCopy.pDisabledValues->Count(); ++nPos ) + { + pDisabledValues->Insert( rCopy.pDisabledValues->GetObject(nPos), + nPos ); + } + } +} + +// ----------------------------------------------------------------------- + +SfxAllEnumItem::~SfxAllEnumItem() +{ + DBG_DTOR(SfxAllEnumItem, 0); + delete pValues; + delete pDisabledValues; +} + +// ----------------------------------------------------------------------- + +USHORT SfxAllEnumItem::GetValueCount() const +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + return pValues ? pValues->Count() : 0; +} + +// ----------------------------------------------------------------------- + +XubString SfxAllEnumItem::GetValueTextByPos( USHORT nPos ) const +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + DBG_ASSERT( pValues && nPos < pValues->Count(), "enum overflow" ); + return pValues->GetObject(nPos)->aText; +} + +// ----------------------------------------------------------------------- + +USHORT SfxAllEnumItem::GetValueByPos( USHORT nPos ) const +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + DBG_ASSERT( pValues && nPos < pValues->Count(), "enum overflow" ); + return pValues->GetObject(nPos)->nValue; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxAllEnumItem::Clone( SfxItemPool * ) const +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + return new SfxAllEnumItem(*this); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxAllEnumItem::Create( SvStream & rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + return new SfxAllEnumItem( Which(), rStream ); +} + + +// ----------------------------------------------------------------------- + +USHORT SfxAllEnumItem::_GetPosByValue( USHORT nVal ) const + +/* [Beschreibung] + + Im Ggs. zu <SfxEnumItemInterface::GetPosByValue(USHORT)const> liefert + diese interne Methode bei nicht vorhandenen Values die Position, + an der der Wert liegen w"urde. +*/ + +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + + if ( !pValues ) + return 0; + + //!O: binaere Suche oder SortArray verwenden + USHORT nPos; + for ( nPos = 0; nPos < pValues->Count(); ++nPos ) + if ( pValues->GetObject(nPos)->nValue >= nVal ) + return nPos; + return nPos; +} + +// ----------------------------------------------------------------------- + +USHORT SfxAllEnumItem::GetPosByValue( USHORT nValue ) const + +/* [Beschreibung] + + Liefert im Gegensatz zu <SfxEnumItemInterface::GetPosByValue(USHORT)const> + immer nValue zur"uck, solange nicht mindestens ein Wert mit einer der + Methoden <SfxAllEnumItem::InsertValue()> eingef"ugt wurde. +*/ + +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + + if ( !pValues || !pValues->Count() ) + return nValue; + + return SfxEnumItem::GetPosByValue( nValue ); +} + +// ----------------------------------------------------------------------- + +void SfxAllEnumItem::InsertValue( USHORT nValue, const XubString &rValue ) +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + SfxAllEnumValue_Impl *pVal = new SfxAllEnumValue_Impl; + pVal->nValue = nValue; + pVal->aText = rValue; + const SfxAllEnumValue_Impl *pTemp = pVal; + if ( !pValues ) + pValues = new SfxAllEnumValueArr; + else if ( GetPosByValue( nValue ) != USHRT_MAX ) + // remove when exists + RemoveValue( nValue ); + // then insert + pValues->Insert( pTemp, _GetPosByValue(nValue) ); //! doppelte?! +} + +// ----------------------------------------------------------------------- + +void SfxAllEnumItem::InsertValue( USHORT nValue ) +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + SfxAllEnumValue_Impl *pVal = new SfxAllEnumValue_Impl; + pVal->nValue = nValue; + pVal->aText = XubString::CreateFromInt32( nValue ); + const SfxAllEnumValue_Impl *pTemp = pVal; + if ( !pValues ) + pValues = new SfxAllEnumValueArr; + + pValues->Insert( pTemp, _GetPosByValue(nValue) ); //! doppelte?! +} + +void SfxAllEnumItem::DisableValue( USHORT nValue ) +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + if ( !pDisabledValues ) + pDisabledValues = new SvUShorts; + + pDisabledValues->Insert( nValue, pDisabledValues->Count() ); +} + +BOOL SfxAllEnumItem::IsEnabled( USHORT nValue ) const +{ + if ( pDisabledValues ) + { + for ( USHORT i=0; i<pDisabledValues->Count(); i++ ) + if ( (*pDisabledValues)[i] == nValue ) + return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +void SfxAllEnumItem::RemoveValue( USHORT nValue ) +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + USHORT nPos = GetPosByValue(nValue); + DBG_ASSERT( nPos != USHRT_MAX, "removing value not in enum" ); + pValues->Remove( nPos ); +} + +// ----------------------------------------------------------------------- + + +void SfxAllEnumItem::RemoveAllValues() +{ + DBG_CHKTHIS(SfxAllEnumItem, 0); + if ( pValues ) + pValues->DeleteAndDestroy( 0, pValues->Count() ); +} + + + diff --git a/svl/source/items/cenumitm.cxx b/svl/source/items/cenumitm.cxx new file mode 100644 index 000000000000..3c2f7764a351 --- /dev/null +++ b/svl/source/items/cenumitm.cxx @@ -0,0 +1,297 @@ +/************************************************************************* + * + * 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: cenumitm.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <tools/stream.hxx> +#include <svl/cenumitm.hxx> +#include <whassert.hxx> + +#ifndef _CPPUHELPER_EXTRACT_HXX_ +#include <cppuhelper/extract.hxx> +#endif + +//============================================================================ +// +// class SfxEnumItemInterface +// +//============================================================================ + +DBG_NAME(SfxEnumItemInterface) + +//============================================================================ +TYPEINIT1(SfxEnumItemInterface, SfxPoolItem) + +//============================================================================ +// virtual +int SfxEnumItemInterface::operator ==(const SfxPoolItem & rItem) const +{ + SFX_ASSERT(SfxPoolItem::operator ==(rItem), Which(), "unequal type"); + return GetEnumValue() + == static_cast< const SfxEnumItemInterface * >(&rItem)-> + GetEnumValue(); +} + +//============================================================================ +// virtual +SfxItemPresentation +SfxEnumItemInterface::GetPresentation(SfxItemPresentation, SfxMapUnit, + SfxMapUnit, XubString & rText, + const IntlWrapper *) const +{ + rText = XubString::CreateFromInt32(GetEnumValue()); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL SfxEnumItemInterface::QueryValue(com::sun::star::uno::Any& rVal, BYTE) + const +{ + rVal <<= sal_Int32(GetEnumValue()); + return true; +} + +//============================================================================ +// virtual +BOOL SfxEnumItemInterface::PutValue(const com::sun::star::uno::Any& rVal, + BYTE) +{ + sal_Int32 nTheValue = 0; + + if ( ::cppu::enum2int( nTheValue, rVal ) ) + { + SetEnumValue(USHORT(nTheValue)); + return true; + } + DBG_ERROR("SfxEnumItemInterface::PutValue(): Wrong type"); + return false; +} + +//============================================================================ +XubString SfxEnumItemInterface::GetValueTextByPos(USHORT) const +{ + DBG_WARNING("SfxEnumItemInterface::GetValueTextByPos(): Pure virtual"); + return XubString(); +} + +//============================================================================ +// virtual +USHORT SfxEnumItemInterface::GetValueByPos(USHORT nPos) const +{ + return nPos; +} + +//============================================================================ +// virtual +USHORT SfxEnumItemInterface::GetPosByValue(USHORT nValue) const +{ + USHORT nCount = GetValueCount(); + for (USHORT i = 0; i < nCount; ++i) + if (GetValueByPos(i) == nValue) + return i; + return USHRT_MAX; +} + +BOOL SfxEnumItemInterface::IsEnabled(USHORT) const +{ + return TRUE; +} + +//============================================================================ +// virtual +int SfxEnumItemInterface::HasBoolValue() const +{ + return false; +} + +//============================================================================ +// virtual +BOOL SfxEnumItemInterface::GetBoolValue() const +{ + return false; +} + +//============================================================================ +// virtual +void SfxEnumItemInterface::SetBoolValue(BOOL) +{} + +//============================================================================ +// +// class CntEnumItem +// +//============================================================================ + +DBG_NAME(CntEnumItem) + +//============================================================================ +CntEnumItem::CntEnumItem(USHORT which, SvStream & rStream): + SfxEnumItemInterface(which) +{ + m_nValue = 0; + rStream >> m_nValue; +} + +//============================================================================ +TYPEINIT1(CntEnumItem, SfxEnumItemInterface) + +//============================================================================ +// virtual +SvStream & CntEnumItem::Store(SvStream & rStream, USHORT) const +{ + rStream << m_nValue; + return rStream; +} + +//============================================================================ +// virtual +USHORT CntEnumItem::GetEnumValue() const +{ + return GetValue(); +} + +//============================================================================ +// virtual +void CntEnumItem::SetEnumValue(USHORT nTheValue) +{ + SetValue(nTheValue); +} + +//============================================================================ +// +// class CntBoolItem +// +//============================================================================ + +DBG_NAME(CntBoolItem) + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntBoolItem, SfxPoolItem) + +//============================================================================ +CntBoolItem::CntBoolItem(USHORT which, SvStream & rStream): + SfxPoolItem(which) +{ + m_bValue = false; + rStream >> m_bValue; +} + +//============================================================================ +// virtual +int CntBoolItem::operator ==(const SfxPoolItem & rItem) const +{ + DBG_ASSERT(rItem.ISA(CntBoolItem), + "CntBoolItem::operator ==(): Bad type"); + return m_bValue == static_cast< CntBoolItem const * >(&rItem)->m_bValue; +} + +//============================================================================ +// virtual +int CntBoolItem::Compare(const SfxPoolItem & rWith) const +{ + DBG_ASSERT(rWith.ISA(CntBoolItem), "CntBoolItem::Compare(): Bad type"); + return m_bValue == static_cast< CntBoolItem const * >(&rWith)->m_bValue ? + 0 : m_bValue ? -1 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation CntBoolItem::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + UniString & rText, + const IntlWrapper *) const +{ + rText = GetValueTextByVal(m_bValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntBoolItem::QueryValue(com::sun::star::uno::Any& rVal, BYTE) const +{ + rVal <<= sal_Bool(m_bValue); + return true; +} + +//============================================================================ +// virtual +BOOL CntBoolItem::PutValue(const com::sun::star::uno::Any& rVal, BYTE) +{ + sal_Bool bTheValue = sal_Bool(); + if (rVal >>= bTheValue) + { + m_bValue = bTheValue; + return true; + } + DBG_ERROR("CntBoolItem::PutValue(): Wrong type"); + return false; +} + +//============================================================================ +// virtual +SfxPoolItem * CntBoolItem::Create(SvStream & rStream, USHORT) const +{ + return new CntBoolItem(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & CntBoolItem::Store(SvStream & rStream, USHORT) const +{ + rStream << m_bValue; + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * CntBoolItem::Clone(SfxItemPool *) const +{ + return new CntBoolItem(*this); +} + +//============================================================================ +// virtual +USHORT CntBoolItem::GetValueCount() const +{ + return 2; +} + +//============================================================================ +// virtual +UniString CntBoolItem::GetValueTextByVal(BOOL bTheValue) const +{ + return + bTheValue ? + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TRUE")) : + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("FALSE")); +} + diff --git a/svl/source/items/cintitem.cxx b/svl/source/items/cintitem.cxx new file mode 100644 index 000000000000..9d9d58421fc4 --- /dev/null +++ b/svl/source/items/cintitem.cxx @@ -0,0 +1,565 @@ +/************************************************************************* + * + * 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: cintitem.cxx,v $ + * $Revision: 1.10 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <tools/stream.hxx> +#include <svl/cintitem.hxx> + +//============================================================================ +// +// class CntByteItem +// +//============================================================================ + +DBG_NAME(CntByteItem) + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntByteItem, SfxPoolItem); + +//============================================================================ +CntByteItem::CntByteItem(USHORT which, SvStream & rStream): + SfxPoolItem(which) +{ + DBG_CTOR(CntByteItem, 0); + rStream >> m_nValue; +} + +//============================================================================ +// virtual +int CntByteItem::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(CntByteItem, 0); + DBG_ASSERT(rItem.ISA(CntByteItem), + "CntByteItem::operator ==(): Bad type"); + return m_nValue == SAL_STATIC_CAST(const CntByteItem *, &rItem)->m_nValue; +} + +//============================================================================ +// virtual +int CntByteItem::Compare(const SfxPoolItem & rWith) const +{ + DBG_CHKTHIS(CntByteItem, 0); + DBG_ASSERT(rWith.ISA(CntByteItem), "CntByteItem::Compare(): Bad type"); + return SAL_STATIC_CAST(const CntByteItem *, &rWith)->m_nValue < m_nValue ? + -1 : + SAL_STATIC_CAST(const CntByteItem *, &rWith)->m_nValue + == m_nValue ? + 0 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation CntByteItem::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) const +{ + DBG_CHKTHIS(CntByteItem, 0); + rText = XubString::CreateFromInt32(m_nValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntByteItem::QueryValue(com::sun::star::uno::Any& rVal,BYTE) const +{ + sal_Int8 nValue = m_nValue; + rVal <<= nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL CntByteItem::PutValue(const com::sun::star::uno::Any& rVal,BYTE) +{ + sal_Int8 nValue = sal_Int8(); + if (rVal >>= nValue) + { + m_nValue = nValue; + return TRUE; + } + + DBG_ERROR( "CntByteItem::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * CntByteItem::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(CntByteItem, 0); + short nTheValue = 0; + rStream >> nTheValue; + return new CntByteItem(Which(), BYTE(nTheValue)); +} + +//============================================================================ +// virtual +SvStream & CntByteItem::Store(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(CntByteItem, 0); + rStream << short(m_nValue); + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * CntByteItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(CntByteItem, 0); + return new CntByteItem(*this); +} + +//============================================================================ +// virtual +BYTE CntByteItem::GetMin() const +{ + DBG_CHKTHIS(CntByteItem, 0); + return 0; +} + +//============================================================================ +// virtual +BYTE CntByteItem::GetMax() const +{ + DBG_CHKTHIS(CntByteItem, 0); + return 255; +} + +//============================================================================ +// virtual +SfxFieldUnit CntByteItem::GetUnit() const +{ + DBG_CHKTHIS(CntByteItem, 0); + return SFX_FUNIT_NONE; +} + +//============================================================================ +// +// class CntUInt16Item +// +//============================================================================ + +DBG_NAME(CntUInt16Item); + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntUInt16Item, SfxPoolItem); + +//============================================================================ +CntUInt16Item::CntUInt16Item(USHORT which, SvStream & rStream) : + SfxPoolItem(which) +{ + DBG_CTOR(CntUInt16Item, 0); + USHORT nTheValue = 0; + rStream >> nTheValue; + m_nValue = nTheValue; +} + +//============================================================================ +// virtual +int CntUInt16Item::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + DBG_ASSERT(rItem.ISA(CntUInt16Item), + "CntUInt16Item::operator ==(): Bad type"); + return m_nValue == SAL_STATIC_CAST(const CntUInt16Item *, &rItem)-> + m_nValue; +} + +//============================================================================ +// virtual +int CntUInt16Item::Compare(const SfxPoolItem & rWith) const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + DBG_ASSERT(rWith.ISA(CntUInt16Item), + "CntUInt16Item::Compare(): Bad type"); + return SAL_STATIC_CAST(const CntUInt16Item *, &rWith)->m_nValue + < m_nValue ? + -1 : + SAL_STATIC_CAST(const CntUInt16Item *, &rWith)->m_nValue + == m_nValue ? + 0 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation CntUInt16Item::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) + const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + rText = XubString::CreateFromInt32(m_nValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntUInt16Item::QueryValue(com::sun::star::uno::Any& rVal,BYTE) const +{ + sal_Int32 nValue = m_nValue; + rVal <<= nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL CntUInt16Item::PutValue(const com::sun::star::uno::Any& rVal,BYTE) +{ + sal_Int32 nValue = 0; + if (rVal >>= nValue) + { + DBG_ASSERT( nValue <= USHRT_MAX, "Overflow in UInt16 value!"); + m_nValue = (sal_uInt16)nValue; + return TRUE; + } + + DBG_ERROR( "CntUInt16Item::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * CntUInt16Item::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + return new CntUInt16Item(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & CntUInt16Item::Store(SvStream &rStream, USHORT) const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + rStream << USHORT(m_nValue); + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * CntUInt16Item::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + return new CntUInt16Item(*this); +} + +//============================================================================ +// virtual +UINT16 CntUInt16Item::GetMin() const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + return 0; +} + +//============================================================================ +// virtual +UINT16 CntUInt16Item::GetMax() const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + return 65535; +} + +//============================================================================ +// virtual +SfxFieldUnit CntUInt16Item::GetUnit() const +{ + DBG_CHKTHIS(CntUInt16Item, 0); + return SFX_FUNIT_NONE; +} + +//============================================================================ +// +// class CntInt32Item +// +//============================================================================ + +DBG_NAME(CntInt32Item); + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntInt32Item, SfxPoolItem); + +//============================================================================ +CntInt32Item::CntInt32Item(USHORT which, SvStream & rStream) : + SfxPoolItem(which) +{ + DBG_CTOR(CntInt32Item, 0); + long nTheValue = 0; + rStream >> nTheValue; + m_nValue = nTheValue; +} + +//============================================================================ +// virtual +int CntInt32Item::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + DBG_ASSERT(rItem.ISA(CntInt32Item), + "CntInt32Item::operator ==(): Bad type"); + return m_nValue == SAL_STATIC_CAST(const CntInt32Item *, &rItem)-> + m_nValue; +} + +//============================================================================ +// virtual +int CntInt32Item::Compare(const SfxPoolItem & rWith) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + DBG_ASSERT(rWith.ISA(CntInt32Item), "CntInt32Item::Compare(): Bad type"); + return SAL_STATIC_CAST(const CntInt32Item *, &rWith)->m_nValue + < m_nValue ? + -1 : + SAL_STATIC_CAST(const CntInt32Item *, &rWith)->m_nValue + == m_nValue ? + 0 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation CntInt32Item::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + rText = XubString::CreateFromInt32(m_nValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntInt32Item::QueryValue(com::sun::star::uno::Any& rVal,BYTE) const +{ + sal_Int32 nValue = m_nValue; + rVal <<= nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL CntInt32Item::PutValue(const com::sun::star::uno::Any& rVal,BYTE) +{ + sal_Int32 nValue = 0; + if (rVal >>= nValue) + { + m_nValue = nValue; + return TRUE; + } + + DBG_ERROR( "CntInt32Item::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * CntInt32Item::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + return new CntInt32Item(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & CntInt32Item::Store(SvStream &rStream, USHORT) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + rStream << long(m_nValue); + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * CntInt32Item::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(CntInt32Item, 0); + return new CntInt32Item(*this); +} + +//============================================================================ +// virtual +INT32 CntInt32Item::GetMin() const +{ + DBG_CHKTHIS(CntInt32Item, 0); + return INT32(0x80000000); +} + +//============================================================================ +// virtual +INT32 CntInt32Item::GetMax() const +{ + DBG_CHKTHIS(CntInt32Item, 0); + return 0x7FFFFFFF; +} + +//============================================================================ +// virtual +SfxFieldUnit CntInt32Item::GetUnit() const +{ + DBG_CHKTHIS(CntInt32Item, 0); + return SFX_FUNIT_NONE; +} + +//============================================================================ +// +// class CntUInt32Item +// +//============================================================================ + +DBG_NAME(CntUInt32Item); + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntUInt32Item, SfxPoolItem); + +//============================================================================ +CntUInt32Item::CntUInt32Item(USHORT which, SvStream & rStream) : + SfxPoolItem(which) +{ + DBG_CTOR(CntUInt32Item, 0); + sal_uInt32 nTheValue = 0; + rStream >> nTheValue; + m_nValue = nTheValue; +} + +//============================================================================ +// virtual +int CntUInt32Item::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + DBG_ASSERT(rItem.ISA(CntUInt32Item), + "CntUInt32Item::operator ==(): Bad type"); + return m_nValue == SAL_STATIC_CAST(const CntUInt32Item *, &rItem)-> + m_nValue; +} + +//============================================================================ +// virtual +int CntUInt32Item::Compare(const SfxPoolItem & rWith) const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + DBG_ASSERT(rWith.ISA(CntUInt32Item), + "CntUInt32Item::operator ==(): Bad type"); + return SAL_STATIC_CAST(const CntUInt32Item *, &rWith)->m_nValue + < m_nValue ? + -1 : + SAL_STATIC_CAST(const CntUInt32Item *, &rWith)->m_nValue + == m_nValue ? + 0 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation CntUInt32Item::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) + const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + rText = XubString::CreateFromInt64(m_nValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntUInt32Item::QueryValue(com::sun::star::uno::Any& rVal,BYTE) const +{ + sal_Int32 nValue = m_nValue; + DBG_ASSERT( nValue>=0, "Overflow in UInt32 value!"); + rVal <<= nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL CntUInt32Item::PutValue(const com::sun::star::uno::Any& rVal,BYTE) +{ + sal_Int32 nValue = 0; + if (rVal >>= nValue) + { + DBG_ASSERT( nValue>=0, "Overflow in UInt32 value!"); + m_nValue = nValue; + return TRUE; + } + + DBG_ERROR( "CntUInt32Item::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * CntUInt32Item::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + return new CntUInt32Item(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & CntUInt32Item::Store(SvStream &rStream, USHORT) const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + rStream << static_cast<sal_uInt32>(m_nValue); + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * CntUInt32Item::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + return new CntUInt32Item(*this); +} + +//============================================================================ +// virtual +UINT32 CntUInt32Item::GetMin() const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + return 0; +} + +//============================================================================ +// virtual +UINT32 CntUInt32Item::GetMax() const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + return 0xFFFFFFFF; +} + +//============================================================================ +// virtual +SfxFieldUnit CntUInt32Item::GetUnit() const +{ + DBG_CHKTHIS(CntUInt32Item, 0); + return SFX_FUNIT_NONE; +} + diff --git a/svl/source/items/cntwall.cxx b/svl/source/items/cntwall.cxx new file mode 100644 index 000000000000..824ad6b2b5b0 --- /dev/null +++ b/svl/source/items/cntwall.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * 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: cntwall.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <tools/debug.hxx> +#include <tools/string.hxx> +#include <tools/stream.hxx> +#include <tools/vcompat.hxx> + +#include <svl/cntwall.hxx> + +#define CNTWALLPAPERITEM_STREAM_MAGIC ( (UINT32)0xfefefefe ) +#define CNTWALLPAPERITEM_STREAM_SEEKREL (-( (long)( sizeof( UINT32 ) ) ) ) + +TYPEINIT1( CntWallpaperItem, SfxPoolItem ); + +// ----------------------------------------------------------------------- +CntWallpaperItem::CntWallpaperItem( USHORT which ) + : SfxPoolItem( which ), _nColor( COL_TRANSPARENT ), _nStyle( 0 ) +{ +} + +// ----------------------------------------------------------------------- +CntWallpaperItem::CntWallpaperItem( USHORT which, SvStream& rStream, USHORT nVersion ) + : SfxPoolItem( which ), _nColor( COL_TRANSPARENT ), _nStyle( 0 ) +{ + UINT32 nMagic = 0; + rStream >> nMagic; + if ( nMagic == CNTWALLPAPERITEM_STREAM_MAGIC ) + { + // Okay, data were stored by CntWallpaperItem. + + readUnicodeString(rStream, _aURL, nVersion >= 1); + // !!! Color stream operators do not work - they discard any + // transparency info !!! + _nColor.Read( rStream, TRUE ); + rStream >> _nStyle; + } + else + { + rStream.SeekRel( CNTWALLPAPERITEM_STREAM_SEEKREL ); + + // Data were stored by SfxWallpaperItem ( SO < 6.0 ). The only + // thing we can do here is to get the URL and to position the stream. + + { + // "Read" Wallpaper member - The version compat object positions + // the stream after the wallpaper data in its dtor. We must use + // this trick here as no VCL must be used here ( No Wallpaper + // object allowed ). + VersionCompat aCompat( rStream, STREAM_READ ); + } + + // Read SfxWallpaperItem's string member _aURL. + readUnicodeString(rStream, _aURL, false); + + // "Read" SfxWallpaperItem's string member _aFilter. + ByteString aDummy; + rStream.ReadByteString(aDummy); + } +} + +// ----------------------------------------------------------------------- +CntWallpaperItem::CntWallpaperItem( const CntWallpaperItem& rItem ) : + SfxPoolItem( rItem ), + _aURL( rItem._aURL ), + _nColor( rItem._nColor ), + _nStyle( rItem._nStyle ) +{ +} + +// ----------------------------------------------------------------------- +CntWallpaperItem::~CntWallpaperItem() +{ +} + +// ----------------------------------------------------------------------- +int CntWallpaperItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + + const CntWallpaperItem& rWallItem = (const CntWallpaperItem&)rItem; + + if( ( rWallItem._nStyle == _nStyle ) && + ( rWallItem._nColor == _nColor ) && + ( rWallItem._aURL == _aURL ) ) + return TRUE; + else + return FALSE; +} + +//============================================================================ +// virtual +USHORT CntWallpaperItem::GetVersion(USHORT) const +{ + return 1; // because it uses SfxPoolItem::read/writeUnicodeString() +} + +// ----------------------------------------------------------------------- +SfxPoolItem* CntWallpaperItem::Create( SvStream& rStream, USHORT nVersion) const +{ + return new CntWallpaperItem( Which(), rStream, nVersion ); +} + +// ----------------------------------------------------------------------- +SvStream& CntWallpaperItem::Store( SvStream& rStream, USHORT ) const +{ + rStream << CNTWALLPAPERITEM_STREAM_MAGIC; + writeUnicodeString(rStream, _aURL); + // !!! Color stream operators do not work - they discard any + // transparency info !!! + // ??? Why the hell Color::Write(...) isn't const ??? + SAL_CONST_CAST( CntWallpaperItem*, this )->_nColor.Write( rStream, TRUE ); + rStream << _nStyle; + + return rStream; +} + +// ----------------------------------------------------------------------- +SfxPoolItem* CntWallpaperItem::Clone( SfxItemPool* ) const +{ + return new CntWallpaperItem( *this ); +} + +//---------------------------------------------------------------------------- +// virtual +BOOL CntWallpaperItem::QueryValue( com::sun::star::uno::Any&,BYTE ) const +{ + DBG_ERROR("Not implemented!"); + return FALSE; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL CntWallpaperItem::PutValue( const com::sun::star::uno::Any&,BYTE ) +{ + DBG_ERROR("Not implemented!"); + return FALSE; +} + + diff --git a/svl/source/items/cstitem.src b/svl/source/items/cstitem.src new file mode 100644 index 000000000000..54951dd3761e --- /dev/null +++ b/svl/source/items/cstitem.src @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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: cstitem.src,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <svl/svtools.hrc> +String STR_COLUM_DT_AUTO +{ + Text [ en-US ] = "automatic" ; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svl/source/items/ctypeitm.cxx b/svl/source/items/ctypeitm.cxx new file mode 100644 index 000000000000..69302ebdb868 --- /dev/null +++ b/svl/source/items/ctypeitm.cxx @@ -0,0 +1,254 @@ +/************************************************************************* + * + * 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: ctypeitm.cxx,v $ + * $Revision: 1.7.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/uno/Any.hxx> + +#include <unotools/intlwrapper.hxx> +#include <tools/stream.hxx> +#include <svl/ctypeitm.hxx> + +//============================================================================ +// The following defines are copied from chaos/source/items/cstritem.cxx: +#define CNTSTRINGITEM_STREAM_MAGIC ( (UINT32)0xfefefefe ) +#define CNTSTRINGITEM_STREAM_SEEKREL (-( (long)( sizeof( UINT32 ) ) ) ) + +//============================================================================ +// +// class CntContentTypeItem Implementation. +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY( CntContentTypeItem, CntUnencodedStringItem ); + +#define CONTENT_TYPE_NOT_INIT ( (INetContentType)-1 ) + +//---------------------------------------------------------------------------- +CntContentTypeItem::CntContentTypeItem() +: CntUnencodedStringItem(), + _eType( CONTENT_TYPE_NOT_INIT ) +{ +} + +//---------------------------------------------------------------------------- +CntContentTypeItem::CntContentTypeItem( USHORT which, const XubString& rType ) +: CntUnencodedStringItem( which, rType ), + _eType( CONTENT_TYPE_NOT_INIT ) +{ +} + +//---------------------------------------------------------------------------- +CntContentTypeItem::CntContentTypeItem( USHORT which, + const INetContentType eType ) +: CntUnencodedStringItem( which, INetContentTypes::GetContentType( eType ) ), + _eType( eType ) +{ +} + +//---------------------------------------------------------------------------- +CntContentTypeItem::CntContentTypeItem( const CntContentTypeItem& rOrig ) +: CntUnencodedStringItem( rOrig ), + _eType( rOrig._eType ), + _aPresentation( rOrig._aPresentation ) +{ +} + +//============================================================================ +// virtual +USHORT CntContentTypeItem::GetVersion(USHORT) const +{ + return 1; // because it uses SfxPoolItem::read/writeUnicodeString() +} + +//---------------------------------------------------------------------------- +// virtual +SfxPoolItem* CntContentTypeItem::Create( SvStream& rStream, + USHORT nItemVersion ) const +{ + // CntContentTypeItem used to be derived from CntStringItem, so take that + // into account: + UniString aValue; + readUnicodeString(rStream, aValue, nItemVersion >= 1); + UINT32 nMagic = 0; + rStream >> nMagic; + if (nMagic == CNTSTRINGITEM_STREAM_MAGIC) + { + BOOL bEncrypted = FALSE; + rStream >> bEncrypted; + DBG_ASSERT(!bEncrypted, + "CntContentTypeItem::Create() reads encrypted data"); + } + else + rStream.SeekRel(CNTSTRINGITEM_STREAM_SEEKREL); + + return new CntContentTypeItem(Which(), aValue); +} + +//---------------------------------------------------------------------------- +// virtual +SvStream & CntContentTypeItem::Store(SvStream & rStream, USHORT) const +{ + // CntContentTypeItem used to be derived from CntStringItem, so take that + // into account: + writeUnicodeString(rStream, GetValue()); + rStream << CNTSTRINGITEM_STREAM_MAGIC << BOOL(FALSE); + return rStream; +} + +//---------------------------------------------------------------------------- +// virtual +int CntContentTypeItem::operator==( const SfxPoolItem& rOrig ) const +{ + const CntContentTypeItem& rOther = (const CntContentTypeItem&)rOrig; + + if ( ( _eType != CONTENT_TYPE_NOT_INIT ) && + ( rOther._eType != CONTENT_TYPE_NOT_INIT ) ) + return _eType == rOther._eType; + else + return CntUnencodedStringItem::operator==( rOther ); +} + +//---------------------------------------------------------------------------- +// virtual +SfxPoolItem* CntContentTypeItem::Clone( SfxItemPool* /* pPool */ ) const +{ + return new CntContentTypeItem( *this ); +} + +//---------------------------------------------------------------------------- +void CntContentTypeItem::SetValue( const XubString& rNewVal ) +{ + // De-initialize enum type and presentation. + _eType = CONTENT_TYPE_NOT_INIT; + _aPresentation.Erase(); + + CntUnencodedStringItem::SetValue( rNewVal ); +} + +//---------------------------------------------------------------------------- +void CntContentTypeItem::SetPresentation( const XubString& rNewVal ) +{ + _aPresentation = rNewVal; +} + +//---------------------------------------------------------------------------- +int CntContentTypeItem::Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const +{ + String aOwnText, aWithText; + GetPresentation( SFX_ITEM_PRESENTATION_NAMELESS, + SFX_MAPUNIT_APPFONT, SFX_MAPUNIT_APPFONT, aOwnText, &rIntlWrapper ); + rWith.GetPresentation( SFX_ITEM_PRESENTATION_NAMELESS, + SFX_MAPUNIT_APPFONT, SFX_MAPUNIT_APPFONT, aWithText, &rIntlWrapper ); + return rIntlWrapper.getCollator()->compareString( aOwnText, aWithText ); +} + +//---------------------------------------------------------------------------- +SfxItemPresentation CntContentTypeItem::GetPresentation( + SfxItemPresentation ePres, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresMetric, + XubString & rText, + const IntlWrapper * pIntlWrapper) const +{ + if (_aPresentation.Len() == 0) + { + DBG_ASSERT(pIntlWrapper, + "CntContentTypeItem::GetPresentation(): No IntlWrapper"); + if (pIntlWrapper) + SAL_CONST_CAST(CntContentTypeItem *, this)->_aPresentation + = INetContentTypes::GetPresentation(GetEnumValue(), + pIntlWrapper-> + getLocale()); + } + if (_aPresentation.Len() > 0) + { + rText = _aPresentation; + return SFX_ITEM_PRESENTATION_COMPLETE; + } + else + return CntUnencodedStringItem::GetPresentation(ePres, eCoreMetric, + ePresMetric, rText, + pIntlWrapper); +} + +//---------------------------------------------------------------------------- +INetContentType CntContentTypeItem::GetEnumValue() const +{ + if ( _eType == CONTENT_TYPE_NOT_INIT ) + { + // Not yet initialized... Get enum value for string content type. + + CntContentTypeItem* pVarThis = SAL_CONST_CAST( CntContentTypeItem*, this ); + + pVarThis->_eType = INetContentTypes::GetContentType( GetValue() ); + } + + return _eType; +} + +//---------------------------------------------------------------------------- +void CntContentTypeItem::SetValue( const INetContentType eType ) +{ + SetValue( INetContentTypes::GetContentType( eType ) ); + + // Note: SetValue( const String& ....) resets _eType. Set new enum value + // after(!) calling it. + _eType = eType; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL CntContentTypeItem::QueryValue( com::sun::star::uno::Any& rVal,BYTE ) const +{ + rVal <<= rtl::OUString(GetValue()); + return true; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL CntContentTypeItem::PutValue( const com::sun::star::uno::Any& rVal,BYTE ) +{ + rtl::OUString aValue; + if ( rVal >>= aValue ) + { + // SetValue with an empty string resets the item; so call that + // function when PutValue is called with an empty string + if (aValue.getLength() == 0) + SetValue(aValue); + else + SetValue( + INetContentTypes::RegisterContentType(aValue, UniString())); + return true; + } + + DBG_ERROR( "CntContentTypeItem::PutValue - Wrong type!" ); + return false; +} diff --git a/svl/source/items/custritm.cxx b/svl/source/items/custritm.cxx new file mode 100644 index 000000000000..8687aafbae49 --- /dev/null +++ b/svl/source/items/custritm.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * 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: custritm.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/uno/Any.hxx> + +#include <unotools/intlwrapper.hxx> +#include <tools/stream.hxx> +#include <svl/custritm.hxx> + +//============================================================================ +// +// class CntUnencodedStringItem +// +//============================================================================ + +DBG_NAME(CntUnencodedStringItem) + +//============================================================================ +TYPEINIT1_AUTOFACTORY(CntUnencodedStringItem, SfxPoolItem) + +//============================================================================ +// virtual +int CntUnencodedStringItem::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(CntUnencodedStringItem, 0); + DBG_ASSERT(rItem.ISA(CntUnencodedStringItem), + "CntUnencodedStringItem::operator ==(): Bad type"); + return m_aValue + == SAL_STATIC_CAST(const CntUnencodedStringItem *, &rItem)-> + m_aValue; +} + +//============================================================================ +// virtual +int CntUnencodedStringItem::Compare(SfxPoolItem const & rWith) const +{ + DBG_ERROR("CntUnencodedStringItem::Compare(): No international"); + DBG_CHKTHIS(CntUnencodedStringItem, 0); + DBG_ASSERT(rWith.ISA(CntUnencodedStringItem), + "CntUnencodedStringItem::Compare(): Bad type"); + switch (m_aValue.CompareTo(static_cast< CntUnencodedStringItem const * >( + &rWith)-> + m_aValue)) + { + case COMPARE_LESS: + return -1; + + case COMPARE_EQUAL: + return 0; + + default: // COMPARE_GREATER + return 1; + } +} + +//============================================================================ +// virtual +int CntUnencodedStringItem::Compare(SfxPoolItem const & rWith, + IntlWrapper const & rIntlWrapper) + const +{ + DBG_CHKTHIS(CntUnencodedStringItem, 0); + DBG_ASSERT(rWith.ISA(CntUnencodedStringItem), + "CntUnencodedStringItem::Compare(): Bad type"); + return rIntlWrapper.getCollator()->compareString( m_aValue, + static_cast< CntUnencodedStringItem const * >(&rWith)->m_aValue ); +} + +//============================================================================ +// virtual +SfxItemPresentation +CntUnencodedStringItem::GetPresentation(SfxItemPresentation, SfxMapUnit, + SfxMapUnit, XubString & rText, + const IntlWrapper *) const +{ + DBG_CHKTHIS(CntUnencodedStringItem, 0); + rText = m_aValue; + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//============================================================================ +// virtual +BOOL CntUnencodedStringItem::QueryValue(com::sun::star::uno::Any& rVal, BYTE) + const +{ + rVal <<= rtl::OUString(m_aValue); + return true; +} + +//============================================================================ +// virtual +BOOL CntUnencodedStringItem::PutValue(const com::sun::star::uno::Any& rVal, + BYTE) +{ + rtl::OUString aTheValue; + if (rVal >>= aTheValue) + { + m_aValue = UniString(aTheValue); + return true; + } + DBG_ERROR("CntUnencodedStringItem::PutValue(): Wrong type"); + return false; +} + +//============================================================================ +// virtual +SfxPoolItem * CntUnencodedStringItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(CntUnencodedStringItem, 0); + return new CntUnencodedStringItem(*this); +} + diff --git a/svl/source/items/dateitem.cxx b/svl/source/items/dateitem.cxx new file mode 100644 index 000000000000..d6ef8fdc7c9e --- /dev/null +++ b/svl/source/items/dateitem.cxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * 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: dateitem.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +// include --------------------------------------------------------------- + +#define _DATETIMEITEM_CXX +#include <svl/dateitem.hxx> +#include <svl/svldata.hxx> +#include <svl/svtools.hrc> + +#include <unotools/intlwrapper.hxx> +#include <comphelper/processfactory.hxx> + +#include <tools/stream.hxx> +#include <tools/debug.hxx> +#include <tools/datetime.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <com/sun/star/lang/Locale.hpp> + + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxDateTimeItem) + + +// ----------------------------------------------------------------------- + +TYPEINIT1(SfxDateTimeItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxDateTimeItem::SfxDateTimeItem( USHORT which ) : + SfxPoolItem( which ) +{ + DBG_CTOR(SfxDateTimeItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxDateTimeItem::SfxDateTimeItem( USHORT which, const DateTime& rDT ) : + SfxPoolItem( which ), + aDateTime( rDT ) + +{ + DBG_CTOR(SfxDateTimeItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxDateTimeItem::SfxDateTimeItem( const SfxDateTimeItem& rItem ) : + SfxPoolItem( rItem ), + aDateTime( rItem.aDateTime ) +{ + DBG_CTOR(SfxDateTimeItem, 0); +} + +// ----------------------------------------------------------------------- + +int SfxDateTimeItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + return ( ( (SfxDateTimeItem&)rItem ).aDateTime == aDateTime ); +} + +// ----------------------------------------------------------------------- + +int SfxDateTimeItem::Compare( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + + // da X.Compare( Y ) am String einem Compare( Y, X ) entspricht, + // vergleichen wir hier Y mit X + if ( ( (const SfxDateTimeItem&)rItem ).aDateTime < aDateTime ) + return -1; + else if ( ( (const SfxDateTimeItem&)rItem ).aDateTime == aDateTime ) + return 0; + else + return 1; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxDateTimeItem::Create( SvStream& rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + sal_uInt32 nDate = 0; + sal_Int32 nTime = 0; + rStream >> nDate; + rStream >> nTime; + DateTime aDT(nDate, nTime); + return new SfxDateTimeItem( Which(), aDT ); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxDateTimeItem::Store( SvStream& rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + rStream << aDateTime.GetDate(); + rStream << aDateTime.GetTime(); + return rStream; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxDateTimeItem::Clone( SfxItemPool* ) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + return new SfxDateTimeItem( *this ); +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxDateTimeItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * pIntlWrapper +) const +{ + DBG_CHKTHIS(SfxDateTimeItem, 0); + if (aDateTime.IsValid()) + if (pIntlWrapper) + { + rText = pIntlWrapper->getLocaleData()->getDate(aDateTime); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += pIntlWrapper->getLocaleData()->getTime(aDateTime); + } + else + { + DBG_WARNING("SfxDateTimeItem::GetPresentation():" + " Using default en_US IntlWrapper"); + const IntlWrapper aIntlWrapper( + ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US ); + rText = aIntlWrapper.getLocaleData()->getDate(aDateTime); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += aIntlWrapper.getLocaleData()->getTime(aDateTime); + } + else + rText.Erase(); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxDateTimeItem::PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + com::sun::star::util::DateTime aValue; + if ( rVal >>= aValue ) + { + aDateTime = DateTime( Date( aValue.Day, + aValue.Month, + aValue.Year ), + Time( aValue.Hours, + aValue.Minutes, + aValue.Seconds, + aValue.HundredthSeconds ) ); + return TRUE; + } + + DBG_ERROR( "SfxDateTimeItem::PutValue - Wrong type!" ); + return FALSE; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxDateTimeItem::QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + com::sun::star::util::DateTime aValue( aDateTime.Get100Sec(), + aDateTime.GetSec(), + aDateTime.GetMin(), + aDateTime.GetHour(), + aDateTime.GetDay(), + aDateTime.GetMonth(), + aDateTime.GetYear() ); + rVal <<= aValue; + return TRUE; +} + +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- + +TYPEINIT1(SfxColumnDateTimeItem, SfxDateTimeItem); + + +SfxColumnDateTimeItem::SfxColumnDateTimeItem( USHORT which ) : + SfxDateTimeItem( which ) +{} + +SfxColumnDateTimeItem::SfxColumnDateTimeItem( USHORT which, const DateTime& rDT ) : + SfxDateTimeItem( which, rDT ) +{} + +SfxColumnDateTimeItem::SfxColumnDateTimeItem( const SfxDateTimeItem& rCpy ) : + SfxDateTimeItem( rCpy ) +{} + +SfxPoolItem* SfxColumnDateTimeItem::Clone( SfxItemPool* ) const +{ + return new SfxColumnDateTimeItem( *this ); +} + +SfxItemPresentation SfxColumnDateTimeItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * pIntlWrapper +) const +{ + DBG_ASSERT(pIntlWrapper, + "SfxColumnDateTimeItem::GetPresentation():" + " Using default en_US IntlWrapper"); + + ::com::sun::star::lang::Locale aLocale; + if (GetDateTime() == DateTime(Date(1, 2, 3), Time(3, 2, 1))) + { + rText = String(SvtSimpleResId(STR_COLUM_DT_AUTO, + pIntlWrapper ? + pIntlWrapper->getLocale() : + aLocale)); + } + else if (pIntlWrapper) + { + rText = pIntlWrapper->getLocaleData()->getDate(GetDateTime()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += pIntlWrapper->getLocaleData()->getTime(GetDateTime()); + } + else + { + const IntlWrapper aIntlWrapper( + ::comphelper::getProcessServiceFactory(), LANGUAGE_ENGLISH_US ); + rText = aIntlWrapper.getLocaleData()->getDate(GetDateTime()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += aIntlWrapper.getLocaleData()->getTime(GetDateTime()); + } + return SFX_ITEM_PRESENTATION_NAMELESS; +} + + + diff --git a/svl/source/items/eitem.cxx b/svl/source/items/eitem.cxx new file mode 100644 index 000000000000..16d5aae5a16f --- /dev/null +++ b/svl/source/items/eitem.cxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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: eitem.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/eitem.hxx> +//============================================================================ +// +// class SfxEnumItem +// +//============================================================================ + +TYPEINIT1(SfxEnumItem, CntEnumItem); + +//============================================================================ +// +// class SfxBoolItem +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxBoolItem, CntBoolItem); + + diff --git a/svl/source/items/flagitem.cxx b/svl/source/items/flagitem.cxx new file mode 100644 index 000000000000..537632db04ff --- /dev/null +++ b/svl/source/items/flagitem.cxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * 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: flagitem.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/flagitem.hxx> +#include <svl/poolitem.hxx> +#include <tools/stream.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxFlagItem) + +USHORT nSfxFlagVal[16] = +{ + 0x0001, 0x0002, 0x0004, 0x0008, + 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, + 0x1000, 0x2000, 0x4000, 0x8000 +}; + + +// ----------------------------------------------------------------------- + +TYPEINIT1(SfxFlagItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxFlagItem::SfxFlagItem( USHORT nW, USHORT nV ) : + SfxPoolItem( nW ), + nVal(nV) +{ + DBG_CTOR(SfxFlagItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxFlagItem::SfxFlagItem( USHORT nW, SvStream &rStream) : + SfxPoolItem( nW ) +{ + DBG_CTOR(SfxFlagItem, 0); + rStream >> nVal; +} + +// ----------------------------------------------------------------------- + +SfxFlagItem::SfxFlagItem( const SfxFlagItem& rItem ) : + SfxPoolItem( rItem ), + nVal( rItem.nVal ) +{ + DBG_CTOR(SfxFlagItem, 0); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxFlagItem::Store(SvStream &rStream, USHORT) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + rStream << nVal; + return rStream; +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxFlagItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + rText.Erase(); + for ( BYTE nFlag = 0; nFlag < GetFlagCount(); ++nFlag ) + rText += XubString::CreateFromInt32( GetFlag(nFlag) ); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ----------------------------------------------------------------------- + +XubString SfxFlagItem::GetFlagText( BYTE ) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + DBG_WARNING( "calling GetValueText(USHORT) on SfxFlagItem -- overload!" ); + return XubString(); +} + +// ----------------------------------------------------------------------- + +BYTE SfxFlagItem::GetFlagCount() const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + DBG_WARNING( "calling GetValueText(USHORT) on SfxFlagItem -- overload!" ); + return 0; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxFlagItem::Create(SvStream &, USHORT) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + DBG_WARNING( "calling Create() on SfxFlagItem -- overload!" ); + return 0; +} + +// ----------------------------------------------------------------------- + +int SfxFlagItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + return (((SfxFlagItem&)rItem).nVal == nVal); +} + +// ----------------------------------------------------------------------- + +void SfxFlagItem::SetFlag( BYTE nFlag, int bVal ) +{ + if ( bVal ) + nVal |= nSfxFlagVal[nFlag]; + else + nVal &= ~nSfxFlagVal[nFlag]; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxFlagItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxFlagItem, 0); + return new SfxFlagItem( *this ); +} + + + + + diff --git a/svl/source/items/globalnameitem.cxx b/svl/source/items/globalnameitem.cxx new file mode 100644 index 000000000000..1b676a95bf71 --- /dev/null +++ b/svl/source/items/globalnameitem.cxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * 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: globalnameitem.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/script/XTypeConverter.hpp> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <comphelper/processfactory.hxx> + +#include <svl/globalnameitem.hxx> + +// STATIC DATA ----------------------------------------------------------- + + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxGlobalNameItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxGlobalNameItem::SfxGlobalNameItem() +{ +} + +// ----------------------------------------------------------------------- + +SfxGlobalNameItem::SfxGlobalNameItem( USHORT nW, const SvGlobalName& rName ) +: SfxPoolItem( nW ), + m_aName( rName ) +{ +} + +// ----------------------------------------------------------------------- + +SfxGlobalNameItem::~SfxGlobalNameItem() +{ +} + +// ----------------------------------------------------------------------- + +int SfxGlobalNameItem::operator==( const SfxPoolItem& rItem ) const +{ + return ((SfxGlobalNameItem&)rItem).m_aName == m_aName; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxGlobalNameItem::Clone(SfxItemPool *) const +{ + return new SfxGlobalNameItem( *this ); +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxGlobalNameItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE ) +{ + com::sun::star::uno::Reference < com::sun::star::script::XTypeConverter > xConverter + ( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), + com::sun::star::uno::UNO_QUERY ); + com::sun::star::uno::Sequence< sal_Int8 > aSeq; + com::sun::star::uno::Any aNew; + + try { aNew = xConverter->convertTo( rVal, ::getCppuType((const com::sun::star::uno::Sequence < sal_Int8 >*)0) ); } + catch (com::sun::star::uno::Exception&) {} + aNew >>= aSeq; + if ( aSeq.getLength() == 16 ) + { + m_aName.MakeFromMemory( (void*) aSeq.getConstArray() ); + return TRUE; + } + + DBG_ERROR( "SfxGlobalNameItem::PutValue - Wrong type!" ); + return FALSE; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxGlobalNameItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE ) const +{ + com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); + void* pData = ( void* ) &m_aName.GetCLSID(); + memcpy( aSeq.getArray(), pData, 16 ); + rVal <<= aSeq; + return TRUE; +} + diff --git a/svl/source/items/ilstitem.cxx b/svl/source/items/ilstitem.cxx new file mode 100644 index 000000000000..4d2cb0a3b5b9 --- /dev/null +++ b/svl/source/items/ilstitem.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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: ilstitem.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <comphelper/processfactory.hxx> + +#include <svl/ilstitem.hxx> + +#define _SVSTDARR_ULONGS +#include <svl/svstdarr.hxx> + +TYPEINIT1_AUTOFACTORY(SfxIntegerListItem, SfxPoolItem); + +SfxIntegerListItem::SfxIntegerListItem() +{ +} + +SfxIntegerListItem::SfxIntegerListItem( USHORT which, const SvULongs& rList ) + : SfxPoolItem( which ) +{ + m_aList.realloc( rList.Count() ); + for ( USHORT n=0; n<rList.Count(); n++ ) + m_aList[n] = rList[n]; +} + +SfxIntegerListItem::SfxIntegerListItem( const SfxIntegerListItem& rItem ) + : SfxPoolItem( rItem ) +{ + m_aList = rItem.m_aList; +} + +SfxIntegerListItem::~SfxIntegerListItem() +{ +} + +int SfxIntegerListItem::operator==( const SfxPoolItem& rPoolItem ) const +{ + if ( !rPoolItem.ISA( SfxIntegerListItem ) ) + return FALSE; + + const SfxIntegerListItem rItem = (const SfxIntegerListItem&) rPoolItem; + return rItem.m_aList == m_aList; +} + +SfxPoolItem* SfxIntegerListItem::Clone( SfxItemPool * ) const +{ + return new SfxIntegerListItem( *this ); +} + +BOOL SfxIntegerListItem::PutValue ( const com::sun::star::uno::Any& rVal, BYTE ) +{ + ::com::sun::star::uno::Reference < ::com::sun::star::script::XTypeConverter > xConverter + ( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), + ::com::sun::star::uno::UNO_QUERY ); + ::com::sun::star::uno::Any aNew; + try { aNew = xConverter->convertTo( rVal, ::getCppuType((const ::com::sun::star::uno::Sequence < sal_Int32 >*)0) ); } + catch (::com::sun::star::uno::Exception&) + { + return FALSE; + } + + return ( aNew >>= m_aList ); +} + +BOOL SfxIntegerListItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE ) const +{ + rVal <<= m_aList; + return TRUE; +} + +void SfxIntegerListItem::GetList( SvULongs& rList ) const +{ + for ( sal_Int32 n=0; n<m_aList.getLength(); n++ ) + rList.Insert( m_aList[n], sal::static_int_cast< USHORT >(n) ); +} diff --git a/svl/source/items/imageitm.cxx b/svl/source/items/imageitm.cxx new file mode 100644 index 000000000000..dec2626472cc --- /dev/null +++ b/svl/source/items/imageitm.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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: imageitm.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/imageitm.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +TYPEINIT1( SfxImageItem, SfxInt16Item ); + +struct SfxImageItem_Impl +{ + String aURL; + long nAngle; + BOOL bMirrored; + int operator == ( const SfxImageItem_Impl& rOther ) const + { return nAngle == rOther.nAngle && bMirrored == rOther.bMirrored; } +}; + +//--------------------------------------------------------- + +SfxImageItem::SfxImageItem( USHORT which, UINT16 nImage ) + : SfxInt16Item( which, nImage ) +{ + pImp = new SfxImageItem_Impl; + pImp->nAngle = 0; + pImp->bMirrored = FALSE; +} + +SfxImageItem::SfxImageItem( USHORT which, const String& rURL ) + : SfxInt16Item( which, 0 ) +{ + pImp = new SfxImageItem_Impl; + pImp->nAngle = 0; + pImp->bMirrored = FALSE; + pImp->aURL = rURL; +} + +SfxImageItem::SfxImageItem( const SfxImageItem& rItem ) + : SfxInt16Item( rItem ) +{ + pImp = new SfxImageItem_Impl( *(rItem.pImp) ); +} + +//--------------------------------------------------------- +SfxImageItem::~SfxImageItem() +{ + delete pImp; +} + +//--------------------------------------------------------- + +SfxPoolItem* SfxImageItem::Clone( SfxItemPool* ) const +{ + return new SfxImageItem( *this ); +} + +//--------------------------------------------------------- + +int SfxImageItem::operator==( const SfxPoolItem& rItem ) const +{ + return( ((SfxImageItem&) rItem).GetValue() == GetValue() && (*pImp == *(((SfxImageItem&)rItem).pImp) ) ); +} + +BOOL SfxImageItem::QueryValue( com::sun::star::uno::Any& rVal, BYTE ) const +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aSeq( 4 ); + aSeq[0] = ::com::sun::star::uno::makeAny( GetValue() ); + aSeq[1] = ::com::sun::star::uno::makeAny( pImp->nAngle ); + aSeq[2] = ::com::sun::star::uno::makeAny( pImp->bMirrored ); + aSeq[3] = ::com::sun::star::uno::makeAny( rtl::OUString( pImp->aURL )); + + rVal = ::com::sun::star::uno::makeAny( aSeq ); + return TRUE; +} + +BOOL SfxImageItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE ) +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aSeq; + if (( rVal >>= aSeq ) && ( aSeq.getLength() == 4 )) + { + sal_Int16 nVal = sal_Int16(); + rtl::OUString aURL; + if ( aSeq[0] >>= nVal ) + SetValue( nVal ); + aSeq[1] >>= pImp->nAngle; + aSeq[2] >>= pImp->bMirrored; + if ( aSeq[3] >>= aURL ) + pImp->aURL = aURL; + return TRUE; + } + + return FALSE; +} + +void SfxImageItem::SetRotation( long nValue ) +{ + pImp->nAngle = nValue; +} + +long SfxImageItem::GetRotation() const +{ + return pImp->nAngle; +} + +void SfxImageItem::SetMirrored( BOOL bSet ) +{ + pImp->bMirrored = bSet; +} + +BOOL SfxImageItem::IsMirrored() const +{ + return pImp->bMirrored; +} + +String SfxImageItem::GetURL() const +{ + return pImp->aURL; +} + diff --git a/svl/source/items/intitem.cxx b/svl/source/items/intitem.cxx new file mode 100644 index 000000000000..1133cdf553d1 --- /dev/null +++ b/svl/source/items/intitem.cxx @@ -0,0 +1,261 @@ +/************************************************************************* + * + * 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: intitem.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/intitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <tools/bigint.hxx> +#include <tools/stream.hxx> +#include <svl/metitem.hxx> + +//============================================================================ +// +// class SfxByteItem +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxByteItem, CntByteItem); + +//============================================================================ +// virtual +SfxPoolItem * SfxByteItem::Create(SvStream & rStream, USHORT) const +{ + short nValue = 0; + rStream >> nValue; + return new SfxByteItem(Which(), BYTE(nValue)); +} + +//============================================================================ +// +// class SfxInt16Item +// +//============================================================================ + +DBG_NAME(SfxInt16Item); + +//============================================================================ +TYPEINIT1_AUTOFACTORY(SfxInt16Item, SfxPoolItem); + +//============================================================================ +SfxInt16Item::SfxInt16Item(USHORT which, SvStream & rStream): + SfxPoolItem(which) +{ + DBG_CTOR(SfxInt16Item, 0); + short nTheValue = 0; + rStream >> nTheValue; + m_nValue = nTheValue; +} + +//============================================================================ +// virtual +int SfxInt16Item::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + DBG_ASSERT(SfxPoolItem::operator ==(rItem), "unequal type"); + return m_nValue == SAL_STATIC_CAST(const SfxInt16Item *, &rItem)-> + m_nValue; +} + +//============================================================================ +// virtual +int SfxInt16Item::Compare(const SfxPoolItem & rWith) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + DBG_ASSERT(SfxPoolItem::operator ==(rWith), "unequal type"); + return SAL_STATIC_CAST(const SfxInt16Item *, &rWith)->m_nValue + < m_nValue ? + -1 : + SAL_STATIC_CAST(const SfxInt16Item *, &rWith)->m_nValue + == m_nValue ? + 0 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation SfxInt16Item::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + rText = UniString::CreateFromInt32(m_nValue); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + + +//============================================================================ +// virtual +BOOL SfxInt16Item::QueryValue(com::sun::star::uno::Any& rVal, BYTE) const +{ + sal_Int16 nValue = m_nValue; + rVal <<= nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL SfxInt16Item::PutValue(const com::sun::star::uno::Any& rVal, BYTE ) +{ + sal_Int16 nValue = sal_Int16(); + if (rVal >>= nValue) + { + m_nValue = nValue; + return TRUE; + } + + DBG_ERROR( "SfxInt16Item::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * SfxInt16Item::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + return new SfxInt16Item(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & SfxInt16Item::Store(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + rStream << short(m_nValue); + return rStream; +} + +//============================================================================ +SfxPoolItem * SfxInt16Item::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + return new SfxInt16Item(*this); +} + +//============================================================================ +INT16 SfxInt16Item::GetMin() const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + return -32768; +} + +//============================================================================ +INT16 SfxInt16Item::GetMax() const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + return 32767; +} + +//============================================================================ +SfxFieldUnit SfxInt16Item::GetUnit() const +{ + DBG_CHKTHIS(SfxInt16Item, 0); + return SFX_FUNIT_NONE; +} + +//============================================================================ +// +// class SfxUInt16Item +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxUInt16Item, CntUInt16Item); + + +//============================================================================ +// +// class SfxInt32Item +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxInt32Item, CntInt32Item); + + +//============================================================================ +// +// class SfxUInt32Item +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxUInt32Item, CntUInt32Item); + + +//============================================================================ +// +// class SfxMetricItem +// +//============================================================================ + +DBG_NAME(SfxMetricItem); + +//============================================================================ +TYPEINIT1_AUTOFACTORY(SfxMetricItem, SfxInt32Item); + +//============================================================================ +SfxMetricItem::SfxMetricItem(USHORT which, UINT32 nValue): + SfxInt32Item(which, nValue) +{ + DBG_CTOR(SfxMetricItem, 0); +} + +//============================================================================ +SfxMetricItem::SfxMetricItem(USHORT which, SvStream & rStream): + SfxInt32Item(which, rStream) +{ + DBG_CTOR(SfxMetricItem, 0); +} + +//============================================================================ +SfxMetricItem::SfxMetricItem(const SfxMetricItem & rItem): + SfxInt32Item(rItem) +{ + DBG_CTOR(SfxMetricItem, 0); +} + +//============================================================================ +// virtual +int SfxMetricItem::ScaleMetrics(long nMult, long nDiv) +{ + BigInt aTheValue(GetValue()); + aTheValue *= nMult; + aTheValue += nDiv / 2; + aTheValue /= nDiv; + SetValue(aTheValue); + return 1; +} + +//============================================================================ +// virtual +int SfxMetricItem::HasMetrics() const +{ + return 1; +} + diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx new file mode 100644 index 000000000000..c8c6eea67c82 --- /dev/null +++ b/svl/source/items/itemiter.cxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * 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: itemiter.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifndef GCC +#endif + +#include <svl/itemiter.hxx> +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxItemIter); + + +// -------------------------------------------------------------------------- + + +SfxItemIter::SfxItemIter( const SfxItemSet& rItemSet ) + : _rSet( rItemSet ) +{ + DBG_CTOR(SfxItemIter, 0); + DBG_ASSERTWARNING( _rSet.Count(), "es gibt gar keine Attribute" ); + + if ( !_rSet._nCount ) + { + _nStt = 1; + _nEnd = 0; + } + else + { + SfxItemArray ppFnd = _rSet._aItems; + + // suche das 1. gesetzte Item + for ( _nStt = 0; !*(ppFnd + _nStt ); ++_nStt ) + ; // empty loop + if ( 1 < _rSet.Count() ) + for( _nEnd = _rSet.TotalCount(); !*( ppFnd + --_nEnd); ) + ; // empty loop + else + _nEnd = _nStt; + } + + _nAkt = _nStt; +} + +// -------------------------------------------------------------------------- + + +SfxItemIter::~SfxItemIter() +{ + DBG_DTOR(SfxItemIter, 0); +} + +// -------------------------------------------------------------------------- + + +const SfxPoolItem* SfxItemIter::NextItem() +{ + DBG_CHKTHIS(SfxItemIter, 0); + SfxItemArray ppFnd = _rSet._aItems; + + if( _nAkt < _nEnd ) + { + do { + _nAkt++; + } while( _nAkt < _nEnd && !*(ppFnd + _nAkt ) ); + return *(ppFnd+_nAkt); + } + return 0; +} + +// -------------------------------------------------------------------------- + + +const SfxPoolItem* SfxItemIter::PrevItem() +{ + DBG_CHKTHIS(SfxItemIter, 0); + SfxItemArray ppFnd = _rSet._aItems; + + if ( _nAkt > _nStt ) + { + do { + --_nAkt; + } while( _nAkt && !*(ppFnd + _nAkt )); + return *(ppFnd+_nAkt); + } + return 0; +} + + + diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx new file mode 100644 index 000000000000..5f34560e8471 --- /dev/null +++ b/svl/source/items/itempool.cxx @@ -0,0 +1,1176 @@ +/************************************************************************* + * + * 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: itempool.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <string.h> +#include <stdio.h> +#ifndef GCC +#endif + +#include <svl/itempool.hxx> +#include "whassert.hxx" +#include <svl/brdcst.hxx> +#include <svl/smplhint.hxx> +#include "poolio.hxx" +#include <algorithm> + +// STATIC DATA ----------------------------------------------------------- + + +//======================================================================== + +SV_IMPL_PTRARR( SfxPoolVersionArr_Impl, SfxPoolVersion_Impl* ); + +//======================================================================== + + +void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser) +{ + maSfxItemPoolUsers.push_back(&rNewUser); +} + +void SfxItemPool::RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser) +{ + const SfxItemPoolUserVector::iterator aFindResult = ::std::find(maSfxItemPoolUsers.begin(), maSfxItemPoolUsers.end(), &rOldUser); + if(aFindResult != maSfxItemPoolUsers.end()) + { + maSfxItemPoolUsers.erase(aFindResult); + } +} + +const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( USHORT nWhich ) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + const SfxPoolItem* pRet; + if( IsInRange( nWhich ) ) + pRet = *(ppPoolDefaults + GetIndex_Impl( nWhich )); + else if( pSecondary ) + pRet = pSecondary->GetPoolDefaultItem( nWhich ); + else + { + SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get pool default" ); + pRet = 0; + } + return pRet; +} + +// ----------------------------------------------------------------------- + +inline FASTBOOL SfxItemPool::IsItemFlag_Impl( USHORT nPos, USHORT nFlag ) const +{ + USHORT nItemFlag = pItemInfos[nPos]._nFlags; + return nFlag == (nItemFlag & nFlag); +} + +// ----------------------------------------------------------------------- + +FASTBOOL SfxItemPool::IsItemFlag( USHORT nWhich, USHORT nFlag ) const +{ + for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pSecondary ) + { + if ( pPool->IsInRange(nWhich) ) + return pPool->IsItemFlag_Impl( pPool->GetIndex_Impl(nWhich), nFlag); + } + DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" ); + return FALSE; +} + +// ----------------------------------------------------------------------- + +SfxBroadcaster& SfxItemPool::BC() +{ + return pImp->aBC; +} + +// ----------------------------------------------------------------------- + + +SfxItemPool::SfxItemPool +( + UniString const & rName, /* Name des Pools zur Idetifikation + im File-Format */ + USHORT nStartWhich, /* erste Which-Id des Pools */ + USHORT nEndWhich, /* letzte Which-Id des Pools */ +#ifdef TF_POOLABLE + const SfxItemInfo* pInfos, /* SID-Map und Item-Flags */ +#endif + SfxPoolItem** pDefaults, /* Pointer auf statische Defaults, + wird direkt vom Pool referenziert, + jedoch kein Eigent"umer"ubergang */ +#ifndef TF_POOLABLE + USHORT* pSlotIdArray, /* Zuordnung von Slot-Ids zu Which-Ids */ +#endif + FASTBOOL bLoadRefCounts /* Ref-Counts mitladen oder auf 1 setzen */ +) + +/* [Beschreibung] + + Der im Normalfall verwendete Konstruktor der Klasse SfxItemPool. Es + wird eine SfxItemPool-Instanz initialisiert, die Items im b"undigen + Which-Bereich von 'nStartWhich' bis 'nEndWhich' verwalten kann. + + F"ur jede dieser Which-Ids mu\s ein statischer Default im Array 'pDefaults' + vorhanden sein, die dort beginnend mit einem <SfxPoolItem> mit der + Which-Id 'nStartWhich' nach Which-Ids sortiert aufeinanderfolgend + eingetragen sein m"ussen. + + 'pItemInfos' ist ein identisch angeordnetes Array von USHORTs, die + Slot-Ids darstellen und Flags. Die Slot-Ids k"onnen 0 sein, wenn die + betreffenden Items ausschlie\slich in der Core verwendet werden. + "Uber die Flags kann z.B. bestimmt werden, ob Value-Sharing + (SFX_ITEM_POOLABLE) stattfinden soll. + + [Anmerkung] + + Wenn der Pool <SfxSetItem>s enthalten soll, k"onnen im Konstruktor noch + keine static-Defaults angegeben werden. Dies mu\s dann nachtr"aglich + mit <SfxItemPool::SetDefaults(SfxItemPool**)> geschehen. + + + [Querverweise] + + <SfxItemPool::SetDefaults(SfxItemPool**)> + <SfxItemPool::ReleaseDefaults(SfxPoolItem**,USHORT,BOOL)> + <SfxItemPool::ReldaseDefaults(BOOL)> +*/ + +: aName(rName), + nStart(nStartWhich), + nEnd(nEndWhich), +#ifdef TF_POOLABLE + pItemInfos(pInfos), +#else + pSlotIds(pSlotIdArray), +#endif + pImp( new SfxItemPool_Impl( nStart, nEnd ) ), + ppStaticDefaults(0), + ppPoolDefaults(new SfxPoolItem* [ nEndWhich - nStartWhich + 1]), + pSecondary(0), + pMaster(this), + _pPoolRanges( 0 ), + bPersistentRefCounts(bLoadRefCounts), + maSfxItemPoolUsers() +{ + DBG_CTOR(SfxItemPool, 0); + DBG_ASSERT(nStart, "Start-Which-Id must be greater 0" ); + + pImp->eDefMetric = SFX_MAPUNIT_TWIP; + pImp->nVersion = 0; + pImp->bStreaming = FALSE; + pImp->nLoadingVersion = 0; + pImp->nInitRefCount = 1; + pImp->nVerStart = nStart; + pImp->nVerEnd = nEnd; + pImp->bInSetItem = FALSE; + pImp->nStoringStart = nStartWhich; + pImp->nStoringEnd = nEndWhich; + + memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1)); + + if ( pDefaults ) + SetDefaults(pDefaults); +} + +// ----------------------------------------------------------------------- + + +SfxItemPool::SfxItemPool +( + const SfxItemPool& rPool, // von dieser Instanz kopieren + BOOL bCloneStaticDefaults /* TRUE + statische Defaults kopieren + + FALSE + statische Defaults + "ubernehehmen */ +) + +/* [Beschreibung] + + Copy-Konstruktor der Klasse SfxItemPool. + + + [Querverweise] + + <SfxItemPool::Clone()const> +*/ + +: aName(rPool.aName), + nStart(rPool.nStart), + nEnd(rPool.nEnd), +#ifdef TF_POOLABLE + pItemInfos(rPool.pItemInfos), +#else + pSlotIds(rPool.pSlotIds), +#endif + pImp( new SfxItemPool_Impl( nStart, nEnd ) ), + ppStaticDefaults(0), + ppPoolDefaults(new SfxPoolItem* [ nEnd - nStart + 1]), + pSecondary(0), + pMaster(this), + _pPoolRanges( 0 ), + bPersistentRefCounts(rPool.bPersistentRefCounts ), + maSfxItemPoolUsers() +{ + DBG_CTOR(SfxItemPool, 0); + pImp->eDefMetric = rPool.pImp->eDefMetric; + pImp->nVersion = rPool.pImp->nVersion; + pImp->bStreaming = FALSE; + pImp->nLoadingVersion = 0; + pImp->nInitRefCount = 1; + pImp->nVerStart = rPool.pImp->nVerStart; + pImp->nVerEnd = rPool.pImp->nVerEnd; + pImp->bInSetItem = FALSE; + pImp->nStoringStart = nStart; + pImp->nStoringEnd = nEnd; + + memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1)); + + // Static Defaults "ubernehmen + if ( bCloneStaticDefaults ) + { + SfxPoolItem **ppDefaults = new SfxPoolItem*[nEnd-nStart+1]; + for ( USHORT n = 0; n <= nEnd - nStart; ++n ) + { + (*( ppDefaults + n )) = (*( rPool.ppStaticDefaults + n ))->Clone(this); + (*( ppDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT ); + } + + SetDefaults( ppDefaults ); + } + else + SetDefaults( rPool.ppStaticDefaults ); + + // Pool Defaults kopieren + for ( USHORT n = 0; n <= nEnd - nStart; ++n ) + if ( (*( rPool.ppPoolDefaults + n )) ) + { + (*( ppPoolDefaults + n )) = (*( rPool.ppPoolDefaults + n ))->Clone(this); + (*( ppPoolDefaults + n ))->SetKind( SFX_ITEMS_POOLDEFAULT ); + } + + // Version-Map kopieren + USHORT nVerCount = rPool.pImp->aVersions.Count(); + for ( USHORT nVer = 0; nVer < nVerCount; ++nVer ) + { + const SfxPoolVersion_Impl *pOld = rPool.pImp->aVersions.GetObject(nVer); + const SfxPoolVersion_Impl *pNew = new SfxPoolVersion_Impl( *pOld ); + pImp->aVersions.Insert( pNew, nVer ); + } + + // Verkettung wiederherstellen + if ( rPool.pSecondary ) + SetSecondaryPool( rPool.pSecondary->Clone() ); +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::SetDefaults( SfxPoolItem **pDefaults ) +{ + DBG_CHKTHIS(SfxItemPool, 0); + DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." ); + DBG_ASSERT( !ppStaticDefaults, "habe schon defaults" ); + + ppStaticDefaults = pDefaults; + //! if ( (*ppStaticDefaults)->GetKind() != SFX_ITEMS_STATICDEFAULT ) + //! geht wohl nicht im Zshg mit SetItems, die hinten stehen + { + DBG_ASSERT( (*ppStaticDefaults)->GetRefCount() == 0 || + IsDefaultItem( (*ppStaticDefaults) ), + "das sind keine statics" ); + for ( USHORT n = 0; n <= nEnd - nStart; ++n ) + { + SFX_ASSERT( (*( ppStaticDefaults + n ))->Which() == n + nStart, + n + nStart, "static defaults not sorted" ); + (*( ppStaticDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT ); + DBG_ASSERT( !(pImp->ppPoolItems[n]), "defaults with setitems with items?!" ); + } + } +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::ReleaseDefaults +( + BOOL bDelete /* TRUE + l"oscht sowohl das Array als auch die einzelnen + statischen Defaults + + FALSE + l"oscht weder das Array noch die einzelnen + statischen Defaults */ +) + +/* [Beschreibung] + + Gibt die statischen Defaults der betreffenden SfxItemPool-Instanz frei + und l"oscht ggf. die statischen Defaults. + + Nach Aufruf dieser Methode darf die SfxItemPool-Instanz nicht mehr + verwendet werden, einzig ist der Aufruf des Destruktors zu"lassig. +*/ + +{ + DBG_ASSERT( ppStaticDefaults, "keine Arme keine Kekse" ); + ReleaseDefaults( ppStaticDefaults, nEnd - nStart + 1, bDelete ); + + // KSO (22.10.98): ppStaticDefaults zeigt auf geloeschten Speicher, + // wenn bDelete == TRUE. + if ( bDelete ) + ppStaticDefaults = 0; +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::ReleaseDefaults +( + SfxPoolItem** pDefaults, /* freizugebende statische Defaults */ + + USHORT nCount, /* Anzahl der statischen Defaults */ + + BOOL bDelete /* TRUE + l"oscht sowohl das Array als auch die + einzelnen statischen Defaults + + FALSE + l"oscht weder das Array noch die + einzelnen statischen Defaults */ +) + +/* [Beschreibung] + + Gibt die angegebenen statischen Defaults frei und l"oscht ggf. + die statischen Defaults. + + Diese Methode darf erst nach Zerst"orung aller SfxItemPool-Instanzen, + welche die angegebenen statischen Defaults 'pDefault' verwenden, + aufgerufen werden. +*/ + +{ + DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." ); + + for ( USHORT n = 0; n < nCount; ++n ) + { + SFX_ASSERT( IsStaticDefaultItem( *(pDefaults+n) ), + n, "das ist kein static-default" ); + (*( pDefaults + n ))->SetRefCount( 0 ); + if ( bDelete ) + { delete *( pDefaults + n ); *(pDefaults + n) = 0; } + } + + if ( bDelete ) + { delete[] pDefaults; pDefaults = 0; } +} + +// ----------------------------------------------------------------------- + +SfxItemPool::~SfxItemPool() +{ + DBG_DTOR(SfxItemPool, 0); + DBG_ASSERT( pMaster == this, "destroying active Secondary-Pool" ); + + if ( pImp->ppPoolItems && ppPoolDefaults ) + Delete(); + delete[] _pPoolRanges; + delete pImp; +} + +void SfxItemPool::Free(SfxItemPool* pPool) +{ + if(pPool) + { + // tell all the registered SfxItemPoolUsers that the pool is in destruction + SfxItemPoolUserVector aListCopy(pPool->maSfxItemPoolUsers.begin(), pPool->maSfxItemPoolUsers.end()); + for(SfxItemPoolUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); aIterator++) + { + SfxItemPoolUser* pSfxItemPoolUser = *aIterator; + DBG_ASSERT(pSfxItemPoolUser, "corrupt SfxItemPoolUser list (!)"); + pSfxItemPoolUser->ObjectInDestruction(*pPool); + } + + // Clear the vector. This means that user do not need to call RemoveSfxItemPoolUser() + // when they get called from ObjectInDestruction(). + pPool->maSfxItemPoolUsers.clear(); + + // delete pool + delete pPool; + } +} + +// ----------------------------------------------------------------------- + + +void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool ) +{ + // ggf. an abgeh"angten Pools den Master zur"ucksetzen + if ( pSecondary ) + { +#ifdef DBG_UTIL + HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" ) + if ( ppStaticDefaults ) + { + // Delete() ist noch nicht gelaufen? + if ( pImp->ppPoolItems && pSecondary->pImp->ppPoolItems ) + { + // hat der master SetItems? + BOOL bHasSetItems = FALSE; + for ( USHORT i = 0; !bHasSetItems && i < nEnd-nStart; ++i ) + bHasSetItems = ppStaticDefaults[i]->ISA(SfxSetItem); + + // abgehaengte Pools muessen leer sein + BOOL bOK = bHasSetItems; + for ( USHORT n = 0; + bOK && n <= pSecondary->nEnd - pSecondary->nStart; + ++n ) + { + SfxPoolItemArray_Impl** ppItemArr = + pSecondary->pImp->ppPoolItems + n; + if ( *ppItemArr ) + { + SfxPoolItem** ppHtArr = + (SfxPoolItem**)(*ppItemArr)->GetData(); + for( USHORT i = (*ppItemArr)->Count(); i; ++ppHtArr, --i ) + if ( !(*ppHtArr) ) + { + DBG_ERROR( "old secondary pool must be empty" ); + bOK = FALSE; + break; + } + } + } + } + } +#endif + + pSecondary->pMaster = pSecondary; + for ( SfxItemPool *p = pSecondary->pSecondary; p; p = p->pSecondary ) + p->pMaster = pSecondary; + } + + // ggf. den Master der neuen Secondary-Pools setzen + DBG_ASSERT( !pPool || pPool->pMaster == pPool, "Secondary tanzt auf zwei Hochzeiten " ); + SfxItemPool *pNewMaster = pMaster ? pMaster : this; + for ( SfxItemPool *p = pPool; p; p = p->pSecondary ) + p->pMaster = pNewMaster; + + // neuen Secondary-Pool merken + pSecondary = pPool; +} + +// ----------------------------------------------------------------------- + +SfxMapUnit SfxItemPool::GetMetric( USHORT ) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + + return pImp->eDefMetric; +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::SetDefaultMetric( SfxMapUnit eNewMetric ) +{ + DBG_CHKTHIS(SfxItemPool, 0); + + pImp->eDefMetric = eNewMetric; +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxItemPool::GetPresentation +( + const SfxPoolItem& rItem, /* IN: <SfxPoolItem>, dessen textuelle + Wert-Darstellung geliefert werden + soll */ + SfxItemPresentation ePresent, /* IN: gew"unschte Art der Darstellung; + siehe <SfxItemPresentation> */ + SfxMapUnit eMetric, /* IN: gew"unschte Ma\seinheit der Darstellung */ + XubString& rText, /* OUT: textuelle Darstellung von 'rItem' */ + const IntlWrapper * pIntlWrapper +) const + +/* [Beschreibung] + + "Uber diese virtuelle Methode k"onnen textuelle Darstellungen der + von der jeweilige SfxItemPool-Subklasse verwalteten SfxPoolItems + angefordert werden. + + In Ableitungen sollte diese Methode "uberladen werden und auf + SfxPoolItems reagiert werden, die bei <SfxPoolItem::GetPresentation()const> + keine vollst"andige Information liefern k"onnen. + + Die Basisklasse liefert die unver"anderte Presentation von 'rItem'. +*/ + +{ + DBG_CHKTHIS(SfxItemPool, 0); + return rItem.GetPresentation( + ePresent, GetMetric(rItem.Which()), eMetric, rText, pIntlWrapper ); +} + + +// ----------------------------------------------------------------------- + +SfxItemPool* SfxItemPool::Clone() const +{ + DBG_CHKTHIS(SfxItemPool, 0); + + SfxItemPool *pPool = new SfxItemPool( *this ); + return pPool; +} + +// ---------------------------------------------------------------------- + +void SfxItemPool::Delete() +{ + DBG_CHKTHIS(SfxItemPool, 0); + + // schon deleted? + if ( !pImp->ppPoolItems || !ppPoolDefaults ) + return; + + // z.B. laufenden Requests bescheidsagen + pImp->aBC.Broadcast( SfxSimpleHint( SFX_HINT_DYING ) ); + + //MA 16. Apr. 97: Zweimal durchlaufen, in der ersten Runde fuer die SetItems. + //Der Klarheit halber wird das jetzt in zwei besser lesbare Schleifen aufgeteilt. + + SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems; + SfxPoolItem** ppDefaultItem = ppPoolDefaults; + SfxPoolItem** ppStaticDefaultItem = ppStaticDefaults; + USHORT nArrCnt; + + //Erst die SetItems abraeumen + HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" ) + if ( ppStaticDefaults ) + { + for ( nArrCnt = GetSize_Impl(); + nArrCnt; + --nArrCnt, ++ppItemArr, ++ppDefaultItem, ++ppStaticDefaultItem ) + { + // KSO (22.10.98): *ppStaticDefaultItem kann im dtor einer + // von SfxItemPool abgeleiteten Klasse bereits geloescht worden + // sein! -> CHAOS Itempool + if ( *ppStaticDefaultItem && (*ppStaticDefaultItem)->ISA(SfxSetItem) ) + { + if ( *ppItemArr ) + { + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for ( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if (*ppHtArr) + { +#ifdef DBG_UTIL + ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() ); +#endif + delete *ppHtArr; + } + DELETEZ( *ppItemArr ); + } + if ( *ppDefaultItem ) + { +#ifdef DBG_UTIL + SetRefCount( **ppDefaultItem, 0 ); +#endif + DELETEZ( *ppDefaultItem ); + } + } + } + } + + ppItemArr = pImp->ppPoolItems; + ppDefaultItem = ppPoolDefaults; + + //Jetzt die 'einfachen' Items + for ( nArrCnt = GetSize_Impl(); + nArrCnt; + --nArrCnt, ++ppItemArr, ++ppDefaultItem ) + { + if ( *ppItemArr ) + { + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for ( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if (*ppHtArr) + { +#ifdef DBG_UTIL + ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() ); +#endif + delete *ppHtArr; + } + delete *ppItemArr; + } + if ( *ppDefaultItem ) + { +#ifdef DBG_UTIL + SetRefCount( **ppDefaultItem, 0 ); +#endif + delete *ppDefaultItem; + } + } + + pImp->DeleteItems(); + delete[] ppPoolDefaults; ppPoolDefaults = 0; +} + +// ---------------------------------------------------------------------- + +void SfxItemPool::Cleanup() +{ + DBG_CHKTHIS(SfxItemPool, 0); + + //MA 16. Apr. 97: siehe ::Delete() + + SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems; + SfxPoolItem** ppDefaultItem = ppPoolDefaults; + SfxPoolItem** ppStaticDefaultItem = ppStaticDefaults; + USHORT nArrCnt; + + HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" ) + if ( ppStaticDefaults ) //HACK fuer Image, dort gibt es keine Statics!! + { + for ( nArrCnt = GetSize_Impl(); + nArrCnt; + --nArrCnt, ++ppItemArr, ++ppDefaultItem, ++ppStaticDefaultItem ) + { + //Fuer jedes Item gibt es entweder ein Default oder ein static Default! + if ( *ppItemArr && + ((*ppDefaultItem && (*ppDefaultItem)->ISA(SfxSetItem)) || + (*ppStaticDefaultItem)->ISA(SfxSetItem)) ) + { + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for ( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if ( *ppHtArr && !(*ppHtArr)->GetRefCount() ) + { + DELETEZ(*ppHtArr); + } + } + } + } + + ppItemArr = pImp->ppPoolItems; + + for ( nArrCnt = GetSize_Impl(); + nArrCnt; + --nArrCnt, ++ppItemArr ) + { + if ( *ppItemArr ) + { + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for ( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if ( *ppHtArr && !(*ppHtArr)->GetRefCount() ) + DELETEZ( *ppHtArr ); + } + } +} + +// ---------------------------------------------------------------------- + +void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem) +{ + DBG_CHKTHIS(SfxItemPool, 0); + if ( IsInRange(rItem.Which()) ) + { + SfxPoolItem **ppOldDefault = + ppPoolDefaults + GetIndex_Impl(rItem.Which()); + SfxPoolItem *pNewDefault = rItem.Clone(this); + pNewDefault->SetKind(SFX_ITEMS_POOLDEFAULT); + if ( *ppOldDefault ) + { + (*ppOldDefault)->SetRefCount(0); + DELETEZ( *ppOldDefault ); + } + *ppOldDefault = pNewDefault; + } + else if ( pSecondary ) + pSecondary->SetPoolDefaultItem(rItem); + else + { + SFX_ASSERT( 0, rItem.Which(), "unknown Which-Id - cannot set pool default" ); + } +} + +/* + * Resets the default of the given <Which-Id> back to the static default. + * If a pool default exists it is removed. + */ +void SfxItemPool::ResetPoolDefaultItem( USHORT nWhichId ) +{ + DBG_CHKTHIS(SfxItemPool, 0); + if ( IsInRange(nWhichId) ) + { + SfxPoolItem **ppOldDefault = + ppPoolDefaults + GetIndex_Impl( nWhichId ); + if ( *ppOldDefault ) + { + (*ppOldDefault)->SetRefCount(0); + DELETEZ( *ppOldDefault ); + } + } + else if ( pSecondary ) + pSecondary->ResetPoolDefaultItem(nWhichId); + else + { + SFX_ASSERT( 0, nWhichId, "unknown Which-Id - cannot set pool default" ); + } +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, USHORT nWhich ) +{ + DBG_ASSERT( !rItem.ISA(SfxSetItem) || + 0 != &((const SfxSetItem&)rItem).GetItemSet(), + "SetItem without ItemSet" ); + + DBG_CHKTHIS(SfxItemPool, 0); + if ( 0 == nWhich ) + nWhich = rItem.Which(); + + // richtigen Secondary-Pool finden + BOOL bSID = nWhich > SFX_WHICH_MAX; + if ( !bSID && !IsInRange(nWhich) ) + { + if ( pSecondary ) + return pSecondary->Put( rItem, nWhich ); + DBG_ERROR( "unknown Which-Id - cannot put item" ); + } + + // SID oder nicht poolable (neue Definition)? + USHORT nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich); + if ( USHRT_MAX == nIndex || + IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) ) + { + SFX_ASSERT( USHRT_MAX != nIndex || rItem.Which() != nWhich || + !IsDefaultItem(&rItem) || rItem.GetKind() == SFX_ITEMS_DELETEONIDLE, + nWhich, "ein nicht Pool-Item ist Default?!" ); + SfxPoolItem *pPoolItem = rItem.Clone(pMaster); + pPoolItem->SetWhich(nWhich); + AddRef( *pPoolItem ); + return *pPoolItem; + } + + SFX_ASSERT( rItem.IsA(GetDefaultItem(nWhich).Type()), nWhich, + "SFxItemPool: wrong item type in Put" ); + + SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems + nIndex; + if( !*ppItemArr ) + *ppItemArr = new SfxPoolItemArray_Impl; + + SfxPoolItem **ppFree = 0; + SfxPoolItem** ppHtArray = (SfxPoolItem**)(*ppItemArr)->GetData(); + if ( IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) ) + { + // wenn es ueberhaupt gepoolt ist, koennte es schon drin sein + if ( IsPooledItem(&rItem) ) + { + // 1. Schleife: teste ob der Pointer vorhanden ist. + for( USHORT n = (*ppItemArr)->Count(); n; ++ppHtArray, --n ) + if( &rItem == (*ppHtArray) ) + { + AddRef( **ppHtArray ); + return **ppHtArray; + } + } + + // 2. Schleife: dann muessen eben die Attribute verglichen werden + USHORT n; + for ( n = (*ppItemArr)->Count(), ppHtArray = (SfxPoolItem**)(*ppItemArr)->GetData(); + n; ++ppHtArray, --n ) + { + if ( *ppHtArray ) + { + if( **ppHtArray == rItem ) + { + AddRef( **ppHtArray ); + return **ppHtArray; + } + } + else + if ( !ppFree ) + ppFree = ppHtArray; + } + } + else + { + // freien Platz suchen + SfxPoolItem** ppHtArr; + USHORT n, nCount = (*ppItemArr)->Count(); + for ( n = (*ppItemArr)->nFirstFree, + ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData() + n; + n < nCount; + ++ppHtArr, ++n ) + if ( !*ppHtArr ) + { + ppFree = ppHtArr; + break; + } + + // naechstmoeglichen freien Platz merken + (*ppItemArr)->nFirstFree = n; + } + + // nicht vorhanden, also im PtrArray eintragen + SfxPoolItem* pNewItem = rItem.Clone(pMaster); + pNewItem->SetWhich(nWhich); +#ifdef DBG_UTIL + SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" ) +#ifdef TF_POOLABLE + if ( !rItem.ISA(SfxSetItem) ) + { + SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) || + rItem == *pNewItem, + nWhich, "unequal items in Put(): no operator==?" ); + SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) || + *pNewItem == rItem, + nWhich, "unequal items in Put(): no operator==?" ); + } +#endif +#endif + AddRef( *pNewItem, pImp->nInitRefCount ); + const SfxPoolItem* pTemp = pNewItem; + if ( !ppFree ) + (*ppItemArr)->Insert( pTemp, (*ppItemArr)->Count() ); + else + { + DBG_ASSERT( *ppFree == 0, "using surrogate in use" ); + *ppFree = pNewItem; + } + return *pNewItem; +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::Remove( const SfxPoolItem& rItem ) +{ + DBG_CHKTHIS(SfxItemPool, 0); + + DBG_ASSERT( !rItem.ISA(SfxSetItem) || + 0 != &((const SfxSetItem&)rItem).GetItemSet(), + "SetItem without ItemSet" ); + + SFX_ASSERT( !IsPoolDefaultItem(&rItem), rItem.Which(), + "wo kommt denn hier ein Pool-Default her" ); + + // richtigen Secondary-Pool finden + const USHORT nWhich = rItem.Which(); + BOOL bSID = nWhich > SFX_WHICH_MAX; + if ( !bSID && !IsInRange(nWhich) ) + { + if ( pSecondary ) + { + pSecondary->Remove( rItem ); + return; + } + DBG_ERROR( "unknown Which-Id - cannot remove item" ); + } + + // SID oder nicht poolable (neue Definition)? + USHORT nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich); + if ( bSID || IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) ) + { + SFX_ASSERT( USHRT_MAX != nIndex || + !IsDefaultItem(&rItem), rItem.Which(), + "ein nicht Pool-Item ist Default?!" ); + if ( 0 == ReleaseRef(rItem) ) + { + SfxPoolItem *pItem = &(SfxPoolItem &)rItem; + delete pItem; + } + return; + } + + SFX_ASSERT( rItem.GetRefCount(), rItem.Which(), "RefCount == 0, Remove unmoeglich" ); + + // statische Defaults sind eben einfach da + if ( rItem.GetKind() == SFX_ITEMS_STATICDEFAULT && + &rItem == *( ppStaticDefaults + GetIndex_Impl(nWhich) ) ) + return; + + // Item im eigenen Pool suchen + SfxPoolItemArray_Impl** ppItemArr = (pImp->ppPoolItems + nIndex); + SFX_ASSERT( *ppItemArr, rItem.Which(), "removing Item not in Pool" ); + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for( USHORT n = (*ppItemArr)->Count(); n; ++ppHtArr, --n ) + if( *ppHtArr == &rItem ) + { + if ( (*ppHtArr)->GetRefCount() ) //! + ReleaseRef( **ppHtArr ); + else + { + SFX_ASSERT( 0, rItem.Which(), "removing Item without ref" ); + SFX_TRACE( "to be removed, but not no refs: ", *ppHtArr ); + } + + // ggf. kleinstmoegliche freie Position merken + USHORT nPos = (*ppItemArr)->Count() - n; + if ( (*ppItemArr)->nFirstFree > nPos ) + (*ppItemArr)->nFirstFree = nPos; + + //! MI: Hack, solange wir das Problem mit dem Outliner haben + //! siehe anderes MI-REF + if ( 0 == (*ppHtArr)->GetRefCount() && nWhich < 4000 ) + DELETEZ(*ppHtArr); + return; + } + + // nicht vorhanden + SFX_ASSERT( 0, rItem.Which(), "removing Item not in Pool" ); + SFX_TRACE( "to be removed, but not in pool: ", &rItem ); +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem& SfxItemPool::GetDefaultItem( USHORT nWhich ) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + + if ( !IsInRange(nWhich) ) + { + if ( pSecondary ) + return pSecondary->GetDefaultItem( nWhich ); + SFX_ASSERT( 0, nWhich, "unknown which - dont ask me for defaults" ); + } + + DBG_ASSERT( ppStaticDefaults, "no defaults known - dont ask me for defaults" ); + USHORT nPos = GetIndex_Impl(nWhich); + SfxPoolItem *pDefault = *(ppPoolDefaults + nPos); + if ( pDefault ) + return *pDefault; + return **(ppStaticDefaults + nPos); +} + +// ----------------------------------------------------------------------- + + +void SfxItemPool::FreezeIdRanges() + +/* [Beschreibung] + + This method should be called at the master pool, when all secondary + pools are appended to it. + + It calculates the ranges of 'which-ids' for fast construction of + item-sets, which contains all 'which-ids'. +*/ + +{ + FillItemIdRanges_Impl( _pPoolRanges ); +} + + +// ----------------------------------------------------------------------- + +void SfxItemPool::FillItemIdRanges_Impl( USHORT*& pWhichRanges ) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + DBG_ASSERT( !_pPoolRanges, "GetFrozenRanges() would be faster!" ); + + const SfxItemPool *pPool; + USHORT nLevel = 0; + for( pPool = this; pPool; pPool = pPool->pSecondary ) + ++nLevel; + + pWhichRanges = new USHORT[ 2*nLevel + 1 ]; + + nLevel = 0; + for( pPool = this; pPool; pPool = pPool->pSecondary ) + { + *(pWhichRanges+(nLevel++)) = pPool->nStart; + *(pWhichRanges+(nLevel++)) = pPool->nEnd; + *(pWhichRanges+nLevel) = 0; + } +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem *SfxItemPool::GetItem(USHORT nWhich, USHORT nOfst) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + + if ( !IsInRange(nWhich) ) + { + if ( pSecondary ) + return pSecondary->GetItem( nWhich, nOfst ); + SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" ); + return 0; + } + + // dflt-Attribut? + if ( nOfst == SFX_ITEMS_STATICDEFAULT ) + return *(ppStaticDefaults + GetIndex_Impl(nWhich)); + + SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(nWhich)); + if( pItemArr && nOfst < pItemArr->Count() ) + return (*pItemArr)[nOfst]; + + return 0; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetItemCount(USHORT nWhich) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + + if ( !IsInRange(nWhich) ) + { + if ( pSecondary ) + return pSecondary->GetItemCount( nWhich ); + SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" ); + return 0; + } + + SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(nWhich)); + if ( pItemArr ) + return pItemArr->Count(); + return 0; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetWhich( USHORT nSlotId, BOOL bDeep ) const +{ + if ( !IsSlot(nSlotId) ) + return nSlotId; + +#ifdef TF_POOLABLE + USHORT nCount = nEnd - nStart + 1; + for ( USHORT nOfs = 0; nOfs < nCount; ++nOfs ) + if ( pItemInfos[nOfs]._nSID == nSlotId ) + return nOfs + nStart; +#else + if ( pSlotIds ) + { + USHORT nCount = nEnd - nStart + 1; + for ( USHORT nOfs = 0; nOfs < nCount; ++nOfs ) + if ( pSlotIds[nOfs] == nSlotId ) + return nOfs + nStart; + } +#endif + if ( pSecondary && bDeep ) + return pSecondary->GetWhich(nSlotId); + return nSlotId; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetSlotId( USHORT nWhich, BOOL bDeep ) const +{ + if ( !IsWhich(nWhich) ) + return nWhich; + + if ( !IsInRange( nWhich ) ) + { + if ( pSecondary && bDeep ) + return pSecondary->GetSlotId(nWhich); + SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" ); + return 0; + } +#ifdef TF_POOLABLE + + USHORT nSID = pItemInfos[nWhich - nStart]._nSID; + return nSID ? nSID : nWhich; +#else + else if ( pSlotIds ) + return pSlotIds[nWhich - nStart]; + return nWhich; +#endif +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetTrueWhich( USHORT nSlotId, BOOL bDeep ) const +{ + if ( !IsSlot(nSlotId) ) + return 0; + +#ifdef TF_POOLABLE + USHORT nCount = nEnd - nStart + 1; + for ( USHORT nOfs = 0; nOfs < nCount; ++nOfs ) + if ( pItemInfos[nOfs]._nSID == nSlotId ) + return nOfs + nStart; +#else + if ( pSlotIds ) + { + USHORT nCount = nEnd - nStart + 1; + for ( USHORT nOfs = 0; nOfs < nCount; ++nOfs ) + if ( pSlotIds[nOfs] == nSlotId ) + return nOfs + nStart; + } +#endif + if ( pSecondary && bDeep ) + return pSecondary->GetTrueWhich(nSlotId); + return 0; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetTrueSlotId( USHORT nWhich, BOOL bDeep ) const +{ + if ( !IsWhich(nWhich) ) + return 0; + + if ( !IsInRange( nWhich ) ) + { + if ( pSecondary && bDeep ) + return pSecondary->GetTrueSlotId(nWhich); + SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" ); + return 0; + } +#ifdef TF_POOLABLE + return pItemInfos[nWhich - nStart]._nSID; +#else + else if ( pSlotIds ) + return pSlotIds[nWhich - nStart]; + else + return 0; +#endif +} +// ----------------------------------------------------------------------- +void SfxItemPool::SetFileFormatVersion( USHORT nFileFormatVersion ) + +/* [Description] + + You must call this function to set the file format version after + concatenating your secondary-pools but before you store any + pool, itemset or item. Only set the version at the master pool, + never at any secondary pool. +*/ + +{ + DBG_ASSERT( this == pMaster, + "SfxItemPool::SetFileFormatVersion() but not a master pool" ); + for ( SfxItemPool *pPool = this; pPool; pPool = pPool->pSecondary ) + pPool->_nFileFormatVersion = nFileFormatVersion; +} + + diff --git a/svl/source/items/itemprop.cxx b/svl/source/items/itemprop.cxx new file mode 100644 index 000000000000..3add3f466495 --- /dev/null +++ b/svl/source/items/itemprop.cxx @@ -0,0 +1,506 @@ +/************************************************************************* + * + * 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: itemprop.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/itemprop.hxx> +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <hash_map> +/************************************************************************* + UNO III Implementation +*************************************************************************/ +using namespace com::sun::star; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; + +/*-- 16.02.2009 10:03:55--------------------------------------------------- + + -----------------------------------------------------------------------*/ + +struct equalOUString +{ + bool operator()(const ::rtl::OUString& r1, const ::rtl::OUString& r2) const + { + return r1.equals( r2 ); + } +}; + +typedef ::std::hash_map< ::rtl::OUString, + SfxItemPropertySimpleEntry, + ::rtl::OUStringHash, + equalOUString > SfxItemPropertyHashMap_t; + +class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t +{ +public: + mutable uno::Sequence< beans::Property > m_aPropSeq; + + SfxItemPropertyMap_Impl(){} + SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ); +}; +SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ) +{ + this->SfxItemPropertyHashMap_t::operator=( *pSource ); + m_aPropSeq = pSource->m_aPropSeq; +} + +/*-- 16.02.2009 10:03:51--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) : + m_pImpl( new SfxItemPropertyMap_Impl ) +{ + while( pEntries->pName ) + { + ::rtl::OUString sEntry(pEntries->pName, pEntries->nNameLen, RTL_TEXTENCODING_ASCII_US ); + (*m_pImpl) [ sEntry ] = pEntries; + ++pEntries; + } +} +/*-- 16.02.2009 12:46:41--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap* pSource ) : + m_pImpl( new SfxItemPropertyMap_Impl( pSource->m_pImpl ) ) +{ +} +/*-- 16.02.2009 10:03:51--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertyMap::~SfxItemPropertyMap() +{ + delete m_pImpl; +} +/*-- 16.02.2009 10:03:51--------------------------------------------------- + + -----------------------------------------------------------------------*/ +const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const ::rtl::OUString &rName ) const +{ + SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); + if( aIter == m_pImpl->end() ) + return 0; + return &aIter->second; +} + +/*-- 16.02.2009 10:44:24--------------------------------------------------- + + -----------------------------------------------------------------------*/ +uno::Sequence<beans::Property> SfxItemPropertyMap::getProperties() const +{ + if( !m_pImpl->m_aPropSeq.getLength() ) + { + m_pImpl->m_aPropSeq.realloc( m_pImpl->size() ); + beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray(); + sal_uInt32 n = 0; + SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); + while( aIt != m_pImpl->end() ) + //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap ) + { + const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; + pPropArray[n].Name = (*aIt).first; + pPropArray[n].Handle = pEntry->nWID; + if(pEntry->pType) + pPropArray[n].Type = *pEntry->pType; + pPropArray[n].Attributes = + sal::static_int_cast< sal_Int16 >(pEntry->nFlags); + n++; + ++aIt; + } + } + + return m_pImpl->m_aPropSeq; +} +/*-- 16.02.2009 11:04:31--------------------------------------------------- + + -----------------------------------------------------------------------*/ +beans::Property SfxItemPropertyMap::getPropertyByName( const ::rtl::OUString rName ) const + throw( beans::UnknownPropertyException ) +{ + SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); + if( aIter == m_pImpl->end() ) + throw UnknownPropertyException(); + const SfxItemPropertySimpleEntry* pEntry = &aIter->second; + beans::Property aProp; + aProp.Name = rName; + aProp.Handle = pEntry->nWID; + if(pEntry->pType) + aProp.Type = *pEntry->pType; + aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags); + return aProp; +} +/*-- 16.02.2009 11:09:16--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_Bool SfxItemPropertyMap::hasPropertyByName( const ::rtl::OUString& rName ) const +{ + SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); + return aIter != m_pImpl->end(); +} +/*-- 16.02.2009 11:25:14--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq ) +{ + const beans::Property* pPropArray = rPropSeq.getConstArray(); + sal_uInt32 nElements = rPropSeq.getLength(); + for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement ) + { + SfxItemPropertySimpleEntry aTemp( + sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID + &pPropArray[nElement].Type, //pType + pPropArray[nElement].Attributes, //nFlags + 0 ); //nMemberId + (*m_pImpl)[pPropArray[nElement].Name] = aTemp; + } +} +/*-- 18.02.2009 12:04:42--------------------------------------------------- + + -----------------------------------------------------------------------*/ +PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const +{ + PropertyEntryVector_t aRet; + aRet.reserve(m_pImpl->size()); + + SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); + while( aIt != m_pImpl->end() ) + { + const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; + aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) ); + ++aIt; + } + return aRet; +} +/*-- 18.02.2009 15:11:06--------------------------------------------------- + + -----------------------------------------------------------------------*/ +sal_uInt32 SfxItemPropertyMap::getSize() const +{ + return m_pImpl->size(); +} +/*-- 16.02.2009 13:44:54--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertySet::~SfxItemPropertySet() +{ +} +/* -----------------------------21.02.00 11:26-------------------------------- + + ---------------------------------------------------------------------------*/ +BOOL SfxItemPropertySet::FillItem(SfxItemSet&, USHORT, BOOL) const +{ + return FALSE; +} +/* -----------------------------06.06.01 12:32-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry, + const SfxItemSet& rSet, Any& rAny ) const + throw(RuntimeException) +{ + // get the SfxPoolItem + const SfxPoolItem* pItem = 0; + SfxItemState eState = rSet.GetItemState( rEntry.nWID, TRUE, &pItem ); + if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) + pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); + // return item values as uno::Any + if(eState >= SFX_ITEM_DEFAULT && pItem) + { + pItem->QueryValue( rAny, rEntry.nMemberId ); + } + else + { + SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); + if(FillItem(aSet, rEntry.nWID, TRUE)) + { + const SfxPoolItem& rItem = aSet.Get(rEntry.nWID); + rItem.QueryValue( rAny, rEntry.nMemberId ); + } + else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID)) + throw RuntimeException(); + } + + + // convert general SfxEnumItem values to specific values + if( rEntry.pType && TypeClass_ENUM == rEntry.pType->getTypeClass() && + rAny.getValueTypeClass() == TypeClass_LONG ) + { + INT32 nTmp = *(INT32*)rAny.getValue(); + rAny.setValue( &nTmp, *rEntry.pType ); + } +} +/* -----------------------------06.06.01 12:32-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, + const SfxItemSet& rSet, Any& rAny ) const + throw(RuntimeException, UnknownPropertyException) +{ + // detect which-id + const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); + if ( !pEntry ) + throw UnknownPropertyException(); + getPropertyValue( *pEntry,rSet, rAny ); +} +/* -----------------------------21.02.00 11:26-------------------------------- + + ---------------------------------------------------------------------------*/ +Any SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, + const SfxItemSet& rSet ) const + throw(RuntimeException, UnknownPropertyException) +{ + Any aVal; + getPropertyValue( rName,rSet, aVal ); + return aVal; +} +/* -----------------------------15.11.00 14:46-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry, + const Any& aVal, + SfxItemSet& rSet ) const + throw(RuntimeException, + IllegalArgumentException) +{ + // get the SfxPoolItem + const SfxPoolItem* pItem = 0; + SfxPoolItem *pNewItem = 0; + SfxItemState eState = rSet.GetItemState( rEntry.nWID, TRUE, &pItem ); + if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) + pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); + //maybe there's another way to find an Item + if(eState < SFX_ITEM_DEFAULT) + { + SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); + if(FillItem(aSet, rEntry.nWID, FALSE)) + { + const SfxPoolItem &rItem = aSet.Get(rEntry.nWID); + pNewItem = rItem.Clone(); + } + } + if(!pNewItem && pItem) + { + pNewItem = pItem->Clone(); + } + if(pNewItem) + { + if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) ) + { + DELETEZ(pNewItem); + throw IllegalArgumentException(); + } + // apply new item + rSet.Put( *pNewItem, rEntry.nWID ); + delete pNewItem; + } +} +/* -----------------------------21.02.00 11:26-------------------------------- + + ---------------------------------------------------------------------------*/ +void SfxItemPropertySet::setPropertyValue( const rtl::OUString &rName, + const Any& aVal, + SfxItemSet& rSet ) const + throw(RuntimeException, + IllegalArgumentException, + UnknownPropertyException) +{ + const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); + if ( !pEntry ) + { + throw UnknownPropertyException(); + } + setPropertyValue(*pEntry, aVal, rSet); +} +/* -----------------------------21.02.00 11:26-------------------------------- + + ---------------------------------------------------------------------------*/ +PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const + throw() +{ + PropertyState eRet = PropertyState_DIRECT_VALUE; + USHORT nWhich = rEntry.nWID; + + // item state holen + SfxItemState eState = rSet.GetItemState( nWhich, FALSE ); + // item-Wert als UnoAny zurueckgeben + if(eState == SFX_ITEM_DEFAULT) + eRet = PropertyState_DEFAULT_VALUE; + else if(eState < SFX_ITEM_DEFAULT) + eRet = PropertyState_AMBIGUOUS_VALUE; + return eRet; +} +PropertyState SfxItemPropertySet::getPropertyState( + const rtl::OUString& rName, const SfxItemSet& rSet) const + throw(UnknownPropertyException) +{ + PropertyState eRet = PropertyState_DIRECT_VALUE; + + // which-id ermitteln + const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); + if( !pEntry || !pEntry->nWID ) + { + throw UnknownPropertyException(); + } + USHORT nWhich = pEntry->nWID; + + // item holen + const SfxPoolItem* pItem = 0; + SfxItemState eState = rSet.GetItemState( nWhich, FALSE, &pItem ); + if(!pItem && nWhich != rSet.GetPool()->GetSlotId(nWhich)) + pItem = &rSet.GetPool()->GetDefaultItem(nWhich); + // item-Wert als UnoAny zurueckgeben + if(eState == SFX_ITEM_DEFAULT) + eRet = PropertyState_DEFAULT_VALUE; + else if(eState < SFX_ITEM_DEFAULT) + eRet = PropertyState_AMBIGUOUS_VALUE; + return eRet; +} +/* -----------------------------21.02.00 11:26-------------------------------- + + ---------------------------------------------------------------------------*/ +Reference<XPropertySetInfo> + SfxItemPropertySet::getPropertySetInfo() const +{ + if( !m_xInfo.is() ) + m_xInfo = new SfxItemPropertySetInfo( &m_aMap ); + return m_xInfo; +} +/*-- 16.02.2009 13:49:25--------------------------------------------------- + + -----------------------------------------------------------------------*/ +struct SfxItemPropertySetInfo_Impl +{ + SfxItemPropertyMap* m_pOwnMap; +}; +/*-- 16.02.2009 13:49:24--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap *pMap ) : + m_pImpl( new SfxItemPropertySetInfo_Impl ) +{ + m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pMap ); +} +/*-- 16.02.2009 13:49:25--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries ) : + m_pImpl( new SfxItemPropertySetInfo_Impl ) +{ + m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries ); +} +/* -----------------------------21.02.00 11:09-------------------------------- + + ---------------------------------------------------------------------------*/ +Sequence< Property > SAL_CALL + SfxItemPropertySetInfo::getProperties( ) + throw(RuntimeException) +{ + return m_pImpl->m_pOwnMap->getProperties(); +} +/*-- 16.02.2009 13:49:27--------------------------------------------------- + + -----------------------------------------------------------------------*/ +const SfxItemPropertyMap* SfxItemPropertySetInfo::getMap() const +{ + return m_pImpl->m_pOwnMap; +} + +/*-- 16.02.2009 12:43:36--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxItemPropertySetInfo::~SfxItemPropertySetInfo() +{ + delete m_pImpl->m_pOwnMap; + delete m_pImpl; +} +/* -----------------------------21.02.00 11:27-------------------------------- + + ---------------------------------------------------------------------------*/ +Property SAL_CALL + SfxItemPropertySetInfo::getPropertyByName( const ::rtl::OUString& rName ) + throw(UnknownPropertyException, RuntimeException) +{ + return m_pImpl->m_pOwnMap->getPropertyByName( rName ); +} +/* -----------------------------21.02.00 11:28-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool SAL_CALL + SfxItemPropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName ) + throw(RuntimeException) +{ + return m_pImpl->m_pOwnMap->hasPropertyByName( rName ); +} +/* -----------------------------21.02.00 12:03-------------------------------- + + ---------------------------------------------------------------------------*/ +SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( + const SfxItemPropertyMapEntry *pMap, + const Sequence<Property>& rPropSeq ) : + aExtMap( pMap ) +{ + aExtMap.mergeProperties( rPropSeq ); +} +/*-- 16.02.2009 12:06:49--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo() +{ +} +/* -----------------------------21.02.00 12:03-------------------------------- + + ---------------------------------------------------------------------------*/ +Sequence< Property > SAL_CALL + SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException) +{ + return aExtMap.getProperties(); +} +/* -----------------------------21.02.00 12:03-------------------------------- + + ---------------------------------------------------------------------------*/ +Property SAL_CALL +SfxExtItemPropertySetInfo::getPropertyByName( const rtl::OUString& rPropertyName ) + throw(UnknownPropertyException, RuntimeException) +{ + return aExtMap.getPropertyByName( rPropertyName ); +} +/* -----------------------------21.02.00 12:03-------------------------------- + + ---------------------------------------------------------------------------*/ +sal_Bool SAL_CALL +SfxExtItemPropertySetInfo::hasPropertyByName( const rtl::OUString& rPropertyName ) + throw(RuntimeException) +{ + return aExtMap.hasPropertyByName( rPropertyName ); +} + diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx new file mode 100644 index 000000000000..45516660ee21 --- /dev/null +++ b/svl/source/items/itemset.cxx @@ -0,0 +1,2128 @@ +/************************************************************************* + * + * 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: itemset.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <string.h> + +#if STLPORT_VERSION>=321 +#include <cstdarg> +#endif + +#ifndef GCC +#endif + +#define _SVSTDARR_USHORTS +#define _SVSTDARR_ULONGS + +#include <svl/svstdarr.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> +#include <svl/itemiter.hxx> +#include "whiter.hxx" +#include <svl/nranges.hxx> +#include "whassert.hxx" + +#include <tools/stream.hxx> +#include <tools/solar.h> + +// STATIC DATA ----------------------------------------------------------- + +static const USHORT nInitCount = 10; // einzelne USHORTs => 5 Paare ohne '0' +#ifdef DBG_UTIL +static ULONG nRangesCopyCount = 0; // wie oft wurden Ranges kopiert +#endif + +DBG_NAME(SfxItemSet) + +//======================================================================== + +#define NUMTYPE USHORT +#define SvNums SvUShorts +#define SfxNumRanges SfxUShortRanges +#include "nranges.cxx" +#undef NUMTYPE +#undef SvNums +#undef SfxNumRanges + +#define NUMTYPE ULONG +#define SvNums SvULongs +#define SfxNumRanges SfxULongRanges +#include "nranges.cxx" +#undef NUMTYPE +#undef SvNums +#undef SfxNumRanges + +//======================================================================== + +#ifdef DBG_UTIL + + +const sal_Char *DbgCheckItemSet( const void* pVoid ) +{ + const SfxItemSet *pSet = (const SfxItemSet*) pVoid; + SfxWhichIter aIter( *pSet ); + USHORT nCount = 0, n = 0; + for ( USHORT nWh = aIter.FirstWhich(); nWh; nWh = aIter.NextWhich(), ++n ) + { + const SfxPoolItem *pItem = pSet->_aItems[n]; + if ( pItem ) + { + ++nCount; + DBG_ASSERT( IsInvalidItem(pItem) || + pItem->Which() == 0 || pItem->Which() == nWh, + "SfxItemSet: invalid which-id" ); + DBG_ASSERT( IsInvalidItem(pItem) || !pItem->Which() || + !SfxItemPool::IsWhich(pItem->Which()) || + pSet->GetPool()->IsItemFlag(nWh, SFX_ITEM_NOT_POOLABLE) || + SFX_ITEMS_NULL != pSet->GetPool()->GetSurrogate(pItem), + "SfxItemSet: item in set which is not in pool" ); + } + + } + DBG_ASSERT( pSet->_nCount == nCount, "wrong SfxItemSet::nCount detected" ); + + return 0; +} + +#endif +// ----------------------------------------------------------------------- + +SfxItemSet::SfxItemSet +( + SfxItemPool& rPool, /* der Pool, in dem die SfxPoolItems, + welche in dieses SfxItemSet gelangen, + aufgenommen werden sollen */ + BOOL +#ifdef DBG_UTIL +#ifdef SFX_ITEMSET_NO_DEFAULT_CTOR + + bTotalRanges /* komplette Pool-Ranges uebernehmen, + muss auf TRUE gesetzt werden */ +#endif +#endif +) +/* [Beschreibung] + + Konstruktor fuer ein SfxItemSet mit genau den Which-Bereichen, welche + dem angegebenen <SfxItemPool> bekannt sind. + + + [Anmerkung] + + F"ur Sfx-Programmierer ein derart konstruiertes SfxItemSet kann + keinerlei Items mit Slot-Ids als Which-Werte aufnehmen! +*/ + +: _pPool( &rPool ), + _pParent( 0 ), + _nCount( 0 ) +{ + DBG_CTOR(SfxItemSet, DbgCheckItemSet); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + DBG( _pChildCountCtor; *_pChildCount(this) = 0 ); +// DBG_ASSERT( bTotalRanges || abs( &bTotalRanges - this ) < 1000, +// "please use suitable ranges" ); +#ifdef DBG_UTIL +#ifdef SFX_ITEMSET_NO_DEFAULT_CTOR + if ( !bTotalRanges ) + *(int*)0 = 0; // GPF +#endif +#endif + + _pWhichRanges = (USHORT*) _pPool->GetFrozenIdRanges(); + DBG_ASSERT( _pWhichRanges, "don't create ItemSets with full range before FreezeIdRanges()" ); + if ( !_pWhichRanges ) + _pPool->FillItemIdRanges_Impl( _pWhichRanges ); + + const USHORT nSize = TotalCount(); + _aItems = new const SfxPoolItem* [ nSize ]; + memset( (void*) _aItems, 0, nSize * sizeof( SfxPoolItem* ) ); +} + +// ----------------------------------------------------------------------- + +SfxItemSet::SfxItemSet( SfxItemPool& rPool, USHORT nWhich1, USHORT nWhich2 ): + _pPool( &rPool ), + _pParent( 0 ), + _nCount( 0 ) +{ + DBG_CTOR(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( nWhich1 <= nWhich2, "Ungueltiger Bereich" ); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + DBG( _pChildCountCtor; *_pChildCount(this) = 0 ); + + InitRanges_Impl(nWhich1, nWhich2); +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::InitRanges_Impl(USHORT nWh1, USHORT nWh2) +{ + DBG_CHKTHIS(SfxItemSet, 0); + _pWhichRanges = new USHORT[ 3 ]; + *(_pWhichRanges+0) = nWh1; + *(_pWhichRanges+1) = nWh2; + *(_pWhichRanges+2) = 0; + const USHORT nRg = nWh2 - nWh1 + 1; + _aItems = new const SfxPoolItem* [ nRg ]; + memset( (void*) _aItems, 0, nRg * sizeof( SfxPoolItem* ) ); +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::InitRanges_Impl(va_list pArgs, USHORT nWh1, USHORT nWh2, USHORT nNull) +{ + DBG_CHKTHIS(SfxItemSet, 0); + + USHORT nSize = InitializeRanges_Impl( _pWhichRanges, pArgs, nWh1, nWh2, nNull ); + _aItems = new const SfxPoolItem* [ nSize ]; + memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nSize ); +} + +// ----------------------------------------------------------------------- + +SfxItemSet::SfxItemSet( SfxItemPool& rPool, + USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ... ): + _pPool( &rPool ), + _pParent( 0 ), + _pWhichRanges( 0 ), + _nCount( 0 ) +{ + DBG_CTOR(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" ); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + DBG( _pChildCountCtor; *_pChildCount(this) = 0 ); + + if(!nNull) + InitRanges_Impl( + sal::static_int_cast< USHORT >(nWh1), + sal::static_int_cast< USHORT >(nWh2)); + else { + va_list pArgs; + va_start( pArgs, nNull ); + InitRanges_Impl( + pArgs, sal::static_int_cast< USHORT >(nWh1), + sal::static_int_cast< USHORT >(nWh2), + sal::static_int_cast< USHORT >(nNull)); + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::InitRanges_Impl(const USHORT *pWhichPairTable) +{ + DBG_CHKTHIS(SfxItemSet, 0); + DBG_TRACE1("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount); + + USHORT nCnt = 0; + const USHORT* pPtr = pWhichPairTable; + while( *pPtr ) + { + nCnt += ( *(pPtr+1) - *pPtr ) + 1; + pPtr += 2; + } + + _aItems = new const SfxPoolItem* [ nCnt ]; + memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nCnt ); + + std::ptrdiff_t cnt = pPtr - pWhichPairTable +1; + _pWhichRanges = new USHORT[ cnt ]; + memcpy( _pWhichRanges, pWhichPairTable, sizeof( USHORT ) * cnt ); +} + + +// ----------------------------------------------------------------------- + +SfxItemSet::SfxItemSet( SfxItemPool& rPool, const USHORT* pWhichPairTable ): + _pPool( &rPool ), + _pParent( 0 ), + _pWhichRanges(0), + _nCount( 0 ) +{ + DBG_CTOR(SfxItemSet, 0); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + DBG( _pChildCountCtor; *_pChildCount(this) = 0 ); + + // pWhichPairTable == 0 ist f"ur das SfxAllEnumItemSet + if ( pWhichPairTable ) + InitRanges_Impl(pWhichPairTable); +} + +// ----------------------------------------------------------------------- + +SfxItemSet::SfxItemSet( const SfxItemSet& rASet ): + _pPool( rASet._pPool ), + _pParent( rASet._pParent ), + _nCount( rASet._nCount ) +{ + DBG_CTOR(SfxItemSet, DbgCheckItemSet); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + DBG( _pChildCountCtor; *_pChildCount(this) = 0 ); + DBG( ++*_pChildCount(_pParent) ); + + // errechne die Anzahl von Attributen + USHORT nCnt = 0; + USHORT* pPtr = rASet._pWhichRanges; + while( *pPtr ) + { + nCnt += ( *(pPtr+1) - *pPtr ) + 1; + pPtr += 2; + } + + _aItems = new const SfxPoolItem* [ nCnt ]; + + // Attribute kopieren + SfxItemArray ppDst = _aItems, ppSrc = rASet._aItems; + for( USHORT n = nCnt; n; --n, ++ppDst, ++ppSrc ) + if ( 0 == *ppSrc || // aktueller Default? + IsInvalidItem(*ppSrc) || // Dont Care? + IsStaticDefaultItem(*ppSrc) ) // nicht zu poolende Defaults + // einfach Pointer kopieren + *ppDst = *ppSrc; + else if ( _pPool->IsItemFlag( **ppSrc, SFX_ITEM_POOLABLE ) ) + { + // einfach Pointer kopieren und Ref-Count erh"ohen + *ppDst = *ppSrc; + ( (SfxPoolItem*) (*ppDst) )->AddRef(); + } + else if ( !(*ppSrc)->Which() ) + *ppDst = (*ppSrc)->Clone(); + else + // !IsPoolable() => via Pool zuweisen + *ppDst = &_pPool->Put( **ppSrc ); + + // dann noch die Which Ranges kopieren + DBG_TRACE1("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount); + std::ptrdiff_t cnt = pPtr - rASet._pWhichRanges+1; + _pWhichRanges = new USHORT[ cnt ]; + memcpy( _pWhichRanges, rASet._pWhichRanges, sizeof( USHORT ) * cnt); +} + +// ----------------------------------------------------------------------- + +SfxItemSet::~SfxItemSet() +{ + DBG_DTOR(SfxItemSet, DbgCheckItemSet); +#ifdef DBG_UTIL + DBG( DBG_ASSERT( 0 == *_pChildCount(this), "SfxItemSet: deleting parent-itemset" ) ) +#endif + + USHORT nCount = TotalCount(); + if( Count() ) + { + SfxItemArray ppFnd = _aItems; + for( USHORT nCnt = nCount; nCnt; --nCnt, ++ppFnd ) + if( *ppFnd && !IsInvalidItem(*ppFnd) ) + { + if( !(*ppFnd)->Which() ) + delete (SfxPoolItem*) *ppFnd; + else { + // noch mehrer Referenzen vorhanden, also nur den + // ReferenzCounter manipulieren + if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) ) + (*ppFnd)->ReleaseRef(); + else + if ( !IsDefaultItem(*ppFnd) ) + // aus dem Pool loeschen + _pPool->Remove( **ppFnd ); + } + } + } + + // FIXME: could be delete[] (SfxPoolItem **)_aItems; + delete[] _aItems; + if ( _pWhichRanges != _pPool->GetFrozenIdRanges() ) + delete[] _pWhichRanges; + _pWhichRanges = 0; // for invariant-testing + + DBG( --*_pChildCount(_pParent) ); + DBG( delete _pChildCount(this); _pChildCountDtor ); +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemSet::ClearItem( USHORT nWhich ) + +// einzelnes Item oder alle Items (nWhich==0) l"oschen + +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + if( !Count() ) + return 0; + + USHORT nDel = 0; + SfxItemArray ppFnd = _aItems; + + if( nWhich ) + { + const USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + // in diesem Bereich? + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // "uberhaupt gesetzt? + ppFnd += nWhich - *pPtr; + if( *ppFnd ) + { + // wegen der Assertions ins Sub-Calls mu\s das hier sein + --_nCount; + const SfxPoolItem *pItemToClear = *ppFnd; + *ppFnd = 0; + + if ( !IsInvalidItem(pItemToClear) ) + { + if ( nWhich <= SFX_WHICH_MAX ) + { + const SfxPoolItem& rNew = _pParent + ? _pParent->Get( nWhich, TRUE ) + : _pPool->GetDefaultItem( nWhich ); + + Changed( *pItemToClear, rNew ); + } + if ( pItemToClear->Which() ) + _pPool->Remove( *pItemToClear ); + } + ++nDel; + } + + // gefunden => raus + break; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + } + else + { + nDel = _nCount; + + USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd ) + if( *ppFnd ) + { + // wegen der Assertions ins Sub-Calls mu\s das hier sein + --_nCount; + const SfxPoolItem *pItemToClear = *ppFnd; + *ppFnd = 0; + + if ( !IsInvalidItem(pItemToClear) ) + { + if ( nWhich <= SFX_WHICH_MAX ) + { + const SfxPoolItem& rNew = _pParent + ? _pParent->Get( nWhich, TRUE ) + : _pPool->GetDefaultItem( nWhich ); + + Changed( *pItemToClear, rNew ); + } + + // #i32448# + // Take care of disabled items, too. + if(!pItemToClear->nWhich) + { + // item is disabled, delete it + delete pItemToClear; + } + else + { + // remove item from pool + _pPool->Remove( *pItemToClear ); + } + } + } + pPtr += 2; + } + } + return nDel; +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::ClearInvalidItems( BOOL bHardDefault ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + USHORT* pPtr = _pWhichRanges; + SfxItemArray ppFnd = _aItems; + if ( bHardDefault ) + while( *pPtr ) + { + for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd ) + if ( IsInvalidItem(*ppFnd) ) + *ppFnd = &_pPool->Put( _pPool->GetDefaultItem(nWhich) ); + pPtr += 2; + } + else + while( *pPtr ) + { + for( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd ) + if( IsInvalidItem(*ppFnd) ) + { + *ppFnd = 0; + --_nCount; + } + pPtr += 2; + } +} + +//------------------------------------------------------------------------ + + +void SfxItemSet::InvalidateAllItems() +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( !_nCount, "Es sind noch Items gesetzt" ); + + memset( (void*)_aItems, -1, ( _nCount = TotalCount() ) * sizeof( SfxPoolItem*) ); +} + +// ----------------------------------------------------------------------- + +SfxItemState SfxItemSet::GetItemState( USHORT nWhich, + BOOL bSrchInParent, + const SfxPoolItem **ppItem ) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + // suche den Bereich in dem das Which steht: + const SfxItemSet* pAktSet = this; + SfxItemState eRet = SFX_ITEM_UNKNOWN; + do + { + SfxItemArray ppFnd = pAktSet->_aItems; + const USHORT* pPtr = pAktSet->_pWhichRanges; + if (pPtr) + { + while ( *pPtr ) + { + if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // in diesem Bereich + ppFnd += nWhich - *pPtr; + if ( !*ppFnd ) + { + eRet = SFX_ITEM_DEFAULT; + if( !bSrchInParent ) + return eRet; // nicht vorhanden + break; // JP: in den Parents weitersuchen !!! + } + + if ( (SfxPoolItem*) -1 == *ppFnd ) + // Unterschiedlich vorhanden + return SFX_ITEM_DONTCARE; + + if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) ) + return SFX_ITEM_DISABLED; + + if (ppItem) + { + #ifdef DBG_UTIL + const SfxPoolItem *pItem = *ppFnd; + DBG_ASSERT( !pItem->ISA(SfxSetItem) || + 0 != &((const SfxSetItem*)pItem)->GetItemSet(), + "SetItem without ItemSet" ); + #endif + *ppItem = *ppFnd; + } + return SFX_ITEM_SET; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + } + } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent )); + return eRet; +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, USHORT nWhich ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( !rItem.ISA(SfxSetItem) || + 0 != &((const SfxSetItem&)rItem).GetItemSet(), + "SetItem without ItemSet" ); + if ( !nWhich ) + return 0; //! nur wegen Outliner-Bug + SfxItemArray ppFnd = _aItems; + const USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // in diesem Bereich + ppFnd += nWhich - *pPtr; + if( *ppFnd ) // schon einer vorhanden + { + // selbes Item bereits vorhanden? + if ( *ppFnd == &rItem ) + return 0; + + // wird dontcare oder disabled mit was echtem ueberschrieben? + if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) ) + { + *ppFnd = &_pPool->Put( rItem, nWhich ); + return *ppFnd; + } + + // wird disabled? + if( !rItem.Which() ) + { + *ppFnd = rItem.Clone(_pPool); + return 0; + } + else + { + // selber Wert bereits vorhanden? + if ( rItem == **ppFnd ) + return 0; + + // den neuen eintragen, den alten austragen + const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich ); + const SfxPoolItem* pOld = *ppFnd; + *ppFnd = &rNew; + if(nWhich <= SFX_WHICH_MAX) + Changed( *pOld, rNew ); + _pPool->Remove( *pOld ); + } + } + else + { + ++_nCount; + if( !rItem.Which() ) + *ppFnd = rItem.Clone(_pPool); + else { + const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich ); + *ppFnd = &rNew; + if (nWhich <= SFX_WHICH_MAX ) + { + const SfxPoolItem& rOld = _pParent + ? _pParent->Get( nWhich, TRUE ) + : _pPool->GetDefaultItem( nWhich ); + Changed( rOld, rNew ); + } + } + } + SFX_ASSERT( !_pPool->IsItemFlag(nWhich, SFX_ITEM_POOLABLE) || + rItem.ISA(SfxSetItem) || **ppFnd == rItem, + nWhich, "putted Item unequal" ); + return *ppFnd; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + return 0; +} + +// ----------------------------------------------------------------------- + +int SfxItemSet::Put( const SfxItemSet& rSet, BOOL bInvalidAsDefault ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + BOOL bRet = FALSE; + if( rSet.Count() ) + { + SfxItemArray ppFnd = rSet._aItems; + const USHORT* pPtr = rSet._pWhichRanges; + while ( *pPtr ) + { + for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd ) + if( *ppFnd ) + { + if ( IsInvalidItem( *ppFnd ) ) + { + if ( bInvalidAsDefault ) + bRet |= 0 != ClearItem( nWhich ); + // gab GPF bei non.WIDs: + // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich ); + else + InvalidateItem( nWhich ); + } + else + bRet |= 0 != Put( **ppFnd, nWhich ); + } + pPtr += 2; + } + } + return bRet; +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::PutExtended +( + const SfxItemSet& rSet, // Quelle der zu puttenden Items + SfxItemState eDontCareAs, // was mit DontCare-Items passiert + SfxItemState eDefaultAs // was mit Default-Items passiert +) + +/* [Beschreibung] + + Diese Methode "ubernimmt die Items aus 'rSet' in '*this'. Die + Which-Bereiche in '*this', die in 'rSet' nicht vorkommen bleiben unver- + "andert. Der Which-Bereich von '*this' bleibt auch unver"andert. + + In 'rSet' gesetzte Items werden auch in '*this*' gesetzt. Default- + (0 Pointer) und Invalid- (-1 Pointer) Items werden je nach Parameter + ('eDontCareAs' und 'eDefaultAs' behandelt: + + SFX_ITEM_SET: hart auf Default des Pools gesetzt + SFX_ITEM_DEFAULT: gel"oscht (0 Pointer) + SFX_ITEM_DONTCARE: invalidiert (-1 Pointer) + + Alle anderen Werte f"ur 'eDontCareAs' und 'eDefaultAs' sind ung"ultig. +*/ + +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + + // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults + SfxItemArray ppFnd = rSet._aItems; + const USHORT* pPtr = rSet._pWhichRanges; + while ( *pPtr ) + { + for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd ) + if( *ppFnd ) + { + if ( IsInvalidItem( *ppFnd ) ) + { + // Item ist DontCare: + switch ( eDontCareAs ) + { + case SFX_ITEM_SET: + Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich ); + break; + + case SFX_ITEM_DEFAULT: + ClearItem( nWhich ); + break; + + case SFX_ITEM_DONTCARE: + InvalidateItem( nWhich ); + break; + + default: + DBG_ERROR( "invalid Argument for eDontCareAs" ); + } + } + else + // Item ist gesetzt: + Put( **ppFnd, nWhich ); + } + else + { + // Item ist Default: + switch ( eDefaultAs ) + { + case SFX_ITEM_SET: + Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich ); + break; + + case SFX_ITEM_DEFAULT: + ClearItem( nWhich ); + break; + + case SFX_ITEM_DONTCARE: + InvalidateItem( nWhich ); + break; + + default: + DBG_ERROR( "invalid Argument for eDefaultAs" ); + } + } + pPtr += 2; + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::MergeRange( USHORT nFrom, USHORT nTo ) +/** <H3>Description</H3> + + Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of + items which are new ranges too. +*/ + +{ + // special case: exactly one USHORT which is already included? + if ( nFrom == nTo && SFX_ITEM_AVAILABLE <= GetItemState(nFrom, FALSE) ) + return; + + // merge new range + SfxUShortRanges aRanges( _pWhichRanges ); + aRanges += SfxUShortRanges( nFrom, nTo ); + SetRanges( aRanges ); +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::SetRanges( const USHORT *pNewRanges ) + +/** <H3>Description</H3> + + Modifies the ranges of settable items. Keeps state of items which + are new ranges too. +*/ + +{ + // identische Ranges? + if ( _pWhichRanges == pNewRanges ) + return; + const USHORT* pOld = _pWhichRanges; + const USHORT* pNew = pNewRanges; + while ( *pOld == *pNew ) + { + if ( !*pOld && !*pNew ) + return; + ++pOld, ++pNew; + } + + // create new item-array (by iterating through all new ranges) + ULONG nSize = Capacity_Impl(pNewRanges); + SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ]; + USHORT n = 0, nNewCount = 0; + if ( _nCount == 0 ) + memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) ); + else + { + for ( const USHORT *pRange = pNewRanges; *pRange; pRange += 2 ) + { + // iterate through all ids in the range + for ( USHORT nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n ) + { + // direct move of pointer (not via pool) + SfxItemState eState = GetItemState( nWID, FALSE, aNewItems+n ); + if ( SFX_ITEM_SET == eState ) + { + // increment new item count and possibly increment ref count + ++nNewCount; + aNewItems[n]->AddRef(); + } + else if ( SFX_ITEM_DISABLED == eState ) + { + // put "disabled" item + ++nNewCount; + aNewItems[n] = new SfxVoidItem(0); + } + else if ( SFX_ITEM_DONTCARE == eState ) + { + ++nNewCount; + aNewItems[n] = (SfxPoolItem*)-1; + } + else + { + // default + aNewItems[n] = 0; + } + } + } + // free old items + USHORT nOldTotalCount = TotalCount(); + for ( USHORT nItem = 0; nItem < nOldTotalCount; ++nItem ) + { + const SfxPoolItem *pItem = _aItems[nItem]; + if ( pItem && !IsInvalidItem(pItem) && pItem->Which() ) + _pPool->Remove(*pItem); + } + } + + // replace old items-array and ranges + delete[] _aItems; + _aItems = aNewItems; + _nCount = nNewCount; + + if( pNewRanges == GetPool()->GetFrozenIdRanges() ) + { + delete[] _pWhichRanges; + _pWhichRanges = ( USHORT* ) pNewRanges; + } + else + { + USHORT nCount = Count_Impl(pNewRanges) + 1; + if ( _pWhichRanges != _pPool->GetFrozenIdRanges() ) + delete[] _pWhichRanges; + _pWhichRanges = new USHORT[ nCount ]; + memcpy( _pWhichRanges, pNewRanges, sizeof( USHORT ) * nCount ); + } +} + +// ----------------------------------------------------------------------- + +int SfxItemSet::Set +( + const SfxItemSet& rSet, /* das SfxItemSet, dessen SfxPoolItems + "ubernommen werden sollen */ + + BOOL bDeep /* TRUE (default) + auch die SfxPoolItems aus den ggf. an + rSet vorhandenen Parents werden direkt + in das SfxItemSet "ubernommen + + FALSE + die SfxPoolItems aus den Parents von + rSet werden nicht ber"ucksichtigt */ +) + +/* [Beschreibung] + + Das SfxItemSet nimmt genau die SfxPoolItems an, die auch in + rSet gesetzt sind und im eigenen <Which-Bereich> liegen. Alle + anderen werden entfernt. Der SfxItemPool wird dabei beibehalten, + so da"s die "ubernommenen SfxPoolItems dabei ggf. vom SfxItemPool + von rSet in den SfxItemPool von *this "ubernommen werden. + + SfxPoolItems, f"ur die in rSet IsInvalidItem() == TRUE gilt, + werden als Invalid-Item "ubernommen. + + + [R"uckgabewert] + + int TRUE + es wurden SfxPoolItems "ubernommen + + FALSE + es wurden keine SfxPoolItems "ubernommen, + da z.B. die Which-Bereiche der SfxItemSets + keine Schnittmenge haben oder in der + Schnittmenge keine SfxPoolItems in rSet + gesetzt sind + +*/ + +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + int bRet = FALSE; + if ( _nCount ) + ClearItem(); + if ( bDeep ) + { + SfxWhichIter aIter(*this); + USHORT nWhich = aIter.FirstWhich(); + while ( nWhich ) + { + const SfxPoolItem* pItem; + if( SFX_ITEM_SET == rSet.GetItemState( nWhich, TRUE, &pItem ) ) + bRet |= 0 != Put( *pItem, pItem->Which() ); + nWhich = aIter.NextWhich(); + } + } + else + bRet = Put(rSet, FALSE); + + return bRet; +} + +//------------------------------------------------------------------------ + +const SfxPoolItem* SfxItemSet::GetItem +( + USHORT nId, // Slot-Id oder Which-Id des Items + BOOL bSrchInParent, // TRUE: auch in Parent-ItemSets suchen + TypeId aItemType // != 0 => RTTI Pruefung mit Assertion +) const + +/* [Beschreibung] + + Mit dieser Methode wird der Zugriff auf einzelne Items im + SfxItemSet wesentlich vereinfacht. Insbesondere wird die Typpr"ufung + (per Assertion) durchgef"uhrt, wodurch die Applikations-Sourcen + wesentlich "ubersichtlicher werden. In der PRODUCT-Version wird + eine 0 zur"uckgegeben, wenn das gefundene Item nicht von der + angegebenen Klasse ist. Ist kein Item mit der Id 'nWhich' in dem ItemSet, + so wird 0 zurueckgegeben. +*/ + +{ + // ggf. in Which-Id umrechnen + USHORT nWhich = GetPool()->GetWhich(nId); + + // ist das Item gesetzt oder bei bDeep==TRUE verf"ugbar? + const SfxPoolItem *pItem = 0; + SfxItemState eState = GetItemState( nWhich, bSrchInParent, &pItem ); + if ( bSrchInParent && SFX_ITEM_AVAILABLE == eState && + nWhich <= SFX_WHICH_MAX ) + pItem = &_pPool->GetDefaultItem(nWhich); + if ( pItem ) + { + // stimmt der Typ "uberein? + if ( !aItemType || pItem->IsA(aItemType) ) + return pItem; + + // sonst Fehler melden + DBG_ERROR( "invalid argument type" ); + } + + // kein Item gefunden oder falschen Typ gefunden + return 0; +} + + +//------------------------------------------------------------------------ + + +const SfxPoolItem& SfxItemSet::Get( USHORT nWhich, BOOL bSrchInParent) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + // suche den Bereich in dem das Which steht: + const SfxItemSet* pAktSet = this; + do + { + if( pAktSet->Count() ) + { + SfxItemArray ppFnd = pAktSet->_aItems; + const USHORT* pPtr = pAktSet->_pWhichRanges; + while( *pPtr ) + { + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // in diesem Bereich + ppFnd += nWhich - *pPtr; + if( *ppFnd ) + { + if( (SfxPoolItem*)-1 == *ppFnd ) { + //?MI: folgender code ist Doppelt (unten) + SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig"); + //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich); + //!return aDefault; + return _pPool->GetDefaultItem( nWhich ); + } +#ifdef DBG_UTIL + const SfxPoolItem *pItem = *ppFnd; + DBG_ASSERT( !pItem->ISA(SfxSetItem) || + 0 != &((const SfxSetItem*)pItem)->GetItemSet(), + "SetItem without ItemSet" ); + if ( pItem->ISA(SfxVoidItem) || !pItem->Which() ) + DBG_WARNING( "SFX_WARNING: Getting disabled Item" ); +#endif + return **ppFnd; + } + break; // dann beim Parent suchen + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + } +// bis zum Ende vom Such-Bereich: was nun ? zum Parent, oder Default ?? +// if( !*pPtr ) // bis zum Ende vom Such-Bereich ? +// break; + } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent )); + + // dann das Default vom Pool holen und returnen + SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig"); + const SfxPoolItem *pItem = &_pPool->GetDefaultItem( nWhich ); + DBG_ASSERT( !pItem->ISA(SfxSetItem) || + 0 != &((const SfxSetItem*)pItem)->GetItemSet(), + "SetItem without ItemSet" ); + return *pItem; +} + + // Notification-Callback +// ----------------------------------------------------------------------- + +void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemSet::TotalCount() const +{ + DBG_CHKTHIS(SfxItemSet, 0); // wird im Ctor benutzt bevor vollst. init. + USHORT nRet = 0; + USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + nRet += ( *(pPtr+1) - *pPtr ) + 1; + pPtr += 2; + } + return nRet; +} +// ----------------------------------------------------------------------- + +// behalte nur die Items, die auch in rSet enthalten sein (Wert egal) + +void SfxItemSet::Intersect( const SfxItemSet& rSet ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT(_pPool, "nicht implementiert ohne Pool"); + if( !Count() ) // gar keine gesetzt ? + return; + + // loesche alle Items, die im rSet nicht mehr vorhanden sind + if( !rSet.Count() ) + { + ClearItem(); // alles loeschen + return; + } + + // teste mal, ob sich die Which-Bereiche unterscheiden. + BOOL bEqual = TRUE; + USHORT* pWh1 = _pWhichRanges; + USHORT* pWh2 = rSet._pWhichRanges; + USHORT nSize = 0; + + for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n ) + { + if( *pWh1 != *pWh2 ) + { + bEqual = FALSE; + break; + } + if( n & 1 ) + nSize += ( *(pWh1) - *(pWh1-1) ) + 1; + } + bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen + + // sind die Bereiche identisch, ist es einfacher zu handhaben ! + if( bEqual ) + { + SfxItemArray ppFnd1 = _aItems; + SfxItemArray ppFnd2 = rSet._aItems; + + for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) + if( *ppFnd1 && !*ppFnd2 ) + { + // aus dem Pool loeschen + if( !IsInvalidItem( *ppFnd1 ) ) + { + USHORT nWhich = (*ppFnd1)->Which(); + if(nWhich <= SFX_WHICH_MAX) + { + const SfxPoolItem& rNew = _pParent + ? _pParent->Get( nWhich, TRUE ) + : _pPool->GetDefaultItem( nWhich ); + + Changed( **ppFnd1, rNew ); + } + _pPool->Remove( **ppFnd1 ); + } + *ppFnd1 = 0; + --_nCount; + } + } + else + { + SfxItemIter aIter( *this ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + USHORT nWhich = IsInvalidItem( pItem ) + ? GetWhichByPos( aIter.GetCurPos() ) + : pItem->Which(); + if( 0 == rSet.GetItemState( nWhich, FALSE ) ) + ClearItem( nWhich ); // loeschen + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::Differentiate( const SfxItemSet& rSet ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + if( !Count() || !rSet.Count() ) // gar keine gesetzt ? + return; + + // teste mal, ob sich die Which-Bereiche unterscheiden. + BOOL bEqual = TRUE; + USHORT* pWh1 = _pWhichRanges; + USHORT* pWh2 = rSet._pWhichRanges; + USHORT nSize = 0; + + for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n ) + { + if( *pWh1 != *pWh2 ) + { + bEqual = FALSE; + break; + } + if( n & 1 ) + nSize += ( *(pWh1) - *(pWh1-1) ) + 1; + } + bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen + + // sind die Bereiche identisch, ist es einfacher zu handhaben ! + if( bEqual ) + { + SfxItemArray ppFnd1 = _aItems; + SfxItemArray ppFnd2 = rSet._aItems; + + for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) + if( *ppFnd1 && *ppFnd2 ) + { + // aus dem Pool loeschen + if( !IsInvalidItem( *ppFnd1 ) ) + { + USHORT nWhich = (*ppFnd1)->Which(); + if(nWhich <= SFX_WHICH_MAX) + { + const SfxPoolItem& rNew = _pParent + ? _pParent->Get( nWhich, TRUE ) + : _pPool->GetDefaultItem( nWhich ); + + Changed( **ppFnd1, rNew ); + } + _pPool->Remove( **ppFnd1 ); + } + *ppFnd1 = 0; + --_nCount; + } + } + else + { + SfxItemIter aIter( *this ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + while( TRUE ) + { + USHORT nWhich = IsInvalidItem( pItem ) + ? GetWhichByPos( aIter.GetCurPos() ) + : pItem->Which(); + if( SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE ) ) + ClearItem( nWhich ); // loeschen + if( aIter.IsAtEnd() ) + break; + pItem = aIter.NextItem(); + } + + } +} + +// ----------------------------------------------------------------------- +/* Entscheidungstabelle fuer MergeValue[s] + +Grundsaetze: + 1. Ist der Which-Wert im 1.Set "unknown", dann folgt niemals eine Aktion. + 2. Ist der Which-Wert im 2.Set "unknown", dann gilt er als "default". + 3. Es gelten fuer Vergleiche die Werte der "default"-Items. + +1.-Item 2.-Item Values bIgnoreDefs Remove Assign Add + +set set == FALSE - - - +default set == FALSE - - - +dontcare set == FALSE - - - +unknown set == FALSE - - - +set default == FALSE - - - +default default == FALSE - - - +dontcare default == FALSE - - - +unknown default == FALSE - - - +set dontcare == FALSE 1.-Item -1 - +default dontcare == FALSE - -1 - +dontcare dontcare == FALSE - - - +unknown dontcare == FALSE - - - +set unknown == FALSE 1.-Item -1 - +default unknown == FALSE - - - +dontcare unknown == FALSE - - - +unknown unknown == FALSE - - - + +set set != FALSE 1.-Item -1 - +default set != FALSE - -1 - +dontcare set != FALSE - - - +unknown set != FALSE - - - +set default != FALSE 1.-Item -1 - +default default != FALSE - - - +dontcare default != FALSE - - - +unknown default != FALSE - - - +set dontcare != FALSE 1.-Item -1 - +default dontcare != FALSE - -1 - +dontcare dontcare != FALSE - - - +unknown dontcare != FALSE - - - +set unknown != FALSE 1.-Item -1 - +default unknown != FALSE - - - +dontcare unknown != FALSE - - - +unknown unknown != FALSE - - - + +set set == TRUE - - - +default set == TRUE - 2.-Item 2.-Item +dontcare set == TRUE - - - +unknown set == TRUE - - - +set default == TRUE - - - +default default == TRUE - - - +dontcare default == TRUE - - - +unknown default == TRUE - - - +set dontcare == TRUE - - - +default dontcare == TRUE - -1 - +dontcare dontcare == TRUE - - - +unknown dontcare == TRUE - - - +set unknown == TRUE - - - +default unknown == TRUE - - - +dontcare unknown == TRUE - - - +unknown unknown == TRUE - - - + +set set != TRUE 1.-Item -1 - +default set != TRUE - 2.-Item 2.-Item +dontcare set != TRUE - - - +unknown set != TRUE - - - +set default != TRUE - - - +default default != TRUE - - - +dontcare default != TRUE - - - +unknown default != TRUE - - - +set dontcare != TRUE 1.-Item -1 - +default dontcare != TRUE - -1 - +dontcare dontcare != TRUE - - - +unknown dontcare != TRUE - - - +set unknown != TRUE - - - +default unknown != TRUE - - - +dontcare unknown != TRUE - - - +unknown unknown != TRUE - - - +*/ + + +static void MergeItem_Impl( SfxItemPool *_pPool, USHORT &rCount, + const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, + BOOL bIgnoreDefaults ) +{ + DBG_ASSERT( ppFnd1 != 0, "Merging to 0-Item" ); + + // 1. Item ist default? + if ( !*ppFnd1 ) + { + if ( IsInvalidItem(pFnd2) ) + // Entscheidungstabelle: default, dontcare, egal, egal + *ppFnd1 = (SfxPoolItem*) -1; + + else if ( pFnd2 && !bIgnoreDefaults && + _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 ) + // Entscheidungstabelle: default, set, !=, FALSE + *ppFnd1 = (SfxPoolItem*) -1; + + else if ( pFnd2 && bIgnoreDefaults ) + // Entscheidungstabelle: default, set, egal, TRUE + *ppFnd1 = &_pPool->Put( *pFnd2 ); + + if ( *ppFnd1 ) + ++rCount; + } + + // 1. Item ist gesetzt? + else if ( !IsInvalidItem(*ppFnd1) ) + { + if ( !pFnd2 ) + { + // 2. Item ist default + if ( !bIgnoreDefaults && + **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) ) + { + // Entscheidungstabelle: set, default, !=, FALSE + _pPool->Remove( **ppFnd1 ); + *ppFnd1 = (SfxPoolItem*) -1; + } + } + else if ( IsInvalidItem(pFnd2) ) + { + // 2. Item ist dontcare + if ( !bIgnoreDefaults || + **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) ) + { + // Entscheidungstabelle: set, dontcare, egal, FALSE + // oder: set, dontcare, !=, TRUE + _pPool->Remove( **ppFnd1 ); + *ppFnd1 = (SfxPoolItem*) -1; + } + } + else + { + // 2. Item ist gesetzt + if ( **ppFnd1 != *pFnd2 ) + { + // Entscheidungstabelle: set, set, !=, egal + _pPool->Remove( **ppFnd1 ); + *ppFnd1 = (SfxPoolItem*) -1; + } + } + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::MergeValues( const SfxItemSet& rSet, BOOL bIgnoreDefaults ) +{ + // Achtung!!! Bei Aenderungen/Bugfixes immer obenstehende Tabelle pflegen! + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( GetPool() == rSet.GetPool(), "MergeValues mit verschiedenen Pools" ); + + // teste mal, ob sich die Which-Bereiche unterscheiden. + BOOL bEqual = TRUE; + USHORT* pWh1 = _pWhichRanges; + USHORT* pWh2 = rSet._pWhichRanges; + USHORT nSize = 0; + + for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n ) + { + if( *pWh1 != *pWh2 ) + { + bEqual = FALSE; + break; + } + if( n & 1 ) + nSize += ( *(pWh1) - *(pWh1-1) ) + 1; + } + bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen + + // sind die Bereiche identisch, ist es effizieter zu handhaben ! + if( bEqual ) + { + SfxItemArray ppFnd1 = _aItems; + SfxItemArray ppFnd2 = rSet._aItems; + + for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 ) + MergeItem_Impl( _pPool, _nCount, ppFnd1, *ppFnd2, bIgnoreDefaults ); + } + else + { + SfxWhichIter aIter( rSet ); + register USHORT nWhich; + while( 0 != ( nWhich = aIter.NextWhich() ) ) + { + const SfxPoolItem* pItem = 0; + rSet.GetItemState( nWhich, TRUE, &pItem ); + if( !pItem ) + { + // nicht gesetzt, also default + if ( !bIgnoreDefaults ) + MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ), bIgnoreDefaults ); + } + else if( IsInvalidItem( pItem ) ) + // dont care + InvalidateItem( nWhich ); + else + MergeValue( *pItem, bIgnoreDefaults ); + } + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, BOOL bIgnoreDefaults ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + SfxItemArray ppFnd = _aItems; + const USHORT* pPtr = _pWhichRanges; + const USHORT nWhich = rAttr.Which(); + while( *pPtr ) + { + // in diesem Bereich? + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + ppFnd += nWhich - *pPtr; + MergeItem_Impl( _pPool, _nCount, ppFnd, &rAttr, bIgnoreDefaults ); + break; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } +} + +// ----------------------------------------------------------------------- + +void SfxItemSet::InvalidateItem( USHORT nWhich ) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + SfxItemArray ppFnd = _aItems; + const USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // in diesem Bereich + ppFnd += nWhich - *pPtr; + + if( *ppFnd ) // bei mir gesetzt + { + if( (SfxPoolItem*)-1 != *ppFnd ) // noch nicht dontcare ! + { + _pPool->Remove( **ppFnd ); + *ppFnd = (SfxPoolItem*)-1; + } + } + else + { + *ppFnd = (SfxPoolItem*)-1; + ++_nCount; + } + break; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemSet::GetWhichByPos( USHORT nPos ) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + USHORT n = 0; + USHORT* pPtr = _pWhichRanges; + while( *pPtr ) + { + n = ( *(pPtr+1) - *pPtr ) + 1; + if( nPos < n ) + return *(pPtr)+nPos; + nPos = nPos - n; + pPtr += 2; + } + DBG_ASSERT( FALSE, "Hier sind wir falsch" ); + return 0; +} + +// ----------------------------------------------------------------------- + +SvStream &SfxItemSet::Store +( + SvStream& rStream, // Zielstream f"ur normale Items + FASTBOOL bDirect // TRUE: Items direkt speicher, FALSE: Surrogate +) const + +/* [Beschreibung] + + Speichert die <SfxItemSet>-Instanz in den angegebenen Stream. Dabei + werden die Surrorage der gesetzten <SfxPoolItem>s bzw. ('bDirect==TRUE') + die gesetzten Items selbst wie folgt im Stream abgelegt: + + USHORT (Count) Anzahl der gesetzten Items + Count* _pPool->StoreItem() siehe <SfxItemPool::StoreItem()const> + + + [Querverweise] + + <SfxItemSet::Load(SvStream&,BOOL,const SfxItemPool*)> +*/ + +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( _pPool, "Kein Pool" ); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" ); + + // Position des Counts merken, um ggf. zu korrigieren + ULONG nCountPos = rStream.Tell(); + rStream << _nCount; + + // wenn nichts zu speichern ist, auch keinen ItemIter aufsetzen! + if ( _nCount ) + { + // mitz"ahlen wieviel Items tats"achlich gespeichert werden + USHORT nWrittenCount = 0; // Anzahl in 'rStream' gestreamter Items + + // "uber alle gesetzten Items iterieren + SfxItemIter aIter(*this); + for ( const SfxPoolItem *pItem = aIter.FirstItem(); + pItem; + pItem = aIter.NextItem() ) + { + // Item (ggf. als Surrogat) via Pool speichern lassen + DBG_ASSERT( !IsInvalidItem(pItem), "can't store invalid items" ); + if ( !IsInvalidItem(pItem) && + _pPool->StoreItem( rStream, *pItem, bDirect ) ) + // Item wurde in 'rStream' gestreamt + ++nWrittenCount; + }; + + // weniger geschrieben als enthalten (z.B. altes Format) + if ( nWrittenCount != _nCount ) + { + // tats"achlichen Count im Stream ablegen + ULONG nPos = rStream.Tell(); + rStream.Seek( nCountPos ); + rStream << nWrittenCount; + rStream.Seek( nPos ); + } + } + + return rStream; +} + +// ----------------------------------------------------------------------- + +SvStream &SfxItemSet::Load +( + SvStream& rStream, // Stream, aus dem geladen werden soll + + FASTBOOL bDirect, /* TRUE + Items werden direkt aus dem Stream + gelesen, nicht "uber Surrogate + + FALSE (default) + Items werden "uber Surrogate gelesen */ + + const SfxItemPool* pRefPool /* Pool, der die Surrogate aufl"osen kann + (z.B. zum Einf"ugen von Dokumenten) */ +) + +/* [Beschreibung] + + Diese Methode l"adt ein <SfxItemSet> aus einem Stream. Falls der + <SfxItemPool> ohne Ref-Counts geladen wurde, werden die geladenen + Item-Referenzen in den Items hochgez"ahlt, ansonsten wird vorausgesetzt, + da\s sie schon beim Laden des SfxItemPools ber"ucksichtigt waren. + + [Querverweise] + + <SfxItemSet::Store(Stream&,BOOL)const> +*/ + +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_ASSERT( _pPool, "Kein Pool"); + DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "Kein Master-Pool"); + + // kein Ref-Pool => Surrogate mit Pool des ItemSets aufl"osen + if ( !pRefPool ) + pRefPool = _pPool; + + // Anzahl der zu ladenden Items laden und dann ebensoviele Items + USHORT nCount = 0; + rStream >> nCount; + for ( USHORT i = 0; i < nCount; ++i ) + { + // Surrogat/Item laden und (Surrogat) aufl"osen lassen + const SfxPoolItem *pItem = + _pPool->LoadItem( rStream, bDirect, pRefPool ); + + // konnte ein Item geladen oder via Surrogat aufgel"ost werden? + if ( pItem ) + { + // Position f"ur Item-Pointer im Set suchen + USHORT nWhich = pItem->Which(); + SfxItemArray ppFnd = _aItems; + const USHORT* pPtr = _pWhichRanges; + while ( *pPtr ) + { + // in diesem Bereich? + if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // Item-Pointer im Set merken + ppFnd += nWhich - *pPtr; + SFX_ASSERT( !*ppFnd, nWhich, "Item doppelt eingetragen"); + *ppFnd = pItem; + ++_nCount; + break; + } + + // im Range-Array und Item-Array zum n"achsten Which-Range + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + } + } + + return rStream; +} + +// ----------------------------------------------------------------------- + +int SfxItemSet::operator==(const SfxItemSet &rCmp) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + DBG_CHKOBJ(&rCmp, SfxItemSet, DbgCheckItemSet); + + // besonders schnell zu ermittelnde Werte muessen gleich sein + if ( _pParent != rCmp._pParent || + _pPool != rCmp._pPool || + Count() != rCmp.Count() ) + return FALSE; + + // Ranges durchzaehlen lassen dauert laenger, muss aber auch gleich sein + USHORT nCount1 = TotalCount(); + USHORT nCount2 = rCmp.TotalCount(); + if ( nCount1 != nCount2 ) + return FALSE; + + // sind die Ranges selbst ungleich? + for ( USHORT nRange = 0; _pWhichRanges[nRange]; nRange += 2 ) + if ( _pWhichRanges[nRange] != rCmp._pWhichRanges[nRange] || + _pWhichRanges[nRange+1] != rCmp._pWhichRanges[nRange+1] ) + { + // dann m"ussen wir die langsame Methode verwenden + SfxWhichIter aIter( *this ); + for ( USHORT nWh = aIter.FirstWhich(); + nWh; + nWh = aIter.NextWhich() ) + { + // wenn die Pointer von poolable Items ungleich sind, + // muessen die Items gleich sein + const SfxPoolItem *pItem1 = 0, *pItem2 = 0; + if ( GetItemState( nWh, FALSE, &pItem1 ) != + rCmp.GetItemState( nWh, FALSE, &pItem2 ) || + ( pItem1 != pItem2 && + ( !pItem1 || IsInvalidItem(pItem1) || + ( _pPool->IsItemFlag(*pItem1, SFX_ITEM_POOLABLE) && + *pItem1 != *pItem2 ) ) ) ) + return FALSE; + } + + return TRUE; + } + + // Pointer alle gleich? + if ( 0 == memcmp( _aItems, rCmp._aItems, nCount1 * sizeof(_aItems[0]) ) ) + return TRUE; + + // dann werden wir wohl alle einzeln vergleichen muessen + const SfxPoolItem **ppItem1 = (const SfxPoolItem**) _aItems; + const SfxPoolItem **ppItem2 = (const SfxPoolItem**) rCmp._aItems; + for ( USHORT nPos = 0; nPos < nCount1; ++nPos ) + { + // wenn die Pointer von poolable Items ungleich sind, + // muessen die Items gleich sein + if ( *ppItem1 != *ppItem2 && + ( ( !*ppItem1 || !*ppItem2 ) || + ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) || + ( _pPool->IsItemFlag(**ppItem1, SFX_ITEM_POOLABLE) ) || + **ppItem1 != **ppItem2 ) ) + return FALSE; + + ++ppItem1; + ++ppItem2; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +SfxItemSet *SfxItemSet::Clone(BOOL bItems, SfxItemPool *pToPool ) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + if ( pToPool && pToPool != _pPool ) + { + SfxItemSet *pNewSet = new SfxItemSet( *pToPool, _pWhichRanges ); + if ( bItems ) + { + SfxWhichIter aIter(*pNewSet); + USHORT nWhich = aIter.FirstWhich(); + while ( nWhich ) + { + const SfxPoolItem* pItem; + if ( SFX_ITEM_SET == GetItemState( nWhich, FALSE, &pItem ) ) + pNewSet->Put( *pItem, pItem->Which() ); + nWhich = aIter.NextWhich(); + } + } + return pNewSet; + } + else + return bItems + ? new SfxItemSet(*this) + : new SfxItemSet(*_pPool, _pWhichRanges); +} + +// ----------------------------------------------------------------------- + +int SfxItemSet::PutDirect(const SfxPoolItem &rItem) +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + SfxItemArray ppFnd = _aItems; + const USHORT* pPtr = _pWhichRanges; + const USHORT nWhich = rItem.Which(); +#ifdef DBG_UTIL + IsPoolDefaultItem(&rItem) || _pPool->GetSurrogate(&rItem); + // nur Assertion in den callees provozieren +#endif + while( *pPtr ) + { + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // in diesem Bereich + ppFnd += nWhich - *pPtr; + const SfxPoolItem* pOld = *ppFnd; + if( pOld ) // schon einer vorhanden + { + if( rItem == **ppFnd ) + return FALSE; // schon vorhanden ! + _pPool->Remove( *pOld ); + } + else + ++_nCount; + + // den neuen eintragen + if( IsPoolDefaultItem(&rItem) ) + *ppFnd = &_pPool->Put( rItem ); + else + { + *ppFnd = &rItem; + if( !IsStaticDefaultItem( &rItem ) ) + rItem.AddRef(); + } + + return TRUE; + } + ppFnd += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + return FALSE; +} + +// ----------------------------------------------------------------------- + +SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool ) +: SfxItemSet(rPool, (const USHORT*) 0), + aDefault(0), + nFree(nInitCount) +{ + // initial keine Items + _aItems = 0; + + // nInitCount Paare an USHORTs fuer Ranges allozieren + _pWhichRanges = new USHORT[ nInitCount + 1 ]; + memset( _pWhichRanges, 0, ( nInitCount + 1 ) * sizeof(USHORT) ); +} + + +// ----------------------------------------------------------------------- + + +SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy) +: SfxItemSet(rCopy), + aDefault(0), + nFree(0) +{ +} + +// ----------------------------------------------------------------------- + + + +SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy) +: SfxItemSet(rCopy), + aDefault(0), + nFree(0) +/* [Anmerkung] + + Der mu\s sein, da sonst vom Compiler einer generiert wird, er nimmt + nicht den Ctor mit der 'const SfxItemSet&'! +*/ +{ +} + +// ----------------------------------------------------------------------- + +static USHORT *AddRanges_Impl( + USHORT *pUS, std::ptrdiff_t nOldSize, USHORT nIncr) + +/* Diese interne Funktion erzeugt ein neues Which-Range-Array, welches von + dem 'nOldSize'-USHORTs langen 'pUS' kopiert wird und hinten an Platz + f"ur 'nIncr' neue USHORTs hat. Das terminierende USHORT mit der '0' + wird weder in 'nOldSize' noch in 'nIncr' mitgez"ahlt, sondern implizit + hinzugerechnet. + + Das neue Which-Range-Array wird als Returnwert zur"uckgegeben, das alte + 'pUS' freigegeben. +*/ + +{ + // neues Which-Range-Array anlegen + USHORT *pNew = new USHORT[ nOldSize + nIncr + 1 ]; + + // die alten Ranges "ubernehmen + memcpy( pNew, pUS, nOldSize * sizeof(USHORT) ); + + // die neuen auf 0 initialisieren + memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(USHORT) ); + + // das alte Array freigeben + delete[] pUS; + + return pNew; +} + +// ----------------------------------------------------------------------- + +static SfxItemArray AddItem_Impl(SfxItemArray pItems, USHORT nOldSize, USHORT nPos) + +/* Diese interne Funktion erzeugt ein neues ItemArray, welches von 'pItems' + kopiert wird, an der Position 'nPos' jedoch Platz f"ur einen neuen + ItemPointer hat. + + Das neue ItemArray wird als Returnwert zur"uckgegeben, das alte 'pItems' + wird freigegeben. +*/ + +{ + // neues ItemArray anlegen + SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1]; + + // war schon vorher eins da? + if ( pItems ) + { + // alte Items vor nPos kopieren + if ( nPos ) + memcpy( (void*) pNew, pItems, nPos * sizeof(SfxPoolItem **) ); + + // alte Items hinter nPos kopieren + if ( nPos < nOldSize ) + memcpy( (void*) (pNew + nPos + 1), pItems + nPos, + (nOldSize-nPos) * sizeof(SfxPoolItem **) ); + } + + // neues Item initialisieren + *(pNew + nPos) = 0; + + // altes ItemArray freigeben + delete[] pItems; + + return pNew; +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, USHORT nWhich ) + +// Putten mit automatischer Erweiterung der Whichs-Ids um die ID +// des Items. + +{ + USHORT nPos = 0; // Position f"ur 'rItem' in '_aItems' + const USHORT nItemCount = TotalCount(); + + // erstmal sehen, ob es schon einen passenden Bereich gibt + USHORT *pPtr = _pWhichRanges; + while ( *pPtr ) + { + // Which-Id liegt in diesem Bereich? + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + // Einfuegen + nPos += nWhich - *pPtr; + break; + } + + // Position des Items in _aItems mitf"uhren + nPos += *(pPtr+1) - *pPtr + 1; + + // zum n"achsten Bereich + pPtr += 2; + } + + // Which-Id noch nicht vorhanden? + if ( !*pPtr ) + { + // suchen, ob man sie irgendwo dranpacken kann + pPtr = _pWhichRanges; + nPos = 0; + while ( *pPtr ) + { + // Which-Id liegt exakt vor diesem Bereich? + if ( (nWhich+1) == *pPtr ) + { + // Bereich waechst nach unten + (*pPtr)--; + + // vor erstem Item dieses Bereichs Platz schaffen + _aItems = AddItem_Impl(_aItems, nItemCount, nPos); + break; + } + + // Which-Id liegt exakt hinter diesem Bereich? + else if ( (nWhich-1) == *(pPtr+1) ) + { + // Bereich waechst nach oben + (*(pPtr+1))++; + + // hinter letztem Item dieses Bereichs Platz schaffen + nPos += nWhich - *pPtr; + _aItems = AddItem_Impl(_aItems, nItemCount, nPos); + break; + } + + // Position des Items in _aItems mitf"uhren + nPos += *(pPtr+1) - *pPtr + 1; + + // zum n"achsten Bereich + pPtr += 2; + } + } + + // keinen erweiterbaren Bereich gefunden? + if ( !*pPtr ) + { + // kein Platz mehr in _pWhichRanges => erweitern + std::ptrdiff_t nSize = pPtr - _pWhichRanges; + if( !nFree ) + { + _pWhichRanges = AddRanges_Impl(_pWhichRanges, nSize, nInitCount); + nFree += nInitCount; + } + + // neuen Which-Range anh"angen + pPtr = _pWhichRanges + nSize; + *pPtr++ = nWhich; + *pPtr = nWhich; + nFree -= 2; + + // Itemarray vergroessern + nPos = nItemCount; + _aItems = AddItem_Impl(_aItems, nItemCount, nPos); + } + + // neues Item in Pool aufnehmen + const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich ); + + // altes Item merken + BOOL bIncrementCount = FALSE; + const SfxPoolItem* pOld = *( _aItems + nPos ); + if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare" + pOld = NULL; + if ( !pOld ) + { + bIncrementCount = TRUE; + pOld = _pParent ? + &_pParent->Get( nWhich, TRUE ) + : nWhich <= SFX_WHICH_MAX ? &_pPool->GetDefaultItem( nWhich ) : 0; + } + + // neue Item in ItemSet aufnehmen + *(_aItems + nPos) = &rNew; + + // Changed Notification versenden + if ( pOld ) + { + Changed( *pOld, rNew ); + if ( !IsDefaultItem(pOld) ) + _pPool->Remove( *pOld ); + } + + if ( bIncrementCount ) + ++_nCount; + + return &rNew; +} + +// ----------------------------------------------------------------------- + + +/* Diese Methode wird forwarded, damit sie nicht durch die anderen + Put-Methoden dieser SubClass gehided wird. +*/ + +int SfxAllItemSet::Put( const SfxItemSet& rSet, BOOL bInvalidAsDefault ) +{ + //? pruefen, ob Which-Ranges erweitert werden + return SfxItemSet::Put( rSet, bInvalidAsDefault ); +} + +// ----------------------------------------------------------------------- +// Item disablen, wenn durch ein VoidItem mit dem Which-Wert 0 ausgedrueckt + +void SfxItemSet::DisableItem(USHORT nWhich) +{ + DBG_CHKTHIS(SfxItemSet, 0); + Put( SfxVoidItem(0), nWhich ); +} + +// ----------------------------------------------------------------------- + +#if 0 +BOOL SfxAllItemSet::Remove(USHORT nWhich) +{ + DBG_CHKTHIS(SfxAllItemSet, 0); + USHORT *pPtr = _pWhichRanges; + USHORT nPos = 0; + while( *pPtr ) + { + if( *pPtr <= nWhich && nWhich <= *(pPtr+1) ) + { + USHORT *pTmp = pPtr; + USHORT nLeft = 0; + USHORT nRest = 0; + while(*++pTmp){ + if( nLeft & 1 ) + nRest = *pTmp - *(pTmp-1) + 1; + ++nLeft; + } + + // in diesem Bereich + nPos += nWhich - *pPtr; + nRest -= nWhich - *pPtr; + // 3,3 + if(*pPtr == nWhich && *(pPtr+1) == nWhich) { + memmove(pPtr, pPtr + 2, nLeft * sizeof(USHORT)); + nFree += 2; + } + // Anfang + else if(*pPtr == nWhich) + (*pPtr)++; + // Ende + else if(*(pPtr+1) == nWhich) + (*(pPtr+1))--; + else { + if(nPos + nRest + 2 > nFree) { + USHORT nOf = pPtr - _pWhichRanges; + _pWhichRanges = IncrSize(_pWhichRanges, nPos + nRest, nInitCount); + nFree += nInitCount; + pPtr = _pWhichRanges + nOf; + } + memmove(pPtr +2, pPtr, (nLeft+2) * sizeof(USHORT)); + *++pPtr = nWhich-1; + *++pPtr = nWhich+1; + nFree -= 2; + } + SfxPoolItem* pItem = *( _aItems + nPos ); + if( pItem ) + { + if(_pPool) + _pPool->Remove(*pItem ); + else + delete pItem; + --_nCount; + } + memmove(_aItems + nPos +1, _aItems + nPos, + sizeof(SfxPoolItem *) * (nRest - 1)); + break; // dann beim Parent suchen + } + nPos += *(pPtr+1) - *pPtr + 1; + pPtr += 2; + } + return *pPtr? TRUE: FALSE; +} +#endif + +// ----------------------------------------------------------------------- + +SfxItemSet *SfxAllItemSet::Clone(BOOL bItems, SfxItemPool *pToPool ) const +{ + DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet); + if ( pToPool && pToPool != _pPool ) + { + SfxAllItemSet *pNewSet = new SfxAllItemSet( *pToPool ); + if ( bItems ) + pNewSet->Set( *this ); + return pNewSet; + } + else + return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*_pPool); +} + diff --git a/svl/source/items/lckbitem.cxx b/svl/source/items/lckbitem.cxx new file mode 100644 index 000000000000..04e2edb70026 --- /dev/null +++ b/svl/source/items/lckbitem.cxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * 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: lckbitem.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define _LCKBITEM_CXX +#include <svl/lckbitem.hxx> +#include <svl/poolitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <tools/cachestr.hxx> + +// STATIC DATA ----------------------------------------------------------- + + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxLockBytesItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxLockBytesItem::SfxLockBytesItem() +{ +} + +// ----------------------------------------------------------------------- + +SfxLockBytesItem::SfxLockBytesItem( USHORT nW, SvLockBytes *pLockBytes ) +: SfxPoolItem( nW ), + _xVal( pLockBytes ) +{ +} + +// ----------------------------------------------------------------------- + +SfxLockBytesItem::SfxLockBytesItem( USHORT nW, SvStream &rStream ) +: SfxPoolItem( nW ) +{ + rStream.Seek( 0L ); + _xVal = new SvLockBytes( new SvCacheStream(), TRUE ); + + SvStream aLockBytesStream( _xVal ); + rStream >> aLockBytesStream; +} + +// ----------------------------------------------------------------------- + +SfxLockBytesItem::SfxLockBytesItem( const SfxLockBytesItem& rItem ) +: SfxPoolItem( rItem ), + _xVal( rItem._xVal ) +{ +} + +// ----------------------------------------------------------------------- + +SfxLockBytesItem::~SfxLockBytesItem() +{ +} + +// ----------------------------------------------------------------------- + +int SfxLockBytesItem::operator==( const SfxPoolItem& rItem ) const +{ + return ((SfxLockBytesItem&)rItem)._xVal == _xVal; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxLockBytesItem::Clone(SfxItemPool *) const +{ + return new SfxLockBytesItem( *this ); +} + +// ----------------------------------------------------------------------- + +#define MAX_BUF 32000 + +SfxPoolItem* SfxLockBytesItem::Create( SvStream &rStream, USHORT ) const +{ + sal_uInt32 nSize = 0; + ULONG nActRead = 0; + sal_Char cTmpBuf[MAX_BUF]; + SvMemoryStream aNewStream; + rStream >> nSize; + + do { + ULONG nToRead; + if( (nSize - nActRead) > MAX_BUF ) + nToRead = MAX_BUF; + else + nToRead = nSize - nActRead; + nActRead += rStream.Read( cTmpBuf, nToRead ); + aNewStream.Write( cTmpBuf, nToRead ); + } while( nSize > nActRead ); + + return new SfxLockBytesItem( Which(), aNewStream ); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxLockBytesItem::Store(SvStream &rStream, USHORT ) const +{ + SvStream aLockBytesStream( _xVal ); + sal_uInt32 nSize = aLockBytesStream.Seek( STREAM_SEEK_TO_END ); + aLockBytesStream.Seek( 0L ); + + rStream << nSize; + rStream << aLockBytesStream; + + return rStream; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxLockBytesItem::PutValue( const com::sun::star::uno::Any& rVal, BYTE ) +{ + com::sun::star::uno::Sequence< sal_Int8 > aSeq; + if ( rVal >>= aSeq ) + { + if ( aSeq.getLength() ) + { + SvCacheStream* pStream = new SvCacheStream; + pStream->Write( (void*)aSeq.getConstArray(), aSeq.getLength() ); + pStream->Seek(0); + + _xVal = new SvLockBytes( pStream, TRUE ); + } + else + _xVal = NULL; + + return TRUE; + } + + DBG_ERROR( "SfxLockBytesItem::PutValue - Wrong type!" ); + return FALSE; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxLockBytesItem::QueryValue( com::sun::star::uno::Any& rVal,BYTE ) const +{ + if ( _xVal.Is() ) + { + sal_uInt32 nLen; + SvLockBytesStat aStat; + + if ( _xVal->Stat( &aStat, SVSTATFLAG_DEFAULT ) == ERRCODE_NONE ) + nLen = aStat.nSize; + else + return FALSE; + + ULONG nRead = 0; + com::sun::star::uno::Sequence< sal_Int8 > aSeq( nLen ); + + _xVal->ReadAt( 0, aSeq.getArray(), nLen, &nRead ); + rVal <<= aSeq; + } + else + { + com::sun::star::uno::Sequence< sal_Int8 > aSeq( 0 ); + rVal <<= aSeq; + } + + return TRUE; +} + diff --git a/svl/source/items/macitem.cxx b/svl/source/items/macitem.cxx new file mode 100644 index 000000000000..511ca2bba57c --- /dev/null +++ b/svl/source/items/macitem.cxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * 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: macitem.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/stream.hxx> + +#ifndef GCC +#endif + +#include <svl/macitem.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SvxMacroItem); + +// ----------------------------------------------------------------------- + +TYPEINIT1_FACTORY(SvxMacroItem, SfxPoolItem, new SvxMacroItem(0)); + +// ----------------------------------------------------------------------- + + +SjJSbxObjectBase::~SjJSbxObjectBase() +{ +} + +SjJSbxObjectBase* SjJSbxObjectBase::Clone( void ) +{ + return NULL; +} + +SvxMacro::SvxMacro( const String &rMacName, const String &rLanguage) + : aMacName( rMacName ), aLibName( rLanguage), + pFunctionObject(NULL), eType( EXTENDED_STYPE) +{ + if (rLanguage.EqualsAscii(SVX_MACRO_LANGUAGE_STARBASIC)) + eType=STARBASIC; + else if (rLanguage.EqualsAscii(SVX_MACRO_LANGUAGE_JAVASCRIPT)) + eType=JAVASCRIPT; +} + + +SvxMacro::~SvxMacro() +{ + delete pFunctionObject; +} + +String SvxMacro::GetLanguage()const +{ + if(eType==STARBASIC) + { + return UniString::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM(SVX_MACRO_LANGUAGE_STARBASIC)); + } + else if(eType==JAVASCRIPT) + { + return UniString::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM(SVX_MACRO_LANGUAGE_JAVASCRIPT)); + } + else if(eType==EXTENDED_STYPE) + { + return UniString::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM(SVX_MACRO_LANGUAGE_SF)); + + } + return aLibName; +} + + + +SvxMacro& SvxMacro::operator=( const SvxMacro& rBase ) +{ + if( this != &rBase ) + { + aMacName = rBase.aMacName; + aLibName = rBase.aLibName; + delete pFunctionObject; + pFunctionObject = rBase.pFunctionObject ? rBase.pFunctionObject->Clone() : NULL; + eType = rBase.eType; + } + return *this; +} + + +SvxMacroTableDtor& SvxMacroTableDtor::operator=( const SvxMacroTableDtor& rTbl ) +{ + DelDtor(); + SvxMacro* pTmp = ((SvxMacroTableDtor&)rTbl).First(); + while( pTmp ) + { + SvxMacro *pNew = new SvxMacro( *pTmp ); + Insert( rTbl.GetCurKey(), pNew ); + pTmp = ((SvxMacroTableDtor&)rTbl).Next(); + } + return *this; +} + + +SvStream& SvxMacroTableDtor::Read( SvStream& rStrm, USHORT nVersion ) +{ + if( SVX_MACROTBL_VERSION40 <= nVersion ) + rStrm >> nVersion; + short nMacro; + rStrm >> nMacro; + + for( short i = 0; i < nMacro; ++i ) + { + USHORT nCurKey, eType = STARBASIC; + String aLibName, aMacName; + rStrm >> nCurKey; + SfxPoolItem::readByteString(rStrm, aLibName); + SfxPoolItem::readByteString(rStrm, aMacName); + + if( SVX_MACROTBL_VERSION40 <= nVersion ) + rStrm >> eType; + + SvxMacro* pNew = new SvxMacro( aMacName, aLibName, (ScriptType)eType ); + + SvxMacro *pOld = Get( nCurKey ); + if( pOld ) + { + delete pOld; + Replace( nCurKey, pNew ); + } + else + Insert( nCurKey, pNew ); + } + return rStrm; +} + + +SvStream& SvxMacroTableDtor::Write( SvStream& rStream ) const +{ + USHORT nVersion = SOFFICE_FILEFORMAT_31 == rStream.GetVersion() + ? SVX_MACROTBL_VERSION31 + : SVX_MACROTBL_AKTVERSION; + + if( SVX_MACROTBL_VERSION40 <= nVersion ) + rStream << nVersion; + + rStream << (USHORT)Count(); + + SvxMacro* pMac = ((SvxMacroTableDtor*)this)->First(); + while( pMac && rStream.GetError() == SVSTREAM_OK ) + { + rStream << (short)GetCurKey(); + SfxPoolItem::writeByteString(rStream, pMac->GetLibName()); + SfxPoolItem::writeByteString(rStream, pMac->GetMacName()); + + if( SVX_MACROTBL_VERSION40 <= nVersion ) + rStream << (USHORT)pMac->GetScriptType(); + pMac = ((SvxMacroTableDtor*)this)->Next(); + } + return rStream; +} + +// ----------------------------------------------------------------------- + +void SvxMacroTableDtor::DelDtor() +{ + SvxMacro* pTmp = First(); + while( pTmp ) + { + delete pTmp; + pTmp = Next(); + } + Clear(); +} + +// ----------------------------------------------------------------------- + +int SvxMacroItem::operator==( const SfxPoolItem& rAttr ) const +{ + DBG_ASSERT( SfxPoolItem::operator==(rAttr), "unequal types" ); + + const SvxMacroTableDtor& rOwn = aMacroTable; + const SvxMacroTableDtor& rOther = ( (SvxMacroItem&) rAttr ).aMacroTable; + + // Anzahl unterschiedlich => auf jeden Fall ungleich + if ( rOwn.Count() != rOther.Count() ) + return FALSE; + + // einzeln verleichen; wegen Performance ist die Reihenfolge wichtig + for ( USHORT nNo = 0; nNo < rOwn.Count(); ++nNo ) + { + const SvxMacro *pOwnMac = rOwn.GetObject(nNo); + const SvxMacro *pOtherMac = rOther.GetObject(nNo); + if ( rOwn.GetKey(pOwnMac) != rOther.GetKey(pOtherMac) || + pOwnMac->GetLibName() != pOtherMac->GetLibName() || + pOwnMac->GetMacName() != pOtherMac->GetMacName() ) + return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SvxMacroItem::Clone( SfxItemPool* ) const +{ + return new SvxMacroItem( *this ); +} + +//------------------------------------------------------------------------ + +SfxItemPresentation SvxMacroItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + SfxMapUnit /*eCoreUnit*/, + SfxMapUnit /*ePresUnit*/, + XubString& rText, + const IntlWrapper * +) const +{ +/*!!! + SvxMacroTableDtor& rTbl = (SvxMacroTableDtor&)GetMacroTable(); + SvxMacro* pMac = rTbl.First(); + + while ( pMac ) + { + rText += pMac->GetLibName(); + rText += cpDelim; + rText += pMac->GetMacName(); + pMac = rTbl.Next(); + if ( pMac ) + rText += cpDelim; + } +*/ + rText.Erase(); + return SFX_ITEM_PRESENTATION_NONE; +} + +// ----------------------------------------------------------------------- + +SvStream& SvxMacroItem::Store( SvStream& rStrm , USHORT ) const +{ + return aMacroTable.Write( rStrm ); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SvxMacroItem::Create( SvStream& rStrm, USHORT nVersion ) const +{ + SvxMacroItem* pAttr = new SvxMacroItem( Which() ); + pAttr->aMacroTable.Read( rStrm, nVersion ); + return pAttr; +} + +// ----------------------------------------------------------------------- + +void SvxMacroItem::SetMacro( USHORT nEvent, const SvxMacro& rMacro ) +{ + SvxMacro *pMacro; + if ( 0 != (pMacro=aMacroTable.Get(nEvent)) ) + { + delete pMacro; + aMacroTable.Replace(nEvent, new SvxMacro( rMacro ) ); + } + else + aMacroTable.Insert(nEvent, new SvxMacro( rMacro ) ); +} + +// ----------------------------------------------------------------------- + +USHORT SvxMacroItem::GetVersion( USHORT nFileFormatVersion ) const +{ + return SOFFICE_FILEFORMAT_31 == nFileFormatVersion + ? 0 : aMacroTable.GetVersion(); +} + diff --git a/svl/source/items/makefile.mk b/svl/source/items/makefile.mk new file mode 100644 index 000000000000..d779e16e24d1 --- /dev/null +++ b/svl/source/items/makefile.mk @@ -0,0 +1,87 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.13 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=svl +TARGET=items +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/aeitem.obj \ + $(SLO)$/cenumitm.obj \ + $(SLO)$/cintitem.obj \ + $(SLO)$/cntwall.obj \ + $(SLO)$/ctypeitm.obj \ + $(SLO)$/custritm.obj \ + $(SLO)$/dateitem.obj \ + $(SLO)$/eitem.obj \ + $(SLO)$/flagitem.obj \ + $(SLO)$/globalnameitem.obj \ + $(SLO)$/ilstitem.obj \ + $(SLO)$/imageitm.obj \ + $(SLO)$/intitem.obj \ + $(SLO)$/itemiter.obj \ + $(SLO)$/itempool.obj \ + $(SLO)$/itemprop.obj \ + $(SLO)$/itemset.obj \ + $(SLO)$/lckbitem.obj \ + $(SLO)$/macitem.obj \ + $(SLO)$/poolcach.obj \ + $(SLO)$/poolio.obj \ + $(SLO)$/poolitem.obj \ + $(SLO)$/ptitem.obj \ + $(SLO)$/rectitem.obj \ + $(SLO)$/rngitem.obj \ + $(SLO)$/sfontitm.obj \ + $(SLO)$/sitem.obj \ + $(SLO)$/slstitm.obj \ + $(SLO)$/stritem.obj \ + $(SLO)$/style.obj \ + $(SLO)$/stylepool.obj \ + $(SLO)$/szitem.obj \ + $(SLO)$/visitem.obj \ + $(SLO)$/whiter.obj + +SRS1NAME=$(TARGET) +SRC1FILES=\ + cstitem.src + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/items/nranges.cxx b/svl/source/items/nranges.cxx new file mode 100644 index 000000000000..789da8dc5ff9 --- /dev/null +++ b/svl/source/items/nranges.cxx @@ -0,0 +1,853 @@ +/************************************************************************* + * + * 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: nranges.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +// compiled via include from itemset.cxx only! + +//======================================================================== + +#ifdef DBG_UTIL + +#define DBG_CHECK_RANGES(NUMTYPE, pArr) \ + for ( const NUMTYPE *pRange = pArr; *pRange; pRange += 2 ) \ + { \ + DBG_ASSERT( pRange[0] <= pRange[1], "ranges must be sorted" ); \ + DBG_ASSERT( !pRange[2] || ( pRange[2] - pRange[1] ) > 1, \ + "ranges must be sorted and discrete" ); \ + } + +#else + +#define DBG_CHECK_RANGES(NUMTYPE,pArr) + +#endif + +//============================================================================ +inline void Swap_Impl(const NUMTYPE *& rp1, const NUMTYPE *& rp2) +{ + const NUMTYPE * pTemp = rp1; + rp1 = rp2; + rp2 = pTemp; +} + +//======================================================================== + +NUMTYPE InitializeRanges_Impl( NUMTYPE *&rpRanges, va_list pArgs, + NUMTYPE nWh1, NUMTYPE nWh2, NUMTYPE nNull ) + +/** <H3>Description</H3> + + Creates an USHORT-ranges-array in 'rpRanges' using 'nWh1' and 'nWh2' as + first range, 'nNull' as terminator or start of 2nd range and 'pArgs' as + remaider. + + It returns the number of NUMTYPEs which are contained in the described + set of NUMTYPEs. +*/ + +{ + NUMTYPE nSize = 0, nIns = 0; + USHORT nCnt = 0; + SvNums aNumArr( 11, 8 ); + aNumArr.Insert( nWh1, nCnt++ ); + aNumArr.Insert( nWh2, nCnt++ ); + DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" ); + nSize += nWh2 - nWh1 + 1; + aNumArr.Insert( nNull, nCnt++ ); + while ( 0 != + ( nIns = + sal::static_int_cast< NUMTYPE >( + va_arg( pArgs, NUMTYPE_ARG ) ) ) ) + { + aNumArr.Insert( nIns, nCnt++ ); + if ( 0 == (nCnt & 1) ) // 4,6,8, usw. + { + DBG_ASSERT( aNumArr[ nCnt-2 ] <= nIns, "Ungueltiger Bereich" ); + nSize += nIns - aNumArr[ nCnt-2 ] + 1; + } + } + va_end( pArgs ); + + DBG_ASSERT( 0 == (nCnt & 1), "ungerade Anzahl von Which-Paaren!" ); + + // so, jetzt sind alle Bereiche vorhanden und + rpRanges = new NUMTYPE[ nCnt+1 ]; + memcpy( rpRanges, aNumArr.GetData(), sizeof(NUMTYPE) * nCnt ); + *(rpRanges+nCnt) = 0; + + return nSize; +} + +//------------------------------------------------------------------------ + +NUMTYPE Count_Impl( const NUMTYPE *pRanges ) + +/** <H3>Description</H3> + + Determines the number of NUMTYPEs in an 0-terminated array of pairs of + NUMTYPEs. The terminating 0 is not included in the count. +*/ + +{ + NUMTYPE nCount = 0; + while ( *pRanges ) + { + nCount += 2; + pRanges += 2; + } + return nCount; +} + +//------------------------------------------------------------------------ + +NUMTYPE Capacity_Impl( const NUMTYPE *pRanges ) + +/** <H3>Description</H3> + + Determines the total number of NUMTYPEs described in an 0-terminated + array of pairs of NUMTYPEs, each representing an range of NUMTYPEs. +*/ + +{ + NUMTYPE nCount = 0; + + if ( pRanges ) + { + while ( *pRanges ) + { + nCount += pRanges[1] - pRanges[0] + 1; + pRanges += 2; + } + } + return nCount; +} + +//------------------------------------------------------------------------ + +SfxNumRanges::SfxNumRanges( const SfxNumRanges &rOrig ) + +/** <H3>Description</H3> + + Copy-Ctor. +*/ + +{ + if ( rOrig._pRanges ) + { + NUMTYPE nCount = Count_Impl( rOrig._pRanges ) + 1; + _pRanges = new NUMTYPE[nCount]; + memcpy( _pRanges, rOrig._pRanges, sizeof(NUMTYPE) * nCount ); + } + else + _pRanges = 0; +} + +//------------------------------------------------------------------------ + +SfxNumRanges::SfxNumRanges( NUMTYPE nWhich1, NUMTYPE nWhich2 ) + +/** <H3>Description</H3> + + Constructs an SfxNumRanges-instance from one range of NUMTYPEs. + + precondition: + nWhich1 <= nWhich2 +*/ + +: _pRanges( new NUMTYPE[3] ) +{ + _pRanges[0] = nWhich1; + _pRanges[1] = nWhich2; + _pRanges[2] = 0; +} + +//------------------------------------------------------------------------ + +SfxNumRanges::SfxNumRanges( NUMTYPE_ARG nWh0, NUMTYPE_ARG nWh1, NUMTYPE_ARG nNull, ... ) + +/** <H3>Description</H3> + + Constructs an SfxNumRanges-instance from more than one sorted ranges of + NUMTYPEs terminated with one 0. + + precondition: for each n >= 0 && n < nArgs + nWh(2n) <= nWh(2n+1) && ( nWh(2n+2)-nWh(2n+1) ) > 1 +*/ + +{ + va_list pArgs; + va_start( pArgs, nNull ); + InitializeRanges_Impl( + _pRanges, pArgs, sal::static_int_cast< NUMTYPE >(nWh0), + sal::static_int_cast< NUMTYPE >(nWh1), + sal::static_int_cast< NUMTYPE >(nNull)); + DBG_CHECK_RANGES(NUMTYPE, _pRanges); +} + +//------------------------------------------------------------------------ + +SfxNumRanges::SfxNumRanges( const NUMTYPE* pArr ) + +/** <H3>Description</H3> + + Constcurts an SfxNumRanges-instance from an sorted ranges of NUMTYPEs, + terminates with on 0. + + precondition: for each n >= 0 && n < (sizeof(pArr)-1) + pArr[2n] <= pArr[2n+1] && ( pArr[2n+2]-pArr[2n+1] ) > 1 +*/ + +{ + DBG_CHECK_RANGES(NUMTYPE, pArr); + NUMTYPE nCount = Count_Impl(pArr) + 1; + _pRanges = new NUMTYPE[ nCount ]; + memcpy( _pRanges, pArr, sizeof(NUMTYPE) * nCount ); +} + +//------------------------------------------------------------------------ + +BOOL SfxNumRanges::operator==( const SfxNumRanges &rOther ) const +{ + // Object pointers equal? + if ( this == &rOther ) + return TRUE; + + // Ranges pointers equal? + if ( _pRanges == rOther._pRanges ) + return TRUE; + + // Counts equal? + NUMTYPE nCount = Count(); + if ( nCount != rOther.Count() ) + return FALSE; + + // Check arrays. + NUMTYPE n = 0; + while( _pRanges[ n ] != 0 ) + { + // Elements at current position equal? + if ( _pRanges[ n ] != rOther._pRanges[ n ] ) + return FALSE; + + ++n; + } + + return TRUE; +} + +//------------------------------------------------------------------------ + +SfxNumRanges& SfxNumRanges::operator = +( + const SfxNumRanges &rRanges +) + +/** <H3>Description</H3> + + Assigns ranges from 'rRanges' to '*this'. +*/ + +{ + // special case: assign itself + if ( &rRanges == this ) + return *this; + + delete[] _pRanges; + + // special case: 'rRanges' is empty + if ( rRanges.IsEmpty() ) + _pRanges = 0; + else + { + // copy ranges + NUMTYPE nCount = Count_Impl( rRanges._pRanges ) + 1; + _pRanges = new NUMTYPE[ nCount ]; + memcpy( _pRanges, rRanges._pRanges, sizeof(NUMTYPE) * nCount ); + } + return *this; +} + +//------------------------------------------------------------------------ + +SfxNumRanges& SfxNumRanges::operator += +( + const SfxNumRanges &rRanges +) + +/** <H3>Description</H3> + + Merges *this with 'rRanges'. + + for each NUMTYPE n: + this->Contains( n ) || rRanges.Contains( n ) => this'->Contains( n ) + !this->Contains( n ) && !rRanges.Contains( n ) => !this'->Contains( n ) +*/ + +{ + // special cases: one is empty + if ( rRanges.IsEmpty() ) + return *this; + if ( IsEmpty() ) + return *this = rRanges; + + // First, run thru _pRanges and rRanges._pRanges and determine the size of + // the new, merged ranges: + NUMTYPE nCount = 0; + const NUMTYPE * pRA = _pRanges; + const NUMTYPE * pRB = rRanges._pRanges; + + for (;;) + { + // The first pair of pRA has a lower lower bound than the first pair + // of pRB: + if (pRA[0] > pRB[0]) + Swap_Impl(pRA, pRB); + + // We are done with the merging if at least pRA is exhausted: + if (!pRA[0]) + break; + + for (;;) + { + // Skip those pairs in pRB that completely lie in the first pair + // of pRA: + while (pRB[1] <= pRA[1]) + { + pRB += 2; + + // Watch out for exhaustion of pRB: + if (!pRB[0]) + { + Swap_Impl(pRA, pRB); + goto count_rest; + } + } + + // If the next pair of pRA does not at least touch the current new + // pair, we are done with the current new pair: + if (pRB[0] > pRA[1] + 1) + break; + + // The next pair of pRB extends the current new pair; first, + // extend the current new pair (we are done if pRB is then + // exhausted); second, switch the roles of pRA and pRB in order to + // merge in those following pairs of the original pRA that will + // lie in the (now larger) current new pair or will even extend it + // further: + pRA += 2; + if (!pRA[0]) + goto count_rest; + Swap_Impl(pRA, pRB); + } + + // Done with the current new pair: + pRA += 2; + nCount += 2; + } + + // Only pRB has more pairs available, pRA is already exhausted: +count_rest: + for (; pRB[0]; pRB += 2) + nCount += 2; + + // Now, create new ranges of the correct size and, on a second run thru + // _pRanges and rRanges._pRanges, copy the merged pairs into the new + // ranges: + NUMTYPE * pNew = new NUMTYPE[nCount + 1]; + pRA = _pRanges; + pRB = rRanges._pRanges; + NUMTYPE * pRN = pNew; + + for (;;) + { + // The first pair of pRA has a lower lower bound than the first pair + // of pRB: + if (pRA[0] > pRB[0]) + Swap_Impl(pRA, pRB); + + // We are done with the merging if at least pRA is exhausted: + if (!pRA[0]) + break; + + // Lower bound of current new pair is already known: + *pRN++ = pRA[0]; + + for (;;) + { + // Skip those pairs in pRB that completely lie in the first pair + // of pRA: + while (pRB[1] <= pRA[1]) + { + pRB += 2; + + // Watch out for exhaustion of pRB: + if (!pRB[0]) + { + Swap_Impl(pRA, pRB); + ++pRB; + goto copy_rest; + } + } + + // If the next pair of pRA does not at least touch the current new + // pair, we are done with the current new pair: + if (pRB[0] > pRA[1] + 1) + break; + + // The next pair of pRB extends the current new pair; first, + // extend the current new pair (we are done if pRB is then + // exhausted); second, switch the roles of pRA and pRB in order to + // merge in those following pairs of the original pRA that will + // lie in the (now larger) current new pair or will even extend it + // further: + pRA += 2; + if (!pRA[0]) + { + ++pRB; + goto copy_rest; + } + Swap_Impl(pRA, pRB); + } + + // Done with the current new pair, now upper bound is also known: + *pRN++ = pRA[1]; + pRA += 2; + } + + // Only pRB has more pairs available (which are copied to the new ranges + // unchanged), pRA is already exhausted: +copy_rest: + for (; *pRB;) + *pRN++ = *pRB++; + *pRN = 0; + + delete[] _pRanges; + _pRanges = pNew; + + return *this; +} + +//------------------------------------------------------------------------ + +SfxNumRanges& SfxNumRanges::operator -= +( + const SfxNumRanges &rRanges +) + +/** <H3>Description</H3> + + Removes 'rRanges' from '*this'. + + for each NUMTYPE n: + this->Contains( n ) && rRanges.Contains( n ) => !this'->Contains( n ) + this->Contains( n ) && !rRanges.Contains( n ) => this'->Contains( n ) + !this->Contains( n ) => !this'->Contains( n ) +*/ + +{ + // special cases: one is empty + if ( rRanges.IsEmpty() || IsEmpty() ) + return *this; + + // differentiate 'rRanges' in a temporary copy of '*this' + // (size is computed for maximal possibly split-count plus terminating 0) + NUMTYPE nThisSize = Count_Impl(_pRanges); + NUMTYPE nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) ); + NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ]; + memset( pTarget, sizeof(NUMTYPE)*nTargetSize, 0 ); + memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize ); + + NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0; + while( _pRanges[ nPos1 ] ) + { + NUMTYPE l1 = _pRanges[ nPos1 ]; // lower bound of interval 1 + NUMTYPE u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1 + NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2 + NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2 + + // boundary cases + // * subtrahend is empty -> copy the minuend + if( !l2 ) + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = u1; + nTargetPos += 2; + nPos1 += 2; + continue; + } + // * next subtrahend interval is completely higher -> copy the minuend + if( u1 < l2 ) + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = u1; + nTargetPos += 2; + nPos1 += 2; + continue; + } + + // * next subtrahend interval is completely lower -> try next + if( u2 < l1 ) + { + nPos2 += 2; + continue; + } + + // intersecting cases + // * subtrahend cuts out from the beginning of the minuend + if( l2 <= l1 && u2 <= u1 ) + { + // reduce minuend interval, try again (minuend might be affected by other subtrahend intervals) + _pRanges[ nPos1 ] = u2 + 1; + nPos2 += 2; // this cannot hurt any longer + continue; + } + + // * subtrahend cuts out from the end of the minuend + if( l1 <= l2 && u1 <= u2 ) + { + // copy remaining part of minuend (cannot be affected by other intervals) + if( l1 < l2 ) // anything left at all? + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = l2 - 1; + nTargetPos += 2; + // do not increment nPos2, might affect next minuend interval, too + } + nPos1 += 2; // nothing left at all + continue; + } + + // * subtrahend completely deletes minuend (larger or same at both ends) + if( l1 >= l2 && u1 <= u2 ) + { + nPos1 += 2; // minuend deleted + // do not increment nPos2, might affect next minuend interval, too + continue; + } + + // * subtrahend divides minuend into two pieces + if( l1 <= l2 && u1 >= u2 ) // >= and <= since they may be something left only at one side + { + // left side + if( l1 < l2 ) // anything left at all + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = l2 - 1; + nTargetPos += 2; + } + + // right side + if( u1 > u2 ) // anything left at all + { + // reduce minuend interval, try again (minuend might be affected by other subtrahend itnervals ) + _pRanges[ nPos1 ] = u2 + 1; + } + + // subtrahend is completely used + nPos2 += 2; + continue; + } + + // we should never be here + DBG_ERROR( "SfxNumRanges::operator-=: internal error" ); + } // while + + pTarget[ nTargetPos ] = 0; + + // assign the differentiated ranges + delete[] _pRanges; + + NUMTYPE nUShorts = Count_Impl(pTarget) + 1; + if ( 1 != nUShorts ) + { + _pRanges = new NUMTYPE[ nUShorts ]; + memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) ); + } + else + _pRanges = 0; + + delete [] pTarget; + return *this; + + /* untested code from MI commented out (MDA, 28.01.97) + do + { + // 1st range is smaller than 2nd range? + if ( pRange1[1] < pRange2[0] ) + // => keep 1st range + pRange1 += 2; + + // 2nd range is smaller than 1st range? + else if ( pRange2[1] < pRange1[0] ) + // => skip 2nd range + pRange2 += 2; + + // 2nd range totally overlaps the 1st range? + else if ( pRange2[0] <= pRange1[0] && pRange2[1] >= pRange1[1] ) + // => remove 1st range + memmove( pRange1, pRange1+2, sizeof(NUMTYPE) * (pEndOfTarget-pRange1+2) ); + + // 2nd range overlaps only the beginning of 1st range? + else if ( pRange2[0] <= pRange1[0] && pRange2[1] < pRange1[1] ) + { + // => cut the beginning of 1st range and goto next 2nd range + pRange1[0] = pRange2[1] + 1; + pRange2 += 2; + } + + // 2nd range overlaps only the end of 1st range? + else if ( pRange2[0] > pRange1[0] && pRange2[1] >= pRange1[0] ) + // => cut the beginning of 1st range + pRange1[0] = pRange2[1]+1; + + // 2nd range is a real subset of 1st range + else + { + // => split 1st range and goto next 2nd range + memmove( pRange1+3, pRange1+1, sizeof(NUMTYPE) * (pEndOfTarget-pRange1-1) ); + pRange1[1] = pRange2[0] - 1; + pRange1[2] = pRange2[1] + 1; + pRange1 += 2; + pRange2 += 2; + } + } + while ( *pRange1 && *pRange2 ); + + // assign the differentiated ranges + delete[] _pRanges; + NUMTYPE nUShorts = Count_Impl(pTarget) + 1; + if ( 1 != nUShorts ) + { + _pRanges = new NUMTYPE[ nUShorts ]; + memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) ); + _pRanges[ nUShorts-1 ] = 0; + } + else + _pRanges = 0; + return *this; + */ +} + +//------------------------------------------------------------------------ + +SfxNumRanges& SfxNumRanges::operator /= +( + const SfxNumRanges &rRanges +) + +/** <H3>Description</H3> + + Determines intersection of '*this' with 'rRanges'. + + for each NUMTYPE n: + this->Contains( n ) && rRanges.Contains( n ) => this'->Contains( n ) + !this->Contains( n ) => !this'->Contains( n ) + !rRanges.Contains( n ) => !this'->Contains( n ) +*/ + +{ + // boundary cases + // * first set is empty -> nothing to be done + // * second set is empty -> delete first set + if( rRanges.IsEmpty() ) + { + delete[] _pRanges; + + _pRanges = new NUMTYPE[1]; + _pRanges[0] = 0; + + return *this; + } + + // intersect 'rRanges' in a temporary copy of '*this' + // (size is computed for maximal possibly split-count plus terminating 0) + NUMTYPE nThisSize = Count_Impl(_pRanges); + NUMTYPE nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) ); + NUMTYPE *pTarget = new NUMTYPE[ nTargetSize ]; + memset( pTarget, sizeof(NUMTYPE)*nTargetSize, 0 ); + memcpy( pTarget, _pRanges, sizeof(NUMTYPE)*nThisSize ); + + NUMTYPE nPos1 = 0, nPos2 = 0, nTargetPos = 0; + while( _pRanges[ nPos1 ] != 0 && rRanges._pRanges[ nPos2 ] != 0 ) + { + NUMTYPE l1 = _pRanges[ nPos1 ]; // lower bound of interval 1 + NUMTYPE u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1 + NUMTYPE l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2 + NUMTYPE u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2 + + if( u1 < l2 ) + { + // current interval in s1 is completely before ci in s2 + nPos1 += 2; + continue; + } + if( u2 < l1 ) + { + // ci in s2 is completely before ci in s1 + nPos2 += 2; + continue; + } + + // assert: there exists an intersection between ci1 and ci2 + + if( l1 <= l2 ) + { + // c1 "is more to the left" than c2 + + if( u1 <= u2 ) + { + pTarget[ nTargetPos ] = l2; + pTarget[ nTargetPos+1 ] = u1; + nTargetPos += 2; + nPos1 += 2; + continue; + } + else + { + pTarget[ nTargetPos ] = l2; + pTarget[ nTargetPos+1 ] = u2; + nTargetPos += 2; + nPos2 += 2; + } + } + else + { + // c2 "is more to the left" than c1" + + if( u1 > u2 ) + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = u2; + nTargetPos += 2; + nPos2 += 2; + } + else + { + pTarget[ nTargetPos ] = l1; + pTarget[ nTargetPos+1 ] = u1; + nTargetPos += 2; + nPos1 += 2; + } + } + }; // while + pTarget[ nTargetPos ] = 0; + + // assign the intersected ranges + delete[] _pRanges; + + NUMTYPE nUShorts = Count_Impl(pTarget) + 1; + if ( 1 != nUShorts ) + { + _pRanges = new NUMTYPE[ nUShorts ]; + memcpy( _pRanges, pTarget, nUShorts * sizeof(NUMTYPE) ); + } + else + _pRanges = 0; + + delete [] pTarget; + return *this; +} + +//------------------------------------------------------------------------ + +BOOL SfxNumRanges::Intersects( const SfxNumRanges &rRanges ) const + +/** <H3>Description</H3> + + Determines if at least one range in 'rRanges' intersects with one + range in '*this'. + + TRUE, if there is at least one with: + this->Contains( n ) && rRanges.Contains( n ) +*/ + +{ + // special cases: one is empty + if ( rRanges.IsEmpty() || IsEmpty() ) + return FALSE; + + // find at least one intersecting range + const NUMTYPE *pRange1 = _pRanges; + const NUMTYPE *pRange2 = rRanges._pRanges; + + do + { + // 1st range is smaller than 2nd range? + if ( pRange1[1] < pRange2[0] ) + // => keep 1st range + pRange1 += 2; + + // 2nd range is smaller than 1st range? + else if ( pRange2[1] < pRange1[0] ) + // => skip 2nd range + pRange2 += 2; + + // the ranges are overlappung + else + return TRUE; + } + while ( *pRange2 ); + + // no intersection found + return FALSE; +} + +//------------------------------------------------------------------------ + +NUMTYPE SfxNumRanges::Count() const + +/** <H3>Description</H3> + + Determines the number of USHORTs in the set described by the ranges + of USHORTs in '*this'. +*/ + +{ + return Capacity_Impl( _pRanges ); +} + +//------------------------------------------------------------------------ + +BOOL SfxNumRanges::Contains( NUMTYPE n ) const + +/** <H3>Description</H3> + + Determines if '*this' contains 'n'. +*/ + +{ + for ( NUMTYPE *pRange = _pRanges; *pRange && *pRange <= n; pRange += 2 ) + if ( pRange[0] <= n && n <= pRange[1] ) + return TRUE; + return FALSE; + +} diff --git a/svl/source/items/poolcach.cxx b/svl/source/items/poolcach.cxx new file mode 100644 index 000000000000..e64325213ff4 --- /dev/null +++ b/svl/source/items/poolcach.cxx @@ -0,0 +1,159 @@ +/************************************************************************* + * + * 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: poolcach.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <limits.h> + +#ifndef GCC +#endif + +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include "poolcach.hxx" + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxItemPoolCache) + + +//------------------------------------------------------------------------ + +struct SfxItemModifyImpl +{ + const SfxSetItem *pOrigItem; + SfxSetItem *pPoolItem; +}; + +SV_DECL_VARARR( SfxItemModifyArr_Impl, SfxItemModifyImpl, 8, 8 ) +SV_IMPL_VARARR( SfxItemModifyArr_Impl, SfxItemModifyImpl); + +//------------------------------------------------------------------------ + +SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, + const SfxPoolItem *pPutItem ): + pPool(pItemPool), + pCache(new SfxItemModifyArr_Impl), + pSetToPut( 0 ), + pItemToPut( &pItemPool->Put(*pPutItem) ) +{ + DBG_CTOR(SfxItemPoolCache, 0); + DBG_ASSERT(pItemPool, "kein Pool angegeben"); +} + +//------------------------------------------------------------------------ + +SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, + const SfxItemSet *pPutSet ): + pPool(pItemPool), + pCache(new SfxItemModifyArr_Impl), + pSetToPut( pPutSet ), + pItemToPut( 0 ) +{ + DBG_CTOR(SfxItemPoolCache, 0); + DBG_ASSERT(pItemPool, "kein Pool angegeben"); +} + +//------------------------------------------------------------------------ + +SfxItemPoolCache::~SfxItemPoolCache() +{ + DBG_DTOR(SfxItemPoolCache, 0); + for ( USHORT nPos = 0; nPos < pCache->Count(); ++nPos ) { + pPool->Remove( *(*pCache)[nPos].pPoolItem ); + pPool->Remove( *(*pCache)[nPos].pOrigItem ); + } + delete pCache; pCache = 0; + + if ( pItemToPut ) + pPool->Remove( *pItemToPut ); +} + +//------------------------------------------------------------------------ + +const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem, BOOL bNew ) +{ + DBG_CHKTHIS(SfxItemPoolCache, 0); + DBG_ASSERT( pPool == rOrigItem.GetItemSet().GetPool(), "invalid Pool" ); + DBG_ASSERT( IsDefaultItem( &rOrigItem ) || IsPooledItem( &rOrigItem ), + "original not in pool" ); + + // Suchen, ob diese Transformations schon einmal vorkam + for ( USHORT nPos = 0; nPos < pCache->Count(); ++nPos ) + { + SfxItemModifyImpl &rMapEntry = (*pCache)[nPos]; + if ( rMapEntry.pOrigItem == &rOrigItem ) + { + // aendert sich ueberhaupt etwas? + if ( rMapEntry.pPoolItem != &rOrigItem ) + { + rMapEntry.pPoolItem->AddRef(2); // einen davon fuer den Cache + if ( bNew ) + pPool->Put( rOrigItem ); //! AddRef?? + } + return *rMapEntry.pPoolItem; + } + } + + // die neue Attributierung in einem neuen Set eintragen + SfxSetItem *pNewItem = (SfxSetItem *)rOrigItem.Clone(); + if ( pItemToPut ) + { + pNewItem->GetItemSet().PutDirect( *pItemToPut ); + DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, + "wrong item in temporary set" ); + } + else + pNewItem->GetItemSet().Put( *pSetToPut ); + const SfxSetItem* pNewPoolItem = (const SfxSetItem*) &pPool->Put( *pNewItem ); + DBG_ASSERT( pNewPoolItem != pNewItem, "Pool: rein == raus?" ); + delete pNewItem; + + // Refernzzaehler anpassen, je einen davon fuer den Cache + pNewPoolItem->AddRef( pNewPoolItem != &rOrigItem ? 2 : 1 ); + if ( bNew ) + pPool->Put( rOrigItem ); //! AddRef?? + + // die Transformation im Cache eintragen + SfxItemModifyImpl aModify; + aModify.pOrigItem = &rOrigItem; + aModify.pPoolItem = (SfxSetItem*) pNewPoolItem; + pCache->Insert( aModify, pCache->Count() ); + + DBG_ASSERT( !pItemToPut || + &pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, + "wrong item in resulting set" ); + + return *pNewPoolItem; +} + + + diff --git a/svl/source/items/poolio.cxx b/svl/source/items/poolio.cxx new file mode 100644 index 000000000000..4383ac99d2ed --- /dev/null +++ b/svl/source/items/poolio.cxx @@ -0,0 +1,1715 @@ +/************************************************************************* + * + * 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: poolio.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <string.h> +#include <stdio.h> + +#ifndef GCC +#endif + +#include <tools/solar.h> +#include <svl/itempool.hxx> +#include "whassert.hxx" +#include <svl/brdcst.hxx> +#include <svl/filerec.hxx> +#include <svl/svldata.hxx> +#include "poolio.hxx" + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxItemPool); + +//======================================================================== + +void SfxItemPool::SetStoringPool( const SfxItemPool *pStoringPool ) + +/* [Beschreibung] + + Diese Methode setzt den <SfxItemPool>, der gerade gespeichert wird. + Sie sollte nur in Notf"allen verwendet werden, um z.B. File-Format- + Kompatibilit"at zu gew"ahrleisten o."o. - z.B. in der "uberladung eines + <SfxPoolItem::Store()> zus"atzliche Daten aus dem dazuge"horigen + Pool mit <SfxItemPool::GetStoringPool()> zu besorgen. + + Sie wird von <SfxItemPool::Store()> bedient, kann jedoch f"ur nicht + poolable Items auch direkt gerufen werden. Bitte m"oglichst nicht + f"ur jedes Item einzeln, da 2 Calls! +*/ + +{ + ImpSvlData::GetSvlData().pStoringPool = pStoringPool; +} + +//------------------------------------------------------------------------- + +const SfxItemPool* SfxItemPool::GetStoringPool() + +/* [Beschreibung] + + Diese Methode liefert den <SfxItemPool>, der gerade gespeichert wird. + Sie sollte nur in Notf"allen verwendet werden, um z.B. File-Format- + Kompatibilit"at zu gew"ahrleisten o."o. - z.B. in der "uberladung eines + <SfxPoolItem::Store()> zus"atzliche Daten aus dem dazuge"horigen + Pool zu besorgen. +*/ + +{ + return ImpSvlData::GetSvlData().pStoringPool; +} + +//------------------------------------------------------------------------- + +SvStream &SfxItemPool::Store(SvStream &rStream) const + +/* [Beschreibung] + + Der SfxItemPool wird inklusive aller seiner Sekund"arpools mit + Pool-Defaults und gepoolten Items in dem angegebenen Stream gespeichert. + Die statischen Defaults werden nicht gespeichert. + + + [Fileformat] + + ;zun"achst ein Kompatiblit"ats-Header-Block + Start: 0x1111 SFX_ITEMPOOL_TAG_STARTPOOLS(_4/_5) + BYTE MAJOR_VER ;SfxItemPool-Version + BYTE MINOR_VER ;" + 0xFFFF SFX_ITEMPOOL_TAG_TRICK4OLD ;ex. GetVersion() + USHORT 0x0000 ;Pseudo-StyleSheetPool + USHORT 0x0000 ;Pseudo-StyleSheetPool + + ;den ganzen Pool in einen Record + record SfxMiniRecod(SFX_ITEMPOOL_REC) + + ;je ein Header vorweg + Header: record SfxMiniRecord(SFX_ITEMPOOL_REC_HEADER) + USHORT GetVersion() ;Which-Ranges etc. + String GetName() ;Pool-Name + + ;die Versions-Map, um WhichIds neuer File-Versionen mappen zu k"onnen + Versions: record SfxMultiRecord(SFX_ITEMPOOL_REC_VERSIONS, 0) + USHORT OldVersion + USHORT OldStartWhich + USHORT OldEndWhich + USHORT[] NewWhich (OldEndWhich-OldStartWhich+1) + + ;jetzt die gepoolten Items (zuerst nicht-SfxSetItems) + Items: record SfxMultiRecord(SFX_ITEMPOOL_REC_WHICHIDS, 0) + content SlotId, 0 + USHORT WhichId + USHORT pItem->GetVersion() + USHORT Array-Size + record SfxMultiRecord(SFX_, 0) + content Surrogate + USHORT RefCount + unknown pItem->Store() + + ;jetzt die gesetzten Pool-Defaults + Defaults: record SfxMultiRecord(SFX_ITEMPOOL_REC_DEFAULTS, 0) + content SlotId, 0 + USHORT WhichId + USHORT pPoolDef->GetVersion() + unknown pPoolDef->Store(); + + ;dahinter folgt ggf. der Secondary ohne Kompatiblit"ats-Header-Block +*/ + +{ + DBG_CHKTHIS(SfxItemPool, 0); + + // Store-Master finden + SfxItemPool *pStoreMaster = pMaster != this ? pMaster : 0; + while ( pStoreMaster && !pStoreMaster->pImp->bStreaming ) + pStoreMaster = pStoreMaster->pSecondary; + + // Alter-Header (Version des Pools an sich und Inhalts-Version 0xffff) + pImp->bStreaming = TRUE; + if ( !pStoreMaster ) + { + rStream << ( rStream.GetVersion() >= SOFFICE_FILEFORMAT_50 + ? SFX_ITEMPOOL_TAG_STARTPOOL_5 + : SFX_ITEMPOOL_TAG_STARTPOOL_4 ); + rStream << SFX_ITEMPOOL_VER_MAJOR << SFX_ITEMPOOL_VER_MINOR; + rStream << SFX_ITEMPOOL_TAG_TRICK4OLD; + + // SfxStyleSheet-Bug umgehen + rStream << UINT16(0); // Version + rStream << UINT16(0); // Count (2. Schleife f"allt sonst auf die Fresse) + } + + // jeder Pool ist als ganzes ein Record + SfxMiniRecordWriter aPoolRec( &rStream, SFX_ITEMPOOL_REC ); + ImpSvlData::GetSvlData().pStoringPool = this; + + // Einzel-Header (Version des Inhalts und Name) + { + SfxMiniRecordWriter aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER); + rStream << pImp->nVersion; + SfxPoolItem::writeByteString(rStream, aName); + } + + // Version-Maps + { + SfxMultiVarRecordWriter aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP, 0 ); + for ( USHORT nVerNo = 0; nVerNo < pImp->aVersions.Count(); ++nVerNo ) + { + aVerRec.NewContent(); + SfxPoolVersion_Impl *pVer = pImp->aVersions[nVerNo]; + rStream << pVer->_nVer << pVer->_nStart << pVer->_nEnd; + USHORT nCount = pVer->_nEnd - pVer->_nStart + 1; + USHORT nNewWhich = 0; + for ( USHORT n = 0; n < nCount; ++n ) + { + nNewWhich = pVer->_pMap[n]; + rStream << nNewWhich; + } + + // Workaround gegen Bug in SetVersionMap der 312 + if ( SOFFICE_FILEFORMAT_31 == _nFileFormatVersion ) + rStream << USHORT(nNewWhich+1); + } + } + + // gepoolte Items + { + SfxMultiMixRecordWriter aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS, 0 ); + + // erst Atomaren-Items und dann die Sets schreiben (wichtig beim Laden) + for ( pImp->bInSetItem = FALSE; pImp->bInSetItem <= TRUE && !rStream.GetError(); ++pImp->bInSetItem ) + { + SfxPoolItemArray_Impl **pArr = pImp->ppPoolItems; + SfxPoolItem **ppDefItem = ppStaticDefaults; + const USHORT nSize = GetSize_Impl(); + for ( USHORT i = 0; i < nSize && !rStream.GetError(); ++i, ++pArr, ++ppDefItem ) + { + // Version des Items feststellen + USHORT nItemVersion = (*ppDefItem)->GetVersion( _nFileFormatVersion ); + if ( USHRT_MAX == nItemVersion ) + // => kam in zu exportierender Version gar nicht vor + continue; + + // !poolable wird gar nicht im Pool gespeichert + // und itemsets/plain-items je nach Runde +#ifdef TF_POOLABLE + if ( *pArr && IsItemFlag(**ppDefItem, SFX_ITEM_POOLABLE) && +#else + if ( *pArr && (*ppDefItem)->IsPoolable() && +#endif + pImp->bInSetItem == (*ppDefItem)->ISA(SfxSetItem) ) + { + // eigene Kennung, globale Which-Id und Item-Version + USHORT nSlotId = GetSlotId( (*ppDefItem)->Which(), FALSE ); + aWhichIdsRec.NewContent(nSlotId, 0); + rStream << (*ppDefItem)->Which(); + rStream << nItemVersion; + const USHORT nCount = (*pArr)->Count(); + DBG_ASSERT(nCount, "ItemArr ist leer"); + rStream << nCount; + + // Items an sich schreiben + SfxMultiMixRecordWriter aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS, 0 ); + for ( USHORT j = 0; j < nCount; ++j ) + { + // Item selbst besorgen + const SfxPoolItem *pItem = (*pArr)->GetObject(j); + if ( pItem && pItem->GetRefCount() ) //! siehe anderes MI-REF + { + aItemsRec.NewContent(j, 'X' ); + + if ( pItem->GetRefCount() == SFX_ITEMS_SPECIAL ) + rStream << (USHORT) pItem->GetKind(); + else + { + rStream << (USHORT) pItem->GetRefCount(); + if( pItem->GetRefCount() > SFX_ITEMS_OLD_MAXREF ) + rStream.SetError( ERRCODE_IO_NOTSTORABLEINBINARYFORMAT ); + } + + if ( !rStream.GetError() ) + pItem->Store(rStream, nItemVersion); + else + break; +#ifdef DBG_UTIL_MI + if ( !pItem->ISA(SfxSetItem) ) + { + ULONG nMark = rStream.Tell(); + rStream.Seek( nItemStartPos + sizeof(USHORT) ); + SfxPoolItem *pClone = pItem->Create(rStream, nItemVersion ); + USHORT nWh = pItem->Which(); + SFX_ASSERT( rStream.Tell() == nMark, nWh,"asymmetric store/create" ); + SFX_ASSERT( *pClone == *pItem, nWh, "unequal after store/create" ); + delete pClone; + } +#endif + } + } + } + } + } + + pImp->bInSetItem = FALSE; + } + + // die gesetzten Defaults speichern (Pool-Defaults) + if ( !rStream.GetError() ) + { + SfxMultiMixRecordWriter aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS, 0 ); + USHORT nCount = GetSize_Impl(); + for ( USHORT n = 0; n < nCount; ++n ) + { + const SfxPoolItem* pDefaultItem = ppPoolDefaults[n]; + if ( pDefaultItem ) + { + // Version ermitteln + USHORT nItemVersion = pDefaultItem->GetVersion( _nFileFormatVersion ); + if ( USHRT_MAX == nItemVersion ) + // => gab es in der Version noch nicht + continue; + + // eigene Kennung, globale Kennung, Version + USHORT nSlotId = GetSlotId( pDefaultItem->Which(), FALSE ); + aDefsRec.NewContent( nSlotId, 0 ); + rStream << pDefaultItem->Which(); + rStream << nItemVersion; + + // Item an sich + pDefaultItem->Store( rStream, nItemVersion ); + } + } + } + + // weitere Pools rausschreiben + ImpSvlData::GetSvlData().pStoringPool = 0; + aPoolRec.Close(); + if ( !rStream.GetError() && pSecondary ) + pSecondary->Store( rStream ); + + pImp->bStreaming = FALSE; + return rStream; +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::LoadCompleted() + +/* [Beschreibung] + + Wurde der SfxItemPool mit 'bRefCounts' == FALSE geladen, mu\s das + Laden der Dokumentinhalte mit einem Aufruf dieser Methode beendet + werden. Ansonsten hat der Aufruf dieser Methode keine Funktion. + + + [Anmerkung] + + Beim Laden ohne Ref-Counts werden diese tats"achlich auf 1 gesetzt, + damit nicht w"ahrend des Ladevorgangs SfxPoolItems gel"oscht werden, + die danach, aber auch noch beim Ladevorgang, ben"otigt werden. Diese + Methode setzt den Ref-Count wieder zur"uck und entfernt dabei + gleichzeitig alle nicht mehr ben"otigten Items. + + + [Querverweise] + + <SfxItemPool::Load()> +*/ + +{ + // wurden keine Ref-Counts mitgeladen? + if ( pImp->nInitRefCount > 1 ) + { + + // "uber alle Which-Werte iterieren + SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems; + for( USHORT nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++ppItemArr ) + { + // ist "uberhaupt ein Item mit dem Which-Wert da? + if ( *ppItemArr ) + { + // "uber alle Items mit dieser Which-Id iterieren + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if (*ppHtArr) + { + #ifdef DBG_UTIL + const SfxPoolItem &rItem = **ppHtArr; + DBG_ASSERT( !rItem.ISA(SfxSetItem) || + 0 != &((const SfxSetItem&)rItem).GetItemSet(), + "SetItem without ItemSet" ); + #endif + + if ( !ReleaseRef( **ppHtArr, 1 ) ) + DELETEZ( *ppHtArr ); + } + } + } + + // from now on normal initial ref count + pImp->nInitRefCount = 1; + } + + // notify secondary pool + if ( pSecondary ) + pSecondary->LoadCompleted(); +} + +//============================================================================ +// This had to be moved to a method of its own to keep Solaris GCC happy: +void SfxItemPool::readTheItems ( + SvStream & rStream, USHORT nItemCount, USHORT nVersion, + SfxPoolItem * pDefItem, SfxPoolItemArray_Impl ** ppArr) +{ + SfxMultiRecordReader aItemsRec( &rStream, SFX_ITEMPOOL_REC_ITEMS ); + + SfxPoolItemArray_Impl *pNewArr = new SfxPoolItemArray_Impl( nItemCount ); + SfxPoolItem *pItem = 0; + + USHORT n, nLastSurrogate = USHORT(-1); + while (aItemsRec.GetContent()) + { + // n"achstes Surrogat holen + USHORT nSurrogate = aItemsRec.GetContentTag(); + DBG_ASSERT( aItemsRec.GetContentVersion() == 'X', + "not an item content" ); + + // fehlende auff"ullen + for ( pItem = 0, n = nLastSurrogate+1; n < nSurrogate; ++n ) + pNewArr->C40_INSERT(SfxPoolItem, pItem, n); + nLastSurrogate = nSurrogate; + + // Ref-Count und Item laden + USHORT nRef; + rStream >> nRef; + + pItem = pDefItem->Create(rStream, nVersion); + pNewArr->C40_INSERT(SfxPoolItem, pItem, nSurrogate); + + if ( !bPersistentRefCounts ) + // bis <SfxItemPool::LoadCompleted()> festhalten + AddRef(*pItem, 1); + else + { + if ( nRef > SFX_ITEMS_OLD_MAXREF ) + pItem->SetKind( nRef ); + else + AddRef(*pItem, nRef); + } + } + + // fehlende auff"ullen + for ( pItem = 0, n = nLastSurrogate+1; n < nItemCount; ++n ) + pNewArr->C40_INSERT(SfxPoolItem, pItem, n); + + SfxPoolItemArray_Impl *pOldArr = *ppArr; + *ppArr = pNewArr; + + // die Items merken, die schon im Pool sind + int bEmpty = TRUE; + if ( 0 != pOldArr ) + for ( n = 0; bEmpty && n < pOldArr->Count(); ++n ) + bEmpty = pOldArr->GetObject(n) == 0; + DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" ); + if ( !bEmpty ) + { + // f"ur alle alten suchen, ob ein gleiches neues existiert + for ( USHORT nOld = 0; nOld < pOldArr->Count(); ++nOld ) + { + SfxPoolItem *pOldItem = (*pOldArr)[nOld]; + if ( pOldItem ) + { + USHORT nFree = USHRT_MAX; + int bFound = FALSE; + USHORT nCount = (*ppArr)->Count(); + for ( USHORT nNew = nCount; !bFound && nNew--; ) + { + // geladenes Item + SfxPoolItem *&rpNewItem = + (SfxPoolItem*&)(*ppArr)->GetData()[nNew]; + + // surrogat unbenutzt? + if ( !rpNewItem ) + nFree = nNew; + + // gefunden? + else if ( *rpNewItem == *pOldItem ) + { + // wiederverwenden + AddRef( *pOldItem, rpNewItem->GetRefCount() ); + SetRefCount( *rpNewItem, 0 ); + delete rpNewItem; + rpNewItem = pOldItem; + bFound = TRUE; + } + } + + // vorhervorhandene, nicht geladene uebernehmen + if ( !bFound ) + { + if ( nFree != USHRT_MAX ) + (SfxPoolItem*&)(*ppArr)->GetData()[nFree] = pOldItem; + else + (*ppArr)->C40_INSERT( SfxPoolItem, pOldItem, nCount ); + } + } + } + } + delete pOldArr; +} + +// ----------------------------------------------------------------------- + +SvStream &SfxItemPool::Load(SvStream &rStream) +{ + DBG_CHKTHIS(SfxItemPool, 0); + DBG_ASSERT(ppStaticDefaults, "kein DefaultArray"); + + // protect items by increasing ref count + if ( !bPersistentRefCounts ) + { + + // "uber alle Which-Werte iterieren + SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems; + for( USHORT nArrCnt = GetSize_Impl(); nArrCnt; --nArrCnt, ++ppItemArr ) + { + // ist "uberhaupt ein Item mit dem Which-Wert da? + if ( *ppItemArr ) + { + // "uber alle Items mit dieser Which-Id iterieren + SfxPoolItem** ppHtArr = (SfxPoolItem**)(*ppItemArr)->GetData(); + for( USHORT n = (*ppItemArr)->Count(); n; --n, ++ppHtArr ) + if (*ppHtArr) + { + #ifdef DBG_UTIL + const SfxPoolItem &rItem = **ppHtArr; + DBG_ASSERT( !rItem.ISA(SfxSetItem) || + 0 != &((const SfxSetItem&)rItem).GetItemSet(), + "SetItem without ItemSet" ); + DBG_WARNING( "loading non-empty ItemPool" ); + #endif + + AddRef( **ppHtArr, 1 ); + } + } + } + + // during loading (until LoadCompleted()) protect all items + pImp->nInitRefCount = 2; + } + + // Load-Master finden + SfxItemPool *pLoadMaster = pMaster != this ? pMaster : 0; + while ( pLoadMaster && !pLoadMaster->pImp->bStreaming ) + pLoadMaster = pLoadMaster->pSecondary; + + // Gesamt Header einlesen + pImp->bStreaming = TRUE; + if ( !pLoadMaster ) + { + // Format-Version laden + CHECK_FILEFORMAT2( rStream, + SFX_ITEMPOOL_TAG_STARTPOOL_5, SFX_ITEMPOOL_TAG_STARTPOOL_4 ); + rStream >> pImp->nMajorVer >> pImp->nMinorVer; + + // Format-Version in Master-Pool "ubertragen + pMaster->pImp->nMajorVer = pImp->nMajorVer; + pMaster->pImp->nMinorVer = pImp->nMinorVer; + + // altes Format? + if ( pImp->nMajorVer < 2 ) + // pImp->bStreaming wird von Load1_Impl() zur"uckgesetzt + return Load1_Impl( rStream ); + + // zu neues Format? + if ( pImp->nMajorVer > SFX_ITEMPOOL_VER_MAJOR ) + { + rStream.SetError(SVSTREAM_FILEFORMAT_ERROR); + pImp->bStreaming = FALSE; + return rStream; + } + + // Version 1.2-Trick-Daten "uberspringen + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_TRICK4OLD ); + rStream.SeekRel( 4 ); // Hack-Daten wegen SfxStyleSheetPool-Bug skippen + } + + // neues Record-orientiertes Format + SfxMiniRecordReader aPoolRec( &rStream, SFX_ITEMPOOL_REC ); + if ( rStream.GetError() ) + { + pImp->bStreaming = FALSE; + return rStream; + } + + // Einzel-Header + int bOwnPool = TRUE; + UniString aExternName; + { + // Header-Record suchen + SfxMiniRecordReader aPoolHeaderRec( &rStream, SFX_ITEMPOOL_REC_HEADER ); + if ( rStream.GetError() ) + { + pImp->bStreaming = FALSE; + return rStream; + } + + // Header-lesen + rStream >> pImp->nLoadingVersion; + SfxPoolItem::readByteString(rStream, aExternName); + bOwnPool = aExternName == aName; + + //! solange wir keine fremden Pools laden k"onnen + if ( !bOwnPool ) + { + rStream.SetError(SVSTREAM_FILEFORMAT_ERROR); + aPoolRec.Skip(); + pImp->bStreaming = FALSE; + return rStream; + } + } + + // Version-Maps + { + SfxMultiRecordReader aVerRec( &rStream, SFX_ITEMPOOL_REC_VERSIONMAP ); + if ( rStream.GetError() ) + { + pImp->bStreaming = FALSE; + return rStream; + } + + // Versions-Maps einlesen + USHORT nOwnVersion = pImp->nVersion; + for ( USHORT nVerNo = 0; aVerRec.GetContent(); ++nVerNo ) + { + // Header f"ur einzelne Version einlesen + USHORT nVersion, nHStart, nHEnd; + rStream >> nVersion >> nHStart >> nHEnd; + USHORT nCount = nHEnd - nHStart + 1; + + // Version neuer als bekannt? + if ( nVerNo >= pImp->aVersions.Count() ) + { + // neue Version hinzufuegen + USHORT *pMap = new USHORT[nCount]; + for ( USHORT n = 0; n < nCount; ++n ) + rStream >> pMap[n]; + SetVersionMap( nVersion, nHStart, nHEnd, pMap ); + } + } + pImp->nVersion = nOwnVersion; + } + + // Items laden + FASTBOOL bSecondaryLoaded = FALSE; + long nSecondaryEnd = 0; + { + SfxMultiRecordReader aWhichIdsRec( &rStream, SFX_ITEMPOOL_REC_WHICHIDS); + while ( aWhichIdsRec.GetContent() ) + { + // SlotId, Which-Id und Item-Version besorgen + USHORT nCount, nVersion, nWhich; + //!USHORT nSlotId = aWhichIdsRec.GetContentTag(); + rStream >> nWhich; + if ( pImp->nLoadingVersion != pImp->nVersion ) + // Which-Id aus File-Version in Pool-Version verschieben + nWhich = GetNewWhich( nWhich ); + + // unbekanntes Item aus neuerer Version + if ( !IsInRange(nWhich) ) + continue; + + rStream >> nVersion; + rStream >> nCount; + //!SFX_ASSERTWARNING( !nSlotId || !HasMap() || + //! ( nSlotId == GetSlotId( nWhich, FALSE ) ) || + //! !GetSlotId( nWhich, FALSE ), + //! nWhich, "Slot/Which mismatch" ); + + USHORT nIndex = GetIndex_Impl(nWhich); + SfxPoolItemArray_Impl **ppArr = pImp->ppPoolItems + nIndex; + + // SfxSetItems k"onnten Items aus Sekund"arpools beinhalten + SfxPoolItem *pDefItem = *(ppStaticDefaults + nIndex); + pImp->bInSetItem = pDefItem->ISA(SfxSetItem); + if ( !bSecondaryLoaded && pSecondary && pImp->bInSetItem ) + { + // an das Ende des eigenen Pools seeken + ULONG nLastPos = rStream.Tell(); + aPoolRec.Skip(); + + // Sekund"arpool einlesen + pSecondary->Load( rStream ); + bSecondaryLoaded = TRUE; + nSecondaryEnd = rStream.Tell(); + + // zur"uck zu unseren eigenen Items + rStream.Seek(nLastPos); + } + + // Items an sich lesen + readTheItems(rStream, nCount, nVersion, pDefItem, ppArr); + + pImp->bInSetItem = FALSE; + } + } + + // Pool-Defaults lesen + { + SfxMultiRecordReader aDefsRec( &rStream, SFX_ITEMPOOL_REC_DEFAULTS ); + + while ( aDefsRec.GetContent() ) + { + // SlotId, Which-Id und Item-Version besorgen + USHORT nVersion, nWhich; + //!USHORT nSlotId = aDefsRec.GetContentTag(); + rStream >> nWhich; + if ( pImp->nLoadingVersion != pImp->nVersion ) + // Which-Id aus File-Version in Pool-Version verschieben + nWhich = GetNewWhich( nWhich ); + + // unbekanntes Item aus neuerer Version + if ( !IsInRange(nWhich) ) + continue; + + rStream >> nVersion; + //!SFX_ASSERTWARNING( !HasMap() || ( nSlotId == GetSlotId( nWhich, FALSE ) ), + //! nWhich, "Slot/Which mismatch" ); + + // Pool-Default-Item selbst laden + SfxPoolItem *pItem = + ( *( ppStaticDefaults + GetIndex_Impl(nWhich) ) ) + ->Create( rStream, nVersion ); + pItem->SetKind( SFX_ITEMS_POOLDEFAULT ); + *( ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem; + } + } + + // ggf. Secondary-Pool laden + aPoolRec.Skip(); + if ( pSecondary ) + { + if ( !bSecondaryLoaded ) + pSecondary->Load( rStream ); + else + rStream.Seek( nSecondaryEnd ); + } + + // wenn nicht own-Pool, dann kein Name + if ( aExternName != aName ) + aName.Erase(); + + pImp->bStreaming = FALSE; + return rStream; +}; + +// ----------------------------------------------------------------------- + +SvStream &SfxItemPool::Load1_Impl(SvStream &rStream) +{ + // beim Master ist der Header schon von <Load()> geladen worden + if ( !pImp->bStreaming ) + { + // Header des Secondary lesen + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_STARTPOOL_4 ); + rStream >> pImp->nMajorVer >> pImp->nMinorVer; + } + sal_uInt32 nAttribSize; + int bOwnPool = TRUE; + UniString aExternName; + if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 2 ) + rStream >> pImp->nLoadingVersion; + SfxPoolItem::readByteString(rStream, aExternName); + bOwnPool = aExternName == aName; + pImp->bStreaming = TRUE; + + //! solange wir keine fremden laden k"onnen + if ( !bOwnPool ) + { + rStream.SetError(SVSTREAM_FILEFORMAT_ERROR); + pImp->bStreaming = FALSE; + return rStream; + } + + // Versionen bis 1.3 k"onnen noch keine Which-Verschiebungen lesen + if ( pImp->nMajorVer == 1 && pImp->nMinorVer <= 2 && + pImp->nVersion < pImp->nLoadingVersion ) + { + rStream.SetError(ERRCODE_IO_WRONGVERSION); + pImp->bStreaming = FALSE; + return rStream; + } + + // Size-Table liegt hinter den eigentlichen Attributen + rStream >> nAttribSize; + + // Size-Table einlesen + ULONG nStartPos = rStream.Tell(); + rStream.SeekRel( nAttribSize ); + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_SIZES ); + sal_uInt32 nSizeTableLen; + rStream >> nSizeTableLen; + sal_Char *pBuf = new sal_Char[nSizeTableLen]; + rStream.Read( pBuf, nSizeTableLen ); + ULONG nEndOfSizes = rStream.Tell(); + SvMemoryStream aSizeTable( pBuf, nSizeTableLen, STREAM_READ ); + + // ab Version 1.3 steht in der Size-Table eine Versions-Map + if ( pImp->nMajorVer > 1 || pImp->nMinorVer >= 3 ) + { + // Version-Map finden (letztes ULONG der Size-Table gibt Pos an) + rStream.Seek( nEndOfSizes - sizeof(sal_uInt32) ); + sal_uInt32 nVersionMapPos; + rStream >> nVersionMapPos; + rStream.Seek( nVersionMapPos ); + + // Versions-Maps einlesen + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_VERSIONMAP ); + USHORT nVerCount; + rStream >> nVerCount; + for ( USHORT nVerNo = 0; nVerNo < nVerCount; ++nVerNo ) + { + // Header f"ur einzelne Version einlesen + USHORT nVersion, nHStart, nHEnd; + rStream >> nVersion >> nHStart >> nHEnd; + USHORT nCount = nHEnd - nHStart + 1; + USHORT nBytes = (nCount)*sizeof(USHORT); + + // Version neuer als bekannt? + if ( nVerNo >= pImp->aVersions.Count() ) + { + // neue Version hinzufuegen + USHORT *pMap = new USHORT[nCount]; + for ( USHORT n = 0; n < nCount; ++n ) + rStream >> pMap[n]; + SetVersionMap( nVersion, nHStart, nHEnd, pMap ); + } + else + // Version schon bekannt => "uberspringen + rStream.SeekRel( nBytes ); + } + } + + // Items laden + rStream.Seek( nStartPos ); + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ITEMS ); + FASTBOOL bSecondaryLoaded = FALSE; + long nSecondaryEnd = 0; + USHORT nWhich, nSlot; + while ( rStream >> nWhich, nWhich ) + { + // ggf. Which-Id aus alter Version verschieben? + if ( pImp->nLoadingVersion != pImp->nVersion ) + nWhich = GetNewWhich( nWhich ); + + rStream >> nSlot; + USHORT nMappedWhich = GetWhich(nSlot, FALSE); + int bKnownItem = bOwnPool || IsWhich(nMappedWhich); + + USHORT nRef, nCount, nVersion; + sal_uInt32 nAttrSize; + rStream >> nVersion >> nCount; + + SfxPoolItemArray_Impl **ppArr = 0; + SfxPoolItemArray_Impl *pNewArr = 0; + SfxPoolItem *pDefItem = 0; + if ( bKnownItem ) + { + if ( !bOwnPool ) + nWhich = nMappedWhich; + + //!SFX_ASSERTWARNING( !nSlot || !HasMap() || + //! ( nSlot == GetSlotId( nWhich, FALSE ) ) || + //! !GetSlotId( nWhich, FALSE ), + //! nWhich, "Slot/Which mismatch" ); + + USHORT nIndex = GetIndex_Impl(nWhich); + ppArr = pImp->ppPoolItems + nIndex; + pNewArr = new SfxPoolItemArray_Impl( nCount ); + pDefItem = *(ppStaticDefaults + nIndex); + } + + // Position vor ersten Item merken + ULONG nLastPos = rStream.Tell(); + + // SfxSetItems k"onnten Items aus Sekund"arpools beinhalten + if ( !bSecondaryLoaded && pSecondary && pDefItem->ISA(SfxSetItem) ) + { + // an das Ende des eigenen Pools seeken + rStream.Seek(nEndOfSizes); + CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr ); + CHECK_FILEFORMAT_RELEASE( rStream, SFX_ITEMPOOL_TAG_ENDPOOL, pNewArr ); + + // Sekund"arpool einlesen + pSecondary->Load1_Impl( rStream ); + bSecondaryLoaded = TRUE; + nSecondaryEnd = rStream.Tell(); + + // zur"uck zu unseren eigenen Items + rStream.Seek(nLastPos); + } + + // Items an sich lesen + for ( USHORT j = 0; j < nCount; ++j ) + { + ULONG nPos = nLastPos; + rStream >> nRef; + + if ( bKnownItem ) + { + SfxPoolItem *pItem = 0; + if ( nRef ) + { + pItem = pDefItem->Create(rStream, nVersion); + + if ( !bPersistentRefCounts ) + // bis <SfxItemPool::LoadCompleted()> festhalten + AddRef(*pItem, 1); + else + { + if ( nRef > SFX_ITEMS_OLD_MAXREF ) + pItem->SetKind( nRef ); + else + AddRef(*pItem, nRef); + } + } + + pNewArr->C40_INSERT( SfxPoolItem, pItem, j); + + // restliche gespeicherte Laenge skippen (neueres Format) + nLastPos = rStream.Tell(); + } + + aSizeTable >> nAttrSize; + SFX_ASSERT( !bKnownItem || ( nPos + nAttrSize) >= nLastPos, + nPos, + "too many bytes read - version mismatch?" ); + + if ( !bKnownItem || ( nLastPos < (nPos + nAttrSize) ) ) + { + nLastPos = nPos + nAttrSize; + rStream.Seek( nLastPos ); + } + } + + if ( bKnownItem ) + { + SfxPoolItemArray_Impl *pOldArr = *ppArr; + *ppArr = pNewArr; + + // die Items merken, die schon im Pool sind + int bEmpty = TRUE; + if ( 0 != pOldArr ) + for ( USHORT n = 0; bEmpty && n < pOldArr->Count(); ++n ) + bEmpty = pOldArr->GetObject(n) == 0; + DBG_ASSERTWARNING( bEmpty, "loading non-empty pool" ); + if ( !bEmpty ) + { + // f"ur alle alten suchen, ob ein gleiches neues existiert + for ( USHORT nOld = 0; nOld < pOldArr->Count(); ++nOld ) + { + SfxPoolItem *pOldItem = (*pOldArr)[nOld]; + if ( pOldItem ) + { + int bFound = FALSE; + for ( USHORT nNew = 0; + !bFound && nNew < (*ppArr)->Count(); + ++nNew ) + { + SfxPoolItem *&rpNewItem = + (SfxPoolItem*&)(*ppArr)->GetData()[nNew]; + + if ( rpNewItem && *rpNewItem == *pOldItem ) + { + AddRef( *pOldItem, rpNewItem->GetRefCount() ); + SetRefCount( *rpNewItem, 0 ); + delete rpNewItem; + rpNewItem = pOldItem; + bFound = TRUE; + SFX_TRACE( "reusing item", pOldItem ); + } + } + //! DBG_ASSERT( bFound, "old-item not found in file" ); + if ( !bFound ) + { + SFX_TRACE( "item not found: ", pOldItem ); + } + } + } + } + delete pOldArr; /* @@@ */ + } + } + + // Pool-Defaults lesen + if ( pImp->nMajorVer > 1 || pImp->nMinorVer > 0 ) + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_DEFAULTS ); + + ULONG nLastPos = rStream.Tell(); + while ( rStream >> nWhich, nWhich ) + { + // ggf. Which-Id aus alter Version verschieben? + if ( pImp->nLoadingVersion != pImp->nVersion ) + nWhich = GetNewWhich( nWhich ); + + rStream >> nSlot; + USHORT nMappedWhich = GetWhich(nSlot, FALSE); + int bKnownItem = bOwnPool || IsWhich(nMappedWhich); + + ULONG nPos = nLastPos; + sal_uInt32 nSize; + USHORT nVersion; + rStream >> nVersion; + + if ( bKnownItem ) + { + if ( !bOwnPool ) + nWhich = nMappedWhich; + SfxPoolItem *pItem = + ( *( ppStaticDefaults + GetIndex_Impl(nWhich) ) ) + ->Create( rStream, nVersion ); + pItem->SetKind( SFX_ITEMS_POOLDEFAULT ); + *( ppPoolDefaults + GetIndex_Impl(nWhich) ) = pItem; + } + + nLastPos = rStream.Tell(); + aSizeTable >> nSize; + SFX_ASSERT( ( nPos + nSize) >= nLastPos, nPos, + "too many bytes read - version mismatch?" ); + if ( nLastPos < (nPos + nSize) ) + rStream.Seek( nPos + nSize ); + } + + delete[] pBuf; + rStream.Seek(nEndOfSizes); + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL ); + CHECK_FILEFORMAT( rStream, SFX_ITEMPOOL_TAG_ENDPOOL ); + + if ( pSecondary ) + { + if ( !bSecondaryLoaded ) + pSecondary->Load1_Impl( rStream ); + else + rStream.Seek( nSecondaryEnd ); + } + + if ( aExternName != aName ) + aName.Erase(); + + pImp->bStreaming = FALSE; + return rStream; +} + +// ----------------------------------------------------------------------- + +const SfxPoolItem* SfxItemPool::LoadSurrogate +( + SvStream& rStream, // vor einem Surrogat positionierter Stream + USHORT& rWhich, // Which-Id des zu ladenden <SfxPoolItem>s + USHORT nSlotId, // Slot-Id des zu ladenden <SfxPoolItem>s + const SfxItemPool* pRefPool // <SfxItemPool> in dem das Surrogat gilt +) + +/* [Beschreibung] + + L"adt Surrogat aus 'rStream' und liefert das dadurch in 'rRefPool' + repr"asentierte SfxPoolItem zu"ruck. Ist das im Stream befindliche + Surrogat == SFX_ITEMS_DIRECT (!SFX_ITEM_POOLABLE) wird 0 zur"uckgegeben, + das Item ist direkt aus dem Stream zu laden. Bei 0xfff0 (SFX_ITEMS_NULL) + wird auch 0 zurueckgegeben und rWhich auf 0 gesetzt, das Item ist nicht + verfuegbar. + + Ansonsten wird ber"ucksichtigt, ob der betroffene Pool ohne Ref-Counts + geladen wird, ob aus einem neuen Pool nachgeladen wird (&rRefPool != this) + oder ob aus einem g"anzlich anders aufgebauten Pool geladen wird. + + Wird aus einem anders aufgebauten Pool geladen und die 'nSlotId' kann + nicht in eine Which-Id dieses Pools gemappt werden, wird ebenfalls 0 + zur"uckgeliefert. + + Preconditions: - Pool mu\s geladen sein + - LoadCompleted darf noch nicht gerufen worden sein + - 'rStream' steht genau an der Position, an der ein + Surrogat f"ur ein Item mit der SlotId 'nSlotId' und + der WhichId 'rWhichId' mit StoreSurrogate gepeichert + wurde + + Postconditions: - 'rStream' ist so positioniert, wie auch StoreSurrogate + sein speichern beendet hatte + - konnte ein Item geladen werden, befindet es sich + in diesem SfxItemPool + - 'rWhichId' enth"alt die ggf. gemappte Which-Id + Laufzeit: Tiefe des Ziel Sekund"arpools * 10 + 10 + + [Querverweise] + + <SfxItemPool::StoreSurrogate(SvStream&,const SfxPoolItem &)const> +*/ + +{ + // erstmal das Surrogat lesen + USHORT nSurrogat; + rStream >> nSurrogat; + + // direkt gespeichertes Item? + if ( SFX_ITEMS_DIRECT == nSurrogat ) + return 0; + + // nicht vorhandenes Item? + if ( SFX_ITEMS_NULL == nSurrogat ) + { + rWhich = 0; + return 0; + } + + // Bei einem identisch aufgebauten Pool (im Stream) kann das Surrogat + // auf jeden Fall aufgel"ost werden. + if ( !pRefPool ) + pRefPool = this; + FASTBOOL bResolvable = pRefPool->GetName().Len() > 0; + if ( !bResolvable ) + { + // Bei einem anders aufgebauten Pool im Stream, mu\s die SlotId + // aus dem Stream in eine Which-Id gemappt werden k"onnen. + USHORT nMappedWhich = nSlotId ? GetWhich(nSlotId, TRUE) : 0; + if ( IsWhich(nMappedWhich) ) + { + // gemappte SlotId kann "ubernommen werden + rWhich = nMappedWhich; + bResolvable = TRUE; + } + } + + // kann Surrogat aufgel"ost werden? + const SfxPoolItem *pItem = 0; + if ( bResolvable ) + { + for ( SfxItemPool *pTarget = this; pTarget; pTarget = pTarget->pSecondary ) + { + // richtigen (Folge-) Pool gefunden? + if ( pTarget->IsInRange(rWhich) ) + { + // dflt-Attribut? + if ( SFX_ITEMS_STATICDEFAULT == nSurrogat ) + return *(pTarget->ppStaticDefaults + + pTarget->GetIndex_Impl(rWhich)); + + SfxPoolItemArray_Impl* pItemArr = *(pTarget->pImp->ppPoolItems + + pTarget->GetIndex_Impl(rWhich)); + pItem = pItemArr && nSurrogat < pItemArr->Count() + ? (*pItemArr)[nSurrogat] + : 0; + if ( !pItem ) + { + DBG_ERROR( "can't resolve surrogate" ); + rWhich = 0; // nur zur Sicherheit fuer richtige Stream-Pos + return 0; + } + + // Nachladen aus Ref-Pool? + if ( pRefPool != pMaster ) + return &pTarget->Put( *pItem ); + + // Referenzen sind NICHT schon mit Pool geladen worden? + if ( !pTarget->HasPersistentRefCounts() ) + AddRef( *pItem, 1 ); + else + return pItem; + + return pItem; + } + } + + SFX_ASSERT( FALSE, rWhich, "can't resolve Which-Id in LoadSurrogate" ); + } + + return 0; +} + +//------------------------------------------------------------------------- + + +FASTBOOL SfxItemPool::StoreSurrogate +( + SvStream& rStream, + const SfxPoolItem* pItem +) const + +/* [Beschreibung] + + Speichert ein Surrogat f"ur '*pItem' in 'rStream'. + + + [R"uckgabewert] + + FASTBOOL TRUE + es wurde ein echtes Surrogat gespeichert, auch + SFX_ITEMS_NULL bei 'pItem==0', + SFX_ITEMS_STATICDEFAULT und SFX_ITEMS_POOLDEFAULT + gelten als 'echte' Surrogate + + FALSE + es wurde ein Dummy-Surrogat (SFX_ITEMS_DIRECT) + gespeichert, das eigentliche Item mu\s direkt + hinterher selbst gespeichert werden +*/ + +{ + if ( pItem ) + { + FASTBOOL bRealSurrogate = IsItemFlag(*pItem, SFX_ITEM_POOLABLE); + rStream << ( bRealSurrogate + ? GetSurrogate( pItem ) + : (UINT16) SFX_ITEMS_DIRECT ); + return bRealSurrogate; + } + + rStream << (UINT16) SFX_ITEMS_NULL; + return TRUE; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetSurrogate(const SfxPoolItem *pItem) const +{ + DBG_CHKTHIS(SfxItemPool, 0); + DBG_ASSERT( pItem, "no 0-Pointer Surrogate" ); + DBG_ASSERT( !IsInvalidItem(pItem), "no Invalid-Item Surrogate" ); + DBG_ASSERT( !IsPoolDefaultItem(pItem), "no Pool-Default-Item Surrogate" ); + + if ( !IsInRange(pItem->Which()) ) + { + if ( pSecondary ) + return pSecondary->GetSurrogate( pItem ); + SFX_ASSERT( 0, pItem->Which(), "unknown Which-Id - dont ask me for surrogates" ); + } + + // Pointer auf static- oder pool-dflt-Attribut? + if( IsStaticDefaultItem(pItem) || IsPoolDefaultItem(pItem) ) + return SFX_ITEMS_STATICDEFAULT; + + SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(pItem->Which())); + DBG_ASSERT(pItemArr, "ItemArr nicht vorhanden"); + const USHORT nCount = pItemArr->Count(); + for ( USHORT i = 0; i < nCount; ++i ) + { + const SfxPoolItem *p = (*pItemArr)[i]; + if ( p == pItem ) + return i; + } + SFX_ASSERT( 0, pItem->Which(), "Item nicht im Pool"); + return SFX_ITEMS_NULL; +} + +// ----------------------------------------------------------------------- + +FASTBOOL SfxItemPool::IsInStoringRange( USHORT nWhich ) const +{ + return nWhich >= pImp->nStoringStart && + nWhich <= pImp->nStoringEnd; +} + +//------------------------------------------------------------------------ + +void SfxItemPool::SetStoringRange( USHORT nFrom, USHORT nTo ) + +/* [Beschreibung] + + Mit dieser Methode kann der Which-Bereich eingeengt werden, der + von ItemSets dieses Pool (und dem Pool selbst) gespeichert wird. + Die Methode muss dazu vor <SfxItemPool::Store()> gerufen werden + und die Werte muessen auch noch gesetzt sein, wenn das eigentliche + Dokument (also die ItemSets gespeicher werden). + + Ein Zuruecksetzen ist dann nicht noetig, wenn dieser Range vor + JEDEM Speichern richtig gesetzt wird, da er nur beim Speichern + beruecksichtigt wird. + + Dieses muss fuer das 3.1-Format gemacht werden, da dort eine + Bug in der Pool-Lade-Methode vorliegt. +*/ + +{ + pImp->nStoringStart = nFrom; + pImp->nStoringEnd = nTo; +} + +// ----------------------------------------------------------------------- + +void SfxItemPool::SetVersionMap +( + USHORT nVer, /* neue Versionsnummer */ + USHORT nOldStart, /* alte erste Which-Id */ + USHORT nOldEnd, /* alte letzte Which-Id */ + USHORT* pOldWhichIdTab /* Array mit genau dem Aufbau der Which-Ids + der vorhergehenden Version, in denen + die jeweils neue Which-Id steht. */ +) + +/* [Beschreibung] + + Mit dieser Methode k"onnen neue, inkompatible Which-Id-Folgen oder + Verteilungen realisiert werden. Pools, die noch mit alten Versionen + gespeichert wurden, werden dann "uber die angegebene Tabelle solange + gemappt, bis die aktuelle Version erreicht ist. Neuere Pools k"onnen + unter Verlust neuer Attribute geladen werden, da die Map mit dem Pool + gespeichert wird. + + Precondition: Pool darf noch nicht geladen sein + Postcondition: Which-Ids aus fr"uheren Versionen k"onnen bei Laden auf + Version 'nVer' gemappt werden + Laufzeit: 1.5 * new + 10 + + [Anmerkung] + + F"ur neue Which-Ranges (nStart,nEnd) m"ssen im Vergleich zur Vorg"anger- + Version (nOldStart,nOldEnd) immer gelten, da\s (nOldStart,nOldEnd) + vollst"andig in (nStart,nEnd) enthalten ist. Es ist also zul"assig, den + Which-Range in beide Richtungen zu erweitern, auch durch Einf"ugung + von Which-Ids, nicht aber ihn zu beschneiden. + + Diese Methode sollte nur im oder direkt nach Aufruf des Konstruktors + gerufen werden. + + Das Array mu\s statisch sein, da es nicht kopiert wird und au\serdem + im Copy-Ctor des SfxItemPool wiederverwendet wird. + + + [Beispiel] + + Urspr"unglich (Version 0) hatte der Pool folgende Which-Ids: + + 1:A, 2:B, 3:C, 4:D + + Nun soll eine neue Version (Version 1) zwei zus"atzliche Ids X und Y + zwischen B und C erhalten, also wie folgt aussehen: + + 1:A, 2:B, 3:X, 4:Y, 5:C, 6:D + + Dabei haben sich also die Ids 3 und 4 ge"andert. F"ur die neue Version + m"u\ste am Pool folgendes gesetzt werden: + + static USHORT nVersion1Map = { 1, 2, 5, 6 }; + pPool->SetVersionMap( 1, 1, 4, &nVersion1Map ); + + + [Querverweise] + + <SfxItemPool::IsLoadingVersionCurrent()const> + <SfxItemPool::GetNewWhich(USHORT)> + <SfxItemPool::GetVersion()const> + <SfxItemPool::GetLoadingVersion()const> +*/ + +{ + // neuen Map-Eintrag erzeugen und einf"ugen + const SfxPoolVersion_Impl *pVerMap = new SfxPoolVersion_Impl( + nVer, nOldStart, nOldEnd, pOldWhichIdTab ); + pImp->aVersions.Insert( pVerMap, pImp->aVersions.Count() ); + + DBG_ASSERT( nVer > pImp->nVersion, "Versions not sorted" ); + pImp->nVersion = nVer; + + // Versions-Range anpassen + for ( USHORT n = 0; n < nOldEnd-nOldStart+1; ++n ) + { + USHORT nWhich = pOldWhichIdTab[n]; + if ( nWhich < pImp->nVerStart ) + { + if ( !nWhich ) + nWhich = 0; + pImp->nVerStart = nWhich; + } + else if ( nWhich > pImp->nVerEnd ) + pImp->nVerEnd = nWhich; + } +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetNewWhich +( + USHORT nFileWhich // die aus dem Stream geladene Which-Id +) const + +/* [Beschreibung] + + Diese Methoden rechnet Which-Ids aus einem File-Format in die der + aktuellen Pool-Version um. Ist das File-Format "alter, werden die vom + Pool-Entwickler mit SetVersion() gesetzten Tabellen verwendet, + ist das File-Format neuer, dann die aus dem File geladenen Tabellen. + Im letzteren Fall kann ggf. nicht jede Which-Id gemappt werden, + so da\s 0 zur"uckgeliefert wird. + + Die Berechnung ist nur f"ur Which-Ids definiert, die in der betreffenden + File-Version unterst"utzt wurden. Dies ist per Assertion abgesichert. + + Precondition: Pool mu\s geladen sein + Postcondition: unver"andert + Laufzeit: linear(Anzahl der Sekund"arpools) + + linear(Differenz zwischen alter und neuer Version) + + + [Querverweise] + + <SfxItemPool::IsLoadingVersionCurrent()const> + <SfxItemPool::SetVersionMap(USHORT,USHORT,USHORT,USHORT*)> + <SfxItemPool::GetVersion()const> + <SfxItemPool::GetLoadingVersion()const> +*/ + +{ + // (Sekund"ar-) Pool bestimmen + if ( !IsInVersionsRange(nFileWhich) ) + { + if ( pSecondary ) + return pSecondary->GetNewWhich( nFileWhich ); + SFX_ASSERT( 0, nFileWhich, "unknown which in GetNewWhich()" ); + } + + // Version neuer/gleich/"alter? + short nDiff = (short)pImp->nLoadingVersion - (short)pImp->nVersion; + + // Which-Id einer neueren Version? + if ( nDiff > 0 ) + { + // von der Top-Version bis runter zur File-Version stufenweise mappen + for ( USHORT nMap = pImp->aVersions.Count(); nMap > 0; --nMap ) + { + SfxPoolVersion_Impl *pVerInfo = pImp->aVersions[nMap-1]; + if ( pVerInfo->_nVer > pImp->nVersion ) + { USHORT nOfs; + USHORT nCount = pVerInfo->_nEnd - pVerInfo->_nStart + 1; + for ( nOfs = 0; + nOfs <= nCount && + pVerInfo->_pMap[nOfs] != nFileWhich; + ++nOfs ) + continue; + + if ( pVerInfo->_pMap[nOfs] == nFileWhich ) + nFileWhich = pVerInfo->_nStart + nOfs; + else + return 0; + } + else + break; + } + } + + // Which-Id einer neueren Version? + else if ( nDiff < 0 ) + { + // von der File-Version bis zur aktuellen Version stufenweise mappen + for ( USHORT nMap = 0; nMap < pImp->aVersions.Count(); ++nMap ) + { + SfxPoolVersion_Impl *pVerInfo = pImp->aVersions[nMap]; + if ( pVerInfo->_nVer > pImp->nLoadingVersion ) + { + DBG_ASSERT( nFileWhich >= pVerInfo->_nStart && + nFileWhich <= pVerInfo->_nEnd, + "which-id unknown in version" ); + nFileWhich = pVerInfo->_pMap[nFileWhich - pVerInfo->_nStart]; + } + } + } + + // originale (nDiff==0) bzw. gemappte (nDiff!=0) Id zur"uckliefern + return nFileWhich; +} + +// ----------------------------------------------------------------------- + + +FASTBOOL SfxItemPool::IsInVersionsRange( USHORT nWhich ) const +{ + return nWhich >= pImp->nVerStart && nWhich <= pImp->nVerEnd; +} + +// ----------------------------------------------------------------------- + +FASTBOOL SfxItemPool::IsCurrentVersionLoading() const + +/* [Beschreibung] + + Mit dieser Methode kann festgestellt werden, ob die geladene Pool-Version + dem aktuellen Pool-Aufbau entspricht. + + Precondition: Pool mu\s geladen sein + Postcondition: unver"andert + Laufzeit: linear(Anzahl der Sekund"arpools) + + + [Querverweise] + + <SfxItemPool::SetVersionMap(USHORT,USHORT,USHORT,USHORT*)> + <SfxItemPool::GetNewWhich(USHORT)const> + <SfxItemPool::GetVersion()const> + <SfxItemPool::GetLoadingVersion()const> +*/ + +{ + return ( pImp->nVersion == pImp->nLoadingVersion ) && + ( !pSecondary || pSecondary->IsCurrentVersionLoading() ); +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetVersion() const + +/* [Beschreibung] + + Diese Methode liefert die aktuelle Versionsnummer des SfxItemPool-Aufbaus + (also des Which-Bereichs). + + Precondition: keine + Postcondition: unver"andert + Laufzeit: 2 + + + [Anmerkung] + + Achtung: Es mu\s ggf. die Versionsnummer von Sekund"arpools + ber"ucksichtigt werden. + + + [Querverweise] + + <SfxItemPool::IsLoadingVersionCurrent()const> + <SfxItemPool::SetVersionMap(USHORT,USHORT,USHORT,USHORT*)> + <SfxItemPool::GetNewWhich(USHORT)const> + <SfxItemPool::GetLoadingVersion()const> +*/ + +{ + return pImp->nVersion; +} + +// ----------------------------------------------------------------------- + +USHORT SfxItemPool::GetLoadingVersion() const + +/* [Beschreibung] + + Diese Methode liefert die Versionsnummer des SfxItemPool-Aufbaus + (also des Which-Bereichs), die bei Laden vorgefunden wurde. + + Precondition: Pool mu\s geladen sein + Postcondition: unver"andert + Laufzeit: 2 + + + [Anmerkung] + + Achtung: Es mu\s ggf. die Versionsnummer von Sekund"arpools + ber"ucksichtigt werden. + + + [Querverweise] + + <SfxItemPool::IsLoadingVersionCurrent()const> + <SfxItemPool::SetVersionMap(USHORT,USHORT,USHORT,USHORT*)> + <SfxItemPool::GetNewWhich(USHORT)const> + <SfxItemPool::GetVersion()const> +*/ + +{ + return pImp->nLoadingVersion; +} + +//------------------------------------------------------------------------- + +FASTBOOL SfxItemPool::IsVer2_Impl() const +{ + return pMaster->pImp->nMajorVer >= 2; +} + +//------------------------------------------------------------------------- + + +FASTBOOL SfxItemPool::StoreItem( SvStream &rStream, const SfxPoolItem &rItem, + FASTBOOL bDirect ) const + +/* [Beschreibung] + + Speichert das <SfxPoolItem> 'rItem' in den <SvStream> 'rStream' + entweder als Surrogat ('bDirect == FALSE') oder direkt mit 'rItem.Store()'. + Nicht poolable Items werden immer direkt gespeichert. Items ohne Which-Id, + also SID-Items, werden nicht gespeichert, ebenso wenn Items, die in der + File-Format-Version noch nicht vorhanden waren (return FALSE). + + Das Item wird im Stream wie folgt abgelegt: + + USHORT rItem.Which() + USHORT GetSlotId( rItem.Which() ) bzw. 0 falls nicht verf"urbar + USHORT GetSurrogate( &rItem ) bzw. SFX_ITEM_DIRECT bei '!SFX_ITEM_POOLBLE' + + optional (falls 'bDirect == TRUE' oder '!rItem.IsPoolable()': + + USHORT rItem.GetVersion() + ULONG Size + Size rItem.Store() + + + [Querverweise] + + <SfxItemPool::LoadItem(SvStream&,FASTBOOL)const> +*/ + +{ + DBG_ASSERT( !IsInvalidItem(&rItem), "cannot store invalid items" ); + + if ( IsSlot( rItem.Which() ) ) + return FALSE; + const SfxItemPool *pPool = this; + while ( !pPool->IsInStoringRange(rItem.Which()) ) + if ( 0 == ( pPool = pPool->pSecondary ) ) + return FALSE; + + DBG_ASSERT( !pImp->bInSetItem || !rItem.ISA(SfxSetItem), + "SetItem contains ItemSet with SetItem" ); + + USHORT nSlotId = pPool->GetSlotId( rItem.Which(), TRUE ); + USHORT nItemVersion = rItem.GetVersion(_nFileFormatVersion); + if ( USHRT_MAX == nItemVersion ) + return FALSE; + + rStream << rItem.Which() << nSlotId; + if ( bDirect || !pPool->StoreSurrogate( rStream, &rItem ) ) + { + rStream << nItemVersion; + rStream << (UINT32) 0L; // Platz fuer Laenge in Bytes + ULONG nIStart = rStream.Tell(); + rItem.Store(rStream, nItemVersion); + ULONG nIEnd = rStream.Tell(); + rStream.Seek( nIStart-4 ); + rStream << (INT32) ( nIEnd-nIStart ); + rStream.Seek( nIEnd ); + } + + return TRUE; +} + +//------------------------------------------------------------------------- + + +const SfxPoolItem* SfxItemPool::LoadItem( SvStream &rStream, FASTBOOL bDirect, + const SfxItemPool *pRefPool ) + +// pRefPool==-1 => nicht putten! + +{ + USHORT nWhich, nSlot; // nSurrogate; + rStream >> nWhich >> nSlot; + + BOOL bDontPut = (SfxItemPool*)-1 == pRefPool; + if ( bDontPut || !pRefPool ) + pRefPool = this; + + // richtigen Sekund"ar-Pool finden + while ( !pRefPool->IsInVersionsRange(nWhich) ) + { + if ( pRefPool->pSecondary ) + pRefPool = pRefPool->pSecondary; + else + { + // WID in der Version nicht vorhanden => ueberspringen + USHORT nSurro, nVersion, nLen; + rStream >> nSurro; + if ( SFX_ITEMS_DIRECT == nSurro ) + { + rStream >> nVersion >> nLen; + rStream.SeekRel( nLen ); + } + return 0; + } + } + + // wird eine andere Version geladen? + FASTBOOL bCurVersion = pRefPool->IsCurrentVersionLoading(); + if ( !bCurVersion ) + // Which-Id auf neue Version mappen + nWhich = pRefPool->GetNewWhich( nWhich ); + + DBG_ASSERT( !nWhich || !pImp->bInSetItem || + !pRefPool->ppStaticDefaults[pRefPool->GetIndex_Impl(nWhich)]->ISA(SfxSetItem), + "loading SetItem in ItemSet of SetItem" ); + + // soll "uber Surrogat geladen werden? + const SfxPoolItem *pItem = 0; + if ( !bDirect ) + { + // Which-Id in dieser Version bekannt? + if ( nWhich ) + // Surrogat laden, reagieren falls keins vorhanden + pItem = LoadSurrogate( rStream, nWhich, nSlot, pRefPool ); + else + // sonst "uberspringen + rStream.SeekRel( sizeof(USHORT) ); + } + + // wird direkt, also nicht "uber Surrogat geladen? + if ( bDirect || ( nWhich && !pItem ) ) + { + // bDirekt bzw. nicht IsPoolable() => Item direkt laden + USHORT nVersion; + sal_uInt32 nLen; + rStream >> nVersion >> nLen; + ULONG nIStart = rStream.Tell(); + + // Which-Id in dieser Version bekannt? + if ( nWhich ) + { + // Item direkt laden + SfxPoolItem *pNewItem = + pRefPool->GetDefaultItem(nWhich).Create(rStream, nVersion); + if ( bDontPut ) + pItem = pNewItem; + else + if ( pNewItem ) + { + pItem = &Put(*pNewItem); + delete pNewItem; + } + else + pItem = 0; + ULONG nIEnd = rStream.Tell(); + DBG_ASSERT( nIEnd <= (nIStart+nLen), "read past end of item" ); + if ( (nIStart+nLen) != nIEnd ) + rStream.Seek( nIStart+nLen ); + } + else + // Item "uberspringen + rStream.Seek( nIStart+nLen ); + } + + return pItem; +} + + diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx new file mode 100644 index 000000000000..4957c5c16945 --- /dev/null +++ b/svl/source/items/poolitem.cxx @@ -0,0 +1,527 @@ +/************************************************************************* + * + * 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: poolitem.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/poolitem.hxx> +#include <tools/stream.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxPoolItem) +DBG_NAME(SfxVoidItem) +// @@@ DBG_NAME(SfxInvalidItem); +DBG_NAME(SfxItemHandle) + +BYTE nSfxFlag8Val[8] = +{ + 1, 2, 4, 8, 16, 32, 64, 128 +}; + +USHORT nSfxFlag16Val[16] = +{ + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, + 1024, 2048, 4096, 8192, 16384, 32768 +}; + +ULONG nSfxFlag32Val[32] = +{ + 0x1L, 0x2L, 0x4L, 0x8L, + 0x10L, 0x20L, 0x40L, 0x80L, + 0x100L, 0x200L, 0x400L, 0x800L, + 0x1000L, 0x2000L, 0x40000L, 0x8000L, + 0x10000L, 0x20000L, 0x40000L, 0x80000L, + 0x100000L, 0x200000L, 0x400000L, 0x800000L, + 0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L, + 0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L +}; + +// RTTI ------------------------------------------------------------------ + +TYPEINIT0(SfxPoolItem); +TYPEINIT1(SfxVoidItem, SfxPoolItem); +// @@@ TYPEINIT1(SfxInvalidItem, SfxPoolItem); +TYPEINIT1(SfxSetItem, SfxPoolItem); +// @@@ TYPEINIT1(SfxItemChangedHint, SfxHint); + +// ------------------------------------------------------------------------ +#if OSL_DEBUG_LEVEL > 1 +static ULONG nItemCount = 0; + +const char* pw1 = "Wow! 10.000 items!"; +const char* pw2 = "Wow! 100.000 items!"; +const char* pw3 = "Wow! 1.000.000 items!"; +const char* pw4 = "Wow! 50.000.000 items!"; +const char* pw5 = "Wow! 10.000.000 items!"; +#endif + +IMPL_PTRHINT(SfxPoolItemHint,SfxPoolItem) + +// SfxPoolItem ----------------------------------------------------------- +SfxPoolItem::SfxPoolItem( USHORT nW ) + : nRefCount( 0 ), + nWhich( nW ) + , nKind( 0 ) +{ + DBG_CTOR(SfxPoolItem, 0); + DBG_ASSERT(nW <= SHRT_MAX, "Which Bereich ueberschritten"); +#if OSL_DEBUG_LEVEL > 1 + ++nItemCount; + if ( pw1 && nItemCount>=10000 ) + { + DBG_WARNING( pw1 ); + pw1 = NULL; + } + if ( pw2 && nItemCount>=100000 ) + { + DBG_WARNING( pw2 ); + pw2 = NULL; + } + if ( pw3 && nItemCount>=1000000 ) + { + DBG_WARNING( pw3 ); + pw3 = NULL; + } + if ( pw4 && nItemCount>=5000000 ) + { + DBG_WARNING( pw4 ); + pw4 = NULL; + } + if ( pw5 && nItemCount>=10000000 ) + { + DBG_WARNING( pw5 ); + pw5 = NULL; + } +#endif +} + +// ----------------------------------------------------------------------- +SfxPoolItem::SfxPoolItem( const SfxPoolItem& rCpy ) + : nRefCount( 0 ), // wird ja ein neues Object! + nWhich( rCpy.Which() ) // Funktion rufen wg. ChkThis() + , nKind( 0 ) +{ + DBG_CTOR(SfxPoolItem, 0); +#if OSL_DEBUG_LEVEL > 1 + ++nItemCount; + if ( pw1 && nItemCount>=10000 ) + { + DBG_WARNING( pw1 ); + pw1 = NULL; + } + if ( pw2 && nItemCount>=100000 ) + { + DBG_WARNING( pw2 ); + pw2 = NULL; + } + if ( pw3 && nItemCount>=1000000 ) + { + DBG_WARNING( pw3 ); + pw3 = NULL; + } + if ( pw4 && nItemCount>=5000000 ) + { + DBG_WARNING( pw4 ); + pw4 = NULL; + } + if ( pw5 && nItemCount>=10000000 ) + { + DBG_WARNING( pw5 ); + pw5 = NULL; + } +#endif +} + +// ------------------------------------------------------------------------ +SfxPoolItem::~SfxPoolItem() +{ + DBG_DTOR(SfxPoolItem, 0); + DBG_ASSERT(nRefCount == 0 || nRefCount > SFX_ITEMS_MAXREF, "destroying item in use" ); +#if OSL_DEBUG_LEVEL > 1 + --nItemCount; +#endif +} + +// ------------------------------------------------------------------------ +int SfxPoolItem::Compare( const SfxPoolItem& ) const +{ + return 0; +} + +// ------------------------------------------------------------------------ +int SfxPoolItem::Compare( const SfxPoolItem& rWith, const IntlWrapper& ) const +{ + return Compare( rWith ); +} + +// ------------------------------------------------------------------------ +int SfxPoolItem::operator==( const SfxPoolItem& rCmp ) const +{ + DBG_CHKTHIS(SfxPoolItem, 0); + return rCmp.Type() == Type(); +} + +// ----------------------------------------------------------------------- +#ifndef TF_POOLABLE + +int SfxPoolItem::IsPoolable() const +{ + DBG_CHKTHIS(SfxPoolItem, 0); + return TRUE; +} +#endif + +// ----------------------------------------------------------------------- +SfxPoolItem* SfxPoolItem::Create(SvStream &, USHORT) const +{ + DBG_CHKTHIS(SfxPoolItem, 0); + return Clone(0); +} + +// ----------------------------------------------------------------------- +USHORT SfxPoolItem::GetVersion( USHORT ) const +{ + DBG_CHKTHIS(SfxPoolItem, 0); + return 0; +} + +// ----------------------------------------------------------------------- +SvStream& SfxPoolItem::Store(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxPoolItem, 0); + return rStream; +} + +//============================================================================ +// static +bool SfxPoolItem::readByteString(SvStream & rStream, UniString & rString) +{ + rStream.ReadByteString(rString); + return rStream.GetError() == ERRCODE_NONE; +} + +//============================================================================ +// static +void SfxPoolItem::writeByteString(SvStream & rStream, + UniString const & rString) +{ + rStream.WriteByteString(rString); +} + +//============================================================================ +// static +bool SfxPoolItem::readUnicodeString(SvStream & rStream, UniString & rString, + bool bUnicode) +{ + rStream.ReadByteString(rString, + bUnicode ? RTL_TEXTENCODING_UCS2 : + rStream.GetStreamCharSet()); + return rStream.GetError() == ERRCODE_NONE; +} + +//============================================================================ +// static +void SfxPoolItem::writeUnicodeString(SvStream & rStream, + UniString const & rString) +{ + rStream.WriteByteString(rString, RTL_TEXTENCODING_UCS2); +} + +// ------------------------------------------------------------------------ +SfxItemPresentation SfxPoolItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, // IN: wie formatiert werden soll + SfxMapUnit /*eCoreMetric*/, // IN: Ma\seinheit des SfxPoolItems + SfxMapUnit /*ePresentationMetric*/, // IN: Wunsch-Ma\einheit der Darstellung + XubString& /*rText*/, // OUT: textuelle Darstellung + const IntlWrapper * +) const + +/* [Beschreibung] + + "Uber diese virtuelle Methode kann von den SfxPoolItem-Subklassen + eine textuelle Datstellung des Wertes erhalten werden. Sie sollte + von allen UI-relevanten SfxPoolItem-Subklassen "uberladen werden. + + Da die Ma\seinheit des Wertes im SfxItemPool nur "uber + <SfxItemPool::GetMetric(USHORT)const> erfragbar ist, und nicht etwa + in der SfxPoolItem-Instanz oder -Subklasse verf"ugbar ist, wird die + eigene Ma\seinheit als 'eCoreMetric' "ubergeben. + + Die darzustellende Ma\seinheit wird als 'ePresentationMetric' + "ubergeben. + + + [R"uckgabewert] + + SfxItemPresentation SFX_ITEM_PRESENTATION_NONE + es konnte keine Text-Darstellung erzeugt werden + + SFX_ITEM_PRESENTATION_NAMELESS + es konnte eine Text-Darstellung (ggf. mit + Ma\seinheit) erzeugt werden, die jedoch keine + semantische Bedeutung enth"alt + + SFX_ITEM_PRESENTATION_COMPLETE + es konnte eine komplette Text-Darstellung mit + semantischer Bedeutung (und ggf. Ma\seinheit) + erzeugt werden + + + [Beispiele] + + pSvxFontItem->GetPresentation( SFX_PRESENTATION_NAMELESS, ... ) + "12pt" mit return SFX_ITEM_PRESENTATION_NAMELESS + + pSvxColorItem->GetPresentation( SFX_PRESENTATION_COMPLETE, ... ) + "rot" mit return SFX_ITEM_PRESENTATION_NAMELESS + (das das SvxColorItem nicht wei\s, was f"ur eine Farbe es darstellt, + kann es keinen Namen angeben, was durch den Returnwert mitgeteilt wird. + + pSvxBorderItem->GetPresentation( SFX_PRESENTATION_COMPLETE, ... ) + "1cm oberer Rand, 2cm linker Rand, 0,2cm unterer Rand, ..." +*/ + +{ + return SFX_ITEM_PRESENTATION_NONE; +} + +// SfxVoidItem ------------------------------------------------------------ +SfxVoidItem::SfxVoidItem( USHORT which ): + SfxPoolItem(which) +{ + DBG_CTOR(SfxVoidItem, 0); +} + +// SfxVoidItem ------------------------------------------------------------ +SfxVoidItem::SfxVoidItem( const SfxVoidItem& rCopy): + SfxPoolItem(rCopy) +{ + DBG_CTOR(SfxVoidItem, 0); +} + +// ------------------------------------------------------------------------ +int SfxVoidItem::operator==( const SfxPoolItem& +#ifdef DBG_UTIL +rCmp +#endif +) const +{ + DBG_CHKTHIS(SfxVoidItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rCmp ), "unequal type" ); + return TRUE; +} + +// ------------------------------------------------------------------------ +SfxItemPresentation SfxVoidItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxVoidItem, 0); + rText.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Void")); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ------------------------------------------------------------------------ +SfxPoolItem* SfxVoidItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxVoidItem, 0); + return new SfxVoidItem(*this); +} + +// SfxInvalidItem --------------------------------------------------------- +#if 0 /* @@@ NOT USED @@@ */ +SfxInvalidItem::SfxInvalidItem( USHORT nWhich, const SfxPoolItem &rDefault ): + SfxPoolItem(nWhich), + pDefaultItem(&rDefault) +{ + DBG_CTOR(SfxInvalidItem, 0); +} + +// ------------------------------------------------------------------------ +SfxInvalidItem::SfxInvalidItem( const SfxInvalidItem& rCopy): + SfxPoolItem(rCopy), + pDefaultItem(rCopy.pDefaultItem) +{ + DBG_CTOR(SfxInvalidItem, 0); + //! pDefaultItem->ReleaseRef? +} + +// ------------------------------------------------------------------------ +SfxInvalidItem::~SfxInvalidItem() +{ + DBG_DTOR(SfxInvalidItem, 0); +} + +// ------------------------------------------------------------------------ +int SfxInvalidItem::operator==( const SfxPoolItem& rCmp) const +{ + DBG_CHKTHIS(SfxInvalidItem, 0); + DBG_ASSERT( SfxPoolItem::operator==(rCmp), "unequal type" ); + return *pDefaultItem == *((SfxInvalidItem&)rCmp).pDefaultItem; +} + +// ------------------------------------------------------------------------ +SfxItemPresentation SfxInvalidItem::GetPresentation +( + SfxItemPresentation ePresentation, + SfxMapUnit eCoreMetric, + SfxMapUnit ePresentationMetric, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxInvalidItem, 0); + rText.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Invalid")); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ------------------------------------------------------------------------ +SfxPoolItem* SfxInvalidItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxInvalidItem, 0); + return new SfxInvalidItem(*this); +} + +// ------------------------------------------------------------------------ +SfxPoolItem* SfxInvalidItem::Create(SvStream &, USHORT nVersion) const +{ + DBG_CHKTHIS(SfxInvalidItem, 0); + DBG_ERROR("SfxInvalidItem::Create() ist sinnlos"); + return Clone(); +} + +// ------------------------------------------------------------------------ +SvStream& SfxInvalidItem::Store(SvStream &rStream, USHORT nItemVersion ) const +{ + DBG_CHKTHIS(SfxInvalidItem, 0); + DBG_ERROR("SfxInvalidItem::Store() ist sinnlos"); + return rStream; +} +#endif /* @@@ NOT USED @@@ */ + +// SfxItemHandle ---------------------------------------------------------- +SfxItemHandle::SfxItemHandle(SfxPoolItem &rItem): + pRef(new USHORT(1)), + pItem(rItem.Clone(0)) +{ + DBG_CTOR(SfxItemHandle, 0); +} + +// ------------------------------------------------------------------------ +SfxItemHandle::SfxItemHandle(const SfxItemHandle &rCopy): + pRef(rCopy.pRef), + pItem(rCopy.pItem) +{ + DBG_CTOR(SfxItemHandle, 0); + ++(*pRef); +} + +// ------------------------------------------------------------------------ +const SfxItemHandle &SfxItemHandle::operator=(const SfxItemHandle &rCopy) +{ + DBG_CHKTHIS(SfxItemHandle, 0); + if(&rCopy == this || pItem == rCopy.pItem) + return *this; + --(*pRef); + if(!(*pRef)) + { + delete pItem; + pItem = 0; + } + pRef = rCopy.pRef; + ++(*pRef); + pItem = rCopy.pItem; + return *this; +} + +// ------------------------------------------------------------------------ +SfxItemHandle::~SfxItemHandle() +{ + DBG_DTOR(SfxItemHandle, 0); + --(*pRef); + if(!(*pRef)) { + delete pRef; pRef = 0; + delete pItem; pItem = 0; + } +} + +// ------------------------------------------------------------------------ +int SfxPoolItem::ScaleMetrics( long /*lMult*/, long /*lDiv*/ ) +{ + return 0; +} + +// ------------------------------------------------------------------------ +int SfxPoolItem::HasMetrics() const +{ + return 0; +} + +// ----------------------------------------------------------------------- +#if 0 /* @@@ NOT USED @@@ */ +void SfxPoolItem::GetVersion() const +{ + DBG_ERROR( "dummy called" ); +} + +// ----------------------------------------------------------------------- +void SfxPoolItem::Store(SvStream &rStream) const +{ + DBG_ERROR( "dummy called" ); +} +#endif /* @@@ NOT USED @@@ */ + +// ----------------------------------------------------------------------- + +BOOL SfxPoolItem::QueryValue( com::sun::star::uno::Any&, BYTE ) const +{ + DBG_ERROR("There is no implementation for QueryValue for this item!"); + return FALSE; +} + +// ----------------------------------------------------------------------- + +BOOL SfxPoolItem::PutValue( const com::sun::star::uno::Any&, BYTE ) +{ + DBG_ERROR("There is no implementation for PutValue for this item!"); + return FALSE; +} + +SfxVoidItem::~SfxVoidItem() +{ + DBG_DTOR(SfxVoidItem, 0); +} diff --git a/svl/source/items/ptitem.cxx b/svl/source/items/ptitem.cxx new file mode 100644 index 000000000000..30fef0227397 --- /dev/null +++ b/svl/source/items/ptitem.cxx @@ -0,0 +1,208 @@ +/************************************************************************* + * + * 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: ptitem.cxx,v $ + * $Revision: 1.12 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/ptitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/awt/Point.hpp> +#include <tools/stream.hxx> + +#include <svl/poolitem.hxx> +#include "memberid.hrc" + +using namespace ::com::sun::star; +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxPointItem) + +#define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L)) +#define MM100_TO_TWIP(MM100) ((MM100) >= 0 ? (((MM100)*72L+63L)/127L) : (((MM100)*72L-63L)/127L)) + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxPointItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxPointItem::SfxPointItem() +{ + DBG_CTOR(SfxPointItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxPointItem::SfxPointItem( USHORT nW, const Point& rVal ) : + SfxPoolItem( nW ), + aVal( rVal ) +{ + DBG_CTOR(SfxPointItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxPointItem::SfxPointItem( USHORT nW, SvStream &rStream ) : + SfxPoolItem( nW ) +{ + DBG_CTOR(SfxPointItem, 0); + rStream >> aVal; +} + +// ----------------------------------------------------------------------- + +SfxPointItem::SfxPointItem( const SfxPointItem& rItem ) : + SfxPoolItem( rItem ), + aVal( rItem.aVal ) +{ + DBG_CTOR(SfxPointItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxPointItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxPointItem, 0); + rText = UniString::CreateFromInt32(aVal.X()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += UniString::CreateFromInt32(aVal.Y()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ----------------------------------------------------------------------- + +int SfxPointItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxPointItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + return ((SfxPointItem&)rItem).aVal == aVal; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxPointItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxPointItem, 0); + return new SfxPointItem( *this ); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxPointItem::Create(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxPointItem, 0); + Point aStr; + rStream >> aStr; + return new SfxPointItem(Which(), aStr); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxPointItem::Store(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxPointItem, 0); + rStream << aVal; + return rStream; +} + +// ----------------------------------------------------------------------- + +BOOL SfxPointItem::QueryValue( uno::Any& rVal, + BYTE nMemberId ) const +{ + sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + awt::Point aTmp(aVal.X(), aVal.Y()); + if( bConvert ) + { + aTmp.X = TWIP_TO_MM100(aTmp.X); + aTmp.Y = TWIP_TO_MM100(aTmp.Y); + } + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case 0: rVal <<= aTmp; break; + case MID_X: rVal <<= aTmp.X; break; + case MID_Y: rVal <<= aTmp.Y; break; + default: DBG_ERROR("Wrong MemberId!"); return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- + +BOOL SfxPointItem::PutValue( const uno::Any& rVal, + BYTE nMemberId ) +{ + sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + BOOL bRet = FALSE; + awt::Point aValue; + sal_Int32 nVal = 0; + if ( !nMemberId ) + { + bRet = ( rVal >>= aValue ); + if( bConvert ) + { + aValue.X = MM100_TO_TWIP(aValue.X); + aValue.Y = MM100_TO_TWIP(aValue.Y); + } + } + else + { + bRet = ( rVal >>= nVal ); + if( bConvert ) + nVal = MM100_TO_TWIP( nVal ); + } + + if ( bRet ) + { + switch ( nMemberId ) + { + case 0: aVal.setX( aValue.X ); aVal.setY( aValue.Y ); break; + case MID_X: aVal.setX( nVal ); break; + case MID_Y: aVal.setY( nVal ); break; + default: DBG_ERROR("Wrong MemberId!"); return FALSE; + } + } + + return bRet; +} + + + diff --git a/svl/source/items/rectitem.cxx b/svl/source/items/rectitem.cxx new file mode 100644 index 000000000000..26c4876d8c2c --- /dev/null +++ b/svl/source/items/rectitem.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * 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: rectitem.cxx,v $ + * $Revision: 1.12 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/rectitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/awt/Rectangle.hpp> +#include <tools/stream.hxx> + +#include <svl/poolitem.hxx> +#include "memberid.hrc" + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxRectangleItem) + + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxRectangleItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxRectangleItem::SfxRectangleItem() +{ + DBG_CTOR(SfxRectangleItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxRectangleItem::SfxRectangleItem( USHORT nW, const Rectangle& rVal ) : + SfxPoolItem( nW ), + aVal( rVal ) +{ + DBG_CTOR(SfxRectangleItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxRectangleItem::SfxRectangleItem( USHORT nW, SvStream &rStream ) : + SfxPoolItem( nW ) +{ + DBG_CTOR(SfxRectangleItem, 0); + rStream >> aVal; +} + +// ----------------------------------------------------------------------- + +SfxRectangleItem::SfxRectangleItem( const SfxRectangleItem& rItem ) : + SfxPoolItem( rItem ), + aVal( rItem.aVal ) +{ + DBG_CTOR(SfxRectangleItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxRectangleItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxRectangleItem, 0); + rText = UniString::CreateFromInt32(aVal.Top()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += UniString::CreateFromInt32(aVal.Left()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += UniString::CreateFromInt32(aVal.Bottom()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += UniString::CreateFromInt32(aVal.Right()); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ----------------------------------------------------------------------- + +int SfxRectangleItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxRectangleItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + return ((SfxRectangleItem&)rItem).aVal == aVal; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxRectangleItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxRectangleItem, 0); + return new SfxRectangleItem( *this ); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxRectangleItem::Create(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxRectangleItem, 0); + Rectangle aStr; + rStream >> aStr; + return new SfxRectangleItem(Which(), aStr); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxRectangleItem::Store(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxRectangleItem, 0); + rStream << aVal; + return rStream; +} + + +// ----------------------------------------------------------------------- +BOOL SfxRectangleItem::QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case 0: + { + rVal <<= com::sun::star::awt::Rectangle( aVal.getX(), + aVal.getY(), + aVal.getWidth(), + aVal.getHeight() ); + break; + } + case MID_RECT_LEFT: rVal <<= aVal.getX(); break; + case MID_RECT_RIGHT: rVal <<= aVal.getY(); break; + case MID_WIDTH: rVal <<= aVal.getWidth(); break; + case MID_HEIGHT: rVal <<= aVal.getHeight(); break; + default: DBG_ERROR("Wrong MemberID!"); return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- +BOOL SfxRectangleItem::PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId ) +{ + BOOL bRet = FALSE; + nMemberId &= ~CONVERT_TWIPS; + com::sun::star::awt::Rectangle aValue; + sal_Int32 nVal = 0; + if ( !nMemberId ) + bRet = (rVal >>= aValue); + else + bRet = (rVal >>= nVal); + + if ( bRet ) + { + switch ( nMemberId ) + { + case 0: + aVal.setX( aValue.X ); + aVal.setY( aValue.Y ); + aVal.setWidth( aValue.Width ); + aVal.setHeight( aValue.Height ); + break; + case MID_RECT_LEFT: aVal.setX( nVal ); break; + case MID_RECT_RIGHT: aVal.setY( nVal ); break; + case MID_WIDTH: aVal.setWidth( nVal ); break; + case MID_HEIGHT: aVal.setHeight( nVal ); break; + default: DBG_ERROR("Wrong MemberID!"); return FALSE; + } + } + + return bRet; +} + + + diff --git a/svl/source/items/rngitem.cxx b/svl/source/items/rngitem.cxx new file mode 100644 index 000000000000..b6340d662112 --- /dev/null +++ b/svl/source/items/rngitem.cxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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: rngitem.cxx,v $ + * $Revision: 1.12 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/stream.hxx> + +#ifndef NUMTYPE + +#define NUMTYPE USHORT +#define SfxXRangeItem SfxRangeItem +#define SfxXRangesItem SfxUShortRangesItem +#include <svl/rngitem.hxx> +#include "rngitem_inc.cxx" + +#define NUMTYPE sal_uInt32 +#define SfxXRangeItem SfxULongRangeItem +#define SfxXRangesItem SfxULongRangesItem +#include <svl/rngitem.hxx> +#include "rngitem_inc.cxx" + +#else + +// We leave this condition just in case NUMTYPE has been defined externally to this +// file and we are supposed to define the SfxXRangeItem based on that. + +#include "rngitem_inc.cxx" + +#endif + diff --git a/svl/source/items/rngitem_inc.cxx b/svl/source/items/rngitem_inc.cxx new file mode 100755 index 000000000000..d8cc7ed185ae --- /dev/null +++ b/svl/source/items/rngitem_inc.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * 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: rngitem_inc.cxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// This snippet of code is included by rngitem.cxx but not compiled directly. +// Ugly hack, probably due to lack of templates in the 20th century. + +static inline NUMTYPE Count_Impl(const NUMTYPE * pRanges) +{ + NUMTYPE nCount = 0; + for (; *pRanges; pRanges += 2) nCount += 2; + return nCount; +} + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxXRangeItem, SfxPoolItem); +TYPEINIT1_AUTOFACTORY(SfxXRangesItem, SfxPoolItem); + +NUMTYPE Count_Impl( const NUMTYPE *pRanges ); + +// ----------------------------------------------------------------------- + +SfxXRangeItem::SfxXRangeItem() +{ + nFrom = 0; + nTo = 0; +} + +// ----------------------------------------------------------------------- + +SfxXRangeItem::SfxXRangeItem( USHORT which, NUMTYPE from, NUMTYPE to ): + SfxPoolItem( which ), + nFrom( from ), + nTo( to ) +{ +} + + +// ----------------------------------------------------------------------- + +SfxXRangeItem::SfxXRangeItem( USHORT nW, SvStream &rStream ) : + SfxPoolItem( nW ) +{ + rStream >> nFrom; + rStream >> nTo; +} + +// ----------------------------------------------------------------------- + +SfxXRangeItem::SfxXRangeItem( const SfxXRangeItem& rItem ) : + SfxPoolItem( rItem ) +{ + nFrom = rItem.nFrom; + nTo = rItem.nTo; +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxXRangeItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + rText = UniString::CreateFromInt64(nFrom); + rText += ':'; + rText += UniString::CreateFromInt64(nTo); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ----------------------------------------------------------------------- + +int SfxXRangeItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + SfxXRangeItem* pT = (SfxXRangeItem*)&rItem; + if( nFrom==pT->nFrom && nTo==pT->nTo ) + return 1; + return 0; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxXRangeItem::Clone(SfxItemPool *) const +{ + return new SfxXRangeItem( Which(), nFrom, nTo ); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxXRangeItem::Create(SvStream &rStream, USHORT) const +{ + NUMTYPE nVon, nBis; + rStream >> nVon; + rStream >> nBis; + return new SfxXRangeItem( Which(), nVon, nBis ); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxXRangeItem::Store(SvStream &rStream, USHORT) const +{ + rStream << nFrom; + rStream << nTo; + return rStream; +} + +//========================================================================= + +SfxXRangesItem::SfxXRangesItem() +: _pRanges(0) +{ +} + +//------------------------------------------------------------------------- + +SfxXRangesItem::SfxXRangesItem( USHORT nWID, const NUMTYPE *pRanges ) +: SfxPoolItem( nWID ) +{ + NUMTYPE nCount = Count_Impl(pRanges) + 1; + _pRanges = new NUMTYPE[nCount]; + memcpy( _pRanges, pRanges, sizeof(NUMTYPE) * nCount ); +} + +//------------------------------------------------------------------------- + +SfxXRangesItem::SfxXRangesItem( USHORT nWID, SvStream &rStream ) +: SfxPoolItem( nWID ) +{ + NUMTYPE nCount; + rStream >> nCount; + _pRanges = new NUMTYPE[nCount + 1]; + for ( NUMTYPE n = 0; n < nCount; ++n ) + rStream >> _pRanges[n]; + _pRanges[nCount] = 0; +} + +//------------------------------------------------------------------------- + +SfxXRangesItem::SfxXRangesItem( const SfxXRangesItem& rItem ) +: SfxPoolItem( rItem ) +{ + NUMTYPE nCount = Count_Impl(rItem._pRanges) + 1; + _pRanges = new NUMTYPE[nCount]; + memcpy( _pRanges, rItem._pRanges, sizeof(NUMTYPE) * nCount ); +} + +//------------------------------------------------------------------------- + +SfxXRangesItem::~SfxXRangesItem() +{ + delete _pRanges; +} + +//------------------------------------------------------------------------- + +int SfxXRangesItem::operator==( const SfxPoolItem &rItem ) const +{ + const SfxXRangesItem &rOther = (const SfxXRangesItem&) rItem; + if ( !_pRanges && !rOther._pRanges ) + return TRUE; + if ( _pRanges || rOther._pRanges ) + return FALSE; + + NUMTYPE n; + for ( n = 0; _pRanges[n] && rOther._pRanges[n]; ++n ) + if ( *_pRanges != rOther._pRanges[n] ) + return 0; + + return !_pRanges[n] && !rOther._pRanges[n]; +} + +//------------------------------------------------------------------------- + +SfxItemPresentation SfxXRangesItem::GetPresentation( SfxItemPresentation /*ePres*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresMetric*/, + XubString &/*rText*/, + const IntlWrapper * ) const +{ + HACK(n. i.) + return SFX_ITEM_PRESENTATION_NONE; +} + +//------------------------------------------------------------------------- + +SfxPoolItem* SfxXRangesItem::Clone( SfxItemPool * ) const +{ + return new SfxXRangesItem( *this ); +} + +//------------------------------------------------------------------------- + +SfxPoolItem* SfxXRangesItem::Create( SvStream &rStream, USHORT ) const +{ + return new SfxXRangesItem( Which(), rStream ); +} + +//------------------------------------------------------------------------- + +SvStream& SfxXRangesItem::Store( SvStream &rStream, USHORT ) const +{ + NUMTYPE nCount = Count_Impl( _pRanges ); + rStream >> nCount; + for ( NUMTYPE n = 0; _pRanges[n]; ++n ) + rStream >> _pRanges[n]; + return rStream; +} + + +#undef NUMTYPE +#undef SfxXRangeItem +#undef SfxXRangesItem diff --git a/svl/source/items/sfontitm.cxx b/svl/source/items/sfontitm.cxx new file mode 100644 index 000000000000..9ec06bc5a105 --- /dev/null +++ b/svl/source/items/sfontitm.cxx @@ -0,0 +1,142 @@ +/************************************************************************* + * + * 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: sfontitm.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/stream.hxx> +#include <tools/vcompat.hxx> +#include <svl/sfontitm.hxx> + +//============================================================================ +// +// class SfxFontItem +// +//============================================================================ + +TYPEINIT1(SfxFontItem, SfxPoolItem); + +//============================================================================ +// virtual +int SfxFontItem::operator ==(const SfxPoolItem & rItem) const +{ + const SfxFontItem * pFontItem = PTR_CAST(SfxFontItem, &rItem); + return pFontItem && m_bHasFont == pFontItem->m_bHasFont + && m_bHasColor == pFontItem->m_bHasColor + && m_bHasFillColor == pFontItem->m_bHasFillColor + && (!m_bHasColor || m_aColor == pFontItem->m_aColor) + && (!m_bHasFillColor || m_aFillColor == pFontItem->m_aFillColor) + && (!m_bHasFont || (m_bKerning == pFontItem->m_bKerning + && m_bShadow == pFontItem->m_bShadow + && m_bOutline == pFontItem->m_bOutline + && m_bWordLine == pFontItem->m_bWordLine + && m_nOrientation == pFontItem->m_nOrientation + && m_nStrikeout == pFontItem->m_nStrikeout + && m_nUnderline == pFontItem->m_nUnderline + && m_nItalic == pFontItem->m_nItalic + && m_nWidthType == pFontItem->m_nWidthType + && m_nWeight == pFontItem->m_nWeight + && m_nPitch == pFontItem->m_nPitch + && m_nFamily == pFontItem->m_nFamily + && m_nLanguage == pFontItem->m_nLanguage + && m_nCharSet == pFontItem->m_nCharSet + && m_aFillColor == pFontItem->m_aFillColor + && m_aColor == pFontItem->m_aColor + && m_aSize == pFontItem->m_aSize + && m_aStyleName == pFontItem->m_aStyleName + && m_aName == pFontItem->m_aName)); +} + +//============================================================================ +// virtual +SfxPoolItem * SfxFontItem::Create(SvStream & rStream, USHORT) const +{ + VersionCompat aItemCompat(rStream, STREAM_READ); + SfxFontItem * pItem = new SfxFontItem(Which()); + { + VersionCompat aFontCompat(rStream, STREAM_READ); + readByteString(rStream, pItem->m_aName); + readByteString(rStream, pItem->m_aStyleName); + rStream >> pItem->m_aSize; + sal_Int16 nCharSet = 0; + rStream >> nCharSet; + pItem->m_nCharSet = rtl_TextEncoding(nCharSet); + rStream >> pItem->m_nFamily >> pItem->m_nPitch >> pItem->m_nWeight + >> pItem->m_nUnderline >> pItem->m_nStrikeout + >> pItem->m_nItalic; + sal_Int16 nLanguage = 0; + rStream >> nLanguage; + pItem->m_nLanguage = LanguageType(nLanguage); + rStream >> pItem->m_nWidthType >> pItem->m_nOrientation; + sal_Int8 nWordLine = 0; + rStream >> nWordLine; + pItem->m_bWordLine = nWordLine != 0; + sal_Int8 nOutline = 0; + rStream >> nOutline; + pItem->m_bOutline = nOutline != 0; + sal_Int8 nShadow = 0; + rStream >> nShadow; + pItem->m_bShadow = nShadow != 0; + sal_Int8 nKerning = 0; + rStream >> nKerning; + pItem->m_bKerning = nKerning != 0; + } + pItem->m_aColor.Read(rStream, TRUE); + pItem->m_aFillColor.Read(rStream, TRUE); + sal_Int16 nFlags = 0; + rStream >> nFlags; + pItem->m_bHasFont = (nFlags & 4) != 0; + pItem->m_bHasColor = (nFlags & 1) != 0; + pItem->m_bHasFillColor = (nFlags & 2) != 0; + return pItem; +} + +//============================================================================ +// virtual +SvStream & SfxFontItem::Store(SvStream & rStream, USHORT) const +{ + VersionCompat aItemCompat(rStream, STREAM_WRITE, 1); + { + VersionCompat aFontCompat(rStream, STREAM_WRITE, 1); + writeByteString(rStream, m_aName); + writeByteString(rStream, m_aStyleName); + rStream << m_aSize << sal_Int16(m_nCharSet) + << m_nFamily << m_nPitch << m_nWeight << m_nUnderline + << m_nStrikeout << m_nItalic << sal_Int16(m_nLanguage) + << m_nWidthType << m_nOrientation << sal_Int8(m_bWordLine) + << sal_Int8(m_bOutline) << sal_Int8(m_bShadow) + << sal_Int8(m_bKerning); + } + SAL_CONST_CAST(Color &, m_aColor).Write(rStream, TRUE); + SAL_CONST_CAST(Color &, m_aFillColor).Write(rStream, TRUE); + rStream << sal_Int16(m_bHasFont << 2 | m_bHasColor + | m_bHasFillColor << 1); + return rStream; +} + diff --git a/svl/source/items/sitem.cxx b/svl/source/items/sitem.cxx new file mode 100644 index 000000000000..52f0931c9eae --- /dev/null +++ b/svl/source/items/sitem.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * 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: sitem.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +// INCLUDE --------------------------------------------------------------- + +#ifndef GCC +#endif + +#include <tools/string.hxx> +#include <tools/stream.hxx> + +#include <svl/poolitem.hxx> +#include <svl/itemset.hxx> + + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxSetItem) + +// -------------------------------------------------------------------------- + +SfxSetItem::SfxSetItem( USHORT which, const SfxItemSet &rSet) : + SfxPoolItem(which), + pSet(rSet.Clone(TRUE)) +{ + DBG_CTOR(SfxSetItem, 0); +} + +// -------------------------------------------------------------------------- + +SfxSetItem::SfxSetItem( USHORT which, SfxItemSet *pS) : + SfxPoolItem(which), + pSet(pS) +{ + DBG_CTOR(SfxSetItem, 0); + DBG_ASSERT(pS, "SfxSetItem without set constructed" ); +} + +// -------------------------------------------------------------------------- + +SfxSetItem::SfxSetItem( const SfxSetItem& rCopy, SfxItemPool *pPool ) : + SfxPoolItem(rCopy.Which()), + pSet(rCopy.pSet->Clone(TRUE, pPool)) +{ + DBG_CTOR(SfxSetItem, 0); +} + +// -------------------------------------------------------------------------- + +SfxSetItem::~SfxSetItem() +{ + DBG_DTOR(SfxSetItem, 0); + delete pSet; pSet = 0; +} + +// -------------------------------------------------------------------------- + +int SfxSetItem::operator==( const SfxPoolItem& rCmp) const +{ + DBG_CHKTHIS(SfxSetItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rCmp ), "unequal type" ); + return *pSet == *(((const SfxSetItem &)rCmp).pSet); +} + +// -------------------------------------------------------------------------- + +SfxItemPresentation SfxSetItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& /*rText*/, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxSetItem, 0); + return SFX_ITEM_PRESENTATION_NONE; +} + +// -------------------------------------------------------------------------- + +SvStream& SfxSetItem::Store(SvStream& rStream, USHORT) const +{ + GetItemSet().Store(rStream); + return rStream; +} + diff --git a/svl/source/items/slstitm.cxx b/svl/source/items/slstitm.cxx new file mode 100644 index 000000000000..d0dd801bb6f9 --- /dev/null +++ b/svl/source/items/slstitm.cxx @@ -0,0 +1,425 @@ +/************************************************************************* + * + * 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: slstitm.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/slstitm.hxx> +#include <svl/poolitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <tools/stream.hxx> + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxStringListItem) + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxStringListItem, SfxPoolItem); + +class SfxImpStringList +{ +public: + USHORT nRefCount; + List aList; + + SfxImpStringList() { nRefCount = 1; } + ~SfxImpStringList(); + void Sort( BOOL bAscending, List* ); +}; + +//------------------------------------------------------------------------ + +SfxImpStringList::~SfxImpStringList() +{ + DBG_ASSERT(nRefCount!=0xffff,"ImpList already deleted"); + String* pStr = (String*)aList.First(); + while( pStr ) + { + delete pStr; + pStr = (String*)aList.Next(); + } + nRefCount = 0xffff; +} + +//------------------------------------------------------------------------ + +void SfxImpStringList::Sort( BOOL bAscending, List* pParallelList ) +{ + DBG_ASSERT(!pParallelList || pParallelList->Count() >= aList.Count(),"Sort:ParallelList too small"); + ULONG nCount = aList.Count(); + if( nCount > 1 ) + { + nCount -= 2; + // Bubble Dir Einen + BOOL bSwapped = TRUE; + while( bSwapped ) + { + bSwapped = FALSE; + for( ULONG nCur = 0; nCur <= nCount; nCur++ ) + { + String* pStr1 = (String*)aList.GetObject( nCur ); + String* pStr2 = (String*)aList.GetObject( nCur+1 ); + // COMPARE_GREATER => pStr2 ist groesser als pStr1 + StringCompare eCompare = pStr1->CompareIgnoreCaseToAscii( *pStr2 ); //@@@ + BOOL bSwap = FALSE; + if( bAscending ) + { + if( eCompare == COMPARE_LESS ) + bSwap = TRUE; + } + else if( eCompare == COMPARE_GREATER ) + bSwap = TRUE; + + if( bSwap ) + { + bSwapped = TRUE; + aList.Replace( pStr1, nCur + 1 ); + aList.Replace( pStr2, nCur ); + if( pParallelList ) + { + void* p1 = pParallelList->GetObject( nCur ); + void* p2 = pParallelList->GetObject( nCur + 1 ); + pParallelList->Replace( p1, nCur + 1 ); + pParallelList->Replace( p2, nCur ); + } + } + } + } + } +} + +// class SfxStringListItem ----------------------------------------------- + +SfxStringListItem::SfxStringListItem() : + pImp(NULL) +{ +} + +//------------------------------------------------------------------------ + +SfxStringListItem::SfxStringListItem( USHORT which, const List* pList ) : + SfxPoolItem( which ), + pImp(NULL) +{ + // PB: das Putten einer leeren Liste funktionierte nicht, + // deshalb habe ich hier die Abfrage nach dem Count auskommentiert + if( pList /*!!! && pList->Count() */ ) + { + pImp = new SfxImpStringList; + + long i, nCount = pList->Count(); + String *pStr1, *pStr2; + for( i=0; i < nCount; i++ ) + { + pStr1 = (String*)pList->GetObject(i); + pStr2 = new String( *pStr1 ); + pImp->aList.Insert( pStr2, LIST_APPEND ); + } + } +} + +//------------------------------------------------------------------------ + +SfxStringListItem::SfxStringListItem( USHORT which, SvStream& rStream ) : + SfxPoolItem( which ), + pImp(NULL) +{ + long nEntryCount; + rStream >> nEntryCount; + + if( nEntryCount ) + pImp = new SfxImpStringList; + + long i; + String* pStr; + for( i=0; i < nEntryCount; i++ ) + { + pStr = new String; + readByteString(rStream, *pStr); + pImp->aList.Insert( pStr, LIST_APPEND ); + } +} + +//------------------------------------------------------------------------ + +SfxStringListItem::SfxStringListItem( const SfxStringListItem& rItem ) : + SfxPoolItem( rItem ), + pImp(NULL) +{ + pImp = rItem.pImp; + + if( pImp ) + { + DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid"); + pImp->nRefCount++; + } +} + +//------------------------------------------------------------------------ + +SfxStringListItem::~SfxStringListItem() +{ + if( pImp ) + { + DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid"); + if( pImp->nRefCount > 1 ) + pImp->nRefCount--; + else + delete pImp; + } +} + +//------------------------------------------------------------------------ + +List* SfxStringListItem::GetList() +{ + if( !pImp ) + pImp = new SfxImpStringList; + DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid"); + return &(pImp->aList); +} + +//------------------------------------------------------------------------ + +int SfxStringListItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + + SfxStringListItem* pItem = (SfxStringListItem*)&rItem; + + if( pImp == pItem->pImp ) + return TRUE; + else + return FALSE; +} + +//------------------------------------------------------------------------ + +SfxItemPresentation SfxStringListItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + rText.AssignAscii(RTL_CONSTASCII_STRINGPARAM("(List)")); + return SFX_ITEM_PRESENTATION_NONE; +} + +//------------------------------------------------------------------------ + +SfxPoolItem* SfxStringListItem::Clone( SfxItemPool *) const +{ + return new SfxStringListItem( *this ); + /* + if( pImp ) + return new SfxStringListItem( Which(), &(pImp->aList) ); + else + return new SfxStringListItem( Which(), NULL ); + */ + +} + +//------------------------------------------------------------------------ + +SfxPoolItem* SfxStringListItem::Create( SvStream & rStream, USHORT ) const +{ + return new SfxStringListItem( Which(), rStream ); +} + +//------------------------------------------------------------------------ + +SvStream& SfxStringListItem::Store( SvStream & rStream, USHORT ) const +{ + if( !pImp ) + { + rStream << 0L; + return rStream; + } + + DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid"); + + long nCount = pImp->aList.Count(); + rStream << nCount; + + long i; + String* pStr; + for( i=0; i < nCount; i++ ) + { + pStr = (String*)(pImp->aList.GetObject( i )); + writeByteString(rStream, *pStr); + } + + return rStream; +} + +//------------------------------------------------------------------------ + +void SfxStringListItem::SetString( const XubString& rStr ) +{ + DBG_ASSERT(GetRefCount()==0,"SetString:RefCount!=0"); + + if ( pImp && (pImp->nRefCount == 1) ) + delete pImp; + else + if( pImp ) + pImp->nRefCount--; + pImp = new SfxImpStringList; + + xub_StrLen nStart = 0; + xub_StrLen nDelimPos; + XubString aStr(rStr); + aStr.ConvertLineEnd(LINEEND_CR); + do + { + nDelimPos = aStr.Search( _CR, nStart ); + xub_StrLen nLen; + if ( nDelimPos == STRING_NOTFOUND ) + nLen = 0xffff; + else + nLen = nDelimPos - nStart; + + XubString* pStr = new XubString(aStr.Copy(nStart, nLen)); + // String gehoert der Liste + pImp->aList.Insert( pStr, LIST_APPEND ); + + nStart += nLen + 1 ; // delimiter ueberspringen + } while( nDelimPos != STRING_NOTFOUND ); + + // Kein Leerstring am Ende + if( pImp->aList.Last() && + !((XubString*)pImp->aList.Last())->Len() ) + delete (XubString*)pImp->aList.Remove( pImp->aList.Count()-1 ); +} + +//------------------------------------------------------------------------ + +XubString SfxStringListItem::GetString() +{ + XubString aStr; + if ( pImp ) + { + DBG_ASSERT(pImp->nRefCount!=0xffff,"ImpList not valid"); + XubString* pStr = (XubString*)(pImp->aList.First()); + while( pStr ) + { + aStr += *pStr; + pStr = (XubString*)(pImp->aList.Next()); + if ( pStr ) + aStr += '\r'; + } + } + aStr.ConvertLineEnd(); + return aStr; +} + +//------------------------------------------------------------------------ + +#ifndef TF_POOLABLE + +int SfxStringListItem::IsPoolable() const +{ + return FALSE; +} + +#endif + +//------------------------------------------------------------------------ + +void SfxStringListItem::Sort( BOOL bAscending, List* pParallelList ) +{ + DBG_ASSERT(GetRefCount()==0,"Sort:RefCount!=0"); + if( pImp ) + pImp->Sort( bAscending, pParallelList ); +} + +//---------------------------------------------------------------------------- +void SfxStringListItem::SetStringList( const com::sun::star::uno::Sequence< rtl::OUString >& rList ) +{ + DBG_ASSERT(GetRefCount()==0,"SetString:RefCount!=0"); + + if ( pImp && (pImp->nRefCount == 1) ) + delete pImp; + else + if( pImp ) + pImp->nRefCount--; + pImp = new SfxImpStringList; + + for ( sal_Int32 n = 0; n < rList.getLength(); n++ ) + { + XubString* pStr = new XubString( rList[n] ); + // String gehoert der Liste + pImp->aList.Insert( pStr, LIST_APPEND ); + } +} + +//---------------------------------------------------------------------------- +void SfxStringListItem::GetStringList( com::sun::star::uno::Sequence< rtl::OUString >& rList ) const +{ + long nCount = pImp->aList.Count(); + + rList.realloc( nCount ); + for( long i=0; i < nCount; i++ ) + rList[i] = *(String*)(pImp->aList.GetObject( i )); +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxStringListItem::PutValue( const com::sun::star::uno::Any& rVal,BYTE ) +{ + com::sun::star::uno::Sequence< rtl::OUString > aValue; + if ( rVal >>= aValue ) + { + SetStringList( aValue ); + return TRUE; + } + + DBG_ERROR( "SfxStringListItem::PutValue - Wrong type!" ); + return FALSE; +} + +//---------------------------------------------------------------------------- +// virtual +BOOL SfxStringListItem::QueryValue( com::sun::star::uno::Any& rVal,BYTE ) const +{ + // GetString() is not const!!! + SfxStringListItem* pThis = const_cast< SfxStringListItem * >( this ); + + com::sun::star::uno::Sequence< rtl::OUString > aStringList; + pThis->GetStringList( aStringList ); + rVal = ::com::sun::star::uno::makeAny( aStringList ); + return TRUE; +} + + diff --git a/svl/source/items/stritem.cxx b/svl/source/items/stritem.cxx new file mode 100644 index 000000000000..5f6b692106a3 --- /dev/null +++ b/svl/source/items/stritem.cxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * 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: stritem.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/stritem.hxx> + +//============================================================================ +// +// class SfxStringItem +// +//============================================================================ + +TYPEINIT1_AUTOFACTORY(SfxStringItem, CntUnencodedStringItem) + +//============================================================================ +// virtual +SfxStringItem::SfxStringItem(USHORT which, SvStream & rStream): + CntUnencodedStringItem(which) +{ + UniString aValue; + readByteString(rStream, aValue); + SetValue(aValue); +} + + +//============================================================================ +// virtual +SfxPoolItem * SfxStringItem::Create(SvStream & rStream, USHORT) const +{ + return new SfxStringItem(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & SfxStringItem::Store(SvStream & rStream, USHORT) const +{ + writeByteString(rStream, GetValue()); + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * SfxStringItem::Clone(SfxItemPool *) const +{ + return new SfxStringItem(*this); +} + diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx new file mode 100644 index 000000000000..756a2f7edc21 --- /dev/null +++ b/svl/source/items/style.cxx @@ -0,0 +1,1380 @@ +/************************************************************************* + * + * 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: style.cxx,v $ + * $Revision: 1.19.60.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifndef GCC +#endif + +#define _SVSTDARR_STRINGS +#define _SVSTDARR_STRINGSSORTDTOR +#define _SVSTDARR_BYTESTRINGS +#define _SVSTDARR_BYTESTRINGSSORTDTOR + +#include <rtl/uuid.h> +#include <tools/tenccvt.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/intlwrapper.hxx> +#include <svl/smplhint.hxx> +#include <svl/poolitem.hxx> +#include <svl/itemset.hxx> +#include <svl/itempool.hxx> +#include <poolio.hxx> +#include <svl/filerec.hxx> +#include <svl/itemiter.hxx> +#include <svl/style.hxx> +#include <svl/svstdarr.hxx> +#include <unotools/syslocale.hxx> +#include <algorithm> + +#define STYLESTREAM "SfxStyleSheets" +#define STYLESTREAM_VERSION USHORT(50) + +#ifdef DBG_UTIL +class DbgStyleSheetReferences +{ +public: + DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {} + ~DbgStyleSheetReferences() + { + OSL_TRACE("DbgStyleSheetReferences\nSfxStyleSheetBase left %ld\nSfxStyleSheetBasePool left %ld\n", mnStyles, mnPools ); + } + + sal_uInt32 mnStyles; + sal_uInt32 mnPools; +} +aDbgStyleSheetReferences; + +#endif + +TYPEINIT0(SfxStyleSheetBase) + +TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster) + + +//========================================================================= + +TYPEINIT1(SfxStyleSheetHint, SfxHint); +TYPEINIT1(SfxStyleSheetHintExtended, SfxStyleSheetHint); +TYPEINIT1(SfxStyleSheetPoolHint, SfxHint); + +SfxStyleSheetHintExtended::SfxStyleSheetHintExtended +( + USHORT nAction, // SFX_STYLESHEET_... (s.o.) + const String& rOldName +) +: SfxStyleSheetHint( nAction ), + aName( rOldName ) +{} +SfxStyleSheetHintExtended::SfxStyleSheetHintExtended +( + USHORT nAction, // SFX_STYLESHEET_... (s.o.) + const String& rOldName, + SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer +) +: SfxStyleSheetHint( nAction, rStyleSheet ), + aName( rOldName ) +{} + +//------------------------------------------------------------------------- + +SfxStyleSheetHint::SfxStyleSheetHint +( + USHORT nAction, // SFX_STYLESHEET_... (s.o.) + SfxStyleSheetBase& rStyleSheet // geh"ort weiterhin dem Aufrufer +) +: pStyleSh( &rStyleSheet ), + nHint( nAction ) +{} + +SfxStyleSheetHint::SfxStyleSheetHint +( + USHORT nAction // SFX_STYLESHEET_... (s.o.) +) +: pStyleSh( NULL ), + nHint( nAction ) +{} + +//========================================================================= + +class SfxStyleSheetBasePool_Impl +{ + public: + SfxStyles aStyles; + SfxStyleSheetIterator *pIter; + SfxStyleSheetBasePool_Impl() : pIter(0){} + ~SfxStyleSheetBasePool_Impl(){delete pIter;} +}; + + +//////////////////////////// SfxStyleSheetBase /////////////////////////////// + +// Konstruktoren + +SfxStyleSheetBase::SfxStyleSheetBase( const XubString& rName, SfxStyleSheetBasePool& r, SfxStyleFamily eFam, USHORT mask ) + : rPool( r ) + , nFamily( eFam ) + , aName( rName ) + , aParent() + , aFollow( rName ) + , pSet( NULL ) + , nMask(mask) + , nHelpId( 0 ) + , bMySet( FALSE ) +{ +#ifdef DBG_UTIL + aDbgStyleSheetReferences.mnStyles++; +#endif +} + +SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r ) + : comphelper::OWeakTypeObject() + , rPool( r.rPool ) + , nFamily( r.nFamily ) + , aName( r.aName ) + , aParent( r.aParent ) + , aFollow( r.aFollow ) + , aHelpFile( r.aHelpFile ) + , nMask( r.nMask ) + , nHelpId( r.nHelpId ) + , bMySet( r.bMySet ) +{ +#ifdef DBG_UTIL + aDbgStyleSheetReferences.mnStyles++; +#endif + if( r.pSet ) + pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet; + else + pSet = NULL; +} + +static SfxStyleSheetBasePool& implGetStaticPool() +{ + static SfxStyleSheetBasePool* pSheetPool = 0; + static SfxItemPool* pBasePool = 0; + if( !pSheetPool ) + { + UniString aName; + pBasePool = new SfxItemPool( aName, 0, 0, 0 ); + pSheetPool = new SfxStyleSheetBasePool(*pBasePool); + } + return *pSheetPool; +} + +SfxStyleSheetBase::SfxStyleSheetBase() +: comphelper::OWeakTypeObject() +, rPool( implGetStaticPool() ) +{ +} + +SfxStyleSheetBase::~SfxStyleSheetBase() +{ +#ifdef DBG_UTIL + --aDbgStyleSheetReferences.mnStyles; +#endif + + if( bMySet ) + { + delete pSet; + pSet = 0; + } +} + +USHORT SfxStyleSheetBase::GetVersion() const +{ + return 0x0000; +} + +// Namen aendern + +const XubString& SfxStyleSheetBase::GetName() const +{ + return aName; +} + +BOOL SfxStyleSheetBase::SetName( const XubString& rName ) +{ + if(rName.Len() == 0) + return FALSE; + if( aName != rName ) + { + String aOldName = aName; + SfxStyleSheetBase *pOther = rPool.Find( rName, nFamily ) ; + if ( pOther && pOther != this ) + return FALSE; + + SfxStyleFamily eTmpFam=rPool.GetSearchFamily(); + USHORT nTmpMask=rPool.GetSearchMask(); + + rPool.SetSearchMask(nFamily); + + if ( aName.Len() ) + rPool.ChangeParent( aName, rName, FALSE ); + if ( aFollow.Equals( aName ) ) + aFollow = rName; + aName = rName; + rPool.SetSearchMask(eTmpFam, nTmpMask); + rPool.Broadcast( SfxStyleSheetHintExtended( + SFX_STYLESHEET_MODIFIED, aOldName, *this ) ); + } + return TRUE; +} + +rtl::OUString SfxStyleSheetBase::GetDisplayName() const +{ + if( maDisplayName.getLength() == 0 ) + { + return aName; + } + else + { + return maDisplayName; + } +} + +void SfxStyleSheetBase::SetDisplayName( const rtl::OUString& rDisplayName ) +{ + maDisplayName = rDisplayName; +} + +// Parent aendern + +const XubString& SfxStyleSheetBase::GetParent() const +{ + return aParent; +} + +BOOL SfxStyleSheetBase::SetParent( const XubString& rName ) +{ + if ( rName == aName ) + return FALSE; + + if( aParent != rName ) + { + SfxStyleSheetBase* pIter = rPool.Find(rName, nFamily); + if( rName.Len() && !pIter ) + { + DBG_ERROR( "StyleSheet-Parent nicht gefunden" ); + return FALSE; + } + // rekursive Verknuepfungen verhindern + if( aName.Len() ) + while(pIter) + { + if(pIter->GetName() == aName && aName != rName) + return FALSE; + pIter = rPool.Find(pIter->GetParent(), nFamily); + } + aParent = rName; + } + rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) ); + return TRUE; +} + +// Follow aendern + +const XubString& SfxStyleSheetBase::GetFollow() const +{ + return aFollow; +} + +BOOL SfxStyleSheetBase::SetFollow( const XubString& rName ) +{ + if( aFollow != rName ) + { + if( !rPool.Find( rName, nFamily ) ) + { + DBG_ERROR( "StyleSheet-Follow nicht gefunden" ); + return FALSE; + } + aFollow = rName; + } + rPool.Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_MODIFIED, *this ) ); + return TRUE; +} + +// Itemset setzen. Die Dflt-Implementation legt ein neues Set an. + +SfxItemSet& SfxStyleSheetBase::GetItemSet() +{ + if( !pSet ) + { + pSet = new SfxItemSet( rPool.GetPool() ); + bMySet = TRUE; + } + return *pSet; +} + +// Hilfe-Datei und -ID setzen und abfragen + +ULONG SfxStyleSheetBase::GetHelpId( String& rFile ) +{ + rFile = aHelpFile; + return nHelpId; +} + +void SfxStyleSheetBase::SetHelpId( const String& rFile, ULONG nId ) +{ + aHelpFile = rFile; + nHelpId = nId; +} + +// Folgevorlage m"oglich? Default: Ja + +BOOL SfxStyleSheetBase::HasFollowSupport() const +{ + return TRUE; +} + +// Basisvorlage m"oglich? Default: Ja + +BOOL SfxStyleSheetBase::HasParentSupport() const +{ + return TRUE; +} + +// Basisvorlage uf NULL setzen m"oglich? Default: Nein + +BOOL SfxStyleSheetBase::HasClearParentSupport() const +{ + return FALSE; +} + +// Defaultmaessig sind alle StyleSheets Used + +BOOL SfxStyleSheetBase::IsUsed() const +{ + return TRUE; +} + +// eingestellte Attribute ausgeben + + +XubString SfxStyleSheetBase::GetDescription() +{ + return GetDescription( SFX_MAPUNIT_CM ); +} + +// eingestellte Attribute ausgeben + +XubString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric ) +{ + SfxItemIter aIter( GetItemSet() ); + XubString aDesc; + const SfxPoolItem* pItem = aIter.FirstItem(); + + IntlWrapper aIntlWrapper(comphelper::getProcessServiceFactory(), + SvtSysLocale().GetLanguage()); + while ( pItem ) + { + XubString aItemPresentation; + + if ( !IsInvalidItem( pItem ) && + rPool.GetPool().GetPresentation( + *pItem, SFX_ITEM_PRESENTATION_COMPLETE, + eMetric, aItemPresentation, &aIntlWrapper ) ) + { + if ( aDesc.Len() && aItemPresentation.Len() ) + aDesc.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" + ")); + if ( aItemPresentation.Len() ) + aDesc += aItemPresentation; + } + pItem = aIter.NextItem(); + } + return aDesc; +} + +/////////////////////////// SfxStyleSheetIterator /////////////////////////////// + +SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const +{ + return nSearchFamily; +} + +inline BOOL SfxStyleSheetIterator::IsTrivialSearch() +{ + return nMask == 0xFFFF && GetSearchFamily() == SFX_STYLE_FAMILY_ALL; +} + +BOOL SfxStyleSheetIterator::DoesStyleMatch(SfxStyleSheetBase *pStyle) +{ + return ((GetSearchFamily() == SFX_STYLE_FAMILY_ALL) || + ( pStyle->GetFamily() == GetSearchFamily() )) + && (( pStyle->GetMask() & ( GetSearchMask() & ~SFXSTYLEBIT_USED )) || + ( bSearchUsed ? pStyle->IsUsed() : FALSE ) || + GetSearchMask() == SFXSTYLEBIT_ALL ); +} + + +SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase, + SfxStyleFamily eFam, USHORT n) +{ + pBasePool=pBase; + nSearchFamily=eFam; + bSearchUsed=FALSE; + if((n != SFXSTYLEBIT_ALL ) && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED)) + { + bSearchUsed = TRUE; + n &= ~SFXSTYLEBIT_USED; + } + nMask=n; +} + +SfxStyleSheetIterator::~SfxStyleSheetIterator() +{ +} + + +USHORT SfxStyleSheetIterator::Count() +{ + USHORT n = 0; + if( IsTrivialSearch()) + n = (USHORT) pBasePool->aStyles.size(); + else + for(USHORT i=0; i<pBasePool->aStyles.size(); i++) + { + SfxStyleSheetBase* pStyle = pBasePool->aStyles[i].get(); + if(DoesStyleMatch(pStyle)) + n++; + } + return n; +} + +SfxStyleSheetBase* SfxStyleSheetIterator::operator[](USHORT nIdx) +{ + if( IsTrivialSearch()) + return pBasePool->aStyles[nIdx].get(); + + USHORT z = 0; + for(USHORT n=0; n<pBasePool->aStyles.size(); n++) + { + SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); + if( DoesStyleMatch(pStyle)) + { + if(z == nIdx) + { + nAktPosition=n; + return pAktStyle=pStyle; + } + ++z; + } + } + DBG_ERROR("falscher Index"); + return 0; +} + +SfxStyleSheetBase* SfxStyleSheetIterator::First() +{ + INT32 nIdx = -1; + + if ( IsTrivialSearch() && pBasePool->aStyles.size() ) + nIdx = 0; + else + for( USHORT n = 0; n < pBasePool->aStyles.size(); n++ ) + { + SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); + + if ( DoesStyleMatch( pStyle ) ) + { + nIdx = n; + break; + } + } + + if ( nIdx != -1 ) + { + nAktPosition = (USHORT)nIdx; + return pAktStyle = pBasePool->aStyles[nIdx].get(); + } + return 0; +} + + +SfxStyleSheetBase* SfxStyleSheetIterator::Next() +{ + INT32 nIdx = -1; + + if ( IsTrivialSearch() && + (USHORT)pBasePool->aStyles.size() > nAktPosition + 1 ) + nIdx = nAktPosition + 1; + else + for( USHORT n = nAktPosition + 1; n < pBasePool->aStyles.size(); n++ ) + { + SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); + + if ( DoesStyleMatch( pStyle ) ) + { + nIdx = n; + break; + } + } + + if ( nIdx != -1 ) + { + nAktPosition = (USHORT)nIdx; + return pAktStyle = pBasePool->aStyles[nIdx].get(); + } + return 0; +} + + +SfxStyleSheetBase* SfxStyleSheetIterator::Find(const XubString& rStr) +{ + for ( USHORT n = 0; n < pBasePool->aStyles.size(); n++ ) + { + SfxStyleSheetBase* pStyle = pBasePool->aStyles[n].get(); + + // #98454# performance: in case of bSearchUsed==TRUE it may be + // significant to first compare the name and only if it matches to call + // the style sheet IsUsed() method in DoesStyleMatch(). + if ( pStyle->GetName().Equals( rStr ) && DoesStyleMatch( pStyle ) ) + { + nAktPosition = n; + return pAktStyle = pStyle; + } + } + return 0; +} + + +USHORT SfxStyleSheetIterator::GetSearchMask() const +{ + USHORT mask = nMask; + + if ( bSearchUsed ) + mask |= SFXSTYLEBIT_USED; + return mask; +} + +/////////////////////////// SfxStyleSheetBasePool /////////////////////////////// + +void SfxStyleSheetBasePool::Replace( + SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget ) +{ + rTarget.SetFollow( rSource.GetFollow() ); + rTarget.SetParent( rSource.GetParent() ); + SfxItemSet& rSourceSet = rSource.GetItemSet(); + SfxItemSet& rTargetSet = rTarget.GetItemSet(); + rTargetSet.Intersect( rSourceSet ); + rTargetSet.Put( rSourceSet ); +} + +SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl() +{ + SfxStyleSheetIterator*& rpIter = pImp->pIter; + if( !rpIter || (rpIter->GetSearchMask() != nMask) || (rpIter->GetSearchFamily() != nSearchFamily) ) + { + delete rpIter; + rpIter = CreateIterator( nSearchFamily, nMask ); + } + return *rpIter; +} + + +SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) + : aAppName(r.GetName()) + , rPool(r) + , nSearchFamily(SFX_STYLE_FAMILY_PARA) + , nMask(0xFFFF) +{ +#ifdef DBG_UTIL + aDbgStyleSheetReferences.mnPools++; +#endif + + pImp = new SfxStyleSheetBasePool_Impl; +} + +SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) + : SfxBroadcaster( r ) + , comphelper::OWeakTypeObject() + , aAppName(r.aAppName) + , rPool(r.rPool) + , nSearchFamily(r.nSearchFamily) + , nMask( r.nMask ) +{ +#ifdef DBG_UTIL + aDbgStyleSheetReferences.mnPools++; +#endif + + pImp = new SfxStyleSheetBasePool_Impl; + *this += r; +} + +SfxStyleSheetBasePool::~SfxStyleSheetBasePool() +{ +#ifdef DBG_UTIL + aDbgStyleSheetReferences.mnPools--; +#endif + + Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); + Clear(); + delete pImp; +} + +BOOL SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const XubString& rStyle, const XubString& rParent) +{ + SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL); + SfxStyleSheetBase *pStyle = + aIter.Find(rStyle); + DBG_ASSERT(pStyle, "Vorlage nicht gefunden. Writer mit Solar <2541??"); + if(pStyle) + return pStyle->SetParent(rParent); + else + return FALSE; +} + + +void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, USHORT n) +{ + nSearchFamily = eFam; nMask = n; +} + +USHORT SfxStyleSheetBasePool::GetSearchMask() const +{ + return nMask; +} + + +// Der Name des Streams + +String SfxStyleSheetBasePool::GetStreamName() +{ + return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STYLESTREAM)); +} + +/////////////////////////////////// Factory //////////////////////////////// + + + +SfxStyleSheetIterator* SfxStyleSheetBasePool::CreateIterator +( + SfxStyleFamily eFam, + USHORT mask +) +{ + return new SfxStyleSheetIterator(this,eFam,mask); +} + + +SfxStyleSheetBase* SfxStyleSheetBasePool::Create +( + const XubString& rName, + SfxStyleFamily eFam, + USHORT mask +) +{ + return new SfxStyleSheetBase( rName, *this, eFam, mask ); +} + +SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r ) +{ + return new SfxStyleSheetBase( r ); +} + +SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const XubString& rName, SfxStyleFamily eFam, USHORT mask, USHORT nPos) +{ + DBG_ASSERT( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" ); + + SfxStyleSheetIterator aIter(this, eFam, mask); + rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) ); + DBG_ASSERT( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" ); + SfxStyleSheetIterator& rIter = GetIterator_Impl(); + + if( !xStyle.is() ) + { + xStyle = Create( rName, eFam, mask ); + if(0xffff == nPos || nPos == aStyles.size() || nPos == rIter.Count()) + { + aStyles.push_back( xStyle ); + } + else + { + rIter[nPos]; + aStyles.insert( aStyles.begin() + rIter.GetPos(), xStyle ); + } + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *xStyle.get() ) ); + } + return *xStyle.get(); +} + +/////////////////////////////// Kopieren /////////////////////////////////// + +// Hilfsroutine: Falls eine Vorlage dieses Namens existiert, wird +// sie neu erzeugt. Alle Vorlagen, die diese Vorlage zum Parent haben, +// werden umgehaengt. + +SfxStyleSheetBase& SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet ) +{ + SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask); + SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() ); + Remove( pOld ); + rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) ); + aStyles.push_back( xNew ); + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CHANGED, *xNew.get() ) ); + return *xNew.get(); +} + +SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r ) +{ + if( &r != this ) + { + Clear(); + *this += r; + } + return *this; +} + +SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r ) +{ + if( &r != this ) + { + SfxStyles::const_iterator aIter( r.aStyles.begin() ); + while( aIter != r.aStyles.end() ) + { + Add(*(*aIter++).get()); + } + } + return *this; +} + +//////////////////////////////// Suchen //////////////////////////////////// + +USHORT SfxStyleSheetBasePool::Count() +{ + return GetIterator_Impl().Count(); +} + +SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](USHORT nIdx) +{ + return GetIterator_Impl()[nIdx]; +} + +SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const XubString& rName, + SfxStyleFamily eFam, + USHORT mask) +{ + SfxStyleSheetIterator aIter(this,eFam,mask); + return aIter.Find(rName); +} + +const SfxStyles& SfxStyleSheetBasePool::GetStyles() +{ + return aStyles; +} + +SfxStyleSheetBase* SfxStyleSheetBasePool::First() +{ + return GetIterator_Impl().First(); +} + +SfxStyleSheetBase* SfxStyleSheetBasePool::Next() +{ + return GetIterator_Impl().Next(); +} + +//////////////////////////////// Loeschen ///////////////////////////////// + +void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p ) +{ + if( p ) + { + SfxStyles::iterator aIter( std::find( aStyles.begin(), aStyles.end(), rtl::Reference< SfxStyleSheetBase >( p ) ) ); + if( aIter != aStyles.end() ) + { + // Alle Styles umsetzen, deren Parent dieser hier ist + ChangeParent( p->GetName(), p->GetParent() ); + aStyles.erase(aIter); + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) ); + } + } +} + +void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p ) +{ + DBG_ASSERT( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" ); + + SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask()); + SfxStyleSheetBase* pOld = aIter.Find( p->GetName() ); + DBG_ASSERT( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" ); + if( p->GetParent().Len() ) + { + pOld = aIter.Find( p->GetParent() ); + DBG_ASSERT( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" ); + } + aStyles.push_back( rtl::Reference< SfxStyleSheetBase >( p ) ); + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_CREATED, *p ) ); +} + +void SfxStyleSheetBasePool::Clear() +{ + SfxStyles aClearStyles; + aClearStyles.swap( aStyles ); + + SfxStyles::iterator aIter( aClearStyles.begin() ); + while( aIter != aClearStyles.end() ) + { + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) ); + } +} + +/////////////////////////// Parents umsetzen //////////////////////////////// + +void SfxStyleSheetBasePool::ChangeParent(const XubString& rOld, + const XubString& rNew, + BOOL bVirtual) +{ + const USHORT nTmpMask = GetSearchMask(); + SetSearchMask(GetSearchFamily(), 0xffff); + for( SfxStyleSheetBase* p = First(); p; p = Next() ) + { + if( p->GetParent().Equals( rOld ) ) + { + if(bVirtual) + p->SetParent( rNew ); + else + p->aParent = rNew; + } + } + SetSearchMask(GetSearchFamily(), nTmpMask); +} + +/////////////////////////// Laden/Speichern ///////////////////////////////// + +void SfxStyleSheetBase::Load( SvStream&, USHORT ) +{ +} + +void SfxStyleSheetBase::Store( SvStream& ) +{ +} + + +BOOL SfxStyleSheetBasePool::Load( SvStream& rStream ) +{ + // alte Version? + if ( !rPool.IsVer2_Impl() ) + return Load1_Impl( rStream ); + + // gesamten StyleSheetPool in neuer Version aus einem MiniRecord lesen + SfxMiniRecordReader aPoolRec( &rStream, SFX_STYLES_REC ); + + // Header-Record lesen + short nCharSet = 0; + if ( !rStream.GetError() ) + { + SfxSingleRecordReader aHeaderRec( &rStream, SFX_STYLES_REC_HEADER ); + if ( !aHeaderRec.IsValid() ) + return FALSE; + + aAppName = rPool.GetName(); + rStream >> nCharSet; + } + + // Styles-Record lesen + if ( !rStream.GetError() ) + { + SfxMultiRecordReader aStylesRec( &rStream, SFX_STYLES_REC_STYLES ); + if ( !aStylesRec.IsValid() ) + return FALSE; + + rtl_TextEncoding eEnc = GetSOLoadTextEncoding( + (rtl_TextEncoding)nCharSet, + sal::static_int_cast< USHORT >(rStream.GetVersion()) ); + rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); + rStream.SetStreamCharSet( eEnc ); + + USHORT nStyles; + for ( nStyles = 0; aStylesRec.GetContent(); nStyles++ ) + { + // kann nicht mehr weiterlesen? + if ( rStream.GetError() ) + break; + + // Globale Teile + XubString aName, aParent, aFollow; + String aHelpFile; + USHORT nFamily, nStyleMask,nCount; + sal_uInt32 nHelpId; + rStream.ReadByteString(aName, eEnc ); + rStream.ReadByteString(aParent, eEnc ); + rStream.ReadByteString(aFollow, eEnc ); + rStream >> nFamily >> nStyleMask; + SfxPoolItem::readByteString(rStream, aHelpFile); + rStream >> nHelpId; + + SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); + rSheet.SetHelpId( aHelpFile, nHelpId ); + // Hier erst einmal Parent und Follow zwischenspeichern + rSheet.aParent = aParent; + rSheet.aFollow = aFollow; + UINT32 nPos = rStream.Tell(); + rStream >> nCount; + if(nCount) + { + rStream.Seek( nPos ); + // Das Laden des ItemSets bedient sich der Methode GetItemSet(), + // damit eigene ItemSets untergeschoben werden koennen + SfxItemSet& rSet = rSheet.GetItemSet(); + rSet.ClearItem(); + //! SfxItemSet aTmpSet( *pTmpPool ); + /*!aTmpSet*/ rSet.Load( rStream ); + //! rSet.Put( aTmpSet ); + } + // Lokale Teile + UINT32 nSize; + USHORT nVer; + rStream >> nVer >> nSize; + nPos = rStream.Tell() + nSize; + rSheet.Load( rStream, nVer ); + rStream.Seek( nPos ); + } + + // #72939# only loop through the styles that were really inserted + ULONG n = aStyles.size(); + + //! delete pTmpPool; + // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. + // Mit Setxxx() noch einmal den String eintragen, da diese + // virtuellen Methoden evtl. ueberlagert sind. + for ( ULONG i = 0; i < n; i++ ) + { + SfxStyleSheetBase* p = aStyles[ i ].get(); + XubString aText = p->aParent; + p->aParent.Erase(); + p->SetParent( aText ); + aText = p->aFollow; + p->aFollow.Erase(); + p->SetFollow( aText ); + } + + rStream.SetStreamCharSet( eOldEnc ); + } + + // alles klar? + return BOOL( rStream.GetError() == SVSTREAM_OK ); +} + +BOOL SfxStyleSheetBasePool::Load1_Impl( SvStream& rStream ) +{ + aAppName = rPool.GetName(); + USHORT nVersion; + short nCharSet; + rStream >> nVersion; + + if(nVersion!=STYLESTREAM_VERSION) + nCharSet=nVersion; + else + rStream >> nCharSet; + + rtl_TextEncoding eEnc = GetSOLoadTextEncoding( + (rtl_TextEncoding)nCharSet, + sal::static_int_cast< USHORT >(rStream.GetVersion()) ); + rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); + rStream.SetStreamCharSet( eEnc ); + + USHORT nStyles; + rStream >> nStyles; + USHORT i; + for ( i = 0; i < nStyles; i++ ) + { + // kann nicht mehr weiterlesen? + if ( rStream.GetError() ) + { + nStyles = i; + break; + } + + // Globale Teile + XubString aName, aParent, aFollow; + String aHelpFile; + USHORT nFamily, nStyleMask,nCount; + sal_uInt32 nHelpId; + rStream.ReadByteString(aName, eEnc ); + rStream.ReadByteString(aParent, eEnc ); + rStream.ReadByteString(aFollow, eEnc ); + rStream >> nFamily >> nStyleMask; + SfxPoolItem::readByteString(rStream, aHelpFile); + if(nVersion!=STYLESTREAM_VERSION) + { + USHORT nTmpHelpId; + rStream >> nTmpHelpId; + nHelpId=nTmpHelpId; + } + else + rStream >> nHelpId; + + SfxStyleSheetBase& rSheet = Make( aName, (SfxStyleFamily)nFamily , nStyleMask); + rSheet.SetHelpId( aHelpFile, nHelpId ); + // Hier erst einmal Parent und Follow zwischenspeichern + rSheet.aParent = aParent; + rSheet.aFollow = aFollow; + UINT32 nPos = rStream.Tell(); + rStream >> nCount; + if(nCount) { + rStream.Seek( nPos ); + // Das Laden des ItemSets bedient sich der Methode GetItemSet(), + // damit eigene ItemSets untergeschoben werden koennen + SfxItemSet& rSet = rSheet.GetItemSet(); + rSet.ClearItem(); +//! SfxItemSet aTmpSet( *pTmpPool ); + /*!aTmpSet*/ rSet.Load( rStream ); + //! rSet.Put( aTmpSet ); + } + // Lokale Teile + UINT32 nSize; + USHORT nVer; + rStream >> nVer >> nSize; + nPos = rStream.Tell() + nSize; + rSheet.Load( rStream, nVer ); + rStream.Seek( nPos ); + } + + //! delete pTmpPool; + // Jetzt Parent und Follow setzen. Alle Sheets sind geladen. + // Mit Setxxx() noch einmal den String eintragen, da diese + // virtuellen Methoden evtl. ueberlagert sind. + for ( i = 0; i < nStyles; i++ ) + { + SfxStyleSheetBase* p = aStyles[ i ].get(); + XubString aText = p->aParent; + p->aParent.Erase(); + p->SetParent( aText ); + aText = p->aFollow; + p->aFollow.Erase(); + p->SetFollow( aText ); + } + + rStream.SetStreamCharSet( eOldEnc ); + + return BOOL( rStream.GetError() == SVSTREAM_OK ); +} + +BOOL SfxStyleSheetBasePool::Store( SvStream& rStream, BOOL bUsed ) +{ + // den ganzen StyleSheet-Pool in einen Mini-Record + SfxMiniRecordWriter aPoolRec( &rStream, SFX_STYLES_REC ); + + // Erst einmal die Dummies rauszaehlen; die werden nicht gespeichert + USHORT nCount = 0; + for( SfxStyleSheetBase* p = First(); p; p = Next() ) + { + if(!bUsed || p->IsUsed()) + nCount++; + } + + // einen Header-Record vorweg + rtl_TextEncoding eEnc + = ::GetSOStoreTextEncoding( + rStream.GetStreamCharSet(), + sal::static_int_cast< USHORT >(rStream.GetVersion()) ); + rtl_TextEncoding eOldEnc = rStream.GetStreamCharSet(); + rStream.SetStreamCharSet( eEnc ); + + { + SfxSingleRecordWriter aHeaderRec( &rStream, + SFX_STYLES_REC_HEADER, + STYLESTREAM_VERSION ); + rStream << (short) eEnc; + } + + // die StyleSheets in einen MultiVarRecord + { + // Bug 79478: + // make a check loop, to be shure, that the converted names are also + // unique like the originals! In other cases we get a loop. + SvStringsSortDtor aSortOrigNames( 0, 128 ); + SvStrings aOrigNames( 0, 128 ); + SvByteStringsSortDtor aSortConvNames( 0, 128 ); + SvByteStrings aConvNames( 0, 128 ); + + { + + for( SfxStyleSheetBase* p = First(); p; p = Next() ) + { + if(!bUsed || p->IsUsed()) + { + USHORT nFamily = (USHORT)p->GetFamily(); + String* pName = new String( p->GetName() ); + ByteString* pConvName = new ByteString( *pName, eEnc ); + + pName->Insert( (sal_Unicode)nFamily, 0 ); + pConvName->Insert( " ", 0 ); + pConvName->SetChar( + 0, + sal::static_int_cast< char >(0xff & (nFamily >> 8)) ); + pConvName->SetChar( + 1, sal::static_int_cast< char >(0xff & nFamily) ); + + USHORT nInsPos, nAdd = aSortConvNames.Count(); + while( !aSortConvNames.Insert( pConvName, nInsPos ) ) + (pConvName->Append( '_' )).Append( + ByteString::CreateFromInt32( nAdd++ )); + aOrigNames.Insert( pName, nInsPos ); + } + } + + // now we have the list of the names, sorted by convertede names + // But now we need the sorted list of orignames. + { + USHORT nInsPos, nEnd = aOrigNames.Count(); + const ByteStringPtr* ppB = aSortConvNames.GetData(); + for( USHORT n = 0; n < nEnd; ++n, ++ppB ) + { + String* p = aOrigNames.GetObject( n ); + aSortOrigNames.Insert( p, nInsPos ); + aConvNames.Insert( *ppB, nInsPos ); + } + + } + } + + + ByteString sEmpty; + USHORT nFndPos; + String sNm; + SfxMultiVarRecordWriter aStylesRec( &rStream, SFX_STYLES_REC_STYLES, 0 ); + for( SfxStyleSheetBase* p = First(); p; p = Next() ) + { + if(!bUsed || p->IsUsed()) + { + aStylesRec.NewContent(); + + // Globale Teile speichern + String aHelpFile; + sal_uInt32 nHelpId = p->GetHelpId( aHelpFile ); + USHORT nFamily = sal::static_int_cast< USHORT >(p->GetFamily()); + String sFamily( (sal_Unicode)nFamily ); + + (sNm = sFamily) += p->GetName(); + if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) + rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); + else + rStream.WriteByteString( sEmpty ); + + (sNm = sFamily) += p->GetParent(); + if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) + rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); + else + rStream.WriteByteString( sEmpty ); + + (sNm = sFamily) += p->GetFollow(); + if( aSortOrigNames.Seek_Entry( &sNm, &nFndPos )) + rStream.WriteByteString( aConvNames.GetObject( nFndPos )->Copy( 2 )); + else + rStream.WriteByteString( sEmpty ); + + rStream << nFamily << p->GetMask(); + SfxPoolItem::writeByteString(rStream, aHelpFile); + rStream << nHelpId; + if(p->pSet) + p->pSet->Store( rStream ); + else + rStream << (USHORT)0; + + // Lokale Teile speichern + // Vor dem lokalen Teil wird die Laenge der lokalen Daten + // als UINT32 sowie die Versionsnummer gespeichert. + rStream << (USHORT) p->GetVersion(); + ULONG nPos1 = rStream.Tell(); + rStream << (UINT32) 0; + p->Store( rStream ); + ULONG nPos2 = rStream.Tell(); + rStream.Seek( nPos1 ); + rStream << (UINT32) ( nPos2 - nPos1 - sizeof( UINT32 ) ); + rStream.Seek( nPos2 ); + if( rStream.GetError() != SVSTREAM_OK ) + break; + } + } + } + + rStream.SetStreamCharSet( eOldEnc ); + + return BOOL( rStream.GetError() == SVSTREAM_OK ); +} + +SfxItemPool& SfxStyleSheetBasePool::GetPool() +{ + return rPool; +} + +const SfxItemPool& SfxStyleSheetBasePool::GetPool() const +{ + return rPool; +} + +/////////////////////// SfxStyleSheet ///////////////////////////////// + +SfxStyleSheet::SfxStyleSheet(const XubString &rName, + const SfxStyleSheetBasePool& r_Pool, + SfxStyleFamily eFam, + USHORT mask ): + SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool& >( r_Pool ), eFam, mask) +{} + +SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle) : + SfxStyleSheetBase(rStyle), + SfxListener( rStyle ), + SfxBroadcaster( rStyle ) +{} + +SfxStyleSheet::SfxStyleSheet() +{ +} + +SfxStyleSheet::~SfxStyleSheet() +{ + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_INDESTRUCTION, *this ) ); +} + + +BOOL SfxStyleSheet::SetParent( const XubString& rName ) +{ + if(aParent == rName) + return TRUE; + const XubString aOldParent(aParent); + if(SfxStyleSheetBase::SetParent(rName)) { + // aus der Benachrichtigungskette des alten + // Parents gfs. austragen + if(aOldParent.Len()) { + SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aOldParent, nFamily, 0xffff); + if(pParent) + EndListening(*pParent); + } + // in die Benachrichtigungskette des neuen + // Parents eintragen + if(aParent.Len()) { + SfxStyleSheet *pParent = (SfxStyleSheet *)rPool.Find(aParent, nFamily, 0xffff); + if(pParent) + StartListening(*pParent); + } + return TRUE; + } + return FALSE; +} + +// alle Zuhoerer benachtichtigen + +void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + Forward(rBC, rHint); +} + +//////////////////////// SfxStyleSheetPool /////////////////////////////// + +SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet) +: SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) ) +{ +} + +/////////////////////////////////// Factory //////////////////////////////// + +SfxStyleSheetBase* SfxStyleSheetPool::Create( const XubString& rName, + SfxStyleFamily eFam, USHORT mask ) +{ + return new SfxStyleSheet( rName, *this, eFam, mask ); +} + +SfxStyleSheetBase* SfxStyleSheetPool::Create( const SfxStyleSheet& r ) +{ + return new SfxStyleSheet( r ); +} +/* +BOOL SfxStyleSheetPool::CopyTo(SfxStyleSheetPool &, const String &) +{ + return FALSE; +} +*/ + +// -------------------------------------------------------------------- +// class SfxUnoStyleSheet +// -------------------------------------------------------------------- + +SfxUnoStyleSheet::SfxUnoStyleSheet( const UniString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, USHORT _nMaske ) +: ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske ) +{ +} + +// -------------------------------------------------------------------- +SfxUnoStyleSheet::SfxUnoStyleSheet( const SfxStyleSheet& _rSheet ) +: ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rSheet ) +{ +} + +// -------------------------------------------------------------------- + +SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle ) +{ + SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() ); + if( !pRet ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY ); + if( xUT.is() ) + pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier()))); + } + return pRet; +} + +// -------------------------------------------------------------------- +// XUnoTunnel +// -------------------------------------------------------------------- + +::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException) +{ + if( rId.getLength() == 16 && 0 == rtl_compareMemory( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); + } + else + { + return 0; + } +} + +// -------------------------------------------------------------------- + +const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier() +{ + static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0; + if( !pSeq ) + { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +// -------------------------------------------------------------------- diff --git a/svl/source/items/stylepool.cxx b/svl/source/items/stylepool.cxx new file mode 100644 index 000000000000..6d214b6b94dd --- /dev/null +++ b/svl/source/items/stylepool.cxx @@ -0,0 +1,544 @@ +/************************************************************************* + * + * 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: stylepool.cxx,v $ + * $Revision: 1.10.78.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <vector> +#include <map> + +#include "stylepool.hxx" +#include <svl/itemiter.hxx> +#include <svl/itempool.hxx> + + +using namespace boost; + +namespace { + // A "Node" represents a subset of inserted SfxItemSets + // The root node represents the empty set + // The other nodes contain a SfxPoolItem and represents an item set which contains their + // pool item and the pool items of their parents. + class Node + { + std::vector<Node*> mChildren; // child nodes, create by findChildNode(..) + // container of shared pointers of inserted item sets; for non-poolable + // items more than one item set is needed + std::vector< StylePool::SfxItemSet_Pointer_t > maItemSet; + const SfxPoolItem *mpItem; // my pool item + Node *mpUpper; // if I'm a child node that's my parent node + // --> OD 2008-03-07 #i86923# + const bool mbIsItemIgnorable; + // <-- + public: + // --> OD 2008-03-07 #i86923# + Node() // root node Ctor + : mChildren(), + maItemSet(), + mpItem( 0 ), + mpUpper( 0 ), + mbIsItemIgnorable( false ) + {} + Node( const SfxPoolItem& rItem, Node* pParent, const bool bIgnorable ) // child node Ctor + : mChildren(), + maItemSet(), + mpItem( rItem.Clone() ), + mpUpper( pParent ), + mbIsItemIgnorable( bIgnorable ) + {} + // <-- + ~Node(); + // --> OD 2008-03-11 #i86923# + bool hasItemSet( const bool bCheckUsage ) const; + // <-- + // --> OD 2008-04-29 #i87808# +// const StylePool::SfxItemSet_Pointer_t getItemSet() const { return aItemSet[aItemSet.size()-1]; } + const StylePool::SfxItemSet_Pointer_t getItemSet() const + { + return maItemSet.back(); + } + const StylePool::SfxItemSet_Pointer_t getUsedOrLastAddedItemSet() const; + // <-- + void setItemSet( const SfxItemSet& rSet ){ maItemSet.push_back( StylePool::SfxItemSet_Pointer_t( rSet.Clone() ) ); } + // --> OD 2008-03-11 #i86923# + Node* findChildNode( const SfxPoolItem& rItem, + const bool bIsItemIgnorable = false ); + Node* nextItemSet( Node* pLast, + const bool bSkipUnusedItemSet, + const bool bSkipIgnorable ); + // <-- + const SfxPoolItem& getPoolItem() const { return *mpItem; } + // --> OD 2008-03-11 #i86923# + bool hasIgnorableChildren( const bool bCheckUsage ) const; + const StylePool::SfxItemSet_Pointer_t getItemSetOfIgnorableChild( + const bool bSkipUnusedItemSets ) const; + // <-- + }; + + // --> OD 2008-04-29 #i87808# + const StylePool::SfxItemSet_Pointer_t Node::getUsedOrLastAddedItemSet() const + { + std::vector< StylePool::SfxItemSet_Pointer_t >::const_reverse_iterator aIter; + + for ( aIter = maItemSet.rbegin(); aIter != maItemSet.rend(); ++aIter ) + { + if ( (*aIter).use_count() > 1 ) + { + return *aIter; + } + } + + return maItemSet.back(); + } + // <-- + + // --> OD 2008-05-06 #i86923# + bool Node::hasItemSet( const bool bCheckUsage ) const + { + bool bHasItemSet = false; + + if ( maItemSet.size() > 0 ) + { + if ( bCheckUsage ) + { + std::vector< StylePool::SfxItemSet_Pointer_t >::const_reverse_iterator aIter; + + for ( aIter = maItemSet.rbegin(); aIter != maItemSet.rend(); ++aIter ) + { + if ( (*aIter).use_count() > 1 ) + { + bHasItemSet = true; + break; + } + } + } + else + { + bHasItemSet = true; + } + } + return bHasItemSet; + } + // <-- + + // --> OD 2008-03-07 #i86923# + Node* Node::findChildNode( const SfxPoolItem& rItem, + const bool bIsItemIgnorable ) + // <-- + { + Node* pNextNode = this; + std::vector<Node*>::iterator aIter = mChildren.begin(); + while( aIter != mChildren.end() ) + { + if( rItem.Which() == (*aIter)->getPoolItem().Which() && + rItem == (*aIter)->getPoolItem() ) + return *aIter; + ++aIter; + } + // --> OD 2008-03-07 #i86923# + pNextNode = new Node( rItem, pNextNode, bIsItemIgnorable ); + // <-- + mChildren.push_back( pNextNode ); + return pNextNode; + } + + /* Find the next node which has a SfxItemSet. + The input parameter pLast has a sophisticated meaning: + downstairs only: + pLast == 0 => scan your children and their children + but neither your parents neither your siblings + downstairs and upstairs: + pLast == this => scan your children, their children, + the children of your parent behind you, and so on + partial downstairs and upstairs + pLast != 0 && pLast != this => scan your children behind the given children, + the children of your parent behind you and so on. + + OD 2008-03-11 #i86923# + introduce parameters <bSkipUnusedItemSets> and <bSkipIgnorable> + and its handling. + */ + Node* Node::nextItemSet( Node* pLast, + const bool bSkipUnusedItemSets, + const bool bSkipIgnorable ) + { + // Searching downstairs + std::vector<Node*>::iterator aIter = mChildren.begin(); + // For pLast == 0 and pLast == this all children are of interest + // for another pLast the search starts behind pLast... + if( pLast && pLast != this ) + { + aIter = std::find( mChildren.begin(), mChildren.end(), pLast ); + if( aIter != mChildren.end() ) + ++aIter; + } + Node *pNext = 0; + while( aIter != mChildren.end() ) + { + // --> OD 2008-03-11 #i86923# + if ( bSkipIgnorable && (*aIter)->mbIsItemIgnorable ) + { + ++aIter; + continue; + } + // <-- + pNext = *aIter; + // --> OD 2008-03-11 #i86923# + if ( pNext->hasItemSet( bSkipUnusedItemSets ) ) + { + return pNext; + } + if ( bSkipIgnorable && + pNext->hasIgnorableChildren( bSkipUnusedItemSets ) ) + { + return pNext; + } + pNext = pNext->nextItemSet( 0, bSkipUnusedItemSets, bSkipIgnorable ); // 0 => downstairs only + // <-- + if( pNext ) + return pNext; + ++aIter; + } + // Searching upstairs + if( pLast && mpUpper ) + { + // --> OD 2008-03-11 #i86923# + pNext = mpUpper->nextItemSet( this, bSkipUnusedItemSets, bSkipIgnorable ); + // <-- + } + return pNext; + } + + // --> OD 2008-03-11 #i86923# + bool Node::hasIgnorableChildren( const bool bCheckUsage ) const + { + bool bHasIgnorableChildren( false ); + + std::vector<Node*>::const_iterator aIter = mChildren.begin(); + while( aIter != mChildren.end() && !bHasIgnorableChildren ) + { + Node* pChild = *aIter; + if ( pChild->mbIsItemIgnorable ) + { + bHasIgnorableChildren = + !bCheckUsage || + ( pChild->hasItemSet( bCheckUsage /* == true */ ) || + pChild->hasIgnorableChildren( bCheckUsage /* == true */ ) ); + } + ++aIter; + } + + return bHasIgnorableChildren; + } + + const StylePool::SfxItemSet_Pointer_t Node::getItemSetOfIgnorableChild( + const bool bSkipUnusedItemSets ) const + { + DBG_ASSERT( hasIgnorableChildren( bSkipUnusedItemSets ), + "<Node::getItemSetOfIgnorableChild> - node has no ignorable children" ); + + std::vector<Node*>::const_iterator aIter = mChildren.begin(); + while( aIter != mChildren.end() ) + { + Node* pChild = *aIter; + if ( pChild->mbIsItemIgnorable ) + { + if ( pChild->hasItemSet( bSkipUnusedItemSets ) ) + { + return pChild->getUsedOrLastAddedItemSet(); + } + else + { + pChild = pChild->nextItemSet( 0, bSkipUnusedItemSets, false ); + if ( pChild ) + { + return pChild->getUsedOrLastAddedItemSet(); + } + } + } + ++aIter; + } + + StylePool::SfxItemSet_Pointer_t pReturn; + return pReturn; + } + // <-- + + Node::~Node() + { + std::vector<Node*>::iterator aIter = mChildren.begin(); + while( aIter != mChildren.end() ) + { + delete *aIter; + ++aIter; + } + delete mpItem; + } + + class Iterator : public IStylePoolIteratorAccess + { + std::map< const SfxItemSet*, Node >& mrRoot; + std::map< const SfxItemSet*, Node >::iterator mpCurrNode; + Node* mpNode; + const bool mbSkipUnusedItemSets; + const bool mbSkipIgnorable; + public: + // --> OD 2008-03-07 #i86923# + Iterator( std::map< const SfxItemSet*, Node >& rR, + const bool bSkipUnusedItemSets, + const bool bSkipIgnorable ) + : mrRoot( rR ), + mpCurrNode( rR.begin() ), + mpNode(0), + mbSkipUnusedItemSets( bSkipUnusedItemSets ), + mbSkipIgnorable( bSkipIgnorable ) + {} + // <-- + virtual StylePool::SfxItemSet_Pointer_t getNext(); + virtual ::rtl::OUString getName(); + }; + + StylePool::SfxItemSet_Pointer_t Iterator::getNext() + { + StylePool::SfxItemSet_Pointer_t pReturn; + while( mpNode || mpCurrNode != mrRoot.end() ) + { + if( !mpNode ) + { + mpNode = &mpCurrNode->second; + ++mpCurrNode; + // --> OD 2008-03-11 #i86923# + if ( mpNode->hasItemSet( mbSkipUnusedItemSets ) ) + { + // --> OD 2008-04-30 #i87808# +// return pNode->getItemSet(); + return mpNode->getUsedOrLastAddedItemSet(); + // <-- + } + // <-- + } + // --> OD 2008-03-11 #i86923# + mpNode = mpNode->nextItemSet( mpNode, mbSkipUnusedItemSets, mbSkipIgnorable ); + if ( mpNode && mpNode->hasItemSet( mbSkipUnusedItemSets ) ) + { + // --> OD 2008-04-30 #i87808# +// return pNode->getItemSet(); + return mpNode->getUsedOrLastAddedItemSet(); + // <-- + } + if ( mbSkipIgnorable && + mpNode && mpNode->hasIgnorableChildren( mbSkipUnusedItemSets ) ) + { + return mpNode->getItemSetOfIgnorableChild( mbSkipUnusedItemSets ); + } + // <-- + } + return pReturn; + } + + ::rtl::OUString Iterator::getName() + { + ::rtl::OUString aString; + if( mpNode && mpNode->hasItemSet( false ) ) + { + // --> OD 2008-04-30 #i87808# +// aString = StylePool::nameOf( pNode->getItemSet() ); + aString = StylePool::nameOf( mpNode->getUsedOrLastAddedItemSet() ); + // <-- + } + return aString; + } + +} + +/* This static method creates a unique name from a shared pointer to a SfxItemSet + The name is the memory address of the SfxItemSet itself. */ + +::rtl::OUString StylePool::nameOf( SfxItemSet_Pointer_t pSet ) +{ + return ::rtl::OUString::valueOf( reinterpret_cast<sal_IntPtr>( pSet.get() ), 16 ); +} + +// class StylePoolImpl organized a tree-structure where every node represents a SfxItemSet. +// The insertItemSet method adds a SfxItemSet into the tree if necessary and returns a shared_ptr +// to a copy of the SfxItemSet. +// The aRoot-Node represents an empty SfxItemSet. + +class StylePoolImpl +{ +private: + std::map< const SfxItemSet*, Node > maRoot; + sal_Int32 mnCount; + // --> OD 2008-03-07 #i86923# + SfxItemSet* mpIgnorableItems; + // <-- +public: + // --> OD 2008-03-07 #i86923# + explicit StylePoolImpl( SfxItemSet* pIgnorableItems = 0 ) + : maRoot(), + mnCount(0), + mpIgnorableItems( pIgnorableItems != 0 + ? pIgnorableItems->Clone( FALSE ) + : 0 ) + { + DBG_ASSERT( !pIgnorableItems || !pIgnorableItems->Count(), + "<StylePoolImpl::StylePoolImpl(..)> - misusage: item set for ignorable item should be empty. Please correct usage." ); + DBG_ASSERT( !mpIgnorableItems || !mpIgnorableItems->Count(), + "<StylePoolImpl::StylePoolImpl(..)> - <SfxItemSet::Clone( FALSE )> does not work as excepted - <mpIgnorableItems> is not empty. Please inform OD." ); + } + + ~StylePoolImpl() + { + delete mpIgnorableItems; + } + // <-- + + StylePool::SfxItemSet_Pointer_t insertItemSet( const SfxItemSet& rSet ); + + // --> OD 2008-03-07 #i86923# + IStylePoolIteratorAccess* createIterator( bool bSkipUnusedItemSets = false, + bool bSkipIgnorableItems = false ); + // <-- + sal_Int32 getCount() const { return mnCount; } +}; + +StylePool::SfxItemSet_Pointer_t StylePoolImpl::insertItemSet( const SfxItemSet& rSet ) +{ + bool bNonPoolable = false; + Node* pCurNode = &maRoot[ rSet.GetParent() ]; + SfxItemIter aIter( rSet ); + const SfxPoolItem* pItem = aIter.GetCurItem(); + // Every SfxPoolItem in the SfxItemSet causes a step deeper into the tree, + // a complete empty SfxItemSet would stay at the root node. + // --> OD 2008-03-07 #i86923# + // insert ignorable items to the tree leaves. + std::auto_ptr<SfxItemSet> pFoundIgnorableItems; + if ( mpIgnorableItems ) + { + pFoundIgnorableItems.reset( new SfxItemSet( *mpIgnorableItems ) ); + } + while( pItem ) + { + if( !rSet.GetPool()->IsItemFlag(pItem->Which(), SFX_ITEM_POOLABLE ) ) + bNonPoolable = true; + if ( !pFoundIgnorableItems.get() || + ( pFoundIgnorableItems.get() && + pFoundIgnorableItems->Put( *pItem ) == 0 ) ) + { + pCurNode = pCurNode->findChildNode( *pItem ); + } + pItem = aIter.NextItem(); + } + if ( pFoundIgnorableItems.get() && + pFoundIgnorableItems->Count() > 0 ) + { + SfxItemIter aIgnorableItemsIter( *pFoundIgnorableItems ); + pItem = aIgnorableItemsIter.GetCurItem(); + while( pItem ) + { + if( !rSet.GetPool()->IsItemFlag(pItem->Which(), SFX_ITEM_POOLABLE ) ) + bNonPoolable = true; + pCurNode = pCurNode->findChildNode( *pItem, true ); + pItem = aIgnorableItemsIter.NextItem(); + } + } + // <-- + // Every leaf node represents an inserted item set, but "non-leaf" nodes represents subsets + // of inserted itemsets. + // These nodes could have but does not need to have a shared_ptr to a item set. + if( !pCurNode->hasItemSet( false ) ) + { + pCurNode->setItemSet( rSet ); + bNonPoolable = false; // to avoid a double insertion + ++mnCount; + } + // If rSet contains at least one non poolable item, a new itemset has to be inserted + if( bNonPoolable ) + pCurNode->setItemSet( rSet ); +#ifdef DEBUG + { + sal_Int32 nCheck = -1; + sal_Int32 nNo = -1; + IStylePoolIteratorAccess* pIter = createIterator(); + StylePool::SfxItemSet_Pointer_t pTemp; + do + { + ++nCheck; + pTemp = pIter->getNext(); + if( pCurNode->hasItemSet( false ) && pTemp.get() == pCurNode->getItemSet().get() ) + { + ::rtl::OUString aStr = StylePool::nameOf( pTemp ); + nNo = nCheck; + } + } while( pTemp.get() ); + DBG_ASSERT( mnCount == nCheck, "Wrong counting"); + delete pIter; + } +#endif + return pCurNode->getItemSet(); +} + +// --> OD 2008-03-07 #i86923# +IStylePoolIteratorAccess* StylePoolImpl::createIterator( bool bSkipUnusedItemSets, + bool bSkipIgnorableItems ) +{ + return new Iterator( maRoot, bSkipUnusedItemSets, bSkipIgnorableItems ); +} +// <-- + +// Ctor, Dtor and redirected methods of class StylePool, nearly inline ;-) + +// --> OD 2008-03-07 #i86923# +StylePool::StylePool( SfxItemSet* pIgnorableItems ) + : pImpl( new StylePoolImpl( pIgnorableItems ) ) +{} +// <-- + +StylePool::SfxItemSet_Pointer_t StylePool::insertItemSet( const SfxItemSet& rSet ) +{ return pImpl->insertItemSet( rSet ); } + +// --> OD 2008-03-11 #i86923# +IStylePoolIteratorAccess* StylePool::createIterator( const bool bSkipUnusedItemSets, + const bool bSkipIgnorableItems ) +{ + return pImpl->createIterator( bSkipUnusedItemSets, bSkipIgnorableItems ); +} +// <-- + +sal_Int32 StylePool::getCount() const +{ return pImpl->getCount(); } + +StylePool::~StylePool() { delete pImpl; } + +// End of class StylePool + diff --git a/svl/source/items/szitem.cxx b/svl/source/items/szitem.cxx new file mode 100644 index 000000000000..a7667a25a97c --- /dev/null +++ b/svl/source/items/szitem.cxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * 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: szitem.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <svl/szitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/awt/Size.hpp> +#include <tools/stream.hxx> +#include <tools/gen.hxx> + +#include <svl/poolitem.hxx> +#include "memberid.hrc" + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxSizeItem) + +// ----------------------------------------------------------------------- + +TYPEINIT1_AUTOFACTORY(SfxSizeItem, SfxPoolItem); + +// ----------------------------------------------------------------------- + +SfxSizeItem::SfxSizeItem() +{ + DBG_CTOR(SfxSizeItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxSizeItem::SfxSizeItem( USHORT nW, const Size& rVal ) : + SfxPoolItem( nW ), + aVal( rVal ) +{ + DBG_CTOR(SfxSizeItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxSizeItem::SfxSizeItem( USHORT nW, SvStream &rStream ) : + SfxPoolItem( nW ) +{ + DBG_CTOR(SfxSizeItem, 0); + rStream >> aVal; +} + +// ----------------------------------------------------------------------- + +SfxSizeItem::SfxSizeItem( const SfxSizeItem& rItem ) : + SfxPoolItem( rItem ), + aVal( rItem.aVal ) +{ + DBG_CTOR(SfxSizeItem, 0); +} + +// ----------------------------------------------------------------------- + +SfxItemPresentation SfxSizeItem::GetPresentation +( + SfxItemPresentation /*ePresentation*/, + SfxMapUnit /*eCoreMetric*/, + SfxMapUnit /*ePresentationMetric*/, + XubString& rText, + const IntlWrapper * +) const +{ + DBG_CHKTHIS(SfxSizeItem, 0); + rText = UniString::CreateFromInt32(aVal.Width()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + rText += UniString::CreateFromInt32(aVal.Height()); + rText.AppendAscii(RTL_CONSTASCII_STRINGPARAM(", ")); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + +// ----------------------------------------------------------------------- + +int SfxSizeItem::operator==( const SfxPoolItem& rItem ) const +{ + DBG_CHKTHIS(SfxSizeItem, 0); + DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" ); + return ((SfxSizeItem&)rItem).aVal == aVal; +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxSizeItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxSizeItem, 0); + return new SfxSizeItem( *this ); +} + +// ----------------------------------------------------------------------- + +SfxPoolItem* SfxSizeItem::Create(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxSizeItem, 0); + Size aStr; + rStream >> aStr; + return new SfxSizeItem(Which(), aStr); +} + +// ----------------------------------------------------------------------- + +SvStream& SfxSizeItem::Store(SvStream &rStream, USHORT ) const +{ + DBG_CHKTHIS(SfxSizeItem, 0); + rStream << aVal; + return rStream; +} + +// ----------------------------------------------------------------------- +BOOL SfxSizeItem::QueryValue( com::sun::star::uno::Any& rVal, + BYTE nMemberId ) const +{ + sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + Size aTmp(aVal); + if( bConvert ) + { + aTmp.Height() = ( aTmp.Height() * 127 + 36) / 72; + aTmp.Width() = ( aTmp.Width() * 127 + 36) / 72; + } + + switch ( nMemberId ) + { + case 0: + { + rVal <<= com::sun::star::awt::Size( aTmp.getWidth(), aTmp.getHeight() ); + break; + } + case MID_WIDTH: + rVal <<= aTmp.getWidth(); break; + case MID_HEIGHT: + rVal <<= aTmp.getHeight(); break; + default: DBG_ERROR("Wrong MemberId!"); return FALSE; + } + + return TRUE; +} + +// ----------------------------------------------------------------------- +BOOL SfxSizeItem::PutValue( const com::sun::star::uno::Any& rVal, + BYTE nMemberId ) +{ + sal_Bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + BOOL bRet = FALSE; + com::sun::star::awt::Size aValue; + sal_Int32 nVal = 0; + if ( !nMemberId ) + bRet = ( rVal >>= aValue ); + else + { + bRet = ( rVal >>= nVal ); + if ( nMemberId == MID_WIDTH ) + { + aValue.Width = nVal; + aValue.Height = aVal.Height(); + } + else + { + aValue.Height = nVal; + aValue.Width = aVal.Width(); + } + } + + if ( bRet ) + { + Size aTmp( aValue.Width, aValue.Height ); + if( bConvert ) + { + aTmp.Height() = ( aTmp.Height() * 72 + 63) / 127; + aTmp.Width() = ( aTmp.Width() * 72 + 63) / 127; + } + + aVal = aTmp; + } + + return bRet; +} + + + diff --git a/svl/source/items/visitem.cxx b/svl/source/items/visitem.cxx new file mode 100644 index 000000000000..e4ff302541fe --- /dev/null +++ b/svl/source/items/visitem.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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: visitem.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/visitem.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <tools/stream.hxx> + +//============================================================================ +// +// class SfxVisibilityItem +// +//============================================================================ + +DBG_NAME(SfxVisibilityItem) + +//============================================================================ +TYPEINIT1_AUTOFACTORY(SfxVisibilityItem, SfxPoolItem); + +//============================================================================ +SfxVisibilityItem::SfxVisibilityItem(USHORT which, SvStream & rStream): + SfxPoolItem(which) +{ + DBG_CTOR(SfxVisibilityItem, 0); + sal_Bool bValue = 0; + rStream >> bValue; + m_nValue.bVisible = bValue; +} + +//============================================================================ +// virtual +int SfxVisibilityItem::operator ==(const SfxPoolItem & rItem) const +{ + DBG_CHKTHIS(SfxVisibilityItem, 0); + DBG_ASSERT(SfxPoolItem::operator ==(rItem), "unequal type"); + return m_nValue.bVisible == SAL_STATIC_CAST(const SfxVisibilityItem *, &rItem)-> + m_nValue.bVisible; +} + +//============================================================================ +// virtual +int SfxVisibilityItem::Compare(const SfxPoolItem & rWith) const +{ + DBG_ASSERT(rWith.ISA(SfxVisibilityItem), "SfxVisibilityItem::Compare(): Bad type"); + return m_nValue.bVisible == static_cast< SfxVisibilityItem const * >(&rWith)->m_nValue.bVisible ? + 0 : m_nValue.bVisible ? -1 : 1; +} + +//============================================================================ +// virtual +SfxItemPresentation SfxVisibilityItem::GetPresentation(SfxItemPresentation, + SfxMapUnit, SfxMapUnit, + XubString & rText, + const IntlWrapper *) const +{ + rText = GetValueTextByVal(m_nValue.bVisible); + return SFX_ITEM_PRESENTATION_NAMELESS; +} + + +//============================================================================ +// virtual +BOOL SfxVisibilityItem::QueryValue(com::sun::star::uno::Any& rVal,BYTE) const +{ + rVal <<= m_nValue; + return TRUE; +} + +//============================================================================ +// virtual +BOOL SfxVisibilityItem::PutValue(const com::sun::star::uno::Any& rVal,BYTE) +{ + if (rVal >>= m_nValue) + return TRUE; + + DBG_ERROR( "SfxInt16Item::PutValue - Wrong type!" ); + return FALSE; +} + +//============================================================================ +// virtual +SfxPoolItem * SfxVisibilityItem::Create(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(SfxVisibilityItem, 0); + return new SfxVisibilityItem(Which(), rStream); +} + +//============================================================================ +// virtual +SvStream & SfxVisibilityItem::Store(SvStream & rStream, USHORT) const +{ + DBG_CHKTHIS(SfxVisibilityItem, 0); + rStream << m_nValue.bVisible; + return rStream; +} + +//============================================================================ +// virtual +SfxPoolItem * SfxVisibilityItem::Clone(SfxItemPool *) const +{ + DBG_CHKTHIS(SfxVisibilityItem, 0); + return new SfxVisibilityItem(*this); +} + +//============================================================================ +// virtual +USHORT SfxVisibilityItem::GetValueCount() const +{ + return 2; +} + +//============================================================================ +// virtual +UniString SfxVisibilityItem::GetValueTextByVal(BOOL bTheValue) const +{ + return + bTheValue ? + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TRUE")) : + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("FALSE")); +} diff --git a/svl/source/items/whassert.hxx b/svl/source/items/whassert.hxx new file mode 100644 index 000000000000..fe9a834816c2 --- /dev/null +++ b/svl/source/items/whassert.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * 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: whassert.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SFX_WHASSERT_HXX +#define _SFX_WHASSERT_HXX + +#include <tools/debug.hxx> +#include <tools/string.hxx> + +//------------------------------------------------------------------------ + +#ifdef DBG_UTIL +#define SFX_ASSERT( bCondition, nId, sMessage ) \ +{ \ + if ( DbgIsAssert() ) \ + { \ + if ( !(bCondition) ) \ + { \ + ByteString aMsg( sMessage ); \ + aMsg.Append(RTL_CONSTASCII_STRINGPARAM("\nwith Id/Pos: ")); \ + aMsg += ByteString::CreateFromInt32( nId ); \ + DbgOut( aMsg.GetBuffer(), DBG_OUT_ERROR, __FILE__, __LINE__); \ + } \ + } \ +} +#else +#define SFX_ASSERT( bCondition, nId, sMessage ) +#endif + + +#endif diff --git a/svl/source/items/whiter.cxx b/svl/source/items/whiter.cxx new file mode 100644 index 000000000000..b5e53e0bc278 --- /dev/null +++ b/svl/source/items/whiter.cxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * 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: whiter.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +// INCLUDE --------------------------------------------------------------- +#ifndef GCC +#endif + +#include "whiter.hxx" +#include <svl/itemset.hxx> + +DBG_NAME(SfxWhichIter) + +// ----------------------------------------------------------------------- + +SfxWhichIter::SfxWhichIter( const SfxItemSet& rSet, USHORT nFromWh, USHORT nToWh ): + pRanges(rSet.GetRanges()), + pStart(rSet.GetRanges()), + nOfst(0), nFrom(nFromWh), nTo(nToWh) +{ + DBG_CTOR(SfxWhichIter, 0); + if ( nFrom > 0 ) + FirstWhich(); +} + +// ----------------------------------------------------------------------- + +SfxWhichIter::~SfxWhichIter() +{ + DBG_DTOR(SfxWhichIter, 0); +} + +// ----------------------------------------------------------------------- + +USHORT SfxWhichIter::NextWhich() +{ + DBG_CHKTHIS(SfxWhichIter, 0); + while ( 0 != *pRanges ) + { + const USHORT nLastWhich = *pRanges + nOfst; + ++nOfst; + if (*(pRanges+1) == nLastWhich) + { + pRanges += 2; + nOfst = 0; + } + USHORT nWhich = *pRanges + nOfst; + if ( 0 == nWhich || ( nWhich >= nFrom && nWhich <= nTo ) ) + return nWhich; + } + return 0; +} + +// ----------------------------------------------------------------------- + +USHORT SfxWhichIter::PrevWhich() +{ + DBG_CHKTHIS(SfxWhichIter, 0); + while ( pRanges != pStart || 0 != nOfst ) + { + if(nOfst) + --nOfst; + else { + pRanges -= 2; + nOfst = *(pRanges+1) - (*pRanges); + } + USHORT nWhich = *pRanges + nOfst; + if ( nWhich >= nFrom && nWhich <= nTo ) + return nWhich; + } + return 0; +} + +// ----------------------------------------------------------------------- + +USHORT SfxWhichIter::FirstWhich() +{ + DBG_CHKTHIS(SfxWhichIter, 0); + pRanges = pStart; + nOfst = 0; + if ( *pRanges >= nFrom && *pRanges <= nTo ) + return *pRanges; + return NextWhich(); +} + +// ----------------------------------------------------------------------- + +USHORT SfxWhichIter::LastWhich() +{ + DBG_CHKTHIS(SfxWhichIter, 0); + while(*pRanges) + ++pRanges; + nOfst = 0; + USHORT nWhich = *(pRanges-1); + if ( nWhich >= nFrom && nWhich <= nTo ) + return nWhich; + return PrevWhich(); +} + diff --git a/svl/source/memtools/makefile.mk b/svl/source/memtools/makefile.mk new file mode 100644 index 000000000000..8f59391a25ee --- /dev/null +++ b/svl/source/memtools/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.5 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=svarray + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/svarray.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/memtools/svarray.cxx b/svl/source/memtools/svarray.cxx new file mode 100644 index 000000000000..e2fa809c1b52 --- /dev/null +++ b/svl/source/memtools/svarray.cxx @@ -0,0 +1,385 @@ +/************************************************************************* + * + * 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: svarray.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define _SVARRAY_CXX + +#define _SVSTDARR_BOOLS +#define _SVSTDARR_BYTES +#define _SVSTDARR_ULONGS +#define _SVSTDARR_ULONGSSORT +#define _SVSTDARR_USHORTS +#define _SVSTDARR_LONGS +#define _SVSTDARR_LONGSSORT +#define _SVSTDARR_SHORTS +#define _SVSTDARR_STRINGS +#define _SVSTDARR_STRINGSDTOR +#define _SVSTDARR_STRINGSSORT +#define _SVSTDARR_STRINGSSORTDTOR +#define _SVSTDARR_STRINGSISORT +#define _SVSTDARR_STRINGSISORTDTOR +#define _SVSTDARR_USHORTSSORT + +#define _SVSTDARR_BYTESTRINGS +#define _SVSTDARR_BYTESTRINGSDTOR +#define _SVSTDARR_BYTESTRINGSSORT +#define _SVSTDARR_BYTESTRINGSSORTDTOR +#define _SVSTDARR_BYTESTRINGSISORT +#define _SVSTDARR_BYTESTRINGSISORTDTOR + +#define _SVSTDARR_XUB_STRLEN +#define _SVSTDARR_XUB_STRLENSORT + +#include <svl/svstdarr.hxx> +#include <tools/string.hxx> +#include <tools/debug.hxx> + +SV_IMPL_VARARR(SvPtrarr,VoidPtr) +SV_IMPL_VARARR_PLAIN(SvPtrarrPlain,VoidPtr) + +USHORT SvPtrarr::GetPos( const VoidPtr& aElement ) const +{ USHORT n; + for( n=0; n < nA && *(GetData()+n) != aElement; ) n++; + return ( n >= nA ? USHRT_MAX : n ); +} + +USHORT SvPtrarrPlain::GetPos( const VoidPtr aElement ) const +{ USHORT n; + for( n=0; n < nA && *(GetData()+n) != aElement; ) n++; + return ( n >= nA ? USHRT_MAX : n ); +} + + +SV_IMPL_VARARR( SvBools, BOOL ) +SV_IMPL_VARARR( SvBytes, BYTE ) +SV_IMPL_VARARR( SvULongs, ULONG ) +SV_IMPL_VARARR( SvUShorts, USHORT ) +SV_IMPL_VARARR( SvLongs, long) +SV_IMPL_VARARR( SvShorts, short ) + +SV_IMPL_VARARR_SORT( SvULongsSort, ULONG ) +SV_IMPL_VARARR_SORT( SvLongsSort, long ) +SV_IMPL_VARARR_SORT( SvXub_StrLensSort, xub_StrLen ) + +SV_IMPL_VARARR( SvXub_StrLens, xub_StrLen ) + +SV_IMPL_PTRARR( SvStrings, StringPtr ) +SV_IMPL_PTRARR( SvStringsDtor, StringPtr ) +SV_IMPL_OP_PTRARR_SORT( SvStringsSort, StringPtr ) +SV_IMPL_OP_PTRARR_SORT( SvStringsSortDtor, StringPtr ) + +SV_IMPL_PTRARR( SvByteStrings, ByteStringPtr ) +SV_IMPL_PTRARR( SvByteStringsDtor, ByteStringPtr ) +SV_IMPL_OP_PTRARR_SORT( SvByteStringsSort, ByteStringPtr ) +SV_IMPL_OP_PTRARR_SORT( SvByteStringsSortDtor, ByteStringPtr ) + + + +// ---------------- strings ------------------------------------- + +// Array mit anderer Seek-Methode! +_SV_IMPL_SORTAR_ALG( SvStringsISort, StringPtr ) +void SvStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL ) +{ + if( nL ) + { + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" ); + for( USHORT n=nP; n < nP + nL; n++ ) + delete *((StringPtr*)pData+n); + SvPtrarr::Remove( nP, nL ); + } +} +BOOL SvStringsISort::Seek_Entry( const StringPtr aE, USHORT* pP ) const +{ + register USHORT nO = SvStringsISort_SAR::Count(), + nM, + nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + StringCompare eCmp = (*((StringPtr*)pData + nM))-> + CompareIgnoreCaseToAscii( *(aE) ); + if( COMPARE_EQUAL == eCmp ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( COMPARE_LESS == eCmp ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pP ) *pP = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + +// ---------------- strings ------------------------------------- + +// Array mit anderer Seek-Methode! +_SV_IMPL_SORTAR_ALG( SvStringsISortDtor, StringPtr ) +void SvStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL ) +{ + if( nL ) + { + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" ); + for( USHORT n=nP; n < nP + nL; n++ ) + delete *((StringPtr*)pData+n); + SvPtrarr::Remove( nP, nL ); + } +} +BOOL SvStringsISortDtor::Seek_Entry( const StringPtr aE, USHORT* pP ) const +{ + register USHORT nO = SvStringsISortDtor_SAR::Count(), + nM, + nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + StringCompare eCmp = (*((StringPtr*)pData + nM))-> + CompareIgnoreCaseToAscii( *(aE) ); + if( COMPARE_EQUAL == eCmp ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( COMPARE_LESS == eCmp ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pP ) *pP = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + +// ---------------- Ushorts ------------------------------------- + +/* SortArray fuer UShorts */ +BOOL SvUShortsSort::Seek_Entry( const USHORT aE, USHORT* pP ) const +{ + register USHORT nO = SvUShorts::Count(), + nM, + nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + if( *(pData + nM) == aE ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( *(pData + nM) < aE ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pP ) *pP = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + +void SvUShortsSort::Insert( const SvUShortsSort * pI, USHORT nS, USHORT nE ) +{ + if( USHRT_MAX == nE ) + nE = pI->Count(); + USHORT nP; + const USHORT * pIArr = pI->GetData(); + for( ; nS < nE; ++nS ) + { + if( ! Seek_Entry( *(pIArr+nS), &nP) ) + SvUShorts::Insert( *(pIArr+nS), nP ); + if( ++nP >= Count() ) + { + SvUShorts::Insert( pI, nP, nS+1, nE ); + nS = nE; + } + } +} + +BOOL SvUShortsSort::Insert( const USHORT aE ) +{ + USHORT nP; + BOOL bExist = Seek_Entry( aE, &nP ); + if( !bExist ) + SvUShorts::Insert( aE, nP ); + return !bExist; +} + +BOOL SvUShortsSort::Insert( const USHORT aE, USHORT& rP ) +{ + BOOL bExist = Seek_Entry( aE, &rP ); + if( !bExist ) + SvUShorts::Insert( aE, rP ); + return !bExist; +} + +void SvUShortsSort::Insert( const USHORT* pE, USHORT nL) +{ + USHORT nP; + for( USHORT n = 0; n < nL; ++n ) + if( ! Seek_Entry( *(pE+n), &nP )) + SvUShorts::Insert( *(pE+n), nP ); +} + +// remove ab Pos +void SvUShortsSort::RemoveAt( const USHORT nP, USHORT nL ) +{ + if( nL ) + SvUShorts::Remove( nP, nL); +} + +// remove ab dem Eintrag +void SvUShortsSort::Remove( const USHORT aE, USHORT nL ) +{ + USHORT nP; + if( nL && Seek_Entry( aE, &nP ) ) + SvUShorts::Remove( nP, nL); +} + +// ---------------- bytestrings ------------------------------------- + +// Array mit anderer Seek-Methode! +_SV_IMPL_SORTAR_ALG( SvByteStringsISort, ByteStringPtr ) +void SvByteStringsISort::DeleteAndDestroy( USHORT nP, USHORT nL ) +{ + if( nL ) + { + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" ); + for( USHORT n=nP; n < nP + nL; n++ ) + delete *((ByteStringPtr*)pData+n); + SvPtrarr::Remove( nP, nL ); + } +} +BOOL SvByteStringsISort::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const +{ + register USHORT nO = SvByteStringsISort_SAR::Count(), + nM, + nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + StringCompare eCmp = (*((ByteStringPtr*)pData + nM))-> + CompareIgnoreCaseToAscii( *(aE) ); + if( COMPARE_EQUAL == eCmp ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( COMPARE_LESS == eCmp ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pP ) *pP = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + + +// Array mit anderer Seek-Methode! +_SV_IMPL_SORTAR_ALG( SvByteStringsISortDtor, ByteStringPtr ) +void SvByteStringsISortDtor::DeleteAndDestroy( USHORT nP, USHORT nL ) +{ + if( nL ) + { + DBG_ASSERT( nP < nA && nP + nL <= nA, "ERR_VAR_DEL" ); + for( USHORT n=nP; n < nP + nL; n++ ) + delete *((ByteStringPtr*)pData+n); + SvPtrarr::Remove( nP, nL ); + } +} +BOOL SvByteStringsISortDtor::Seek_Entry( const ByteStringPtr aE, USHORT* pP ) const +{ + register USHORT nO = SvByteStringsISortDtor_SAR::Count(), + nM, + nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + StringCompare eCmp = (*((ByteStringPtr*)pData + nM))-> + CompareIgnoreCaseToAscii( *(aE) ); + if( COMPARE_EQUAL == eCmp ) + { + if( pP ) *pP = nM; + return TRUE; + } + else if( COMPARE_LESS == eCmp ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pP ) *pP = nU; + return FALSE; + } + else + nO = nM - 1; + } + } + if( pP ) *pP = nU; + return FALSE; +} + diff --git a/svl/source/misc/PasswordHelper.cxx b/svl/source/misc/PasswordHelper.cxx new file mode 100644 index 000000000000..a1125306eb7b --- /dev/null +++ b/svl/source/misc/PasswordHelper.cxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * 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: PasswordHelper.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + + +#ifndef GCC +#endif +#include "PasswordHelper.hxx" +#include <rtl/digest.h> +#include <tools/string.hxx> + +using namespace com::sun::star; + +void SvPasswordHelper::GetHashPassword(uno::Sequence<sal_Int8>& rPassHash, const sal_Char* pPass, sal_uInt32 nLen) +{ + rPassHash.realloc(RTL_DIGEST_LENGTH_SHA1); + + rtlDigestError aError = rtl_digest_SHA1 (pPass, nLen, reinterpret_cast<sal_uInt8*>(rPassHash.getArray()), rPassHash.getLength()); + if (aError != rtl_Digest_E_None) + { + rPassHash.realloc(0); + } +} + +void SvPasswordHelper::GetHashPasswordLittleEndian(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + xub_StrLen nSize(sPass.Len()); + sal_Char* pCharBuffer = new sal_Char[nSize * sizeof(sal_Unicode)]; + + for (xub_StrLen i = 0; i < nSize; ++i) + { + sal_Unicode ch(sPass.GetChar(i)); + pCharBuffer[2 * i] = static_cast< sal_Char >(ch & 0xFF); + pCharBuffer[2 * i + 1] = static_cast< sal_Char >(ch >> 8); + } + + GetHashPassword(rPassHash, pCharBuffer, nSize * sizeof(sal_Unicode)); + + delete[] pCharBuffer; +} + +void SvPasswordHelper::GetHashPasswordBigEndian(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + xub_StrLen nSize(sPass.Len()); + sal_Char* pCharBuffer = new sal_Char[nSize * sizeof(sal_Unicode)]; + + for (xub_StrLen i = 0; i < nSize; ++i) + { + sal_Unicode ch(sPass.GetChar(i)); + pCharBuffer[2 * i] = static_cast< sal_Char >(ch >> 8); + pCharBuffer[2 * i + 1] = static_cast< sal_Char >(ch & 0xFF); + } + + GetHashPassword(rPassHash, pCharBuffer, nSize * sizeof(sal_Unicode)); + + delete[] pCharBuffer; +} + +void SvPasswordHelper::GetHashPassword(uno::Sequence<sal_Int8>& rPassHash, const String& sPass) +{ + GetHashPasswordLittleEndian(rPassHash, sPass); +} + +bool SvPasswordHelper::CompareHashPassword(const uno::Sequence<sal_Int8>& rOldPassHash, const String& sNewPass) +{ + bool bResult = false; + + uno::Sequence<sal_Int8> aNewPass(RTL_DIGEST_LENGTH_SHA1); + GetHashPasswordLittleEndian(aNewPass, sNewPass); + if (aNewPass == rOldPassHash) + bResult = true; + else + { + GetHashPasswordBigEndian(aNewPass, sNewPass); + bResult = (aNewPass == rOldPassHash); + } + + return bResult; +} + diff --git a/svl/source/misc/adrparse.cxx b/svl/source/misc/adrparse.cxx new file mode 100644 index 000000000000..b45650846df5 --- /dev/null +++ b/svl/source/misc/adrparse.cxx @@ -0,0 +1,921 @@ +/************************************************************************* + * + * 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: adrparse.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/inetmime.hxx> +#include <adrparse.hxx> + +namespace unnamed_svl_adrparse {} +using namespace unnamed_svl_adrparse; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_adrparse { + +enum ElementType { ELEMENT_START, ELEMENT_DELIM, ELEMENT_ITEM, ELEMENT_END }; + +//============================================================================ +struct ParsedAddrSpec +{ + sal_Unicode const * m_pBegin; + sal_Unicode const * m_pEnd; + ElementType m_eLastElem; + bool m_bAtFound; + bool m_bReparse; + + ParsedAddrSpec() { reset(); } + + bool isPoorlyValid() const { return m_eLastElem >= ELEMENT_ITEM; } + + bool isValid() const { return isPoorlyValid() && m_bAtFound; } + + inline void reset(); + + inline void finish(); +}; + +inline void ParsedAddrSpec::reset() +{ + m_pBegin = 0; + m_pEnd = 0; + m_eLastElem = ELEMENT_START; + m_bAtFound = false; + m_bReparse = false; +} + +inline void ParsedAddrSpec::finish() +{ + if (isPoorlyValid()) + m_eLastElem = ELEMENT_END; + else + reset(); +} + +} + +//============================================================================ +class SvAddressParser_Impl +{ + enum State { BEFORE_COLON, BEFORE_LESS, AFTER_LESS, AFTER_GREATER }; + + enum TokenType { TOKEN_QUOTED = 0x80000000, TOKEN_DOMAIN, TOKEN_COMMENT, + TOKEN_ATOM }; + + sal_Unicode const * m_pInputPos; + sal_Unicode const * m_pInputEnd; + sal_uInt32 m_nCurToken; + sal_Unicode const * m_pCurTokenBegin; + sal_Unicode const * m_pCurTokenEnd; + sal_Unicode const * m_pCurTokenContentBegin; + sal_Unicode const * m_pCurTokenContentEnd; + bool m_bCurTokenReparse; + ParsedAddrSpec m_aOuterAddrSpec; + ParsedAddrSpec m_aInnerAddrSpec; + ParsedAddrSpec * m_pAddrSpec; + sal_Unicode const * m_pRealNameBegin; + sal_Unicode const * m_pRealNameEnd; + sal_Unicode const * m_pRealNameContentBegin; + sal_Unicode const * m_pRealNameContentEnd; + bool m_bRealNameReparse; + bool m_bRealNameFinished; + sal_Unicode const * m_pFirstCommentBegin; + sal_Unicode const * m_pFirstCommentEnd; + bool m_bFirstCommentReparse; + State m_eState; + TokenType m_eType; + + inline void resetRealNameAndFirstComment(); + + inline void reset(); + + inline void addTokenToAddrSpec(ElementType eTokenElem); + + inline void addTokenToRealName(); + + bool readToken(); + + static UniString reparse(sal_Unicode const * pBegin, + sal_Unicode const * pEnd, bool bAddrSpec); + + static UniString reparseComment(sal_Unicode const * pBegin, + sal_Unicode const * pEnd); + +public: + SvAddressParser_Impl(SvAddressParser * pParser, UniString const & rInput); +}; + +inline void SvAddressParser_Impl::resetRealNameAndFirstComment() +{ + m_pRealNameBegin = 0; + m_pRealNameEnd = 0; + m_pRealNameContentBegin = 0; + m_pRealNameContentEnd = 0; + m_bRealNameReparse = false; + m_bRealNameFinished = false; + m_pFirstCommentBegin = 0; + m_pFirstCommentEnd = 0; + m_bFirstCommentReparse = false; +} + +inline void SvAddressParser_Impl::reset() +{ + m_aOuterAddrSpec.reset(); + m_aInnerAddrSpec.reset(); + m_pAddrSpec = &m_aOuterAddrSpec; + resetRealNameAndFirstComment(); + m_eState = BEFORE_COLON; + m_eType = TOKEN_ATOM; +} + +inline void SvAddressParser_Impl::addTokenToAddrSpec(ElementType eTokenElem) +{ + if (!m_pAddrSpec->m_pBegin) + m_pAddrSpec->m_pBegin = m_pCurTokenBegin; + else if (m_pAddrSpec->m_pEnd < m_pCurTokenBegin) + m_pAddrSpec->m_bReparse = true; + m_pAddrSpec->m_pEnd = m_pCurTokenEnd; + m_pAddrSpec->m_eLastElem = eTokenElem; +} + +inline void SvAddressParser_Impl::addTokenToRealName() +{ + if (!m_bRealNameFinished && m_eState != AFTER_LESS) + { + if (!m_pRealNameBegin) + m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin; + else if (m_pRealNameEnd < m_pCurTokenBegin - 1 + || (m_pRealNameEnd == m_pCurTokenBegin - 1 + && *m_pRealNameEnd != ' ')) + m_bRealNameReparse = true; + m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd; + } +} + +//============================================================================ +// +// SvAddressParser_Impl +// +//============================================================================ + +bool SvAddressParser_Impl::readToken() +{ + m_nCurToken = m_eType; + m_bCurTokenReparse = false; + switch (m_eType) + { + case TOKEN_QUOTED: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = m_pInputPos; + bool bEscaped = false; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + { + m_bCurTokenReparse = true; + bEscaped = false; + } + else if (cChar == '"') + { + m_pCurTokenEnd = m_pInputPos; + m_pCurTokenContentEnd = m_pInputPos - 1; + return true; + } + else if (cChar == '\\') + bEscaped = true; + } + } + + case TOKEN_DOMAIN: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = m_pInputPos; + bool bEscaped = false; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + bEscaped = false; + else if (cChar == ']') + { + m_pCurTokenEnd = m_pInputPos; + return true; + } + else if (cChar == '\\') + bEscaped = true; + } + } + + case TOKEN_COMMENT: + { + m_pCurTokenBegin = m_pInputPos - 1; + m_pCurTokenContentBegin = 0; + m_pCurTokenContentEnd = 0; + bool bEscaped = false; + xub_StrLen nLevel = 0; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + sal_Unicode cChar = *m_pInputPos++; + if (bEscaped) + { + m_bCurTokenReparse = true; + m_pCurTokenContentEnd = m_pInputPos; + bEscaped = false; + } + else if (cChar == '(') + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + m_pCurTokenContentEnd = m_pInputPos; + ++nLevel; + } + else if (cChar == ')') + if (nLevel) + { + m_pCurTokenContentEnd = m_pInputPos; + --nLevel; + } + else + return true; + else if (cChar == '\\') + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + bEscaped = true; + } + else if (cChar > ' ' && cChar != 0x7F) // DEL + { + if (!m_pCurTokenContentBegin) + m_pCurTokenContentBegin = m_pInputPos - 1; + m_pCurTokenContentEnd = m_pInputPos; + } + } + } + + default: + { + sal_Unicode cChar; + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + return false; + cChar = *m_pInputPos++; + if (cChar > ' ' && cChar != 0x7F) // DEL + break; + } + m_pCurTokenBegin = m_pInputPos - 1; + if (cChar == '"' || cChar == '(' || cChar == ')' || cChar == ',' + || cChar == '.' || cChar == ':' || cChar == ';' + || cChar == '<' || cChar == '>' || cChar == '@' + || cChar == '[' || cChar == '\\' || cChar == ']') + { + m_nCurToken = cChar; + m_pCurTokenEnd = m_pInputPos; + return true; + } + else + for (;;) + { + if (m_pInputPos >= m_pInputEnd) + { + m_pCurTokenEnd = m_pInputPos; + return true; + } + cChar = *m_pInputPos++; + if (cChar <= ' ' || cChar == '"' || cChar == '(' + || cChar == ')' || cChar == ',' || cChar == '.' + || cChar == ':' || cChar == ';' || cChar == '<' + || cChar == '>' || cChar == '@' || cChar == '[' + || cChar == '\\' || cChar == ']' + || cChar == 0x7F) // DEL + { + m_pCurTokenEnd = --m_pInputPos; + return true; + } + } + } + } +} + +//============================================================================ +// static +UniString SvAddressParser_Impl::reparse(sal_Unicode const * pBegin, + sal_Unicode const * pEnd, + bool bAddrSpec) +{ + UniString aResult; + TokenType eMode = TOKEN_ATOM; + bool bEscaped = false; + bool bEndsWithSpace = false; + xub_StrLen nLevel = 0; + while (pBegin < pEnd) + { + sal_Unicode cChar = *pBegin++; + switch (eMode) + { + case TOKEN_QUOTED: + if (bEscaped) + { + aResult += cChar; + bEscaped = false; + } + else if (cChar == '"') + { + if (bAddrSpec) + aResult += cChar; + eMode = TOKEN_ATOM; + } + else if (cChar == '\\') + { + if (bAddrSpec) + aResult += cChar; + bEscaped = true; + } + else + aResult += cChar; + break; + + case TOKEN_DOMAIN: + if (bEscaped) + { + aResult += cChar; + bEscaped = false; + } + else if (cChar == ']') + { + aResult += cChar; + eMode = TOKEN_ATOM; + } + else if (cChar == '\\') + { + if (bAddrSpec) + aResult += cChar; + bEscaped = true; + } + else + aResult += cChar; + break; + + case TOKEN_COMMENT: + if (bEscaped) + bEscaped = false; + else if (cChar == '(') + ++nLevel; + else if (cChar == ')') + if (nLevel) + --nLevel; + else + eMode = TOKEN_ATOM; + else if (cChar == '\\') + bEscaped = true; + break; + + case TOKEN_ATOM: + if (cChar <= ' ' || cChar == 0x7F) // DEL + { + if (!bAddrSpec && !bEndsWithSpace) + { + aResult += ' '; + bEndsWithSpace = true; + } + } + else if (cChar == '(') + { + if (!bAddrSpec && !bEndsWithSpace) + { + aResult += ' '; + bEndsWithSpace = true; + } + eMode = TOKEN_COMMENT; + } + else + { + bEndsWithSpace = false; + if (cChar == '"') + { + if (bAddrSpec) + aResult += cChar; + eMode = TOKEN_QUOTED; + } + else if (cChar == '[') + { + aResult += cChar; + eMode = TOKEN_QUOTED; + } + else + aResult += cChar; + } + break; + } + } + return aResult; +} + +//============================================================================ +// static +UniString SvAddressParser_Impl::reparseComment(sal_Unicode const * pBegin, + sal_Unicode const * pEnd) +{ + UniString aResult; + while (pBegin < pEnd) + { + sal_Unicode cChar = *pBegin++; + if (cChar == '\\') + cChar = *pBegin++; + aResult += cChar; + } + return aResult; +} + +//============================================================================ +SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, + UniString const & rInput) +{ + m_pInputPos = rInput.GetBuffer(); + m_pInputEnd = m_pInputPos + rInput.Len(); + + reset(); + bool bDone = false; + for (;;) + { + if (!readToken()) + { + m_bRealNameFinished = true; + if (m_eState == AFTER_LESS) + m_nCurToken = '>'; + else + { + m_nCurToken = ','; + bDone = true; + } + } + switch (m_nCurToken) + { + case TOKEN_QUOTED: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_bAtFound + || m_pAddrSpec->m_eLastElem <= ELEMENT_DELIM) + m_pAddrSpec->reset(); + addTokenToAddrSpec(ELEMENT_ITEM); + } + if (!m_bRealNameFinished && m_eState != AFTER_LESS) + { + if (m_bCurTokenReparse) + { + if (!m_pRealNameBegin) + m_pRealNameBegin = m_pCurTokenBegin; + m_pRealNameEnd = m_pCurTokenEnd; + m_bRealNameReparse = true; + } + else if (m_bRealNameReparse) + m_pRealNameEnd = m_pCurTokenEnd; + else if (!m_pRealNameBegin) + { + m_pRealNameBegin = m_pCurTokenBegin; + m_pRealNameContentBegin = m_pCurTokenContentBegin; + m_pRealNameEnd = m_pRealNameContentEnd + = m_pCurTokenContentEnd; + } + else + { + m_pRealNameEnd = m_pCurTokenEnd; + m_bRealNameReparse = true; + } + } + m_eType = TOKEN_ATOM; + break; + + case TOKEN_DOMAIN: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_bAtFound + && m_pAddrSpec->m_eLastElem == ELEMENT_DELIM) + addTokenToAddrSpec(ELEMENT_ITEM); + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + m_eType = TOKEN_ATOM; + break; + + case TOKEN_COMMENT: + if (!m_bRealNameFinished && m_eState != AFTER_LESS + && !m_pFirstCommentBegin && m_pCurTokenContentBegin) + { + m_pFirstCommentBegin = m_pCurTokenContentBegin; + m_pFirstCommentEnd = m_pCurTokenContentEnd; + m_bFirstCommentReparse = m_bCurTokenReparse; + } + m_eType = TOKEN_ATOM; + break; + + case TOKEN_ATOM: + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) + m_pAddrSpec->reset(); + addTokenToAddrSpec(ELEMENT_ITEM); + } + addTokenToRealName(); + break; + + case '(': + m_eType = TOKEN_COMMENT; + break; + + case ')': + case '\\': + case ']': + m_pAddrSpec->finish(); + addTokenToRealName(); + break; + + case '<': + switch (m_eState) + { + case BEFORE_COLON: + case BEFORE_LESS: + m_aOuterAddrSpec.finish(); + if (m_pRealNameBegin) + m_bRealNameFinished = true; + m_pAddrSpec = &m_aInnerAddrSpec; + m_eState = AFTER_LESS; + break; + + case AFTER_LESS: + m_aInnerAddrSpec.finish(); + break; + + case AFTER_GREATER: + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + break; + } + break; + + case '>': + if (m_eState == AFTER_LESS) + { + m_aInnerAddrSpec.finish(); + if (m_aInnerAddrSpec.isValid()) + m_aOuterAddrSpec.m_eLastElem = ELEMENT_END; + m_pAddrSpec = &m_aOuterAddrSpec; + m_eState = AFTER_GREATER; + } + else + { + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + } + break; + + case '@': + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (!m_pAddrSpec->m_bAtFound + && m_pAddrSpec->m_eLastElem == ELEMENT_ITEM) + { + addTokenToAddrSpec(ELEMENT_DELIM); + m_pAddrSpec->m_bAtFound = true; + } + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + break; + + case ',': + case ';': + if (m_eState == AFTER_LESS) + if (m_nCurToken == ',') + { + if (m_aInnerAddrSpec.m_eLastElem + != ELEMENT_END) + m_aInnerAddrSpec.reset(); + } + else + m_aInnerAddrSpec.finish(); + else + { + m_pAddrSpec = m_aInnerAddrSpec.isValid() + || (!m_aOuterAddrSpec.isValid() + && m_aInnerAddrSpec.isPoorlyValid()) ? + &m_aInnerAddrSpec : + m_aOuterAddrSpec.isPoorlyValid() ? + &m_aOuterAddrSpec : 0; + if (m_pAddrSpec) + { + UniString aTheAddrSpec; + if (m_pAddrSpec->m_bReparse) + aTheAddrSpec = reparse(m_pAddrSpec->m_pBegin, + m_pAddrSpec->m_pEnd, true); + else + { + xub_StrLen nLen = + sal::static_int_cast< xub_StrLen >( + m_pAddrSpec->m_pEnd + - m_pAddrSpec->m_pBegin); + if (nLen == rInput.Len()) + aTheAddrSpec = rInput; + else + aTheAddrSpec + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pAddrSpec->m_pBegin + - rInput.GetBuffer()), + nLen); + } + UniString aTheRealName; + if (!m_pRealNameBegin + || (m_pAddrSpec == &m_aOuterAddrSpec + && m_pRealNameBegin + == m_aOuterAddrSpec.m_pBegin + && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd + && m_pFirstCommentBegin)) + if (!m_pFirstCommentBegin) + aTheRealName = aTheAddrSpec; + else if (m_bFirstCommentReparse) + aTheRealName + = reparseComment(m_pFirstCommentBegin, + m_pFirstCommentEnd); + else + aTheRealName + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pFirstCommentBegin + - rInput.GetBuffer()), + sal::static_int_cast< xub_StrLen >( + m_pFirstCommentEnd + - m_pFirstCommentBegin)); + else if (m_bRealNameReparse) + aTheRealName = reparse(m_pRealNameBegin, + m_pRealNameEnd, false); + else + { + xub_StrLen nLen = + sal::static_int_cast< xub_StrLen >( + m_pRealNameContentEnd + - m_pRealNameContentBegin); + if (nLen == rInput.Len()) + aTheRealName = rInput; + else + aTheRealName + = rInput.Copy( + sal::static_int_cast< xub_StrLen >( + m_pRealNameContentBegin + - rInput.GetBuffer()), + nLen); + } + if (pParser->m_bHasFirst) + pParser->m_aRest.Insert(new SvAddressEntry_Impl( + aTheAddrSpec, + aTheRealName), + LIST_APPEND); + else + { + pParser->m_bHasFirst = true; + pParser->m_aFirst.m_aAddrSpec = aTheAddrSpec; + pParser->m_aFirst.m_aRealName = aTheRealName; + } + } + if (bDone) + return; + reset(); + } + break; + + case ':': + switch (m_eState) + { + case BEFORE_COLON: + m_aOuterAddrSpec.reset(); + resetRealNameAndFirstComment(); + m_eState = BEFORE_LESS; + break; + + case BEFORE_LESS: + case AFTER_GREATER: + m_aOuterAddrSpec.finish(); + addTokenToRealName(); + break; + + case AFTER_LESS: + m_aInnerAddrSpec.reset(); + break; + } + break; + + case '"': + m_eType = TOKEN_QUOTED; + break; + + case '.': + if (m_pAddrSpec->m_eLastElem != ELEMENT_END) + { + if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) + addTokenToAddrSpec(ELEMENT_DELIM); + else + m_pAddrSpec->reset(); + } + addTokenToRealName(); + break; + + case '[': + m_eType = TOKEN_DOMAIN; + break; + } + } +} + +//============================================================================ +// +// SvAddressParser +// +//============================================================================ + +SvAddressParser::SvAddressParser(UniString const & rInput): m_bHasFirst(false) +{ + SvAddressParser_Impl(this, rInput); +} + +//============================================================================ +SvAddressParser::~SvAddressParser() +{ + for (ULONG i = m_aRest.Count(); i != 0;) + delete m_aRest.Remove(--i); +} + +//============================================================================ +// static +bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, + String const & rAddrSpec, + String & rMailbox) +{ + String aTheAddrSpec; + sal_Unicode const * p = rAddrSpec.GetBuffer(); + sal_Unicode const * pEnd = p + rAddrSpec.Len(); + {for (bool bSegment = false;;) + { + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + if (bSegment) + { + sal_Unicode c = *p++; + if (c == '@') + break; + else if (c != '.') + return false; + aTheAddrSpec += '.'; + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + } + else + bSegment = true; + if (*p == '"') + { + aTheAddrSpec += *p++; + for (;;) + { + if (INetMIME::startsWithLineFolding(p, pEnd)) + p += 2; + if (p == pEnd) + return false; + if (*p == '"') + break; + if (*p == '\x0D' || (*p == '\\' && ++p == pEnd) + || !INetMIME::isUSASCII(*p)) + return false; + if (INetMIME::needsQuotedStringEscape(*p)) + aTheAddrSpec += '\\'; + aTheAddrSpec += *p++; + } + aTheAddrSpec += *p++; + } + else if (INetMIME::isAtomChar(*p)) + while (p != pEnd && INetMIME::isAtomChar(*p)) + aTheAddrSpec += *p++; + else + return false; + }} + aTheAddrSpec += '@'; + {for (bool bSegment = false;;) + { + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + { + if (bSegment) + break; + else + return false; + } + if (bSegment) + { + if (*p++ != '.') + return false; + aTheAddrSpec += '.'; + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd) + return false; + } + else + bSegment = true; + if (*p == '[') + { + aTheAddrSpec += *p++; + for (;;) + { + if (INetMIME::startsWithLineFolding(p, pEnd)) + p += 2; + if (p == pEnd) + return false; + if (*p == ']') + break; + if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd) + || !INetMIME::isUSASCII(*p)) + return false; + if (*p >= '[' && *p <= ']') + aTheAddrSpec += '\\'; + aTheAddrSpec += *p++; + } + aTheAddrSpec += *p++; + } + else if (INetMIME::isAtomChar(*p)) + while (p != pEnd && INetMIME::isAtomChar(*p)) + aTheAddrSpec += *p++; + else + return false; + }} + + if (rPhrase.Len() == 0) + rMailbox = aTheAddrSpec; + else + { + bool bQuotedString = false; + p = rPhrase.GetBuffer(); + pEnd = p + rPhrase.Len(); + for (;p != pEnd; ++p) + if (!(INetMIME::isAtomChar(*p))) + { + bQuotedString = true; + break; + } + String aTheMailbox; + if (bQuotedString) + { + aTheMailbox = '"'; + for (p = rPhrase.GetBuffer(); p != pEnd; ++p) + { + if (INetMIME::needsQuotedStringEscape(*p)) + aTheMailbox += '\\'; + aTheMailbox += *p; + } + aTheMailbox += '"'; + } + else + aTheMailbox = rPhrase; + aTheMailbox.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" <")); + aTheMailbox += aTheAddrSpec; + aTheMailbox += '>'; + rMailbox = aTheMailbox; + } + return true; +} + diff --git a/svl/source/misc/documentlockfile.cxx b/svl/source/misc/documentlockfile.cxx new file mode 100644 index 000000000000..b0c4148749e7 --- /dev/null +++ b/svl/source/misc/documentlockfile.cxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * 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: documentlockfile.cxx,v $ + * + * $Revision: 1.3.82.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/bootstrap.hxx> + +#include <ucbhelper/content.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/documentlockfile.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +sal_Bool DocumentLockFile::m_bAllowInteraction = sal_True; + +// ---------------------------------------------------------------------- +DocumentLockFile::DocumentLockFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~lock." ) ) ) +{ +} + +// ---------------------------------------------------------------------- +DocumentLockFile::~DocumentLockFile() +{ +} + +// ---------------------------------------------------------------------- +void DocumentLockFile::WriteEntryToStream( uno::Sequence< ::rtl::OUString > aEntry, uno::Reference< io::XOutputStream > xOutput ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + ::rtl::OUStringBuffer aBuffer; + + for ( sal_Int32 nEntryInd = 0; nEntryInd < aEntry.getLength(); nEntryInd++ ) + { + aBuffer.append( EscapeCharacters( aEntry[nEntryInd] ) ); + if ( nEntryInd < aEntry.getLength() - 1 ) + aBuffer.append( (sal_Unicode)',' ); + else + aBuffer.append( (sal_Unicode)';' ); + } + + ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) ); + uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() ); + xOutput->writeBytes( aData ); +} + +// ---------------------------------------------------------------------- +sal_Bool DocumentLockFile::CreateOwnLockFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + try + { + uno::Reference< io::XStream > xTempFile( + m_xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW ); + + uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream(); + uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream(); + + if ( !xInput.is() || !xOutput.is() ) + throw uno::RuntimeException(); + + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + WriteEntryToStream( aNewEntry, xOutput ); + xOutput->closeOutput(); + + xSeekable->seek( 0 ); + + uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; + ::ucbhelper::Content aTargetContent( m_aURL, xEnv ); + + ucb::InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + aInsertArg.ReplaceExisting = sal_False; + uno::Any aCmdArg; + aCmdArg <<= aInsertArg; + aTargetContent.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ), aCmdArg ); + + // try to let the file be hidden if possible + try { + aTargetContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) ); + } catch( uno::Exception& ) {} + } + catch( ucb::NameClashException& ) + { + return sal_False; + } + + return sal_True; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > DocumentLockFile::GetLockData() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< io::XInputStream > xInput = OpenStream(); + if ( !xInput.is() ) + throw uno::RuntimeException(); + + const sal_Int32 nBufLen = 32000; + uno::Sequence< sal_Int8 > aBuffer( nBufLen ); + + sal_Int32 nRead = 0; + + nRead = xInput->readBytes( aBuffer, nBufLen ); + xInput->closeInput(); + + if ( nRead == nBufLen ) + throw io::WrongFormatException(); + + sal_Int32 nCurPos = 0; + return ParseEntry( aBuffer, nCurPos ); +} + +// ---------------------------------------------------------------------- +uno::Reference< io::XInputStream > DocumentLockFile::OpenStream() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + + // the file can be opened readonly, no locking will be done + return xSimpleFileAccess->openFileRead( m_aURL ); +} + +// ---------------------------------------------------------------------- +sal_Bool DocumentLockFile::OverwriteOwnLockFile() +{ + // allows to overwrite the lock file with the current data + try + { + uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv; + ::ucbhelper::Content aTargetContent( m_aURL, xEnv ); + + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + + uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock(); + uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream(); + uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW ); + + xTruncate->truncate(); + WriteEntryToStream( aNewEntry, xOutput ); + xOutput->closeOutput(); + } + catch( uno::Exception& ) + { + return sal_False; + } + + return sal_True; +} + +// ---------------------------------------------------------------------- +void DocumentLockFile::RemoveFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + // TODO/LATER: the removing is not atomar, is it possible in general to make it atomar? + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + uno::Sequence< ::rtl::OUString > aFileData = GetLockData(); + + if ( aFileData.getLength() < LOCKFILE_ENTRYSIZE ) + throw io::WrongFormatException(); + + if ( !aFileData[LOCKFILE_SYSUSERNAME_ID].equals( aNewEntry[LOCKFILE_SYSUSERNAME_ID] ) + || !aFileData[LOCKFILE_LOCALHOST_ID].equals( aNewEntry[LOCKFILE_LOCALHOST_ID] ) + || !aFileData[LOCKFILE_USERURL_ID].equals( aNewEntry[LOCKFILE_USERURL_ID] ) ) + throw io::IOException(); // not the owner, access denied + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + xSimpleFileAccess->kill( m_aURL ); +} + +} // namespace svt + diff --git a/svl/source/misc/filenotation.cxx b/svl/source/misc/filenotation.cxx new file mode 100644 index 000000000000..d50645c97439 --- /dev/null +++ b/svl/source/misc/filenotation.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * 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: filenotation.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "filenotation.hxx" +#include <osl/file.h> +#include <osl/diagnose.h> +#include <tools/urlobj.hxx> + +//......................................................................... +namespace svt +{ +//......................................................................... + + //===================================================================== + //= OFileNotation + //===================================================================== + //--------------------------------------------------------------------- + OFileNotation::OFileNotation( const ::rtl::OUString& _rUrlOrPath ) + { + construct( _rUrlOrPath ); + } + + //--------------------------------------------------------------------- + OFileNotation::OFileNotation( const ::rtl::OUString& _rUrlOrPath, NOTATION _eInputNotation ) + { + if ( _eInputNotation == N_URL ) + { + INetURLObject aParser( _rUrlOrPath ); + if ( aParser.GetProtocol() == INET_PROT_FILE ) + implInitWithURLNotation( _rUrlOrPath ); + else + m_sSystem = m_sFileURL = _rUrlOrPath; + } + else + implInitWithSystemNotation( _rUrlOrPath ); + } + + //--------------------------------------------------------------------- + bool OFileNotation::implInitWithSystemNotation( const ::rtl::OUString& _rSystemPath ) + { + bool bSuccess = false; + + m_sSystem = _rSystemPath; + if ( ( osl_File_E_None != osl_getFileURLFromSystemPath( m_sSystem.pData, &m_sFileURL.pData ) ) + && ( 0 == m_sFileURL.getLength() ) + ) + { + if ( _rSystemPath.getLength() ) + { + INetURLObject aSmartParser; + aSmartParser.SetSmartProtocol( INET_PROT_FILE ); + if ( aSmartParser.SetSmartURL( _rSystemPath ) ) + { + m_sFileURL = aSmartParser.GetMainURL( INetURLObject::NO_DECODE ); + osl_getSystemPathFromFileURL( m_sFileURL.pData, &m_sSystem.pData ); + bSuccess = true; + } + } + } + else + bSuccess = true; + return bSuccess; + } + + //--------------------------------------------------------------------- + bool OFileNotation::implInitWithURLNotation( const ::rtl::OUString& _rURL ) + { + m_sFileURL = _rURL; + osl_getSystemPathFromFileURL( _rURL.pData, &m_sSystem.pData ); + return true; + } + + //--------------------------------------------------------------------- + void OFileNotation::construct( const ::rtl::OUString& _rUrlOrPath ) + { + bool bSuccess = false; + // URL notation? + INetURLObject aParser( _rUrlOrPath ); + switch ( aParser.GetProtocol() ) + { + case INET_PROT_FILE: + // file URL + bSuccess = implInitWithURLNotation( _rUrlOrPath ); + break; + + case INET_PROT_NOT_VALID: + // assume system notation + bSuccess = implInitWithSystemNotation( _rUrlOrPath ); + break; + + default: + // it's a known scheme, but no file-URL -> assume that bothe the URL representation and the + // system representation are the URL itself + m_sSystem = m_sFileURL = _rUrlOrPath; + bSuccess = true; + break; + } + + OSL_ENSURE( bSuccess, "OFileNotation::OFileNotation: could not detect the format!" ); + } + + //--------------------------------------------------------------------- + ::rtl::OUString OFileNotation::get(NOTATION _eOutputNotation) + { + switch (_eOutputNotation) + { + case N_SYSTEM: return m_sSystem; + case N_URL: return m_sFileURL; + } + + OSL_ENSURE(sal_False, "OFileNotation::get: inavlid enum value!"); + return ::rtl::OUString(); + } + +//......................................................................... +} // namespace svt +//......................................................................... + diff --git a/svl/source/misc/folderrestriction.cxx b/svl/source/misc/folderrestriction.cxx new file mode 100644 index 000000000000..9ec7ead0a4be --- /dev/null +++ b/svl/source/misc/folderrestriction.cxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * 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: folderrestriction.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "folderrestriction.hxx" +#include "osl/process.h" +#include "tools/urlobj.hxx" +#include "unotools/localfilehelper.hxx" + +//----------------------------------------------------------------------------- + +static void convertStringListToUrls ( + const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) +{ + const sal_Unicode s_cSeparator = +#if defined(WNT) + ';' +#else + ':' +#endif + ; + xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); + _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); + for ( xub_StrLen i=0; i<nTokens; ++i ) + { + // the current token in the list + String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); + if ( !sCurrentToken.Len() ) + continue; + + INetURLObject aCurrentURL; + + String sURL; + if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) + aCurrentURL = INetURLObject( sURL ); + else + { + // smart URL parsing, assuming FILE protocol + aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); + } + + if ( _bFinalSlash ) + aCurrentURL.setFinalSlash( ); + else + aCurrentURL.removeFinalSlash( ); + _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } +} + +/** retrieves the value of an environment variable + @return <TRUE/> if and only if the retrieved string value is not empty +*/ +static bool getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) +{ + _rValue = ::rtl::OUString(); + ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); + osl_getEnvironment( sEnvName.pData, &_rValue.pData ); + return _rValue.getLength() != 0; +} + +//----------------------------------------------------------------------------- + +namespace svt +{ + + void getUnrestrictedFolders( ::std::vector< String >& _rFolders ) + { + _rFolders.resize( 0 ); + ::rtl::OUString sRestrictedPathList; + if ( getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) ) + { + // append a final slash. This ensures that when we later on check + // for unrestricted paths, we don't allow paths like "/home/user35" just because + // "/home/user3" is allowed - with the final slash, we make it "/home/user3/". + convertStringListToUrls( sRestrictedPathList, _rFolders, true ); + } + } + +} // namespace svt + diff --git a/svl/source/misc/fstathelper.cxx b/svl/source/misc/fstathelper.cxx new file mode 100644 index 000000000000..43619e879a91 --- /dev/null +++ b/svl/source/misc/fstathelper.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * 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: fstathelper.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/date.hxx> +#include <tools/time.hxx> +#include <tools/string.hxx> +#include <ucbhelper/content.hxx> +#include <com/sun/star/util/DateTime.hpp> + +#include <fstathelper.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::ucb; +using namespace ::rtl; + +sal_Bool FStatHelper::GetModifiedDateTimeOfFile( const UniString& rURL, + Date* pDate, Time* pTime ) +{ + sal_Bool bRet = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + uno::Any aAny = aTestContent.getPropertyValue( + OUString::createFromAscii( "DateModified" ) ); + if( aAny.hasValue() ) + { + bRet = sal_True; + const util::DateTime* pDT = (util::DateTime*)aAny.getValue(); + if( pDate ) + *pDate = Date( pDT->Day, pDT->Month, pDT->Year ); + if( pTime ) + *pTime = Time( pDT->Hours, pDT->Minutes, + pDT->Seconds, pDT->HundredthSeconds ); + } + } + catch(...) + { + } + + return bRet; +} + +sal_Bool FStatHelper::IsDocument( const UniString& rURL ) +{ + BOOL bExist = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + bExist = aTestContent.isDocument(); + } + catch(...) + { + } + return bExist; +} + +sal_Bool FStatHelper::IsFolder( const UniString& rURL ) +{ + BOOL bExist = FALSE; + try + { + ::ucbhelper::Content aTestContent( rURL, + uno::Reference< XCommandEnvironment > ()); + bExist = aTestContent.isFolder(); + } + catch(...) + { + } + return bExist; +} + diff --git a/svl/source/misc/inethist.cxx b/svl/source/misc/inethist.cxx new file mode 100644 index 000000000000..290312c0efd8 --- /dev/null +++ b/svl/source/misc/inethist.cxx @@ -0,0 +1,545 @@ +/************************************************************************* + * + * 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: inethist.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/inethist.hxx> + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif +#include "rtl/instance.hxx" +#include "rtl/crc.h" +#include "rtl/memory.h" +#include <tools/solar.h> +#include <tools/debug.hxx> +#include <tools/string.hxx> +#include <tools/urlobj.hxx> + +/*======================================================================== + * + * INetURLHistory internals. + * + *======================================================================*/ +#define INETHIST_DEF_FTP_PORT 21 +#define INETHIST_DEF_HTTP_PORT 80 +#define INETHIST_DEF_HTTPS_PORT 443 + +#define INETHIST_SIZE_LIMIT 1024 +#define INETHIST_MAGIC_HEAD 0x484D4849UL + +/* + * INetURLHistoryHint implementation. + */ +IMPL_PTRHINT (INetURLHistoryHint, const INetURLObject); + +/*======================================================================== + * + * INetURLHistory_Impl interface. + * + *======================================================================*/ +class INetURLHistory_Impl +{ + /** head_entry. + */ + struct head_entry + { + /** Representation. + */ + UINT32 m_nMagic; + UINT16 m_nNext; + UINT16 m_nMBZ; + + /** Initialization. + */ + void initialize (void) + { + m_nMagic = INETHIST_MAGIC_HEAD; + m_nNext = 0; + m_nMBZ = 0; + } + }; + + /** hash_entry. + */ + struct hash_entry + { + /** Representation. + */ + UINT32 m_nHash; + UINT16 m_nLru; + UINT16 m_nMBZ; + + /** Initialization. + */ + void initialize (UINT16 nLru, UINT32 nHash = 0) + { + m_nHash = nHash; + m_nLru = nLru; + m_nMBZ = 0; + } + + /** Comparison. + */ + BOOL operator== (const hash_entry &rOther) const + { + return (m_nHash == rOther.m_nHash); + } + BOOL operator< (const hash_entry &rOther) const + { + return (m_nHash < rOther.m_nHash); + } + + BOOL operator== (UINT32 nHash) const + { + return (m_nHash == nHash); + } + BOOL operator< (UINT32 nHash) const + { + return (m_nHash < nHash); + } + }; + + /** lru_entry. + */ + struct lru_entry + { + /** Representation. + */ + UINT32 m_nHash; + UINT16 m_nNext; + UINT16 m_nPrev; + + /** Initialization. + */ + void initialize (UINT16 nThis, UINT32 nHash = 0) + { + m_nHash = nHash; + m_nNext = nThis; + m_nPrev = nThis; + } + }; + + /** Representation. + */ + head_entry m_aHead; + hash_entry m_pHash[INETHIST_SIZE_LIMIT]; + lru_entry m_pList[INETHIST_SIZE_LIMIT]; + + /** Initialization. + */ + void initialize (void); + + void downheap (hash_entry a[], UINT16 n, UINT16 k); + void heapsort (hash_entry a[], UINT16 n); + + /** capacity. + */ + UINT16 capacity (void) const + { + return (UINT16)(INETHIST_SIZE_LIMIT); + } + + /** crc32. + */ + UINT32 crc32 (UniString const & rData) const + { + return rtl_crc32 (0, rData.GetBuffer(), rData.Len() * sizeof(sal_Unicode)); + } + + /** find. + */ + UINT16 find (UINT32 nHash) const; + + /** move. + */ + void move (UINT16 nSI, UINT16 nDI); + + /** backlink. + */ + void backlink (UINT16 nThis, UINT16 nTail) + { + register lru_entry &rThis = m_pList[nThis]; + register lru_entry &rTail = m_pList[nTail]; + + rTail.m_nNext = nThis; + rTail.m_nPrev = rThis.m_nPrev; + rThis.m_nPrev = nTail; + m_pList[rTail.m_nPrev].m_nNext = nTail; + } + + /** unlink. + */ + void unlink (UINT16 nThis) + { + register lru_entry &rThis = m_pList[nThis]; + + m_pList[rThis.m_nPrev].m_nNext = rThis.m_nNext; + m_pList[rThis.m_nNext].m_nPrev = rThis.m_nPrev; + rThis.m_nNext = nThis; + rThis.m_nPrev = nThis; + } + + /** Not implemented. + */ + INetURLHistory_Impl (const INetURLHistory_Impl&); + INetURLHistory_Impl& operator= (const INetURLHistory_Impl&); + +public: + INetURLHistory_Impl (void); + ~INetURLHistory_Impl (void); + + /** putUrl/queryUrl. + */ + void putUrl (const String &rUrl); + BOOL queryUrl (const String &rUrl); +}; + +/*======================================================================== + * + * INetURLHistory_Impl implementation. + * + *======================================================================*/ +/* + * INetURLHistory_Impl. + */ +INetURLHistory_Impl::INetURLHistory_Impl (void) +{ + initialize(); +} + +/* + * ~INetURLHistory_Impl. + */ +INetURLHistory_Impl::~INetURLHistory_Impl (void) +{ +} + +/* + * initialize. + */ +void INetURLHistory_Impl::initialize (void) +{ + m_aHead.initialize(); + + USHORT i, n = capacity(); + for (i = 0; i < n; i++) + m_pHash[i].initialize(i); + for (i = 0; i < n; i++) + m_pList[i].initialize(i); + for (i = 1; i < n; i++) + backlink (m_aHead.m_nNext, i); +} + +/* + * downheap. + */ +void INetURLHistory_Impl::downheap (hash_entry a[], UINT16 n, UINT16 k) +{ + hash_entry h = a[k]; + while (k < n / 2) + { + UINT16 i = k + k + 1; + if (((i + 1) < n) && (a[i] < a[i + 1])) i++; + if (!(h < a[i])) break; + a[k] = a[i]; + k = i; + } + a[k] = h; +} + +/* + * heapsort. + */ +void INetURLHistory_Impl::heapsort (hash_entry a[], UINT16 n) +{ + hash_entry h; + + for (UINT16 k = (n - 1) / 2 + 1; k > 0; k--) + downheap (a, n, k - 1); + + while (n > 0) + { + h = a[0 ]; + a[0 ] = a[n - 1]; + a[n - 1] = h; + downheap (a, --n, 0); + } +} + +/* + * find. + */ +UINT16 INetURLHistory_Impl::find (UINT32 nHash) const +{ + UINT16 l = 0; + UINT16 r = capacity() - 1; + UINT16 c = capacity(); + + while ((l < r) && (r < c)) + { + UINT16 m = (l + r) / 2; + if (m_pHash[m] == nHash) + return m; + + if (m_pHash[m] < nHash) + l = m + 1; + else + r = m - 1; + } + return l; +} + +/* + * move. + */ +void INetURLHistory_Impl::move (UINT16 nSI, UINT16 nDI) +{ + hash_entry e = m_pHash[nSI]; + if (nSI < nDI) + { + // shift left. + rtl_moveMemory ( + &m_pHash[nSI ], + &m_pHash[nSI + 1], + (nDI - nSI) * sizeof(hash_entry)); + } + if (nSI > nDI) + { + // shift right. + rtl_moveMemory ( + &m_pHash[nDI + 1], + &m_pHash[nDI ], + (nSI - nDI) * sizeof(hash_entry)); + } + m_pHash[nDI] = e; +} + +/* + * putUrl. + */ +void INetURLHistory_Impl::putUrl (const String &rUrl) +{ + UINT32 h = crc32 (rUrl); + UINT16 k = find (h); + if ((k < capacity()) && (m_pHash[k] == h)) + { + // Cache hit. + UINT16 nMRU = m_pHash[k].m_nLru; + if (nMRU != m_aHead.m_nNext) + { + // Update LRU chain. + unlink (nMRU); + backlink (m_aHead.m_nNext, nMRU); + + // Rotate LRU chain. + m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; + } + } + else + { + // Cache miss. Obtain least recently used. + UINT16 nLRU = m_pList[m_aHead.m_nNext].m_nPrev; + + UINT16 nSI = find (m_pList[nLRU].m_nHash); + if (!(nLRU == m_pHash[nSI].m_nLru)) + { + // Update LRU chain. + nLRU = m_pHash[nSI].m_nLru; + unlink (nLRU); + backlink (m_aHead.m_nNext, nLRU); + } + + // Rotate LRU chain. + m_aHead.m_nNext = m_pList[m_aHead.m_nNext].m_nPrev; + + // Check source and destination. + UINT16 nDI = std::min (k, UINT16(capacity() - 1)); + if (nSI < nDI) + { + if (!(m_pHash[nDI] < h)) + nDI -= 1; + } + if (nDI < nSI) + { + if (m_pHash[nDI] < h) + nDI += 1; + } + + // Assign data. + m_pList[m_aHead.m_nNext].m_nHash = m_pHash[nSI].m_nHash = h; + move (nSI, nDI); + } +} + +/* + * queryUrl. + */ +BOOL INetURLHistory_Impl::queryUrl (const String &rUrl) +{ + UINT32 h = crc32 (rUrl); + UINT16 k = find (h); + if ((k < capacity()) && (m_pHash[k] == h)) + { + // Cache hit. + return TRUE; + } + else + { + // Cache miss. + return FALSE; + } +} + +/*======================================================================== + * + * INetURLHistory::StaticInstance implementation. + * + *======================================================================*/ +INetURLHistory * INetURLHistory::StaticInstance::operator ()() +{ + static INetURLHistory g_aInstance; + return &g_aInstance; +} + +/*======================================================================== + * + * INetURLHistory implementation. + * + *======================================================================*/ +/* + * INetURLHistory. + */ +INetURLHistory::INetURLHistory() : m_pImpl (new INetURLHistory_Impl()) +{ +} + +/* + * ~INetURLHistory. + */ +INetURLHistory::~INetURLHistory() +{ + DELETEZ (m_pImpl); +} + +/* + * GetOrCreate. + */ +INetURLHistory* INetURLHistory::GetOrCreate() +{ + return rtl_Instance< + INetURLHistory, StaticInstance, + osl::MutexGuard, osl::GetGlobalMutex >::create ( + StaticInstance(), osl::GetGlobalMutex()); +} + +/* + * NormalizeUrl_Impl. + */ +void INetURLHistory::NormalizeUrl_Impl (INetURLObject &rUrl) +{ + switch (rUrl.GetProtocol()) + { + case INET_PROT_FILE: + if (!rUrl.IsCaseSensitive()) + { + String aPath (rUrl.GetURLPath(INetURLObject::NO_DECODE)); + aPath.ToLowerAscii(); + rUrl.SetURLPath (aPath, INetURLObject::NOT_CANONIC); + } + break; + + case INET_PROT_FTP: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_FTP_PORT); + break; + + case INET_PROT_HTTP: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_HTTP_PORT); + if (!rUrl.HasURLPath()) + rUrl.SetURLPath ("/"); + break; + + case INET_PROT_HTTPS: + if (!rUrl.HasPort()) + rUrl.SetPort (INETHIST_DEF_HTTPS_PORT); + if (!rUrl.HasURLPath()) + rUrl.SetURLPath ("/"); + break; + + default: + break; + } +} + +/* + * PutUrl_Impl. + */ +void INetURLHistory::PutUrl_Impl (const INetURLObject &rUrl) +{ + DBG_ASSERT (m_pImpl, "PutUrl_Impl(): no Implementation"); + if (m_pImpl) + { + INetURLObject aHistUrl (rUrl); + NormalizeUrl_Impl (aHistUrl); + + m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + Broadcast (INetURLHistoryHint (&rUrl)); + + if (aHistUrl.HasMark()) + { + aHistUrl.SetURL (aHistUrl.GetURLNoMark(INetURLObject::NO_DECODE), + INetURLObject::NOT_CANONIC); + + m_pImpl->putUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + Broadcast (INetURLHistoryHint (&aHistUrl)); + } + } +} + +/* + * QueryUrl_Impl. + */ +BOOL INetURLHistory::QueryUrl_Impl (const INetURLObject &rUrl) +{ + DBG_ASSERT (m_pImpl, "QueryUrl_Impl(): no Implementation"); + if (m_pImpl) + { + INetURLObject aHistUrl (rUrl); + NormalizeUrl_Impl (aHistUrl); + + return m_pImpl->queryUrl (aHistUrl.GetMainURL(INetURLObject::NO_DECODE)); + } + return FALSE; +} + + diff --git a/svl/source/misc/inettype.cxx b/svl/source/misc/inettype.cxx new file mode 100644 index 000000000000..47183be1d7b2 --- /dev/null +++ b/svl/source/misc/inettype.cxx @@ -0,0 +1,1348 @@ +/************************************************************************* + * + * 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: inettype.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <tools/table.hxx> +#include <tools/wldcrd.hxx> +#include <svl/inettype.hxx> +#include <svl/svldata.hxx> +#ifndef _SVTOOLS_HRC +#include <svl/svtools.hrc> +#endif + +#ifndef _SVSTDARR_STRINGSSORT_DECL +#define _SVSTDARR_STRINGSSORT +#include <svl/svstdarr.hxx> +#undef _SVSTDARR_STRINGSSORT +#endif + +namespace unnamed_svl_inettype {} +using namespace unnamed_svl_inettype; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_inettype { + +//============================================================================ +struct MediaTypeEntry +{ + sal_Char const * m_pTypeName; + INetContentType m_eTypeID; + sal_Char const * m_pExtension; +}; + +//============================================================================ +struct TypeIDMapEntry +{ + UniString m_aTypeName; + UniString m_aPresentation; + UniString m_aSystemFileType; +}; + +//============================================================================ +struct TypeNameMapEntry: public UniString +{ + UniString m_aExtension; + INetContentType m_eTypeID; + + TypeNameMapEntry(const UniString & rType): + UniString(rType), m_eTypeID(CONTENT_TYPE_UNKNOWN) {} +}; + +//============================================================================ +struct ExtensionMapEntry: public UniString +{ + INetContentType m_eTypeID; + + ExtensionMapEntry(const UniString & rExt): + UniString(rExt), m_eTypeID(CONTENT_TYPE_UNKNOWN) {} +}; + +//============================================================================ +class Registration +{ + static Registration * m_pRegistration; + + Table m_aTypeIDMap; // map TypeID to TypeName, Presentation + SvStringsSort m_aTypeNameMap; // map TypeName to TypeID, Extension + SvStringsSort m_aExtensionMap; // map Extension to TypeID + sal_uInt32 m_nNextDynamicID; + +public: + Registration(): m_nNextDynamicID(CONTENT_TYPE_LAST + 1) {} + + ~Registration(); + + static inline void deinitialize(); + + static inline TypeIDMapEntry * getEntry(INetContentType eTypeID); + + static TypeNameMapEntry * getExtensionEntry(UniString const & rTypeName); + + static INetContentType RegisterContentType(UniString const & rTypeName, + UniString const & + rPresentation, + UniString const * pExtension, + UniString const * + pSystemFileType); + + static INetContentType GetContentType(UniString const & rTypeName); + + static UniString GetContentType(INetContentType eTypeID); + + static UniString GetPresentation(INetContentType eTypeID); + + static UniString GetExtension(const UniString & rTypeName); + + static INetContentType GetContentType4Extension(UniString const & + rExtension); + +}; + +// static +inline void Registration::deinitialize() +{ + delete m_pRegistration; + m_pRegistration = 0; +} + +// static +inline TypeIDMapEntry * Registration::getEntry(INetContentType eTypeID) +{ + return + m_pRegistration ? + static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)) : + 0; +} + +//============================================================================ +MediaTypeEntry const * seekEntry(UniString const & rTypeName, + MediaTypeEntry const * pMap, sal_Size nSize); + +//============================================================================ +/** A mapping from type names to type ids and extensions. Sorted by type + name. + */ +MediaTypeEntry const aStaticTypeNameMap[CONTENT_TYPE_LAST + 1] + = { { " ", CONTENT_TYPE_UNKNOWN, "" }, + { CONTENT_TYPE_STR_X_CNT_DOCUMENT, CONTENT_TYPE_X_CNT_DOCUMENT, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSBOX, CONTENT_TYPE_X_CNT_FSYSBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDROM_VOLUME, + CONTENT_TYPE_X_CNT_CDROM_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_DISK_35, CONTENT_TYPE_X_CNT_DISK_35, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_DISK_525, CONTENT_TYPE_X_CNT_DISK_525, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSFILE, CONTENT_TYPE_X_CNT_FSYSFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FIXED_VOLUME, + CONTENT_TYPE_X_CNT_FIXED_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSFOLDER, CONTENT_TYPE_X_CNT_FSYSFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_RAM_VOLUME, CONTENT_TYPE_X_CNT_RAM_VOLUME, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_REMOTE_VOLUME, + CONTENT_TYPE_X_CNT_REMOTE_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_REMOVEABLE_VOLUME, + CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFILE, + CONTENT_TYPE_X_CNT_FSYSSPECIALFILE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSSPECIALFOLDER, + CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TAPEDRIVE, CONTENT_TYPE_X_CNT_TAPEDRIVE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FSYSURLFILE, CONTENT_TYPE_X_CNT_FSYSURLFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPBOX, CONTENT_TYPE_X_CNT_FTPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPFILE, CONTENT_TYPE_X_CNT_FTPFILE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPFOLDER, CONTENT_TYPE_X_CNT_FTPFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_FTPLINK, CONTENT_TYPE_X_CNT_FTPLINK, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_HTTPBOX, CONTENT_TYPE_X_CNT_HTTPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_HTTPFILE, CONTENT_TYPE_X_CNT_HTTPFILE, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_IMAPBOX, CONTENT_TYPE_X_CNT_IMAPBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_IMAPFOLDER, CONTENT_TYPE_X_CNT_IMAPFOLDER, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_MESSAGE, CONTENT_TYPE_X_CNT_MESSAGE, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_NEWSBOX, CONTENT_TYPE_X_CNT_NEWSBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_NEWSGROUP, CONTENT_TYPE_X_CNT_NEWSGROUP, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_OUTBOX, CONTENT_TYPE_X_CNT_OUTBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_POP3BOX, CONTENT_TYPE_X_CNT_POP3BOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_PUBLISHBOX, CONTENT_TYPE_X_CNT_PUBLISHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SEARCHBOX, CONTENT_TYPE_X_CNT_SEARCHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SEPARATOR, CONTENT_TYPE_X_CNT_SEPARATOR, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_BOOKMARK, CONTENT_TYPE_X_CNT_BOOKMARK, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_SUBSCRIBEBOX, + CONTENT_TYPE_X_CNT_SUBSCRIBEBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDF, CONTENT_TYPE_X_CNT_CDF, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDFITEM, CONTENT_TYPE_X_CNT_CDFITEM, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_CDFSUB, CONTENT_TYPE_X_CNT_CDFSUB, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_STARCHANNEL, CONTENT_TYPE_X_CNT_STARCHANNEL, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TRASHBOX, CONTENT_TYPE_X_CNT_TRASHBOX, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_TRASH, CONTENT_TYPE_X_CNT_TRASH, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBBOARD, CONTENT_TYPE_X_CNT_VIMBBOARD, + "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBBOARDBOX, + CONTENT_TYPE_X_CNT_VIMBBOARDBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMBOX, CONTENT_TYPE_X_CNT_VIMBOX, "tmp" }, + { CONTENT_TYPE_STR_X_CNT_VIMINBOX, CONTENT_TYPE_X_CNT_VIMINBOX, + "tmp" }, + { CONTENT_TYPE_STR_APP_OCTSTREAM, CONTENT_TYPE_APP_OCTSTREAM, "tmp" }, + { CONTENT_TYPE_STR_APP_PDF, CONTENT_TYPE_APP_PDF, "pdf" }, + { CONTENT_TYPE_STR_APP_RTF, CONTENT_TYPE_APP_RTF, "rtf" }, + { CONTENT_TYPE_STR_APP_VND_CALC, CONTENT_TYPE_APP_VND_CALC, "sdc" }, + { CONTENT_TYPE_STR_APP_VND_CHART, CONTENT_TYPE_APP_VND_CHART, "sds" }, + { CONTENT_TYPE_STR_APP_VND_DRAW, CONTENT_TYPE_APP_VND_DRAW, "sda" }, + { CONTENT_TYPE_STR_APP_VND_IMAGE, CONTENT_TYPE_APP_VND_IMAGE, "sim" }, + { CONTENT_TYPE_STR_APP_VND_IMPRESS, CONTENT_TYPE_APP_VND_IMPRESS, + "sdd" }, + { CONTENT_TYPE_STR_APP_VND_IMPRESSPACKED, + CONTENT_TYPE_APP_VND_IMPRESSPACKED, "sdp" }, + { CONTENT_TYPE_STR_APP_VND_MAIL, CONTENT_TYPE_APP_VND_MAIL, "sdm" }, + { CONTENT_TYPE_STR_APP_VND_MATH, CONTENT_TYPE_APP_VND_MATH, "smf" }, + { CONTENT_TYPE_STR_APP_VND_NEWS, CONTENT_TYPE_APP_VND_NEWS, "sdm" }, + { CONTENT_TYPE_STR_APP_VND_OUTTRAY, CONTENT_TYPE_APP_VND_OUTTRAY, + "sdm" }, + { CONTENT_TYPE_STR_APP_VND_TEMPLATE, CONTENT_TYPE_APP_VND_TEMPLATE, + "vor" }, + { CONTENT_TYPE_STR_APP_VND_WRITER, CONTENT_TYPE_APP_VND_WRITER, + "sdw" }, + { CONTENT_TYPE_STR_APP_VND_WRITER_GLOBAL, + CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "sgl" }, + { CONTENT_TYPE_STR_APP_VND_WRITER_WEB, + CONTENT_TYPE_APP_VND_WRITER_WEB, "htm" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_CALC, CONTENT_TYPE_APP_VND_SUN_XML_CALC, "sxc" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_CHART, CONTENT_TYPE_APP_VND_SUN_XML_CHART, "sxs" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_DRAW, CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "sxd" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESS, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "sxi" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_IMPRESSPACKED, CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "sxp" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_MATH, CONTENT_TYPE_APP_VND_SUN_XML_MATH, "sxm" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER, CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "sxw" }, + { CONTENT_TYPE_STR_APP_VND_SUN_XML_WRITER_GLOBAL, CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "sxg" }, + { CONTENT_TYPE_STR_APP_FRAMESET, CONTENT_TYPE_APP_FRAMESET, "sfs" }, + { CONTENT_TYPE_STR_APP_GALLERY, CONTENT_TYPE_APP_GALLERY, "gal" }, + { CONTENT_TYPE_STR_APP_GALLERY_THEME, CONTENT_TYPE_APP_GALLERY_THEME, + "thm" }, + { CONTENT_TYPE_STR_APP_JAR, CONTENT_TYPE_APP_JAR, "jar" }, + { CONTENT_TYPE_STR_APP_MACRO, CONTENT_TYPE_APP_MACRO, "tmp" }, + { CONTENT_TYPE_STR_APP_MSEXCEL, CONTENT_TYPE_APP_MSEXCEL, "xls" }, + { CONTENT_TYPE_STR_APP_MSEXCEL_TEMPL, CONTENT_TYPE_APP_MSEXCEL_TEMPL, + "xlt" }, + { CONTENT_TYPE_STR_APP_MSPPOINT, CONTENT_TYPE_APP_MSPPOINT, "ppt" }, + { CONTENT_TYPE_STR_APP_MSPPOINT_TEMPL, + CONTENT_TYPE_APP_MSPPOINT_TEMPL, "pot" }, + { CONTENT_TYPE_STR_APP_MSWORD, CONTENT_TYPE_APP_MSWORD, "doc" }, + { CONTENT_TYPE_STR_APP_MSWORD_TEMPL, CONTENT_TYPE_APP_MSWORD_TEMPL, + "dot" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_CMB, CONTENT_TYPE_APP_SCHEDULE, + "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_EVT, CONTENT_TYPE_APP_SCHEDULE_EVT, + "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_FEVT, + CONTENT_TYPE_APP_SCHEDULE_FORM_EVT, "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_FTASK, + CONTENT_TYPE_APP_SCHEDULE_FORM_TASK, "tmp" }, + { CONTENT_TYPE_STR_APP_SCHEDULE_TASK, CONTENT_TYPE_APP_SCHEDULE_TASK, + "tmp" }, + { CONTENT_TYPE_STR_APP_STARCALC, CONTENT_TYPE_APP_STARCALC, "sdc" }, + { CONTENT_TYPE_STR_APP_STARCHART, CONTENT_TYPE_APP_STARCHART, "sds" }, + { CONTENT_TYPE_STR_APP_STARDRAW, CONTENT_TYPE_APP_STARDRAW, "sda" }, + { CONTENT_TYPE_STR_APP_STARHELP, CONTENT_TYPE_APP_STARHELP, "svh" }, + { CONTENT_TYPE_STR_APP_STARIMAGE, CONTENT_TYPE_APP_STARIMAGE, "sim" }, + { CONTENT_TYPE_STR_APP_STARIMPRESS, CONTENT_TYPE_APP_STARIMPRESS, + "sdd" }, + { CONTENT_TYPE_STR_APP_STARMAIL_SDM, CONTENT_TYPE_APP_STARMAIL_SDM, + "sdm" }, + { CONTENT_TYPE_STR_APP_STARMAIL_SMD, CONTENT_TYPE_APP_STARMAIL_SMD, + "smd" }, + { CONTENT_TYPE_STR_APP_STARMATH, CONTENT_TYPE_APP_STARMATH, "smf" }, + { CONTENT_TYPE_STR_APP_STARWRITER, CONTENT_TYPE_APP_STARWRITER, + "sdw" }, + { CONTENT_TYPE_STR_APP_STARWRITER_GLOB, + CONTENT_TYPE_APP_STARWRITER_GLOB, "sgl" }, + { CONTENT_TYPE_STR_APP_CDE_CALENDAR_APP, + CONTENT_TYPE_APP_CDE_CALENDAR_APP, "appt" }, + { CONTENT_TYPE_STR_APP_ZIP, CONTENT_TYPE_APP_ZIP, "zip" }, + { CONTENT_TYPE_STR_AUDIO_AIFF, CONTENT_TYPE_AUDIO_AIFF, "aif" }, + { CONTENT_TYPE_STR_AUDIO_BASIC, CONTENT_TYPE_AUDIO_BASIC, "au" }, + { CONTENT_TYPE_STR_AUDIO_MIDI, CONTENT_TYPE_AUDIO_MIDI, "mid" }, + { CONTENT_TYPE_STR_AUDIO_WAV, CONTENT_TYPE_AUDIO_WAV, "wav" }, + { CONTENT_TYPE_STR_IMAGE_GENERIC, CONTENT_TYPE_IMAGE_GENERIC, "tmp" }, + { CONTENT_TYPE_STR_IMAGE_GIF, CONTENT_TYPE_IMAGE_GIF, "gif" }, + { CONTENT_TYPE_STR_IMAGE_JPEG, CONTENT_TYPE_IMAGE_JPEG, "jpg" }, + { CONTENT_TYPE_STR_IMAGE_PCX, CONTENT_TYPE_IMAGE_PCX, "pcx" }, + { CONTENT_TYPE_STR_IMAGE_PNG, CONTENT_TYPE_IMAGE_PNG, "png" }, + { CONTENT_TYPE_STR_IMAGE_TIFF, CONTENT_TYPE_IMAGE_TIFF, "tif" }, + { CONTENT_TYPE_STR_IMAGE_BMP, CONTENT_TYPE_IMAGE_BMP, "bmp" }, + { CONTENT_TYPE_STR_INET_MSG_RFC822, CONTENT_TYPE_INET_MESSAGE_RFC822, + "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_ALTERNATIVE, + CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_DIGEST, + CONTENT_TYPE_INET_MULTIPART_DIGEST, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_MIXED, + CONTENT_TYPE_INET_MULTIPART_MIXED, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_PARALLEL, + CONTENT_TYPE_INET_MULTIPART_PARALLEL, "tmp" }, + { CONTENT_TYPE_STR_INET_MULTI_RELATED, + CONTENT_TYPE_INET_MULTIPART_RELATED, "tmp" }, + { CONTENT_TYPE_STR_TEXT_ICALENDAR, CONTENT_TYPE_TEXT_ICALENDAR, + "ics" }, + { CONTENT_TYPE_STR_TEXT_HTML, CONTENT_TYPE_TEXT_HTML, "htm" }, + { CONTENT_TYPE_STR_TEXT_PLAIN, CONTENT_TYPE_TEXT_PLAIN, "txt" }, + { CONTENT_TYPE_STR_TEXT_XMLICALENDAR, CONTENT_TYPE_TEXT_XMLICALENDAR, + "xcs" }, + { CONTENT_TYPE_STR_TEXT_URL, CONTENT_TYPE_TEXT_URL, "url" }, + { CONTENT_TYPE_STR_TEXT_VCALENDAR, CONTENT_TYPE_TEXT_VCALENDAR, + "vcs" }, + { CONTENT_TYPE_STR_TEXT_VCARD, CONTENT_TYPE_TEXT_VCARD, "vcf" }, + { CONTENT_TYPE_STR_VIDEO_VDO, CONTENT_TYPE_VIDEO_VDO, "vdo" }, + { CONTENT_TYPE_STR_VIDEO_MSVIDEO, CONTENT_TYPE_VIDEO_MSVIDEO, "avi" }, + { CONTENT_TYPE_STR_X_STARMAIL, CONTENT_TYPE_X_STARMAIL, "smd" }, + { CONTENT_TYPE_STR_X_VRML, CONTENT_TYPE_X_VRML, "wrl" } +}; + +//============================================================================ +/** A mapping from type IDs to presentation resource IDs. Sorted by type ID. + */ +USHORT const aStaticResourceIDMap[CONTENT_TYPE_LAST + 1] + = { STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_UNKNOWN + STR_SVT_MIMETYPE_APP_OCTSTREAM, // CONTENT_TYPE_APP_OCTSTREAM + STR_SVT_MIMETYPE_APP_PDF, // CONTENT_TYPE_APP_PDF + STR_SVT_MIMETYPE_APP_RTF, // CONTENT_TYPE_APP_RTF + STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD + STR_SVT_MIMETYPE_APP_MSWORD, // CONTENT_TYPE_APP_MSWORD_TEMPL //@todo new presentation string? + STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_STARCALC + STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_STARCHART + STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_STARDRAW + STR_SVT_MIMETYPE_APP_STARHELP, // CONTENT_TYPE_APP_STARHELP + STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_STARIMAGE + STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_STARIMPRESS + STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_STARMATH + STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_STARWRITER + STR_SVT_MIMETYPE_APP_ZIP, // CONTENT_TYPE_APP_ZIP + STR_SVT_MIMETYPE_AUDIO_AIFF, // CONTENT_TYPE_AUDIO_AIFF + STR_SVT_MIMETYPE_AUDIO_BASIC, // CONTENT_TYPE_AUDIO_BASIC + STR_SVT_MIMETYPE_AUDIO_MIDI, // CONTENT_TYPE_AUDIO_MIDI + STR_SVT_MIMETYPE_AUDIO_WAV, // CONTENT_TYPE_AUDIO_WAV + STR_SVT_MIMETYPE_IMAGE_GIF, // CONTENT_TYPE_IMAGE_GIF + STR_SVT_MIMETYPE_IMAGE_JPEG, // CONTENT_TYPE_IMAGE_JPEG + STR_SVT_MIMETYPE_IMAGE_PCX, // CONTENT_TYPE_IMAGE_PCX + STR_SVT_MIMETYPE_IMAGE_PNG, // CONTENT_TYPE_IMAGE_PNG + STR_SVT_MIMETYPE_IMAGE_TIFF, // CONTENT_TYPE_IMAGE_TIFF + STR_SVT_MIMETYPE_IMAGE_BMP, // CONTENT_TYPE_IMAGE_BMP + STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_TEXT_HTML + STR_SVT_MIMETYPE_TEXT_PLAIN, // CONTENT_TYPE_TEXT_PLAIN + STR_SVT_MIMETYPE_TEXT_URL, // CONTENT_TYPE_TEXT_URL + STR_SVT_MIMETYPE_TEXT_VCARD, // CONTENT_TYPE_TEXT_VCARD + STR_SVT_MIMETYPE_VIDEO_VDO, // CONTENT_TYPE_VIDEO_VDO + STR_SVT_MIMETYPE_VIDEO_MSVIDEO, // CONTENT_TYPE_VIDEO_MSVIDEO + STR_SVT_MIMETYPE_CNT_MSG, // CONTENT_TYPE_X_CNT_MESSAGE + STR_SVT_MIMETYPE_CNT_DOCUMENT, // CONTENT_TYPE_X_CNT_DOCUMENT + STR_SVT_MIMETYPE_CNT_POP3BOX, // CONTENT_TYPE_X_CNT_POP3BOX + STR_SVT_MIMETYPE_CNT_IMAPBOX, // CONTENT_TYPE_X_CNT_IMAPBOX + STR_SVT_MIMETYPE_CNT_IMAPFLD, // CONTENT_TYPE_X_CNT_IMAPFOLDER + STR_SVT_MIMETYPE_CNT_VIMBOX, // CONTENT_TYPE_X_CNT_VIMBOX + STR_SVT_MIMETYPE_CNT_VIMINBOX, // CONTENT_TYPE_X_CNT_VIMINBOX + STR_SVT_MIMETYPE_CNT_BBBOX, // CONTENT_TYPE_X_CNT_VIMBBOARDBOX + STR_SVT_MIMETYPE_CNT_VIM_BB, // CONTENT_TYPE_X_CNT_VIMBBOARD + STR_SVT_MIMETYPE_CNT_NEWSBOX, // CONTENT_TYPE_X_CNT_NEWSBOX + STR_SVT_MIMETYPE_CNT_NEWSGRP, // CONTENT_TYPE_X_CNT_NEWSGROUP + STR_SVT_MIMETYPE_CNT_OUTBOX, // CONTENT_TYPE_X_CNT_OUTBOX + STR_SVT_MIMETYPE_CNT_FTPBOX, // CONTENT_TYPE_X_CNT_FTPBOX + STR_SVT_MIMETYPE_CNT_FTPFLD, // CONTENT_TYPE_X_CNT_FTPFOLDER + STR_SVT_MIMETYPE_CNT_FTPFILE, // CONTENT_TYPE_X_CNT_FTPFILE + STR_SVT_MIMETYPE_CNT_FTPLINK, // CONTENT_TYPE_X_CNT_FTPLINK + STR_SVT_MIMETYPE_CNT_HTTPBOX, // CONTENT_TYPE_X_CNT_HTTPBOX + STR_SVT_MIMETYPE_CNT_FSYSBOX, // CONTENT_TYPE_X_CNT_FSYSBOX + STR_SVT_MIMETYPE_CNT_FSYSFLD, // CONTENT_TYPE_X_CNT_FSYSFOLDER + STR_SVT_MIMETYPE_CNT_FSYSFILE, // CONTENT_TYPE_X_CNT_FSYSFILE + STR_SVT_MIMETYPE_CNT_FSYSURLFILE, // CONTENT_TYPE_X_CNT_FSYSURLFILE + STR_SVT_MIMETYPE_CNT_PUBLBOX, // CONTENT_TYPE_X_CNT_PUBLISHBOX + STR_SVT_MIMETYPE_CNT_SRCHBOX, // CONTENT_TYPE_X_CNT_SEARCHBOX + STR_SVT_MIMETYPE_CNT_SUBSCRBOX, // CONTENT_TYPE_X_CNT_SUBSCRIBEBOX + STR_SVT_MIMETYPE_CNT_BOOKMARK, // CONTENT_TYPE_X_CNT_BOOKMARK + STR_SVT_MIMETYPE_CNT_CDF, // CONTENT_TYPE_X_CNT_CDF + STR_SVT_MIMETYPE_CNT_CDFSUB, // CONTENT_TYPE_X_CNT_CDFSUB + STR_SVT_MIMETYPE_CNT_CDFITEM, // CONTENT_TYPE_X_CNT_CDFITEM + STR_SVT_MIMETYPE_CNT_TRASHBOX, // CONTENT_TYPE_X_CNT_TRASHBOX + STR_SVT_MIMETYPE_CNT_TRASH, // CONTENT_TYPE_X_CNT_TRASH + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_X_STARMAIL + STR_SVT_MIMETYPE_X_VRML, // CONTENT_TYPE_X_VRML + STR_SVT_MIMETYPE_CNT_REMOV_VOL, + // CONTENT_TYPE_X_CNT_REMOVEABLE_VOLUME + STR_SVT_MIMETYPE_CNT_FIX_VOL, // CONTENT_TYPE_X_CNT_FIXED_VOLUME + STR_SVT_MIMETYPE_CNT_REM_VOL, // CONTENT_TYPE_X_CNT_REMOTE_VOLUME + STR_SVT_MIMETYPE_CNT_RAM_VOL, // CONTENT_TYPE_X_CNT_RAM_VOLUME + STR_SVT_MIMETYPE_CNT_CDROM, // CONTENT_TYPE_X_CNT_CDROM_VOLUME + STR_SVT_MIMETYPE_CNT_DISK_35, // CONTENT_TYPE_X_CNT_DISK_35 + STR_SVT_MIMETYPE_CNT_DISK_525, // CONTENT_TYPE_X_CNT_DISK_525 + STR_SVT_MIMETYPE_CNT_TAPEDRIVE, // CONTENT_TYPE_X_CNT_TAPEDRIVE + STR_SVT_MIMETYPE_APP_GAL, // CONTENT_TYPE_APP_GALLERY + STR_SVT_MIMETYPE_APP_GAL_THEME, // CONTENT_TYPE_APP_GALLERY_THEME + STR_SVT_MIMETYPE_CNT_STARCHANNEL, // CONTENT_TYPE_X_CNT_STARCHANNEL + STR_SVT_MIMETYPE_CNT_SEPARATOR, // CONTENT_TYPE_X_CNT_SEPARATOR + STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_STARWRITER_GLOB + STR_SVT_MIMETYPE_APP_SDM, // CONTENT_TYPE_APP_STARMAIL_SDM + STR_SVT_MIMETYPE_APP_SMD, // CONTENT_TYPE_APP_STARMAIL_SMD + STR_SVT_MIMETYPE_APP_STARCALC, // CONTENT_TYPE_APP_VND_CALC + STR_SVT_MIMETYPE_APP_STARCHART, // CONTENT_TYPE_APP_VND_CHART + STR_SVT_MIMETYPE_APP_STARDRAW, // CONTENT_TYPE_APP_VND_DRAW + STR_SVT_MIMETYPE_APP_STARIMAGE, // CONTENT_TYPE_APP_VND_IMAGE + STR_SVT_MIMETYPE_APP_STARIMPRESS, // CONTENT_TYPE_APP_VND_IMPRESS + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_MAIL + STR_SVT_MIMETYPE_APP_STARMATH, // CONTENT_TYPE_APP_VND_MATH + STR_SVT_MIMETYPE_APP_STARWRITER, // CONTENT_TYPE_APP_VND_WRITER + STR_SVT_MIMETYPE_APP_STARW_GLOB, // CONTENT_TYPE_APP_VND_WRITER_GLOBAL + STR_SVT_MIMETYPE_APP_STARW_WEB, // CONTENT_TYPE_APP_VND_WRITER_WEB + STR_SVT_MIMETYPE_SCHEDULE, // CONTENT_TYPE_APP_SCHEDULE + STR_SVT_MIMETYPE_SCHEDULE_EVT, // CONTENT_TYPE_APP_SCHEDULE_EVT + STR_SVT_MIMETYPE_SCHEDULE_TASK, // CONTENT_TYPE_APP_SCHEDULE_TASK + STR_SVT_MIMETYPE_SCHEDULE_FEVT, // CONTENT_TYPE_APP_SCHEDULE_FORM_EVT + STR_SVT_MIMETYPE_SCHEDULE_FTASK, + // CONTENT_TYPE_APP_SCHEDULE_FORM_TASK + STR_SVT_MIMETYPE_FRAMESET, // CONTENT_TYPE_APP_FRAMESET + STR_SVT_MIMETYPE_MACRO, // CONTENT_TYPE_APP_MACRO + STR_SVT_MIMETYPE_CNT_SFSYSFOLDER, + // CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER + STR_SVT_MIMETYPE_CNT_SFSYSFILE, // CONTENT_TYPE_X_CNT_FSYSSPECIALFILE + STR_SVT_MIMETYPE_APP_TEMPLATE, // CONTENT_TYPE_APP_VND_TEMPLATE + STR_SVT_MIMETYPE_IMAGE_GENERIC, // CONTENT_TYPE_IMAGE_GENERIC + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_NEWS + STR_SVT_MIMETYPE_X_STARMAIL, // CONTENT_TYPE_APP_VND_OUTTRAY + STR_SVT_MIMETYPE_TEXT_HTML, // CONTENT_TYPE_X_CNT_HTTPFILE + STR_SVT_MIMETYPE_APP_MSEXCEL, // CONTENT_TYPE_APP_MSEXCEL + STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL, // CONTENT_TYPE_APP_MSEXCEL_TEMPL + STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT + STR_SVT_MIMETYPE_APP_MSPPOINT, // CONTENT_TYPE_APP_MSPPOINT_TEMPL //@todo new presentation string? + STR_SVT_MIMETYPE_TEXT_VCALENDAR, // CONTENT_TYPE_TEXT_VCALENDAR + STR_SVT_MIMETYPE_TEXT_ICALENDAR, // CONTENT_TYPE_TEXT_ICALENDAR + STR_SVT_MIMETYPE_TEXT_XMLICALENDAR, // CONTENT_TYPE_TEXT_XMLICALENDAR + STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP, + // CONTENT_TYPE_APP_CDE_CALENDAR_APP + STR_SVT_MIMETYPE_INET_MSG_RFC822, // CONTENT_TYPE_INET_MESSAGE_RFC822 + STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE, + // CONTENT_TYPE_INET_MULTIPART_ALTERNATIVE + STR_SVT_MIMETYPE_INET_MULTI_DIGEST, + // CONTENT_TYPE_INET_MULTIPART_DIGEST + STR_SVT_MIMETYPE_INET_MULTI_PARALLEL, + // CONTENT_TYPE_INET_MULTIPART_PARALLEL + STR_SVT_MIMETYPE_INET_MULTI_RELATED, + // CONTENT_TYPE_INET_MULTIPART_RELATED + STR_SVT_MIMETYPE_INET_MULTI_MIXED, + // CONTENT_TYPE_INET_MULTIPART_MIXED + STR_SVT_MIMETYPE_APP_IMPRESSPACKED, + // CONTENT_TYPE_APP_VND_IMPRESSPACKED + STR_SVT_MIMETYPE_APP_JAR, // CONTENT_TYPE_APP_JAR + STR_SVT_MIMETYPE_APP_SXWRITER, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER + STR_SVT_MIMETYPE_APP_SXCALC, // CONTENT_TYPE_APP_VND_SUN_XML_CALC + STR_SVT_MIMETYPE_APP_SXIMPRESS, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS + STR_SVT_MIMETYPE_APP_SXDRAW, // CONTENT_TYPE_APP_VND_SUN_XML_DRAW + STR_SVT_MIMETYPE_APP_SXCHART, // CONTENT_TYPE_APP_VND_SUN_XML_CHART + STR_SVT_MIMETYPE_APP_SXMATH, // CONTENT_TYPE_APP_VND_SUN_XML_MATH + STR_SVT_MIMETYPE_APP_SXGLOBAL, // CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL + STR_SVT_MIMETYPE_APP_SXIPACKED, // CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED + }; + +//============================================================================ +/** A mapping from extensions to type IDs. Sorted by extension. + */ +MediaTypeEntry const aStaticExtensionMap[] + = { { "aif", CONTENT_TYPE_AUDIO_AIFF, "" }, + { "aiff", CONTENT_TYPE_AUDIO_AIFF, "" }, + { "appt", CONTENT_TYPE_APP_CDE_CALENDAR_APP, "" }, + { "au", CONTENT_TYPE_AUDIO_BASIC, "" }, + { "avi", CONTENT_TYPE_VIDEO_MSVIDEO, "" }, + { "bmp", CONTENT_TYPE_IMAGE_BMP, "" }, + { "cgm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "doc", CONTENT_TYPE_APP_MSWORD, "" }, + { "dot", CONTENT_TYPE_APP_MSWORD_TEMPL, "" }, + { "dxf", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "eps", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "gal", CONTENT_TYPE_APP_GALLERY, "" }, + { "gif", CONTENT_TYPE_IMAGE_GIF, "" }, + { "htm", CONTENT_TYPE_TEXT_HTML, "" }, + { "html", CONTENT_TYPE_TEXT_HTML, "" }, + { "ics", CONTENT_TYPE_TEXT_ICALENDAR, "" }, + { "jar", CONTENT_TYPE_APP_JAR, "" }, + { "jpeg", CONTENT_TYPE_IMAGE_JPEG, "" }, + { "jpg", CONTENT_TYPE_IMAGE_JPEG, "" }, + { "met", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "mid", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "midi", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "pbm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pcd", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pct", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "pcx", CONTENT_TYPE_IMAGE_PCX, "" }, + { "pdf", CONTENT_TYPE_APP_PDF, "" }, + { "pgm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "png", CONTENT_TYPE_IMAGE_PNG, "" }, + { "pot", CONTENT_TYPE_APP_MSPPOINT_TEMPL, "" }, + { "ppm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "ppt", CONTENT_TYPE_APP_MSPPOINT, "" }, + { "psd", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "ras", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "rtf", CONTENT_TYPE_APP_RTF, "" }, + { "sda", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "sdc", CONTENT_TYPE_APP_VND_CALC, "" }, + { "sdd", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "sdm", CONTENT_TYPE_APP_VND_MAIL, "" }, + { "sdp", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" }, + { "sds", CONTENT_TYPE_APP_VND_CHART, "" }, + { "sdw", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "sd~", CONTENT_TYPE_X_STARMAIL, "" }, + { "sfs", CONTENT_TYPE_APP_FRAMESET , "" }, + { "sgl", CONTENT_TYPE_APP_VND_WRITER_GLOBAL , "" }, + { "sim", CONTENT_TYPE_APP_VND_IMAGE, "" }, + { "smd", CONTENT_TYPE_APP_STARMAIL_SMD, "" }, //CONTENT_TYPE_X_STARMAIL + { "smf", CONTENT_TYPE_APP_VND_MATH, "" }, + { "svh", CONTENT_TYPE_APP_STARHELP, "" }, + { "svm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "sxc", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" }, + { "sxd", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" }, + { "sxg", CONTENT_TYPE_APP_VND_SUN_XML_WRITER_GLOBAL, "" }, + { "sxi", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" }, + { "sxm", CONTENT_TYPE_APP_VND_SUN_XML_MATH, "" }, + { "sxp", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESSPACKED, "" }, + { "sxs", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" }, + { "sxw", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" }, + { "tga", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "thm", CONTENT_TYPE_APP_GALLERY_THEME, "" }, + { "tif", CONTENT_TYPE_IMAGE_TIFF, "" }, + { "tiff", CONTENT_TYPE_IMAGE_TIFF, "" }, + { "txt", CONTENT_TYPE_TEXT_PLAIN, "" }, + { "url", CONTENT_TYPE_TEXT_URL, "" }, + { "vcf", CONTENT_TYPE_TEXT_VCARD, "" }, + { "vcs", CONTENT_TYPE_TEXT_VCALENDAR, "" }, + { "vdo", CONTENT_TYPE_VIDEO_VDO, "" }, + { "vor", CONTENT_TYPE_APP_VND_TEMPLATE, "" }, + { "wav", CONTENT_TYPE_AUDIO_WAV, "" }, + { "wmf", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "wrl", CONTENT_TYPE_X_VRML, "" }, + { "xbm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "xcs", CONTENT_TYPE_TEXT_XMLICALENDAR, "" }, + { "xls", CONTENT_TYPE_APP_MSEXCEL, "" }, + { "xlt", CONTENT_TYPE_APP_MSEXCEL_TEMPL, "" }, + { "xlw", CONTENT_TYPE_APP_MSEXCEL, "" }, + { "xpm", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "zip", CONTENT_TYPE_APP_ZIP, "" } }; + +//============================================================================ +/** A mapping from presentations to type IDs. Sorted by presentations. + */ +MediaTypeEntry const aStaticPresentationMap[] + = { { "Binary Data", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Bitmap", CONTENT_TYPE_IMAGE_BMP, "" }, + { "DOS Command File", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Digital Video", CONTENT_TYPE_VIDEO_MSVIDEO, "" }, + { "Executable", CONTENT_TYPE_APP_OCTSTREAM, "" }, + { "Grafik", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "HTM", CONTENT_TYPE_TEXT_HTML, "" }, + { "HTML", CONTENT_TYPE_TEXT_HTML, "" }, + { "Hypertext", CONTENT_TYPE_TEXT_HTML, "" }, + { "Icon", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "Image File", CONTENT_TYPE_IMAGE_GENERIC, "" }, + { "MIDI", CONTENT_TYPE_AUDIO_MIDI, "" }, + { "Master Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "Plain Text", CONTENT_TYPE_TEXT_PLAIN, "" }, + { "StarCalc", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 3.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 4.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc 5.0", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc Datei", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc Document", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarCalc File", CONTENT_TYPE_APP_VND_CALC, "" }, + { "StarChart 3.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart 4.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart 5.0", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarChart Document", CONTENT_TYPE_APP_VND_CHART, "" }, + { "StarDraw 3.0", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw 5.0", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarDraw Document", CONTENT_TYPE_APP_VND_DRAW, "" }, + { "StarImpress 4.0", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarImpress 5.0 (packed)", CONTENT_TYPE_APP_VND_IMPRESSPACKED, "" }, + { "StarImpress 5.0", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarImpress Document", CONTENT_TYPE_APP_VND_IMPRESS, "" }, + { "StarMath 3.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath 4.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath 5.0", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMath Document", CONTENT_TYPE_APP_VND_MATH, "" }, + { "StarMessage5", CONTENT_TYPE_APP_VND_MAIL, "" }, + { "StarOffice XML (Calc)", CONTENT_TYPE_APP_VND_SUN_XML_CALC, "" }, + { "StarOffice XML (Impress)", CONTENT_TYPE_APP_VND_SUN_XML_IMPRESS, "" }, + { "StarOffice XML (Draw)", CONTENT_TYPE_APP_VND_SUN_XML_DRAW, "" }, + { "StarOffice XML (Chart)", CONTENT_TYPE_APP_VND_SUN_XML_CHART, "" }, + { "StarOffice XML (Writer)", CONTENT_TYPE_APP_VND_SUN_XML_WRITER, "" }, + { "StarWriter", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 3.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 4.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter 5.0", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter Document", CONTENT_TYPE_APP_VND_WRITER, "" }, + { "StarWriter/Global 5.0", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriter/Global Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriter/Web 5.0", CONTENT_TYPE_APP_VND_WRITER_WEB, "" }, + { "StarWriterGlobal Document", CONTENT_TYPE_APP_VND_WRITER_GLOBAL, "" }, + { "StarWriterHtml Document", CONTENT_TYPE_APP_VND_WRITER_WEB, "" }, + { "UniformResourceLocator", CONTENT_TYPE_TEXT_URL, "" }, + { "text/html", CONTENT_TYPE_TEXT_HTML, "" } }; + +} + +//============================================================================ +// +// Registration +// +//============================================================================ + +// static +Registration * Registration::m_pRegistration = 0; + +//============================================================================ +Registration::~Registration() +{ + {for (ULONG i = 0; i < m_aTypeIDMap.Count(); ++i) + delete static_cast< TypeIDMapEntry * >(m_aTypeIDMap.GetObject(i)); + } + m_aTypeIDMap.Clear(); + {for (USHORT i = 0; i < m_aTypeNameMap.Count(); ++i) + delete static_cast< TypeNameMapEntry * >(m_aTypeNameMap.GetObject(i)); + } + m_aTypeNameMap.Remove(USHORT(0), m_aTypeNameMap.Count()); + {for (USHORT i = 0; i < m_aExtensionMap.Count(); ++i) + delete + static_cast< ExtensionMapEntry * >(m_aExtensionMap.GetObject(i)); + } + m_aExtensionMap.Remove(USHORT(0), m_aExtensionMap.Count()); +} + +//============================================================================ +// static +TypeNameMapEntry * Registration::getExtensionEntry(UniString const & + rTypeName) +{ + if (m_pRegistration) + { + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + if (m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos)) + return static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos)); + } + return 0; +} + +//============================================================================ +// static +INetContentType Registration::RegisterContentType(UniString const & rTypeName, + UniString const & + rPresentation, + UniString const * + pExtension, + UniString const * + pSystemFileType) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + DBG_ASSERT(GetContentType(rTypeName) == CONTENT_TYPE_UNKNOWN, + "Registration::RegisterContentType(): Already registered"); + + INetContentType eTypeID + = INetContentType(m_pRegistration->m_nNextDynamicID++); + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + + TypeIDMapEntry * pTypeIDMapEntry = new TypeIDMapEntry; + pTypeIDMapEntry->m_aTypeName = aTheTypeName; + pTypeIDMapEntry->m_aPresentation = rPresentation; + if (pSystemFileType) + pTypeIDMapEntry->m_aSystemFileType = *pSystemFileType; + m_pRegistration->m_aTypeIDMap.Insert(eTypeID, pTypeIDMapEntry); + + TypeNameMapEntry * pTypeNameMapEntry = new TypeNameMapEntry(aTheTypeName); + if (pExtension) + pTypeNameMapEntry->m_aExtension = *pExtension; + pTypeNameMapEntry->m_eTypeID = eTypeID; + m_pRegistration->m_aTypeNameMap.Insert(pTypeNameMapEntry); + + if (pExtension) + { + ExtensionMapEntry * pExtensionMapEntry + = new ExtensionMapEntry(*pExtension); + pExtensionMapEntry->m_eTypeID = eTypeID; + m_pRegistration->m_aExtensionMap.Insert(pExtensionMapEntry); + } + + return eTypeID; +} + +//============================================================================ +// static +INetContentType Registration::GetContentType(UniString const & rTypeName) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ? + static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos))-> + m_eTypeID : + CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// static +UniString Registration::GetContentType(INetContentType eTypeID) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + TypeIDMapEntry * pEntry + = static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)); + return pEntry ? pEntry->m_aTypeName : UniString(); +} + +//============================================================================ +// static +UniString Registration::GetPresentation(INetContentType eTypeID) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + TypeIDMapEntry * pEntry + = static_cast< TypeIDMapEntry * >(m_pRegistration-> + m_aTypeIDMap.Get(eTypeID)); + return pEntry ? pEntry->m_aPresentation : UniString(); +} + +//============================================================================ +// static +UniString Registration::GetExtension(UniString const & rTypeName) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + UniString aTheTypeName = rTypeName; + aTheTypeName.ToLowerAscii(); + USHORT nPos; + return m_pRegistration->m_aTypeNameMap.Seek_Entry(&aTheTypeName, &nPos) ? + static_cast< TypeNameMapEntry * >(m_pRegistration-> + m_aTypeNameMap. + GetObject(nPos))-> + m_aExtension : + UniString(); +} + +//============================================================================ +// static +INetContentType Registration::GetContentType4Extension(UniString const & + rExtension) +{ + if (!m_pRegistration) + m_pRegistration = new Registration; + + USHORT nPos; + return m_pRegistration-> + m_aExtensionMap. + Seek_Entry(const_cast< UniString * >(&rExtension), + &nPos) ? + static_cast< ExtensionMapEntry * >(m_pRegistration-> + m_aExtensionMap. + GetObject(nPos))-> + m_eTypeID : + CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// +// seekEntry +// +//============================================================================ + +namespace unnamed_svl_inettype { + +MediaTypeEntry const * seekEntry(UniString const & rTypeName, + MediaTypeEntry const * pMap, sal_Size nSize) +{ +#if defined DBG_UTIL || defined INETTYPE_DEBUG + static bool bChecked = false; + if (!bChecked) + { + for (sal_Size i = 0; i < nSize - 1; ++i) + DBG_ASSERT(pMap[i].m_pTypeName < pMap[i + 1].m_pTypeName, + "seekEntry(): Bad map"); + bChecked = true; + } +#endif // DBG_UTIL, INETTYPE_DEBUG + + sal_Size nLow = 0; + sal_Size nHigh = nSize; + while (nLow != nHigh) + { + sal_Size nMiddle = (nLow + nHigh) / 2; + MediaTypeEntry const * pEntry = pMap + nMiddle; + switch (rTypeName.CompareIgnoreCaseToAscii(pEntry->m_pTypeName)) + { + case COMPARE_LESS: + nHigh = nMiddle; + break; + + case COMPARE_EQUAL: + return pEntry; + + case COMPARE_GREATER: + nLow = nMiddle + 1; + break; + } + } + return 0; +} + +} + +//============================================================================ +// +// INetContentTypes +// +//============================================================================ + +//static +void INetContentTypes::Uninitialize() +{ + Registration::deinitialize(); +} + +//============================================================================ +//static +INetContentType INetContentTypes::RegisterContentType(UniString const & + rTypeName, + UniString const & + rPresentation, + UniString const * + pExtension, + UniString const * + pSystemFileType) +{ + INetContentType eTypeID = GetContentType(rTypeName); + if (eTypeID == CONTENT_TYPE_UNKNOWN) + eTypeID = Registration::RegisterContentType(rTypeName, rPresentation, + pExtension, + pSystemFileType); + else if (eTypeID > CONTENT_TYPE_LAST) + { + TypeIDMapEntry * pTypeEntry = Registration::getEntry(eTypeID); + if (pTypeEntry) + { + if (rPresentation.Len() != 0) + pTypeEntry->m_aPresentation = rPresentation; + if (pSystemFileType) + pTypeEntry->m_aSystemFileType = *pSystemFileType; + } + if (pExtension) + { + TypeNameMapEntry * pEntry + = Registration::getExtensionEntry(rTypeName); + if (pEntry) + pEntry->m_aExtension = *pExtension; + } + } + return eTypeID; +} + +//============================================================================ +// static +INetContentType INetContentTypes::GetContentType(UniString const & rTypeName) +{ + UniString aType; + UniString aSubType; + if (parse(rTypeName, aType, aSubType)) + { + aType += '/'; + aType += aSubType; + MediaTypeEntry const * pEntry = seekEntry(aType, aStaticTypeNameMap, + CONTENT_TYPE_LAST + 1); + return pEntry ? pEntry->m_eTypeID : + Registration::GetContentType(aType); + } + else + return + rTypeName.EqualsIgnoreCaseAscii(CONTENT_TYPE_STR_X_STARMAIL) ? + CONTENT_TYPE_X_STARMAIL : CONTENT_TYPE_UNKNOWN; + // the content type "x-starmail" has no sub type +} + +//============================================================================ +//static +UniString INetContentTypes::GetContentType(INetContentType eTypeID) +{ + static sal_Char const * aMap[CONTENT_TYPE_LAST + 1]; + static bool bInitialized = false; + if (!bInitialized) + { + for (sal_Size i = 0; i <= CONTENT_TYPE_LAST; ++i) + aMap[aStaticTypeNameMap[i].m_eTypeID] + = aStaticTypeNameMap[i].m_pTypeName; + aMap[CONTENT_TYPE_UNKNOWN] = CONTENT_TYPE_STR_APP_OCTSTREAM; + aMap[CONTENT_TYPE_TEXT_PLAIN] = CONTENT_TYPE_STR_TEXT_PLAIN + "; charset=iso-8859-1"; + bInitialized = true; + } + + UniString aTypeName = eTypeID <= CONTENT_TYPE_LAST ? + UniString::CreateFromAscii(aMap[eTypeID]) : + Registration::GetContentType(eTypeID); + if (aTypeName.Len() == 0) + { + DBG_ERROR("INetContentTypes::GetContentType(): Bad ID"); + return + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( + CONTENT_TYPE_STR_APP_OCTSTREAM)); + } + return aTypeName; +} + +//============================================================================ +//static +UniString INetContentTypes::GetPresentation(INetContentType eTypeID, + const ::com::sun::star::lang::Locale& aLocale) +{ + USHORT nResID = USHORT(); + if (eTypeID <= CONTENT_TYPE_LAST) + nResID = aStaticResourceIDMap[eTypeID]; + else + { + UniString aPresentation = Registration::GetPresentation(eTypeID); + if (aPresentation.Len() == 0) + nResID = STR_SVT_MIMETYPE_APP_OCTSTREAM; + else + return aPresentation; + } + return SvtSimpleResId(nResID, aLocale); +} + +//============================================================================ +//static +UniString INetContentTypes::GetExtension(UniString const & rTypeName) +{ + MediaTypeEntry const * pEntry = seekEntry(rTypeName, aStaticTypeNameMap, + CONTENT_TYPE_LAST + 1); + if (pEntry) + return UniString::CreateFromAscii(pEntry->m_pExtension); + + UniString aExtension = Registration::GetExtension(rTypeName); + if (aExtension.Len() != 0) + return aExtension; + // special handling of text types, which come in uncounted variations: + return rTypeName.EqualsIgnoreCaseAscii("text", 0, + RTL_CONSTASCII_LENGTH("text")) ? + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("txt")) : + UniString::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("tmp")); +} + +//============================================================================ +//static +INetContentType INetContentTypes::GetContentType4Extension(UniString const & + rExtension) +{ + MediaTypeEntry const * pEntry = seekEntry(rExtension, aStaticExtensionMap, + sizeof aStaticExtensionMap + / sizeof (MediaTypeEntry)); + if (pEntry) + return pEntry->m_eTypeID; + INetContentType eTypeID + = Registration::GetContentType4Extension(rExtension); + return eTypeID == CONTENT_TYPE_UNKNOWN ? CONTENT_TYPE_APP_OCTSTREAM : + eTypeID; +} + +//============================================================================ +//static +INetContentType INetContentTypes::GetContentTypeFromURL(UniString const & + rURL) +{ + INetContentType eTypeID = CONTENT_TYPE_UNKNOWN; + UniString aToken = rURL.GetToken(0, ':'); + if (aToken.Len() != 0) + { + if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_FILE)) + if (rURL.GetChar(rURL.Len() - 1) == '/') // folder + if (rURL.Len() > RTL_CONSTASCII_LENGTH("file:///")) + if (WildCard(UniString(RTL_CONSTASCII_USTRINGPARAM( + "*/{*}/"))). + Matches(rURL)) // special folder + eTypeID = CONTENT_TYPE_X_CNT_FSYSSPECIALFOLDER; + else + // drive? -> "file:///?|/" + if (rURL.Len() == 11 + && rURL.GetChar(rURL.Len() - 2) == '|') + { + // Drives need further processing, because of + // dynamic type according to underlying volume, + // which cannot be determined here. + } + else // normal folder + eTypeID = CONTENT_TYPE_X_CNT_FSYSFOLDER; + else // file system root + eTypeID = CONTENT_TYPE_X_CNT_FSYSBOX; + else // file + { + //@@@ + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTP) + || aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_HTTPS)) + eTypeID = CONTENT_TYPE_TEXT_HTML; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_PRIVATE)) + { + UniString aSecondPart = rURL.GetToken(1, ':'); + aToken = aSecondPart.GetToken(0, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SUB_FACTORY)) + { + aToken = aSecondPart.GetToken(1, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SWRITER)) + { + aToken = aSecondPart.GetToken(2, '/'); + eTypeID = aToken.EqualsAscii(INETTYPE_URL_SSSUB_WEB) ? + CONTENT_TYPE_APP_VND_WRITER_WEB : + aToken.EqualsAscii(INETTYPE_URL_SSSUB_GLOB) ? + CONTENT_TYPE_APP_VND_WRITER_GLOBAL : + CONTENT_TYPE_APP_VND_WRITER; + } + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCALC)) + eTypeID = CONTENT_TYPE_APP_VND_CALC; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SDRAW)) + eTypeID = CONTENT_TYPE_APP_VND_DRAW; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMPRESS)) + eTypeID = CONTENT_TYPE_APP_VND_IMPRESS; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SCHART)) + eTypeID = CONTENT_TYPE_APP_VND_CHART; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SIMAGE)) + eTypeID = CONTENT_TYPE_APP_VND_IMAGE; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SMATH)) + eTypeID = CONTENT_TYPE_APP_VND_MATH; + else if (aToken.EqualsAscii(INETTYPE_URL_SSUB_FRAMESET)) + eTypeID = CONTENT_TYPE_APP_FRAMESET; + } + else if (aToken.EqualsAscii(INETTYPE_URL_SUB_HELPID)) + eTypeID = CONTENT_TYPE_APP_STARHELP; + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_COMPONENT)) + { + aToken = rURL.GetToken(1, ':'); // aToken now equals ss / * + aToken = aToken.GetToken(0, '/'); + if (aToken.EqualsAscii(INETTYPE_URL_SSUB_SS)) + eTypeID = rURL.SearchAscii(INETTYPE_URL_SCHED_CMB) + == STRING_NOTFOUND + && rURL.SearchAscii(INETTYPE_URL_SCHED_FORM) + == STRING_NOTFOUND ? + CONTENT_TYPE_APP_SCHEDULE : + rURL.SearchAscii(INETTYPE_URL_SCHED_TASK) + == STRING_NOTFOUND ? + CONTENT_TYPE_APP_SCHEDULE_EVT : + CONTENT_TYPE_APP_SCHEDULE_TASK; + } + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MAILTO)) + eTypeID = CONTENT_TYPE_APP_VND_OUTTRAY; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_MACRO)) + eTypeID = CONTENT_TYPE_APP_MACRO; + else if (aToken.EqualsIgnoreCaseAscii(INETTYPE_URL_PROT_DATA)) + { + UniString aSecondPart = rURL.GetToken(1, ':'); + aToken = aSecondPart.GetToken(0, ','); + eTypeID = GetContentType(aToken); + } + } + if (eTypeID == CONTENT_TYPE_UNKNOWN) + { + UniString aExtension; + if (GetExtensionFromURL(rURL, aExtension)) + eTypeID = GetContentType4Extension(aExtension); + } + return eTypeID; +} + +//============================================================================ +//static +bool INetContentTypes::GetExtensionFromURL(UniString const & rURL, + UniString & rExtension) +{ + xub_StrLen nSlashPos = 0; + xub_StrLen i = 0; + while (i != STRING_NOTFOUND) + { + nSlashPos = i; + i = rURL.Search('/', i + 1); + } + if (nSlashPos != 0) + { + xub_StrLen nLastDotPos = i = rURL.Search('.', nSlashPos); + while (i != STRING_NOTFOUND) + { + nLastDotPos = i; + i = rURL.Search('.', i + 1); + } + if (nLastDotPos != STRING_NOTFOUND) + rExtension = rURL.Copy(nLastDotPos + 1); + return true; + } + return false; +} + +//============================================================================ +//static +INetContentType INetContentTypes::MapStringToContentType(UniString const & + rPresentation) +{ + MediaTypeEntry const * pEntry = seekEntry(rPresentation, + aStaticPresentationMap, + sizeof aStaticPresentationMap + / sizeof (MediaTypeEntry)); + return pEntry ? pEntry->m_eTypeID : CONTENT_TYPE_UNKNOWN; +} + +//============================================================================ +// static +bool INetContentTypes::parse(ByteString const & rMediaType, + ByteString & rType, ByteString & rSubType, + INetContentTypeParameterList * pParameters) +{ + sal_Char const * p = rMediaType.GetBuffer(); + sal_Char const * pEnd = p + rMediaType.Len(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + sal_Char const * pToken = p; + bool bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rType = ByteString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rType.ToLowerAscii(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd || *p++ != '/') + return false; + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + pToken = p; + bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rSubType = ByteString( + pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rSubType.ToLowerAscii(); + + return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd; +} + +//============================================================================ +// static +bool INetContentTypes::parse(UniString const & rMediaType, + UniString & rType, UniString & rSubType, + INetContentTypeParameterList * pParameters) +{ + sal_Unicode const * p = rMediaType.GetBuffer(); + sal_Unicode const * pEnd = p + rMediaType.Len(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + sal_Unicode const * pToken = p; + bool bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rType = UniString(pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rType.ToLowerAscii(); + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + if (p == pEnd || *p++ != '/') + return false; + + p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); + pToken = p; + bDowncase = false; + while (p != pEnd && INetMIME::isTokenChar(*p)) + { + bDowncase = bDowncase || INetMIME::isUpperCase(*p); + ++p; + } + if (p == pToken) + return false; + rSubType = UniString( + pToken, sal::static_int_cast< xub_StrLen >(p - pToken)); + if (bDowncase) + rSubType.ToLowerAscii(); + + return INetMIME::scanParameters(p, pEnd, pParameters) == pEnd; +} + +//============================================================================ +// static +ByteString INetContentTypes::appendUSASCIIParameter(ByteString const & + rMediaType, + ByteString const & + rAttribute, + ByteString const & rValue) +{ + ByteString aResult = rMediaType; + aResult.Append(RTL_CONSTASCII_STRINGPARAM("; ")); + aResult += rAttribute; + aResult += '='; + bool bQuote = false; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // When the value contains any ' characters, use a quoted string + // instead of a token, in order to avoid confusion with RFC 2231 + // extensions: + sal_uInt32 nChar = sal_uChar(rValue.GetChar(i)); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter(): Bad value"); + if (!INetMIME::isTokenChar(nChar) || nChar == '\'') + { + bQuote = true; + break; + } + } + if (bQuote) + { + aResult += '"'; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // Escape LF as well as CR to avoid confusion with line folding: + sal_uInt32 nChar = sal_uChar(rValue.GetChar(i)); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter():" + " Bad value"); + switch (nChar) + { + case 0x0A: // LF + case 0x0D: // CR + case '"': + case '\\': + aResult += '\\'; + default: + aResult += static_cast< char >(nChar); + break; + } + } + aResult += '"'; + } + else + aResult += rValue; + return aResult; +} + +//============================================================================ +// static +UniString INetContentTypes::appendUSASCIIParameter(UniString const & + rMediaType, + UniString const & + rAttribute, + UniString const & rValue) +{ + UniString aResult = rMediaType; + aResult.AppendAscii(RTL_CONSTASCII_STRINGPARAM("; ")); + aResult += rAttribute; + aResult += '='; + bool bQuote = false; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // When the value contains any ' characters, use a quoted string + // instead of a token, in order to avoid confusion with RFC 2231 + // extensions: + sal_uInt32 nChar = rValue.GetChar(i); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter(): Bad value"); + if (!INetMIME::isTokenChar(nChar) || nChar == '\'') + { + bQuote = true; + break; + } + } + if (bQuote) + { + aResult += '"'; + for (xub_StrLen i = 0; i < rValue.Len(); ++i) + { + // Escape LF as well as CR to avoid confusion with line folding: + sal_uInt32 nChar = rValue.GetChar(i); + DBG_ASSERT(INetMIME::isUSASCII(nChar), + "INetContentTypes::appendUSASCIIParameter():" + " Bad value"); + switch (nChar) + { + case 0x0A: // LF + case 0x0D: // CR + case '"': + case '\\': + aResult += '\\'; + default: + aResult += sal_Unicode(nChar); + break; + } + } + aResult += '"'; + } + else + aResult += rValue; + return aResult; +} + diff --git a/svl/source/misc/lngmisc.cxx b/svl/source/misc/lngmisc.cxx new file mode 100644 index 000000000000..df7c28d22b1d --- /dev/null +++ b/svl/source/misc/lngmisc.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * 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: lngmisc.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <lngmisc.hxx> +#include <tools/solar.h> +#include <tools/string.hxx> +#include <tools/debug.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> + + +using namespace rtl; + +namespace linguistic +{ + +/////////////////////////////////////////////////////////////////////////// + +INT32 GetNumControlChars( const OUString &rTxt ) +{ + INT32 nCnt = 0; + INT32 nLen = rTxt.getLength(); + for (INT32 i = 0; i < nLen; ++i) + { + if (IsControlChar( rTxt[i] )) + ++nCnt; + } + return nCnt; +} + + +BOOL RemoveHyphens( OUString &rTxt ) +{ + BOOL bModified = FALSE; + if (HasHyphens( rTxt )) + { + String aTmp( rTxt ); + aTmp.EraseAllChars( SVT_SOFT_HYPHEN ); + aTmp.EraseAllChars( SVT_HARD_HYPHEN ); + rTxt = aTmp; + bModified = TRUE; + } + return bModified; +} + + +BOOL RemoveControlChars( OUString &rTxt ) +{ + BOOL bModified = FALSE; + INT32 nCtrlChars = GetNumControlChars( rTxt ); + if (nCtrlChars) + { + INT32 nLen = rTxt.getLength(); + INT32 nSize = nLen - nCtrlChars; + OUStringBuffer aBuf( nSize ); + aBuf.setLength( nSize ); + INT32 nCnt = 0; + for (INT32 i = 0; i < nLen; ++i) + { + sal_Unicode cChar = rTxt[i]; + if (!IsControlChar( cChar )) + { + DBG_ASSERT( nCnt < nSize, "index out of range" ); + aBuf.setCharAt( nCnt++, cChar ); + } + } + DBG_ASSERT( nCnt == nSize, "wrong size" ); + rTxt = aBuf.makeStringAndClear(); + bModified = TRUE; + } + return bModified; +} + + +// non breaking field character +#define CH_TXTATR_INWORD ((sal_Char) 0x02) + +BOOL ReplaceControlChars( rtl::OUString &rTxt, sal_Char /*aRplcChar*/ ) +{ + // the resulting string looks like this: + // 1. non breaking field characters get removed + // 2. remaining control characters will be replaced by ' ' + + BOOL bModified = FALSE; + INT32 nCtrlChars = GetNumControlChars( rTxt ); + if (nCtrlChars) + { + INT32 nLen = rTxt.getLength(); + OUStringBuffer aBuf( nLen ); + INT32 nCnt = 0; + for (INT32 i = 0; i < nLen; ++i) + { + sal_Unicode cChar = rTxt[i]; + if (CH_TXTATR_INWORD != cChar) + { + if (IsControlChar( cChar )) + cChar = ' '; + DBG_ASSERT( nCnt < nLen, "index out of range" ); + aBuf.setCharAt( nCnt++, cChar ); + } + } + aBuf.setLength( nCnt ); + rTxt = aBuf.makeStringAndClear(); + bModified = TRUE; + } + return bModified; +} + +/////////////////////////////////////////////////////////////////////////// + +} // namespace linguistic + diff --git a/svl/source/misc/lockfilecommon.cxx b/svl/source/misc/lockfilecommon.cxx new file mode 100644 index 000000000000..f13ed574a87f --- /dev/null +++ b/svl/source/misc/lockfilecommon.cxx @@ -0,0 +1,276 @@ +/************************************************************************* + * + * 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: ,v $ + * + * $Revision: $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/NameClashException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> +#include <osl/file.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> + +#include <tools/urlobj.hxx> +#include <unotools/bootstrap.hxx> + +#include <ucbhelper/content.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/lockfilecommon.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +// ---------------------------------------------------------------------- +LockFileCommon::LockFileCommon( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory, const ::rtl::OUString& aPrefix ) +: m_xFactory( xFactory ) +{ + if ( !m_xFactory.is() ) + m_xFactory = ::comphelper::getProcessServiceFactory(); + + INetURLObject aDocURL = ResolveLinks( INetURLObject( aOrigURL ) ); + + ::rtl::OUString aShareURLString = aDocURL.GetPartBeforeLastName(); + aShareURLString += aPrefix; + aShareURLString += aDocURL.GetName(); + aShareURLString += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "#" ) ); + m_aURL = INetURLObject( aShareURLString ).GetMainURL( INetURLObject::NO_DECODE ); +} + +// ---------------------------------------------------------------------- +LockFileCommon::~LockFileCommon() +{ +} + +// ---------------------------------------------------------------------- +INetURLObject LockFileCommon::ResolveLinks( const INetURLObject& aDocURL ) +{ + if ( aDocURL.HasError() ) + throw lang::IllegalArgumentException(); + + ::rtl::OUString aURLToCheck = aDocURL.GetMainURL( INetURLObject::NO_DECODE ); + + sal_Bool bNeedsChecking = sal_True; + sal_Int32 nMaxLinkCount = 128; + sal_Int32 nCount = 0; + + while( bNeedsChecking ) + { + bNeedsChecking = sal_False; + + // do not allow too deep links + if ( nCount++ >= nMaxLinkCount ) + throw io::IOException(); + + // there is currently no UCB functionality to resolve the symbolic links; + // since the lock files are used only for local file systems the osl functionality is used directly + + ::osl::FileStatus aStatus( FileStatusMask_Type | FileStatusMask_LinkTargetURL ); + ::osl::DirectoryItem aItem; + if ( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aURLToCheck, aItem ) + && aItem.is() && ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) ) + { + if ( aStatus.isValid( FileStatusMask_Type ) + && aStatus.isValid( FileStatusMask_LinkTargetURL ) + && aStatus.getFileType() == ::osl::FileStatus::Link ) + { + aURLToCheck = aStatus.getLinkTargetURL(); + bNeedsChecking = sal_True; + } + } + } + + return INetURLObject( aURLToCheck ); +} + +// ---------------------------------------------------------------------- +uno::Sequence< uno::Sequence< ::rtl::OUString > > LockFileCommon::ParseList( const uno::Sequence< sal_Int8 >& aBuffer ) +{ + sal_Int32 nCurPos = 0; + sal_Int32 nCurEntry = 0; + uno::Sequence< uno::Sequence< ::rtl::OUString > > aResult( 10 ); + + while ( nCurPos < aBuffer.getLength() ) + { + if ( nCurEntry >= aResult.getLength() ) + aResult.realloc( nCurEntry + 10 ); + aResult[nCurEntry] = ParseEntry( aBuffer, nCurPos ); + nCurEntry++; + } + + aResult.realloc( nCurEntry ); + return aResult; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > LockFileCommon::ParseEntry( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos ) +{ + uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE ); + + for ( int nInd = 0; nInd < LOCKFILE_ENTRYSIZE; nInd++ ) + { + aResult[nInd] = ParseName( aBuffer, io_nCurPos ); + if ( io_nCurPos >= aBuffer.getLength() + || ( nInd < LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ',' ) + || ( nInd == LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ';' ) ) + throw io::WrongFormatException(); + } + + return aResult; +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::ParseName( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos ) +{ + ::rtl::OStringBuffer aResult; + sal_Bool bHaveName = sal_False; + sal_Bool bEscape = sal_False; + + while( !bHaveName ) + { + if ( io_nCurPos >= aBuffer.getLength() ) + throw io::WrongFormatException(); + + if ( bEscape ) + { + if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' || aBuffer[io_nCurPos] == '\\' ) + aResult.append( (sal_Char)aBuffer[io_nCurPos] ); + else + throw io::WrongFormatException(); + + bEscape = sal_False; + io_nCurPos++; + } + else if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' ) + bHaveName = sal_True; + else + { + if ( aBuffer[io_nCurPos] == '\\' ) + bEscape = sal_True; + else + aResult.append( (sal_Char)aBuffer[io_nCurPos] ); + + io_nCurPos++; + } + } + + return ::rtl::OStringToOUString( aResult.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::EscapeCharacters( const ::rtl::OUString& aSource ) +{ + ::rtl::OUStringBuffer aBuffer; + const sal_Unicode* pStr = aSource.getStr(); + for ( sal_Int32 nInd = 0; nInd < aSource.getLength() && pStr[nInd] != 0; nInd++ ) + { + if ( pStr[nInd] == '\\' || pStr[nInd] == ';' || pStr[nInd] == ',' ) + aBuffer.append( (sal_Unicode)'\\' ); + aBuffer.append( pStr[nInd] ); + } + + return aBuffer.makeStringAndClear(); +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::GetOOOUserName() +{ + SvtUserOptions aUserOpt; + ::rtl::OUString aName = aUserOpt.GetFirstName(); + if ( aName.getLength() ) + aName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ); + aName += aUserOpt.GetLastName(); + + return aName; +} + +// ---------------------------------------------------------------------- +::rtl::OUString LockFileCommon::GetCurrentLocalTime() +{ + ::rtl::OUString aTime; + + TimeValue aSysTime; + if ( osl_getSystemTime( &aSysTime ) ) + { + TimeValue aLocTime; + if ( osl_getLocalTimeFromSystemTime( &aSysTime, &aLocTime ) ) + { + oslDateTime aDateTime; + if ( osl_getDateTimeFromTimeValue( &aLocTime, &aDateTime ) ) + { + char pDateTime[20]; + sprintf( pDateTime, "%02d.%02d.%4d %02d:%02d", aDateTime.Day, aDateTime.Month, aDateTime.Year, aDateTime.Hours, aDateTime.Minutes ); + aTime = ::rtl::OUString::createFromAscii( pDateTime ); + } + } + } + + return aTime; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > LockFileCommon::GenerateOwnEntry() +{ + uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE ); + + aResult[LOCKFILE_OOOUSERNAME_ID] = GetOOOUserName(); + + ::osl::Security aSecurity; + aSecurity.getUserName( aResult[LOCKFILE_SYSUSERNAME_ID] ); + + aResult[LOCKFILE_LOCALHOST_ID] = ::osl::SocketAddr::getLocalHostname(); + + aResult[LOCKFILE_EDITTIME_ID] = GetCurrentLocalTime(); + + ::utl::Bootstrap::locateUserInstallation( aResult[LOCKFILE_USERURL_ID] ); + + + return aResult; +} + +} // namespace svt + diff --git a/svl/source/misc/makefile.mk b/svl/source/misc/makefile.mk new file mode 100644 index 000000000000..adc659a7b60b --- /dev/null +++ b/svl/source/misc/makefile.mk @@ -0,0 +1,74 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=svl +TARGET=misc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/documentlockfile.obj \ + $(SLO)$/folderrestriction.obj \ + $(SLO)$/fstathelper.obj \ + $(SLO)$/lockfilecommon.obj \ + $(SLO)$/ownlist.obj \ + $(SLO)$/restrictedpaths.obj \ + $(SLO)$/sharecontrolfile.obj \ + $(SLO)$/strmadpt.obj \ + $(SLO)$/svldata.obj \ + $(SLO)$/urihelper.obj + +SLOFILES=\ + $(EXCEPTIONSFILES) \ + $(SLO)$/adrparse.obj \ + $(SLO)$/filenotation.obj \ + $(SLO)$/inethist.obj \ + $(SLO)$/inettype.obj \ + $(SLO)$/lngmisc.obj \ + $(SLO)$/PasswordHelper.obj + +SRS1NAME=$(TARGET) +SRC1FILES=\ + mediatyp.src + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + + + + diff --git a/svl/source/misc/mediatyp.src b/svl/source/misc/mediatyp.src new file mode 100644 index 000000000000..63033af29d03 --- /dev/null +++ b/svl/source/misc/mediatyp.src @@ -0,0 +1,610 @@ +/************************************************************************* + * + * 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: mediatyp.src,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +//============================================================================ +// +// Internet Media Type Presentations +// +// $Author: rt $ $Date: 2008-04-10 21:44:39 $ $Revision: 1.7 $ +//============================================================================ + +#ifndef _SVTOOLS_HRC +#include <svl/svtools.hrc> +#endif + +String STR_SVT_MIMETYPE_APP_OCTSTREAM +{ + Text [ en-US ] = "Binary file" ; +}; + +String STR_SVT_MIMETYPE_APP_PDF +{ + Text [ en-US ] = "PDF file" ; +}; + +String STR_SVT_MIMETYPE_APP_RTF +{ + Text [ en-US ] = "RTF File" ; +}; + +String STR_SVT_MIMETYPE_APP_MSWORD +{ + Text [ en-US ] = "MS-Word document" ; +}; + +String STR_SVT_MIMETYPE_APP_STARCALC +{ + Text [ en-US ] = "%PRODUCTNAME Spreadsheet" ; +}; + +String STR_SVT_MIMETYPE_APP_STARCHART +{ + Text [ en-US ] = "%PRODUCTNAME Chart" ; +}; + +String STR_SVT_MIMETYPE_APP_STARDRAW +{ + Text [ en-US ] = "%PRODUCTNAME Drawing" ; +}; + +String STR_SVT_MIMETYPE_APP_STARIMAGE +{ + Text [ en-US ] = "%PRODUCTNAME Image" ; +}; + +String STR_SVT_MIMETYPE_APP_STARMATH +{ + Text [ en-US ] = "%PRODUCTNAME Formula" ; +}; + +String STR_SVT_MIMETYPE_APP_STARWRITER +{ + Text [ en-US ] = "%PRODUCTNAME Text" ; +}; + +String STR_SVT_MIMETYPE_APP_ZIP +{ + Text [ en-US ] = "ZIP file" ; +}; + +String STR_SVT_MIMETYPE_APP_JAR +{ + Text [ en-US ] = "JAR file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_AIFF +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_BASIC +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_MIDI +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_AUDIO_WAV +{ + Text [ en-US ] = "Audio file" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_GIF +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_JPEG +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_PCX +{ + Text [ en-US ] = "Graphics" ; +}; + +String STR_SVT_MIMETYPE_IMAGE_BMP +{ + Text [ en-US ] = "Bitmap" ; +}; + +String STR_SVT_MIMETYPE_TEXT_HTML +{ + Text [ en-US ] = "HTML document" ; +}; + +String STR_SVT_MIMETYPE_TEXT_PLAIN +{ + Text [ en-US ] = "Text file" ; +}; + +String STR_SVT_MIMETYPE_TEXT_URL +{ + Text [ en-US ] = "Bookmark" ; +}; + +String STR_SVT_MIMETYPE_TEXT_VCARD +{ + Text [ en-US ] = "vCard file" ; +}; + +String STR_SVT_MIMETYPE_VIDEO_VDO +{ + Text [ en-US ] = "Video file" ; +}; + +String STR_SVT_MIMETYPE_VIDEO_MSVIDEO +{ + Text [ en-US ] = "Video file" ; +}; + +String STR_SVT_MIMETYPE_X_STARMAIL +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_X_VRML +{ + Text [ en-US ] = "VRML file" ; +}; + +String STR_SVT_MIMETYPE_APP_STARIMPRESS +{ + Text [ en-US ] = "%PRODUCTNAME Presentation" ; +}; + +String STR_SVT_MIMETYPE_APP_IMPRESSPACKED +{ + Text [ en-US ] = "%PRODUCTNAME Presentation (packed)"; +}; + +String STR_SVT_MIMETYPE_APP_STARHELP +{ + Text [ en-US ] = "%PRODUCTNAME Help" ; +}; + + +String STR_SVT_MIMETYPE_CNT_MSG +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_CNT_DOCUMENT +{ + Text [ en-US ] = "Document" ; +}; + +String STR_SVT_MIMETYPE_CNT_POP3BOX +{ + Text [ en-US ] = "POP3 Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_IMAPBOX +{ + Text [ en-US ] = "IMAP Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_IMAPFLD +{ + Text [ en-US ] = "Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIMBOX +{ + Text [ en-US ] = "VIM Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIMINBOX +{ + Text [ en-US ] = "Inbox" ; +}; + +String STR_SVT_MIMETYPE_CNT_BBBOX +{ + Text [ en-US ] = "Newsgroups" ; +}; + +String STR_SVT_MIMETYPE_CNT_VIM_BB +{ + Text [ en-US ] = "Newsgroup" ; +}; + +String STR_SVT_MIMETYPE_CNT_NEWSBOX +{ + Text [ en-US ] = "News" ; +}; + +String STR_SVT_MIMETYPE_CNT_NEWSGRP +{ + Text [ en-US ] = "Group" ; +}; + +String STR_SVT_MIMETYPE_CNT_OUTBOX +{ + Text [ en-US ] = "Outbox" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPBOX +{ + Text [ en-US ] = "FTP Account" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPFLD +{ + Text [ en-US ] = "FTP Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPFILE +{ + Text [ en-US ] = "FTP File" ; +}; + +String STR_SVT_MIMETYPE_CNT_FTPLINK +{ + Text [ en-US ] = "FTP Link" ; +}; + +String STR_SVT_MIMETYPE_CNT_HTTPBOX +{ + Text [ en-US ] = "HTTP" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSBOX +{ + Text [ en-US ] = "Workplace" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSFLD +{ + Text [ en-US ] = "Folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSFILE +{ + Text [ en-US ] = "File" ; +}; + +String STR_SVT_MIMETYPE_CNT_FSYSURLFILE +{ + Text [ en-US ] = "Link" ; +}; + +String STR_SVT_MIMETYPE_CNT_PUBLBOX +{ + Text [ en-US ] = "Project" ; +}; + +String STR_SVT_MIMETYPE_CNT_SRCHBOX +{ + Text [ en-US ] = "Find" ; +}; + +String STR_SVT_MIMETYPE_CNT_SUBSCRBOX +{ + Text [ en-US ] = "Subscriptions" ; +}; + +String STR_SVT_MIMETYPE_CNT_BOOKMARK +{ + Text [ en-US ] = "Bookmark subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDF +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDFSUB +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDFITEM +{ + Text [ en-US ] = "Channel subscription" ; +}; + +String STR_SVT_MIMETYPE_CNT_STARCHANNEL +{ + Text [ en-US ] = "StarChannel" ; +}; + +String STR_SVT_MIMETYPE_CNT_TRASHBOX +{ + Text [ en-US ] = "Recycle Bin" ; +}; + +String STR_SVT_MIMETYPE_CNT_TRASH +{ + Text [ en-US ] = "Deleted Object" ; +}; + +String STR_SVT_MIMETYPE_CNT_REMOV_VOL +{ + Text [ en-US ] = "Local drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_FIX_VOL +{ + Text [ en-US ] = "Local drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_REM_VOL +{ + Text [ en-US ] = "Network connection" ; +}; + +String STR_SVT_MIMETYPE_CNT_RAM_VOL +{ + Text [ en-US ] = "RAM Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_CDROM +{ + Text [ en-US ] = "CD-ROM drive" ; +}; + +String STR_SVT_MIMETYPE_CNT_DISK_35 +{ + Text [ en-US ] = "3.5'' Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_DISK_525 +{ + Text [ en-US ] = "5.25'' Disk" ; +}; + +String STR_SVT_MIMETYPE_CNT_TAPEDRIVE +{ + Text [ en-US ] = "Tape drive" ; +}; + +String STR_SVT_MIMETYPE_APP_GAL +{ + Text [ en-US ] = "Gallery"; +}; + +String STR_SVT_MIMETYPE_APP_GAL_THEME +{ + Text [ en-US ] = "Gallery theme" ; +}; + +String STR_SVT_MIMETYPE_CNT_SEPARATOR +{ + Text = "CntMenuView-Separator" ; +}; + +String STR_SVT_MIMETYPE_APP_STARW_GLOB +{ + Text [ en-US ] = "%PRODUCTNAME Master Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SDM +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_APP_SMD +{ + Text [ en-US ] = "Message" ; +}; + +String STR_SVT_MIMETYPE_APP_STARW_WEB +{ + Text [ en-US ] = "%PRODUCTNAME Writer/Web" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE +{ + Text [ en-US ] = "Tasks & Events" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_EVT +{ + Text [ en-US ] = "%PRODUCTNAME Events View" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_TASK +{ + Text [ en-US ] = "%PRODUCTNAME Task View" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_FEVT +{ + Text [ en-US ] = "%PRODUCTNAME Event" ; +}; + +String STR_SVT_MIMETYPE_SCHEDULE_FTASK +{ + Text [ en-US ] = "%PRODUCTNAME Task" ; +}; + +String STR_SVT_MIMETYPE_FRAMESET +{ + Text [ en-US ] = "Frameset Document" ; +}; + +String STR_SVT_MIMETYPE_MACRO +{ + Text [ en-US ] = "Macro file" ; +}; + +String STR_SVT_MIMETYPE_CNT_SFSYSFOLDER +{ + Text [ en-US ] = "System folder" ; +}; + +String STR_SVT_MIMETYPE_CNT_SFSYSFILE +{ + Text [ en-US ] = "System object" ; +}; + +String STR_SVT_MIMETYPE_APP_TEMPLATE +{ + Text [ en-US ] = "%PRODUCTNAME Template"; +}; + +String STR_SVT_MIMETYPE_IMAGE_GENERIC +{ + Text [ en-US ] = "Graphics"; +}; + +String STR_SVT_MIMETYPE_APP_MSEXCEL +{ + Text [ en-US ] = "MS Excel document" ; +}; + +String STR_SVT_MIMETYPE_APP_MSEXCEL_TEMPL +{ + Text [ en-US ] = "MS Excel Template" ; +}; + +String STR_SVT_MIMETYPE_APP_MSPPOINT +{ + Text [ en-US ] = "MS PowerPoint document" ; +}; + +String STR_SVT_MIMETYPE_TEXT_VCALENDAR +{ + Text [ en-US ] = "vCalendar-file" ; +}; + +String STR_SVT_MIMETYPE_TEXT_ICALENDAR +{ + Text [ en-US ] = "iCalendar-File"; +}; + +String STR_SVT_MIMETYPE_TEXT_XMLICALENDAR +{ + Text [ en-US ] = "XML-iCalendar-File"; +}; + +String STR_SVT_MIMETYPE_TEXT_CDE_CALENDAR_APP +{ + Text [ en-US ] = "CDE-Calendar-File"; +}; + +String STR_SVT_MIMETYPE_INET_MSG_RFC822 +{ + Text [ en-US ] = "message/rfc822" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_ALTERNATIVE +{ + Text [ en-US ] = "multipart/alternative" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_DIGEST +{ + Text [ en-US ] = "multipart/digest" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_PARALLEL +{ + Text [ en-US ] = "multipart/parallel" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_RELATED +{ + Text [ en-US ] = "multipart/related" ; +}; + +String STR_SVT_MIMETYPE_INET_MULTI_MIXED +{ + Text [ en-US ] = "multipart/mixed" ; +}; + +String STR_SVT_MIMETYPE_APP_SXCALC +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Spreadsheet" ; +}; + +String STR_SVT_MIMETYPE_APP_SXCHART +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Chart" ; +}; + +String STR_SVT_MIMETYPE_APP_SXDRAW +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Drawing" ; +}; + +String STR_SVT_MIMETYPE_APP_SXMATH +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Formula" ; +}; + +String STR_SVT_MIMETYPE_APP_SXWRITER +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Text Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SXIMPRESS +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation" ; +}; + +String STR_SVT_MIMETYPE_APP_SXGLOBAL +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Master Document" ; +}; + +String STR_SVT_MIMETYPE_APP_SXIPACKED +{ + Text [ en-US ] = "%PRODUCTNAME %PRODUCTXMLFILEFORMATVERSION Presentation (packed)" ; +}; + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svl/source/misc/ownlist.cxx b/svl/source/misc/ownlist.cxx new file mode 100644 index 000000000000..def341d57b7c --- /dev/null +++ b/svl/source/misc/ownlist.cxx @@ -0,0 +1,330 @@ +/************************************************************************* + * + * 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: ownlist.cxx,v $ + * $Revision: 1.6.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <ctype.h> +#include <stdio.h> +#include <com/sun/star/beans/PropertyValues.hpp> + +#include <svl/ownlist.hxx> + +using namespace com::sun::star; + +//========================================================================= +//============== SvCommandList ============================================ +//========================================================================= +PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand) + + +static String parseString(const String & rCmd, USHORT * pIndex) +{ + String result; + + if(rCmd.GetChar( *pIndex ) == '\"') { + (*pIndex) ++; + + USHORT begin = *pIndex; + + while(*pIndex < rCmd.Len() && rCmd.GetChar((*pIndex) ++) != '\"') ; + + result = String(rCmd.Copy(begin, *pIndex - begin - 1)); + } + + return result; +} + +static String parseWord(const String & rCmd, USHORT * pIndex) +{ + USHORT begin = *pIndex; + + while(*pIndex < rCmd.Len() && !isspace(rCmd.GetChar(*pIndex)) && rCmd.GetChar(*pIndex) != '=') + (*pIndex) ++; + + return String(rCmd.Copy(begin, *pIndex - begin)); +} + +static void eatSpace(const String & rCmd, USHORT * pIndex) +{ + while(*pIndex < rCmd.Len() && isspace(rCmd.GetChar(*pIndex))) + (*pIndex) ++; +} + + +//========================================================================= +BOOL SvCommandList::AppendCommands +( + const String & rCmd, /* Dieser Text wird in Kommandos umgesetzt */ + USHORT * pEaten /* Anzahl der Zeichen, die gelesen wurden */ +) +/* [Beschreibung] + + Es wird eine Text geparsed und die einzelnen Kommandos werden an + die Liste angeh"angt. + + [R"uckgabewert] + + BOOL TRUE, der Text wurde korrekt geparsed. + FALSE, der Text wurde nicht korrekt geparsed. +*/ +{ + USHORT index = 0; + while(index < rCmd.Len()) + { + + eatSpace(rCmd, &index); + String name = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index); + + eatSpace(rCmd, &index); + String value; + if(index < rCmd.Len() && rCmd.GetChar(index) == '=') + { + index ++; + + eatSpace(rCmd, &index); + value = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index); + } + + SvCommand * pCmd = new SvCommand(name, value); + aTypes.Insert(pCmd, LIST_APPEND); + } + + *pEaten = index; + +// USHORT nPos = 0; +// while( nPos < rCmd.Len() ) +// { +// // ein Zeichen ? Dann faengt hier eine Option an +// if( isalpha( rCmd[nPos] ) ) +// { +// String aValue; +// USHORT nStt = nPos; +// register char c; + +// while( nPos < rCmd.Len() && +// ( isalnum(c=rCmd[nPos]) || '-'==c || '.'==c ) ) +// nPos++; + +// String aToken( rCmd.Copy( nStt, nPos-nStt ) ); + +// while( nPos < rCmd.Len() && +// ( !String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) ) +// nPos++; + +// // hat die Option auch einen Wert? +// if( nPos!=rCmd.Len() && '='==c ) +// { +// nPos++; + +// while( nPos < rCmd.Len() && +// ( !String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) ) +// nPos++; + +// if( nPos != rCmd.Len() ) +// { +// USHORT nLen = 0; +// nStt = nPos; +// if( '"' == c ) +// { +// nPos++; nStt++; +// while( nPos < rCmd.Len() && +// '"' != rCmd[nPos] ) +// nPos++, nLen++; +// if( nPos!=rCmd.Len() ) +// nPos++; +// } +// else +// // hier sind wir etwas laxer als der +// // Standard und erlauben alles druckbare +// while( nPos < rCmd.Len() && +// String::IsPrintable( (c=rCmd[nPos]), +// RTL_TEXTENCODING_MS_1252 ) && +// !isspace( c ) ) +// nPos++, nLen++; + +// if( nLen ) +// aValue = rCmd( nStt, nLen ); +// } +// } + +// SvCommand * pCmd = new SvCommand( aToken, aValue ); +// aTypes.Insert( pCmd, LIST_APPEND ); +// } +// else +// // white space un unerwartete Zeichen ignorieren wie +// nPos++; +// } +// *pEaten = nPos; + return TRUE; +} + +//========================================================================= +String SvCommandList::GetCommands() const +/* [Beschreibung] + + Die Kommandos in der Liste werden als Text hintereinander, durch ein + Leerzeichen getrennt geschrieben. Der Text muss nicht genauso + aussehen wie der in <SvCommandList::AppendCommands()> "ubergebene. + + [R"uckgabewert] + + String Die Kommandos werden zur"uckgegeben. +*/ +{ + String aRet; + for( ULONG i = 0; i < aTypes.Count(); i++ ) + { + if( i != 0 ) + aRet += ' '; + SvCommand * pCmd = (SvCommand *)aTypes.GetObject( i ); + aRet += pCmd->GetCommand(); + if( pCmd->GetArgument().Len() ) + { + aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "=\"" ) ); + aRet += pCmd->GetArgument(); + aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) ); + } + } + return aRet; +} + +//========================================================================= +SvCommand & SvCommandList::Append +( + const String & rCommand, /* das Kommando */ + const String & rArg /* dasArgument des Kommandos */ +) +/* [Beschreibung] + + Es wird eine Objekt vom Typ SvCommand erzeugt und an die Liste + angeh"angt. + + [R"uckgabewert] + + SvCommand & Das erteugte Objekt wird zur"uckgegeben. +*/ +{ + SvCommand * pCmd = new SvCommand( rCommand, rArg ); + aTypes.Insert( pCmd, LIST_APPEND ); + return *pCmd; +} + +//========================================================================= +SvStream & operator >> +( + SvStream & rStm, /* Stream aus dem gelesen wird */ + SvCommandList & rThis /* Die zu f"ullende Liste */ +) +/* [Beschreibung] + + Die Liste mit ihren Elementen wird gelesen. Das Format ist: + 1. Anzahl der Elemente + 2. Alle Elemente + + [R"uckgabewert] + + SvStream & Der "ubergebene Stream. +*/ +{ + UINT32 nCount = 0; + rStm >> nCount; + if( !rStm.GetError() ) + { + while( nCount-- ) + { + SvCommand * pCmd = new SvCommand(); + rStm >> *pCmd; + rThis.aTypes.Insert( pCmd, LIST_APPEND ); + } + } + return rStm; +} + +//========================================================================= +SvStream & operator << +( + SvStream & rStm, /* Stream in den geschrieben wird */ + const SvCommandList & rThis /* Die zu schreibende Liste */ +) +/* [Beschreibung] + + Die Liste mit ihren Elementen wir geschrieben. Das Format ist: + 1. Anzahl der Elemente + 2. Alle Elemente + + [R"uckgabewert] + + SvStream & Der "ubergebene Stream. +*/ +{ + UINT32 nCount = rThis.aTypes.Count(); + rStm << nCount; + + for( UINT32 i = 0; i < nCount; i++ ) + { + SvCommand * pCmd = (SvCommand *)rThis.aTypes.GetObject( i ); + rStm << *pCmd; + } + return rStm; +} + +BOOL SvCommandList::FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence ) +{ + const sal_Int32 nCount = aCommandSequence.getLength(); + String aCommand, aArg; + ::rtl::OUString aApiArg; + for( sal_Int32 nIndex=0; nIndex<nCount; nIndex++ ) + { + aCommand = aCommandSequence[nIndex].Name; + if( !( aCommandSequence[nIndex].Value >>= aApiArg ) ) + return sal_False; + aArg = aApiArg; + Append( aCommand, aArg ); + } + + return TRUE; +} + +void SvCommandList::FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence ) +{ + const sal_Int32 nCount = Count(); + aCommandSequence.realloc( nCount ); + for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) + { + const SvCommand& rCommand = (*this)[ nIndex ]; + aCommandSequence[nIndex].Name = rCommand.GetCommand(); + aCommandSequence[nIndex].Handle = -1; + aCommandSequence[nIndex].Value = uno::makeAny( ::rtl::OUString( rCommand.GetArgument() ) ); + aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE; + } +} + diff --git a/svl/source/misc/restrictedpaths.cxx b/svl/source/misc/restrictedpaths.cxx new file mode 100644 index 000000000000..9eda454604b1 --- /dev/null +++ b/svl/source/misc/restrictedpaths.cxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * 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: restrictedpaths.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/restrictedpaths.hxx> + +#include <algorithm> +#include <osl/process.h> +#include <tools/urlobj.hxx> +#include <unotools/localfilehelper.hxx> +#include <unotools/syslocale.hxx> + +namespace svt +{ + namespace + { + // ---------------------------------------------------------------- + /** retrieves the value of an environment variable + @return <TRUE/> if and only if the retrieved string value is not empty + */ + bool lcl_getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) + { + _rValue = ::rtl::OUString(); + ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); + osl_getEnvironment( sEnvName.pData, &_rValue.pData ); + return _rValue.getLength() != 0; + } + + //----------------------------------------------------------------- + void lcl_convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) + { + const sal_Unicode s_cSeparator = + #if defined(WNT) + ';' + #else + ':' + #endif + ; + xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); + _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); + for ( xub_StrLen i=0; i<nTokens; ++i ) + { + // the current token in the list + String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); + if ( !sCurrentToken.Len() ) + continue; + + INetURLObject aCurrentURL; + + String sURL; + if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) + aCurrentURL = INetURLObject( sURL ); + else + { + // smart URL parsing, assuming FILE protocol + aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); + } + + if ( _bFinalSlash ) + aCurrentURL.setFinalSlash( ); + else + aCurrentURL.removeFinalSlash( ); + _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); + } + } + + } + + //===================================================================== + //= CheckURLAllowed + //===================================================================== + struct CheckURLAllowed + { + protected: + #ifdef WNT + SvtSysLocale m_aSysLocale; + #endif + String m_sCheckURL; // the URL to check + bool m_bAllowParent; + public: + inline CheckURLAllowed( const String& _rCheckURL, bool bAllowParent = true ) + :m_sCheckURL( _rCheckURL ), m_bAllowParent( bAllowParent ) + { + #ifdef WNT + // on windows, assume that the relevant file systems are case insensitive, + // thus normalize the URL + m_sCheckURL = m_aSysLocale.GetCharClass().toLower( m_sCheckURL, 0, m_sCheckURL.Len() ); + #endif + } + + bool operator()( const String& _rApprovedURL ) + { + #ifdef WNT + // on windows, assume that the relevant file systems are case insensitive, + // thus normalize the URL + String sApprovedURL( m_aSysLocale.GetCharClass().toLower( _rApprovedURL, 0, _rApprovedURL.Len() ) ); + #else + String sApprovedURL( _rApprovedURL ); + #endif + + xub_StrLen nLenApproved = sApprovedURL.Len(); + xub_StrLen nLenChecked = m_sCheckURL.Len(); + + if ( nLenApproved > nLenChecked ) + { + if ( m_bAllowParent ) + { + if ( sApprovedURL.Search( m_sCheckURL ) == 0 ) + { + if ( ( m_sCheckURL.GetChar( nLenChecked - 1 ) == '/' ) + || ( sApprovedURL.GetChar( nLenChecked ) == '/' ) ) + return true; + } + } + else + { + // just a difference in final slash? + if ( ( nLenApproved == ( nLenChecked + 1 ) ) && + ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) ) + return true; + } + return false; + } + else if ( nLenApproved < nLenChecked ) + { + if ( m_sCheckURL.Search( sApprovedURL ) == 0 ) + { + if ( ( sApprovedURL.GetChar( nLenApproved - 1 ) == '/' ) + || ( m_sCheckURL.GetChar( nLenApproved ) == '/' ) ) + return true; + } + return false; + } + else + { + // strings have equal length + return ( sApprovedURL == m_sCheckURL ); + } + } + }; + + //===================================================================== + //= RestrictedPaths + //===================================================================== + //--------------------------------------------------------------------- + RestrictedPaths::RestrictedPaths() + :m_bFilterIsEnabled( true ) + { + ::rtl::OUString sRestrictedPathList; + if ( lcl_getEnvironmentValue( "RestrictedPath", sRestrictedPathList ) ) + // append a final slash. This ensures that when we later on check + // for unrestricted paths, we don't allow paths like "/home/user35" just because + // "/home/user3" is allowed - with the final slash, we make it "/home/user3/". + lcl_convertStringListToUrls( sRestrictedPathList, m_aUnrestrictedURLs, true ); + } + + RestrictedPaths::~RestrictedPaths() {} + + // -------------------------------------------------------------------- + bool RestrictedPaths::isUrlAllowed( const String& _rURL ) const + { + if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) + return true; + + ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( + m_aUnrestrictedURLs.begin(), + m_aUnrestrictedURLs.end(), + CheckURLAllowed( _rURL, true ) + ); + + return ( aApprovedURL != m_aUnrestrictedURLs.end() ); + } + + // -------------------------------------------------------------------- + bool RestrictedPaths::isUrlAllowed( const String& _rURL, bool allowParents ) const + { + if ( m_aUnrestrictedURLs.empty() || !m_bFilterIsEnabled ) + return true; + + ::std::vector< String >::const_iterator aApprovedURL = ::std::find_if( + m_aUnrestrictedURLs.begin(), + m_aUnrestrictedURLs.end(), + CheckURLAllowed( _rURL, allowParents ) + ); + + return ( aApprovedURL != m_aUnrestrictedURLs.end() ); + } + +} // namespace svt diff --git a/svl/source/misc/sharecontrolfile.cxx b/svl/source/misc/sharecontrolfile.cxx new file mode 100644 index 000000000000..9249fa3f33de --- /dev/null +++ b/svl/source/misc/sharecontrolfile.cxx @@ -0,0 +1,376 @@ +/************************************************************************* + * + * 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: sharecontrolfile.cxx,v $ + * $Revision: 1.6.82.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <stdio.h> + +#include <com/sun/star/ucb/XSimpleFileAccess.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/ucb/InsertCommandArgument.hpp> +#include <com/sun/star/ucb/InteractiveIOException.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> + +#include <osl/time.h> +#include <osl/security.hxx> +#include <osl/socket.hxx> + +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/processfactory.hxx> +#include <ucbhelper/content.hxx> + +#include <tools/urlobj.hxx> +#include <tools/stream.hxx> +#include <unotools/bootstrap.hxx> +#include <unotools/streamwrap.hxx> + +#include <unotools/useroptions.hxx> + +#include <svl/sharecontrolfile.hxx> + +using namespace ::com::sun::star; + +namespace svt { + +// ---------------------------------------------------------------------- +ShareControlFile::ShareControlFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory ) +: LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".~sharing." ) ) ) +{ + OpenStream(); + + if ( !IsValid() ) + throw io::NotConnectedException(); +} + +// ---------------------------------------------------------------------- +ShareControlFile::~ShareControlFile() +{ + try + { + Close(); + } + catch( uno::Exception& ) + {} +} + +// ---------------------------------------------------------------------- +void ShareControlFile::OpenStream() +{ + // if it is called outside of constructor the mutex must be locked already + + if ( !m_xStream.is() && m_aURL.getLength() ) + { + uno::Reference< ucb::XCommandEnvironment > xDummyEnv; + ::ucbhelper::Content aContent = ::ucbhelper::Content( m_aURL, xDummyEnv ); + + uno::Reference< ucb::XContentIdentifier > xContId( aContent.get().is() ? aContent.get()->getIdentifier() : 0 ); + if ( !xContId.is() || !xContId->getContentProviderScheme().equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "file" ) ) ) ) + throw io::IOException(); // the implementation supports only local files for now + + uno::Reference< io::XStream > xStream; + + // Currently the locking of the original document is intended to be used. + // That means that the shared file should be accessed only when the original document is locked and only by user who has locked the document. + // TODO/LATER: should the own file locking be used? + + try + { + xStream = aContent.openWriteableStreamNoLock(); + } + catch ( ucb::InteractiveIOException const & e ) + { + if ( e.Code == ucb::IOErrorCode_NOT_EXISTING ) + { + // Create file... + SvMemoryStream aStream(0,0); + uno::Reference< io::XInputStream > xInput( new ::utl::OInputStreamWrapper( aStream ) ); + ucb::InsertCommandArgument aInsertArg; + aInsertArg.Data = xInput; + aInsertArg.ReplaceExisting = sal_False; + aContent.executeCommand( rtl::OUString::createFromAscii( "insert" ), uno::makeAny( aInsertArg ) ); + + // try to let the file be hidden if possible + try { + aContent.setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsHidden" ) ), uno::makeAny( sal_True ) ); + } catch( uno::Exception& ) {} + + // Try to open one more time + xStream = aContent.openWriteableStreamNoLock(); + } + else + throw; + } + + m_xSeekable.set( xStream, uno::UNO_QUERY_THROW ); + m_xInputStream.set( xStream->getInputStream(), uno::UNO_QUERY_THROW ); + m_xOutputStream.set( xStream->getOutputStream(), uno::UNO_QUERY_THROW ); + m_xTruncate.set( m_xOutputStream, uno::UNO_QUERY_THROW ); + m_xStream = xStream; + } +} + +// ---------------------------------------------------------------------- +void ShareControlFile::Close() +{ + // if it is called outside of destructor the mutex must be locked + + if ( m_xStream.is() ) + { + try + { + if ( m_xInputStream.is() ) + m_xInputStream->closeInput(); + if ( m_xOutputStream.is() ) + m_xOutputStream->closeOutput(); + } + catch( uno::Exception& ) + {} + + m_xStream = uno::Reference< io::XStream >(); + m_xInputStream = uno::Reference< io::XInputStream >(); + m_xOutputStream = uno::Reference< io::XOutputStream >(); + m_xSeekable = uno::Reference< io::XSeekable >(); + m_xTruncate = uno::Reference< io::XTruncate >(); + m_aUsersData.realloc( 0 ); + } +} + +// ---------------------------------------------------------------------- +uno::Sequence< uno::Sequence< ::rtl::OUString > > ShareControlFile::GetUsersData() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + if ( !m_aUsersData.getLength() ) + { + sal_Int64 nLength = m_xSeekable->getLength(); + if ( nLength > SAL_MAX_INT32 ) + throw uno::RuntimeException(); + + uno::Sequence< sal_Int8 > aBuffer( (sal_Int32)nLength ); + m_xSeekable->seek( 0 ); + + sal_Int32 nRead = m_xInputStream->readBytes( aBuffer, (sal_Int32)nLength ); + nLength -= nRead; + while ( nLength > 0 ) + { + uno::Sequence< sal_Int8 > aTmpBuf( (sal_Int32)nLength ); + nRead = m_xInputStream->readBytes( aTmpBuf, (sal_Int32)nLength ); + if ( nRead > nLength ) + throw uno::RuntimeException(); + + for ( sal_Int32 nInd = 0; nInd < nRead; nInd++ ) + aBuffer[aBuffer.getLength() - (sal_Int32)nLength + nInd] = aTmpBuf[nInd]; + nLength -= nRead; + } + + m_aUsersData = ParseList( aBuffer ); + } + + return m_aUsersData; +} + +// ---------------------------------------------------------------------- +void ShareControlFile::SetUsersDataAndStore( const uno::Sequence< uno::Sequence< ::rtl::OUString > >& aUsersData ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + if ( !m_xTruncate.is() || !m_xOutputStream.is() || !m_xSeekable.is() ) + throw uno::RuntimeException(); + + m_xTruncate->truncate(); + m_xSeekable->seek( 0 ); + + ::rtl::OUStringBuffer aBuffer; + for ( sal_Int32 nInd = 0; nInd < aUsersData.getLength(); nInd++ ) + { + if ( aUsersData[nInd].getLength() != SHARED_ENTRYSIZE ) + throw lang::IllegalArgumentException(); + + for ( sal_Int32 nEntryInd = 0; nEntryInd < SHARED_ENTRYSIZE; nEntryInd++ ) + { + aBuffer.append( EscapeCharacters( aUsersData[nInd][nEntryInd] ) ); + if ( nEntryInd < SHARED_ENTRYSIZE - 1 ) + aBuffer.append( (sal_Unicode)',' ); + else + aBuffer.append( (sal_Unicode)';' ); + } + } + + ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) ); + uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() ); + m_xOutputStream->writeBytes( aData ); + m_aUsersData = aUsersData; +} + +// ---------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > ShareControlFile::InsertOwnEntry() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + GetUsersData(); + uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 ); + uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry(); + + sal_Bool bExists = sal_False; + sal_Int32 nNewInd = 0; + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE ) + { + if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aNewEntry[SHARED_LOCALHOST_ID] + && m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aNewEntry[SHARED_SYSUSERNAME_ID] + && m_aUsersData[nInd][SHARED_USERURL_ID] == aNewEntry[SHARED_USERURL_ID] ) + { + if ( !bExists ) + { + aNewData[nNewInd] = aNewEntry; + bExists = sal_True; + } + } + else + { + aNewData[nNewInd] = m_aUsersData[nInd]; + } + + nNewInd++; + } + } + + if ( !bExists ) + aNewData[nNewInd++] = aNewEntry; + + aNewData.realloc( nNewInd ); + SetUsersDataAndStore( aNewData ); + + return aNewEntry; +} + +// ---------------------------------------------------------------------- +bool ShareControlFile::HasOwnEntry() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + { + throw io::NotConnectedException(); + } + + GetUsersData(); + uno::Sequence< ::rtl::OUString > aEntry = GenerateOwnEntry(); + + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); ++nInd ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE && + m_aUsersData[nInd][SHARED_LOCALHOST_ID] == aEntry[SHARED_LOCALHOST_ID] && + m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] == aEntry[SHARED_SYSUSERNAME_ID] && + m_aUsersData[nInd][SHARED_USERURL_ID] == aEntry[SHARED_USERURL_ID] ) + { + return true; + } + } + + return false; +} + +// ---------------------------------------------------------------------- +void ShareControlFile::RemoveEntry( const uno::Sequence< ::rtl::OUString >& aArgEntry ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + GetUsersData(); + + uno::Sequence< ::rtl::OUString > aEntry = aArgEntry; + if ( aEntry.getLength() != SHARED_ENTRYSIZE ) + aEntry = GenerateOwnEntry(); + + uno::Sequence< ::uno::Sequence< ::rtl::OUString > > aNewData( m_aUsersData.getLength() + 1 ); + + sal_Int32 nNewInd = 0; + for ( sal_Int32 nInd = 0; nInd < m_aUsersData.getLength(); nInd++ ) + { + if ( m_aUsersData[nInd].getLength() == SHARED_ENTRYSIZE ) + { + if ( m_aUsersData[nInd][SHARED_LOCALHOST_ID] != aEntry[SHARED_LOCALHOST_ID] + || m_aUsersData[nInd][SHARED_SYSUSERNAME_ID] != aEntry[SHARED_SYSUSERNAME_ID] + || m_aUsersData[nInd][SHARED_USERURL_ID] != aEntry[SHARED_USERURL_ID] ) + { + aNewData[nNewInd] = m_aUsersData[nInd]; + nNewInd++; + } + } + } + + aNewData.realloc( nNewInd ); + SetUsersDataAndStore( aNewData ); + + if ( !nNewInd ) + { + // try to remove the file if it is empty + RemoveFile(); + } +} + +// ---------------------------------------------------------------------- +void ShareControlFile::RemoveFile() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !IsValid() ) + throw io::NotConnectedException(); + + Close(); + + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess > xSimpleFileAccess( + xFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess") ), + uno::UNO_QUERY_THROW ); + xSimpleFileAccess->kill( m_aURL ); +} + +} // namespace svt + diff --git a/svl/source/misc/strmadpt.cxx b/svl/source/misc/strmadpt.cxx new file mode 100644 index 000000000000..9803f2bcc32f --- /dev/null +++ b/svl/source/misc/strmadpt.cxx @@ -0,0 +1,1048 @@ +/************************************************************************* + * + * 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: strmadpt.cxx,v $ + * $Revision: 1.5.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <functional> // needed under Solaris when including <algorithm>... + +#include <algorithm> +#include <limits> +#include <set> +#include <rtl/alloc.h> +#include <rtl/memory.h> +#include <instrm.hxx> +#include <outstrm.hxx> +#include <strmadpt.hxx> + +using namespace com::sun::star; + +//============================================================================ +class SvDataPipe_Impl +{ +public: + enum SeekResult { SEEK_BEFORE_MARKED, SEEK_OK, SEEK_PAST_END }; + +private: + struct Page + { + Page * m_pPrev; + Page * m_pNext; + sal_Int8 * m_pStart; + sal_Int8 * m_pRead; + sal_Int8 * m_pEnd; + sal_uInt32 m_nOffset; + sal_Int8 m_aBuffer[1]; + }; + + std::multiset< sal_uInt32 > m_aMarks; + Page * m_pFirstPage; + Page * m_pReadPage; + Page * m_pWritePage; + sal_Int8 * m_pReadBuffer; + sal_uInt32 m_nReadBufferSize; + sal_uInt32 m_nReadBufferFilled; + sal_uInt32 m_nPageSize; + sal_uInt32 m_nMinPages; + sal_uInt32 m_nMaxPages; + sal_uInt32 m_nPages; + bool m_bEOF; + + bool remove(Page * pPage); + +public: + inline SvDataPipe_Impl(sal_uInt32 nThePageSize = 1000, + sal_uInt32 nTheMinPages = 100, + sal_uInt32 nTheMaxPages + = std::numeric_limits< sal_uInt32 >::max()); + + ~SvDataPipe_Impl(); + + inline void setReadBuffer(sal_Int8 * pBuffer, sal_uInt32 nSize); + + sal_uInt32 read(); + + void clearReadBuffer() { m_pReadBuffer = 0; } + + sal_uInt32 write(sal_Int8 const * pBuffer, sal_uInt32 nSize); + + void setEOF() { m_bEOF = true; } + + inline bool isEOF() const; + + bool addMark(sal_uInt32 nPosition); + + bool removeMark(sal_uInt32 nPosition); + + inline sal_uInt32 getReadPosition() const; + + SeekResult setReadPosition(sal_uInt32 nPosition); +}; + +SvDataPipe_Impl::SvDataPipe_Impl(sal_uInt32 nThePageSize, + sal_uInt32 nTheMinPages, + sal_uInt32 nTheMaxPages): + m_pFirstPage(0), + m_pReadPage(0), + m_pWritePage(0), + m_pReadBuffer(0), + m_nPageSize(std::min< sal_uInt32 >( + std::max< sal_uInt32 >(nThePageSize, sal_uInt32(1)), + sal_uInt32(std::numeric_limits< sal_uInt32 >::max() + - sizeof (Page) + 1))), + m_nMinPages(std::max< sal_uInt32 >(nTheMinPages, sal_uInt32(1))), + m_nMaxPages(std::max< sal_uInt32 >(nTheMaxPages, sal_uInt32(1))), + m_nPages(0), + m_bEOF(false) +{} + +inline void SvDataPipe_Impl::setReadBuffer(sal_Int8 * pBuffer, + sal_uInt32 nSize) +{ + m_pReadBuffer = pBuffer; + m_nReadBufferSize = nSize; + m_nReadBufferFilled = 0; +} + +inline bool SvDataPipe_Impl::isEOF() const +{ + return m_bEOF && m_pReadPage == m_pWritePage + && (!m_pReadPage || m_pReadPage->m_pRead == m_pReadPage->m_pEnd); +} + +inline sal_uInt32 SvDataPipe_Impl::getReadPosition() const +{ + return m_pReadPage == 0 ? 0 : + m_pReadPage->m_nOffset + + (m_pReadPage->m_pRead + - m_pReadPage->m_aBuffer); +} + +//============================================================================ +// +// SvOutputStreamOpenLockBytes +// +//============================================================================ + +TYPEINIT1(SvOutputStreamOpenLockBytes, SvOpenLockBytes) + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::ReadAt(ULONG, void *, ULONG, ULONG *) + const +{ + return ERRCODE_IO_CANTREAD; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::WriteAt(ULONG nPos, void const * pBuffer, + ULONG nCount, ULONG * pWritten) +{ + if (nPos != m_nPosition) + return ERRCODE_IO_CANTWRITE; + return FillAppend(pBuffer, nCount, pWritten); +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::Flush() const +{ + if (!m_xOutputStream.is()) + return ERRCODE_IO_CANTWRITE; + try + { + m_xOutputStream->flush(); + } + catch (io::IOException) + { + return ERRCODE_IO_CANTWRITE; + } + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::SetSize(ULONG) +{ + return ERRCODE_IO_NOTSUPPORTED; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::Stat(SvLockBytesStat * pStat, + SvLockBytesStatFlag) const +{ + if (pStat) + pStat->nSize = m_nPosition; + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ErrCode SvOutputStreamOpenLockBytes::FillAppend(void const * pBuffer, + ULONG nCount, + ULONG * pWritten) +{ + if (!m_xOutputStream.is()) + return ERRCODE_IO_CANTWRITE; + if (nCount > 0 + && nCount > std::numeric_limits< ULONG >::max() - m_nPosition) + { + nCount = std::numeric_limits< ULONG >::max() - m_nPosition; + if (nCount == 0) + return ERRCODE_IO_CANTWRITE; + } + try + { + m_xOutputStream-> + writeBytes(uno::Sequence< sal_Int8 >( + static_cast< sal_Int8 const * >(pBuffer), nCount)); + } + catch (io::IOException) + { + return ERRCODE_IO_CANTWRITE; + } + m_nPosition += nCount; + if (pWritten) + *pWritten = nCount; + return ERRCODE_NONE; +} + +//============================================================================ +// virtual +ULONG SvOutputStreamOpenLockBytes::Tell() const +{ + return m_nPosition; +} + +//============================================================================ +// virtual +ULONG SvOutputStreamOpenLockBytes::Seek(ULONG) +{ + return m_nPosition; +} + +//============================================================================ +// virtual +void SvOutputStreamOpenLockBytes::Terminate() +{ + if (m_xOutputStream.is()) + try + { + m_xOutputStream->closeOutput(); + } + catch (io::IOException) {} +} + +//============================================================================ +// +// SvLockBytesInputStream +// +//============================================================================ + +// virtual +uno::Any SAL_CALL SvLockBytesInputStream::queryInterface(uno::Type const & + rType) + throw (uno::RuntimeException) +{ + uno::Any + aReturn(cppu::queryInterface(rType, + static_cast< io::XInputStream * >(this), + static_cast< io::XSeekable * >(this))); + return aReturn.hasValue() ? aReturn : OWeakObject::queryInterface(rType); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::acquire() throw () +{ + OWeakObject::acquire(); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::release() throw () +{ + OWeakObject::release(); +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL +SvLockBytesInputStream::readBytes(uno::Sequence< sal_Int8 > & rData, + sal_Int32 nBytesToRead) + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if ( + nBytesToRead < 0 || + ( + static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE && + nBytesToRead > 0 + ) + ) + { + throw io::IOException(); + } + rData.realloc(nBytesToRead); + sal_Int32 nSize = 0; + while (nSize < nBytesToRead) + { + sal_Size nCount; + ErrCode nError = m_xLockBytes->ReadAt(static_cast<sal_Size>( + m_nPosition), + rData.getArray() + nSize, + nBytesToRead - nSize, &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw io::IOException(); + m_nPosition += nCount; + nSize += nCount; + if (nError == ERRCODE_NONE && nCount == 0) + break; + } + rData.realloc(nSize); + return nSize; +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL +SvLockBytesInputStream::readSomeBytes(uno::Sequence< sal_Int8 > & rData, + sal_Int32 nMaxBytesToRead) + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if (static_cast<sal_uInt64>(m_nPosition) > SAL_MAX_SIZE + && nMaxBytesToRead > 0) + throw io::IOException(); + rData.realloc(nMaxBytesToRead); + sal_Size nCount = 0; + if (nMaxBytesToRead > 0) + { + ErrCode nError; + do + { + nError = m_xLockBytes->ReadAt(static_cast<sal_Size>(m_nPosition), + rData.getArray(), + nMaxBytesToRead < 0 ? + 0 : nMaxBytesToRead, + &nCount); + if (nError != ERRCODE_NONE && nError != ERRCODE_IO_PENDING) + throw io::IOException(); + m_nPosition += nCount; + } + while (nCount == 0 && nError == ERRCODE_IO_PENDING); + } + rData.realloc(sal_Int32(nCount)); + return sal_Int32(nCount); +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::skipBytes(sal_Int32 nBytesToSkip) + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + if (nBytesToSkip < 0) + throw io::IOException(); + if (nBytesToSkip > SAL_MAX_INT64 - m_nPosition) + throw io::BufferSizeExceededException(); + m_nPosition += nBytesToSkip; +} + +//============================================================================ +// virtual +sal_Int32 SAL_CALL SvLockBytesInputStream::available() + throw (io::IOException, uno::RuntimeException) +{ + OSL_ASSERT(m_nPosition >= 0); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + SvLockBytesStat aStat; + if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw io::IOException(); + return aStat.nSize <= static_cast<sal_uInt64>(m_nPosition) ? + 0 : + static_cast<sal_Size>(aStat.nSize - m_nPosition) <= + static_cast<sal_uInt32>(SAL_MAX_INT32) ? + static_cast<sal_Int32>(aStat.nSize - m_nPosition) : + SAL_MAX_INT32; +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::closeInput() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + m_xLockBytes = 0; +} + +//============================================================================ +// virtual +void SAL_CALL SvLockBytesInputStream::seek(sal_Int64 nLocation) + throw (lang::IllegalArgumentException, io::IOException, + uno::RuntimeException) +{ + if (nLocation < 0) + throw lang::IllegalArgumentException(); + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + m_nPosition = nLocation; +} + +//============================================================================ +// virtual +sal_Int64 SAL_CALL SvLockBytesInputStream::getPosition() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + return m_nPosition; +} + +//============================================================================ +// virtual +sal_Int64 SAL_CALL SvLockBytesInputStream::getLength() + throw (io::IOException, uno::RuntimeException) +{ + if (!m_xLockBytes.Is()) + throw io::NotConnectedException(); + SvLockBytesStat aStat; + if (m_xLockBytes->Stat(&aStat, SVSTATFLAG_DEFAULT) != ERRCODE_NONE) + throw io::IOException(); +#if SAL_TYPES_SIZEOFPOINTER > 4 // avoid warnings if sal_Size < sal_Int64 + if (aStat.nSize > static_cast<sal_uInt64>(SAL_MAX_INT64)) + throw io::IOException(); +#endif + return aStat.nSize; +} + +//============================================================================ +// +// SvInputStream +// +//============================================================================ + +bool SvInputStream::open() +{ + if (GetError() != ERRCODE_NONE) + return false; + if (!(m_xSeekable.is() || m_pPipe)) + { + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_INVALIDDEVICE); + return false; + } + m_xSeekable + = uno::Reference< io::XSeekable >(m_xStream, uno::UNO_QUERY); + if (!m_xSeekable.is()) + m_pPipe = new SvDataPipe_Impl; + } + return true; +} + +//============================================================================ +// virtual +ULONG SvInputStream::GetData(void * pData, ULONG nSize) +{ + if (!open()) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + sal_uInt32 nRead = 0; + if (m_xSeekable.is()) + { + if (m_nSeekedFrom != STREAM_SEEK_TO_END) + { + try + { + m_xSeekable->seek(m_nSeekedFrom); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + m_nSeekedFrom = STREAM_SEEK_TO_END; + } + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min(ULONG(nSize - nRead), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + uno::Sequence< sal_Int8 > aBuffer; + sal_Int32 nCount; + try + { + nCount = m_xStream->readBytes(aBuffer, nRemain); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + return nRead; + } + rtl_copyMemory(static_cast< sal_Int8 * >(pData) + nRead, + aBuffer.getConstArray(), sal_uInt32(nCount)); + nRead += nCount; + if (nCount < nRemain) + break; + } + } + else + { + if (m_nSeekedFrom != STREAM_SEEK_TO_END) + { + SetError(ERRCODE_IO_CANTREAD); + return 0; + } + m_pPipe->setReadBuffer(static_cast< sal_Int8 * >(pData), nSize); + nRead = m_pPipe->read(); + if (nRead < nSize && !m_pPipe->isEOF()) + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min( + ULONG(nSize - nRead), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + uno::Sequence< sal_Int8 > aBuffer; + sal_Int32 nCount; + try + { + nCount = m_xStream->readBytes(aBuffer, nRemain); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTREAD); + break; + } + m_pPipe->write(aBuffer.getConstArray(), sal_uInt32(nCount)); + nRead += m_pPipe->read(); + if (nCount < nRemain) + { + m_xStream->closeInput(); + m_pPipe->setEOF(); + break; + } + } + m_pPipe->clearReadBuffer(); + } + return nRead; +} + +//============================================================================ +// virtual +ULONG SvInputStream::PutData(void const *, ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +void SvInputStream::FlushData() +{} + +//============================================================================ +// virtual +ULONG SvInputStream::SeekPos(ULONG nPos) +{ + if (open()) + { + if (nPos == STREAM_SEEK_TO_END) + { + if (m_nSeekedFrom == STREAM_SEEK_TO_END) + { + if (m_xSeekable.is()) + try + { + sal_Int64 nLength = m_xSeekable->getLength(); + OSL_ASSERT(nLength >= 0); + if (static_cast<sal_uInt64>(nLength) + < STREAM_SEEK_TO_END) + { + m_nSeekedFrom = Tell(); + return ULONG(nLength); + } + } + catch (io::IOException) {} + else + return Tell(); //@@@ + } + else + return Tell(); + } + else if (nPos == m_nSeekedFrom) + { + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + else if (m_xSeekable.is()) + try + { + m_xSeekable->seek(nPos); + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + catch (io::IOException) {} + else if (m_pPipe->setReadPosition(nPos) == SvDataPipe_Impl::SEEK_OK) + { + m_nSeekedFrom = STREAM_SEEK_TO_END; + return nPos; + } + } + SetError(ERRCODE_IO_CANTSEEK); + return Tell(); +} + +//============================================================================ +// virtual +void SvInputStream::SetSize(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); +} + +//============================================================================ +SvInputStream::SvInputStream( + com::sun::star::uno::Reference< com::sun::star::io::XInputStream > + const & + rTheStream): + m_xStream(rTheStream), + m_pPipe(0), + m_nSeekedFrom(STREAM_SEEK_TO_END) +{ + SetBufferSize(0); +} + +//============================================================================ +// virtual +SvInputStream::~SvInputStream() +{ + if (m_xStream.is()) + try + { + m_xStream->closeInput(); + } + catch (io::IOException) {} + delete m_pPipe; +} + +//============================================================================ +// virtual +USHORT SvInputStream::IsA() const +{ + return 0; +} + +//============================================================================ +// virtual +void SvInputStream::AddMark(ULONG nPos) +{ + if (open() && m_pPipe) + m_pPipe->addMark(nPos); +} + +//============================================================================ +// virtual +void SvInputStream::RemoveMark(ULONG nPos) +{ + if (open() && m_pPipe) + m_pPipe->removeMark(nPos); +} + +//============================================================================ +// +// SvOutputStream +// +//============================================================================ + +// virtual +ULONG SvOutputStream::GetData(void *, ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +ULONG SvOutputStream::PutData(void const * pData, ULONG nSize) +{ + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_CANTWRITE); + return 0; + } + ULONG nWritten = 0; + for (;;) + { + sal_Int32 nRemain + = sal_Int32( + std::min(ULONG(nSize - nWritten), + ULONG(std::numeric_limits< sal_Int32 >::max()))); + if (nRemain == 0) + break; + try + { + m_xStream->writeBytes(uno::Sequence< sal_Int8 >( + static_cast<const sal_Int8 * >(pData) + + nWritten, + nRemain)); + } + catch (io::IOException) + { + SetError(ERRCODE_IO_CANTWRITE); + break; + } + nWritten += nRemain; + } + return nWritten; +} + +//============================================================================ +// virtual +ULONG SvOutputStream::SeekPos(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); + return 0; +} + +//============================================================================ +// virtual +void SvOutputStream::FlushData() +{ + if (!m_xStream.is()) + { + SetError(ERRCODE_IO_INVALIDDEVICE); + return; + } + try + { + m_xStream->flush(); + } + catch (io::IOException) {} +} + +//============================================================================ +// virtual +void SvOutputStream::SetSize(ULONG) +{ + SetError(ERRCODE_IO_NOTSUPPORTED); +} + +//============================================================================ +SvOutputStream::SvOutputStream(uno::Reference< io::XOutputStream > const & + rTheStream): + m_xStream(rTheStream) +{ + SetBufferSize(0); +} + +//============================================================================ +// virtual +SvOutputStream::~SvOutputStream() +{ + if (m_xStream.is()) + try + { + m_xStream->closeOutput(); + } + catch (io::IOException) {} +} + +//============================================================================ +// virtual +USHORT SvOutputStream::IsA() const +{ + return 0; +} + +//============================================================================ +// +// SvDataPipe_Impl +// +//============================================================================ + +bool SvDataPipe_Impl::remove(Page * pPage) +{ + if ( + pPage != m_pFirstPage || + m_pReadPage == m_pFirstPage || + ( + !m_aMarks.empty() && + *m_aMarks.begin() < m_pFirstPage->m_nOffset + m_nPageSize + ) + ) + { + return false; + } + + m_pFirstPage = m_pFirstPage->m_pNext; + + if (m_nPages <= m_nMinPages) + return true; + + pPage->m_pPrev->m_pNext = pPage->m_pNext; + pPage->m_pNext->m_pPrev = pPage->m_pPrev; + rtl_freeMemory(pPage); + --m_nPages; + + return true; +} + +//============================================================================ +SvDataPipe_Impl::~SvDataPipe_Impl() +{ + if (m_pFirstPage != 0) + for (Page * pPage = m_pFirstPage;;) + { + Page * pNext = pPage->m_pNext; + rtl_freeMemory(pPage); + if (pNext == m_pFirstPage) + break; + pPage = pNext; + } +} + +//============================================================================ +sal_uInt32 SvDataPipe_Impl::read() +{ + if (m_pReadBuffer == 0 || m_nReadBufferSize == 0 || m_pReadPage == 0) + return 0; + + sal_uInt32 nSize = m_nReadBufferSize; + sal_uInt32 nRemain = m_nReadBufferSize - m_nReadBufferFilled; + + m_pReadBuffer += m_nReadBufferFilled; + m_nReadBufferSize -= m_nReadBufferFilled; + m_nReadBufferFilled = 0; + + while (nRemain > 0) + { + sal_uInt32 nBlock = std::min(sal_uInt32(m_pReadPage->m_pEnd + - m_pReadPage->m_pRead), + nRemain); + rtl_copyMemory(m_pReadBuffer, m_pReadPage->m_pRead, nBlock); + m_pReadPage->m_pRead += nBlock; + m_pReadBuffer += nBlock; + m_nReadBufferSize -= nBlock; + m_nReadBufferFilled = 0; + nRemain -= nBlock; + + if (m_pReadPage == m_pWritePage) + break; + + if (m_pReadPage->m_pRead == m_pReadPage->m_pEnd) + { + Page * pRemove = m_pReadPage; + m_pReadPage = pRemove->m_pNext; + remove(pRemove); + } + } + + return nSize - nRemain; +} + +//============================================================================ +sal_uInt32 SvDataPipe_Impl::write(sal_Int8 const * pBuffer, sal_uInt32 nSize) +{ + if (nSize == 0) + return 0; + + if (m_pWritePage == 0) + { + m_pFirstPage + = static_cast< Page * >(rtl_allocateMemory(sizeof (Page) + + m_nPageSize + - 1)); + m_pFirstPage->m_pPrev = m_pFirstPage; + m_pFirstPage->m_pNext = m_pFirstPage; + m_pFirstPage->m_pStart = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_pRead = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_pEnd = m_pFirstPage->m_aBuffer; + m_pFirstPage->m_nOffset = 0; + m_pReadPage = m_pFirstPage; + m_pWritePage = m_pFirstPage; + ++m_nPages; + } + + sal_uInt32 nRemain = nSize; + + if (m_pReadBuffer != 0 && m_pReadPage == m_pWritePage + && m_pReadPage->m_pRead == m_pWritePage->m_pEnd) + { + sal_uInt32 nBlock = std::min(nRemain, + sal_uInt32(m_nReadBufferSize + - m_nReadBufferFilled)); + sal_uInt32 nPosition = m_pWritePage->m_nOffset + + (m_pWritePage->m_pEnd + - m_pWritePage->m_aBuffer); + if (!m_aMarks.empty()) + nBlock = *m_aMarks.begin() > nPosition ? + std::min(nBlock, sal_uInt32(*m_aMarks.begin() + - nPosition)) : + 0; + + if (nBlock > 0) + { + rtl_copyMemory(m_pReadBuffer + m_nReadBufferFilled, pBuffer, + nBlock); + m_nReadBufferFilled += nBlock; + nRemain -= nBlock; + + nPosition += nBlock; + m_pWritePage->m_nOffset = (nPosition / m_nPageSize) * m_nPageSize; + m_pWritePage->m_pStart = m_pWritePage->m_aBuffer + + nPosition % m_nPageSize; + m_pWritePage->m_pRead = m_pWritePage->m_pStart; + m_pWritePage->m_pEnd = m_pWritePage->m_pStart; + } + } + + if (nRemain > 0) + for (;;) + { + sal_uInt32 nBlock + = std::min(sal_uInt32(m_pWritePage->m_aBuffer + m_nPageSize + - m_pWritePage->m_pEnd), + nRemain); + rtl_copyMemory(m_pWritePage->m_pEnd, pBuffer, nBlock); + m_pWritePage->m_pEnd += nBlock; + pBuffer += nBlock; + nRemain -= nBlock; + + if (nRemain == 0) + break; + + if (m_pWritePage->m_pNext == m_pFirstPage) + { + if (m_nPages == m_nMaxPages) + break; + + Page * pNew + = static_cast< Page * >(rtl_allocateMemory( + sizeof (Page) + m_nPageSize + - 1)); + pNew->m_pPrev = m_pWritePage; + pNew->m_pNext = m_pWritePage->m_pNext; + + m_pWritePage->m_pNext->m_pPrev = pNew; + m_pWritePage->m_pNext = pNew; + ++m_nPages; + } + + m_pWritePage->m_pNext->m_nOffset = m_pWritePage->m_nOffset + + m_nPageSize; + m_pWritePage = m_pWritePage->m_pNext; + m_pWritePage->m_pStart = m_pWritePage->m_aBuffer; + m_pWritePage->m_pRead = m_pWritePage->m_aBuffer; + m_pWritePage->m_pEnd = m_pWritePage->m_aBuffer; + } + + return nSize - nRemain; +} + +//============================================================================ +bool SvDataPipe_Impl::addMark(sal_uInt32 nPosition) +{ + if (m_pFirstPage != 0 && m_pFirstPage->m_nOffset > nPosition) + return false; + m_aMarks.insert(nPosition); + return true; +} + +//============================================================================ +bool SvDataPipe_Impl::removeMark(sal_uInt32 nPosition) +{ + std::multiset< sal_uInt32 >::iterator t = m_aMarks.find(nPosition); + if (t == m_aMarks.end()) + return false; + m_aMarks.erase(t); + while (remove(m_pFirstPage)) ; + return true; +} + +//============================================================================ +SvDataPipe_Impl::SeekResult SvDataPipe_Impl::setReadPosition(sal_uInt32 + nPosition) +{ + if (m_pFirstPage == 0) + return nPosition == 0 ? SEEK_OK : SEEK_PAST_END; + + if (nPosition + <= m_pReadPage->m_nOffset + + (m_pReadPage->m_pRead - m_pReadPage->m_aBuffer)) + { + if (nPosition + < m_pFirstPage->m_nOffset + + (m_pFirstPage->m_pStart - m_pFirstPage->m_aBuffer)) + return SEEK_BEFORE_MARKED; + + while (nPosition < m_pReadPage->m_nOffset) + { + m_pReadPage->m_pRead = m_pReadPage->m_pStart; + m_pReadPage = m_pReadPage->m_pPrev; + } + } + else + { + if (nPosition + > m_pWritePage->m_nOffset + + (m_pWritePage->m_pEnd - m_pWritePage->m_aBuffer)) + return SEEK_PAST_END; + + while (m_pReadPage != m_pWritePage + && nPosition >= m_pReadPage->m_nOffset + m_nPageSize) + { + Page * pRemove = m_pReadPage; + m_pReadPage = pRemove->m_pNext; + remove(pRemove); + } + } + + m_pReadPage->m_pRead = m_pReadPage->m_aBuffer + + (nPosition - m_pReadPage->m_nOffset); + return SEEK_OK; +} + diff --git a/svl/source/misc/svldata.cxx b/svl/source/misc/svldata.cxx new file mode 100644 index 000000000000..0ba8075069cd --- /dev/null +++ b/svl/source/misc/svldata.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * 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: svldata.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <map> +#include <tools/resmgr.hxx> +#include <tools/shl.hxx> +#include <vos/process.hxx> +#include <svl/svldata.hxx> + +namespace unnamed_svl_svldata {} +using namespace unnamed_svl_svldata; + // unnamed namespaces don't work well yet + +//============================================================================ +namespace unnamed_svl_svldata { + +typedef std::map< rtl::OUString, SimpleResMgr * > SimpleResMgrMap; + +} + +//============================================================================ +// +// ImpSvlData +// +//============================================================================ + +static ImpSvlData* pSvlData = 0; + +ImpSvlData::~ImpSvlData() +{ + for (SimpleResMgrMap::iterator t + = static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs)->begin(); + t != static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs)->end(); ++t) + delete t->second; + delete static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs); +} + +//============================================================================ +SimpleResMgr* ImpSvlData::GetSimpleRM(const ::com::sun::star::lang::Locale& rLocale) +{ + if (!m_pThreadsafeRMs) + m_pThreadsafeRMs = new SimpleResMgrMap; + rtl::OUString aISOcode = rLocale.Language; + aISOcode += rtl::OStringToOUString("-", RTL_TEXTENCODING_UTF8); + aISOcode += rLocale.Country; + + SimpleResMgr *& rResMgr + = (*static_cast< SimpleResMgrMap * >(m_pThreadsafeRMs))[aISOcode]; + if (!rResMgr) + { + rResMgr = new SimpleResMgr(CREATEVERSIONRESMGR_NAME(svs), rLocale ); + } + return rResMgr; +} + +//============================================================================ +// static +ImpSvlData & ImpSvlData::GetSvlData() +{ + if (!pSvlData) + pSvlData= new ImpSvlData; + return *pSvlData; +} + diff --git a/svl/source/misc/urihelper.cxx b/svl/source/misc/urihelper.cxx new file mode 100644 index 000000000000..5473bf1c995d --- /dev/null +++ b/svl/source/misc/urihelper.cxx @@ -0,0 +1,952 @@ +/************************************************************************* + * + * 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: urihelper.cxx,v $ + * $Revision: 1.22.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <urihelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" +#include "com/sun/star/lang/XMultiComponentFactory.hpp" +#include "com/sun/star/ucb/Command.hpp" +#include <com/sun/star/ucb/FileSystemNotation.hpp> +#include "com/sun/star/ucb/IllegalIdentifierException.hpp" +#include "com/sun/star/ucb/UnsupportedCommandException.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/ucb/XCommandProcessor.hpp" +#include "com/sun/star/ucb/XContent.hpp" +#include "com/sun/star/ucb/XContentIdentifierFactory.hpp" +#include "com/sun/star/ucb/XContentProvider.hpp" +#include <com/sun/star/ucb/XContentProviderManager.hpp> +#include "com/sun/star/uno/Any.hxx" +#include "com/sun/star/uno/Exception.hpp" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/Sequence.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uri/UriReferenceFactory.hpp" +#include "com/sun/star/uri/XUriReference.hpp" +#include "com/sun/star/uri/XUriReferenceFactory.hpp" +#include "cppuhelper/exc_hlp.hxx" +#include "comphelper/processfactory.hxx" +#include "osl/diagnose.h" +#include "rtl/ustrbuf.hxx" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include <tools/debug.hxx> +#include <tools/inetmime.hxx> +#include <ucbhelper/contentbroker.hxx> +#include <unotools/charclass.hxx> +#include "rtl/instance.hxx" + +namespace unnamed_svl_urihelper {} +using namespace unnamed_svl_urihelper; + // unnamed namespaces don't work well yet... + +namespace css = com::sun::star; +using namespace com::sun::star; + +//============================================================================ +// +// SmartRel2Abs +// +//============================================================================ + +namespace unnamed_svl_urihelper { + +inline UniString toUniString(ByteString const & rString) +{ + return UniString(rString, RTL_TEXTENCODING_ISO_8859_1); +} + +inline UniString toUniString(UniString const & rString) +{ + return rString; +} + +template< typename Str > +inline UniString SmartRel2Abs_Impl(INetURLObject const & rTheBaseURIRef, + Str const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism + eEncodeMechanism, + INetURLObject::DecodeMechanism + eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + // Backwards compatibility: + if (rTheRelURIRef.Len() != 0 && rTheRelURIRef.GetChar(0) == '#') + return toUniString(rTheRelURIRef); + + INetURLObject aAbsURIRef; + if (rTheBaseURIRef.HasError()) + aAbsURIRef. + SetSmartURL(rTheRelURIRef, eEncodeMechanism, eCharset, eStyle); + else + { + bool bWasAbsolute; + aAbsURIRef = rTheBaseURIRef.smartRel2Abs(rTheRelURIRef, + bWasAbsolute, + bIgnoreFragment, + eEncodeMechanism, + eCharset, + bRelativeNonURIs, + eStyle); + if (bCheckFileExists + && !bWasAbsolute + && (aAbsURIRef.GetProtocol() == INET_PROT_FILE + || aAbsURIRef.GetProtocol() == INET_PROT_VND_SUN_STAR_WFS)) + { + INetURLObject aNonFileURIRef; + aNonFileURIRef.SetSmartURL(rTheRelURIRef, + eEncodeMechanism, + eCharset, + eStyle); + if (!aNonFileURIRef.HasError() + && aNonFileURIRef.GetProtocol() != INET_PROT_FILE) + { + bool bMaybeFile = false; + if (rMaybeFileHdl.IsSet()) + { + UniString aFilePath(toUniString(rTheRelURIRef)); + bMaybeFile = rMaybeFileHdl.Call(&aFilePath) != 0; + } + if (!bMaybeFile) + aAbsURIRef = aNonFileURIRef; + } + } + } + return aAbsURIRef.GetMainURL(eDecodeMechanism, eCharset); +} + +} + +UniString +URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + ByteString const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl, + bCheckFileExists, bIgnoreFragment, + eEncodeMechanism, eDecodeMechanism, eCharset, + bRelativeNonURIs, eStyle); +} + +UniString +URIHelper::SmartRel2Abs(INetURLObject const & rTheBaseURIRef, + UniString const & rTheRelURIRef, + Link const & rMaybeFileHdl, + bool bCheckFileExists, + bool bIgnoreFragment, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset, + bool bRelativeNonURIs, + INetURLObject::FSysStyle eStyle) +{ + return SmartRel2Abs_Impl(rTheBaseURIRef, rTheRelURIRef, rMaybeFileHdl, + bCheckFileExists, bIgnoreFragment, + eEncodeMechanism, eDecodeMechanism, eCharset, + bRelativeNonURIs, eStyle); +} + +//============================================================================ +// +// SetMaybeFileHdl +// +//============================================================================ + +namespace { struct MaybeFileHdl : public rtl::Static< Link, MaybeFileHdl > {}; } + +void URIHelper::SetMaybeFileHdl(Link const & rTheMaybeFileHdl) +{ + MaybeFileHdl::get() = rTheMaybeFileHdl; +} + +//============================================================================ +// +// GetMaybeFileHdl +// +//============================================================================ + +Link URIHelper::GetMaybeFileHdl() +{ + return MaybeFileHdl::get(); +} + +namespace { + +bool isAbsoluteHierarchicalUriReference( + css::uno::Reference< css::uri::XUriReference > const & uriReference) +{ + return uriReference.is() && uriReference->isAbsolute() + && uriReference->isHierarchical() && !uriReference->hasRelativePath(); +} + +// To improve performance, assume that if for any prefix URL of a given +// hierarchical URL either a UCB content cannot be created, or the UCB content +// does not support the getCasePreservingURL command, then this will hold for +// any other prefix URL of the given URL, too: +enum Result { Success, GeneralFailure, SpecificFailure }; + +Result normalizePrefix( + css::uno::Reference< css::ucb::XContentProvider > const & broker, + rtl::OUString const & uri, rtl::OUString * normalized) +{ + OSL_ASSERT(broker.is() && normalized != 0); + css::uno::Reference< css::ucb::XContent > content; + try { + content = broker->queryContent( + css::uno::Reference< css::ucb::XContentIdentifierFactory >( + broker, css::uno::UNO_QUERY_THROW)->createContentIdentifier( + uri)); + } catch (css::ucb::IllegalIdentifierException &) {} + if (!content.is()) { + return GeneralFailure; + } + try { + #if OSL_DEBUG_LEVEL > 0 + bool ok = + #endif + (css::uno::Reference< css::ucb::XCommandProcessor >( + content, css::uno::UNO_QUERY_THROW)->execute( + css::ucb::Command( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "getCasePreservingURL")), + -1, css::uno::Any()), + 0, + css::uno::Reference< css::ucb::XCommandEnvironment >()) + >>= *normalized); + OSL_ASSERT(ok); + } catch (css::uno::RuntimeException &) { + throw; + } catch (css::ucb::UnsupportedCommandException &) { + return GeneralFailure; + } catch (css::uno::Exception &) { + return SpecificFailure; + } + return Success; +} + +rtl::OUString normalize( + css::uno::Reference< css::ucb::XContentProvider > const & broker, + css::uno::Reference< css::uri::XUriReferenceFactory > const & uriFactory, + rtl::OUString const & uriReference) +{ + // normalizePrefix can potentially fail (a typically example being a file + // URL that denotes a non-existing resource); in such a case, try to + // normalize as long a prefix of the given URL as possible (i.e., normalize + // all the existing directories within the path): + rtl::OUString normalized; + sal_Int32 n = uriReference.indexOf('#'); + normalized = n == -1 ? uriReference : uriReference.copy(0, n); + switch (normalizePrefix(broker, normalized, &normalized)) { + case Success: + return n == -1 ? normalized : normalized + uriReference.copy(n); + case GeneralFailure: + return uriReference; + case SpecificFailure: + default: + break; + } + css::uno::Reference< css::uri::XUriReference > ref( + uriFactory->parse(uriReference)); + if (!isAbsoluteHierarchicalUriReference(ref)) { + return uriReference; + } + sal_Int32 count = ref->getPathSegmentCount(); + if (count < 2) { + return uriReference; + } + rtl::OUStringBuffer head(ref->getScheme()); + head.append(static_cast< sal_Unicode >(':')); + if (ref->hasAuthority()) { + head.appendAscii(RTL_CONSTASCII_STRINGPARAM("//")); + head.append(ref->getAuthority()); + } + for (sal_Int32 i = count - 1; i > 0; --i) { + rtl::OUStringBuffer buf(head); + for (sal_Int32 j = 0; j < i; ++j) { + buf.append(static_cast< sal_Unicode >('/')); + buf.append(ref->getPathSegment(j)); + } + normalized = buf.makeStringAndClear(); + if (normalizePrefix(broker, normalized, &normalized) != SpecificFailure) + { + buf.append(normalized); + css::uno::Reference< css::uri::XUriReference > preRef( + uriFactory->parse(normalized)); + if (!isAbsoluteHierarchicalUriReference(preRef)) { + // This could only happen if something is inconsistent: + break; + } + sal_Int32 preCount = preRef->getPathSegmentCount(); + // normalizePrefix may have added or removed a final slash: + if (preCount != i) { + if (preCount == i - 1) { + buf.append(static_cast< sal_Unicode >('/')); + } else if (preCount - 1 == i && buf.getLength() > 0 + && buf.charAt(buf.getLength() - 1) == '/') + { + buf.setLength(buf.getLength() - 1); + } else { + // This could only happen if something is inconsistent: + break; + } + } + for (sal_Int32 j = i; j < count; ++j) { + buf.append(static_cast< sal_Unicode >('/')); + buf.append(ref->getPathSegment(j)); + } + if (ref->hasQuery()) { + buf.append(static_cast< sal_Unicode >('?')); + buf.append(ref->getQuery()); + } + if (ref->hasFragment()) { + buf.append(static_cast< sal_Unicode >('#')); + buf.append(ref->getFragment()); + } + return buf.makeStringAndClear(); + } + } + return uriReference; +} + +} + +css::uno::Reference< css::uri::XUriReference > +URIHelper::normalizedMakeRelative( + css::uno::Reference< css::uno::XComponentContext > const & context, + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference) +{ + OSL_ASSERT(context.is()); + css::uno::Reference< css::lang::XMultiComponentFactory > componentFactory( + context->getServiceManager()); + if (!componentFactory.is()) { + throw css::uno::RuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "component context has no service manager")), + css::uno::Reference< css::uno::XInterface >()); + } + css::uno::Sequence< css::uno::Any > args(2); + args[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local")); + args[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office")); + css::uno::Reference< css::ucb::XContentProvider > broker; + try { + broker = css::uno::Reference< css::ucb::XContentProvider >( + componentFactory->createInstanceWithArgumentsAndContext( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ucb.UniversalContentBroker")), + args, context), + css::uno::UNO_QUERY_THROW); + } catch (css::uno::RuntimeException &) { + throw; + } catch (css::uno::Exception &) { + css::uno::Any exception(cppu::getCaughtException()); + throw css::lang::WrappedTargetRuntimeException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "creating com.sun.star.ucb.UniversalContentBroker failed")), + css::uno::Reference< css::uno::XInterface >(), + exception); + } + css::uno::Reference< css::uri::XUriReferenceFactory > uriFactory( + css::uri::UriReferenceFactory::create(context)); + return uriFactory->makeRelative( + uriFactory->parse(normalize(broker, uriFactory, baseUriReference)), + uriFactory->parse(normalize(broker, uriFactory, uriReference)), true, + true, false); +} + +rtl::OUString URIHelper::simpleNormalizedMakeRelative( + rtl::OUString const & baseUriReference, rtl::OUString const & uriReference) +{ + com::sun::star::uno::Reference< com::sun::star::uri::XUriReference > rel( + URIHelper::normalizedMakeRelative( + com::sun::star::uno::Reference< + com::sun::star::uno::XComponentContext >( + (com::sun::star::uno::Reference< + com::sun::star::beans::XPropertySet >( + comphelper::getProcessServiceFactory(), + com::sun::star::uno::UNO_QUERY_THROW)-> + getPropertyValue( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("DefaultContext")))), + com::sun::star::uno::UNO_QUERY_THROW), + baseUriReference, uriReference)); + return rel.is() ? rel->getUriReference() : uriReference; +} + +//============================================================================ +// +// FindFirstURLInText +// +//============================================================================ + +namespace unnamed_svl_urihelper { + +inline xub_StrLen nextChar(UniString const & rStr, xub_StrLen nPos) +{ + return INetMIME::isHighSurrogate(rStr.GetChar(nPos)) + && rStr.Len() - nPos >= 2 + && INetMIME::isLowSurrogate(rStr.GetChar(nPos + 1)) ? + nPos + 2 : nPos + 1; +} + +bool isBoundary1(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen nPos, xub_StrLen nEnd) +{ + if (nPos == nEnd) + return true; + if (rCharClass.isLetterNumeric(rStr, nPos)) + return false; + switch (rStr.GetChar(nPos)) + { + case '$': + case '%': + case '&': + case '-': + case '/': + case '@': + case '\\': + return false; + default: + return true; + } +} + +bool isBoundary2(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen nPos, xub_StrLen nEnd) +{ + if (nPos == nEnd) + return true; + if (rCharClass.isLetterNumeric(rStr, nPos)) + return false; + switch (rStr.GetChar(nPos)) + { + case '!': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case '+': + case '-': + case '/': + case '=': + case '?': + case '@': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + return false; + default: + return true; + } +} + +bool checkWChar(CharClass const & rCharClass, UniString const & rStr, + xub_StrLen * pPos, xub_StrLen * pEnd, bool bBackslash = false, + bool bPipe = false) +{ + sal_Unicode c = rStr.GetChar(*pPos); + if (INetMIME::isUSASCII(c)) + { + static sal_uInt8 const aMap[128] + = { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 4, 4, 4, 1, // !"#$%&' + 1, 1, 1, 1, 1, 4, 1, 4, // ()*+,-./ + 4, 4, 4, 4, 4, 4, 4, 4, // 01234567 + 4, 4, 1, 1, 0, 1, 0, 1, // 89:;<=>? + 4, 4, 4, 4, 4, 4, 4, 4, // @ABCDEFG + 4, 4, 4, 4, 4, 4, 4, 4, // HIJKLMNO + 4, 4, 4, 4, 4, 4, 4, 4, // PQRSTUVW + 4, 4, 4, 1, 2, 1, 0, 1, // XYZ[\]^_ + 0, 4, 4, 4, 4, 4, 4, 4, // `abcdefg + 4, 4, 4, 4, 4, 4, 4, 4, // hijklmno + 4, 4, 4, 4, 4, 4, 4, 4, // pqrstuvw + 4, 4, 4, 0, 3, 0, 1, 0 }; // xyz{|}~ + switch (aMap[c]) + { + default: // not uric + return false; + + case 1: // uric + ++(*pPos); + return true; + + case 2: // "\" + if (bBackslash) + { + *pEnd = ++(*pPos); + return true; + } + else + return false; + + case 3: // "|" + if (bPipe) + { + *pEnd = ++(*pPos); + return true; + } + else + return false; + + case 4: // alpha, digit, "$", "%", "&", "-", "/", "@" (see + // isBoundary1) + *pEnd = ++(*pPos); + return true; + } + } + else if (rCharClass.isLetterNumeric(rStr, *pPos)) + { + *pEnd = *pPos = nextChar(rStr, *pPos); + return true; + } + else + return false; +} + +sal_uInt32 scanDomain(UniString const & rStr, xub_StrLen * pPos, + xub_StrLen nEnd) +{ + sal_Unicode const * pBuffer = rStr.GetBuffer(); + sal_Unicode const * p = pBuffer + *pPos; + sal_uInt32 nLabels = INetURLObject::scanDomain(p, pBuffer + nEnd, false); + *pPos = sal::static_int_cast< xub_StrLen >(p - pBuffer); + return nLabels; +} + +} + +UniString +URIHelper::FindFirstURLInText(UniString const & rText, + xub_StrLen & rBegin, + xub_StrLen & rEnd, + CharClass const & rCharClass, + INetURLObject::EncodeMechanism eMechanism, + rtl_TextEncoding eCharset, + INetURLObject::FSysStyle eStyle) +{ + if (!(rBegin <= rEnd && rEnd <= rText.Len())) + return UniString(); + + // Search for the first substring of [rBegin..rEnd[ that matches any of the + // following productions (for which the appropriate style bit is set in + // eStyle, if applicable). + // + // 1st Production (known scheme): + // \B1 <one of the known schemes, except file> ":" 1*wchar ["#" 1*wchar] + // \B1 + // + // 2nd Production (file): + // \B1 "FILE:" 1*(wchar / "\" / "|") ["#" 1*wchar] \B1 + // + // 3rd Production (ftp): + // \B1 "FTP" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1 + // + // 4th Production (http): + // \B1 "WWW" 2*("." label) ["/" *wchar] ["#" 1*wchar] \B1 + // + // 5th Production (mailto): + // \B2 local-part "@" domain \B1 + // + // 6th Production (UNC file): + // \B1 "\\" domain "\" *(wchar / "\") \B1 + // + // 7th Production (DOS file): + // \B1 ALPHA ":\" *(wchar / "\") \B1 + // + // 8th Production (Unix-like DOS file): + // \B1 ALPHA ":/" *(wchar / "\") \B1 + // + // The productions use the following auxiliary rules. + // + // local-part = atom *("." atom) + // atom = 1*(alphanum / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" + // / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" + // / "~") + // domain = label *("." label) + // label = alphanum [*(alphanum / "-") alphanum] + // alphanum = ALPHA / DIGIT + // wchar = <any uric character (ignoring the escaped rule), or "%", or + // a letter or digit (according to rCharClass)> + // + // "\B1" (boundary 1) stands for the beginning or end of the block of text, + // or a character that is neither (a) a letter or digit (according to + // rCharClass), nor (b) any of "$", "%", "&", "-", "/", "@", or "\". + // (FIXME: What was the rationale for this set of punctuation characters?) + // + // "\B2" (boundary 2) stands for the beginning or end of the block of text, + // or a character that is neither (a) a letter or digit (according to + // rCharClass), nor (b) any of "!", "#", "$", "%", "&", "'", "*", "+", "-", + // "/", "=", "?", "@", "^", "_", "`", "{", "|", "}", or "~" (i.e., an RFC + // 822 <atom> character, or "@" from \B1's set above). + // + // Productions 1--4, and 6--8 try to find a maximum-length match, but they + // stop at the first <wchar> character that is a "\B1" character which is + // only followed by "\B1" characters (taking "\" and "|" characters into + // account appropriately). Production 5 simply tries to find a maximum- + // length match. + // + // Productions 1--4 use the given eMechanism and eCharset. Productions 5--9 + // use ENCODE_ALL. + // + // Productions 6--9 are only applicable if the FSYS_DOS bit is set in + // eStyle. + + bool bBoundary1 = true; + bool bBoundary2 = true; + for (xub_StrLen nPos = rBegin; nPos != rEnd; nPos = nextChar(rText, nPos)) + { + sal_Unicode c = rText.GetChar(nPos); + if (bBoundary1) + { + if (INetMIME::isAlpha(c)) + { + xub_StrLen i = nPos; + INetProtocol eScheme + = INetURLObject::CompareProtocolScheme(UniString(rText, i, + rEnd)); + if (eScheme == INET_PROT_FILE) // 2nd + { + while (rText.GetChar(i++) != ':') ; + xub_StrLen nPrefixEnd = i; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd, true, + true)) ; + if (i != nPrefixEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (nUriEnd != nPrefixEnd + && isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, eMechanism, eCharset, + eStyle); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + else if (eScheme != INET_PROT_NOT_VALID) // 1st + { + while (rText.GetChar(i++) != ':') ; + xub_StrLen nPrefixEnd = i; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + if (i != nPrefixEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (nUriEnd != nPrefixEnd + && (isBoundary1(rCharClass, rText, nUriEnd, rEnd) + || rText.GetChar(nUriEnd) == '\\')) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_HTTP, eMechanism, + eCharset); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + + // 3rd, 4th: + i = nPos; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 3 + && rText.GetChar(nPos + 3) == '.' + && (((rText.GetChar(nPos) == 'w' + || rText.GetChar(nPos) == 'W') + && (rText.GetChar(nPos + 1) == 'w' + || rText.GetChar(nPos + 1) == 'W') + && (rText.GetChar(nPos + 2) == 'w' + || rText.GetChar(nPos + 2) == 'W')) + || ((rText.GetChar(nPos) == 'f' + || rText.GetChar(nPos) == 'F') + && (rText.GetChar(nPos + 1) == 't' + || rText.GetChar(nPos + 1) == 'T') + && (rText.GetChar(nPos + 2) == 'p' + || rText.GetChar(nPos + 2) == 'P')))) + // (note that rText.GetChar(nPos + 3) is guaranteed to be + // valid) + { + xub_StrLen nUriEnd = i; + if (i != rEnd && rText.GetChar(i) == '/') + { + nUriEnd = ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (i != rEnd && rText.GetChar(i) == '#') + { + ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + } + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd) + || rText.GetChar(nUriEnd) == '\\') + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_HTTP, eMechanism, + eCharset); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + + if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 3 + && rText.GetChar(nPos + 1) == ':' + && (rText.GetChar(nPos + 2) == '/' + || rText.GetChar(nPos + 2) == '\\')) // 7th, 8th + { + i = nPos + 3; + xub_StrLen nUriEnd = i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd)) ; + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, + INetURLObject::ENCODE_ALL, + RTL_TEXTENCODING_UTF8, + INetURLObject::FSYS_DOS); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + } + else if ((eStyle & INetURLObject::FSYS_DOS) != 0 && rEnd - nPos >= 2 + && rText.GetChar(nPos) == '\\' + && rText.GetChar(nPos + 1) == '\\') // 6th + { + xub_StrLen i = nPos + 2; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 1 && i != rEnd && rText.GetChar(i) == '\\') + { + xub_StrLen nUriEnd = ++i; + while (i != rEnd + && checkWChar(rCharClass, rText, &i, &nUriEnd, + true)) ; + if (isBoundary1(rCharClass, rText, nUriEnd, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, + nUriEnd - nPos), + INET_PROT_FILE, + INetURLObject::ENCODE_ALL, + RTL_TEXTENCODING_UTF8, + INetURLObject::FSYS_DOS); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = nUriEnd; + return + aUri.GetMainURL(INetURLObject::DECODE_TO_IURI); + } + } + } + } + } + if (bBoundary2 && INetMIME::isAtomChar(c)) // 5th + { + bool bDot = false; + for (xub_StrLen i = nPos + 1; i != rEnd; ++i) + { + sal_Unicode c2 = rText.GetChar(i); + if (INetMIME::isAtomChar(c2)) + bDot = false; + else if (bDot) + break; + else if (c2 == '.') + bDot = true; + else + { + if (c2 == '@') + { + ++i; + sal_uInt32 nLabels = scanDomain(rText, &i, rEnd); + if (nLabels >= 1 + && isBoundary1(rCharClass, rText, i, rEnd)) + { + INetURLObject aUri(UniString(rText, nPos, i - nPos), + INET_PROT_MAILTO, + INetURLObject::ENCODE_ALL); + if (!aUri.HasError()) + { + rBegin = nPos; + rEnd = i; + return aUri.GetMainURL( + INetURLObject::DECODE_TO_IURI); + } + } + } + break; + } + } + } + bBoundary1 = isBoundary1(rCharClass, rText, nPos, rEnd); + bBoundary2 = isBoundary2(rCharClass, rText, nPos, rEnd); + } + rBegin = rEnd; + return UniString(); +} + +//============================================================================ +// +// removePassword +// +//============================================================================ + +UniString +URIHelper::removePassword(UniString const & rURI, + INetURLObject::EncodeMechanism eEncodeMechanism, + INetURLObject::DecodeMechanism eDecodeMechanism, + rtl_TextEncoding eCharset) +{ + INetURLObject aObj(rURI, eEncodeMechanism, eCharset); + return aObj.HasError() ? + rURI : + String(aObj.GetURLNoPass(eDecodeMechanism, eCharset)); +} + +//============================================================================ +// +// queryFSysStyle +// +//============================================================================ + +INetURLObject::FSysStyle URIHelper::queryFSysStyle(UniString const & rFileUrl, + bool bAddConvenienceStyles) + throw (uno::RuntimeException) +{ + ::ucbhelper::ContentBroker const * pBroker = ::ucbhelper::ContentBroker::get(); + uno::Reference< ucb::XContentProviderManager > xManager; + if (pBroker) + xManager = pBroker->getContentProviderManagerInterface(); + uno::Reference< beans::XPropertySet > xProperties; + if (xManager.is()) + xProperties + = uno::Reference< beans::XPropertySet >( + xManager->queryContentProvider(rFileUrl), uno::UNO_QUERY); + sal_Int32 nNotation = ucb::FileSystemNotation::UNKNOWN_NOTATION; + if (xProperties.is()) + try + { + xProperties->getPropertyValue(rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "FileSystemNotation"))) + >>= nNotation; + } + catch (beans::UnknownPropertyException const &) {} + catch (lang::WrappedTargetException const &) {} + + // The following code depends on the fact that the + // com::sun::star::ucb::FileSystemNotation constants range from UNKNOWN to + // MAC, without any holes. The table below has two entries per notation, + // the first is used if bAddConvenienceStyles == false, while the second + // is used if bAddConvenienceStyles == true: + static INetURLObject::FSysStyle const aMap[][2] + = { { INetURLObject::FSysStyle(0), + INetURLObject::FSYS_DETECT }, + // UNKNOWN + { INetURLObject::FSYS_UNX, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX) }, + // UNIX + { INetURLObject::FSYS_DOS, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX + | INetURLObject::FSYS_DOS) }, + // DOS + { INetURLObject::FSYS_MAC, + INetURLObject::FSysStyle(INetURLObject::FSYS_VOS + | INetURLObject::FSYS_UNX + | INetURLObject::FSYS_MAC) } }; + return aMap[nNotation < ucb::FileSystemNotation::UNKNOWN_NOTATION + || nNotation > ucb::FileSystemNotation::MAC_NOTATION ? + 0 : + nNotation + - ucb::FileSystemNotation::UNKNOWN_NOTATION] + [bAddConvenienceStyles]; +} diff --git a/svl/source/notify/brdcst.cxx b/svl/source/notify/brdcst.cxx new file mode 100644 index 000000000000..08562fe9fece --- /dev/null +++ b/svl/source/notify/brdcst.cxx @@ -0,0 +1,212 @@ +/************************************************************************* + * + * 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: brdcst.cxx,v $ + * $Revision: 1.8.60.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifndef GCC +#endif +#include <tools/debug.hxx> + +#include <svl/hint.hxx> +#include <svl/smplhint.hxx> +#include <svl/lstner.hxx> + +SV_DECL_PTRARR( SfxListenerArr_Impl, SfxListener*, 0, 2 ) + +#define _SFX_BRDCST_CXX +#include <svl/brdcst.hxx> + +//==================================================================== +DBG_NAME(SfxBroadcaster) +TYPEINIT0(SfxBroadcaster); + +//==================================================================== + +//==================================================================== +// broadcast immediately + + +void SfxBroadcaster::Broadcast( const SfxHint &rHint ) +{ + DBG_CHKTHIS(SfxBroadcaster, 0); + + // is anybody to notify? + if ( aListeners.Count() /*! || aGlobListeners.Count() */ ) + { + // notify all registered listeners exactly once + for ( USHORT n = 0; n < aListeners.Count(); ++n ) + { + SfxListener* pListener = aListeners[n]; + if ( pListener ) + pListener->Notify( *this, rHint ); + } + } +} + +//-------------------------------------------------------------------- + +// broadcast after a timeout + + +void SfxBroadcaster::BroadcastDelayed( const SfxHint& rHint ) +{ + DBG_WARNING( "not implemented" ); + Broadcast(rHint); +} +//-------------------------------------------------------------------- + +// broadcast in idle-handler + +void SfxBroadcaster::BroadcastInIdle( const SfxHint& rHint ) +{ + DBG_WARNING( "not implemented" ); + Broadcast(rHint); +} +//-------------------------------------------------------------------- + +// unregister all listeners + +SfxBroadcaster::~SfxBroadcaster() +{ + DBG_DTOR(SfxBroadcaster, 0); + + Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); + + // remove all still registered listeners + for ( USHORT nPos = 0; nPos < aListeners.Count(); ++nPos ) + { + SfxListener *pListener = aListeners[nPos]; + if ( pListener ) + pListener->RemoveBroadcaster_Impl(*this); + } +} + +//-------------------------------------------------------------------- + +// simple ctor of class SfxBroadcaster + +SfxBroadcaster::SfxBroadcaster() +{ + DBG_CTOR(SfxBroadcaster, 0); +} + +//-------------------------------------------------------------------- + +// copy ctor of class SfxBroadcaster + + +SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) +{ + DBG_CTOR(SfxBroadcaster, 0); + + for ( USHORT n = 0; n < rBC.aListeners.Count(); ++n ) + { + SfxListener *pListener = rBC.aListeners[n]; + if ( pListener ) + pListener->StartListening( *this ); + } +} + +//-------------------------------------------------------------------- + +// add a new SfxListener to the list + +BOOL SfxBroadcaster::AddListener( SfxListener& rListener ) +{ + DBG_CHKTHIS(SfxBroadcaster, 0); + const SfxListener *pListener = &rListener; + const SfxListener *pNull = 0; + USHORT nFreePos = aListeners.GetPos( pNull ); + if ( nFreePos < aListeners.Count() ) + aListeners.GetData()[nFreePos] = pListener; + else if ( aListeners.Count() < (USHRT_MAX-1) ) + aListeners.Insert( pListener, aListeners.Count() ); + else + { + DBG_ERROR( "array overflow" ); + return FALSE; + } + + DBG_ASSERT( USHRT_MAX != aListeners.GetPos(pListener), + "AddListener failed" ); + return TRUE; +} + +//-------------------------------------------------------------------- + +// called, if no more listeners exists + +void SfxBroadcaster::ListenersGone() +{ + DBG_CHKTHIS(SfxBroadcaster,0); +} + +//-------------------------------------------------------------------- + +// forward a notification to all registered listeners + +void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint) +{ + const USHORT nCount = aListeners.Count(); + for ( USHORT i = 0; i < nCount; ++i ) + { + SfxListener *pListener = aListeners[i]; + if ( pListener ) + pListener->Notify( rBC, rHint ); + } +} + +//-------------------------------------------------------------------- + +// remove one SfxListener from the list + +void SfxBroadcaster::RemoveListener( SfxListener& rListener ) +{ + {DBG_CHKTHIS(SfxBroadcaster, 0);} + const SfxListener *pListener = &rListener; + USHORT nPos = aListeners.GetPos(pListener); + DBG_ASSERT( nPos != USHRT_MAX, "RemoveListener: Listener unknown" ); + aListeners.GetData()[nPos] = 0; + if ( !HasListeners() ) + ListenersGone(); +} + +//-------------------------------------------------------------------- + +BOOL SfxBroadcaster::HasListeners() const +{ + for ( USHORT n = 0; n < aListeners.Count(); ++n ) + if ( aListeners.GetObject(n) != 0 ) + return TRUE; + return FALSE; +} + +//-------------------------------------------------------------------- diff --git a/svl/source/notify/broadcast.cxx b/svl/source/notify/broadcast.cxx new file mode 100644 index 000000000000..ede14e4171b2 --- /dev/null +++ b/svl/source/notify/broadcast.cxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * 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: broadcast.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifndef GCC +#endif +#include <tools/debug.hxx> + +#include "listener.hxx" +#include "listeneriter.hxx" +#include "broadcast.hxx" +#include <svl/smplhint.hxx> + + +//==================================================================== +TYPEINIT0(SvtBroadcaster); + +//==================================================================== + +// simple ctor of class SvtBroadcaster + +SvtBroadcaster::SvtBroadcaster() + : pRoot( 0 ) +{ +} + +//-------------------------------------------------------------------- + +// copy ctor of class SvtBroadcaster + +SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) + : pRoot( 0 ) +{ + SvtListenerIter aIter( (SvtBroadcaster&)rBC ); + SvtListener* pLast = aIter.GoStart(); + if( pLast ) + do { + pLast->StartListening( *this ); + } while( 0 != ( pLast = aIter.GoNext() )); +} + +//-------------------------------------------------------------------- + +// unregister all listeners + +SvtBroadcaster::~SvtBroadcaster() +{ + Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); + + SvtListenerIter aIter( *this ); + SvtListener* pLast = aIter.GoStart(); + if( pLast ) + do { + pLast->EndListening( *this ); + if( !HasListeners() ) // all gone ?? + break; + } while( 0 != ( pLast = aIter.GoNext() )); +} + +//-------------------------------------------------------------------- + +// broadcast immedeately + +void SvtBroadcaster::Broadcast( const SfxHint &rHint ) +{ + // is anybody to notify? + if( HasListeners() /* && !IsModifyLocked()*/ ) + { +// LockModify(); +// bInModify = TRUE; + + SvtListenerIter aIter( *this ); + SvtListener* pLast = aIter.GoStart(); + if( pLast ) + do { + pLast->Notify( *this, rHint ); + if( !HasListeners() ) // all gone ?? + break; + } while( 0 != ( pLast = aIter.GoNext() )); + +// bInModify = FALSE; +// UnlockModify(); + } +} + +//-------------------------------------------------------------------- + + +// called, if no more listeners exists + +void SvtBroadcaster::ListenersGone() +{ +} + +//-------------------------------------------------------------------- + +// forward a notification to all registered listeners + +void SvtBroadcaster::Forward( SvtBroadcaster& rBC, const SfxHint& rHint ) +{ + // is anybody to notify? + if( rBC.HasListeners() /* && !IsModifyLocked()*/ ) + { +// LockModify(); +// bInModify = TRUE; + + SvtListenerIter aIter( rBC ); + SvtListener* pLast = aIter.GoStart(); + if( pLast ) + do { + pLast->Notify( rBC, rHint ); + if( !rBC.HasListeners() ) // all gone ?? + break; + } while( 0 != ( pLast = aIter.GoNext() )); + +// bInModify = FALSE; +// UnlockModify(); + } +} + + + diff --git a/svl/source/notify/cancel.cxx b/svl/source/notify/cancel.cxx new file mode 100644 index 000000000000..1df3abb22776 --- /dev/null +++ b/svl/source/notify/cancel.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * 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: cancel.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#define _SFX_CANCEL_CXX +#include <svl/cancel.hxx> + +#include <vos/mutex.hxx> +#include <tools/debug.hxx> + +#include <svl/smplhint.hxx> +#include <svl/cnclhint.hxx> +#include <rtl/instance.hxx> + +namespace { struct lclMutex : public rtl::Static< ::vos::OMutex, lclMutex >{}; } + +//========================================================================= + +SfxCancelManager::SfxCancelManager( SfxCancelManager *pParent ) +: _pParent( pParent ) +{ +} + +//------------------------------------------------------------------------- + +SfxCancelManager::~SfxCancelManager() +{ + DBG_ASSERT( _pParent || !_aJobs.Count(), "deleting SfxCancelManager in use" ); + for ( USHORT n = _aJobs.Count(); n--; ) + _aJobs.GetObject(n)->SetManager( _pParent ); +} + +//------------------------------------------------------------------------- + +BOOL SfxCancelManager::CanCancel() const + +/* [Beschreibung] + + Liefert TRUE wenn an diesem CancelManager oder an einem Parent + ein Job l"auft. +*/ + +{ + ::vos::OGuard aGuard( lclMutex::get() ); + return _aJobs.Count() > 0 || ( _pParent && _pParent->CanCancel() ); +} + +//------------------------------------------------------------------------- + +void SfxCancelManager::Cancel( BOOL bDeep ) + +/* [Beschreibung] + + Diese Methode markiert alle angemeldeten <SfxCancellable>-Instanzen + als suspendiert. +*/ + +{ + ::vos::OGuard aGuard( lclMutex::get() ); + SfxCancelManagerWeak xWeak( this ); + for ( USHORT n = _aJobs.Count(); n-- && xWeak.Is(); ) + if ( n < _aJobs.Count() ) + _aJobs.GetObject(n)->Cancel(); + if ( xWeak.Is() && _pParent ) + _pParent->Cancel( bDeep ); +} + +//------------------------------------------------------------------------- + +void SfxCancelManager::InsertCancellable( SfxCancellable *pJob ) + +/* [Beschreibung] + + Diese interne Methode tr"agt 'pJob' in die Liste der unterbrechbaren + Jobs ein und Broadcastet dies. Jeder <SfxCancellable> darf nur + maximal einmal angemeldet sein, dies geschiet in seinem Ctor. +*/ + +{ +#ifdef GPF_ON_EMPTY_TITLE + if ( !pJob->GetTitle() ) + { + DBG_ERROR( "SfxCancellable: empty titles not allowed (Vermummungsverbot)" ) + *(int*)0 = 0; + } +#endif + + ::vos::OClearableGuard aGuard( lclMutex::get() ); + _aJobs.C40_INSERT( SfxCancellable, pJob, _aJobs.Count() ); + + aGuard.clear(); + Broadcast( SfxSimpleHint( SFX_HINT_CANCELLABLE ) ); +} + +//------------------------------------------------------------------------- + + +void SfxCancelManager::RemoveCancellable( SfxCancellable *pJob ) + +/* [Beschreibung] + + Diese interne Methode tr"agt 'pJob' aus die Liste der unterbrechbaren + Jobs aus und Broadcastet dies. Dieser Aufruf mu\s paarig nach einem + <InsertCancellable> erfolgen und wird im Dtor des <SfxCancellable> + ausgel"ost. +*/ + +{ + ::vos::OClearableGuard aGuard( lclMutex::get() ); + const SfxCancellable *pTmp = pJob; + USHORT nPos = _aJobs.GetPos( pTmp ); + if ( nPos != 0xFFFF ) + { + _aJobs.Remove( nPos , 1 ); + aGuard.clear(); + Broadcast( SfxSimpleHint( SFX_HINT_CANCELLABLE ) ); + Broadcast( SfxCancelHint( pJob, SFXCANCELHINT_REMOVED ) ); + } +} + +//------------------------------------------------------------------------- + +SfxCancellable::~SfxCancellable() +{ + SfxCancelManager* pMgr = _pMgr; + if ( pMgr ) + pMgr->RemoveCancellable( this ); +} + +//------------------------------------------------------------------------- + +void SfxCancellable::Cancel() + +/* [Description] + + This virtual function is called when the user hits the cancel-button. + If you overload it, you can stop your activities. Please always call + 'SfxCancellable::Cancel()'. +*/ + +{ +#ifdef GFP_ON_NO_CANCEL + if ( _bCancelled < 5 ) + ++_bCancelled; + else + { + delete this; + } +#else + _bCancelled = TRUE; +#endif +} + +//------------------------------------------------------------------------- + +void SfxCancellable::SetManager( SfxCancelManager *pMgr ) +{ + SfxCancelManager* pTmp = _pMgr; + if ( pTmp ) + pTmp->RemoveCancellable( this ); + _pMgr = pMgr; + if ( pMgr ) + pMgr->InsertCancellable( this ); +} + +//------------------------------------------------------------------------- + +TYPEINIT1(SfxCancelHint, SfxHint); + +SfxCancelHint::SfxCancelHint( SfxCancellable* pJob, USHORT _nAction ) +{ + pCancellable = pJob; + nAction = _nAction; +} + + diff --git a/svl/source/notify/hint.cxx b/svl/source/notify/hint.cxx new file mode 100644 index 000000000000..36bcfb9990d9 --- /dev/null +++ b/svl/source/notify/hint.cxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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: hint.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#include <svl/hint.hxx> + +//==================================================================== + +TYPEINIT0(SfxHint); + +//==================================================================== +// virtual dtor for the typical base-class Hint + +SfxHint::~SfxHint() +{ +} + + + diff --git a/svl/source/notify/isethint.cxx b/svl/source/notify/isethint.cxx new file mode 100644 index 000000000000..5138fb2a9ad9 --- /dev/null +++ b/svl/source/notify/isethint.cxx @@ -0,0 +1,78 @@ +/************************************************************************* + * + * 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: isethint.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifndef GCC +#endif + +#include <svl/isethint.hxx> +#include <svl/itemset.hxx> + +//==================================================================== + +TYPEINIT1(SfxItemSetHint, SfxHint); + +//==================================================================== + +SfxItemSetHint::SfxItemSetHint( SfxItemSet *pItemSet ) + +/* [Beschreibung] + + Dieser Ctor "ubernimmt das als Parameter "ubergeben <SfxItemSet>, + das im Dtor gel"oscht wird. +*/ + +: _pItemSet( pItemSet ) +{ +} + +//-------------------------------------------------------------------- + +SfxItemSetHint::SfxItemSetHint( const SfxItemSet &rItemSet ) + +/* [Beschreibung] + + Dieser Ctor kopiert das als Parameter "ubergeben <SfxItemSet>. +*/ + +: _pItemSet( rItemSet.Clone() ) +{ +} + +//-------------------------------------------------------------------- + +SfxItemSetHint::~SfxItemSetHint() +{ + delete _pItemSet; +} + +//-------------------------------------------------------------------- diff --git a/svl/source/notify/listener.cxx b/svl/source/notify/listener.cxx new file mode 100644 index 000000000000..7d9a223e1a73 --- /dev/null +++ b/svl/source/notify/listener.cxx @@ -0,0 +1,169 @@ +/************************************************************************* + * + * 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: listener.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#ifndef DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#include "broadcast.hxx" +#include "listener.hxx" +#include "listenerbase.hxx" +#include "listeneriter.hxx" + + +//==================================================================== +TYPEINIT0(SvtListener); + +//==================================================================== +// simple ctor of class SvtListener + +SvtListener::SvtListener() + : pBrdCastLst( 0 ) +{ +} +//-------------------------------------------------------------------- + +// copy ctor of class SvtListener + +SvtListener::SvtListener( const SvtListener &rListener ) + : pBrdCastLst( 0 ) +{ + SvtListenerBase* pLst = rListener.pBrdCastLst; + while( pLst ) + { + new SvtListenerBase( *this, *pLst->GetBroadcaster() ); + pLst = pLst->GetNext(); + } +} +//-------------------------------------------------------------------- + +// unregisteres the SvtListener from its SvtBroadcasters + +SvtListener::~SvtListener() +{ + EndListeningAll(); +} + +//-------------------------------------------------------------------- + +// registeres at a specific SvtBroadcaster + +BOOL SvtListener::StartListening( SvtBroadcaster& rBroadcaster ) +{ + const SvtListenerBase* pLst = pBrdCastLst; + while( pLst ) + { + if( &rBroadcaster == pLst->GetBroadcaster() ) + { + // double, than return + return FALSE; + } + pLst = pLst->GetNext(); + } + new SvtListenerBase( *this, rBroadcaster ); + return TRUE; +} + +//-------------------------------------------------------------------- + +// unregisteres at a specific SvtBroadcaster + +BOOL SvtListener::EndListening( SvtBroadcaster& rBroadcaster ) +{ + SvtListenerBase *pLst = pBrdCastLst, *pPrev = pLst; + while( pLst ) + { + if( &rBroadcaster == pLst->GetBroadcaster() ) + { + if( pBrdCastLst == pLst ) + pBrdCastLst = pLst->GetNext(); + else + pPrev->SetNext( pLst->GetNext() ); + + delete pLst; + return TRUE; + } + pPrev = pLst; + pLst = pLst->GetNext(); + } + return FALSE; +} + +//-------------------------------------------------------------------- + +// unregisteres all Broadcasters + +void SvtListener::EndListeningAll() +{ + SvtListenerBase *pLst = pBrdCastLst; + while( pLst ) + { + SvtListenerBase *pDel = pLst; + pLst = pLst->GetNext(); + + delete pDel; + } + pBrdCastLst = 0; +} + +//-------------------------------------------------------------------- + +BOOL SvtListener::IsListening( SvtBroadcaster& rBroadcaster ) const +{ + const SvtListenerBase *pLst = pBrdCastLst; + while( pLst ) + { + if( &rBroadcaster == pLst->GetBroadcaster() ) + break; + pLst = pLst->GetNext(); + } + return 0 != pLst; +} + +//-------------------------------------------------------------------- + +// base implementation of notification handler + +void SvtListener::Notify( SvtBroadcaster& +#ifdef DBG_UTIL +rBC +#endif +, const SfxHint& ) +{ + DBG_ASSERT( IsListening( rBC ), + "notification from unregistered broadcaster" ); +} + + diff --git a/svl/source/notify/listenerbase.cxx b/svl/source/notify/listenerbase.cxx new file mode 100644 index 000000000000..bb1569c128c5 --- /dev/null +++ b/svl/source/notify/listenerbase.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * 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: listenerbase.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#ifndef DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#include "listenerbase.hxx" +#include "listeneriter.hxx" +#include "listener.hxx" +#include "broadcast.hxx" + + +SvtListenerBase::SvtListenerBase( SvtListener& rLst, + SvtBroadcaster& rBroadcaster ) + : pLeft( 0 ), pRight( 0 ), + pBroadcaster( &rBroadcaster ), pListener( &rLst ) +{ + pNext = rLst.pBrdCastLst; + rLst.pBrdCastLst = this; + + if( pBroadcaster->pRoot ) + { + // set ever behind the root + pRight = pBroadcaster->pRoot->pRight; + pBroadcaster->pRoot->pRight = this; + this->pLeft = pBroadcaster->pRoot; + if( pRight ) + pRight->pLeft = this; + } + else + pBroadcaster->pRoot = this; +} + +SvtListenerBase::~SvtListenerBase() +{ + SvtListenerBase *pR = pRight, *pL = pLeft; + if( pBroadcaster->pRoot ) + pBroadcaster->pRoot = pL ? pL : pR; + + if( pL ) + pL->pRight = pR; + if( pR ) + pR->pLeft = pL; + + SvtListenerIter::RemoveListener( *this, pR ); + + if( !pBroadcaster->pRoot ) + pBroadcaster->ListenersGone(); +} + + diff --git a/svl/source/notify/listenerbase.hxx b/svl/source/notify/listenerbase.hxx new file mode 100644 index 000000000000..e73f9dfc37c5 --- /dev/null +++ b/svl/source/notify/listenerbase.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * 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: listenerbase.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SVT_LISTENERBASE_HXX +#define _SVT_LISTENERBASE_HXX + +class SvtBroadcaster; +class SvtListener; + +class SvtListenerBase +{ + SvtListenerBase *pNext; + SvtListenerBase *pLeft, *pRight; + SvtBroadcaster *pBroadcaster; + SvtListener *pListener; + +public: + + SvtListenerBase( SvtListener& rLst, SvtBroadcaster& rBroadcaster ); + ~SvtListenerBase(); + + SvtListenerBase* GetNext() const { return pNext; } + void SetNext( SvtListenerBase* p ) { pNext = p; } + + SvtBroadcaster* GetBroadcaster() const { return pBroadcaster; } + SvtListener* GetListener() const { return pListener; } + + SvtListenerBase* GetLeft() const { return pLeft; } + SvtListenerBase* GetRight() const { return pRight; } +}; + + +#endif + diff --git a/svl/source/notify/listeneriter.cxx b/svl/source/notify/listeneriter.cxx new file mode 100644 index 000000000000..1f92eadfedbc --- /dev/null +++ b/svl/source/notify/listeneriter.cxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * 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: listeneriter.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif +#include <tools/debug.hxx> + +#include "listenerbase.hxx" +#include "listeneriter.hxx" +#include "broadcast.hxx" +#include "listener.hxx" + +SvtListenerIter* SvtListenerIter::pListenerIters = 0; + +SvtListenerIter::SvtListenerIter( SvtBroadcaster& rBrdcst ) + : rRoot( rBrdcst ) +{ + // hinten einketten! + pNxtIter = 0; + if( pListenerIters ) + { + SvtListenerIter* pTmp = pListenerIters; + while( pTmp->pNxtIter ) + pTmp = pTmp->pNxtIter; + pTmp->pNxtIter = this; + } + else + pListenerIters = this; + + pAkt = rRoot.pRoot; + pDelNext = pAkt; +} + + + +SvtListenerIter::~SvtListenerIter() +{ + if( pListenerIters ) + { + if( pListenerIters == this ) + pListenerIters = pNxtIter; + else + { + SvtListenerIter* pTmp = pListenerIters; + while( pTmp->pNxtIter != this ) + if( 0 == ( pTmp = pTmp->pNxtIter ) ) + return ; + pTmp->pNxtIter = pNxtIter; + } + } +} + +void SvtListenerIter::RemoveListener( SvtListenerBase& rDel, + SvtListenerBase* pNext ) +{ + // Update the ListenerIter + SvtListenerIter* pTmp = pListenerIters; + while( pTmp ) + { + if( pTmp->pAkt == &rDel || pTmp->pDelNext == &rDel ) + pTmp->pDelNext = pNext; + pTmp = pTmp->pNxtIter; + } +} + +SvtListener* SvtListenerIter::GoNext() +{ + if( pDelNext == pAkt ) + { + pAkt = pAkt->GetRight(); + pDelNext = pAkt; + } + else + pAkt = pDelNext; + return pAkt ? pAkt->GetListener() : 0; +} + + +SvtListener* SvtListenerIter::GoPrev() +{ + if( pDelNext == pAkt ) + pAkt = pAkt->GetLeft(); + else + pAkt = pDelNext->GetLeft(); + pDelNext = pAkt; + return pAkt ? pAkt->GetListener() : 0; +} + + +SvtListener* SvtListenerIter::GoStart() // zum Anfang des Baums +{ + pAkt = rRoot.pRoot; + if( pAkt ) + while( pAkt->GetLeft() ) + pAkt = pAkt->GetLeft(); + pDelNext = pAkt; + return pAkt ? pAkt->GetListener() : 0; +} + + +SvtListener* SvtListenerIter::GoEnd() // zum End des Baums +{ + pAkt = pDelNext; + if( !pAkt ) + pAkt = rRoot.pRoot; + if( pAkt ) + while( pAkt->GetRight() ) + pAkt = pAkt->GetRight(); + pDelNext = pAkt; + return pAkt ? pAkt->GetListener() : 0; +} + + + +SvtListener* SvtListenerIter::First( TypeId nType ) +{ + aSrchId = nType; + GoStart(); + if( pAkt ) + do { + if( pAkt->GetListener()->IsA( aSrchId ) ) + break; + + if( pDelNext == pAkt ) + { + pAkt = pAkt->GetRight(); + pDelNext = pAkt; + } + else + pAkt = pDelNext; + + } while( pAkt ); + return pAkt ? pAkt->GetListener() : 0; +} + + +SvtListener* SvtListenerIter::Next() +{ + do { + // erstmal zum naechsten + if( pDelNext == pAkt ) + { + pAkt = pAkt->GetRight(); + pDelNext = pAkt; + } + else + pAkt = pDelNext; + + if( pAkt && pAkt->GetListener()->IsA( aSrchId ) ) + break; + } while( pAkt ); + return pAkt ? pAkt->GetListener() : 0; +} + + +SvtListener* SvtListenerIter::GoRoot() // wieder ab Root anfangen +{ + pDelNext = pAkt = rRoot.pRoot; + return pAkt ? pAkt->GetListener() : 0; +} + +SvtListener* SvtListenerIter::GetCurr() const // returns the current +{ + return pDelNext ? pDelNext->GetListener() : 0; +} + diff --git a/svl/source/notify/lstner.cxx b/svl/source/notify/lstner.cxx new file mode 100644 index 000000000000..4be2020967b5 --- /dev/null +++ b/svl/source/notify/lstner.cxx @@ -0,0 +1,196 @@ +/************************************************************************* + * + * 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: lstner.cxx,v $ + * $Revision: 1.8.60.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#ifndef DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#include <svl/hint.hxx> +#include <svl/brdcst.hxx> + +SV_DECL_PTRARR( SfxBroadcasterArr_Impl, SfxBroadcaster*, 0, 2 ) + +#define _SFX_LSTNER_CXX +#include <svl/lstner.hxx> + +//==================================================================== +DBG_NAME(SfxListener) +TYPEINIT0(SfxListener); + +//==================================================================== +// simple ctor of class SfxListener + +SfxListener::SfxListener() +{ + DBG_CTOR(SfxListener, 0); +} +//-------------------------------------------------------------------- + +// copy ctor of class SfxListener + +SfxListener::SfxListener( const SfxListener &rListener ) +{ + DBG_CTOR(SfxListener, 0); + + for ( USHORT n = 0; n < rListener.aBCs.Count(); ++n ) + StartListening( *rListener.aBCs[n] ); +} +//-------------------------------------------------------------------- + +// unregisteres the SfxListener from its SfxBroadcasters + +SfxListener::~SfxListener() +{ + DBG_DTOR(SfxListener, 0); + + // unregister at all remainding broadcasters + for ( USHORT nPos = 0; nPos < aBCs.Count(); ++nPos ) + { + SfxBroadcaster *pBC = aBCs[nPos]; + pBC->RemoveListener(*this); + } +} + +//-------------------------------------------------------------------- + +// unregisteres at a specific SfxBroadcaster + +void SfxListener::RemoveBroadcaster_Impl( SfxBroadcaster& rBC ) +{ + DBG_CHKTHIS(SfxListener, 0); + + const SfxBroadcaster *pBC = &rBC; + aBCs.Remove( aBCs.GetPos(pBC), 1 ); +} + +//-------------------------------------------------------------------- + +// registeres at a specific SfxBroadcaster + +BOOL SfxListener::StartListening( SfxBroadcaster& rBroadcaster, BOOL bPreventDups ) +{ + DBG_CHKTHIS(SfxListener, 0); + + if ( !bPreventDups || !IsListening( rBroadcaster ) ) + { + if ( rBroadcaster.AddListener(*this) ) + { + const SfxBroadcaster *pBC = &rBroadcaster; + aBCs.Insert( pBC, aBCs.Count() ); + + DBG_ASSERT( IsListening(rBroadcaster), "StartListening failed" ); + return TRUE; + } + + } + return FALSE; +} + +//-------------------------------------------------------------------- + +// unregisteres at a specific SfxBroadcaster + +BOOL SfxListener::EndListening( SfxBroadcaster& rBroadcaster, BOOL bAllDups ) +{ + DBG_CHKTHIS(SfxListener, 0); + + if ( !IsListening( rBroadcaster ) ) + return FALSE; + + do + { + rBroadcaster.RemoveListener(*this); + const SfxBroadcaster *pBC = &rBroadcaster; + aBCs.Remove( aBCs.GetPos(pBC), 1 ); + } + while ( bAllDups && IsListening( rBroadcaster ) ); + return TRUE; +} + +//-------------------------------------------------------------------- + +// unregisteres at a specific SfxBroadcaster by index + +void SfxListener::EndListening( USHORT nNo ) +{ + DBG_CHKTHIS(SfxListener, 0); + + SfxBroadcaster *pBC = aBCs.GetObject(nNo); + pBC->RemoveListener(*this); + aBCs.Remove( nNo, 1 ); +} + +//-------------------------------------------------------------------- + +// unregisteres all Broadcasters + +void SfxListener::EndListeningAll() +{ + DBG_CHKTHIS(SfxListener, 0); + + // MI: bei Optimierung beachten: Seiteneffekte von RemoveListener beachten! + while ( aBCs.Count() ) + { + SfxBroadcaster *pBC = aBCs.GetObject(0); + pBC->RemoveListener(*this); + aBCs.Remove( 0, 1 ); + } +} + +//-------------------------------------------------------------------- + +BOOL SfxListener::IsListening( SfxBroadcaster& rBroadcaster ) const +{ + const SfxBroadcaster *pBC = &rBroadcaster; + return USHRT_MAX != aBCs.GetPos( pBC ); +} + +//-------------------------------------------------------------------- + +// base implementation of notification handler + +#ifdef DBG_UTIL +void SfxListener::Notify( SfxBroadcaster& rBC, const SfxHint& ) +#else +void SfxListener::Notify( SfxBroadcaster&, const SfxHint& ) +#endif +{ + #ifdef DBG_UTIL + const SfxBroadcaster *pBC = &rBC; + DBG_ASSERT( USHRT_MAX != aBCs.GetPos(pBC), + "notification from unregistered broadcaster" ); + #endif +} + diff --git a/svl/source/notify/makefile.mk b/svl/source/notify/makefile.mk new file mode 100644 index 000000000000..0d26860d02b5 --- /dev/null +++ b/svl/source/notify/makefile.mk @@ -0,0 +1,67 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=notify + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/smplhint.obj \ + $(SLO)$/hint.obj \ + $(SLO)$/lstner.obj \ + $(SLO)$/isethint.obj \ + $(SLO)$/cancel.obj \ + $(SLO)$/brdcst.obj \ + $(SLO)$/listener.obj \ + $(SLO)$/listenerbase.obj \ + $(SLO)$/listeneriter.obj \ + $(SLO)$/broadcast.obj + +HXX1TARGET= notify +HXX1EXT= hxx +HXX1FILES= $(INC)$/hint.hxx \ + $(INC)$/smplhint.hxx \ + $(INC)$/lstner.hxx \ + $(INC)$/brdcst.hxx +HXX1EXCL= -E:*include* + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/notify/smplhint.cxx b/svl/source/notify/smplhint.cxx new file mode 100644 index 000000000000..454710a1b79f --- /dev/null +++ b/svl/source/notify/smplhint.cxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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: smplhint.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#include <svl/smplhint.hxx> + +//==================================================================== + +TYPEINIT1(SfxSimpleHint, SfxHint); + +//==================================================================== +// creates a SimpleHint with the type nId + +SfxSimpleHint::SfxSimpleHint( ULONG nIdP ) +{ + nId = nIdP; +} + + diff --git a/svl/source/numbers/makefile.mk b/svl/source/numbers/makefile.mk new file mode 100644 index 000000000000..db4b30070ce8 --- /dev/null +++ b/svl/source/numbers/makefile.mk @@ -0,0 +1,78 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.12.148.1 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=numbers +LIBTARGET=NO + +PROJECTPCH= +PROJECTPCHSOURCE= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES= \ + $(SLO)$/numuno.obj \ + $(SLO)$/numfmuno.obj \ + $(SLO)$/supservs.obj \ + $(SLO)$/zforlist.obj + +SLOFILES = \ + $(EXCEPTIONSFILES) \ + $(SLO)$/zforfind.obj \ + $(SLO)$/zformat.obj \ + $(SLO)$/zforscan.obj \ + $(SLO)$/numhead.obj + +LIB1TARGET= $(SLB)$/$(TARGET).uno.lib +LIB1OBJFILES= \ + $(SLO)$/numfmuno.obj \ + $(SLO)$/supservs.obj + +LIB2TARGET= $(SLB)$/$(TARGET).lib +LIB2OBJFILES= \ + $(SLO)$/zforfind.obj \ + $(SLO)$/zforlist.obj \ + $(SLO)$/zformat.obj \ + $(SLO)$/zforscan.obj \ + $(SLO)$/numuno.obj \ + $(SLO)$/numhead.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/numbers/nbdll.cxx b/svl/source/numbers/nbdll.cxx new file mode 100644 index 000000000000..2bc5121e18fd --- /dev/null +++ b/svl/source/numbers/nbdll.cxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * 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: nbdll.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#ifdef WIN +#include <svwin.h> + +#ifndef _SYSDEP_HXX +#include <sysdep.hxx> +#endif + +// Statische DLL-Verwaltungs-Variablen +static HINSTANCE hDLLInst = 0; // HANDLE der DLL + + +/*************************************************************************** +|* +|* LibMain() +|* +|* Beschreibung Initialisierungsfunktion der DLL +|* Ersterstellung TH 05.05.93 +|* Letzte Aenderung TH 05.05.93 +|* +***************************************************************************/ + +extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR ) +{ +#ifndef WNT + if ( nHeap ) + UnlockData( 0 ); +#endif + + hDLLInst = hDLL; + + return TRUE; +} + +/*************************************************************************** +|* +|* WEP() +|* +|* Beschreibung DLL-Deinitialisierung +|* Ersterstellung TH 05.05.93 +|* Letzte Aenderung TH 05.05.93 +|* +***************************************************************************/ + +extern "C" int CALLBACK WEP( int ) +{ + return 1; +} + +#endif diff --git a/svl/source/numbers/numfmuno.cxx b/svl/source/numbers/numfmuno.cxx new file mode 100644 index 000000000000..23f627834955 --- /dev/null +++ b/svl/source/numbers/numfmuno.cxx @@ -0,0 +1,1143 @@ +/************************************************************************* + * + * 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: numfmuno.cxx,v $ + * $Revision: 1.15 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#include <tools/color.hxx> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> +#include <vos/mutex.hxx> +#include <rtl/ustring.hxx> + +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include "numfmuno.hxx" +#include "numuno.hxx" +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <svl/itemprop.hxx> + +using namespace com::sun::star; + +//------------------------------------------------------------------------ + +#define SERVICENAME_NUMBERFORMATTER "com.sun.star.util.NumberFormatter" +#define SERVICENAME_NUMBERSETTINGS "com.sun.star.util.NumberFormatSettings" +#define SERVICENAME_NUMBERFORMATS "com.sun.star.util.NumberFormats" +#define SERVICENAME_NUMBERFORMAT "com.sun.star.util.NumberFormatProperties" + +//------------------------------------------------------------------------ + +#define PROPERTYNAME_FMTSTR "FormatString" +#define PROPERTYNAME_LOCALE "Locale" +#define PROPERTYNAME_TYPE "Type" +#define PROPERTYNAME_COMMENT "Comment" +#define PROPERTYNAME_CURREXT "CurrencyExtension" +#define PROPERTYNAME_CURRSYM "CurrencySymbol" +#define PROPERTYNAME_CURRABB "CurrencyAbbreviation" +#define PROPERTYNAME_DECIMALS "Decimals" +#define PROPERTYNAME_LEADING "LeadingZeros" +#define PROPERTYNAME_NEGRED "NegativeRed" +#define PROPERTYNAME_STDFORM "StandardFormat" +#define PROPERTYNAME_THOUS "ThousandsSeparator" +#define PROPERTYNAME_USERDEF "UserDefined" + +#define PROPERTYNAME_NOZERO "NoZero" +#define PROPERTYNAME_NULLDATE "NullDate" +#define PROPERTYNAME_STDDEC "StandardDecimals" +#define PROPERTYNAME_TWODIGIT "TwoDigitDateStart" + +//------------------------------------------------------------------------ + +// alles ohne Which-ID, Map nur fuer PropertySetInfo + +const SfxItemPropertyMapEntry* lcl_GetNumberFormatPropertyMap() +{ + static SfxItemPropertyMapEntry aNumberFormatPropertyMap_Impl[] = + { + {MAP_CHAR_LEN(PROPERTYNAME_FMTSTR), 0, &getCppuType((rtl::OUString*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_LOCALE), 0, &getCppuType((lang::Locale*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_TYPE), 0, &getCppuType((sal_Int16*)0), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_COMMENT), 0, &getCppuType((rtl::OUString*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_CURREXT), 0, &getCppuType((rtl::OUString*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_CURRSYM), 0, &getCppuType((rtl::OUString*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_DECIMALS), 0, &getCppuType((sal_Int16*)0), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_LEADING), 0, &getCppuType((sal_Int16*)0), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_NEGRED), 0, &getBooleanCppuType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_STDFORM), 0, &getBooleanCppuType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_THOUS), 0, &getBooleanCppuType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_USERDEF), 0, &getBooleanCppuType(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_CURRABB), 0, &getCppuType((rtl::OUString*)0),beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY, 0}, + {0,0,0,0,0,0} + }; + return aNumberFormatPropertyMap_Impl; +} + +const SfxItemPropertyMapEntry* lcl_GetNumberSettingsPropertyMap() +{ + static SfxItemPropertyMapEntry aNumberSettingsPropertyMap_Impl[] = + { + {MAP_CHAR_LEN(PROPERTYNAME_NOZERO), 0, &getBooleanCppuType(), beans::PropertyAttribute::BOUND, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_NULLDATE), 0, &getCppuType((util::Date*)0), beans::PropertyAttribute::BOUND, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_STDDEC), 0, &getCppuType((sal_Int16*)0), beans::PropertyAttribute::BOUND, 0}, + {MAP_CHAR_LEN(PROPERTYNAME_TWODIGIT), 0, &getCppuType((sal_Int16*)0), beans::PropertyAttribute::BOUND, 0}, + {0,0,0,0,0,0} + }; + return aNumberSettingsPropertyMap_Impl; +} + +//---------------------------------------------------------------------------------------- + +LanguageType lcl_GetLanguage( const lang::Locale& rLocale ) +{ + // empty language -> LANGUAGE_SYSTEM + if ( rLocale.Language.getLength() == 0 ) + return LANGUAGE_SYSTEM; + + LanguageType eRet = MsLangId::convertLocaleToLanguage( rLocale ); + if ( eRet == LANGUAGE_NONE ) + eRet = LANGUAGE_SYSTEM; //! or throw an exception? + + return eRet; +} + +//---------------------------------------------------------------------------------------- + +SvNumberFormatterServiceObj::SvNumberFormatterServiceObj() + :m_aMutex() +{ +} + +SvNumberFormatterServiceObj::~SvNumberFormatterServiceObj() +{ +} + +com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SvNumberFormatterServiceObj_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ) +{ + return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new SvNumberFormatterServiceObj ); +} + +// XNumberFormatter + +void SAL_CALL SvNumberFormatterServiceObj::attachNumberFormatsSupplier( + const uno::Reference<util::XNumberFormatsSupplier>& _xSupplier ) + throw(uno::RuntimeException) +{ + ::rtl::Reference< SvNumberFormatsSupplierObj > xAutoReleaseOld; + + // SYNCHRONIZED -> + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + + SvNumberFormatsSupplierObj* pNew = SvNumberFormatsSupplierObj::getImplementation( _xSupplier ); + if (!pNew) + throw uno::RuntimeException(); // wrong object + + xAutoReleaseOld = xSupplier; + + xSupplier = pNew; + m_aMutex = xSupplier->getSharedMutex(); + } + // <- SYNCHRONIZED +} + +uno::Reference<util::XNumberFormatsSupplier> SAL_CALL + SvNumberFormatterServiceObj::getNumberFormatsSupplier() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + return xSupplier.get(); +} + +sal_Int32 SAL_CALL SvNumberFormatterServiceObj::detectNumberFormat( + sal_Int32 nKey, const rtl::OUString& aString ) + throw(util::NotNumericException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aTemp = aString; + sal_uInt32 nUKey = nKey; + double fValue = 0.0; + if ( pFormatter->IsNumberFormat(aTemp, nUKey, fValue) ) + nRet = nUKey; + else + throw util::NotNumericException(); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +double SAL_CALL SvNumberFormatterServiceObj::convertStringToNumber( + sal_Int32 nKey, const rtl::OUString& aString ) + throw(util::NotNumericException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + double fRet = 0.0; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aTemp = aString; + sal_uInt32 nUKey = nKey; + double fValue = 0.0; + if ( pFormatter->IsNumberFormat(aTemp, nUKey, fValue) ) + fRet = fValue; + else + throw util::NotNumericException(); + } + else + throw uno::RuntimeException(); + + return fRet; +} + +rtl::OUString SAL_CALL SvNumberFormatterServiceObj::convertNumberToString( + sal_Int32 nKey, double fValue ) throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + String aRet; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + Color* pColor = NULL; + pFormatter->GetOutputString(fValue, nKey, aRet, &pColor); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +util::Color SAL_CALL SvNumberFormatterServiceObj::queryColorForNumber( sal_Int32 nKey, + double fValue, util::Color aDefaultColor ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + util::Color nRet = aDefaultColor; // color = INT32 + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aStr; + Color* pColor = NULL; + pFormatter->GetOutputString(fValue, nKey, aStr, &pColor); + if (pColor) + nRet = pColor->GetColor(); + // sonst Default behalten + } + else + throw uno::RuntimeException(); + + return nRet; +} + +rtl::OUString SAL_CALL SvNumberFormatterServiceObj::formatString( sal_Int32 nKey, + const rtl::OUString& aString ) throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + String aRet; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aTemp = aString; + Color* pColor = NULL; + pFormatter->GetOutputString(aTemp, nKey, aRet, &pColor); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +util::Color SAL_CALL SvNumberFormatterServiceObj::queryColorForString( sal_Int32 nKey, + const rtl::OUString& aString,util::Color aDefaultColor ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + util::Color nRet = aDefaultColor; // color = INT32 + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aTemp = aString; + String aStr; + Color* pColor = NULL; + pFormatter->GetOutputString(aTemp, nKey, aStr, &pColor); + if (pColor) + nRet = pColor->GetColor(); + // sonst Default behalten + } + else + throw uno::RuntimeException(); + + return nRet; +} + +rtl::OUString SAL_CALL SvNumberFormatterServiceObj::getInputString( sal_Int32 nKey, double fValue ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + String aRet; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + pFormatter->GetInputLineString(fValue, nKey, aRet); + else + throw uno::RuntimeException(); + + return aRet; +} + +// XNumberFormatPreviewer + +rtl::OUString SAL_CALL SvNumberFormatterServiceObj::convertNumberToPreviewString( + const rtl::OUString& aFormat, double fValue, + const lang::Locale& nLocale, sal_Bool bAllowEnglish ) + throw(util::MalformedNumberFormatException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + String aRet; + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aOutString; + String aFormString = aFormat; + LanguageType eLang = lcl_GetLanguage( nLocale ); + Color* pColor = NULL; + + BOOL bOk; + if ( bAllowEnglish ) + bOk = pFormatter->GetPreviewStringGuess( + aFormString, fValue, aOutString, &pColor, eLang ); + else + bOk = pFormatter->GetPreviewString( + aFormString, fValue, aOutString, &pColor, eLang ); + + if (bOk) + aRet = aOutString; + else + throw util::MalformedNumberFormatException(); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +util::Color SAL_CALL SvNumberFormatterServiceObj::queryPreviewColorForNumber( + const rtl::OUString& aFormat, double fValue, + const lang::Locale& nLocale, sal_Bool bAllowEnglish, + util::Color aDefaultColor ) + throw(util::MalformedNumberFormatException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + util::Color nRet = aDefaultColor; // color = INT32 + SvNumberFormatter* pFormatter = xSupplier.is() ? xSupplier->GetNumberFormatter() : NULL; + if (pFormatter) + { + String aOutString; + String aFormString = aFormat; + LanguageType eLang = lcl_GetLanguage( nLocale ); + Color* pColor = NULL; + + BOOL bOk; + if ( bAllowEnglish ) + bOk = pFormatter->GetPreviewStringGuess( + aFormString, fValue, aOutString, &pColor, eLang ); + else + bOk = pFormatter->GetPreviewString( + aFormString, fValue, aOutString, &pColor, eLang ); + + if (bOk) + { + if (pColor) + nRet = pColor->GetColor(); + // sonst Default behalten + } + else + throw util::MalformedNumberFormatException(); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +// XServiceInfo + +rtl::OUString SAL_CALL SvNumberFormatterServiceObj::getImplementationName() + throw(uno::RuntimeException) +{ + return rtl::OUString::createFromAscii("com.sun.star.uno.util.numbers.SvNumberFormatterServiceObject"); +} + +sal_Bool SAL_CALL SvNumberFormatterServiceObj::supportsService( const rtl::OUString& ServiceName ) + throw(uno::RuntimeException) +{ + return ( ServiceName.compareToAscii(SERVICENAME_NUMBERFORMATTER) == 0 ); +} + +uno::Sequence<rtl::OUString> SAL_CALL SvNumberFormatterServiceObj::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + uno::Sequence<rtl::OUString> aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString::createFromAscii(SERVICENAME_NUMBERFORMATTER); + return aRet; +} + +//------------------------------------------------------------------------ + +SvNumberFormatsObj::SvNumberFormatsObj( SvNumberFormatsSupplierObj& _rParent, ::comphelper::SharedMutex& _rMutex ) + :rSupplier( _rParent ) + ,m_aMutex( _rMutex ) +{ + rSupplier.acquire(); +} + +SvNumberFormatsObj::~SvNumberFormatsObj() +{ + rSupplier.release(); +} + +// XNumberFormats + +uno::Reference<beans::XPropertySet> SAL_CALL SvNumberFormatsObj::getByKey( sal_Int32 nKey ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + const SvNumberformat* pFormat = pFormatter ? pFormatter->GetEntry(nKey) : NULL; + if (pFormat) + return new SvNumberFormatObj( rSupplier, nKey, m_aMutex ); + else + throw uno::RuntimeException(); +} + +uno::Sequence<sal_Int32> SAL_CALL SvNumberFormatsObj::queryKeys( sal_Int16 nType, + const lang::Locale& nLocale, sal_Bool bCreate ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if ( pFormatter ) + { + sal_uInt32 nIndex = 0; + LanguageType eLang = lcl_GetLanguage( nLocale ); + SvNumberFormatTable& rTable = bCreate ? + pFormatter->ChangeCL( nType, nIndex, eLang ) : + pFormatter->GetEntryTable( nType, nIndex, eLang ); + sal_uInt32 nCount = rTable.Count(); + uno::Sequence<sal_Int32> aSeq(nCount); + sal_Int32* pAry = aSeq.getArray(); + for (sal_uInt32 i=0; i<nCount; i++) + pAry[i] = rTable.GetObjectKey( i ); + + return aSeq; + } + else + throw uno::RuntimeException(); +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::queryKey( const rtl::OUString& aFormat, + const lang::Locale& nLocale, sal_Bool bScan ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + String aFormStr = aFormat; + LanguageType eLang = lcl_GetLanguage( nLocale ); + if (bScan) + { + //! irgendwas muss hier noch passieren... + } + nRet = pFormatter->GetEntryKey( aFormat, eLang ); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::addNew( const rtl::OUString& aFormat, + const lang::Locale& nLocale ) + throw(util::MalformedNumberFormatException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + String aFormStr = aFormat; + LanguageType eLang = lcl_GetLanguage( nLocale ); + sal_uInt32 nKey = 0; + xub_StrLen nCheckPos = 0; + short nType = 0; + BOOL bOk = pFormatter->PutEntry( aFormStr, nCheckPos, nType, nKey, eLang ); + if (bOk) + nRet = nKey; + else if (nCheckPos) + { + throw util::MalformedNumberFormatException(); // ungueltiges Format + } + else + throw uno::RuntimeException(); // anderer Fehler (z.B. schon vorhanden) + } + else + throw uno::RuntimeException(); + + return nRet; +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::addNewConverted( const rtl::OUString& aFormat, + const lang::Locale& nLocale, const lang::Locale& nNewLocale ) + throw(util::MalformedNumberFormatException, uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + String aFormStr = aFormat; + LanguageType eLang = lcl_GetLanguage( nLocale ); + LanguageType eNewLang = lcl_GetLanguage( nNewLocale ); + sal_uInt32 nKey = 0; + xub_StrLen nCheckPos = 0; + short nType = 0; + BOOL bOk = pFormatter->PutandConvertEntry( aFormStr, nCheckPos, nType, nKey, eLang, eNewLang ); + if (bOk || nKey > 0) + nRet = nKey; + else if (nCheckPos) + { + throw util::MalformedNumberFormatException(); // ungueltiges Format + } + else + throw uno::RuntimeException(); // anderer Fehler (z.B. schon vorhanden) + } + else + throw uno::RuntimeException(); + + return nRet; +} + +void SAL_CALL SvNumberFormatsObj::removeByKey( sal_Int32 nKey ) throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + + if (pFormatter) + { + pFormatter->DeleteEntry(nKey); + rSupplier.NumberFormatDeleted(nKey); // Benachrichtigung fuers Dokument + } +} + +rtl::OUString SAL_CALL SvNumberFormatsObj::generateFormat( sal_Int32 nBaseKey, + const lang::Locale& nLocale, sal_Bool bThousands, + sal_Bool bRed, sal_Int16 nDecimals, sal_Int16 nLeading ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + String aRet; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + LanguageType eLang = lcl_GetLanguage( nLocale ); + pFormatter->GenerateFormat( aRet, nBaseKey, eLang, bThousands, bRed, nDecimals, nLeading ); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +// XNumberFormatTypes + +sal_Int32 SAL_CALL SvNumberFormatsObj::getStandardIndex( const lang::Locale& nLocale ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + LanguageType eLang = lcl_GetLanguage( nLocale ); + nRet = pFormatter->GetStandardIndex(eLang); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::getStandardFormat( sal_Int16 nType, const lang::Locale& nLocale ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + LanguageType eLang = lcl_GetLanguage( nLocale ); + // mask out "defined" bit, so type from an existing number format + // can directly be used for getStandardFormat + nType &= ~NUMBERFORMAT_DEFINED; + nRet = pFormatter->GetStandardFormat(nType, eLang); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::getFormatIndex( sal_Int16 nIndex, const lang::Locale& nLocale ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + LanguageType eLang = lcl_GetLanguage( nLocale ); + nRet = pFormatter->GetFormatIndex( (NfIndexTableOffset)nIndex, eLang ); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +sal_Bool SAL_CALL SvNumberFormatsObj::isTypeCompatible( sal_Int16 nOldType, sal_Int16 nNewType ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + BOOL bRet = FALSE; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + bRet = pFormatter->IsCompatible( nOldType, nNewType ); + else + throw uno::RuntimeException(); + + return bRet; +} + +sal_Int32 SAL_CALL SvNumberFormatsObj::getFormatForLocale( sal_Int32 nKey, const lang::Locale& nLocale ) + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + INT32 nRet = 0; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + LanguageType eLang = lcl_GetLanguage( nLocale ); + nRet = pFormatter->GetFormatForLanguageIfBuiltIn(nKey, eLang); + } + else + throw uno::RuntimeException(); + + return nRet; +} + +// XServiceInfo + +rtl::OUString SAL_CALL SvNumberFormatsObj::getImplementationName() + throw(uno::RuntimeException) +{ + return rtl::OUString::createFromAscii("SvNumberFormatsObj"); +} + +sal_Bool SAL_CALL SvNumberFormatsObj::supportsService( const rtl::OUString& ServiceName ) + throw(uno::RuntimeException) +{ + return ( ServiceName.compareToAscii(SERVICENAME_NUMBERFORMATS) == 0 ); +} + +uno::Sequence<rtl::OUString> SAL_CALL SvNumberFormatsObj::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + uno::Sequence<rtl::OUString> aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString::createFromAscii(SERVICENAME_NUMBERFORMATS); + return aRet; +} + +//------------------------------------------------------------------------ + +SvNumberFormatObj::SvNumberFormatObj( SvNumberFormatsSupplierObj& rParent, ULONG nK, const ::comphelper::SharedMutex& _rMutex ) + :rSupplier( rParent ) + ,nKey( nK ) + ,m_aMutex( _rMutex ) +{ + rSupplier.acquire(); +} + +SvNumberFormatObj::~SvNumberFormatObj() +{ + rSupplier.release(); +} + +// XPropertySet + +uno::Reference<beans::XPropertySetInfo> SAL_CALL SvNumberFormatObj::getPropertySetInfo() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + static uno::Reference<beans::XPropertySetInfo> aRef = + new SfxItemPropertySetInfo( lcl_GetNumberFormatPropertyMap() ); + return aRef; +} + +void SAL_CALL SvNumberFormatObj::setPropertyValue( const rtl::OUString&, + const uno::Any& ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + throw beans::UnknownPropertyException(); // everything is read-only +} + +uno::Any SAL_CALL SvNumberFormatObj::getPropertyValue( const rtl::OUString& aPropertyName ) + throw(beans::UnknownPropertyException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Any aRet; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + const SvNumberformat* pFormat = pFormatter ? pFormatter->GetEntry(nKey) : NULL; + if (pFormat) + { + BOOL bThousand, bRed; + USHORT nDecimals, nLeading; + + String aString = aPropertyName; + if (aString.EqualsAscii( PROPERTYNAME_FMTSTR )) + { + aRet <<= rtl::OUString( pFormat->GetFormatstring() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_LOCALE )) + { + lang::Locale aLocale( MsLangId::convertLanguageToLocale( + pFormat->GetLanguage())); + aRet <<= aLocale; + } + else if (aString.EqualsAscii( PROPERTYNAME_TYPE )) + { + aRet <<= (sal_Int16)( pFormat->GetType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_COMMENT )) + { + aRet <<= rtl::OUString( pFormat->GetComment() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_STDFORM )) + { + //! SvNumberformat Member bStandard rausreichen? + BOOL bStandard = ( ( nKey % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 ); + aRet.setValue( &bStandard, getBooleanCppuType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_USERDEF )) + { + BOOL bUserDef = ( ( pFormat->GetType() & NUMBERFORMAT_DEFINED ) != 0 ); + aRet.setValue( &bUserDef, getBooleanCppuType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_DECIMALS )) + { + pFormat->GetFormatSpecialInfo( bThousand, bRed, nDecimals, nLeading ); + aRet <<= (sal_Int16)( nDecimals ); + } + else if (aString.EqualsAscii( PROPERTYNAME_LEADING )) + { + pFormat->GetFormatSpecialInfo( bThousand, bRed, nDecimals, nLeading ); + aRet <<= (sal_Int16)( nLeading ); + } + else if (aString.EqualsAscii( PROPERTYNAME_NEGRED )) + { + pFormat->GetFormatSpecialInfo( bThousand, bRed, nDecimals, nLeading ); + aRet.setValue( &bRed, getBooleanCppuType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_THOUS )) + { + pFormat->GetFormatSpecialInfo( bThousand, bRed, nDecimals, nLeading ); + aRet.setValue( &bThousand, getBooleanCppuType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_CURRSYM )) + { + String aSymbol, aExt; + pFormat->GetNewCurrencySymbol( aSymbol, aExt ); + aRet <<= rtl::OUString( aSymbol ); + } + else if (aString.EqualsAscii( PROPERTYNAME_CURREXT )) + { + String aSymbol, aExt; + pFormat->GetNewCurrencySymbol( aSymbol, aExt ); + aRet <<= rtl::OUString( aExt ); + } + else if (aString.EqualsAscii( PROPERTYNAME_CURRABB )) + { + String aSymbol, aExt; + BOOL bBank = FALSE; + pFormat->GetNewCurrencySymbol( aSymbol, aExt ); + const NfCurrencyEntry* pCurr = pFormatter->GetCurrencyEntry( bBank, + aSymbol, aExt, pFormat->GetLanguage() ); + if ( pCurr ) + aRet <<= rtl::OUString( pCurr->GetBankSymbol() ); + else + aRet <<= rtl::OUString(); + } + else + throw beans::UnknownPropertyException(); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +void SAL_CALL SvNumberFormatObj::addPropertyChangeListener( const rtl::OUString&, + const uno::Reference<beans::XPropertyChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatObj::removePropertyChangeListener( const rtl::OUString&, + const uno::Reference<beans::XPropertyChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatObj::addVetoableChangeListener( const rtl::OUString&, + const uno::Reference<beans::XVetoableChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatObj::removeVetoableChangeListener( const rtl::OUString&, + const uno::Reference<beans::XVetoableChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +// XPropertyAccess + +uno::Sequence<beans::PropertyValue> SAL_CALL SvNumberFormatObj::getPropertyValues() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + const SvNumberformat* pFormat = pFormatter ? pFormatter->GetEntry(nKey) : NULL; + if (pFormat) + { + String aSymbol, aExt, aAbb; + BOOL bBank = FALSE; + pFormat->GetNewCurrencySymbol( aSymbol, aExt ); + const NfCurrencyEntry* pCurr = pFormatter->GetCurrencyEntry( bBank, + aSymbol, aExt, pFormat->GetLanguage() ); + if ( pCurr ) + aAbb = pCurr->GetBankSymbol(); + + String aFmtStr = pFormat->GetFormatstring(); + String aComment = pFormat->GetComment(); + BOOL bStandard = ( ( nKey % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 ); + //! SvNumberformat Member bStandard rausreichen? + BOOL bUserDef = ( ( pFormat->GetType() & NUMBERFORMAT_DEFINED ) != 0 ); + BOOL bThousand, bRed; + USHORT nDecimals, nLeading; + pFormat->GetFormatSpecialInfo( bThousand, bRed, nDecimals, nLeading ); + lang::Locale aLocale( MsLangId::convertLanguageToLocale( + pFormat->GetLanguage())); + + uno::Sequence<beans::PropertyValue> aSeq(13); + beans::PropertyValue* pArray = aSeq.getArray(); + + pArray[0].Name = rtl::OUString::createFromAscii( PROPERTYNAME_FMTSTR ); + pArray[0].Value <<= rtl::OUString( aFmtStr ); + pArray[1].Name = rtl::OUString::createFromAscii( PROPERTYNAME_LOCALE ); + pArray[1].Value <<= aLocale; + pArray[2].Name = rtl::OUString::createFromAscii( PROPERTYNAME_TYPE ); + pArray[2].Value <<= (sal_Int16)( pFormat->GetType() ); + pArray[3].Name = rtl::OUString::createFromAscii( PROPERTYNAME_COMMENT ); + pArray[3].Value <<= rtl::OUString( aComment ); + pArray[4].Name = rtl::OUString::createFromAscii( PROPERTYNAME_STDFORM ); + pArray[4].Value.setValue( &bStandard, getBooleanCppuType() ); + pArray[5].Name = rtl::OUString::createFromAscii( PROPERTYNAME_USERDEF ); + pArray[5].Value.setValue( &bUserDef, getBooleanCppuType() ); + pArray[6].Name = rtl::OUString::createFromAscii( PROPERTYNAME_DECIMALS ); + pArray[6].Value <<= (sal_Int16)( nDecimals ); + pArray[7].Name = rtl::OUString::createFromAscii( PROPERTYNAME_LEADING ); + pArray[7].Value <<= (sal_Int16)( nLeading ); + pArray[8].Name = rtl::OUString::createFromAscii( PROPERTYNAME_NEGRED ); + pArray[8].Value.setValue( &bRed, getBooleanCppuType() ); + pArray[9].Name = rtl::OUString::createFromAscii( PROPERTYNAME_THOUS ); + pArray[9].Value.setValue( &bThousand, getBooleanCppuType() ); + pArray[10].Name = rtl::OUString::createFromAscii( PROPERTYNAME_CURRSYM ); + pArray[10].Value <<= rtl::OUString( aSymbol ); + pArray[11].Name = rtl::OUString::createFromAscii( PROPERTYNAME_CURREXT ); + pArray[11].Value <<= rtl::OUString( aExt ); + pArray[12].Name = rtl::OUString::createFromAscii( PROPERTYNAME_CURRABB ); + pArray[12].Value <<= rtl::OUString( aAbb ); + + return aSeq; + } + else + throw uno::RuntimeException(); +} + +void SAL_CALL SvNumberFormatObj::setPropertyValues( const uno::Sequence<beans::PropertyValue>& ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + throw beans::UnknownPropertyException(); // everything is read-only +} + +// XServiceInfo + +rtl::OUString SAL_CALL SvNumberFormatObj::getImplementationName() + throw(uno::RuntimeException) +{ + return rtl::OUString::createFromAscii("SvNumberFormatObj"); +} + +sal_Bool SAL_CALL SvNumberFormatObj::supportsService( const rtl::OUString& ServiceName ) + throw(uno::RuntimeException) +{ + return ( ServiceName.compareToAscii(SERVICENAME_NUMBERFORMAT) == 0 ); +} + +uno::Sequence<rtl::OUString> SAL_CALL SvNumberFormatObj::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + uno::Sequence<rtl::OUString> aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString::createFromAscii(SERVICENAME_NUMBERFORMAT); + return aRet; +} + +//------------------------------------------------------------------------ + +SvNumberFormatSettingsObj::SvNumberFormatSettingsObj( SvNumberFormatsSupplierObj& rParent, const ::comphelper::SharedMutex& _rMutex ) + :rSupplier( rParent ) + ,m_aMutex( _rMutex ) +{ + rSupplier.acquire(); +} + +SvNumberFormatSettingsObj::~SvNumberFormatSettingsObj() +{ + rSupplier.release(); +} + +// XPropertySet + +uno::Reference<beans::XPropertySetInfo> SAL_CALL SvNumberFormatSettingsObj::getPropertySetInfo() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + static uno::Reference<beans::XPropertySetInfo> aRef = + new SfxItemPropertySetInfo( lcl_GetNumberSettingsPropertyMap() ); + return aRef; +} + +void SAL_CALL SvNumberFormatSettingsObj::setPropertyValue( const rtl::OUString& aPropertyName, + const uno::Any& aValue ) + throw(beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + String aString = aPropertyName; + if (aString.EqualsAscii( PROPERTYNAME_NOZERO )) + { + // operator >>= shouldn't be used for bool (?) + if ( aValue.getValueTypeClass() == uno::TypeClass_BOOLEAN ) + pFormatter->SetNoZero( *(sal_Bool*)aValue.getValue() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_NULLDATE )) + { + util::Date aDate; + if ( aValue >>= aDate ) + pFormatter->ChangeNullDate( aDate.Day, aDate.Month, aDate.Year ); + } + else if (aString.EqualsAscii( PROPERTYNAME_STDDEC )) + { + sal_Int16 nInt16 = sal_Int16(); + if ( aValue >>= nInt16 ) + pFormatter->ChangeStandardPrec( nInt16 ); + } + else if (aString.EqualsAscii( PROPERTYNAME_TWODIGIT )) + { + sal_Int16 nInt16 = sal_Int16(); + if ( aValue >>= nInt16 ) + pFormatter->SetYear2000( nInt16 ); + } + else + throw beans::UnknownPropertyException(); + + rSupplier.SettingsChanged(); + } + else + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL SvNumberFormatSettingsObj::getPropertyValue( const rtl::OUString& aPropertyName ) + throw(beans::UnknownPropertyException, lang::WrappedTargetException, + uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Any aRet; + SvNumberFormatter* pFormatter = rSupplier.GetNumberFormatter(); + if (pFormatter) + { + String aString = aPropertyName; + if (aString.EqualsAscii( PROPERTYNAME_NOZERO )) + { + BOOL bNoZero = pFormatter->GetNoZero(); + aRet.setValue( &bNoZero, getBooleanCppuType() ); + } + else if (aString.EqualsAscii( PROPERTYNAME_NULLDATE )) + { + Date* pDate = pFormatter->GetNullDate(); + if (pDate) + { + util::Date aUnoDate( pDate->GetDay(), pDate->GetMonth(), pDate->GetYear() ); + aRet <<= aUnoDate; + } + } + else if (aString.EqualsAscii( PROPERTYNAME_STDDEC )) + aRet <<= (sal_Int16)( pFormatter->GetStandardPrec() ); + else if (aString.EqualsAscii( PROPERTYNAME_TWODIGIT )) + aRet <<= (sal_Int16)( pFormatter->GetYear2000() ); + else + throw beans::UnknownPropertyException(); + } + else + throw uno::RuntimeException(); + + return aRet; +} + +void SAL_CALL SvNumberFormatSettingsObj::addPropertyChangeListener( const rtl::OUString&, + const uno::Reference<beans::XPropertyChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatSettingsObj::removePropertyChangeListener( const rtl::OUString&, + const uno::Reference<beans::XPropertyChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatSettingsObj::addVetoableChangeListener( const rtl::OUString&, + const uno::Reference<beans::XVetoableChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +void SAL_CALL SvNumberFormatSettingsObj::removeVetoableChangeListener( const rtl::OUString&, + const uno::Reference<beans::XVetoableChangeListener>&) + throw(beans::UnknownPropertyException, + lang::WrappedTargetException, uno::RuntimeException) +{ + DBG_ERROR("not implemented"); +} + +// XServiceInfo + +rtl::OUString SAL_CALL SvNumberFormatSettingsObj::getImplementationName() + throw(uno::RuntimeException) +{ + return rtl::OUString::createFromAscii("SvNumberFormatSettingsObj"); +} + +sal_Bool SAL_CALL SvNumberFormatSettingsObj::supportsService( const rtl::OUString& ServiceName ) + throw(uno::RuntimeException) +{ + return ( ServiceName.compareToAscii(SERVICENAME_NUMBERSETTINGS) == 0 ); +} + +uno::Sequence<rtl::OUString> SAL_CALL SvNumberFormatSettingsObj::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + uno::Sequence<rtl::OUString> aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString::createFromAscii(SERVICENAME_NUMBERSETTINGS); + return aRet; +} + + diff --git a/svl/source/numbers/numfmuno.hxx b/svl/source/numbers/numfmuno.hxx new file mode 100644 index 000000000000..4148069fb37e --- /dev/null +++ b/svl/source/numbers/numfmuno.hxx @@ -0,0 +1,324 @@ +/************************************************************************* + * + * 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: numfmuno.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _NUMFMUNO_HXX +#define _NUMFMUNO_HXX + +#include <com/sun/star/util/XNumberFormatter.hpp> +#include <com/sun/star/util/XNumberFormatPreviewer.hpp> +#include <com/sun/star/util/XNumberFormats.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <comphelper/sharedmutex.hxx> +#include <rtl/ref.hxx> + +class SvNumberformat; +class SvNumberFormatter; +class SvNumberFormatsSupplierObj; + + +// SvNumberFormatterServiceObj wird global als Service angemeldet + +class SvNumberFormatterServiceObj : public cppu::WeakImplHelper3< + com::sun::star::util::XNumberFormatter, + com::sun::star::util::XNumberFormatPreviewer, + com::sun::star::lang::XServiceInfo> +{ +private: + ::rtl::Reference< SvNumberFormatsSupplierObj > xSupplier; + mutable ::comphelper::SharedMutex m_aMutex; + +public: + SvNumberFormatterServiceObj(); + virtual ~SvNumberFormatterServiceObj(); + + // XNumberFormatter + virtual void SAL_CALL attachNumberFormatsSupplier( + const ::com::sun::star::uno::Reference< + ::com::sun::star::util::XNumberFormatsSupplier >& xSupplier ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > + SAL_CALL getNumberFormatsSupplier() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL detectNumberFormat( sal_Int32 nKey, const ::rtl::OUString& aString ) + throw(::com::sun::star::util::NotNumericException, + ::com::sun::star::uno::RuntimeException); + virtual double SAL_CALL convertStringToNumber( sal_Int32 nKey, const ::rtl::OUString& aString ) + throw(::com::sun::star::util::NotNumericException, + ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL convertNumberToString( sal_Int32 nKey, double fValue ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Color SAL_CALL queryColorForNumber( sal_Int32 nKey, + double fValue, ::com::sun::star::util::Color aDefaultColor ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL formatString( sal_Int32 nKey, const ::rtl::OUString& aString ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Color SAL_CALL queryColorForString( sal_Int32 nKey, + const ::rtl::OUString& aString, + ::com::sun::star::util::Color aDefaultColor ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getInputString( sal_Int32 nKey, double fValue ) + throw(::com::sun::star::uno::RuntimeException); + + // XNumberFormatPreviewer + virtual ::rtl::OUString SAL_CALL convertNumberToPreviewString( + const ::rtl::OUString& aFormat, double fValue, + const ::com::sun::star::lang::Locale& nLocale, sal_Bool bAllowEnglish ) + throw(::com::sun::star::util::MalformedNumberFormatException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::util::Color SAL_CALL queryPreviewColorForNumber( + const ::rtl::OUString& aFormat, double fValue, + const ::com::sun::star::lang::Locale& nLocale, sal_Bool bAllowEnglish, + ::com::sun::star::util::Color aDefaultColor ) + throw(::com::sun::star::util::MalformedNumberFormatException, + ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); +}; + + +class SvNumberFormatsObj : public cppu::WeakImplHelper3< + com::sun::star::util::XNumberFormats, + com::sun::star::util::XNumberFormatTypes, + com::sun::star::lang::XServiceInfo> +{ +private: + SvNumberFormatsSupplierObj& rSupplier; + mutable ::comphelper::SharedMutex m_aMutex; + +public: + SvNumberFormatsObj(SvNumberFormatsSupplierObj& pParent, ::comphelper::SharedMutex& _rMutex); + virtual ~SvNumberFormatsObj(); + + + // XNumberFormats + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + getByKey( sal_Int32 nKey ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL queryKeys( sal_Int16 nType, + const ::com::sun::star::lang::Locale& nLocale, sal_Bool bCreate ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL queryKey( const ::rtl::OUString& aFormat, + const ::com::sun::star::lang::Locale& nLocale, sal_Bool bScan ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL addNew( const ::rtl::OUString& aFormat, + const ::com::sun::star::lang::Locale& nLocale ) + throw(::com::sun::star::util::MalformedNumberFormatException, + ::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL addNewConverted( const ::rtl::OUString& aFormat, + const ::com::sun::star::lang::Locale& nLocale, + const ::com::sun::star::lang::Locale& nNewLocale ) + throw(::com::sun::star::util::MalformedNumberFormatException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeByKey( sal_Int32 nKey ) throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL generateFormat( sal_Int32 nBaseKey, + const ::com::sun::star::lang::Locale& nLocale, sal_Bool bThousands, + sal_Bool bRed, sal_Int16 nDecimals, sal_Int16 nLeading ) + throw(::com::sun::star::uno::RuntimeException); + + // XNumberFormatTypes + virtual sal_Int32 SAL_CALL getStandardIndex( const ::com::sun::star::lang::Locale& nLocale ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getStandardFormat( sal_Int16 nType, + const ::com::sun::star::lang::Locale& nLocale ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getFormatIndex( sal_Int16 nIndex, + const ::com::sun::star::lang::Locale& nLocale ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isTypeCompatible( sal_Int16 nOldType, sal_Int16 nNewType ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getFormatForLocale( sal_Int32 nKey, + const ::com::sun::star::lang::Locale& nLocale ) + throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + +private: + SvNumberFormatsObj(); // never implemented +}; + + +class SvNumberFormatObj : public cppu::WeakImplHelper3< + com::sun::star::beans::XPropertySet, + com::sun::star::beans::XPropertyAccess, + com::sun::star::lang::XServiceInfo> +{ +private: + SvNumberFormatsSupplierObj& rSupplier; + ULONG nKey; + mutable ::comphelper::SharedMutex m_aMutex; + +public: + SvNumberFormatObj( SvNumberFormatsSupplierObj& rParent, ULONG nK, const ::comphelper::SharedMutex& _rMutex ); + virtual ~SvNumberFormatObj(); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + SAL_CALL getPropertySetInfo( ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( + const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XPropertyAccess + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL + getPropertyValues() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& aProps ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); +}; + + +class SvNumberFormatSettingsObj : public cppu::WeakImplHelper2< + com::sun::star::beans::XPropertySet, + com::sun::star::lang::XServiceInfo> +{ +private: + SvNumberFormatsSupplierObj& rSupplier; + mutable ::comphelper::SharedMutex m_aMutex; + +public: + SvNumberFormatSettingsObj( SvNumberFormatsSupplierObj& rParent, const ::comphelper::SharedMutex& _rMutex); + virtual ~SvNumberFormatSettingsObj(); + + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > + SAL_CALL getPropertySetInfo( ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Any& aValue ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::beans::PropertyVetoException, + ::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( + const ::rtl::OUString& PropertyName ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, + const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw(::com::sun::star::beans::UnknownPropertyException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); +}; + + + +#endif + diff --git a/svl/source/numbers/numhead.cxx b/svl/source/numbers/numhead.cxx new file mode 100644 index 000000000000..99ff33433de3 --- /dev/null +++ b/svl/source/numbers/numhead.cxx @@ -0,0 +1,252 @@ +/************************************************************************* + * + * 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: numhead.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif +#include <tools/debug.hxx> + +#include "numhead.hxx" + +// ID's fuer Dateien: +#define SV_NUMID_SIZES 0x4200 + +// STATIC DATA ----------------------------------------------------------- + +//SEG_EOFGLOBALS() + +// ======================================================================= +/* wird fuer SvNumberformatter nicht gebraucht +//#pragma SEG_FUNCDEF(numhead_01) + +SvNumReadHeader::SvNumReadHeader(SvStream& rNewStream) : + rStream( rNewStream ) +{ + ULONG nDataSize; + rStream >> nDataSize; + nDataEnd = rStream.Tell() + nDataSize; +} + +//#pragma SEG_FUNCDEF(numhead_02) + +SvNumReadHeader::~SvNumReadHeader() +{ + ULONG nReadEnd = rStream.Tell(); + DBG_ASSERT( nReadEnd <= nDataEnd, "zuviele Bytes gelesen" ); + if ( nReadEnd != nDataEnd ) + rStream.Seek(nDataEnd); // Rest ueberspringen +} + +//#pragma SEG_FUNCDEF(numhead_03) + +ULONG SvNumReadHeader::BytesLeft() const +{ + ULONG nReadEnd = rStream.Tell(); + if (nReadEnd <= nDataEnd) + return nDataEnd-nReadEnd; + + DBG_ERROR("Fehler bei SvNumReadHeader::BytesLeft"); + return 0; +} + +// ----------------------------------------------------------------------- + +//#pragma SEG_FUNCDEF(numhead_04) + +SvNumWriteHeader::SvNumWriteHeader(SvStream& rNewStream, ULONG nDefault) : + rStream( rNewStream ) +{ + nDataSize = nDefault; + rStream << nDataSize; + nDataPos = rStream.Tell(); +} + +//#pragma SEG_FUNCDEF(numhead_05) + +SvNumWriteHeader::~SvNumWriteHeader() +{ + ULONG nPos = rStream.Tell(); + + if ( nPos - nDataPos != nDataSize ) // Default getroffen? + { + nDataSize = nPos - nDataPos; + rStream.Seek(nDataPos - sizeof(sal_uInt32)); + rStream << nDataSize; // Groesse am Anfang eintragen + rStream.Seek(nPos); + } +} +*/ + +// ======================================================================= + +//#pragma SEG_FUNCDEF(numhead_06) + +//! mit Skip() synchron +ImpSvNumMultipleReadHeader::ImpSvNumMultipleReadHeader(SvStream& rNewStream) : + rStream( rNewStream ) +{ + sal_uInt32 nDataSize; + rStream >> nDataSize; + ULONG nDataPos = rStream.Tell(); + nEntryEnd = nDataPos; + + rStream.SeekRel(nDataSize); + USHORT nID; + rStream >> nID; + if (nID != SV_NUMID_SIZES) + { + DBG_ERROR("SV_NUMID_SIZES nicht gefunden"); + } + sal_uInt32 nSizeTableLen; + rStream >> nSizeTableLen; + pBuf = new char[nSizeTableLen]; + rStream.Read( pBuf, nSizeTableLen ); + pMemStream = new SvMemoryStream( pBuf, nSizeTableLen, STREAM_READ ); + + nEndPos = rStream.Tell(); + rStream.Seek( nDataPos ); +} + +//#pragma SEG_FUNCDEF(numhead_07) + +ImpSvNumMultipleReadHeader::~ImpSvNumMultipleReadHeader() +{ + DBG_ASSERT( pMemStream->Tell() == pMemStream->GetSize(), + "Sizes nicht vollstaendig gelesen" ); + delete pMemStream; + delete [] pBuf; + + rStream.Seek(nEndPos); +} + +//! mit ctor synchron +// static +void ImpSvNumMultipleReadHeader::Skip( SvStream& rStream ) +{ + sal_uInt32 nDataSize; + rStream >> nDataSize; + rStream.SeekRel( nDataSize ); + USHORT nID; + rStream >> nID; + if ( nID != SV_NUMID_SIZES ) + { + DBG_ERROR("SV_NUMID_SIZES nicht gefunden"); + } + sal_uInt32 nSizeTableLen; + rStream >> nSizeTableLen; + rStream.SeekRel( nSizeTableLen ); +} + +//#pragma SEG_FUNCDEF(numhead_08) + +void ImpSvNumMultipleReadHeader::EndEntry() +{ + ULONG nPos = rStream.Tell(); + DBG_ASSERT( nPos <= nEntryEnd, "zuviel gelesen" ); + if ( nPos != nEntryEnd ) + rStream.Seek( nEntryEnd ); // Rest ueberspringen +} + +//#pragma SEG_FUNCDEF(numhead_0d) + +void ImpSvNumMultipleReadHeader::StartEntry() +{ + ULONG nPos = rStream.Tell(); + sal_uInt32 nEntrySize; + (*pMemStream) >> nEntrySize; + + nEntryEnd = nPos + nEntrySize; +} + +//#pragma SEG_FUNCDEF(numhead_09) + +ULONG ImpSvNumMultipleReadHeader::BytesLeft() const +{ + ULONG nReadEnd = rStream.Tell(); + if (nReadEnd <= nEntryEnd) + return nEntryEnd-nReadEnd; + + DBG_ERROR("Fehler bei ImpSvNumMultipleReadHeader::BytesLeft"); + return 0; +} + +// ----------------------------------------------------------------------- + +//#pragma SEG_FUNCDEF(numhead_0a) + +ImpSvNumMultipleWriteHeader::ImpSvNumMultipleWriteHeader(SvStream& rNewStream, + ULONG nDefault) : + rStream( rNewStream ), + aMemStream( 4096, 4096 ) +{ + nDataSize = nDefault; + rStream << nDataSize; + + nDataPos = rStream.Tell(); + nEntryStart = nDataPos; +} + +//#pragma SEG_FUNCDEF(numhead_0b) + +ImpSvNumMultipleWriteHeader::~ImpSvNumMultipleWriteHeader() +{ + ULONG nDataEnd = rStream.Tell(); + + rStream << (USHORT) SV_NUMID_SIZES; + rStream << static_cast<sal_uInt32>(aMemStream.Tell()); + rStream.Write( aMemStream.GetData(), aMemStream.Tell() ); + + if ( nDataEnd - nDataPos != nDataSize ) // Default getroffen? + { + nDataSize = nDataEnd - nDataPos; + ULONG nPos = rStream.Tell(); + rStream.Seek(nDataPos-sizeof(sal_uInt32)); + rStream << nDataSize; // Groesse am Anfang eintragen + rStream.Seek(nPos); + } +} + +//#pragma SEG_FUNCDEF(numhead_0c) + +void ImpSvNumMultipleWriteHeader::EndEntry() +{ + ULONG nPos = rStream.Tell(); + aMemStream << static_cast<sal_uInt32>(nPos - nEntryStart); +} + +//#pragma SEG_FUNCDEF(numhead_0e) + +void ImpSvNumMultipleWriteHeader::StartEntry() +{ + ULONG nPos = rStream.Tell(); + nEntryStart = nPos; +} + diff --git a/svl/source/numbers/numhead.hxx b/svl/source/numbers/numhead.hxx new file mode 100644 index 000000000000..de23b3cbccf4 --- /dev/null +++ b/svl/source/numbers/numhead.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * 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: numhead.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef NF_NUMHEAD_HXX +#define NF_NUMHEAD_HXX + +#include <tools/stream.hxx> + +// ----------------------------------------------------------------------- + + // "Automatischer" Record-Header mit Groessenangabe + +/* wird fuer SvNumberFormatter nicht gebraucht +class SvNumReadHeader +{ +private: + SvStream& rStream; + ULONG nDataEnd; + +public: + SvNumReadHeader(SvStream& rNewStream); + ~SvNumReadHeader(); + + ULONG BytesLeft() const; +}; + +class SvNumWriteHeader +{ +private: + SvStream& rStream; + ULONG nDataPos; + ULONG nDataSize; + +public: + SvNumWriteHeader(SvStream& rNewStream, ULONG nDefault = 0); + ~SvNumWriteHeader(); +}; + +*/ + + // Header mit Groessenangaben fuer mehrere Objekte + +class ImpSvNumMultipleReadHeader +{ +private: + SvStream& rStream; + char* pBuf; + SvMemoryStream* pMemStream; + ULONG nEndPos; + ULONG nEntryEnd; + +public: + ImpSvNumMultipleReadHeader(SvStream& rNewStream); + ~ImpSvNumMultipleReadHeader(); + + void StartEntry(); + void EndEntry(); + ULONG BytesLeft() const; + + static void Skip( SvStream& ); // komplett ueberspringen +}; + +class ImpSvNumMultipleWriteHeader +{ +private: + SvStream& rStream; + SvMemoryStream aMemStream; + ULONG nDataPos; + sal_uInt32 nDataSize; + ULONG nEntryStart; + +public: + ImpSvNumMultipleWriteHeader(SvStream& rNewStream, ULONG nDefault = 0); + ~ImpSvNumMultipleWriteHeader(); + + void StartEntry(); + void EndEntry(); +}; + +#endif + + diff --git a/svl/source/numbers/numuno.cxx b/svl/source/numbers/numuno.cxx new file mode 100644 index 000000000000..3cc90998e2dc --- /dev/null +++ b/svl/source/numbers/numuno.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * 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: numuno.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#define _ZFORLIST_DECLARE_TABLE + +#include <tools/color.hxx> +#include <tools/debug.hxx> +#include <vos/mutex.hxx> +#include <osl/mutex.hxx> +#include <rtl/uuid.h> + +#include "numuno.hxx" +#include "numfmuno.hxx" +#include <svl/zforlist.hxx> + +using namespace com::sun::star; + +//------------------------------------------------------------------------ + +class SvNumFmtSuppl_Impl +{ +public: + SvNumberFormatter* pFormatter; + mutable ::comphelper::SharedMutex aMutex; + + SvNumFmtSuppl_Impl(SvNumberFormatter* p) : + pFormatter(p) {} +}; + +//------------------------------------------------------------------------ + +// Default-ctor fuer getReflection +SvNumberFormatsSupplierObj::SvNumberFormatsSupplierObj() +{ + pImpl = new SvNumFmtSuppl_Impl(NULL); +} + +SvNumberFormatsSupplierObj::SvNumberFormatsSupplierObj(SvNumberFormatter* pForm) +{ + pImpl = new SvNumFmtSuppl_Impl(pForm); +} + +SvNumberFormatsSupplierObj::~SvNumberFormatsSupplierObj() +{ + delete pImpl; +} + +::comphelper::SharedMutex& SvNumberFormatsSupplierObj::getSharedMutex() const +{ + return pImpl->aMutex; +} + +SvNumberFormatter* SvNumberFormatsSupplierObj::GetNumberFormatter() const +{ + return pImpl->pFormatter; +} + +void SvNumberFormatsSupplierObj::SetNumberFormatter(SvNumberFormatter* pNew) +{ + // der alte Numberformatter ist ungueltig geworden, nicht mehr darauf zugreifen! + pImpl->pFormatter = pNew; +} + +void SvNumberFormatsSupplierObj::NumberFormatDeleted(sal_uInt32) +{ + // Basis-Implementierung tut nix... +} + +void SvNumberFormatsSupplierObj::SettingsChanged() +{ + // Basis-Implementierung tut nix... +} + +// XNumberFormatsSupplier + +uno::Reference<beans::XPropertySet> SAL_CALL SvNumberFormatsSupplierObj::getNumberFormatSettings() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( pImpl->aMutex ); + + return new SvNumberFormatSettingsObj( *this, pImpl->aMutex ); +} + +uno::Reference<util::XNumberFormats> SAL_CALL SvNumberFormatsSupplierObj::getNumberFormats() + throw(uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( pImpl->aMutex ); + + return new SvNumberFormatsObj( *this, pImpl->aMutex ); +} + +// XUnoTunnel + +sal_Int64 SAL_CALL SvNumberFormatsSupplierObj::getSomething( + const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) +{ + if ( rId.getLength() == 16 && + 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), + rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); + } + return 0; +} + +// static +const uno::Sequence<sal_Int8>& SvNumberFormatsSupplierObj::getUnoTunnelId() +{ + static uno::Sequence<sal_Int8> * pSeq = 0; + if( !pSeq ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +// static +SvNumberFormatsSupplierObj* SvNumberFormatsSupplierObj::getImplementation( + const uno::Reference<util::XNumberFormatsSupplier> xObj ) +{ + SvNumberFormatsSupplierObj* pRet = NULL; + uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); + if (xUT.is()) + pRet = reinterpret_cast<SvNumberFormatsSupplierObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething( getUnoTunnelId() ))); + return pRet; +} + + +//------------------------------------------------------------------------ + + + diff --git a/svl/source/numbers/supservs.cxx b/svl/source/numbers/supservs.cxx new file mode 100644 index 000000000000..7e4d8560dae7 --- /dev/null +++ b/svl/source/numbers/supservs.cxx @@ -0,0 +1,232 @@ +/************************************************************************* + * + * 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: supservs.cxx,v $ + * $Revision: 1.10 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "supservs.hxx" +#include <com/sun/star/lang/Locale.hpp> +#include <comphelper/sharedmutex.hxx> +#include <i18npool/mslangid.hxx> +#include <tools/debug.hxx> +#include <vos/mutex.hxx> +#include <tools/stream.hxx> +#include <strmadpt.hxx> +#include "instrm.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; +using namespace ::vos; +using namespace ::utl; + +#define PERSISTENT_SERVICE_NAME ::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier"); + +//------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SvNumberFormatsSupplierServiceObject_CreateInstance(const Reference< XMultiServiceFactory >& _rxFactory) +{ + return static_cast< ::cppu::OWeakObject* >(new SvNumberFormatsSupplierServiceObject(_rxFactory)); +} + +//------------------------------------------------------------------------- +SvNumberFormatsSupplierServiceObject::SvNumberFormatsSupplierServiceObject(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB) + :m_pOwnFormatter(NULL) + ,m_xORB(_rxORB) +{ +} + +//------------------------------------------------------------------------- +SvNumberFormatsSupplierServiceObject::~SvNumberFormatsSupplierServiceObject() +{ + if (m_pOwnFormatter) + { + delete m_pOwnFormatter; + m_pOwnFormatter = NULL; + } +} + +//------------------------------------------------------------------------- +Any SAL_CALL SvNumberFormatsSupplierServiceObject::queryAggregation( const Type& _rType ) throw (RuntimeException) +{ + Any aReturn = ::cppu::queryInterface(_rType, + static_cast< XInitialization* >(this), + static_cast< XPersistObject* >(this), + static_cast< XServiceInfo* >(this) + ); + + if (!aReturn.hasValue()) + aReturn = SvNumberFormatsSupplierObj::queryAggregation(_rType); + + return aReturn; +} + +//------------------------------------------------------------------------- +void SAL_CALL SvNumberFormatsSupplierServiceObject::initialize( const Sequence< Any >& _rArguments ) throw(Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( getSharedMutex() ); + + DBG_ASSERT(m_pOwnFormatter == NULL, + "SvNumberFormatsSupplierServiceObject::initialize : already initialized !"); + // maybe you already called a method which needed the formatter + // you should use XMultiServiceFactory::createInstanceWithArguments to avoid that + if (m_pOwnFormatter) + { // !!! this is only a emergency handling, normally this should not occur !!! + delete m_pOwnFormatter; + m_pOwnFormatter = NULL; + SetNumberFormatter(m_pOwnFormatter); + } + + Type aExpectedArgType = ::getCppuType(static_cast<Locale*>(NULL)); + LanguageType eNewFormatterLanguage = LANGUAGE_ENGLISH_US; + // the default + + const Any* pArgs = _rArguments.getConstArray(); + for (sal_Int32 i=0; i<_rArguments.getLength(); ++i, ++pArgs) + { + if (pArgs->getValueType().equals(aExpectedArgType)) + { + Locale aLocale; + *pArgs >>= aLocale; + eNewFormatterLanguage = MsLangId::convertLocaleToLanguage( aLocale); + } +#ifdef DBG_UTIL + else + { + DBG_ERROR("SvNumberFormatsSupplierServiceObject::initialize : unknown argument !"); + } +#endif + } + + m_pOwnFormatter = new SvNumberFormatter(m_xORB, eNewFormatterLanguage); + m_pOwnFormatter->SetEvalDateFormat( NF_EVALDATEFORMAT_FORMAT_INTL ); + SetNumberFormatter(m_pOwnFormatter); +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SvNumberFormatsSupplierServiceObject::getImplementationName( ) throw(RuntimeException) +{ + return ::rtl::OUString::createFromAscii("com.sun.star.uno.util.numbers.SvNumberFormatsSupplierServiceObject"); +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL SvNumberFormatsSupplierServiceObject::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aServices = getSupportedServiceNames(); + const ::rtl::OUString* pServices = aServices.getConstArray(); + for (sal_Int32 i=0; i<aServices.getLength(); ++i, ++pServices) + if (pServices->equals(_rServiceName)) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------- +Sequence< ::rtl::OUString > SAL_CALL SvNumberFormatsSupplierServiceObject::getSupportedServiceNames( ) throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(1); + aSupported.getArray()[0] = PERSISTENT_SERVICE_NAME; + return aSupported; +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SvNumberFormatsSupplierServiceObject::getServiceName( ) throw(RuntimeException) +{ + return PERSISTENT_SERVICE_NAME; +} + +//------------------------------------------------------------------------- +void SAL_CALL SvNumberFormatsSupplierServiceObject::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getSharedMutex() ); + implEnsureFormatter(); + + Reference< XOutputStream > xStream(_rxOutStream.get()); + SvLockBytesRef aLockBytes = new SvOutputStreamOpenLockBytes(xStream); + SvStream aSvOutputSteam(aLockBytes); + + m_pOwnFormatter->Save(aSvOutputSteam); +} + +//------------------------------------------------------------------------- +void SAL_CALL SvNumberFormatsSupplierServiceObject::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException) +{ + ::osl::MutexGuard aGuard( getSharedMutex() ); + implEnsureFormatter(); + + Reference< XInputStream > xStream(_rxInStream.get()); + SvInputStream aSvInputSteam(xStream); + + m_pOwnFormatter->Load(aSvInputSteam); +} + +//------------------------------------------------------------------------- +Reference< XPropertySet > SAL_CALL SvNumberFormatsSupplierServiceObject::getNumberFormatSettings() throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( getSharedMutex() ); + implEnsureFormatter(); + return SvNumberFormatsSupplierObj::getNumberFormatSettings(); +} + +//------------------------------------------------------------------------- +Reference< XNumberFormats > SAL_CALL SvNumberFormatsSupplierServiceObject::getNumberFormats() throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( getSharedMutex() ); + implEnsureFormatter(); + return SvNumberFormatsSupplierObj::getNumberFormats(); +} + +//------------------------------------------------------------------------- +sal_Int64 SAL_CALL SvNumberFormatsSupplierServiceObject::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException) +{ + sal_Int64 nReturn = SvNumberFormatsSupplierObj::getSomething( aIdentifier ); + if ( nReturn ) + // if somebody accesses internals then we should have the formatter + implEnsureFormatter(); + return nReturn; +} + +//------------------------------------------------------------------------- +void SvNumberFormatsSupplierServiceObject::implEnsureFormatter() +{ + if (!m_pOwnFormatter) + { + // get the office's UI locale + SvtSysLocale aSysLocale; + Locale aOfficeLocale = aSysLocale.GetLocaleData().getLocale(); + + // initi with this locale + Sequence< Any > aFakedInitProps( 1 ); + aFakedInitProps[0] <<= aOfficeLocale; + + initialize( aFakedInitProps ); + } +} + diff --git a/svl/source/numbers/supservs.hxx b/svl/source/numbers/supservs.hxx new file mode 100644 index 000000000000..7dbbfe27177d --- /dev/null +++ b/svl/source/numbers/supservs.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * 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: supservs.hxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SVTOOLS_NUMBERS_SUPPLIERSERVICE_HXX_ +#define _SVTOOLS_NUMBERS_SUPPLIERSERVICE_HXX_ + +#include "numuno.hxx" +#include <svl/zforlist.hxx> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/io/XPersistObject.hpp> + +//========================================================================= +//= SvNumberFormatsSupplierServiceObject - a number formats supplier which +//= - can be instantiated as an service +//= - supports the ::com::sun::star::io::XPersistObject interface +//= - works with it's own SvNumberFormatter instance +//= - can be initialized (::com::sun::star::lang::XInitialization) +//= with a specific language (i.e. ::com::sun::star::lang::Locale) +//========================================================================= +class SvNumberFormatsSupplierServiceObject + :protected SvNumberFormatsSupplierObj + ,public ::com::sun::star::lang::XInitialization + ,public ::com::sun::star::io::XPersistObject + ,public ::com::sun::star::lang::XServiceInfo +{ // don't want the Set-/GetNumberFormatter to be accessable from outside + + friend ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + SAL_CALL SvNumberFormatsSupplierServiceObject_CreateInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&); + +protected: + SvNumberFormatter* m_pOwnFormatter; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + m_xORB; + +public: + SvNumberFormatsSupplierServiceObject(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB); + ~SvNumberFormatsSupplierServiceObject(); + + // XInterface + virtual void SAL_CALL acquire() throw() { SvNumberFormatsSupplierObj::acquire(); } + virtual void SAL_CALL release() throw() { SvNumberFormatsSupplierObj::release(); } + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException) + { return SvNumberFormatsSupplierObj::queryInterface(_rType); } + + // XAggregation + virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException); + + // XPersistObject + virtual ::rtl::OUString SAL_CALL getServiceName( ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + + // XNumberFormatsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL + getNumberFormatSettings() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > SAL_CALL + getNumberFormats() throw(::com::sun::star::uno::RuntimeException); + + // XUnoTunnler + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw (::com::sun::star::uno::RuntimeException); + +protected: + void implEnsureFormatter(); +}; + + +#endif // _SVTOOLS_NUMBERS_SUPPLIERSERVICE_HXX_ + diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx new file mode 100644 index 000000000000..372ae2b15abf --- /dev/null +++ b/svl/source/numbers/zforfind.cxx @@ -0,0 +1,2819 @@ +/************************************************************************* + * + * 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: zforfind.cxx,v $ + * $Revision: 1.51.96.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <ctype.h> +#include <stdlib.h> +#include <float.h> +#include <errno.h> +#include <tools/date.hxx> +#include <tools/debug.hxx> +#include <rtl/math.hxx> +#include <unotools/charclass.hxx> +#include <unotools/calendarwrapper.hxx> +#include <unotools/localedatawrapper.hxx> +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> +#include <unotools/digitgroupingiterator.hxx> + +#include <svl/zforlist.hxx> // NUMBERFORMAT_XXX +#include "zforscan.hxx" +#include <svl/zformat.hxx> + +#define _ZFORFIND_CXX +#include "zforfind.hxx" +#undef _ZFORFIND_CXX + + +#ifndef DBG_UTIL +#define NF_TEST_CALENDAR 0 +#else +#define NF_TEST_CALENDAR 0 +#endif +#if NF_TEST_CALENDAR +#include <comphelper/processfactory.hxx> +#include <com/sun/star/i18n/XExtendedCalendar.hpp> +#endif + + +const BYTE ImpSvNumberInputScan::nMatchedEndString = 0x01; +const BYTE ImpSvNumberInputScan::nMatchedMidString = 0x02; +const BYTE ImpSvNumberInputScan::nMatchedStartString = 0x04; +const BYTE ImpSvNumberInputScan::nMatchedVirgin = 0x08; +const BYTE ImpSvNumberInputScan::nMatchedUsedAsReturn = 0x10; + +/* It is not clear how we want timezones to be handled. Convert them to local + * time isn't wanted, as it isn't done in any other place and timezone + * information isn't stored anywhere. Ignoring them and pretending local time + * may be wrong too and might not be what the user expects. Keep the input as + * string so that no information is lost. + * Anyway, defining NF_RECOGNIZE_ISO8601_TIMEZONES to 1 would be the way how it + * would work, together with the nTimezonePos handling in GetTimeRef(). */ +#define NF_RECOGNIZE_ISO8601_TIMEZONES 0 + +//--------------------------------------------------------------------------- +// Konstruktor + +ImpSvNumberInputScan::ImpSvNumberInputScan( SvNumberFormatter* pFormatterP ) + : + pUpperMonthText( NULL ), + pUpperAbbrevMonthText( NULL ), + pUpperDayText( NULL ), + pUpperAbbrevDayText( NULL ) +{ + pFormatter = pFormatterP; + pNullDate = new Date(30,12,1899); + nYear2000 = SvNumberFormatter::GetYear2000Default(); + Reset(); + ChangeIntl(); +} + + +//--------------------------------------------------------------------------- +// Destruktor + +ImpSvNumberInputScan::~ImpSvNumberInputScan() +{ + Reset(); + delete pNullDate; + delete [] pUpperMonthText; + delete [] pUpperAbbrevMonthText; + delete [] pUpperDayText; + delete [] pUpperAbbrevDayText; +} + + +//--------------------------------------------------------------------------- +// Reset + +void ImpSvNumberInputScan::Reset() +{ +#if 0 +// ER 16.06.97 18:56 Vorbelegung erfolgt jetzt in NumberStringDivision, +// wozu immer alles loeschen wenn einiges wieder benutzt oder gar nicht +// gebraucht wird.. + for (USHORT i = 0; i < SV_MAX_ANZ_INPUT_STRINGS; i++) + { + sStrArray[i].Erase(); + nNums[i] = SV_MAX_ANZ_INPUT_STRINGS-1; + IsNum[i] = FALSE; + } +#endif + nMonth = 0; + nMonthPos = 0; + nTimePos = 0; + nSign = 0; + nESign = 0; + nDecPos = 0; + nNegCheck = 0; + nAnzStrings = 0; + nAnzNums = 0; + nThousand = 0; + eScannedType = NUMBERFORMAT_UNDEFINED; + nAmPm = 0; + nPosThousandString = 0; + nLogical = 0; + nStringScanNumFor = 0; + nStringScanSign = 0; + nMatchedAllStrings = nMatchedVirgin; + nMayBeIso8601 = 0; + nTimezonePos = 0; +} + + +//--------------------------------------------------------------------------- +// +// static +inline BOOL ImpSvNumberInputScan::MyIsdigit( sal_Unicode c ) +{ + // If the input string wouldn't be converted using TransformInput() we'd + // to use something similar to the following and to adapt many places. +#if 0 + // use faster isdigit() if possible + if ( c < 128 ) + return isdigit( (unsigned char) c ) != 0; + if ( c < 256 ) + return FALSE; + String aTmp( c ); + return pFormatter->GetCharClass()->isDigit( aTmp, 0 ); +#else + return c < 128 && isdigit( (unsigned char) c ); +#endif +} + + +//--------------------------------------------------------------------------- +// +void ImpSvNumberInputScan::TransformInput( String& rStr ) +{ + xub_StrLen nPos, nLen; + for ( nPos = 0, nLen = rStr.Len(); nPos < nLen; ++nPos ) + { + if ( 256 <= rStr.GetChar( nPos ) && + pFormatter->GetCharClass()->isDigit( rStr, nPos ) ) + break; + } + if ( nPos < nLen ) + rStr = pFormatter->GetNatNum()->getNativeNumberString( rStr, + pFormatter->GetLocale(), 0 ); +} + + +//--------------------------------------------------------------------------- +// StringToDouble +// +// Only simple unsigned floating point values without any error detection, +// decimal separator has to be '.' + +double ImpSvNumberInputScan::StringToDouble( const String& rStr, BOOL bForceFraction ) +{ + double fNum = 0.0; + double fFrac = 0.0; + int nExp = 0; + xub_StrLen nPos = 0; + xub_StrLen nLen = rStr.Len(); + BOOL bPreSep = !bForceFraction; + + while (nPos < nLen) + { + if (rStr.GetChar(nPos) == '.') + bPreSep = FALSE; + else if (bPreSep) + fNum = fNum * 10.0 + (double) (rStr.GetChar(nPos) - '0'); + else + { + fFrac = fFrac * 10.0 + (double) (rStr.GetChar(nPos) - '0'); + --nExp; + } + nPos++; + } + if ( fFrac ) + return fNum + ::rtl::math::pow10Exp( fFrac, nExp ); + return fNum; +} + + +//--------------------------------------------------------------------------- +// NextNumberStringSymbol +// +// Zerlegt die Eingabe in Zahlen und Strings fuer die weitere +// Verarbeitung (Turing-Maschine). +//--------------------------------------------------------------------------- +// Ausgangs Zustand = GetChar +//---------------+-------------------+-----------------------+--------------- +// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand +//---------------+-------------------+-----------------------+--------------- +// GetChar | Ziffer | Symbol=Zeichen | GetValue +// | Sonst | Symbol=Zeichen | GetString +//---------------|-------------------+-----------------------+--------------- +// GetValue | Ziffer | Symbol=Symbol+Zeichen | GetValue +// | Sonst | Dec(CharPos) | Stop +//---------------+-------------------+-----------------------+--------------- +// GetString | Ziffer | Dec(CharPos) | Stop +// | Sonst | Symbol=Symbol+Zeichen | GetString +//---------------+-------------------+-----------------------+--------------- + +enum ScanState // States der Turing-Maschine +{ + SsStop = 0, + SsStart = 1, + SsGetValue = 2, + SsGetString = 3 +}; + +BOOL ImpSvNumberInputScan::NextNumberStringSymbol( + const sal_Unicode*& pStr, + String& rSymbol ) +{ + BOOL isNumber = FALSE; + sal_Unicode cToken; + ScanState eState = SsStart; + register const sal_Unicode* pHere = pStr; + register xub_StrLen nChars = 0; + + while ( ((cToken = *pHere) != 0) && eState != SsStop) + { + pHere++; + switch (eState) + { + case SsStart: + if ( MyIsdigit( cToken ) ) + { + eState = SsGetValue; + isNumber = TRUE; + } + else + eState = SsGetString; + nChars++; + break; + case SsGetValue: + if ( MyIsdigit( cToken ) ) + nChars++; + else + { + eState = SsStop; + pHere--; + } + break; + case SsGetString: + if ( !MyIsdigit( cToken ) ) + nChars++; + else + { + eState = SsStop; + pHere--; + } + break; + default: + break; + } // switch + } // while + + if ( nChars ) + rSymbol.Assign( pStr, nChars ); + else + rSymbol.Erase(); + + pStr = pHere; + + return isNumber; +} + + +//--------------------------------------------------------------------------- +// SkipThousands + +// FIXME: should be grouping; it is only used though in case nAnzStrings is +// near SV_MAX_ANZ_INPUT_STRINGS, in NumberStringDivision(). + +BOOL ImpSvNumberInputScan::SkipThousands( + const sal_Unicode*& pStr, + String& rSymbol ) +{ + BOOL res = FALSE; + sal_Unicode cToken; + const String& rThSep = pFormatter->GetNumThousandSep(); + register const sal_Unicode* pHere = pStr; + ScanState eState = SsStart; + xub_StrLen nCounter = 0; // counts 3 digits + + while ( ((cToken = *pHere) != 0) && eState != SsStop) + { + pHere++; + switch (eState) + { + case SsStart: + if ( StringPtrContains( rThSep, pHere-1, 0 ) ) + { + nCounter = 0; + eState = SsGetValue; + pHere += rThSep.Len()-1; + } + else + { + eState = SsStop; + pHere--; + } + break; + case SsGetValue: + if ( MyIsdigit( cToken ) ) + { + rSymbol += cToken; + nCounter++; + if (nCounter == 3) + { + eState = SsStart; + res = TRUE; // .000 combination found + } + } + else + { + eState = SsStop; + pHere--; + } + break; + default: + break; + } // switch + } // while + + if (eState == SsGetValue) // break witth less than 3 digits + { + if ( nCounter ) + rSymbol.Erase( rSymbol.Len() - nCounter, nCounter ); + pHere -= nCounter + rThSep.Len(); // put back ThSep also + } + pStr = pHere; + + return res; +} + + +//--------------------------------------------------------------------------- +// NumberStringDivision + +void ImpSvNumberInputScan::NumberStringDivision( const String& rString ) +{ + const sal_Unicode* pStr = rString.GetBuffer(); + const sal_Unicode* const pEnd = pStr + rString.Len(); + while ( pStr < pEnd && nAnzStrings < SV_MAX_ANZ_INPUT_STRINGS ) + { + if ( NextNumberStringSymbol( pStr, sStrArray[nAnzStrings] ) ) + { // Zahl + IsNum[nAnzStrings] = TRUE; + nNums[nAnzNums] = nAnzStrings; + nAnzNums++; + if (nAnzStrings >= SV_MAX_ANZ_INPUT_STRINGS - 7 && + nPosThousandString == 0) // nur einmal + if ( SkipThousands( pStr, sStrArray[nAnzStrings] ) ) + nPosThousandString = nAnzStrings; + } + else + { + IsNum[nAnzStrings] = FALSE; + } + nAnzStrings++; + } +} + + +//--------------------------------------------------------------------------- +// Whether rString contains rWhat at nPos + +BOOL ImpSvNumberInputScan::StringContainsImpl( const String& rWhat, + const String& rString, xub_StrLen nPos ) +{ + if ( nPos + rWhat.Len() <= rString.Len() ) + return StringPtrContainsImpl( rWhat, rString.GetBuffer(), nPos ); + return FALSE; +} + + +//--------------------------------------------------------------------------- +// Whether pString contains rWhat at nPos + +BOOL ImpSvNumberInputScan::StringPtrContainsImpl( const String& rWhat, + const sal_Unicode* pString, xub_StrLen nPos ) +{ + if ( rWhat.Len() == 0 ) + return FALSE; + register const sal_Unicode* pWhat = rWhat.GetBuffer(); + register const sal_Unicode* const pEnd = pWhat + rWhat.Len(); + register const sal_Unicode* pStr = pString + nPos; + while ( pWhat < pEnd ) + { + if ( *pWhat != *pStr ) + return FALSE; + pWhat++; + pStr++; + } + return TRUE; +} + + +//--------------------------------------------------------------------------- +// SkipChar +// +// ueberspringt genau das angegebene Zeichen + +inline BOOL ImpSvNumberInputScan::SkipChar( sal_Unicode c, const String& rString, + xub_StrLen& nPos ) +{ + if ((nPos < rString.Len()) && (rString.GetChar(nPos) == c)) + { + nPos++; + return TRUE; + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// SkipBlanks +// +// Ueberspringt Leerzeichen + +inline void ImpSvNumberInputScan::SkipBlanks( const String& rString, + xub_StrLen& nPos ) +{ + if ( nPos < rString.Len() ) + { + register const sal_Unicode* p = rString.GetBuffer() + nPos; + while ( *p == ' ' ) + { + nPos++; + p++; + } + } +} + + +//--------------------------------------------------------------------------- +// SkipString +// +// jump over rWhat in rString at nPos + +inline BOOL ImpSvNumberInputScan::SkipString( const String& rWhat, + const String& rString, xub_StrLen& nPos ) +{ + if ( StringContains( rWhat, rString, nPos ) ) + { + nPos = nPos + rWhat.Len(); + return TRUE; + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetThousandSep +// +// recognizes exactly ,111 in {3} and {3,2} or ,11 in {3,2} grouping + +inline BOOL ImpSvNumberInputScan::GetThousandSep( + const String& rString, + xub_StrLen& nPos, + USHORT nStringPos ) +{ + const String& rSep = pFormatter->GetNumThousandSep(); + // Is it an ordinary space instead of a non-breaking space? + bool bSpaceBreak = rSep.GetChar(0) == 0xa0 && rString.GetChar(0) == 0x20 && + rSep.Len() == 1 && rString.Len() == 1; + if (!( (rString == rSep || bSpaceBreak) // nothing else + && nStringPos < nAnzStrings - 1 // safety first! + && IsNum[nStringPos+1] )) // number follows + return FALSE; // no? => out + + utl::DigitGroupingIterator aGrouping( + pFormatter->GetLocaleData()->getDigitGrouping()); + // Match ,### in {3} or ,## in {3,2} + /* FIXME: this could be refined to match ,## in {3,2} only if ,##,## or + * ,##,### and to match ,### in {3,2} only if it's the last. However, + * currently there is no track kept where group separators occur. In {3,2} + * #,###,### and #,##,## would be valid input, which maybe isn't even bad + * for #,###,###. Other combinations such as #,###,## maybe not. */ + xub_StrLen nLen = sStrArray[nStringPos+1].Len(); + if (nLen == aGrouping.get() // with 3 (or so) digits + || nLen == aGrouping.advance().get() // or with 2 (or 3 or so) digits + || nPosThousandString == nStringPos+1 // or concatenated + ) + { + nPos = nPos + rSep.Len(); + return TRUE; + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetLogical +// +// Conversion of text to logial value +// "TRUE" => 1: +// "FALSE"=> -1: +// else => 0: + +short ImpSvNumberInputScan::GetLogical( const String& rString ) +{ + short res; + + const ImpSvNumberformatScan* pFS = pFormatter->GetFormatScanner(); + if ( rString == pFS->GetTrueString() ) + res = 1; + else if ( rString == pFS->GetFalseString() ) + res = -1; + else + res = 0; + + return res; +} + + +//--------------------------------------------------------------------------- +// GetMonth +// +// Converts a string containing a month name (JAN, January) at nPos into the +// month number (negative if abbreviated), returns 0 if nothing found + +short ImpSvNumberInputScan::GetMonth( const String& rString, xub_StrLen& nPos ) +{ + // #102136# The correct English form of month September abbreviated is + // SEPT, but almost every data contains SEP instead. + static const String aSeptCorrect( RTL_CONSTASCII_USTRINGPARAM( "SEPT" ) ); + static const String aSepShortened( RTL_CONSTASCII_USTRINGPARAM( "SEP" ) ); + + short res = 0; // no month found + + if (rString.Len() > nPos) // only if needed + { + if ( !bTextInitialized ) + InitText(); + sal_Int16 nMonths = pFormatter->GetCalendar()->getNumberOfMonthsInYear(); + for ( sal_Int16 i = 0; i < nMonths; i++ ) + { + if ( StringContains( pUpperMonthText[i], rString, nPos ) ) + { // full names first + nPos = nPos + pUpperMonthText[i].Len(); + res = i+1; + break; // for + } + else if ( StringContains( pUpperAbbrevMonthText[i], rString, nPos ) ) + { // abbreviated + nPos = nPos + pUpperAbbrevMonthText[i].Len(); + res = sal::static_int_cast< short >(-(i+1)); // negative + break; // for + } + else if ( i == 8 && pUpperAbbrevMonthText[i] == aSeptCorrect && + StringContains( aSepShortened, rString, nPos ) ) + { // #102136# SEPT/SEP + nPos = nPos + aSepShortened.Len(); + res = sal::static_int_cast< short >(-(i+1)); // negative + break; // for + } + } + } + + return res; +} + + +//--------------------------------------------------------------------------- +// GetDayOfWeek +// +// Converts a string containing a DayOfWeek name (Mon, Monday) at nPos into the +// DayOfWeek number + 1 (negative if abbreviated), returns 0 if nothing found + +int ImpSvNumberInputScan::GetDayOfWeek( const String& rString, xub_StrLen& nPos ) +{ + int res = 0; // no day found + + if (rString.Len() > nPos) // only if needed + { + if ( !bTextInitialized ) + InitText(); + sal_Int16 nDays = pFormatter->GetCalendar()->getNumberOfDaysInWeek(); + for ( sal_Int16 i = 0; i < nDays; i++ ) + { + if ( StringContains( pUpperDayText[i], rString, nPos ) ) + { // full names first + nPos = nPos + pUpperDayText[i].Len(); + res = i + 1; + break; // for + } + if ( StringContains( pUpperAbbrevDayText[i], rString, nPos ) ) + { // abbreviated + nPos = nPos + pUpperAbbrevDayText[i].Len(); + res = -(i + 1); // negative + break; // for + } + } + } + + return res; +} + + +//--------------------------------------------------------------------------- +// GetCurrency +// +// Lesen eines Waehrungssysmbols +// '$' => TRUE +// sonst => FALSE + +BOOL ImpSvNumberInputScan::GetCurrency( const String& rString, xub_StrLen& nPos, + const SvNumberformat* pFormat ) +{ + if ( rString.Len() > nPos ) + { + if ( !aUpperCurrSymbol.Len() ) + { // if no format specified the currency of the initialized formatter + LanguageType eLang = (pFormat ? pFormat->GetLanguage() : + pFormatter->GetLanguage()); + aUpperCurrSymbol = pFormatter->GetCharClass()->upper( + SvNumberFormatter::GetCurrencyEntry( eLang ).GetSymbol() ); + } + if ( StringContains( aUpperCurrSymbol, rString, nPos ) ) + { + nPos = nPos + aUpperCurrSymbol.Len(); + return TRUE; + } + if ( pFormat ) + { + String aSymbol, aExtension; + if ( pFormat->GetNewCurrencySymbol( aSymbol, aExtension ) ) + { + if ( aSymbol.Len() <= rString.Len() - nPos ) + { + pFormatter->GetCharClass()->toUpper( aSymbol ); + if ( StringContains( aSymbol, rString, nPos ) ) + { + nPos = nPos + aSymbol.Len(); + return TRUE; + } + } + } + } + } + + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetTimeAmPm +// +// Lesen des Zeitsymbols (AM od. PM) f. kurze Zeitangabe +// +// Rueckgabe: +// "AM" od. "PM" => TRUE +// sonst => FALSE +// +// nAmPos: +// "AM" => 1 +// "PM" => -1 +// sonst => 0 + +BOOL ImpSvNumberInputScan::GetTimeAmPm( const String& rString, xub_StrLen& nPos ) +{ + + if ( rString.Len() > nPos ) + { + const CharClass* pChr = pFormatter->GetCharClass(); + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + if ( StringContains( pChr->upper( pLoc->getTimeAM() ), rString, nPos ) ) + { + nAmPm = 1; + nPos = nPos + pLoc->getTimeAM().Len(); + return TRUE; + } + else if ( StringContains( pChr->upper( pLoc->getTimePM() ), rString, nPos ) ) + { + nAmPm = -1; + nPos = nPos + pLoc->getTimePM().Len(); + return TRUE; + } + } + + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetDecSep +// +// Lesen eines Dezimaltrenners (',') +// ',' => TRUE +// sonst => FALSE + +inline BOOL ImpSvNumberInputScan::GetDecSep( const String& rString, xub_StrLen& nPos ) +{ + if ( rString.Len() > nPos ) + { + const String& rSep = pFormatter->GetNumDecimalSep(); + if ( rString.Equals( rSep, nPos, rSep.Len() ) ) + { + nPos = nPos + rSep.Len(); + return TRUE; + } + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// read a hundredth seconds separator + +inline BOOL ImpSvNumberInputScan::GetTime100SecSep( const String& rString, xub_StrLen& nPos ) +{ + if ( rString.Len() > nPos ) + { + const String& rSep = pFormatter->GetLocaleData()->getTime100SecSep(); + if ( rString.Equals( rSep, nPos, rSep.Len() ) ) + { + nPos = nPos + rSep.Len(); + return TRUE; + } + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetSign +// +// Lesen eines Vorzeichens, auch Klammer !?! +// '+' => 1 +// '-' => -1 +// '(' => -1, nNegCheck = 1 +// sonst => 0 + +int ImpSvNumberInputScan::GetSign( const String& rString, xub_StrLen& nPos ) +{ + if (rString.Len() > nPos) + switch (rString.GetChar(nPos)) + { + case '+': + nPos++; + return 1; + case '(': // '(' aehnlich wie '-' ?!? + nNegCheck = 1; + //! fallthru + case '-': + nPos++; + return -1; + default: + break; + } + + return 0; +} + + +//--------------------------------------------------------------------------- +// GetESign +// +// Lesen eines Vorzeichens, gedacht fuer Exponent ?!? +// '+' => 1 +// '-' => -1 +// sonst => 0 + +short ImpSvNumberInputScan::GetESign( const String& rString, xub_StrLen& nPos ) +{ + if (rString.Len() > nPos) + switch (rString.GetChar(nPos)) + { + case '+': + nPos++; + return 1; + case '-': + nPos++; + return -1; + default: + break; + } + + return 0; +} + + +//--------------------------------------------------------------------------- +// GetNextNumber +// +// i counts string portions, j counts numbers thereof. +// It should had been called SkipNumber instead. + +inline BOOL ImpSvNumberInputScan::GetNextNumber( USHORT& i, USHORT& j ) +{ + if ( i < nAnzStrings && IsNum[i] ) + { + j++; + i++; + return TRUE; + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// GetTimeRef + +void ImpSvNumberInputScan::GetTimeRef( + double& fOutNumber, + USHORT nIndex, // j-value of the first numeric time part of input, default 0 + USHORT nAnz ) // count of numeric time parts +{ + USHORT nHour; + USHORT nMinute = 0; + USHORT nSecond = 0; + double fSecond100 = 0.0; + USHORT nStartIndex = nIndex; + + if (nTimezonePos) + { + // find first timezone number index and adjust count + for (USHORT j=0; j<nAnzNums; ++j) + { + if (nNums[j] == nTimezonePos) + { + // nAnz is not total count, but count of time relevant strings. + if (nStartIndex < j && j - nStartIndex < nAnz) + nAnz = j - nStartIndex; + break; // for + } + } + } + + if (nDecPos == 2 && (nAnz == 3 || nAnz == 2)) // 20:45.5 or 45.5 + nHour = 0; + else if (nIndex - nStartIndex < nAnz) + nHour = (USHORT) sStrArray[nNums[nIndex++]].ToInt32(); + else + { + nHour = 0; + DBG_ERRORFILE( "ImpSvNumberInputScan::GetTimeRef: bad number index"); + } + if (nDecPos == 2 && nAnz == 2) // 45.5 + nMinute = 0; + else if (nIndex - nStartIndex < nAnz) + nMinute = (USHORT) sStrArray[nNums[nIndex++]].ToInt32(); + if (nIndex - nStartIndex < nAnz) + nSecond = (USHORT) sStrArray[nNums[nIndex++]].ToInt32(); + if (nIndex - nStartIndex < nAnz) + fSecond100 = StringToDouble( sStrArray[nNums[nIndex]], TRUE ); + if (nAmPm == -1 && nHour != 12) // PM + nHour += 12; + else if (nAmPm == 1 && nHour == 12) // 12 AM + nHour = 0; + + fOutNumber = ((double)nHour*3600 + + (double)nMinute*60 + + (double)nSecond + + fSecond100)/86400.0; +} + + +//--------------------------------------------------------------------------- +// ImplGetDay + +USHORT ImpSvNumberInputScan::ImplGetDay( USHORT nIndex ) +{ + USHORT nRes = 0; + + if (sStrArray[nNums[nIndex]].Len() <= 2) + { + USHORT nNum = (USHORT) sStrArray[nNums[nIndex]].ToInt32(); + if (nNum <= 31) + nRes = nNum; + } + + return nRes; +} + + +//--------------------------------------------------------------------------- +// ImplGetMonth + +USHORT ImpSvNumberInputScan::ImplGetMonth( USHORT nIndex ) +{ + // preset invalid month number + USHORT nRes = pFormatter->GetCalendar()->getNumberOfMonthsInYear(); + + if (sStrArray[nNums[nIndex]].Len() <= 2) + { + USHORT nNum = (USHORT) sStrArray[nNums[nIndex]].ToInt32(); + if ( 0 < nNum && nNum <= nRes ) + nRes = nNum - 1; // zero based for CalendarFieldIndex::MONTH + } + + return nRes; +} + + +//--------------------------------------------------------------------------- +// ImplGetYear +// +// 30 -> 1930, 29 -> 2029, oder 56 -> 1756, 55 -> 1855, ... + +USHORT ImpSvNumberInputScan::ImplGetYear( USHORT nIndex ) +{ + USHORT nYear = 0; + + if (sStrArray[nNums[nIndex]].Len() <= 4) + { + nYear = (USHORT) sStrArray[nNums[nIndex]].ToInt32(); + nYear = SvNumberFormatter::ExpandTwoDigitYear( nYear, nYear2000 ); + } + + return nYear; +} + +//--------------------------------------------------------------------------- + +bool ImpSvNumberInputScan::MayBeIso8601() +{ + if (nMayBeIso8601 == 0) + { + if (nAnzNums >= 3 && nNums[0] < nAnzStrings && + sStrArray[nNums[0]].ToInt32() > 31) + nMayBeIso8601 = 1; + else + nMayBeIso8601 = 2; + } + return nMayBeIso8601 == 1; +} + +//--------------------------------------------------------------------------- +// GetDateRef + +BOOL ImpSvNumberInputScan::GetDateRef( double& fDays, USHORT& nCounter, + const SvNumberformat* pFormat ) +{ + using namespace ::com::sun::star::i18n; + NfEvalDateFormat eEDF; + int nFormatOrder; + if ( pFormat && ((pFormat->GetType() & NUMBERFORMAT_DATE) == NUMBERFORMAT_DATE) ) + { + eEDF = pFormatter->GetEvalDateFormat(); + switch ( eEDF ) + { + case NF_EVALDATEFORMAT_INTL : + case NF_EVALDATEFORMAT_FORMAT : + nFormatOrder = 1; // only one loop + break; + default: + nFormatOrder = 2; + if ( nMatchedAllStrings ) + eEDF = NF_EVALDATEFORMAT_FORMAT_INTL; + // we have a complete match, use it + } + } + else + { + eEDF = NF_EVALDATEFORMAT_INTL; + nFormatOrder = 1; + } + BOOL res = TRUE; + + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + CalendarWrapper* pCal = pFormatter->GetCalendar(); + for ( int nTryOrder = 1; nTryOrder <= nFormatOrder; nTryOrder++ ) + { + pCal->setGregorianDateTime( Date() ); // today + String aOrgCalendar; // empty => not changed yet + DateFormat DateFmt; + BOOL bFormatTurn; + switch ( eEDF ) + { + case NF_EVALDATEFORMAT_INTL : + bFormatTurn = FALSE; + DateFmt = pLoc->getDateFormat(); + break; + case NF_EVALDATEFORMAT_FORMAT : + bFormatTurn = TRUE; + DateFmt = pFormat->GetDateOrder(); + break; + case NF_EVALDATEFORMAT_INTL_FORMAT : + if ( nTryOrder == 1 ) + { + bFormatTurn = FALSE; + DateFmt = pLoc->getDateFormat(); + } + else + { + bFormatTurn = TRUE; + DateFmt = pFormat->GetDateOrder(); + } + break; + case NF_EVALDATEFORMAT_FORMAT_INTL : + if ( nTryOrder == 2 ) + { + bFormatTurn = FALSE; + DateFmt = pLoc->getDateFormat(); + } + else + { + bFormatTurn = TRUE; + DateFmt = pFormat->GetDateOrder(); + } + break; + default: + DBG_ERROR( "ImpSvNumberInputScan::GetDateRef: unknown NfEvalDateFormat" ); + DateFmt = YMD; + bFormatTurn = FALSE; + } + if ( bFormatTurn ) + { +#if 0 +/* TODO: +We are currently not able to fully support a switch to another calendar during +input for the following reasons: +1. We do have a problem if both (locale's default and format's) calendars + define the same YMD order and use the same date separator, there is no way + to distinguish between them if the input results in valid calendar input for + both calendars. How to solve? Would NfEvalDateFormat be sufficient? Should + it always be set to NF_EVALDATEFORMAT_FORMAT_INTL and thus the format's + calendar be preferred? This could be confusing if a Calc cell was formatted + different to the locale's default and has no content yet, then the user has + no clue about the format or calendar being set. +2. In Calc cell edit mode a date is always displayed and edited using the + default edit format of the default calendar (normally being Gregorian). If + input was ambiguous due to issue #1 we'd need a mechanism to tell that a + date was edited and not newly entered. Not feasible. Otherwise we'd need a + mechanism to use a specific edit format with a specific calendar according + to the format set. +3. For some calendars like Japanese Gengou we'd need era input, which isn't + implemented at all. Though this is a rare and special case, forcing a + calendar dependent edit format as suggested in item #2 might require era + input, if it shouldn't result in a fallback to Gregorian calendar. +4. Last and least: the GetMonth() method currently only matches month names of + the default calendar. Alternating month names of the actual format's + calendar would have to be implemented. No problem. + +*/ + if ( pFormat->IsOtherCalendar( nStringScanNumFor ) ) + pFormat->SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + else + pFormat->SwitchToSpecifiedCalendar( aOrgCalendar, fOrgDateTime, + nStringScanNumFor ); +#endif + } + + res = TRUE; + nCounter = 0; + // For incomplete dates, always assume first day of month if not specified. + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 ); + + switch (nAnzNums) // count of numbers in string + { + case 0: // none + if (nMonthPos) // only month (Jan) + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + else + res = FALSE; + break; + + case 1: // only one number + nCounter = 1; + switch (nMonthPos) // where is the month + { + case 0: // not found => only day entered + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + break; + case 1: // month at the beginning (Jan 01) + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + switch (DateFmt) + { + case MDY: + case YMD: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + break; + case DMY: + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + default: + res = FALSE; + break; + } + break; + case 3: // month at the end (10 Jan) + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + switch (DateFmt) + { + case DMY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + break; + case YMD: + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + default: + res = FALSE; + break; + } + break; + default: + res = FALSE; + break; + } // switch (nMonthPos) + break; + + case 2: // 2 numbers + nCounter = 2; + switch (nMonthPos) // where is the month + { + case 0: // not found + { + bool bHadExact; + sal_uInt32 nExactDateOrder = (bFormatTurn ? pFormat->GetExactDateOrder() : 0); + if ( 0xff < nExactDateOrder && nExactDateOrder <= 0xffff ) + { // formatted as date and exactly 2 parts + bHadExact = true; + switch ( (nExactDateOrder >> 8) & 0xff ) + { + case 'Y': + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + case 'M': + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + break; + case 'D': + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + break; + default: + bHadExact = false; + } + switch ( nExactDateOrder & 0xff ) + { + case 'Y': + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + break; + case 'M': + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(1) ); + break; + case 'D': + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + break; + default: + bHadExact = false; + } + } + else + bHadExact = false; + if ( !bHadExact || !pCal->isValid() ) + { + if ( !bHadExact && nExactDateOrder ) + pCal->setGregorianDateTime( Date() ); // reset today + switch (DateFmt) + { + case MDY: + // M D + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + if ( !pCal->isValid() ) // 2nd try + { // M Y + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + } + break; + case DMY: + // D M + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(1) ); + if ( !pCal->isValid() ) // 2nd try + { // M Y + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + } + break; + case YMD: + // M D + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + if ( !pCal->isValid() ) // 2nd try + { // Y M + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, 1 ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(1) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + } + break; + default: + res = FALSE; + break; + } + } + } + break; + case 1: // month at the beginning (Jan 01 01) + { + // The input is valid as MDY in almost any + // constellation, there is no date order (M)YD except if + // set in a format applied. + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + sal_uInt32 nExactDateOrder = (bFormatTurn ? pFormat->GetExactDateOrder() : 0); + if ((((nExactDateOrder >> 8) & 0xff) == 'Y') && ((nExactDateOrder & 0xff) == 'D')) + { + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + } + else + { + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + } + } + break; + case 2: // month in the middle (10 Jan 94) + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + switch (DateFmt) + { + case MDY: // yes, "10-Jan-94" is valid + case DMY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + break; + case YMD: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + default: + res = FALSE; + break; + } + break; + default: // else, e.g. month at the end (94 10 Jan) + res = FALSE; + break; + } // switch (nMonthPos) + break; + + default: // more than two numbers (31.12.94 8:23) (31.12. 8:23) + switch (nMonthPos) // where is the month + { + case 0: // not found + { + nCounter = 3; + if ( nTimePos > 1 ) + { // find first time number index (should only be 3 or 2 anyway) + for ( USHORT j = 0; j < nAnzNums; j++ ) + { + if ( nNums[j] == nTimePos - 2 ) + { + nCounter = j; + break; // for + } + } + } + // ISO 8601 yyyy-mm-dd forced recognition + DateFormat eDF = (MayBeIso8601() ? YMD : DateFmt); + switch (eDF) + { + case MDY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + if ( nCounter > 2 ) + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(2) ); + break; + case DMY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(1) ); + if ( nCounter > 2 ) + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(2) ); + break; + case YMD: + if ( nCounter > 2 ) + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(2) ); + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(1) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + default: + res = FALSE; + break; + } + } + break; + case 1: // month at the beginning (Jan 01 01 8:23) + nCounter = 2; + switch (DateFmt) + { + case MDY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + break; + default: + res = FALSE; + break; + } + break; + case 2: // month in the middle (10 Jan 94 8:23) + nCounter = 2; + pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); + switch (DateFmt) + { + case DMY: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(1) ); + break; + case YMD: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(1) ); + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + default: + res = FALSE; + break; + } + break; + default: // else, e.g. month at the end (94 10 Jan 8:23) + nCounter = 2; + res = FALSE; + break; + } // switch (nMonthPos) + break; + } // switch (nAnzNums) + + if ( res && pCal->isValid() ) + { + double fDiff = DateTime(*pNullDate) - pCal->getEpochStart(); + fDays = ::rtl::math::approxFloor( pCal->getLocalDateTime() ); + fDays -= fDiff; + nTryOrder = nFormatOrder; // break for + } + else + res = FALSE; + + if ( aOrgCalendar.Len() ) + pCal->loadCalendar( aOrgCalendar, pLoc->getLocale() ); // restore calendar + +#if NF_TEST_CALENDAR +{ + using namespace ::com::sun::star; + struct entry { const char* lan; const char* cou; const char* cal; }; + const entry cals[] = { + { "en", "US", "gregorian" }, + { "ar", "TN", "hijri" }, + { "he", "IL", "jewish" }, + { "ja", "JP", "gengou" }, + { "ko", "KR", "hanja_yoil" }, + { "th", "TH", "buddhist" }, + { "zh", "TW", "ROC" }, + {0,0,0} + }; + lang::Locale aLocale; + sal_Bool bValid; + sal_Int16 nDay, nMyMonth, nYear, nHour, nMinute, nSecond; + sal_Int16 nDaySet, nMonthSet, nYearSet, nHourSet, nMinuteSet, nSecondSet; + sal_Int16 nZO, nDST1, nDST2, nDST, nZOmillis, nDST1millis, nDST2millis, nDSTmillis; + sal_Int32 nZoneInMillis, nDST1InMillis, nDST2InMillis; + uno::Reference< lang::XMultiServiceFactory > xSMgr = + ::comphelper::getProcessServiceFactory(); + uno::Reference< ::com::sun::star::i18n::XExtendedCalendar > xCal( + xSMgr->createInstance( ::rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.i18n.LocaleCalendar" ) ) ), + uno::UNO_QUERY ); + for ( const entry* p = cals; p->lan; ++p ) + { + aLocale.Language = ::rtl::OUString::createFromAscii( p->lan ); + aLocale.Country = ::rtl::OUString::createFromAscii( p->cou ); + xCal->loadCalendar( ::rtl::OUString::createFromAscii( p->cal ), + aLocale ); + double nDateTime = 0.0; // 1-Jan-1970 00:00:00 + nZO = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET ); + nZOmillis = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS ); + nZoneInMillis = static_cast<sal_Int32>(nZO) * 60000 + + (nZO < 0 ? -1 : 1) * static_cast<sal_uInt16>(nZOmillis); + nDST1 = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET ); + nDST1millis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS ); + nDST1InMillis = static_cast<sal_Int32>(nDST1) * 60000 + + (nDST1 < 0 ? -1 : 1) * static_cast<sal_uInt16>(nDST1millis); + nDateTime -= (double)(nZoneInMillis + nDST1InMillis) / 1000.0 / 60.0 / 60.0 / 24.0; + xCal->setDateTime( nDateTime ); + nDST2 = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET ); + nDST2millis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS ); + nDST2InMillis = static_cast<sal_Int32>(nDST2) * 60000 + + (nDST2 < 0 ? -1 : 1) * static_cast<sal_uInt16>(nDST2millis); + if ( nDST1InMillis != nDST2InMillis ) + { + nDateTime = 0.0 - (double)(nZoneInMillis + nDST2InMillis) / 1000.0 / 60.0 / 60.0 / 24.0; + xCal->setDateTime( nDateTime ); + } + nDaySet = xCal->getValue( i18n::CalendarFieldIndex::DAY_OF_MONTH ); + nMonthSet = xCal->getValue( i18n::CalendarFieldIndex::MONTH ); + nYearSet = xCal->getValue( i18n::CalendarFieldIndex::YEAR ); + nHourSet = xCal->getValue( i18n::CalendarFieldIndex::HOUR ); + nMinuteSet = xCal->getValue( i18n::CalendarFieldIndex::MINUTE ); + nSecondSet = xCal->getValue( i18n::CalendarFieldIndex::SECOND ); + nZO = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET ); + nZOmillis = xCal->getValue( i18n::CalendarFieldIndex::ZONE_OFFSET_SECOND_MILLIS ); + nDST = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET ); + nDSTmillis = xCal->getValue( i18n::CalendarFieldIndex::DST_OFFSET_SECOND_MILLIS ); + xCal->setValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, nDaySet ); + xCal->setValue( i18n::CalendarFieldIndex::MONTH, nMonthSet ); + xCal->setValue( i18n::CalendarFieldIndex::YEAR, nYearSet ); + xCal->setValue( i18n::CalendarFieldIndex::HOUR, nHourSet ); + xCal->setValue( i18n::CalendarFieldIndex::MINUTE, nMinuteSet ); + xCal->setValue( i18n::CalendarFieldIndex::SECOND, nSecondSet ); + bValid = xCal->isValid(); + nDay = xCal->getValue( i18n::CalendarFieldIndex::DAY_OF_MONTH ); + nMyMonth= xCal->getValue( i18n::CalendarFieldIndex::MONTH ); + nYear = xCal->getValue( i18n::CalendarFieldIndex::YEAR ); + nHour = xCal->getValue( i18n::CalendarFieldIndex::HOUR ); + nMinute = xCal->getValue( i18n::CalendarFieldIndex::MINUTE ); + nSecond = xCal->getValue( i18n::CalendarFieldIndex::SECOND ); + bValid = bValid && nDay == nDaySet && nMyMonth == nMonthSet && nYear == + nYearSet && nHour == nHourSet && nMinute == nMinuteSet && nSecond + == nSecondSet; + } +} +#endif // NF_TEST_CALENDAR + + } + + return res; +} + + +//--------------------------------------------------------------------------- +// ScanStartString +// +// ersten String analysieren +// Alles weg => TRUE +// sonst => FALSE + +BOOL ImpSvNumberInputScan::ScanStartString( const String& rString, + const SvNumberformat* pFormat ) +{ + xub_StrLen nPos = 0; + int nDayOfWeek; + + // First of all, eat leading blanks + SkipBlanks(rString, nPos); + + // Yes, nMatchedAllStrings should know about the sign position + nSign = GetSign(rString, nPos); + if ( nSign ) // sign? + SkipBlanks(rString, nPos); + + // #102371# match against format string only if start string is not a sign character + if ( nMatchedAllStrings && !(nSign && rString.Len() == 1) ) + { // Match against format in any case, so later on for a "x1-2-3" input + // we may distinguish between a xy-m-d (or similar) date and a x0-0-0 + // format. No sign detection here! + if ( ScanStringNumFor( rString, nPos, pFormat, 0, TRUE ) ) + nMatchedAllStrings |= nMatchedStartString; + else + nMatchedAllStrings = 0; + } + + if ( GetDecSep(rString, nPos) ) // decimal separator in start string + { + nDecPos = 1; + SkipBlanks(rString, nPos); + } + else if ( GetCurrency(rString, nPos, pFormat) ) // currency (DM 1)? + { + eScannedType = NUMBERFORMAT_CURRENCY; // !!! it IS currency !!! + SkipBlanks(rString, nPos); + if (nSign == 0) // no sign yet + { + nSign = GetSign(rString, nPos); + if ( nSign ) // DM -1 + SkipBlanks(rString, nPos); + } + } + else + { + nMonth = GetMonth(rString, nPos); + if ( nMonth ) // month (Jan 1)? + { + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date !!! + nMonthPos = 1; // month at the beginning + if ( nMonth < 0 ) + SkipChar( '.', rString, nPos ); // abbreviated + SkipBlanks(rString, nPos); + } + else + { + nDayOfWeek = GetDayOfWeek( rString, nPos ); + if ( nDayOfWeek ) + { // day of week is just parsed away + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date !!! + if ( nPos < rString.Len() ) + { + if ( nDayOfWeek < 0 ) + { // abbreviated + if ( rString.GetChar( nPos ) == '.' ) + ++nPos; + } + else + { // full long name + SkipBlanks(rString, nPos); + SkipString( pFormatter->GetLocaleData()->getLongDateDayOfWeekSep(), rString, nPos ); + } + SkipBlanks(rString, nPos); + nMonth = GetMonth(rString, nPos); + if ( nMonth ) // month (Jan 1)? + { + nMonthPos = 1; // month a the beginning + if ( nMonth < 0 ) + SkipChar( '.', rString, nPos ); // abbreviated + SkipBlanks(rString, nPos); + } + } + } + } + } + + if (nPos < rString.Len()) // not everything consumed + { + // Does input StartString equal StartString of format? + // This time with sign detection! + if ( !ScanStringNumFor( rString, nPos, pFormat, 0 ) ) + return MatchedReturn(); + } + + return TRUE; +} + + +//--------------------------------------------------------------------------- +// ScanMidString +// +// String in der Mitte analysieren +// Alles weg => TRUE +// sonst => FALSE + +BOOL ImpSvNumberInputScan::ScanMidString( const String& rString, + USHORT nStringPos, const SvNumberformat* pFormat ) +{ + xub_StrLen nPos = 0; + short eOldScannedType = eScannedType; + + if ( nMatchedAllStrings ) + { // Match against format in any case, so later on for a "1-2-3-4" input + // we may distinguish between a y-m-d (or similar) date and a 0-0-0-0 + // format. + if ( ScanStringNumFor( rString, 0, pFormat, nStringPos ) ) + nMatchedAllStrings |= nMatchedMidString; + else + nMatchedAllStrings = 0; + } + + SkipBlanks(rString, nPos); + if (GetDecSep(rString, nPos)) // decimal separator? + { + if (nDecPos == 1 || nDecPos == 3) // .12.4 or 1.E2.1 + return MatchedReturn(); + else if (nDecPos == 2) // . dup: 12.4. + { + if (bDecSepInDateSeps) // . also date separator + { + if ( eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_DATE && + eScannedType != NUMBERFORMAT_DATETIME) // already another type + return MatchedReturn(); + if (eScannedType == NUMBERFORMAT_UNDEFINED) + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date + SkipBlanks(rString, nPos); + } + else + return MatchedReturn(); + } + else + { + nDecPos = 2; // . in mid string + SkipBlanks(rString, nPos); + } + } + else if ( ((eScannedType & NUMBERFORMAT_TIME) == NUMBERFORMAT_TIME) + && GetTime100SecSep( rString, nPos ) ) + { // hundredth seconds separator + if ( nDecPos ) + return MatchedReturn(); + nDecPos = 2; // . in mid string + SkipBlanks(rString, nPos); + } + + if (SkipChar('/', rString, nPos)) // fraction? + { + if ( eScannedType != NUMBERFORMAT_UNDEFINED // already another type + && eScannedType != NUMBERFORMAT_DATE) // except date + return MatchedReturn(); // => jan/31/1994 + else if ( eScannedType != NUMBERFORMAT_DATE // analyzed date until now + && ( eSetType == NUMBERFORMAT_FRACTION // and preset was fraction + || (nAnzNums == 3 // or 3 numbers + && nStringPos > 2) ) ) // and what ??? + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_FRACTION; // !!! it IS a fraction + } + else + nPos--; // put '/' back + } + + if (GetThousandSep(rString, nPos, nStringPos)) // 1,000 + { + if ( eScannedType != NUMBERFORMAT_UNDEFINED // already another type + && eScannedType != NUMBERFORMAT_CURRENCY) // except currency + return MatchedReturn(); + nThousand++; + } + + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + const String& rDate = pFormatter->GetDateSep(); + const String& rTime = pLoc->getTimeSep(); + sal_Unicode cTime = rTime.GetChar(0); + SkipBlanks(rString, nPos); + if ( SkipString(rDate, rString, nPos) // 10., 10-, 10/ + || ((cTime != '.') && SkipChar('.', rString, nPos)) // TRICKY: + || ((cTime != '/') && SkipChar('/', rString, nPos)) // short boolean + || ((cTime != '-') && SkipChar('-', rString, nPos)) ) // evaluation! + { + if ( eScannedType != NUMBERFORMAT_UNDEFINED // already another type + && eScannedType != NUMBERFORMAT_DATE) // except date + return MatchedReturn(); + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date + short nTmpMonth = GetMonth(rString, nPos); // 10. Jan 94 + if (nMonth && nTmpMonth) // month dup + return MatchedReturn(); + if (nTmpMonth) + { + nMonth = nTmpMonth; + nMonthPos = 2; // month in the middle + if ( nMonth < 0 && SkipChar( '.', rString, nPos ) ) + ; // short month may be abbreviated Jan. + else if ( SkipChar( '-', rString, nPos ) ) + ; // #79632# recognize 17-Jan-2001 to be a date + // #99065# short and long month name + else + SkipString( pLoc->getLongDateMonthSep(), rString, nPos ); + SkipBlanks(rString, nPos); + } + } + + short nTempMonth = GetMonth(rString, nPos); // month in the middle (10 Jan 94) + if (nTempMonth) + { + if (nMonth != 0) // month dup + return MatchedReturn(); + if ( eScannedType != NUMBERFORMAT_UNDEFINED // already another type + && eScannedType != NUMBERFORMAT_DATE) // except date + return MatchedReturn(); + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date + nMonth = nTempMonth; + nMonthPos = 2; // month in the middle + if ( nMonth < 0 ) + SkipChar( '.', rString, nPos ); // abbreviated + SkipString( pLoc->getLongDateMonthSep(), rString, nPos ); + SkipBlanks(rString, nPos); + } + + if ( SkipChar('E', rString, nPos) // 10E, 10e, 10,Ee + || SkipChar('e', rString, nPos) ) + { + if (eScannedType != NUMBERFORMAT_UNDEFINED) // already another type + return MatchedReturn(); + else + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_SCIENTIFIC; // !!! it IS scientific + if ( nThousand+2 == nAnzNums // special case 1.E2 + && nDecPos == 2 ) + nDecPos = 3; // 1,100.E2 1,100,100.E3 + } + nESign = GetESign(rString, nPos); // signed exponent? + SkipBlanks(rString, nPos); + } + + if ( SkipString(rTime, rString, nPos) ) // time separator? + { + if (nDecPos) // already . => maybe error + { + if (bDecSepInDateSeps) // . also date sep + { + if ( eScannedType != NUMBERFORMAT_DATE && // already another type than date + eScannedType != NUMBERFORMAT_DATETIME) // or date time + return MatchedReturn(); + if (eScannedType == NUMBERFORMAT_DATE) + nDecPos = 0; // reset for time transition + } + else + return MatchedReturn(); + } + if ( ( eScannedType == NUMBERFORMAT_DATE // already date type + || eScannedType == NUMBERFORMAT_DATETIME) // or date time + && nAnzNums > 3) // and more than 3 numbers? (31.Dez.94 8:23) + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_DATETIME; // !!! it IS date with time + } + else if ( eScannedType != NUMBERFORMAT_UNDEFINED // already another type + && eScannedType != NUMBERFORMAT_TIME) // except time + return MatchedReturn(); + else + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_TIME; // !!! it IS a time + } + if ( !nTimePos ) + nTimePos = nStringPos + 1; + } + + if (nPos < rString.Len()) + { + switch (eScannedType) + { + case NUMBERFORMAT_DATE: + if (nMonthPos == 1 && pLoc->getLongDateFormat() == MDY) + { + // #68232# recognize long date separators like ", " in "September 5, 1999" + if (SkipString( pLoc->getLongDateDaySep(), rString, nPos )) + SkipBlanks( rString, nPos ); + } + else if (nStringPos == 5 && nPos == 0 && rString.Len() == 1 && + rString.GetChar(0) == 'T' && MayBeIso8601()) + { + // ISO 8601 combined date and time, yyyy-mm-ddThh:mm + ++nPos; + } + break; +#if NF_RECOGNIZE_ISO8601_TIMEZONES + case NUMBERFORMAT_DATETIME: + if (nPos == 0 && rString.Len() == 1 && nStringPos >= 9 && + MayBeIso8601()) + { + // ISO 8601 timezone offset + switch (rString.GetChar(0)) + { + case '+': + case '-': + if (nStringPos == nAnzStrings-2 || + nStringPos == nAnzStrings-4) + { + ++nPos; // yyyy-mm-ddThh:mm[:ss]+xx[[:]yy] + // nTimezonePos needed for GetTimeRef() + if (!nTimezonePos) + nTimezonePos = nStringPos + 1; + } + break; + case ':': + if (nTimezonePos && nStringPos >= 11 && + nStringPos == nAnzStrings-2) + ++nPos; // yyyy-mm-ddThh:mm[:ss]+xx:yy + break; + } + } + break; +#endif + } + } + + if (nPos < rString.Len()) // not everything consumed? + { + if ( nMatchedAllStrings & ~nMatchedVirgin ) + eScannedType = eOldScannedType; + else + return FALSE; + } + + return TRUE; +} + + +//--------------------------------------------------------------------------- +// ScanEndString +// +// Schlussteil analysieren +// Alles weg => TRUE +// sonst => FALSE + +BOOL ImpSvNumberInputScan::ScanEndString( const String& rString, + const SvNumberformat* pFormat ) +{ + xub_StrLen nPos = 0; + + if ( nMatchedAllStrings ) + { // Match against format in any case, so later on for a "1-2-3-4" input + // we may distinguish between a y-m-d (or similar) date and a 0-0-0-0 + // format. + if ( ScanStringNumFor( rString, 0, pFormat, 0xFFFF ) ) + nMatchedAllStrings |= nMatchedEndString; + else + nMatchedAllStrings = 0; + } + + SkipBlanks(rString, nPos); + if (GetDecSep(rString, nPos)) // decimal separator? + { + if (nDecPos == 1 || nDecPos == 3) // .12.4 or 12.E4. + return MatchedReturn(); + else if (nDecPos == 2) // . dup: 12.4. + { + if (bDecSepInDateSeps) // . also date sep + { + if ( eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_DATE && + eScannedType != NUMBERFORMAT_DATETIME) // already another type + return MatchedReturn(); + if (eScannedType == NUMBERFORMAT_UNDEFINED) + eScannedType = NUMBERFORMAT_DATE; // !!! it IS a date + SkipBlanks(rString, nPos); + } + else + return MatchedReturn(); + } + else + { + nDecPos = 3; // . in end string + SkipBlanks(rString, nPos); + } + } + + if ( nSign == 0 // conflict - not signed + && eScannedType != NUMBERFORMAT_DATE) // and not date +//!? catch time too? + { // not signed yet + nSign = GetSign(rString, nPos); // 1- DM + if (nNegCheck) // '(' as sign + return MatchedReturn(); + } + + SkipBlanks(rString, nPos); + if (nNegCheck && SkipChar(')', rString, nPos)) // skip ')' if appropriate + { + nNegCheck = 0; + SkipBlanks(rString, nPos); + } + + if ( GetCurrency(rString, nPos, pFormat) ) // currency symbol? + { + if (eScannedType != NUMBERFORMAT_UNDEFINED) // currency dup + return MatchedReturn(); + else + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_CURRENCY; + } // behind currency a '-' is allowed + if (nSign == 0) // not signed yet + { + nSign = GetSign(rString, nPos); // DM - + SkipBlanks(rString, nPos); + if (nNegCheck) // 3 DM ( + return MatchedReturn(); + } + if ( nNegCheck && eScannedType == NUMBERFORMAT_CURRENCY + && SkipChar(')', rString, nPos) ) + { + nNegCheck = 0; // ')' skipped + SkipBlanks(rString, nPos); // only if currency + } + } + + if ( SkipChar('%', rString, nPos) ) // 1 % + { + if (eScannedType != NUMBERFORMAT_UNDEFINED) // already another type + return MatchedReturn(); + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_PERCENT; + } + + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + const String& rDate = pFormatter->GetDateSep(); + const String& rTime = pLoc->getTimeSep(); + if ( SkipString(rTime, rString, nPos) ) // 10: + { + if (nDecPos) // already , => error + return MatchedReturn(); + if (eScannedType == NUMBERFORMAT_DATE && nAnzNums > 2) // 31.Dez.94 8: + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_DATETIME; + } + else if (eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_TIME) // already another type + return MatchedReturn(); + else + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_TIME; + } + if ( !nTimePos ) + nTimePos = nAnzStrings; + } + + sal_Unicode cTime = rTime.GetChar(0); + if ( SkipString(rDate, rString, nPos) // 10., 10-, 10/ + || ((cTime != '.') && SkipChar('.', rString, nPos)) // TRICKY: + || ((cTime != '/') && SkipChar('/', rString, nPos)) // short boolean + || ((cTime != '-') && SkipChar('-', rString, nPos)) ) // evaluation! + { + if (eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_DATE) // already another type + return MatchedReturn(); + else + { + SkipBlanks(rString, nPos); + eScannedType = NUMBERFORMAT_DATE; + } + short nTmpMonth = GetMonth(rString, nPos); // 10. Jan + if (nMonth && nTmpMonth) // month dup + return MatchedReturn(); + if (nTmpMonth) + { + nMonth = nTmpMonth; + nMonthPos = 3; // month at end + if ( nMonth < 0 ) + SkipChar( '.', rString, nPos ); // abbreviated + SkipBlanks(rString, nPos); + } + } + + short nTempMonth = GetMonth(rString, nPos); // 10 Jan + if (nTempMonth) + { + if (nMonth) // month dup + return MatchedReturn(); + if (eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_DATE) // already another type + return MatchedReturn(); + eScannedType = NUMBERFORMAT_DATE; + nMonth = nTempMonth; + nMonthPos = 3; // month at end + if ( nMonth < 0 ) + SkipChar( '.', rString, nPos ); // abbreviated + SkipBlanks(rString, nPos); + } + + xub_StrLen nOrigPos = nPos; + if (GetTimeAmPm(rString, nPos)) + { + if (eScannedType != NUMBERFORMAT_UNDEFINED && + eScannedType != NUMBERFORMAT_TIME && + eScannedType != NUMBERFORMAT_DATETIME) // already another type + return MatchedReturn(); + else + { + // If not already scanned as time, 6.78am does not result in 6 + // seconds and 78 hundredths in the morning. Keep as suffix. + if (eScannedType != NUMBERFORMAT_TIME && nDecPos == 2 && nAnzNums == 2) + nPos = nOrigPos; // rewind am/pm + else + { + SkipBlanks(rString, nPos); + if ( eScannedType != NUMBERFORMAT_DATETIME ) + eScannedType = NUMBERFORMAT_TIME; + } + } + } + + if ( nNegCheck && SkipChar(')', rString, nPos) ) + { + if (eScannedType == NUMBERFORMAT_CURRENCY) // only if currency + { + nNegCheck = 0; // skip ')' + SkipBlanks(rString, nPos); + } + else + return MatchedReturn(); + } + + if ( nPos < rString.Len() && + (eScannedType == NUMBERFORMAT_DATE + || eScannedType == NUMBERFORMAT_DATETIME) ) + { // day of week is just parsed away + xub_StrLen nOldPos = nPos; + const String& rSep = pFormatter->GetLocaleData()->getLongDateDayOfWeekSep(); + if ( StringContains( rSep, rString, nPos ) ) + { + nPos = nPos + rSep.Len(); + SkipBlanks(rString, nPos); + } + int nDayOfWeek = GetDayOfWeek( rString, nPos ); + if ( nDayOfWeek ) + { + if ( nPos < rString.Len() ) + { + if ( nDayOfWeek < 0 ) + { // short + if ( rString.GetChar( nPos ) == '.' ) + ++nPos; + } + SkipBlanks(rString, nPos); + } + } + else + nPos = nOldPos; + } + +#if NF_RECOGNIZE_ISO8601_TIMEZONES + if (nPos == 0 && eScannedType == NUMBERFORMAT_DATETIME && + rString.Len() == 1 && rString.GetChar(0) == 'Z' && MayBeIso8601()) + { + // ISO 8601 timezone UTC yyyy-mm-ddThh:mmZ + ++nPos; + } +#endif + + if (nPos < rString.Len()) // everything consumed? + { + // does input EndString equal EndString in Format? + if ( !ScanStringNumFor( rString, nPos, pFormat, 0xFFFF ) ) + return FALSE; + } + + return TRUE; +} + + +BOOL ImpSvNumberInputScan::ScanStringNumFor( + const String& rString, // String to scan + xub_StrLen nPos, // Position until which was consumed + const SvNumberformat* pFormat, // The format to match + USHORT nString, // Substring of format, 0xFFFF => last + BOOL bDontDetectNegation // Suppress sign detection + ) +{ + if ( !pFormat ) + return FALSE; + const ::utl::TransliterationWrapper* pTransliteration = pFormatter->GetTransliteration(); + const String* pStr; + String aString( rString ); + BOOL bFound = FALSE; + BOOL bFirst = TRUE; + BOOL bContinue = TRUE; + USHORT nSub; + do + { + // Don't try "lower" subformats ff the very first match was the second + // or third subformat. + nSub = nStringScanNumFor; + do + { // Step through subformats, first positive, then negative, then + // other, but not the last (text) subformat. + pStr = pFormat->GetNumForString( nSub, nString, TRUE ); + if ( pStr && pTransliteration->isEqual( aString, *pStr ) ) + { + bFound = TRUE; + bContinue = FALSE; + } + else if ( nSub < 2 ) + ++nSub; + else + bContinue = FALSE; + } while ( bContinue ); + if ( !bFound && bFirst && nPos ) + { // try remaining substring + bFirst = FALSE; + aString.Erase( 0, nPos ); + bContinue = TRUE; + } + } while ( bContinue ); + + if ( !bFound ) + { + if ( !bDontDetectNegation && (nString == 0) && !bFirst && (nSign < 0) + && pFormat->IsNegativeRealNegative() ) + { // simply negated twice? --1 + aString.EraseAllChars( ' ' ); + if ( (aString.Len() == 1) && (aString.GetChar(0) == '-') ) + { + bFound = TRUE; + nStringScanSign = -1; + nSub = 0; //! not 1 + } + } + if ( !bFound ) + return FALSE; + } + else if ( !bDontDetectNegation && (nSub == 1) && + pFormat->IsNegativeRealNegative() ) + { // negative + if ( nStringScanSign < 0 ) + { + if ( (nSign < 0) && (nStringScanNumFor != 1) ) + nStringScanSign = 1; // triple negated --1 yyy + } + else if ( nStringScanSign == 0 ) + { + if ( nSign < 0 ) + { // nSign and nStringScanSign will be combined later, + // flip sign if doubly negated + if ( (nString == 0) && !bFirst + && SvNumberformat::HasStringNegativeSign( aString ) ) + nStringScanSign = -1; // direct double negation + else if ( pFormat->IsNegativeWithoutSign() ) + nStringScanSign = -1; // indirect double negation + } + else + nStringScanSign = -1; + } + else // > 0 + nStringScanSign = -1; + } + nStringScanNumFor = nSub; + return TRUE; +} + + +//--------------------------------------------------------------------------- +// IsNumberFormatMain +// +// Recognizes types of number, exponential, fraction, percent, currency, date, time. +// Else text => return FALSE + +BOOL ImpSvNumberInputScan::IsNumberFormatMain( + const String& rString, // string to be analyzed + double& , // OUT: result as number, if possible + const SvNumberformat* pFormat ) // maybe number format set to match against +{ + Reset(); + NumberStringDivision( rString ); // breakdown into strings and numbers + if (nAnzStrings >= SV_MAX_ANZ_INPUT_STRINGS) // too many elements + return FALSE; // Njet, Nope, ... + + if (nAnzNums == 0) // no number in input + { + if ( nAnzStrings > 0 ) + { + // Here we may change the original, we don't need it anymore. + // This saves copies and ToUpper() in GetLogical() and is faster. + String& rStrArray = sStrArray[0]; + rStrArray.EraseTrailingChars( ' ' ); + rStrArray.EraseLeadingChars( ' ' ); + nLogical = GetLogical( rStrArray ); + if ( nLogical ) + { + eScannedType = NUMBERFORMAT_LOGICAL; // !!! it's a BOOLEAN + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + else + return FALSE; // simple text + } + else + return FALSE; // simple text + } + + USHORT i = 0; // mark any symbol + USHORT j = 0; // mark only numbers + + switch ( nAnzNums ) + { + case 1 : // Exactly 1 number in input + { // nAnzStrings >= 1 + if (GetNextNumber(i,j)) // i=1,0 + { // Number at start + if (eSetType == NUMBERFORMAT_FRACTION) // Fraction 1 = 1/1 + { + if (i >= nAnzStrings || // no end string nor decimal separator + sStrArray[i] == pFormatter->GetNumDecimalSep()) + { + eScannedType = NUMBERFORMAT_FRACTION; + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + } + } + else + { // Analyze start string + if (!ScanStartString( sStrArray[i], pFormat )) // i=0 + return FALSE; // already an error + i++; // next symbol, i=1 + } + GetNextNumber(i,j); // i=1,2 + if (eSetType == NUMBERFORMAT_FRACTION) // Fraction -1 = -1/1 + { + if (nSign && !nNegCheck && // Sign +, - + eScannedType == NUMBERFORMAT_UNDEFINED && // not date or currency + nDecPos == 0 && // no previous decimal separator + (i >= nAnzStrings || // no end string nor decimal separator + sStrArray[i] == pFormatter->GetNumDecimalSep()) + ) + { + eScannedType = NUMBERFORMAT_FRACTION; + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + } + if (i < nAnzStrings && !ScanEndString( sStrArray[i], pFormat )) + return FALSE; + } + break; + case 2 : // Exactly 2 numbers in input + { // nAnzStrings >= 3 + if (!GetNextNumber(i,j)) // i=1,0 + { // Analyze start string + if (!ScanStartString( sStrArray[i], pFormat )) + return FALSE; // already an error + i++; // i=1 + } + GetNextNumber(i,j); // i=1,2 + if ( !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; // next symbol, i=2,3 + GetNextNumber(i,j); // i=3,4 + if (i < nAnzStrings && !ScanEndString( sStrArray[i], pFormat )) + return FALSE; + if (eSetType == NUMBERFORMAT_FRACTION) // -1,200. as fraction + { + if (!nNegCheck && // no sign '(' + eScannedType == NUMBERFORMAT_UNDEFINED && + (nDecPos == 0 || nDecPos == 3) // no decimal separator or at end + ) + { + eScannedType = NUMBERFORMAT_FRACTION; + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + } + } + break; + case 3 : // Exactly 3 numbers in input + { // nAnzStrings >= 5 + if (!GetNextNumber(i,j)) // i=1,0 + { // Analyze start string + if (!ScanStartString( sStrArray[i], pFormat )) + return FALSE; // already an error + i++; // i=1 + if (nDecPos == 1) // decimal separator at start => error + return FALSE; + } + GetNextNumber(i,j); // i=1,2 + if ( !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; // i=2,3 + if (eScannedType == NUMBERFORMAT_SCIENTIFIC) // E only at end + return FALSE; + GetNextNumber(i,j); // i=3,4 + if ( !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; // i=4,5 + GetNextNumber(i,j); // i=5,6 + if (i < nAnzStrings && !ScanEndString( sStrArray[i], pFormat )) + return FALSE; + if (eSetType == NUMBERFORMAT_FRACTION) // -1,200,100. as fraction + { + if (!nNegCheck && // no sign '(' + eScannedType == NUMBERFORMAT_UNDEFINED && + (nDecPos == 0 || nDecPos == 3) // no decimal separator or at end + ) + { + eScannedType = NUMBERFORMAT_FRACTION; + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + } + if ( eScannedType == NUMBERFORMAT_FRACTION && nDecPos ) + return FALSE; // #36857# not a real fraction + } + break; + default: // More than 3 numbers in input + { // nAnzStrings >= 7 + if (!GetNextNumber(i,j)) // i=1,0 + { // Analyze startstring + if (!ScanStartString( sStrArray[i], pFormat )) + return FALSE; // already an error + i++; // i=1 + if (nDecPos == 1) // decimal separator at start => error + return FALSE; + } + GetNextNumber(i,j); // i=1,2 + if ( !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; // i=2,3 + USHORT nThOld = 10; // just not 0 or 1 + while (nThOld != nThousand && j < nAnzNums-1) + // Execute at least one time + // but leave one number. + { // Loop over group separators + nThOld = nThousand; + if (eScannedType == NUMBERFORMAT_SCIENTIFIC) // E only at end + return FALSE; + GetNextNumber(i,j); + if ( i < nAnzStrings && !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; + } + if (eScannedType == NUMBERFORMAT_DATE || // long date or + eScannedType == NUMBERFORMAT_TIME || // long time or + eScannedType == NUMBERFORMAT_UNDEFINED) // long number + { + for (USHORT k = j; k < nAnzNums-1; k++) + { + if (eScannedType == NUMBERFORMAT_SCIENTIFIC) // E only at endd + return FALSE; + GetNextNumber(i,j); + if ( i < nAnzStrings && !ScanMidString( sStrArray[i], i, pFormat ) ) + return FALSE; + i++; + } + } + GetNextNumber(i,j); + if (i < nAnzStrings && !ScanEndString( sStrArray[i], pFormat )) + return FALSE; + if (eSetType == NUMBERFORMAT_FRACTION) // -1,200,100. as fraction + { + if (!nNegCheck && // no sign '(' + eScannedType == NUMBERFORMAT_UNDEFINED && + (nDecPos == 0 || nDecPos == 3) // no decimal separator or at end + ) + { + eScannedType = NUMBERFORMAT_FRACTION; + nMatchedAllStrings &= ~nMatchedVirgin; + return TRUE; + } + } + if ( eScannedType == NUMBERFORMAT_FRACTION && nDecPos ) + return FALSE; // #36857# not a real fraction + } + } + + if (eScannedType == NUMBERFORMAT_UNDEFINED) + { + nMatchedAllStrings &= ~nMatchedVirgin; + // did match including nMatchedUsedAsReturn + BOOL bDidMatch = (nMatchedAllStrings != 0); + if ( nMatchedAllStrings ) + { + BOOL bMatch = (pFormat ? pFormat->IsNumForStringElementCountEqual( + nStringScanNumFor, nAnzStrings, nAnzNums ) : FALSE); + if ( !bMatch ) + nMatchedAllStrings = 0; + } + if ( nMatchedAllStrings ) + eScannedType = eSetType; + else if ( bDidMatch ) + return FALSE; + else + eScannedType = NUMBERFORMAT_NUMBER; + // everything else should have been recognized by now + } + else if ( eScannedType == NUMBERFORMAT_DATE ) + { // the very relaxed date input checks may interfere with a preset format + nMatchedAllStrings &= ~nMatchedVirgin; + BOOL bWasReturn = ((nMatchedAllStrings & nMatchedUsedAsReturn) != 0); + if ( nMatchedAllStrings ) + { + BOOL bMatch = (pFormat ? pFormat->IsNumForStringElementCountEqual( + nStringScanNumFor, nAnzStrings, nAnzNums ) : FALSE); + if ( !bMatch ) + nMatchedAllStrings = 0; + } + if ( nMatchedAllStrings ) + eScannedType = eSetType; + else if ( bWasReturn ) + return FALSE; + } + else + nMatchedAllStrings = 0; // reset flag to no substrings matched + + return TRUE; +} + + +//--------------------------------------------------------------------------- +// return TRUE or FALSE depending on the nMatched... state and remember usage +BOOL ImpSvNumberInputScan::MatchedReturn() +{ + if ( nMatchedAllStrings & ~nMatchedVirgin ) + { + nMatchedAllStrings |= nMatchedUsedAsReturn; + return TRUE; + } + return FALSE; +} + + +//--------------------------------------------------------------------------- +// Initialize uppercase months and weekdays + +void ImpSvNumberInputScan::InitText() +{ + sal_Int32 j, nElems; + const CharClass* pChrCls = pFormatter->GetCharClass(); + const CalendarWrapper* pCal = pFormatter->GetCalendar(); + delete [] pUpperMonthText; + delete [] pUpperAbbrevMonthText; + ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > xElems + = pCal->getMonths(); + nElems = xElems.getLength(); + pUpperMonthText = new String[nElems]; + pUpperAbbrevMonthText = new String[nElems]; + for ( j=0; j<nElems; j++ ) + { + pUpperMonthText[j] = pChrCls->upper( xElems[j].FullName ); + pUpperAbbrevMonthText[j] = pChrCls->upper( xElems[j].AbbrevName ); + } + delete [] pUpperDayText; + delete [] pUpperAbbrevDayText; + xElems = pCal->getDays(); + nElems = xElems.getLength(); + pUpperDayText = new String[nElems]; + pUpperAbbrevDayText = new String[nElems]; + for ( j=0; j<nElems; j++ ) + { + pUpperDayText[j] = pChrCls->upper( xElems[j].FullName ); + pUpperAbbrevDayText[j] = pChrCls->upper( xElems[j].AbbrevName ); + } + bTextInitialized = TRUE; +} + + +//=========================================================================== +// P U B L I C + +//--------------------------------------------------------------------------- +// ChangeIntl +// +// MUST be called if International/Locale is changed + +void ImpSvNumberInputScan::ChangeIntl() +{ + sal_Unicode cDecSep = pFormatter->GetNumDecimalSep().GetChar(0); + bDecSepInDateSeps = ( cDecSep == '-' || + cDecSep == '/' || + cDecSep == '.' || + cDecSep == pFormatter->GetDateSep().GetChar(0) ); + bTextInitialized = FALSE; + aUpperCurrSymbol.Erase(); +} + + +//--------------------------------------------------------------------------- +// ChangeNullDate + +void ImpSvNumberInputScan::ChangeNullDate( + const USHORT Day, + const USHORT Month, + const USHORT Year ) +{ + if ( pNullDate ) + *pNullDate = Date(Day, Month, Year); + else + pNullDate = new Date(Day, Month, Year); +} + + +//--------------------------------------------------------------------------- +// IsNumberFormat +// +// => does rString represent a number (also date, time et al) + +BOOL ImpSvNumberInputScan::IsNumberFormat( + const String& rString, // string to be analyzed + short& F_Type, // IN: old type, OUT: new type + double& fOutNumber, // OUT: number if convertable + const SvNumberformat* pFormat ) // maybe a number format to match against +{ + String sResString; + String aString; + BOOL res; // return value + eSetType = F_Type; // old type set + + if ( !rString.Len() ) + res = FALSE; + else if (rString.Len() > 308) // arbitrary + res = FALSE; + else + { + // NoMoreUpperNeeded, all comparisons on UpperCase + aString = pFormatter->GetCharClass()->upper( rString ); + // convert native number to ASCII if necessary + TransformInput( aString ); + res = IsNumberFormatMain( aString, fOutNumber, pFormat ); + } + + if (res) + { + if ( nNegCheck // ')' not found for '(' + || (nSign && (eScannedType == NUMBERFORMAT_DATE + || eScannedType == NUMBERFORMAT_DATETIME)) + ) // signed date/datetime + res = FALSE; + else + { // check count of partial number strings + switch (eScannedType) + { + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + case NUMBERFORMAT_NUMBER: + if (nDecPos == 1) // .05 + { + // matched MidStrings function like group separators + if ( nMatchedAllStrings ) + nThousand = nAnzNums - 1; + else if ( nAnzNums != 1 ) + res = FALSE; + } + else if (nDecPos == 2) // 1.05 + { + // matched MidStrings function like group separators + if ( nMatchedAllStrings ) + nThousand = nAnzNums - 1; + else if ( nAnzNums != nThousand+2 ) + res = FALSE; + } + else // 1,100 or 1,100. + { + // matched MidStrings function like group separators + if ( nMatchedAllStrings ) + nThousand = nAnzNums - 1; + else if ( nAnzNums != nThousand+1 ) + res = FALSE; + } + break; + + case NUMBERFORMAT_SCIENTIFIC: // 1.0e-2 + if (nDecPos == 1) // .05 + { + if (nAnzNums != 2) + res = FALSE; + } + else if (nDecPos == 2) // 1.05 + { + if (nAnzNums != nThousand+3) + res = FALSE; + } + else // 1,100 or 1,100. + { + if (nAnzNums != nThousand+2) + res = FALSE; + } + break; + + case NUMBERFORMAT_DATE: + if (nMonth) + { // month name and numbers + if (nAnzNums > 2) + res = FALSE; + } + else + { + if (nAnzNums > 3) + res = FALSE; + } + break; + + case NUMBERFORMAT_TIME: + if (nDecPos) + { // hundredth seconds included + if (nAnzNums > 4) + res = FALSE; + } + else + { + if (nAnzNums > 3) + res = FALSE; + } + break; + + case NUMBERFORMAT_DATETIME: + if (nMonth) + { // month name and numbers + if (nDecPos) + { // hundredth seconds included + if (nAnzNums > 6) + res = FALSE; + } + else + { + if (nAnzNums > 5) + res = FALSE; + } + } + else + { + if (nDecPos) + { // hundredth seconds included + if (nAnzNums > 7) + res = FALSE; + } + else + { + if (nAnzNums > 6) + res = FALSE; + } + } + break; + + default: + break; + } // switch + } // else + } // if (res) + + if (res) + { // we finally have a number + switch (eScannedType) + { + case NUMBERFORMAT_LOGICAL: + if (nLogical == 1) + fOutNumber = 1.0; // True + else if (nLogical == -1) + fOutNumber = 0.0; // False + else + res = FALSE; // Oops + break; + + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + case NUMBERFORMAT_NUMBER: + case NUMBERFORMAT_SCIENTIFIC: + case NUMBERFORMAT_DEFINED: // if no category detected handle as number + { + if ( nDecPos == 1 ) // . at start + sResString.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "0." ) ); + else + sResString.Erase(); + USHORT k; + for ( k = 0; k <= nThousand; k++) + sResString += sStrArray[nNums[k]]; // integer part + if ( nDecPos == 2 && k < nAnzNums ) // . somewhere + { + sResString += '.'; + USHORT nStop = (eScannedType == NUMBERFORMAT_SCIENTIFIC ? + nAnzNums-1 : nAnzNums); + for ( ; k < nStop; k++) + sResString += sStrArray[nNums[k]]; // fractional part + } + + if (eScannedType != NUMBERFORMAT_SCIENTIFIC) + fOutNumber = StringToDouble(sResString); + else + { // append exponent + sResString += 'E'; + if ( nESign == -1 ) + sResString += '-'; + sResString += sStrArray[nNums[nAnzNums-1]]; + rtl_math_ConversionStatus eStatus; + fOutNumber = ::rtl::math::stringToDouble( + sResString, '.', ',', &eStatus, NULL ); + if ( eStatus == rtl_math_ConversionStatus_OutOfRange ) + { + F_Type = NUMBERFORMAT_TEXT; // overflow/underflow -> Text + if (nESign == -1) + fOutNumber = 0.0; + else + fOutNumber = DBL_MAX; +/*!*/ return TRUE; + } + } + + if ( nStringScanSign ) + { + if ( nSign ) + nSign *= nStringScanSign; + else + nSign = nStringScanSign; + } + if ( nSign < 0 ) + fOutNumber = -fOutNumber; + + if (eScannedType == NUMBERFORMAT_PERCENT) + fOutNumber/= 100.0; + } + break; + + case NUMBERFORMAT_FRACTION: + if (nAnzNums == 1) + fOutNumber = StringToDouble(sStrArray[nNums[0]]); + else if (nAnzNums == 2) + { + if (nThousand == 1) + { + sResString = sStrArray[nNums[0]]; + sResString += sStrArray[nNums[1]]; // integer part + fOutNumber = StringToDouble(sResString); + } + else + { + double fZaehler = StringToDouble(sStrArray[nNums[0]]); + double fNenner = StringToDouble(sStrArray[nNums[1]]); + if (fNenner != 0.0) + fOutNumber = fZaehler/fNenner; + else + res = FALSE; + } + } + else // nAnzNums > 2 + { + USHORT k = 1; + sResString = sStrArray[nNums[0]]; + if (nThousand > 0) + for (k = 1; k <= nThousand; k++) + sResString += sStrArray[nNums[k]]; + fOutNumber = StringToDouble(sResString); + + if (k == nAnzNums-2) + { + double fZaehler = StringToDouble(sStrArray[nNums[k]]); + double fNenner = StringToDouble(sStrArray[nNums[k+1]]); + if (fNenner != 0.0) + fOutNumber += fZaehler/fNenner; + else + res = FALSE; + } + } + + if ( nStringScanSign ) + { + if ( nSign ) + nSign *= nStringScanSign; + else + nSign = nStringScanSign; + } + if ( nSign < 0 ) + fOutNumber = -fOutNumber; + break; + + case NUMBERFORMAT_TIME: + GetTimeRef(fOutNumber, 0, nAnzNums); + if ( nSign < 0 ) + fOutNumber = -fOutNumber; + break; + + case NUMBERFORMAT_DATE: + { + USHORT nCounter = 0; // dummy here + res = GetDateRef( fOutNumber, nCounter, pFormat ); + } + break; + + case NUMBERFORMAT_DATETIME: + { + USHORT nCounter = 0; // needed here + res = GetDateRef( fOutNumber, nCounter, pFormat ); + if ( res ) + { + double fTime; + GetTimeRef( fTime, nCounter, nAnzNums - nCounter ); + fOutNumber += fTime; + } + } + break; + + default: + DBG_ERRORFILE( "Some number recognized but what's it?" ); + fOutNumber = 0.0; + break; + } + } + + if (res) // overflow/underflow -> Text + { + if (fOutNumber < -DBL_MAX) // -1.7E308 + { + F_Type = NUMBERFORMAT_TEXT; + fOutNumber = -DBL_MAX; + return TRUE; + } + else if (fOutNumber > DBL_MAX) // 1.7E308 + { + F_Type = NUMBERFORMAT_TEXT; + fOutNumber = DBL_MAX; + return TRUE; + } + } + + if (res == FALSE) + { + eScannedType = NUMBERFORMAT_TEXT; + fOutNumber = 0.0; + } + + F_Type = eScannedType; + return res; +} + + + diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx new file mode 100644 index 000000000000..049925f2034f --- /dev/null +++ b/svl/source/numbers/zforfind.hxx @@ -0,0 +1,291 @@ +/************************************************************************* + * + * 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: zforfind.hxx,v $ + * $Revision: 1.13 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _ZFORFIND_HXX +#define _ZFORFIND_HXX + +#include <tools/string.hxx> + +class Date; +class SvNumberformat; +class SvNumberFormatter; + +#define SV_MAX_ANZ_INPUT_STRINGS 20 // max count of substrings in input scanner + +class ImpSvNumberInputScan +{ +public: + ImpSvNumberInputScan( SvNumberFormatter* pFormatter ); + ~ImpSvNumberInputScan(); + +/*!*/ void ChangeIntl(); // MUST be called if language changes + + /// set reference date for offset calculation + void ChangeNullDate( + const USHORT nDay, + const USHORT nMonth, + const USHORT nYear ); + + /// convert input string to number + BOOL IsNumberFormat( + const String& rString, /// input string + short& F_Type, /// format type (in + out) + double& fOutNumber, /// value determined (out) + const SvNumberformat* pFormat = NULL /// optional a number format to which compare against + ); + + /// after IsNumberFormat: get decimal position + short GetDecPos() const { return nDecPos; } + /// after IsNumberFormat: get count of numeric substrings in input string + USHORT GetAnzNums() const { return nAnzNums; } + + /// set threshold of two-digit year input + void SetYear2000( USHORT nVal ) { nYear2000 = nVal; } + /// get threshold of two-digit year input + USHORT GetYear2000() const { return nYear2000; } + +private: + SvNumberFormatter* pFormatter; + String* pUpperMonthText; // Array of month names, uppercase + String* pUpperAbbrevMonthText; // Array of month names, abbreviated, uppercase + String* pUpperDayText; // Array of day of week names, uppercase + String* pUpperAbbrevDayText; // Array of day of week names, abbreviated, uppercase + String aUpperCurrSymbol; // Currency symbol, uppercase + BOOL bTextInitialized; // Whether days and months are initialized + Date* pNullDate; // 30Dec1899 + // Variables for provisional results: + String sStrArray[SV_MAX_ANZ_INPUT_STRINGS]; // Array of scanned substrings + BOOL IsNum[SV_MAX_ANZ_INPUT_STRINGS]; // Whether a substring is numeric + USHORT nNums[SV_MAX_ANZ_INPUT_STRINGS]; // Sequence of offsets to numeric strings + USHORT nAnzStrings; // Total count of scanned substrings + USHORT nAnzNums; // Count of numeric substrings + BOOL bDecSepInDateSeps; // True <=> DecSep in {.,-,/,DateSep} + BYTE nMatchedAllStrings; // Scan...String() matched all substrings, + // bit mask of nMatched... constants + + static const BYTE nMatchedEndString; // 0x01 + static const BYTE nMatchedMidString; // 0x02 + static const BYTE nMatchedStartString; // 0x04 + static const BYTE nMatchedVirgin; // 0x08 + static const BYTE nMatchedUsedAsReturn; // 0x10 + + int nSign; // Sign of number + short nMonth; // Month (1..x) if date + // negative => short format + short nMonthPos; // 1 = front, 2 = middle + // 3 = end + USHORT nTimePos; // Index of first time separator (+1) + short nDecPos; // Index of substring containing "," (+1) + short nNegCheck; // '( )' for negative + short nESign; // Sign of exponent + short nAmPm; // +1 AM, -1 PM, 0 if none + short nLogical; // -1 => False, 1 => True + USHORT nThousand; // Count of group (AKA thousand) separators + USHORT nPosThousandString; // Position of concatenaded 000,000,000 string + short eScannedType; // Scanned type + short eSetType; // Preset Type + + USHORT nStringScanNumFor; // Fixed strings recognized in + // pFormat->NumFor[nNumForStringScan] + short nStringScanSign; // Sign resulting of FixString + USHORT nYear2000; // Two-digit threshold + // Year as 20xx + // default 18 + // number <= nYear2000 => 20xx + // number > nYear2000 => 19xx + USHORT nTimezonePos; // Index of timezone separator (+1) + BYTE nMayBeIso8601; // 0:=dontknowyet, 1:=yes, 2:=no + +#ifdef _ZFORFIND_CXX // methods private to implementation + void Reset(); // Reset all variables before start of analysis + + void InitText(); // Init of months and days of week + + // Convert string to double. + // Only simple unsigned floating point values without any error detection, + // decimal separator has to be '.' + // If bForceFraction==TRUE the string is taken to be the fractional part + // of 0.1234 without the leading 0. (thus being just "1234"). + double StringToDouble( + const String& rStr, + BOOL bForceFraction = FALSE ); + + BOOL NextNumberStringSymbol( // Next number/string symbol + const sal_Unicode*& pStr, + String& rSymbol ); + + BOOL SkipThousands( // Concatenate ,000,23 blocks + const sal_Unicode*& pStr, // in input to 000123 + String& rSymbol ); + + void NumberStringDivision( // Divide numbers/strings into + const String& rString ); // arrays and variables above. + // Leading blanks and blanks + // after numbers are thrown away + + + // optimized substring versions + + static inline BOOL StringContains( // Whether rString contains rWhat at nPos + const String& rWhat, + const String& rString, + xub_StrLen nPos ) + { // mostly used with one character + if ( rWhat.GetChar(0) != rString.GetChar(nPos) ) + return FALSE; + return StringContainsImpl( rWhat, rString, nPos ); + } + static inline BOOL StringPtrContains( // Whether pString contains rWhat at nPos + const String& rWhat, + const sal_Unicode* pString, + xub_StrLen nPos ) // nPos MUST be a valid offset from pString + { // mostly used with one character + if ( rWhat.GetChar(0) != *(pString+nPos) ) + return FALSE; + return StringPtrContainsImpl( rWhat, pString, nPos ); + } + static BOOL StringContainsImpl( //! DO NOT use directly + const String& rWhat, + const String& rString, + xub_StrLen nPos ); + static BOOL StringPtrContainsImpl( //! DO NOT use directly + const String& rWhat, + const sal_Unicode* pString, + xub_StrLen nPos ); + + + static inline BOOL SkipChar( // Skip a special character + sal_Unicode c, + const String& rString, + xub_StrLen& nPos ); + static inline void SkipBlanks( // Skip blank + const String& rString, + xub_StrLen& nPos ); + static inline BOOL SkipString( // Jump over rWhat in rString at nPos + const String& rWhat, + const String& rString, + xub_StrLen& nPos ); + + inline BOOL GetThousandSep( // Recognizes exactly ,111 as group separator + const String& rString, + xub_StrLen& nPos, + USHORT nStringPos ); + short GetLogical( // Get boolean value + const String& rString ); + short GetMonth( // Get month and advance string position + const String& rString, + xub_StrLen& nPos ); + int GetDayOfWeek( // Get day of week and advance string position + const String& rString, + xub_StrLen& nPos ); + BOOL GetCurrency( // Get currency symbol and advance string position + const String& rString, + xub_StrLen& nPos, + const SvNumberformat* pFormat = NULL ); // optional number format to match against + BOOL GetTimeAmPm( // Get symbol AM or PM and advance string position + const String& rString, + xub_StrLen& nPos ); + inline BOOL GetDecSep( // Get decimal separator and advance string position + const String& rString, + xub_StrLen& nPos ); + inline BOOL GetTime100SecSep( // Get hundredth seconds separator and advance string position + const String& rString, + xub_StrLen& nPos ); + int GetSign( // Get sign and advance string position + const String& rString, // Including special case '(' + xub_StrLen& nPos ); + short GetESign( // Get sign of exponent and advance string position + const String& rString, + xub_StrLen& nPos ); + + inline BOOL GetNextNumber( // Get next number as array offset + USHORT& i, + USHORT& j ); + + void GetTimeRef( // Converts time -> double (only decimals) + double& fOutNumber, // result as double + USHORT nIndex, // Index of hour in input + USHORT nAnz ); // Count of time substrings in input + USHORT ImplGetDay ( USHORT nIndex ); // Day input, 0 if no match + USHORT ImplGetMonth( USHORT nIndex ); // Month input, zero based return, NumberOfMonths if no match + USHORT ImplGetYear ( USHORT nIndex ); // Year input, 0 if no match + BOOL GetDateRef( // Conversion of date to number + double& fDays, // OUT: days diff to null date + USHORT& nCounter, // Count of date substrings + const SvNumberformat* pFormat = NULL ); // optional number format to match against + + BOOL ScanStartString( // Analyze start of string + const String& rString, + const SvNumberformat* pFormat = NULL ); + BOOL ScanMidString( // Analyze middle substring + const String& rString, + USHORT nStringPos, + const SvNumberformat* pFormat = NULL ); + BOOL ScanEndString( // Analyze end of string + const String& rString, + const SvNumberformat* pFormat = NULL ); + + // Whether input may be a ISO 8601 date format, yyyy-mm-dd... + // checks if at least 3 numbers and first number>31 + bool MayBeIso8601(); + + // Compare rString to substring of array indexed by nString + // nString == 0xFFFF => last substring + BOOL ScanStringNumFor( + const String& rString, + xub_StrLen nPos, + const SvNumberformat* pFormat, + USHORT nString, + BOOL bDontDetectNegation = FALSE ); + + // if nMatchedAllStrings set nMatchedUsedAsReturn and return TRUE, + // else do nothing and return FALSE + BOOL MatchedReturn(); + + //! Be sure that the string to be analyzed is already converted to upper + //! case and if it contained native humber digits that they are already + //! converted to ASCII. + BOOL IsNumberFormatMain( // Main anlyzing function + const String& rString, + double& fOutNumber, // return value if string is numeric + const SvNumberformat* pFormat = NULL // optional number format to match against + ); + + static inline BOOL MyIsdigit( sal_Unicode c ); + + // native number transliteration if necessary + void TransformInput( String& rString ); + +#endif // _ZFORFIND_CXX +}; + + + +#endif // _ZFORFIND_HXX diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx new file mode 100644 index 000000000000..f03ef3f31140 --- /dev/null +++ b/svl/source/numbers/zforlist.cxx @@ -0,0 +1,4348 @@ +/************************************************************************* + * + * 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: zforlist.cxx,v $ + * $Revision: 1.72.60.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +// #include <math.h> +#include <tools/debug.hxx> +#include <unotools/charclass.hxx> +#include <i18npool/mslangid.hxx> +#include <unotools/localedatawrapper.hxx> +#include <unotools/numberformatcodewrapper.hxx> +#include <unotools/calendarwrapper.hxx> +#include <com/sun/star/i18n/KNumberFormatUsage.hpp> +#include <com/sun/star/i18n/KNumberFormatType.hpp> +#include <comphelper/processfactory.hxx> +#include <unotools/misccfg.hxx> + +#define _SVSTDARR_USHORTS +#include <svl/svstdarr.hxx> + +#define _ZFORLIST_CXX +#include <osl/mutex.hxx> +#include <svl/zforlist.hxx> +#undef _ZFORLIST_CXX + +#include "zforscan.hxx" +#include "zforfind.hxx" +#include <svl/zformat.hxx> +#include "numhead.hxx" + +#include <unotools/syslocaleoptions.hxx> +#include <unotools/digitgroupingiterator.hxx> +#include <rtl/logfile.hxx> +#include <rtl/instance.hxx> + +#include <math.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::lang; + + +// Constants for type offsets per Country/Language (CL) +#define ZF_STANDARD 0 +#define ZF_STANDARD_PERCENT 10 +#define ZF_STANDARD_CURRENCY 20 +#define ZF_STANDARD_DATE 30 +#define ZF_STANDARD_TIME 40 +#define ZF_STANDARD_DATETIME 50 +#define ZF_STANDARD_SCIENTIFIC 60 +#define ZF_STANDARD_FRACTION 70 +#define ZF_STANDARD_NEWEXTENDED 75 +#define ZF_STANDARD_NEWEXTENDEDMAX SV_MAX_ANZ_STANDARD_FORMATE-2 // 98 +#define ZF_STANDARD_LOGICAL SV_MAX_ANZ_STANDARD_FORMATE-1 // 99 +#define ZF_STANDARD_TEXT SV_MAX_ANZ_STANDARD_FORMATE // 100 + +/* Locale that is set if an unknown locale (from another system) is loaded of + * legacy documents. Can not be SYSTEM because else, for example, a German "DM" + * (old currency) is recognized as a date (#53155#). */ +#define UNKNOWN_SUBSTITUTE LANGUAGE_ENGLISH_US + +static BOOL bIndexTableInitialized = FALSE; +static sal_uInt32 __FAR_DATA theIndexTable[NF_INDEX_TABLE_ENTRIES]; + + +// ==================================================================== + +/** + instead of every number formatter being a listener we have a registry which + also handles one instance of the SysLocale options + */ + +class SvNumberFormatterRegistry_Impl : public utl::ConfigurationListener +{ + List aFormatters; + SvtSysLocaleOptions aSysLocaleOptions; + LanguageType eSysLanguage; + +public: + SvNumberFormatterRegistry_Impl(); + virtual ~SvNumberFormatterRegistry_Impl(); + + void Insert( SvNumberFormatter* pThis ) + { aFormatters.Insert( pThis, LIST_APPEND ); } + SvNumberFormatter* Remove( SvNumberFormatter* pThis ) + { return (SvNumberFormatter*)aFormatters.Remove( pThis ); } + sal_uInt32 Count() + { return aFormatters.Count(); } + + virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ); +}; + + +SvNumberFormatterRegistry_Impl::SvNumberFormatterRegistry_Impl() +{ + eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM ); + aSysLocaleOptions.AddListener( this ); +} + + +SvNumberFormatterRegistry_Impl::~SvNumberFormatterRegistry_Impl() +{ + aSysLocaleOptions.RemoveListener( this ); +} + + +void SvNumberFormatterRegistry_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint ) +{ + if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE ) + { + ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() ); + for ( SvNumberFormatter* p = (SvNumberFormatter*)aFormatters.First(); + p; p = (SvNumberFormatter*)aFormatters.Next() ) + { + p->ReplaceSystemCL( eSysLanguage ); + } + eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM ); + } + if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY ) + { + ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() ); + for ( SvNumberFormatter* p = (SvNumberFormatter*)aFormatters.First(); + p; p = (SvNumberFormatter*)aFormatters.Next() ) + { + p->ResetDefaultSystemCurrency(); + } + } +} + + +// ==================================================================== + +SvNumberFormatterRegistry_Impl* SvNumberFormatter::pFormatterRegistry = NULL; +BOOL SvNumberFormatter::bCurrencyTableInitialized = FALSE; +namespace +{ + struct theCurrencyTable : + public rtl::Static< NfCurrencyTable, theCurrencyTable > {}; + + struct theLegacyOnlyCurrencyTable : + public rtl::Static< NfCurrencyTable, theLegacyOnlyCurrencyTable > {}; +} +USHORT SvNumberFormatter::nSystemCurrencyPosition = 0; +SV_IMPL_PTRARR( NfCurrencyTable, NfCurrencyEntry* ); +SV_IMPL_PTRARR( NfWSStringsDtor, String* ); + +// ob das BankSymbol immer am Ende ist (1 $;-1 $) oder sprachabhaengig +#define NF_BANKSYMBOL_FIX_POSITION 1 + + +/***********************Funktionen SvNumberFormatter**************************/ + +SvNumberFormatter::SvNumberFormatter( + const Reference< XMultiServiceFactory >& xSMgr, + LanguageType eLang ) + : + xServiceManager( xSMgr ) +{ + ImpConstruct( eLang ); +} + + +SvNumberFormatter::SvNumberFormatter( LanguageType eLang ) +{ + ImpConstruct( eLang ); +} + + +SvNumberFormatter::~SvNumberFormatter() +{ + { + ::osl::MutexGuard aGuard( GetMutex() ); + pFormatterRegistry->Remove( this ); + if ( !pFormatterRegistry->Count() ) + { + delete pFormatterRegistry; + pFormatterRegistry = NULL; + } + } + + SvNumberformat* pEntry = aFTable.First(); + while (pEntry) + { + delete pEntry; + pEntry = aFTable.Next(); + } + delete pFormatTable; + delete pCharClass; + delete pStringScanner; + delete pFormatScanner; + ClearMergeTable(); + delete pMergeTable; +} + + +void SvNumberFormatter::ImpConstruct( LanguageType eLang ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svl", "er93726", "SvNumberFormatter::ImpConstruct" ); + + if ( eLang == LANGUAGE_DONTKNOW ) + eLang = UNKNOWN_SUBSTITUTE; + IniLnge = eLang; + ActLnge = eLang; + eEvalDateFormat = NF_EVALDATEFORMAT_INTL; + nDefaultSystemCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND; + + aLocale = MsLangId::convertLanguageToLocale( eLang ); + pCharClass = new CharClass( xServiceManager, aLocale ); + xLocaleData.init( xServiceManager, aLocale, eLang ); + xCalendar.init( xServiceManager, aLocale ); + xTransliteration.init( xServiceManager, eLang, + ::com::sun::star::i18n::TransliterationModules_IGNORE_CASE ); + xNatNum.init( xServiceManager ); + + // cached locale data items + const LocaleDataWrapper* pLoc = GetLocaleData(); + aDecimalSep = pLoc->getNumDecimalSep(); + aThousandSep = pLoc->getNumThousandSep(); + aDateSep = pLoc->getDateSep(); + + pStringScanner = new ImpSvNumberInputScan( this ); + pFormatScanner = new ImpSvNumberformatScan( this ); + pFormatTable = NULL; + MaxCLOffset = 0; + ImpGenerateFormats( 0, FALSE ); // 0 .. 999 for initialized language formats + pMergeTable = NULL; + bNoZero = FALSE; + + ::osl::MutexGuard aGuard( GetMutex() ); + GetFormatterRegistry().Insert( this ); +} + + +void SvNumberFormatter::ChangeIntl(LanguageType eLnge) +{ + if (ActLnge != eLnge) + { + ActLnge = eLnge; + + aLocale = MsLangId::convertLanguageToLocale( eLnge ); + pCharClass->setLocale( aLocale ); + xLocaleData.changeLocale( aLocale, eLnge ); + xCalendar.changeLocale( aLocale ); + xTransliteration.changeLocale( eLnge ); + + // cached locale data items, initialize BEFORE calling ChangeIntl below + const LocaleDataWrapper* pLoc = GetLocaleData(); + aDecimalSep = pLoc->getNumDecimalSep(); + aThousandSep = pLoc->getNumThousandSep(); + aDateSep = pLoc->getDateSep(); + + pFormatScanner->ChangeIntl(); + pStringScanner->ChangeIntl(); + } +} + + +// static +::osl::Mutex& SvNumberFormatter::GetMutex() +{ + static ::osl::Mutex* pMutex = NULL; + if( !pMutex ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pMutex ) + { + // #i77768# Due to a static reference in the toolkit lib + // we need a mutex that lives longer than the svl library. + // Otherwise the dtor would use a destructed mutex!! + pMutex = new ::osl::Mutex; + } + } + return *pMutex; +} + + +// static +SvNumberFormatterRegistry_Impl& SvNumberFormatter::GetFormatterRegistry() +{ + ::osl::MutexGuard aGuard( GetMutex() ); + if ( !pFormatterRegistry ) + pFormatterRegistry = new SvNumberFormatterRegistry_Impl; + return *pFormatterRegistry; +} + + +Color* SvNumberFormatter::GetUserDefColor(USHORT nIndex) +{ + if( aColorLink.IsSet() ) + return (Color*) ( aColorLink.Call( (void*) &nIndex )); + else + return NULL; +} + +void SvNumberFormatter::ChangeNullDate(USHORT nDay, + USHORT nMonth, + USHORT nYear) +{ + pFormatScanner->ChangeNullDate(nDay, nMonth, nYear); + pStringScanner->ChangeNullDate(nDay, nMonth, nYear); +} + +Date* SvNumberFormatter::GetNullDate() +{ + return pFormatScanner->GetNullDate(); +} + +void SvNumberFormatter::ChangeStandardPrec(short nPrec) +{ + pFormatScanner->ChangeStandardPrec(nPrec); +} + +short SvNumberFormatter::GetStandardPrec() +{ + return pFormatScanner->GetStandardPrec(); +} + +void SvNumberFormatter::ImpChangeSysCL( LanguageType eLnge, BOOL bLoadingSO5 ) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = UNKNOWN_SUBSTITUTE; + if (eLnge != IniLnge) + { + IniLnge = eLnge; + ChangeIntl(eLnge); + SvNumberformat* pEntry = aFTable.First(); + while (pEntry) // delete old formats + { + pEntry = (SvNumberformat*) aFTable.Remove(aFTable.GetCurKey()); + delete pEntry; + pEntry = (SvNumberformat*) aFTable.First(); + } + ImpGenerateFormats( 0, bLoadingSO5 ); // new standard formats + } + else if ( bLoadingSO5 ) + { // delete additional standard formats + sal_uInt32 nKey; + aFTable.Seek( SV_MAX_ANZ_STANDARD_FORMATE + 1 ); + while ( (nKey = aFTable.GetCurKey()) > SV_MAX_ANZ_STANDARD_FORMATE && + nKey < SV_COUNTRY_LANGUAGE_OFFSET ) + { + SvNumberformat* pEntry = (SvNumberformat*) aFTable.Remove( nKey ); + delete pEntry; + } + } +} + + +void SvNumberFormatter::ReplaceSystemCL( LanguageType eOldLanguage ) +{ + sal_uInt32 nCLOffset = ImpGetCLOffset( LANGUAGE_SYSTEM ); + if ( nCLOffset > MaxCLOffset ) + return ; // no SYSTEM entries to replace + + const sal_uInt32 nMaxBuiltin = nCLOffset + SV_MAX_ANZ_STANDARD_FORMATE; + const sal_uInt32 nNextCL = nCLOffset + SV_COUNTRY_LANGUAGE_OFFSET; + sal_uInt32 nKey; + + // remove old builtin formats + aFTable.Seek( nCLOffset ); + while ( (nKey = aFTable.GetCurKey()) >= nCLOffset && nKey <= nMaxBuiltin && aFTable.Count() ) + { + SvNumberformat* pEntry = (SvNumberformat*) aFTable.Remove( nKey ); + delete pEntry; + } + + // move additional and user defined to temporary table + Table aOldTable; + while ( (nKey = aFTable.GetCurKey()) >= nCLOffset && nKey < nNextCL && aFTable.Count() ) + { + SvNumberformat* pEntry = (SvNumberformat*) aFTable.Remove( nKey ); + aOldTable.Insert( nKey, pEntry ); + } + + // generate new old builtin formats + // reset ActLnge otherwise ChangeIntl() wouldn't switch if already LANGUAGE_SYSTEM + ActLnge = LANGUAGE_DONTKNOW; + ChangeIntl( LANGUAGE_SYSTEM ); + ImpGenerateFormats( nCLOffset, TRUE ); + + // convert additional and user defined from old system to new system + SvNumberformat* pStdFormat = (SvNumberformat*) aFTable.Get( nCLOffset + ZF_STANDARD ); + sal_uInt32 nLastKey = nMaxBuiltin; + pFormatScanner->SetConvertMode( eOldLanguage, LANGUAGE_SYSTEM, TRUE ); + aOldTable.First(); + while ( aOldTable.Count() ) + { + nKey = aOldTable.GetCurKey(); + if ( nLastKey < nKey ) + nLastKey = nKey; + SvNumberformat* pOldEntry = (SvNumberformat*) aOldTable.Remove( nKey ); + String aString( pOldEntry->GetFormatstring() ); + xub_StrLen nCheckPos = STRING_NOTFOUND; + + // Same as PutEntry() but assures key position even if format code is + // a duplicate. Also won't mix up any LastInsertKey. + ChangeIntl( eOldLanguage ); + LanguageType eLge = eOldLanguage; // ConvertMode changes this + BOOL bCheck = FALSE; + SvNumberformat* pNewEntry = new SvNumberformat( aString, pFormatScanner, + pStringScanner, nCheckPos, eLge ); + if ( nCheckPos != 0 ) + delete pNewEntry; + else + { + short eCheckType = pNewEntry->GetType(); + if ( eCheckType != NUMBERFORMAT_UNDEFINED ) + pNewEntry->SetType( eCheckType | NUMBERFORMAT_DEFINED ); + else + pNewEntry->SetType( NUMBERFORMAT_DEFINED ); + + if ( !aFTable.Insert( nKey, pNewEntry ) ) + delete pNewEntry; + else + bCheck = TRUE; + } + DBG_ASSERT( bCheck, "SvNumberFormatter::ReplaceSystemCL: couldn't convert" ); + + delete pOldEntry; + } + pFormatScanner->SetConvertMode(FALSE); + pStdFormat->SetLastInsertKey( USHORT(nLastKey - nCLOffset) ); + + // append new system additional formats + NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() ); + ImpGenerateAdditionalFormats( nCLOffset, aNumberFormatCode, TRUE ); +} + + +BOOL SvNumberFormatter::IsTextFormat(sal_uInt32 F_Index) const +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + return FALSE; + else + return pFormat->IsTextFormat(); +} + +BOOL SvNumberFormatter::HasTextFormat(sal_uInt32 F_Index) const +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + return FALSE; + else + return pFormat->HasTextFormat(); +} + +BOOL SvNumberFormatter::PutEntry(String& rString, + xub_StrLen& nCheckPos, + short& nType, + sal_uInt32& nKey, // Formatnummer + LanguageType eLnge) +{ + nKey = 0; + if (rString.Len() == 0) // keinen Leerstring + { + nCheckPos = 1; // -> Fehler + return FALSE; + } + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + + ChangeIntl(eLnge); // ggfs. austauschen + LanguageType eLge = eLnge; // Umgehung const fuer ConvertMode + BOOL bCheck = FALSE; + SvNumberformat* p_Entry = new SvNumberformat(rString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLge); + if (nCheckPos == 0) // Format ok + { // Typvergleich: + short eCheckType = p_Entry->GetType(); + if ( eCheckType != NUMBERFORMAT_UNDEFINED) + { + p_Entry->SetType(eCheckType | NUMBERFORMAT_DEFINED); + nType = eCheckType; + } + else + { + p_Entry->SetType(NUMBERFORMAT_DEFINED); + nType = NUMBERFORMAT_DEFINED; + } + sal_uInt32 CLOffset = ImpGenerateCL(eLge); // ggfs. neu Standard- + // formate anlegen + nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLge); + if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + delete p_Entry; + else + { + SvNumberformat* pStdFormat = + (SvNumberformat*) aFTable.Get(CLOffset + ZF_STANDARD); + sal_uInt32 nPos = CLOffset + pStdFormat->GetLastInsertKey(); + if (nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET) + { + DBG_ERROR("SvNumberFormatter:: Zu viele Formate pro CL"); + delete p_Entry; + } + else if (!aFTable.Insert(nPos+1,p_Entry)) + delete p_Entry; + else + { + bCheck = TRUE; + nKey = nPos+1; + pStdFormat->SetLastInsertKey((USHORT) (nKey-CLOffset)); + } + } + } + else + delete p_Entry; + return bCheck; +} + +BOOL SvNumberFormatter::PutandConvertEntry(String& rString, + xub_StrLen& nCheckPos, + short& nType, + sal_uInt32& nKey, + LanguageType eLnge, + LanguageType eNewLnge) +{ + BOOL bRes; + if (eNewLnge == LANGUAGE_DONTKNOW) + eNewLnge = IniLnge; + + pFormatScanner->SetConvertMode(eLnge, eNewLnge); + bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge); + pFormatScanner->SetConvertMode(FALSE); + return bRes; +} + + +BOOL SvNumberFormatter::PutandConvertEntrySystem(String& rString, + xub_StrLen& nCheckPos, + short& nType, + sal_uInt32& nKey, + LanguageType eLnge, + LanguageType eNewLnge) +{ + BOOL bRes; + if (eNewLnge == LANGUAGE_DONTKNOW) + eNewLnge = IniLnge; + + pFormatScanner->SetConvertMode(eLnge, eNewLnge, TRUE); + bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge); + pFormatScanner->SetConvertMode(FALSE); + return bRes; +} + + +sal_uInt32 SvNumberFormatter::GetIndexPuttingAndConverting( String & rString, + LanguageType eLnge, LanguageType eSysLnge, short & rType, + BOOL & rNewInserted, xub_StrLen & rCheckPos ) +{ + sal_uInt32 nKey = NUMBERFORMAT_ENTRY_NOT_FOUND; + rNewInserted = FALSE; + rCheckPos = 0; + + // #62389# empty format string (of Writer) => General standard format + if (!rString.Len()) + ; // nothing + else if (eLnge == LANGUAGE_SYSTEM && eSysLnge != SvtSysLocale().GetLanguage()) + { + sal_uInt32 nOrig = GetEntryKey( rString, eSysLnge ); + if (nOrig == NUMBERFORMAT_ENTRY_NOT_FOUND) + nKey = nOrig; // none avaliable, maybe user-defined + else + nKey = GetFormatForLanguageIfBuiltIn( nOrig, SvtSysLocale().GetLanguage() ); + + if (nKey == nOrig) + { + // Not a builtin format, convert. + // The format code string may get modified and adapted to the real + // language and wouldn't match eSysLnge anymore, do that on a copy. + String aTmp( rString); + rNewInserted = PutandConvertEntrySystem( aTmp, rCheckPos, rType, + nKey, eLnge, SvtSysLocale().GetLanguage()); + if (rCheckPos > 0) + { + DBG_ERRORFILE("SvNumberFormatter::GetIndexPuttingAndConverting: bad format code string for current locale"); + nKey = NUMBERFORMAT_ENTRY_NOT_FOUND; + } + } + } + else + { + nKey = GetEntryKey( rString, eLnge); + if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + rNewInserted = PutEntry( rString, rCheckPos, rType, nKey, eLnge); + if (rCheckPos > 0) + { + DBG_ERRORFILE("SvNumberFormatter::GetIndexPuttingAndConverting: bad format code string for specified locale"); + nKey = NUMBERFORMAT_ENTRY_NOT_FOUND; + } + } + } + if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND) + nKey = GetStandardIndex( eLnge); + rType = GetType( nKey); + // Convert any (!) old "automatic" currency format to new fixed currency + // default format. + if ((rType & NUMBERFORMAT_CURRENCY) != 0) + { + const SvNumberformat* pFormat = GetEntry( nKey); + if (!pFormat->HasNewCurrency()) + { + if (rNewInserted) + { + DeleteEntry( nKey); // don't leave trails of rubbish + rNewInserted = FALSE; + } + nKey = GetStandardFormat( NUMBERFORMAT_CURRENCY, eLnge); + } + } + return nKey; +} + + +void SvNumberFormatter::DeleteEntry(sal_uInt32 nKey) +{ + SvNumberformat* pEntry = aFTable.Remove(nKey); + delete pEntry; +} + +void SvNumberFormatter::PrepareSave() +{ + SvNumberformat* pFormat = aFTable.First(); + while (pFormat) + { + pFormat->SetUsed(FALSE); + pFormat = aFTable.Next(); + } +} + +void SvNumberFormatter::SetFormatUsed(sal_uInt32 nFIndex) +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (pFormat) + pFormat->SetUsed(TRUE); +} + +BOOL SvNumberFormatter::Load( SvStream& rStream ) +{ + LanguageType eSysLang = SvtSysLocale().GetLanguage(); + SvNumberFormatter* pConverter = NULL; + + ImpSvNumMultipleReadHeader aHdr( rStream ); + USHORT nVersion; + rStream >> nVersion; + SvNumberformat* pEntry; + sal_uInt32 nPos; + LanguageType eSaveSysLang, eLoadSysLang; + USHORT nSysOnStore, eLge, eDummy; // Dummy fuer kompatibles Format + rStream >> nSysOnStore >> eLge; // Systemeinstellung aus + // Dokument + eSaveSysLang = (nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE ? + LANGUAGE_SYSTEM : (LanguageType) nSysOnStore); + LanguageType eLnge = (LanguageType) eLge; + ImpChangeSysCL( eLnge, TRUE ); + + rStream >> nPos; + while (nPos != NUMBERFORMAT_ENTRY_NOT_FOUND) + { + rStream >> eDummy >> eLge; + eLnge = (LanguageType) eLge; + ImpGenerateCL( eLnge, TRUE ); // ggfs. neue Standardformate anlegen + + sal_uInt32 nOffset = nPos % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + BOOL bUserDefined = (nOffset > SV_MAX_ANZ_STANDARD_FORMATE); + //! HACK! ER 29.07.97 15:15 + // SaveLang wurde bei SYSTEM nicht gespeichert sondern war auch SYSTEM, + // erst ab 364i Unterscheidung moeglich + BOOL bConversionHack; + if ( eLnge == LANGUAGE_SYSTEM ) + { + if ( nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE ) + { + bConversionHack = bUserDefined; + eLoadSysLang = eSaveSysLang; + } + else + { + bConversionHack = FALSE; + eLoadSysLang = eSysLang; + } + } + else + { + bConversionHack = FALSE; + eLoadSysLang = eSaveSysLang; + } + + pEntry = new SvNumberformat(*pFormatScanner, eLnge); + if ( bConversionHack ) + { // SYSTEM + // nVersion < SV_NUMBERFORMATTER_VERSION_SYSTORE + // nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS + if ( !pConverter ) + pConverter = new SvNumberFormatter( xServiceManager, eSysLang ); + NfHackConversion eHackConversion = pEntry->Load( + rStream, aHdr, pConverter, *pStringScanner ); + switch ( eHackConversion ) + { + case NF_CONVERT_GERMAN_ENGLISH : + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eSysLang, TRUE ); + break; + case NF_CONVERT_ENGLISH_GERMAN : + switch ( eSysLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + break; + default: + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_GERMAN, eSysLang, TRUE ); + } + break; + case NF_CONVERT_NONE : + break; // -Wall not handled. + } + + } + else + { + pEntry->Load( rStream, aHdr, NULL, *pStringScanner ); + if ( !bUserDefined ) + bUserDefined = (pEntry->GetNewStandardDefined() > SV_NUMBERFORMATTER_VERSION); + if ( bUserDefined ) + { + if ( eSaveSysLang != eLoadSysLang ) + { // SYSTEM verschieden + if ( !pConverter ) + pConverter = new SvNumberFormatter( xServiceManager, eSysLang ); + if ( nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS ) + { + switch ( eSaveSysLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + pEntry->ConvertLanguage( *pConverter, + eSaveSysLang, eLoadSysLang, TRUE ); + break; + default: + // alte english nach neuem anderen + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eLoadSysLang, TRUE ); + } + } + else + pEntry->ConvertLanguage( *pConverter, + eSaveSysLang, eLoadSysLang, TRUE ); + } + else + { // nicht SYSTEM oder gleiches SYSTEM + if ( nVersion < SV_NUMBERFORMATTER_VERSION_KEYWORDS ) + { + LanguageType eLoadLang; + BOOL bSystem; + if ( eLnge == LANGUAGE_SYSTEM ) + { + eLoadLang = eSysLang; + bSystem = TRUE; + } + else + { + eLoadLang = eLnge; + bSystem = FALSE; + } + switch ( eLoadLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + // alles beim alten + break; + default: + // alte english nach neuem anderen + if ( !pConverter ) + pConverter = new SvNumberFormatter( xServiceManager, eSysLang ); + pEntry->ConvertLanguage( *pConverter, + LANGUAGE_ENGLISH_US, eLoadLang, bSystem ); + } + } + } + } + } + if ( nOffset == 0 ) // StandardFormat + { + SvNumberformat* pEnt = aFTable.Get(nPos); + if (pEnt) + pEnt->SetLastInsertKey(pEntry->GetLastInsertKey()); + } + if (!aFTable.Insert(nPos, pEntry)) + delete pEntry; + rStream >> nPos; + } + + // ab SV_NUMBERFORMATTER_VERSION_YEAR2000 + if ( nVersion >= SV_NUMBERFORMATTER_VERSION_YEAR2000 ) + { + aHdr.StartEntry(); + if ( aHdr.BytesLeft() >= sizeof(UINT16) ) + { + UINT16 nY2k; + rStream >> nY2k; + if ( nVersion < SV_NUMBERFORMATTER_VERSION_TWODIGITYEAR && nY2k < 100 ) + nY2k += 1901; // war vor src513e: 29, jetzt: 1930 + SetYear2000( nY2k ); + } + aHdr.EndEntry(); + } + + if ( pConverter ) + delete pConverter; + + // generate additional i18n standard formats for all used locales + LanguageType eOldLanguage = ActLnge; + NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() ); + SvUShorts aList; + GetUsedLanguages( aList ); + USHORT nCount = aList.Count(); + for ( USHORT j=0; j<nCount; j++ ) + { + LanguageType eLang = aList[j]; + ChangeIntl( eLang ); + sal_uInt32 CLOffset = ImpGetCLOffset( eLang ); + ImpGenerateAdditionalFormats( CLOffset, aNumberFormatCode, TRUE ); + } + ChangeIntl( eOldLanguage ); + + if (rStream.GetError()) + return FALSE; + else + return TRUE; +} + +BOOL SvNumberFormatter::Save( SvStream& rStream ) const +{ + ImpSvNumMultipleWriteHeader aHdr( rStream ); + // ab 364i wird gespeichert was SYSTEM wirklich war, vorher hart LANGUAGE_SYSTEM + rStream << (USHORT) SV_NUMBERFORMATTER_VERSION; + rStream << (USHORT) SvtSysLocale().GetLanguage() << (USHORT) IniLnge; + SvNumberFormatTable* pTable = (SvNumberFormatTable*) &aFTable; + SvNumberformat* pEntry = (SvNumberformat*) pTable->First(); + while (pEntry) + { + // Gespeichert werden alle markierten, benutzerdefinierten Formate und + // jeweils das Standardformat zu allen angewaehlten CL-Kombinationen + // sowie NewStandardDefined + if ( pEntry->GetUsed() || (pEntry->GetType() & NUMBERFORMAT_DEFINED) || + pEntry->GetNewStandardDefined() || + (pTable->GetCurKey() % SV_COUNTRY_LANGUAGE_OFFSET == 0) ) + { + rStream << static_cast<sal_uInt32>(pTable->GetCurKey()) + << (USHORT) LANGUAGE_SYSTEM + << (USHORT) pEntry->GetLanguage(); + pEntry->Save(rStream, aHdr); + } + pEntry = (SvNumberformat*) pTable->Next(); + } + rStream << NUMBERFORMAT_ENTRY_NOT_FOUND; // EndeKennung + + // ab SV_NUMBERFORMATTER_VERSION_YEAR2000 + aHdr.StartEntry(); + rStream << (UINT16) GetYear2000(); + aHdr.EndEntry(); + + if (rStream.GetError()) + return FALSE; + else + return TRUE; +} + +// static +void SvNumberFormatter::SkipNumberFormatterInStream( SvStream& rStream ) +{ + ImpSvNumMultipleReadHeader::Skip( rStream ); +} + +void SvNumberFormatter::GetUsedLanguages( SvUShorts& rList ) +{ + rList.Remove( 0, rList.Count() ); + + sal_uInt32 nOffset = 0; + while (nOffset <= MaxCLOffset) + { + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nOffset); + if (pFormat) + rList.Insert( pFormat->GetLanguage(), rList.Count() ); + nOffset += SV_COUNTRY_LANGUAGE_OFFSET; + } +} + + +void SvNumberFormatter::FillKeywordTable( NfKeywordTable& rKeywords, + LanguageType eLang ) +{ + ChangeIntl( eLang ); + const String* pTable = pFormatScanner->GetKeywords(); + for ( USHORT i = 0; i < NF_KEYWORD_ENTRIES_COUNT; ++i ) + { + rKeywords[i] = pTable[i]; + } +} + + +String SvNumberFormatter::GetKeyword( LanguageType eLnge, USHORT nIndex ) +{ + ChangeIntl(eLnge); + const String* pTable = pFormatScanner->GetKeywords(); + if ( pTable && nIndex < NF_KEYWORD_ENTRIES_COUNT ) + return pTable[nIndex]; + + DBG_ERROR("GetKeyword: invalid index"); + return String(); +} + + +String SvNumberFormatter::GetStandardName( LanguageType eLnge ) +{ + ChangeIntl( eLnge ); + return pFormatScanner->GetStandardName(); +} + + +sal_uInt32 SvNumberFormatter::ImpGetCLOffset(LanguageType eLnge) const +{ + SvNumberformat* pFormat; + sal_uInt32 nOffset = 0; + while (nOffset <= MaxCLOffset) + { + pFormat = (SvNumberformat*) aFTable.Get(nOffset); + if (pFormat && pFormat->GetLanguage() == eLnge) + return nOffset; + nOffset += SV_COUNTRY_LANGUAGE_OFFSET; + } + return nOffset; +} + +sal_uInt32 SvNumberFormatter::ImpIsEntry(const String& rString, + sal_uInt32 nCLOffset, + LanguageType eLnge) +{ +#ifndef NF_COMMENT_IN_FORMATSTRING +#error NF_COMMENT_IN_FORMATSTRING not defined (zformat.hxx) +#endif +#if NF_COMMENT_IN_FORMATSTRING + String aStr( rString ); + SvNumberformat::EraseComment( aStr ); +#endif + sal_uInt32 res = NUMBERFORMAT_ENTRY_NOT_FOUND; + SvNumberformat* pEntry; + pEntry = (SvNumberformat*) aFTable.Seek(nCLOffset); + while ( res == NUMBERFORMAT_ENTRY_NOT_FOUND && + pEntry && pEntry->GetLanguage() == eLnge ) + { +#if NF_COMMENT_IN_FORMATSTRING + if ( pEntry->GetComment().Len() ) + { + String aFormat( pEntry->GetFormatstring() ); + SvNumberformat::EraseComment( aFormat ); + if ( aStr == aFormat ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); + } + else + { + if ( aStr == pEntry->GetFormatstring() ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); + } +#else + if ( rString == pEntry->GetFormatstring() ) + res = aFTable.GetCurKey(); + else + pEntry = (SvNumberformat*) aFTable.Next(); +#endif + } + return res; +} + + +SvNumberFormatTable& SvNumberFormatter::GetFirstEntryTable( + short& eType, + sal_uInt32& FIndex, + LanguageType& rLnge) +{ + short eTypetmp = eType; + if (eType == NUMBERFORMAT_ALL) // Leere Zelle oder don't care + rLnge = IniLnge; + else + { + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(FIndex); + if (!pFormat) + { +// DBG_ERROR("SvNumberFormatter:: Unbekanntes altes Zahlformat (1)"); + rLnge = IniLnge; + eType = NUMBERFORMAT_ALL; + eTypetmp = eType; + } + else + { + rLnge = pFormat->GetLanguage(); + eType = pFormat->GetType()&~NUMBERFORMAT_DEFINED; + if (eType == 0) + { + eType = NUMBERFORMAT_DEFINED; + eTypetmp = eType; + } + else if (eType == NUMBERFORMAT_DATETIME) + { + eTypetmp = eType; + eType = NUMBERFORMAT_DATE; + } + else + eTypetmp = eType; + } + } + ChangeIntl(rLnge); + return GetEntryTable(eTypetmp, FIndex, rLnge); +} + +sal_uInt32 SvNumberFormatter::ImpGenerateCL( LanguageType eLnge, BOOL bLoadingSO5 ) +{ + ChangeIntl(eLnge); + sal_uInt32 CLOffset = ImpGetCLOffset(ActLnge); + if (CLOffset > MaxCLOffset) + { // new CL combination + if (LocaleDataWrapper::areChecksEnabled()) + { + Locale aLoadedLocale = xLocaleData->getLoadedLocale(); + if ( aLoadedLocale.Language != aLocale.Language || + aLoadedLocale.Country != aLocale.Country ) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumerFormatter::ImpGenerateCL: locales don't match:")); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg )); + } + // test XML locale data FormatElement entries + { + uno::Sequence< i18n::FormatElement > xSeq = + xLocaleData->getAllFormats(); + // A test for completeness of formatindex="0" ... + // formatindex="47" is not needed here since it is done in + // ImpGenerateFormats(). + + // Test for dupes of formatindex="..." + for ( sal_Int32 j = 0; j < xSeq.getLength(); j++ ) + { + sal_Int16 nIdx = xSeq[j].formatIndex; + String aDupes; + for ( sal_Int32 i = 0; i < xSeq.getLength(); i++ ) + { + if ( i != j && xSeq[i].formatIndex == nIdx ) + { + aDupes += String::CreateFromInt32( i ); + aDupes += '('; + aDupes += String( xSeq[i].formatKey ); + aDupes += ')'; + aDupes += ' '; + } + } + if ( aDupes.Len() ) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "XML locale data FormatElement formatindex dupe: ")); + aMsg += String::CreateFromInt32( nIdx ); + aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( + "\nFormatElements: ")); + aMsg += String::CreateFromInt32( j ); + aMsg += '('; + aMsg += String( xSeq[j].formatKey ); + aMsg += ')'; + aMsg += ' '; + aMsg += aDupes; + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg )); + } + } + } + } + + MaxCLOffset += SV_COUNTRY_LANGUAGE_OFFSET; + ImpGenerateFormats( MaxCLOffset, bLoadingSO5 ); + CLOffset = MaxCLOffset; + } + return CLOffset; +} + +SvNumberFormatTable& SvNumberFormatter::ChangeCL(short eType, + sal_uInt32& FIndex, + LanguageType eLnge) +{ + ImpGenerateCL(eLnge); + return GetEntryTable(eType, FIndex, ActLnge); +} + +SvNumberFormatTable& SvNumberFormatter::GetEntryTable( + short eType, + sal_uInt32& FIndex, + LanguageType eLnge) +{ + if ( pFormatTable ) + pFormatTable->Clear(); + else + pFormatTable = new SvNumberFormatTable; + ChangeIntl(eLnge); + sal_uInt32 CLOffset = ImpGetCLOffset(ActLnge); + + // Might generate and insert a default format for the given type + // (e.g. currency) => has to be done before collecting formats. + sal_uInt32 nDefaultIndex = GetStandardFormat( eType, ActLnge ); + + SvNumberformat* pEntry; + pEntry = (SvNumberformat*) aFTable.Seek(CLOffset); + + if (eType == NUMBERFORMAT_ALL) + { + while (pEntry && pEntry->GetLanguage() == ActLnge) + { // copy all entries to output table + pFormatTable->Insert( aFTable.GetCurKey(), pEntry ); + pEntry = (SvNumberformat*) aFTable.Next(); + } + } + else + { + while (pEntry && pEntry->GetLanguage() == ActLnge) + { // copy entries of queried type to output table + if ((pEntry->GetType()) & eType) + pFormatTable->Insert(aFTable.GetCurKey(),pEntry); + pEntry = (SvNumberformat*) aFTable.Next(); + } + } + if ( pFormatTable->Count() > 0 ) + { // select default if queried format doesn't exist or queried type or + // language differ from existing format + pEntry = aFTable.Get(FIndex); + if ( !pEntry || !(pEntry->GetType() & eType) || pEntry->GetLanguage() != ActLnge ) + FIndex = nDefaultIndex; + } + return *pFormatTable; +} + +BOOL SvNumberFormatter::IsNumberFormat(const String& sString, + sal_uInt32& F_Index, + double& fOutNumber) +{ + short FType; + const SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(F_Index); + if (!pFormat) + { +// DBG_ERROR("SvNumberFormatter:: Unbekanntes altes Zahlformat (2)"); + ChangeIntl(IniLnge); + FType = NUMBERFORMAT_NUMBER; + } + else + { + FType = pFormat->GetType() &~NUMBERFORMAT_DEFINED; + if (FType == 0) + FType = NUMBERFORMAT_DEFINED; + ChangeIntl(pFormat->GetLanguage()); + } + BOOL res; + short RType = FType; + // Ergebnistyp + // ohne def-Kennung + if (RType == NUMBERFORMAT_TEXT) // Zahlzelle ->Stringz. + res = FALSE; + else + res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat); + + if (res && !IsCompatible(FType, RType)) // unpassender Typ + { + switch ( RType ) + { + case NUMBERFORMAT_TIME : + { + if ( pStringScanner->GetDecPos() ) + { // 100stel Sekunden + if ( pStringScanner->GetAnzNums() > 3 || fOutNumber < 0.0 ) + F_Index = GetFormatIndex( NF_TIME_HH_MMSS00, ActLnge ); + else + F_Index = GetFormatIndex( NF_TIME_MMSS00, ActLnge ); + } + else if ( fOutNumber >= 1.0 || fOutNumber < 0.0 ) + F_Index = GetFormatIndex( NF_TIME_HH_MMSS, ActLnge ); + else + F_Index = GetStandardFormat( RType, ActLnge ); + } + break; + default: + F_Index = GetStandardFormat( RType, ActLnge ); + } + } + return res; +} + +BOOL SvNumberFormatter::IsCompatible(short eOldType, + short eNewType) +{ + if (eOldType == eNewType) + return TRUE; + else if (eOldType == NUMBERFORMAT_DEFINED) + return TRUE; + else + { + switch (eNewType) + { + case NUMBERFORMAT_NUMBER: + { + switch (eOldType) + { + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + case NUMBERFORMAT_SCIENTIFIC: + case NUMBERFORMAT_FRACTION: +// case NUMBERFORMAT_LOGICAL: + case NUMBERFORMAT_DEFINED: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_DATE: + { + switch (eOldType) + { + case NUMBERFORMAT_DATETIME: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_TIME: + { + switch (eOldType) + { + case NUMBERFORMAT_DATETIME: + return TRUE; + default: + return FALSE; + } + } + break; + case NUMBERFORMAT_DATETIME: + { + switch (eOldType) + { + case NUMBERFORMAT_TIME: + case NUMBERFORMAT_DATE: + return TRUE; + default: + return FALSE; + } + } + break; + default: + return FALSE; + } + return FALSE; + } +} + + +sal_uInt32 SvNumberFormatter::ImpGetDefaultFormat( short nType ) +{ + sal_uInt32 CLOffset = ImpGetCLOffset( ActLnge ); + sal_uInt32 nSearch; + switch( nType ) + { + case NUMBERFORMAT_DATE : + nSearch = CLOffset + ZF_STANDARD_DATE; + break; + case NUMBERFORMAT_TIME : + nSearch = CLOffset + ZF_STANDARD_TIME; + break; + case NUMBERFORMAT_DATETIME : + nSearch = CLOffset + ZF_STANDARD_DATETIME; + break; + case NUMBERFORMAT_PERCENT : + nSearch = CLOffset + ZF_STANDARD_PERCENT; + break; + case NUMBERFORMAT_SCIENTIFIC: + nSearch = CLOffset + ZF_STANDARD_SCIENTIFIC; + break; + default: + nSearch = CLOffset + ZF_STANDARD; + } + sal_uInt32 nDefaultFormat = (sal_uInt32)(sal_uIntPtr) aDefaultFormatKeys.Get( nSearch ); + if ( !nDefaultFormat ) + nDefaultFormat = NUMBERFORMAT_ENTRY_NOT_FOUND; + if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { // look for a defined standard + sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET; + sal_uInt32 nKey; + aFTable.Seek( CLOffset ); + while ( (nKey = aFTable.GetCurKey()) >= CLOffset && nKey < nStopKey ) + { + const SvNumberformat* pEntry = + (const SvNumberformat*) aFTable.GetCurObject(); + if ( pEntry->IsStandard() && ((pEntry->GetType() & + ~NUMBERFORMAT_DEFINED) == nType) ) + { + nDefaultFormat = nKey; + break; // while + } + aFTable.Next(); + } + + if ( nDefaultFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { // none found, use old fixed standards + switch( nType ) + { + case NUMBERFORMAT_DATE : + nDefaultFormat = CLOffset + ZF_STANDARD_DATE; + break; + case NUMBERFORMAT_TIME : + nDefaultFormat = CLOffset + ZF_STANDARD_TIME+1; + break; + case NUMBERFORMAT_DATETIME : + nDefaultFormat = CLOffset + ZF_STANDARD_DATETIME; + break; + case NUMBERFORMAT_PERCENT : + nDefaultFormat = CLOffset + ZF_STANDARD_PERCENT+1; + break; + case NUMBERFORMAT_SCIENTIFIC: + nDefaultFormat = CLOffset + ZF_STANDARD_SCIENTIFIC; + break; + default: + nDefaultFormat = CLOffset + ZF_STANDARD; + } + } + aDefaultFormatKeys.Insert( nSearch, (void*) nDefaultFormat ); + } + return nDefaultFormat; +} + + +sal_uInt32 SvNumberFormatter::GetStandardFormat( short eType, LanguageType eLnge ) +{ + sal_uInt32 CLOffset = ImpGenerateCL(eLnge); + switch(eType) + { + case NUMBERFORMAT_CURRENCY : + { + if ( eLnge == LANGUAGE_SYSTEM ) + return ImpGetDefaultSystemCurrencyFormat(); + else + return ImpGetDefaultCurrencyFormat(); + } + case NUMBERFORMAT_DATE : + case NUMBERFORMAT_TIME : + case NUMBERFORMAT_DATETIME : + case NUMBERFORMAT_PERCENT : + case NUMBERFORMAT_SCIENTIFIC: + return ImpGetDefaultFormat( eType ); + + case NUMBERFORMAT_FRACTION : return CLOffset + ZF_STANDARD_FRACTION; + case NUMBERFORMAT_LOGICAL : return CLOffset + ZF_STANDARD_LOGICAL; + case NUMBERFORMAT_TEXT : return CLOffset + ZF_STANDARD_TEXT; + case NUMBERFORMAT_ALL : + case NUMBERFORMAT_DEFINED : + case NUMBERFORMAT_NUMBER : + case NUMBERFORMAT_UNDEFINED : + default : return CLOffset + ZF_STANDARD; + } +} + +BOOL SvNumberFormatter::IsSpecialStandardFormat( sal_uInt32 nFIndex, + LanguageType eLnge ) +{ + return + nFIndex == GetFormatIndex( NF_TIME_MMSS00, eLnge ) || + nFIndex == GetFormatIndex( NF_TIME_HH_MMSS00, eLnge ) || + nFIndex == GetFormatIndex( NF_TIME_HH_MMSS, eLnge ) + ; +} + +sal_uInt32 SvNumberFormatter::GetStandardFormat( sal_uInt32 nFIndex, short eType, + LanguageType eLnge ) +{ + if ( IsSpecialStandardFormat( nFIndex, eLnge ) ) + return nFIndex; + else + return GetStandardFormat( eType, eLnge ); +} + +sal_uInt32 SvNumberFormatter::GetStandardFormat( double fNumber, sal_uInt32 nFIndex, + short eType, LanguageType eLnge ) +{ + if ( IsSpecialStandardFormat( nFIndex, eLnge ) ) + return nFIndex; + + switch( eType ) + { + case NUMBERFORMAT_TIME : + { + BOOL bSign; + if ( fNumber < 0.0 ) + { + bSign = TRUE; + fNumber = -fNumber; + } + else + bSign = FALSE; + double fSeconds = fNumber * 86400; + if ( floor( fSeconds + 0.5 ) * 100 != floor( fSeconds * 100 + 0.5 ) ) + { // mit 100stel Sekunden + if ( bSign || fSeconds >= 3600 ) + return GetFormatIndex( NF_TIME_HH_MMSS00, eLnge ); + else + return GetFormatIndex( NF_TIME_MMSS00, eLnge ); + } + else + { + if ( bSign || fNumber >= 1.0 ) + return GetFormatIndex( NF_TIME_HH_MMSS, eLnge ); + else + return GetStandardFormat( eType, eLnge ); + } + } + default: + return GetStandardFormat( eType, eLnge ); + } +} + +void SvNumberFormatter::GetInputLineString(const double& fOutNumber, + sal_uInt32 nFIndex, + String& sOutString) +{ + SvNumberformat* pFormat; + short nOldPrec; + Color* pColor; + pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD); + LanguageType eLang = pFormat->GetLanguage(); + ChangeIntl( eLang ); + short eType = pFormat->GetType() & ~NUMBERFORMAT_DEFINED; + if (eType == 0) + eType = NUMBERFORMAT_DEFINED; + nOldPrec = -1; + if (eType == NUMBERFORMAT_NUMBER || eType == NUMBERFORMAT_PERCENT + || eType == NUMBERFORMAT_CURRENCY + || eType == NUMBERFORMAT_SCIENTIFIC + || eType == NUMBERFORMAT_FRACTION) + { + if (eType != NUMBERFORMAT_PERCENT) // spaeter Sonderbehandlung % + eType = NUMBERFORMAT_NUMBER; + nOldPrec = pFormatScanner->GetStandardPrec(); + ChangeStandardPrec(300); // Merkwert + } + sal_uInt32 nKey = nFIndex; + switch ( eType ) + { // #61619# immer vierstelliges Jahr editieren + case NUMBERFORMAT_DATE : + nKey = GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang ); + break; + case NUMBERFORMAT_DATETIME : + nKey = GetFormatIndex( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, eLang ); + break; + default: + nKey = GetStandardFormat( fOutNumber, nFIndex, eType, eLang ); + } + if ( nKey != nFIndex ) + pFormat = (SvNumberformat*) aFTable.Get( nKey ); + if (pFormat) + { + if ( eType == NUMBERFORMAT_TIME && pFormat->GetFormatPrecision() ) + { + nOldPrec = pFormatScanner->GetStandardPrec(); + ChangeStandardPrec(300); // Merkwert + } + pFormat->GetOutputString(fOutNumber, sOutString, &pColor); + } + if (nOldPrec != -1) + ChangeStandardPrec(nOldPrec); +} + +void SvNumberFormatter::GetOutputString(const double& fOutNumber, + sal_uInt32 nFIndex, + String& sOutString, + Color** ppColor) +{ + if (bNoZero && fOutNumber == 0.0) + { + sOutString.Erase(); + return; + } + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD); + ChangeIntl(pFormat->GetLanguage()); + pFormat->GetOutputString(fOutNumber, sOutString, ppColor); +} + +void SvNumberFormatter::GetOutputString(String& sString, + sal_uInt32 nFIndex, + String& sOutString, + Color** ppColor) +{ + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + pFormat = aFTable.Get(ZF_STANDARD_TEXT); + if (!pFormat->IsTextFormat() && !pFormat->HasTextFormat()) + { + *ppColor = NULL; + sOutString = sString; + } + else + { + ChangeIntl(pFormat->GetLanguage()); + pFormat->GetOutputString(sString, sOutString, ppColor); + } +} + +BOOL SvNumberFormatter::GetPreviewString(const String& sFormatString, + double fPreviewNumber, + String& sOutString, + Color** ppColor, + LanguageType eLnge) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return FALSE; + + xub_StrLen nCheckPos = STRING_NOTFOUND; + sal_uInt32 nKey; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + String sTmpString = sFormatString; + SvNumberformat* p_Entry = new SvNumberformat(sTmpString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLnge); + if (nCheckPos == 0) // String ok + { + sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + nKey = ImpIsEntry(p_Entry->GetFormatstring(),CLOffset, eLnge); + if (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + GetOutputString(fPreviewNumber,nKey,sOutString,ppColor); + else + p_Entry->GetOutputString(fPreviewNumber,sOutString, ppColor); + delete p_Entry; + return TRUE; + } + else + { + delete p_Entry; + return FALSE; + } +} + +BOOL SvNumberFormatter::GetPreviewStringGuess( const String& sFormatString, + double fPreviewNumber, + String& sOutString, + Color** ppColor, + LanguageType eLnge ) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return FALSE; + + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + + ChangeIntl( eLnge ); + eLnge = ActLnge; + BOOL bEnglish = (eLnge == LANGUAGE_ENGLISH_US); + + String aFormatStringUpper( pCharClass->upper( sFormatString ) ); + sal_uInt32 nCLOffset = ImpGenerateCL( eLnge ); + sal_uInt32 nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, eLnge ); + if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND ) + { // Zielformat vorhanden + GetOutputString( fPreviewNumber, nKey, sOutString, ppColor ); + return TRUE; + } + + SvNumberformat *pEntry = NULL; + xub_StrLen nCheckPos = STRING_NOTFOUND; + String sTmpString; + + if ( bEnglish ) + { + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + else + { + nCLOffset = ImpGenerateCL( LANGUAGE_ENGLISH_US ); + nKey = ImpIsEntry( aFormatStringUpper, nCLOffset, LANGUAGE_ENGLISH_US ); + BOOL bEnglishFormat = (nKey != NUMBERFORMAT_ENTRY_NOT_FOUND); + + // try english --> other bzw. english nach other konvertieren + LanguageType eFormatLang = LANGUAGE_ENGLISH_US; + pFormatScanner->SetConvertMode( LANGUAGE_ENGLISH_US, eLnge ); + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eFormatLang ); + pFormatScanner->SetConvertMode( FALSE ); + ChangeIntl( eLnge ); + + if ( !bEnglishFormat ) + { + if ( nCheckPos > 0 || xTransliteration->isEqual( sFormatString, + pEntry->GetFormatstring() ) ) + { // other Format + delete pEntry; + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + else + { // verify english + xub_StrLen nCheckPos2 = STRING_NOTFOUND; + // try other --> english + eFormatLang = eLnge; + pFormatScanner->SetConvertMode( eLnge, LANGUAGE_ENGLISH_US ); + sTmpString = sFormatString; + SvNumberformat* pEntry2 = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos2, eFormatLang ); + pFormatScanner->SetConvertMode( FALSE ); + ChangeIntl( eLnge ); + if ( nCheckPos2 == 0 && !xTransliteration->isEqual( sFormatString, + pEntry2->GetFormatstring() ) ) + { // other Format + delete pEntry; + sTmpString = sFormatString; + pEntry = new SvNumberformat( sTmpString, pFormatScanner, + pStringScanner, nCheckPos, eLnge ); + } + delete pEntry2; + } + } + } + + if (nCheckPos == 0) // String ok + { + ImpGenerateCL( eLnge ); // ggfs. neu Standardformate anlegen + pEntry->GetOutputString( fPreviewNumber, sOutString, ppColor ); + delete pEntry; + return TRUE; + } + delete pEntry; + return FALSE; +} + +sal_uInt32 SvNumberFormatter::TestNewString(const String& sFormatString, + LanguageType eLnge) +{ + if (sFormatString.Len() == 0) // keinen Leerstring + return NUMBERFORMAT_ENTRY_NOT_FOUND; + + xub_StrLen nCheckPos = STRING_NOTFOUND; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + sal_uInt32 nRes; + String sTmpString = sFormatString; + SvNumberformat* pEntry = new SvNumberformat(sTmpString, + pFormatScanner, + pStringScanner, + nCheckPos, + eLnge); + if (nCheckPos == 0) // String ok + { + sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + nRes = ImpIsEntry(pEntry->GetFormatstring(),CLOffset, eLnge); + // schon vorhanden ? + } + else + nRes = NUMBERFORMAT_ENTRY_NOT_FOUND; + delete pEntry; + return nRes; +} + +SvNumberformat* SvNumberFormatter::ImpInsertFormat( + const ::com::sun::star::i18n::NumberFormatCode& rCode, + sal_uInt32 nPos, BOOL bAfterLoadingSO5, sal_Int16 nOrgIndex ) +{ + String aCodeStr( rCode.Code ); + if ( rCode.Index < NF_INDEX_TABLE_ENTRIES && + rCode.Usage == ::com::sun::star::i18n::KNumberFormatUsage::CURRENCY && + rCode.Index != NF_CURRENCY_1000DEC2_CCC ) + { // strip surrounding [$...] on automatic currency + if ( aCodeStr.SearchAscii( "[$" ) != STRING_NOTFOUND ) + aCodeStr = SvNumberformat::StripNewCurrencyDelimiters( aCodeStr, FALSE ); + else + { + if (LocaleDataWrapper::areChecksEnabled() && + rCode.Index != NF_CURRENCY_1000DEC2_CCC ) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpInsertFormat: no [$...] on currency format code, index ")); + aMsg += String::CreateFromInt32( rCode.Index ); + aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ":\n")); + aMsg += String( rCode.Code ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + } + } + xub_StrLen nCheckPos = 0; + SvNumberformat* pFormat = new SvNumberformat(aCodeStr, + pFormatScanner, + pStringScanner, + nCheckPos, + ActLnge); + if ( !pFormat || nCheckPos > 0 ) + { + if (LocaleDataWrapper::areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpInsertFormat: bad format code, index ")); + aMsg += String::CreateFromInt32( rCode.Index ); + aMsg += '\n'; + aMsg += String( rCode.Code ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + delete pFormat; + return NULL; + } + if ( rCode.Index >= NF_INDEX_TABLE_ENTRIES ) + { + sal_uInt32 nCLOffset = nPos - (nPos % SV_COUNTRY_LANGUAGE_OFFSET); + sal_uInt32 nKey = ImpIsEntry( aCodeStr, nCLOffset, ActLnge ); + if ( nKey != NUMBERFORMAT_ENTRY_NOT_FOUND ) + { + if (LocaleDataWrapper::areChecksEnabled()) + { + switch ( nOrgIndex ) + { + // These may be dupes of integer versions for locales where + // currencies have no decimals like Italian Lira. + case NF_CURRENCY_1000DEC2 : // NF_CURRENCY_1000INT + case NF_CURRENCY_1000DEC2_RED : // NF_CURRENCY_1000INT_RED + case NF_CURRENCY_1000DEC2_DASHED : // NF_CURRENCY_1000INT_RED + break; + default: + if ( !bAfterLoadingSO5 ) + { // If bAfterLoadingSO5 there will definitely be some dupes, + // don't cry. But we need this test for verification of locale + // data if not loading old SO5 documents. + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpInsertFormat: dup format code, index ")); + aMsg += String::CreateFromInt32( rCode.Index ); + aMsg += '\n'; + aMsg += String( rCode.Code ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + } + } + delete pFormat; + return NULL; + } + else if ( nPos - nCLOffset >= SV_COUNTRY_LANGUAGE_OFFSET ) + { + if (LocaleDataWrapper::areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpInsertFormat: too many format codes, index ")); + aMsg += String::CreateFromInt32( rCode.Index ); + aMsg += '\n'; + aMsg += String( rCode.Code ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + delete pFormat; + return NULL; + } + } + if ( !aFTable.Insert( nPos, pFormat ) ) + { + if (LocaleDataWrapper::areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "ImpInsertFormat: can't insert number format key pos: ")); + aMsg += String::CreateFromInt32( nPos ); + aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ", code index ")); + aMsg += String::CreateFromInt32( rCode.Index ); + aMsg += '\n'; + aMsg += String( rCode.Code ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + delete pFormat; + return NULL; + } + if ( rCode.Default ) + pFormat->SetStandard(); + if ( rCode.DefaultName.getLength() ) + pFormat->SetComment( rCode.DefaultName ); + return pFormat; +} + +SvNumberformat* SvNumberFormatter::ImpInsertNewStandardFormat( + const ::com::sun::star::i18n::NumberFormatCode& rCode, + sal_uInt32 nPos, USHORT nVersion, BOOL bAfterLoadingSO5, + sal_Int16 nOrgIndex ) +{ + SvNumberformat* pNewFormat = ImpInsertFormat( rCode, nPos, + bAfterLoadingSO5, nOrgIndex ); + if (pNewFormat) + pNewFormat->SetNewStandardDefined( nVersion ); + // so that it gets saved, displayed properly, and converted by old versions + return pNewFormat; +} + +void SvNumberFormatter::GetFormatSpecialInfo(sal_uInt32 nFormat, + BOOL& bThousand, + BOOL& IsRed, + USHORT& nPrecision, + USHORT& nAnzLeading) + +{ + const SvNumberformat* pFormat = aFTable.Get(nFormat); + if (pFormat) + pFormat->GetFormatSpecialInfo(bThousand, IsRed, + nPrecision, nAnzLeading); + else + { + bThousand = FALSE; + IsRed = FALSE; + nPrecision = pFormatScanner->GetStandardPrec(); + nAnzLeading = 0; + } +} + +USHORT SvNumberFormatter::GetFormatPrecision( sal_uInt32 nFormat ) const +{ + const SvNumberformat* pFormat = aFTable.Get( nFormat ); + if ( pFormat ) + return pFormat->GetFormatPrecision(); + else + return pFormatScanner->GetStandardPrec(); +} + + +String SvNumberFormatter::GetFormatDecimalSep( sal_uInt32 nFormat ) const +{ + const SvNumberformat* pFormat = aFTable.Get( nFormat ); + if ( !pFormat || pFormat->GetLanguage() == ActLnge ) + return GetNumDecimalSep(); + + String aRet; + LanguageType eSaveLang = xLocaleData.getCurrentLanguage(); + if ( pFormat->GetLanguage() == eSaveLang ) + aRet = xLocaleData->getNumDecimalSep(); + else + { + ::com::sun::star::lang::Locale aSaveLocale( xLocaleData->getLocale() ); + ::com::sun::star::lang::Locale aTmpLocale(MsLangId::convertLanguageToLocale(pFormat->GetLanguage())); + ((SvNumberFormatter*)this)->xLocaleData.changeLocale(aTmpLocale, pFormat->GetLanguage() ); + aRet = xLocaleData->getNumDecimalSep(); + ((SvNumberFormatter*)this)->xLocaleData.changeLocale( aSaveLocale, eSaveLang ); + } + return aRet; +} + + +sal_uInt32 SvNumberFormatter::GetFormatSpecialInfo( const String& rFormatString, + BOOL& bThousand, BOOL& IsRed, USHORT& nPrecision, + USHORT& nAnzLeading, LanguageType eLnge ) + +{ + xub_StrLen nCheckPos = 0; + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + ChangeIntl(eLnge); // ggfs. austauschen + eLnge = ActLnge; + String aTmpStr( rFormatString ); + SvNumberformat* pFormat = new SvNumberformat( aTmpStr, + pFormatScanner, pStringScanner, nCheckPos, eLnge ); + if ( nCheckPos == 0 ) + pFormat->GetFormatSpecialInfo( bThousand, IsRed, nPrecision, nAnzLeading ); + else + { + bThousand = FALSE; + IsRed = FALSE; + nPrecision = pFormatScanner->GetStandardPrec(); + nAnzLeading = 0; + } + delete pFormat; + return nCheckPos; +} + + +inline sal_uInt32 SetIndexTable( NfIndexTableOffset nTabOff, sal_uInt32 nIndOff ) +{ + if ( !bIndexTableInitialized ) + { + DBG_ASSERT( theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND, + "SetIndexTable: theIndexTable[nTabOff] already occupied" ); + theIndexTable[nTabOff] = nIndOff; + } + return nIndOff; +} + + +sal_Int32 SvNumberFormatter::ImpGetFormatCodeIndex( + ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode >& rSeq, + const NfIndexTableOffset nTabOff ) +{ + const sal_Int32 nLen = rSeq.getLength(); + for ( sal_Int32 j=0; j<nLen; j++ ) + { + if ( rSeq[j].Index == nTabOff ) + return j; + } + if (LocaleDataWrapper::areChecksEnabled() && (nTabOff < NF_CURRENCY_START + || NF_CURRENCY_END < nTabOff || nTabOff == NF_CURRENCY_1000INT + || nTabOff == NF_CURRENCY_1000INT_RED + || nTabOff == NF_CURRENCY_1000DEC2_CCC)) + { // currency entries with decimals might not exist, e.g. Italian Lira + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpGetFormatCodeIndex: not found: ")); + aMsg += String::CreateFromInt32( nTabOff ); + LocaleDataWrapper::outputCheckMessage( xLocaleData->appendLocaleInfo( + aMsg)); + } + if ( nLen ) + { + sal_Int32 j; + // look for a preset default + for ( j=0; j<nLen; j++ ) + { + if ( rSeq[j].Default ) + return j; + } + // currencies are special, not all format codes must exist, but all + // builtin number format key index positions must have a format assigned + if ( NF_CURRENCY_START <= nTabOff && nTabOff <= NF_CURRENCY_END ) + { + // look for a format with decimals + for ( j=0; j<nLen; j++ ) + { + if ( rSeq[j].Index == NF_CURRENCY_1000DEC2 ) + return j; + } + // last resort: look for a format without decimals + for ( j=0; j<nLen; j++ ) + { + if ( rSeq[j].Index == NF_CURRENCY_1000INT ) + return j; + } + } + } + else + { // we need at least _some_ format + rSeq.realloc(1); + rSeq[0] = ::com::sun::star::i18n::NumberFormatCode(); + String aTmp( '0' ); + aTmp += GetNumDecimalSep(); + aTmp.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "############" ) ); + rSeq[0].Code = aTmp; + } + return 0; +} + + +sal_Int32 SvNumberFormatter::ImpAdjustFormatCodeDefault( + ::com::sun::star::i18n::NumberFormatCode * pFormatArr, + sal_Int32 nCnt, BOOL bCheckCorrectness ) +{ + using namespace ::com::sun::star; + + if ( !nCnt ) + return -1; + if (bCheckCorrectness && LocaleDataWrapper::areChecksEnabled()) + { // check the locale data for correctness + ByteString aMsg; + sal_Int32 nElem, nShort, nMedium, nLong, nShortDef, nMediumDef, nLongDef; + nShort = nMedium = nLong = nShortDef = nMediumDef = nLongDef = -1; + for ( nElem = 0; nElem < nCnt; nElem++ ) + { + switch ( pFormatArr[nElem].Type ) + { + case i18n::KNumberFormatType::SHORT : + nShort = nElem; + break; + case i18n::KNumberFormatType::MEDIUM : + nMedium = nElem; + break; + case i18n::KNumberFormatType::LONG : + nLong = nElem; + break; + default: + aMsg = "unknown type"; + } + if ( pFormatArr[nElem].Default ) + { + switch ( pFormatArr[nElem].Type ) + { + case i18n::KNumberFormatType::SHORT : + if ( nShortDef != -1 ) + aMsg = "dupe short type default"; + nShortDef = nElem; + break; + case i18n::KNumberFormatType::MEDIUM : + if ( nMediumDef != -1 ) + aMsg = "dupe medium type default"; + nMediumDef = nElem; + break; + case i18n::KNumberFormatType::LONG : + if ( nLongDef != -1 ) + aMsg = "dupe long type default"; + nLongDef = nElem; + break; + } + } + if ( aMsg.Len() ) + { + aMsg.Insert( "SvNumberFormatter::ImpAdjustFormatCodeDefault: ", 0 ); + aMsg += "\nXML locale data FormatElement formatindex: "; + aMsg += ByteString::CreateFromInt32( pFormatArr[nElem].Index ); + String aUMsg( aMsg, RTL_TEXTENCODING_ASCII_US); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aUMsg)); + aMsg.Erase(); + } + } + if ( nShort != -1 && nShortDef == -1 ) + aMsg += "no short type default "; + if ( nMedium != -1 && nMediumDef == -1 ) + aMsg += "no medium type default "; + if ( nLong != -1 && nLongDef == -1 ) + aMsg += "no long type default "; + if ( aMsg.Len() ) + { + aMsg.Insert( "SvNumberFormatter::ImpAdjustFormatCodeDefault: ", 0 ); + aMsg += "\nXML locale data FormatElement group of: "; + String aUMsg( aMsg, RTL_TEXTENCODING_ASCII_US); + aUMsg += String( pFormatArr[0].NameID ); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aUMsg)); + aMsg.Erase(); + } + } + // find the default (medium preferred, then long) and reset all other defaults + sal_Int32 nElem, nDef, nMedium; + nDef = nMedium = -1; + for ( nElem = 0; nElem < nCnt; nElem++ ) + { + if ( pFormatArr[nElem].Default ) + { + switch ( pFormatArr[nElem].Type ) + { + case i18n::KNumberFormatType::MEDIUM : + nDef = nMedium = nElem; + break; + case i18n::KNumberFormatType::LONG : + if ( nMedium == -1 ) + nDef = nElem; + // fallthru + default: + if ( nDef == -1 ) + nDef = nElem; + pFormatArr[nElem].Default = sal_False; + } + } + } + if ( nDef == -1 ) + nDef = 0; + pFormatArr[nDef].Default = sal_True; + return nDef; +} + + +void SvNumberFormatter::ImpGenerateFormats( sal_uInt32 CLOffset, BOOL bLoadingSO5 ) +{ + using namespace ::com::sun::star; + + if ( !bIndexTableInitialized ) + { + for ( USHORT j=0; j<NF_INDEX_TABLE_ENTRIES; j++ ) + { + theIndexTable[j] = NUMBERFORMAT_ENTRY_NOT_FOUND; + } + } + BOOL bOldConvertMode = pFormatScanner->GetConvertMode(); + if (bOldConvertMode) + pFormatScanner->SetConvertMode(FALSE); // switch off for this function + + NumberFormatCodeWrapper aNumberFormatCode( xServiceManager, GetLocale() ); + + xub_StrLen nCheckPos = 0; + SvNumberformat* pNewFormat = NULL; + String aFormatCode; + sal_Int32 nIdx; + sal_Bool bDefault; + + // Counter for additional builtin formats not fitting into the first 10 + // of a category (TLOT:=The Legacy Of Templin), altogether about 20 formats. + // Has to be incremented on each ImpInsertNewStandardformat, new formats + // must be appended, not inserted! + USHORT nNewExtended = ZF_STANDARD_NEWEXTENDED; + + // Number + uno::Sequence< i18n::NumberFormatCode > aFormatSeq + = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::FIXED_NUMBER ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // General + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_STANDARD ); + SvNumberformat* pStdFormat = ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_STANDARD, ZF_STANDARD )); + if (pStdFormat) + { + // This is _the_ standard format. + if (LocaleDataWrapper::areChecksEnabled() && + pStdFormat->GetType() != NUMBERFORMAT_NUMBER) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpGenerateFormats: General format not NUMBER")); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + pStdFormat->SetType( NUMBERFORMAT_NUMBER ); + pStdFormat->SetStandard(); + pStdFormat->SetLastInsertKey( SV_MAX_ANZ_STANDARD_FORMATE ); + } + else + { + if (LocaleDataWrapper::areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "SvNumberFormatter::ImpGenerateFormats: General format not insertable, nothing will work")); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + } + + // Boolean + aFormatCode = pFormatScanner->GetBooleanString(); + pNewFormat = new SvNumberformat( aFormatCode, + pFormatScanner, pStringScanner, nCheckPos, ActLnge ); + pNewFormat->SetType(NUMBERFORMAT_LOGICAL); + pNewFormat->SetStandard(); + if ( !aFTable.Insert( + CLOffset + SetIndexTable( NF_BOOLEAN, ZF_STANDARD_LOGICAL ), + pNewFormat)) + delete pNewFormat; + + // Text + aFormatCode = '@'; + pNewFormat = new SvNumberformat( aFormatCode, + pFormatScanner, pStringScanner, nCheckPos, ActLnge ); + pNewFormat->SetType(NUMBERFORMAT_TEXT); + pNewFormat->SetStandard(); + if ( !aFTable.Insert( + CLOffset + SetIndexTable( NF_TEXT, ZF_STANDARD_TEXT ), + pNewFormat)) + delete pNewFormat; + + + + // 0 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_INT ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_INT, ZF_STANDARD+1 )); + + // 0.00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_DEC2 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_DEC2, ZF_STANDARD+2 )); + + // #,##0 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_1000INT ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_1000INT, ZF_STANDARD+3 )); + + // #,##0.00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_1000DEC2 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_1000DEC2, ZF_STANDARD+4 )); + + // #.##0,00 System country/language dependent since number formatter version 6 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_NUMBER_SYSTEM ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_NUMBER_SYSTEM, ZF_STANDARD+5 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + + // Percent number + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::PERCENT_NUMBER ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // 0% + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_PERCENT_INT ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_PERCENT_INT, ZF_STANDARD_PERCENT )); + + // 0.00% + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_PERCENT_DEC2 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_PERCENT_DEC2, ZF_STANDARD_PERCENT+1 )); + + + + // Currency. NO default standard option! Default is determined of locale + // data default currency and format is generated if needed. + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY ); + if (LocaleDataWrapper::areChecksEnabled()) + { + // though no default desired here, test for correctness of locale data + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + } + + // #,##0 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000INT ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000INT, ZF_STANDARD_CURRENCY )); + aFormatSeq[nIdx].Default = bDefault; + + // #,##0.00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2 ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2, ZF_STANDARD_CURRENCY+1 )); + aFormatSeq[nIdx].Default = bDefault; + + // #,##0 negative red + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000INT_RED ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000INT_RED, ZF_STANDARD_CURRENCY+2 )); + aFormatSeq[nIdx].Default = bDefault; + + // #,##0.00 negative red + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_RED ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_RED, ZF_STANDARD_CURRENCY+3 )); + aFormatSeq[nIdx].Default = bDefault; + + // #,##0.00 USD since number formatter version 3 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_CCC ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + pNewFormat = ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_CCC, ZF_STANDARD_CURRENCY+4 )); + if ( pNewFormat ) + pNewFormat->SetUsed(TRUE); // must be saved for older versions + aFormatSeq[nIdx].Default = bDefault; + + // #.##0,-- since number formatter version 6 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_CURRENCY_1000DEC2_DASHED ); + bDefault = aFormatSeq[nIdx].Default; + aFormatSeq[nIdx].Default = sal_False; + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_CURRENCY_1000DEC2_DASHED, ZF_STANDARD_CURRENCY+5 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + aFormatSeq[nIdx].Default = bDefault; + + + + // Date + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // DD.MM.YY System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYSTEM_SHORT ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYSTEM_SHORT, ZF_STANDARD_DATE )); + + // NN DD.MMM YY + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DEF_NNDDMMMYY ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DEF_NNDDMMMYY, ZF_STANDARD_DATE+1 )); + + // DD.MM.YY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_MMYY ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_MMYY, ZF_STANDARD_DATE+2 )); + + // DD MMM + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMM, ZF_STANDARD_DATE+3 )); + + // MMMM + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_MMMM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_MMMM, ZF_STANDARD_DATE+4 )); + + // QQ YY + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_QQJJ ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_QQJJ, ZF_STANDARD_DATE+5 )); + + // DD.MM.YYYY since number formatter version 2, was DD.MM.[YY]YY + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMYYYY ); + pNewFormat = ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYYYY, ZF_STANDARD_DATE+6 )); + if ( pNewFormat ) + pNewFormat->SetUsed(TRUE); // must be saved for older versions + + // DD.MM.YY def/System, since number formatter version 6 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DDMMYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DDMMYY, ZF_STANDARD_DATE+7 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // NNN, D. MMMM YYYY System + // Long day of week: "NNNN" instead of "NNN," because of compatibility + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYSTEM_LONG ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYSTEM_LONG, ZF_STANDARD_DATE+8 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // Hard coded but system (regional settings) delimiters dependent long date formats + // since numberformatter version 6 + + // D. MMM YY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYY, ZF_STANDARD_DATE+9 ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + //! Unfortunally TLOT intended only 10 builtin formats per category, more + //! would overwrite the next category (ZF_STANDARD_TIME) :-(( + //! Therefore they are inserted with nNewExtended++ (which is also limited) + + // D. MMM YYYY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // D. MMMM YYYY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_DMMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_DMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // NN, D. MMM YY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNDMMMYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // NN, D. MMMM YYYY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNDMMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_NNDMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // NNN, D. MMMM YYYY def/System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_SYS_NNNNDMMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_SYS_NNNNDMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // Hard coded DIN (Deutsche Industrie Norm) and EN (European Norm) date formats + + // D. MMM. YYYY DIN/EN + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_DMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DIN_DMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // D. MMMM YYYY DIN/EN + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_DMMMMYYYY ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DIN_DMMMMYYYY, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // MM-DD DIN/EN + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_MMDD ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DIN_MMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // YY-MM-DD DIN/EN + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_YYMMDD ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DIN_YYMMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + // YYYY-MM-DD DIN/EN + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATE_DIN_YYYYMMDD ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATE_DIN_YYYYMMDD, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NEWSTANDARD ); + + + + // Time + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::TIME ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // HH:MM + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HHMM, ZF_STANDARD_TIME )); + + // HH:MM:SS + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMSS ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HHMMSS, ZF_STANDARD_TIME+1 )); + + // HH:MM AM/PM + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMAMPM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HHMMAMPM, ZF_STANDARD_TIME+2 )); + + // HH:MM:SS AM/PM + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HHMMSSAMPM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HHMMSSAMPM, ZF_STANDARD_TIME+3 )); + + // [HH]:MM:SS + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HH_MMSS ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HH_MMSS, ZF_STANDARD_TIME+4 )); + + // MM:SS,00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_MMSS00 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_MMSS00, ZF_STANDARD_TIME+5 )); + + // [HH]:MM:SS,00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_TIME_HH_MMSS00 ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_TIME_HH_MMSS00, ZF_STANDARD_TIME+6 ), + SV_NUMBERFORMATTER_VERSION_NF_TIME_HH_MMSS00 ); + + + + // DateTime + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::DATE_TIME ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // DD.MM.YY HH:MM System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATETIME_SYSTEM_SHORT_HHMM ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATETIME_SYSTEM_SHORT_HHMM, ZF_STANDARD_DATETIME )); + + // DD.MM.YYYY HH:MM:SS System + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_DATETIME_SYS_DDMMYYYY_HHMMSS ); + ImpInsertNewStandardFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_DATETIME_SYS_DDMMYYYY_HHMMSS, ZF_STANDARD_DATETIME+1 ), + SV_NUMBERFORMATTER_VERSION_NF_DATETIME_SYS_DDMMYYYY_HHMMSS ); + + + + // Scientific number + aFormatSeq = aNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER ); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), aFormatSeq.getLength() ); + + // 0.00E+000 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_SCIENTIFIC_000E000 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_SCIENTIFIC_000E000, ZF_STANDARD_SCIENTIFIC )); + + // 0.00E+00 + nIdx = ImpGetFormatCodeIndex( aFormatSeq, NF_SCIENTIFIC_000E00 ); + ImpInsertFormat( aFormatSeq[nIdx], + CLOffset + SetIndexTable( NF_SCIENTIFIC_000E00, ZF_STANDARD_SCIENTIFIC+1 )); + + + + // Fraction number (no default option) + i18n::NumberFormatCode aSingleFormatCode; + + // # ?/? + aSingleFormatCode.Code = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "# ?/?" ) ); + String s25( RTL_CONSTASCII_USTRINGPARAM( "# ?/?" ) ); // # ?/? + ImpInsertFormat( aSingleFormatCode, + CLOffset + SetIndexTable( NF_FRACTION_1, ZF_STANDARD_FRACTION )); + + // # ??/?? + //! "??/" would be interpreted by the compiler as a trigraph for '\' + aSingleFormatCode.Code = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "# ?\?/?\?" ) ); + ImpInsertFormat( aSingleFormatCode, + CLOffset + SetIndexTable( NF_FRACTION_2, ZF_STANDARD_FRACTION+1 )); + + // Week of year must be appended here because of nNewExtended + const String* pKeyword = pFormatScanner->GetKeywords(); + aSingleFormatCode.Code = pKeyword[NF_KEY_WW]; + ImpInsertNewStandardFormat( aSingleFormatCode, + CLOffset + SetIndexTable( NF_DATE_WW, nNewExtended++ ), + SV_NUMBERFORMATTER_VERSION_NF_DATE_WW ); + + + + bIndexTableInitialized = TRUE; + DBG_ASSERT( nNewExtended <= ZF_STANDARD_NEWEXTENDEDMAX, + "ImpGenerateFormats: overflow of nNewExtended standard formats" ); + + // Now all additional format codes provided by I18N, but only if not + // loading from old SO5 file format, then they are appended last. + if ( !bLoadingSO5 ) + ImpGenerateAdditionalFormats( CLOffset, aNumberFormatCode, FALSE ); + + if (bOldConvertMode) + pFormatScanner->SetConvertMode(TRUE); +} + + +void SvNumberFormatter::ImpGenerateAdditionalFormats( sal_uInt32 CLOffset, + NumberFormatCodeWrapper& rNumberFormatCode, BOOL bAfterLoadingSO5 ) +{ + using namespace ::com::sun::star; + + SvNumberformat* pStdFormat = + (SvNumberformat*) aFTable.Get( CLOffset + ZF_STANDARD ); + if ( !pStdFormat ) + { + DBG_ERRORFILE( "ImpGenerateAdditionalFormats: no GENERAL format" ); + return ; + } + sal_uInt32 nPos = CLOffset + pStdFormat->GetLastInsertKey(); + rNumberFormatCode.setLocale( GetLocale() ); + sal_Int32 j; + + // All currencies, this time with [$...] which was stripped in + // ImpGenerateFormats for old "automatic" currency formats. + uno::Sequence< i18n::NumberFormatCode > aFormatSeq = + rNumberFormatCode.getAllFormatCode( i18n::KNumberFormatUsage::CURRENCY ); + i18n::NumberFormatCode * pFormatArr = aFormatSeq.getArray(); + sal_Int32 nCodes = aFormatSeq.getLength(); + ImpAdjustFormatCodeDefault( aFormatSeq.getArray(), nCodes ); + for ( j = 0; j < nCodes; j++ ) + { + if ( nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET ) + { + DBG_ERRORFILE( "ImpGenerateAdditionalFormats: too many formats" ); + break; // for + } + if ( pFormatArr[j].Index < NF_INDEX_TABLE_ENTRIES && + pFormatArr[j].Index != NF_CURRENCY_1000DEC2_CCC ) + { // Insert only if not already inserted, but internal index must be + // above so ImpInsertFormat can distinguish it. + sal_Int16 nOrgIndex = pFormatArr[j].Index; + pFormatArr[j].Index = sal::static_int_cast< sal_Int16 >( + pFormatArr[j].Index + nCodes + NF_INDEX_TABLE_ENTRIES); + //! no default on currency + sal_Bool bDefault = aFormatSeq[j].Default; + aFormatSeq[j].Default = sal_False; + if ( ImpInsertNewStandardFormat( pFormatArr[j], nPos+1, + SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS, + bAfterLoadingSO5, nOrgIndex ) ) + nPos++; + pFormatArr[j].Index = nOrgIndex; + aFormatSeq[j].Default = bDefault; + } + } + + // all additional format codes provided by I18N that are not old standard index + aFormatSeq = rNumberFormatCode.getAllFormatCodes(); + nCodes = aFormatSeq.getLength(); + if ( nCodes ) + { + pFormatArr = aFormatSeq.getArray(); + // don't check ALL + sal_Int32 nDef = ImpAdjustFormatCodeDefault( pFormatArr, nCodes, FALSE); + // don't have any defaults here + pFormatArr[nDef].Default = sal_False; + for ( j = 0; j < nCodes; j++ ) + { + if ( nPos - CLOffset >= SV_COUNTRY_LANGUAGE_OFFSET ) + { + DBG_ERRORFILE( "ImpGenerateAdditionalFormats: too many formats" ); + break; // for + } + if ( pFormatArr[j].Index >= NF_INDEX_TABLE_ENTRIES ) + if ( ImpInsertNewStandardFormat( pFormatArr[j], nPos+1, + SV_NUMBERFORMATTER_VERSION_ADDITIONAL_I18N_FORMATS, + bAfterLoadingSO5 ) ) + nPos++; + } + } + + pStdFormat->SetLastInsertKey( (USHORT)(nPos - CLOffset) ); +} + + +void SvNumberFormatter::ImpGetPosCurrFormat( String& sPosStr, const String& rCurrSymbol ) +{ + NfCurrencyEntry::CompletePositiveFormatString( sPosStr, + rCurrSymbol, xLocaleData->getCurrPositiveFormat() ); +} + +void SvNumberFormatter::ImpGetNegCurrFormat( String& sNegStr, const String& rCurrSymbol ) +{ + NfCurrencyEntry::CompleteNegativeFormatString( sNegStr, + rCurrSymbol, xLocaleData->getCurrNegativeFormat() ); +} + +void SvNumberFormatter::GenerateFormat(String& sString, + sal_uInt32 nIndex, + LanguageType eLnge, + BOOL bThousand, + BOOL IsRed, + USHORT nPrecision, + USHORT nAnzLeading) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + short eType = GetType(nIndex); + USHORT i; + ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + sString.Erase(); + + utl::DigitGroupingIterator aGrouping( xLocaleData->getDigitGrouping()); + const xub_StrLen nDigitsInFirstGroup = static_cast<xub_StrLen>(aGrouping.get()); + const String& rThSep = GetNumThousandSep(); + if (nAnzLeading == 0) + { + if (!bThousand) + sString += '#'; + else + { + sString += '#'; + sString += rThSep; + sString.Expand( sString.Len() + nDigitsInFirstGroup, '#' ); + } + } + else + { + for (i = 0; i < nAnzLeading; i++) + { + if (bThousand && i > 0 && i == aGrouping.getPos()) + { + sString.Insert( rThSep, 0 ); + aGrouping.advance(); + } + sString.Insert('0',0); + } + if (bThousand && nAnzLeading < nDigitsInFirstGroup + 1) + { + for (i = nAnzLeading; i < nDigitsInFirstGroup + 1; i++) + { + if (bThousand && i % nDigitsInFirstGroup == 0) + sString.Insert( rThSep, 0 ); + sString.Insert('#',0); + } + } + } + if (nPrecision > 0) + { + sString += GetNumDecimalSep(); + sString.Expand( sString.Len() + nPrecision, '0' ); + } + if (eType == NUMBERFORMAT_PERCENT) + sString += '%'; + else if (eType == NUMBERFORMAT_CURRENCY) + { + String sNegStr = sString; + String aCurr; + const NfCurrencyEntry* pEntry; + BOOL bBank; + if ( GetNewCurrencySymbolString( nIndex, aCurr, &pEntry, &bBank ) ) + { + if ( pEntry ) + { + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + xLocaleData->getCurrPositiveFormat(), + pEntry->GetPositiveFormat(), bBank ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + xLocaleData->getCurrNegativeFormat(), + pEntry->GetNegativeFormat(), bBank ); + pEntry->CompletePositiveFormatString( sString, bBank, + nPosiForm ); + pEntry->CompleteNegativeFormatString( sNegStr, bBank, + nNegaForm ); + } + else + { // assume currency abbreviation (AKA banking symbol), not symbol + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + xLocaleData->getCurrPositiveFormat(), + xLocaleData->getCurrPositiveFormat(), TRUE ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + xLocaleData->getCurrNegativeFormat(), + xLocaleData->getCurrNegativeFormat(), TRUE ); + NfCurrencyEntry::CompletePositiveFormatString( sString, aCurr, + nPosiForm ); + NfCurrencyEntry::CompleteNegativeFormatString( sNegStr, aCurr, + nNegaForm ); + } + } + else + { // "automatic" old style + String aSymbol, aAbbrev; + GetCompatibilityCurrency( aSymbol, aAbbrev ); + ImpGetPosCurrFormat( sString, aSymbol ); + ImpGetNegCurrFormat( sNegStr, aSymbol ); + } + if (IsRed) + { + sString += ';'; + sString += '['; + sString += pFormatScanner->GetRedString(); + sString += ']'; + } + else + sString += ';'; + sString += sNegStr; + } + if (IsRed && eType != NUMBERFORMAT_CURRENCY) + { + String sTmpStr = sString; + sTmpStr += ';'; + sTmpStr += '['; + sTmpStr += pFormatScanner->GetRedString(); + sTmpStr += ']'; + sTmpStr += '-'; + sTmpStr +=sString; + sString = sTmpStr; + } +} + +BOOL SvNumberFormatter::IsUserDefined(const String& sStr, + LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + eLnge = ActLnge; + sal_uInt32 nKey = ImpIsEntry(sStr, CLOffset, eLnge); + if (nKey == NUMBERFORMAT_ENTRY_NOT_FOUND) + return TRUE; + SvNumberformat* pEntry = aFTable.Get(nKey); + if ( pEntry && ((pEntry->GetType() & NUMBERFORMAT_DEFINED) != 0) ) + return TRUE; + return FALSE; +} + +sal_uInt32 SvNumberFormatter::GetEntryKey(const String& sStr, + LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + sal_uInt32 CLOffset = ImpGenerateCL(eLnge); // ggfs. neu Standard- + // formate anlegen + return ImpIsEntry(sStr, CLOffset, eLnge); +} + +sal_uInt32 SvNumberFormatter::GetStandardIndex(LanguageType eLnge) +{ + if (eLnge == LANGUAGE_DONTKNOW) + eLnge = IniLnge; + return GetStandardFormat(NUMBERFORMAT_NUMBER, eLnge); +} + +short SvNumberFormatter::GetType(sal_uInt32 nFIndex) +{ + short eType; + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get(nFIndex); + if (!pFormat) + eType = NUMBERFORMAT_UNDEFINED; + else + { + eType = pFormat->GetType() &~NUMBERFORMAT_DEFINED; + if (eType == 0) + eType = NUMBERFORMAT_DEFINED; + } + return eType; +} + +void SvNumberFormatter::ClearMergeTable() +{ + if ( pMergeTable ) + { + sal_uInt32* pIndex = (sal_uInt32*) pMergeTable->First(); + while (pIndex) + { + delete pIndex; + pIndex = pMergeTable->Next(); + } + pMergeTable->Clear(); + } +} + +SvNumberFormatterIndexTable* SvNumberFormatter::MergeFormatter(SvNumberFormatter& rTable) +{ + if ( pMergeTable ) + ClearMergeTable(); + else + pMergeTable = new SvNumberFormatterIndexTable; + sal_uInt32 nCLOffset = 0; + sal_uInt32 nOldKey, nOffset, nNewKey; + sal_uInt32* pNewIndex; + SvNumberformat* pNewEntry; + SvNumberformat* pFormat = rTable.aFTable.First(); + while (pFormat) + { + nOldKey = rTable.aFTable.GetCurKey(); + nOffset = nOldKey % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if (nOffset == 0) // 1. Format von CL + nCLOffset = ImpGenerateCL(pFormat->GetLanguage()); + + if (nOffset <= SV_MAX_ANZ_STANDARD_FORMATE) // Std.form. + { + nNewKey = nCLOffset + nOffset; + if (!aFTable.Get(nNewKey)) // noch nicht da + { +// pNewEntry = new SvNumberformat(*pFormat); // Copy reicht nicht !!! + pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner ); + if (!aFTable.Insert(nNewKey, pNewEntry)) + delete pNewEntry; + } + if (nNewKey != nOldKey) // neuer Index + { + pNewIndex = new sal_uInt32(nNewKey); + if (!pMergeTable->Insert(nOldKey,pNewIndex)) + delete pNewIndex; + } + } + else // benutzerdef. + { +// pNewEntry = new SvNumberformat(*pFormat); // Copy reicht nicht !!! + pNewEntry = new SvNumberformat( *pFormat, *pFormatScanner ); + nNewKey = ImpIsEntry(pNewEntry->GetFormatstring(), + nCLOffset, + pFormat->GetLanguage()); + if (nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND) // schon vorhanden + delete pNewEntry; + else + { + SvNumberformat* pStdFormat = + (SvNumberformat*) aFTable.Get(nCLOffset + ZF_STANDARD); + sal_uInt32 nPos = nCLOffset + pStdFormat->GetLastInsertKey(); + nNewKey = nPos+1; + if (nPos - nCLOffset >= SV_COUNTRY_LANGUAGE_OFFSET) + { + DBG_ERROR( + "SvNumberFormatter:: Zu viele Formate pro CL"); + delete pNewEntry; + } + else if (!aFTable.Insert(nNewKey, pNewEntry)) + delete pNewEntry; + else + pStdFormat->SetLastInsertKey((USHORT) (nNewKey - nCLOffset)); + } + if (nNewKey != nOldKey) // neuer Index + { + pNewIndex = new sal_uInt32(nNewKey); + if (!pMergeTable->Insert(nOldKey,pNewIndex)) + delete pNewIndex; + } + } + pFormat = rTable.aFTable.Next(); + } + return pMergeTable; +} + + +SvNumberFormatterMergeMap SvNumberFormatter::ConvertMergeTableToMap() +{ + if (!HasMergeFmtTbl()) + return SvNumberFormatterMergeMap(); + + SvNumberFormatterMergeMap aMap; + for (sal_uInt32* pIndex = pMergeTable->First(); pIndex; pIndex = pMergeTable->Next()) + { + sal_uInt32 nOldKey = pMergeTable->GetCurKey(); + aMap.insert( SvNumberFormatterMergeMap::value_type( nOldKey, *pIndex)); + } + ClearMergeTable(); + return aMap; +} + + +sal_uInt32 SvNumberFormatter::GetFormatForLanguageIfBuiltIn( sal_uInt32 nFormat, + LanguageType eLnge ) +{ + if ( eLnge == LANGUAGE_DONTKNOW ) + eLnge = IniLnge; + if ( nFormat < SV_COUNTRY_LANGUAGE_OFFSET && eLnge == IniLnge ) + return nFormat; // es bleibt wie es ist + sal_uInt32 nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE ) + return nFormat; // kein eingebautes Format + sal_uInt32 nCLOffset = ImpGenerateCL(eLnge); // ggbf. generieren + return nCLOffset + nOffset; +} + + +sal_uInt32 SvNumberFormatter::GetFormatIndex( NfIndexTableOffset nTabOff, + LanguageType eLnge ) +{ + if ( nTabOff >= NF_INDEX_TABLE_ENTRIES + || theIndexTable[nTabOff] == NUMBERFORMAT_ENTRY_NOT_FOUND ) + return NUMBERFORMAT_ENTRY_NOT_FOUND; + if ( eLnge == LANGUAGE_DONTKNOW ) + eLnge = IniLnge; + sal_uInt32 nCLOffset = ImpGenerateCL(eLnge); // ggbf. generieren + return nCLOffset + theIndexTable[nTabOff]; +} + + +NfIndexTableOffset SvNumberFormatter::GetIndexTableOffset( sal_uInt32 nFormat ) const +{ + sal_uInt32 nOffset = nFormat % SV_COUNTRY_LANGUAGE_OFFSET; // relativIndex + if ( nOffset > SV_MAX_ANZ_STANDARD_FORMATE ) + return NF_INDEX_TABLE_ENTRIES; // kein eingebautes Format + for ( USHORT j = 0; j < NF_INDEX_TABLE_ENTRIES; j++ ) + { + if ( theIndexTable[j] == nOffset ) + return (NfIndexTableOffset) j; + } + return NF_INDEX_TABLE_ENTRIES; // bad luck +} + + +void SvNumberFormatter::SetYear2000( USHORT nVal ) +{ + pStringScanner->SetYear2000( nVal ); +} + + +USHORT SvNumberFormatter::GetYear2000() const +{ + return pStringScanner->GetYear2000(); +} + + +USHORT SvNumberFormatter::ExpandTwoDigitYear( USHORT nYear ) const +{ + if ( nYear < 100 ) + return SvNumberFormatter::ExpandTwoDigitYear( nYear, + pStringScanner->GetYear2000() ); + return nYear; +} + + +// static +USHORT SvNumberFormatter::GetYear2000Default() +{ + return (USHORT) ::utl::MiscCfg().GetYear2000(); +} + + +// static +const NfCurrencyTable& SvNumberFormatter::GetTheCurrencyTable() +{ + ::osl::MutexGuard aGuard( GetMutex() ); + while ( !bCurrencyTableInitialized ) + ImpInitCurrencyTable(); + return theCurrencyTable::get(); +} + + +// static +const NfCurrencyEntry* SvNumberFormatter::MatchSystemCurrency() +{ + // MUST call GetTheCurrencyTable() before accessing nSystemCurrencyPosition + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + return nSystemCurrencyPosition ? rTable[nSystemCurrencyPosition] : NULL; +} + + +// static +const NfCurrencyEntry& SvNumberFormatter::GetCurrencyEntry( LanguageType eLang ) +{ + if ( eLang == LANGUAGE_SYSTEM ) + { + const NfCurrencyEntry* pCurr = MatchSystemCurrency(); + return pCurr ? *pCurr : *(GetTheCurrencyTable()[0]); + } + else + { + eLang = MsLangId::getRealLanguage( eLang ); + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetLanguage() == eLang ) + return **ppData; + } + return *(rTable[0]); + } +} + + +// static +const NfCurrencyEntry* SvNumberFormatter::GetCurrencyEntry( + const String& rAbbrev, LanguageType eLang ) +{ + eLang = MsLangId::getRealLanguage( eLang ); + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetLanguage() == eLang && + (*ppData)->GetBankSymbol() == rAbbrev ) + return *ppData; + } + return NULL; +} + + +// static +const NfCurrencyEntry* SvNumberFormatter::GetLegacyOnlyCurrencyEntry( + const String& rSymbol, const String& rAbbrev ) +{ + if (!bCurrencyTableInitialized) + GetTheCurrencyTable(); // just for initialization + const NfCurrencyTable& rTable = theLegacyOnlyCurrencyTable::get(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetSymbol() == rSymbol && + (*ppData)->GetBankSymbol() == rAbbrev ) + return *ppData; + } + return NULL; +} + + +// static +IMPL_STATIC_LINK_NOINSTANCE( SvNumberFormatter, CurrencyChangeLink, void*, EMPTYARG ) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + String aAbbrev; + LanguageType eLang = LANGUAGE_SYSTEM; + SvtSysLocaleOptions().GetCurrencyAbbrevAndLanguage( aAbbrev, eLang ); + SetDefaultSystemCurrency( aAbbrev, eLang ); + return 0; +} + + +// static +void SvNumberFormatter::SetDefaultSystemCurrency( const String& rAbbrev, LanguageType eLang ) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + if ( eLang == LANGUAGE_SYSTEM ) + eLang = SvtSysLocale().GetLanguage(); + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + if ( rAbbrev.Len() ) + { + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetLanguage() == eLang && (*ppData)->GetBankSymbol() == rAbbrev ) + { + nSystemCurrencyPosition = j; + return ; + } + } + } + else + { + for ( USHORT j = 0; j < nCount; j++, ppData++ ) + { + if ( (*ppData)->GetLanguage() == eLang ) + { + nSystemCurrencyPosition = j; + return ; + } + } + } + nSystemCurrencyPosition = 0; // not found => simple SYSTEM +} + + +void SvNumberFormatter::ResetDefaultSystemCurrency() +{ + nDefaultSystemCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND; +} + + +sal_uInt32 SvNumberFormatter::ImpGetDefaultSystemCurrencyFormat() +{ + if ( nDefaultSystemCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { + xub_StrLen nCheck; + short nType; + NfWSStringsDtor aCurrList; + USHORT nDefault = GetCurrencyFormatStrings( aCurrList, + GetCurrencyEntry( LANGUAGE_SYSTEM ), FALSE ); + DBG_ASSERT( aCurrList.Count(), "where is the NewCurrency System standard format?!?" ); + // if already loaded or user defined nDefaultSystemCurrencyFormat + // will be set to the right value + PutEntry( *aCurrList.GetObject( nDefault ), nCheck, nType, + nDefaultSystemCurrencyFormat, LANGUAGE_SYSTEM ); + DBG_ASSERT( nCheck == 0, "NewCurrency CheckError" ); + DBG_ASSERT( nDefaultSystemCurrencyFormat != NUMBERFORMAT_ENTRY_NOT_FOUND, + "nDefaultSystemCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND" ); + } + return nDefaultSystemCurrencyFormat; +} + + +sal_uInt32 SvNumberFormatter::ImpGetDefaultCurrencyFormat() +{ + sal_uInt32 CLOffset = ImpGetCLOffset( ActLnge ); + sal_uInt32 nDefaultCurrencyFormat = + (sal_uInt32)(sal_uIntPtr) aDefaultFormatKeys.Get( CLOffset + ZF_STANDARD_CURRENCY ); + if ( !nDefaultCurrencyFormat ) + nDefaultCurrencyFormat = NUMBERFORMAT_ENTRY_NOT_FOUND; + if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { + // look for a defined standard + sal_uInt32 nStopKey = CLOffset + SV_COUNTRY_LANGUAGE_OFFSET; + sal_uInt32 nKey; + aFTable.Seek( CLOffset ); + while ( (nKey = aFTable.GetCurKey()) >= CLOffset && nKey < nStopKey ) + { + const SvNumberformat* pEntry = + (const SvNumberformat*) aFTable.GetCurObject(); + if ( pEntry->IsStandard() && (pEntry->GetType() & NUMBERFORMAT_CURRENCY) ) + { + nDefaultCurrencyFormat = nKey; + break; // while + } + aFTable.Next(); + } + + if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + { // none found, create one + xub_StrLen nCheck; + short nType; + NfWSStringsDtor aCurrList; + USHORT nDefault = GetCurrencyFormatStrings( aCurrList, + GetCurrencyEntry( ActLnge ), FALSE ); + DBG_ASSERT( aCurrList.Count(), "where is the NewCurrency standard format?" ); + if ( aCurrList.Count() ) + { + // if already loaded or user defined nDefaultSystemCurrencyFormat + // will be set to the right value + PutEntry( *aCurrList.GetObject( nDefault ), nCheck, nType, + nDefaultCurrencyFormat, ActLnge ); + DBG_ASSERT( nCheck == 0, "NewCurrency CheckError" ); + DBG_ASSERT( nDefaultCurrencyFormat != NUMBERFORMAT_ENTRY_NOT_FOUND, + "nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND" ); + } + // old automatic currency format as a last resort + if ( nDefaultCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) + nDefaultCurrencyFormat = CLOffset + ZF_STANDARD_CURRENCY+3; + else + { // mark as standard so that it is found next time + SvNumberformat* pEntry = aFTable.Get( nDefaultCurrencyFormat ); + if ( pEntry ) + pEntry->SetStandard(); + } + } + aDefaultFormatKeys.Insert( CLOffset + ZF_STANDARD_CURRENCY, + (void*) nDefaultCurrencyFormat ); + } + return nDefaultCurrencyFormat; +} + + +// static +// try to make it inline if possible since this a loop body +// TRUE: continue; FALSE: break loop, if pFoundEntry==NULL dupe found +#ifndef DBG_UTIL +inline +#endif + BOOL SvNumberFormatter::ImpLookupCurrencyEntryLoopBody( + const NfCurrencyEntry*& pFoundEntry, BOOL& bFoundBank, + const NfCurrencyEntry* pData, USHORT nPos, const String& rSymbol ) +{ + BOOL bFound; + if ( pData->GetSymbol() == rSymbol ) + { + bFound = TRUE; + bFoundBank = FALSE; + } + else if ( pData->GetBankSymbol() == rSymbol ) + { + bFound = TRUE; + bFoundBank = TRUE; + } + else + bFound = FALSE; + if ( bFound ) + { + if ( pFoundEntry && pFoundEntry != pData ) + { + pFoundEntry = NULL; + return FALSE; // break loop, not unique + } + if ( nPos == 0 ) + { // first entry is SYSTEM + pFoundEntry = MatchSystemCurrency(); + if ( pFoundEntry ) + return FALSE; // break loop + // even if there are more matching entries + // this one is propably the one we are looking for + else + pFoundEntry = pData; + } + else + pFoundEntry = pData; + } + return TRUE; +} + + +BOOL SvNumberFormatter::GetNewCurrencySymbolString( sal_uInt32 nFormat, + String& rStr, const NfCurrencyEntry** ppEntry /* = NULL */, + BOOL* pBank /* = NULL */ ) const +{ + rStr.Erase(); + if ( ppEntry ) + *ppEntry = NULL; + if ( pBank ) + *pBank = FALSE; + SvNumberformat* pFormat = (SvNumberformat*) aFTable.Get( nFormat ); + if ( pFormat ) + { + String aSymbol, aExtension; + if ( pFormat->GetNewCurrencySymbol( aSymbol, aExtension ) ) + { + if ( ppEntry ) + { + BOOL bFoundBank = FALSE; + // we definiteley need an entry matching the format code string + const NfCurrencyEntry* pFoundEntry = GetCurrencyEntry( + bFoundBank, aSymbol, aExtension, pFormat->GetLanguage(), + TRUE ); + if ( pFoundEntry ) + { + *ppEntry = pFoundEntry; + if ( pBank ) + *pBank = bFoundBank; + pFoundEntry->BuildSymbolString( rStr, bFoundBank ); + } + } + if ( !rStr.Len() ) + { // analog zu BuildSymbolString + rStr = '['; + rStr += '$'; + if ( aSymbol.Search( '-' ) != STRING_NOTFOUND || + aSymbol.Search( ']' ) != STRING_NOTFOUND ) + { + rStr += '"'; + rStr += aSymbol; + rStr += '"'; + } + else + rStr += aSymbol; + if ( aExtension.Len() ) + rStr += aExtension; + rStr += ']'; + } + return TRUE; + } + } + return FALSE; +} + + +// static +const NfCurrencyEntry* SvNumberFormatter::GetCurrencyEntry( BOOL & bFoundBank, + const String& rSymbol, const String& rExtension, + LanguageType eFormatLanguage, BOOL bOnlyStringLanguage ) +{ + xub_StrLen nExtLen = rExtension.Len(); + LanguageType eExtLang; + if ( nExtLen ) + { + sal_Int32 nExtLang = ::rtl::OUString( rExtension ).toInt32( 16 ); + if ( !nExtLang ) + eExtLang = LANGUAGE_DONTKNOW; + else + eExtLang = (LanguageType) ((nExtLang < 0) ? + -nExtLang : nExtLang); + } + else + eExtLang = LANGUAGE_DONTKNOW; + const NfCurrencyEntry* pFoundEntry = NULL; + const NfCurrencyTable& rTable = GetTheCurrencyTable(); + USHORT nCount = rTable.Count(); + BOOL bCont = TRUE; + + // first try with given extension language/country + if ( nExtLen ) + { + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount && bCont; j++, ppData++ ) + { + LanguageType eLang = (*ppData)->GetLanguage(); + if ( eLang == eExtLang || + ((eExtLang == LANGUAGE_DONTKNOW) && + (eLang == LANGUAGE_SYSTEM)) + ) + { + bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank, + *ppData, j, rSymbol ); + } + } + } + + // ok? + if ( pFoundEntry || !bCont || (bOnlyStringLanguage && nExtLen) ) + return pFoundEntry; + + if ( !bOnlyStringLanguage ) + { + // now try the language/country of the number format + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount && bCont; j++, ppData++ ) + { + LanguageType eLang = (*ppData)->GetLanguage(); + if ( eLang == eFormatLanguage || + ((eFormatLanguage == LANGUAGE_DONTKNOW) && + (eLang == LANGUAGE_SYSTEM)) + ) + { + bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank, + *ppData, j, rSymbol ); + } + } + + // ok? + if ( pFoundEntry || !bCont ) + return pFoundEntry; + } + + // then try without language/country if no extension specified + if ( !nExtLen ) + { + const NfCurrencyEntryPtr* ppData = rTable.GetData(); + for ( USHORT j = 0; j < nCount && bCont; j++, ppData++ ) + { + bCont = ImpLookupCurrencyEntryLoopBody( pFoundEntry, bFoundBank, + *ppData, j, rSymbol ); + } + } + + return pFoundEntry; +} + + +void SvNumberFormatter::GetCompatibilityCurrency( String& rSymbol, String& rAbbrev ) const +{ + ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 > + xCurrencies = xLocaleData->getAllCurrencies(); + sal_Int32 nCurrencies = xCurrencies.getLength(); + sal_Int32 j; + for ( j=0; j < nCurrencies; ++j ) + { + if ( xCurrencies[j].UsedInCompatibleFormatCodes ) + { + rSymbol = xCurrencies[j].Symbol; + rAbbrev = xCurrencies[j].BankSymbol; + break; + } + } + if ( j >= nCurrencies ) + { + if (LocaleDataWrapper::areChecksEnabled()) + { + String aMsg( RTL_CONSTASCII_USTRINGPARAM( + "GetCompatibilityCurrency: none?")); + LocaleDataWrapper::outputCheckMessage( + xLocaleData->appendLocaleInfo( aMsg)); + } + rSymbol = xLocaleData->getCurrSymbol(); + rAbbrev = xLocaleData->getCurrBankSymbol(); + } +} + + +void lcl_CheckCurrencySymbolPosition( const NfCurrencyEntry& rCurr ) +{ + short nPos = -1; // -1:=unknown, 0:=vorne, 1:=hinten + short nNeg = -1; + switch ( rCurr.GetPositiveFormat() ) + { + case 0: // $1 + nPos = 0; + break; + case 1: // 1$ + nPos = 1; + break; + case 2: // $ 1 + nPos = 0; + break; + case 3: // 1 $ + nPos = 1; + break; + default: + LocaleDataWrapper::outputCheckMessage( + "lcl_CheckCurrencySymbolPosition: unknown PositiveFormat"); + break; + } + switch ( rCurr.GetNegativeFormat() ) + { + case 0: // ($1) + nNeg = 0; + break; + case 1: // -$1 + nNeg = 0; + break; + case 2: // $-1 + nNeg = 0; + break; + case 3: // $1- + nNeg = 0; + break; + case 4: // (1$) + nNeg = 1; + break; + case 5: // -1$ + nNeg = 1; + break; + case 6: // 1-$ + nNeg = 1; + break; + case 7: // 1$- + nNeg = 1; + break; + case 8: // -1 $ + nNeg = 1; + break; + case 9: // -$ 1 + nNeg = 0; + break; + case 10: // 1 $- + nNeg = 1; + break; + case 11: // $ -1 + nNeg = 0; + break; + case 12 : // $ 1- + nNeg = 0; + break; + case 13 : // 1- $ + nNeg = 1; + break; + case 14 : // ($ 1) + nNeg = 0; + break; + case 15 : // (1 $) + nNeg = 1; + break; + default: + LocaleDataWrapper::outputCheckMessage( + "lcl_CheckCurrencySymbolPosition: unknown NegativeFormat"); + break; + } + if ( nPos >= 0 && nNeg >= 0 && nPos != nNeg ) + { + ByteString aStr( "positions of currency symbols differ\nLanguage: " ); + aStr += ByteString::CreateFromInt32( rCurr.GetLanguage() ); + aStr += " <"; + aStr += ByteString( rCurr.GetSymbol(), RTL_TEXTENCODING_UTF8 ); + aStr += "> positive: "; + aStr += ByteString::CreateFromInt32( rCurr.GetPositiveFormat() ); + aStr += ( nPos ? " (postfix)" : " (prefix)" ); + aStr += ", negative: "; + aStr += ByteString::CreateFromInt32( rCurr.GetNegativeFormat() ); + aStr += ( nNeg ? " (postfix)" : " (prefix)" ); +#if 0 +// seems that there really are some currencies which differ, e.g. YugoDinar + DBG_ERRORFILE( aStr.GetBuffer() ); +#endif + } +} + + +// static +void SvNumberFormatter::ImpInitCurrencyTable() +{ + // racing condition possible: + // ::osl::MutexGuard aGuard( GetMutex() ); + // while ( !bCurrencyTableInitialized ) + // ImpInitCurrencyTable(); + static BOOL bInitializing = FALSE; + if ( bCurrencyTableInitialized || bInitializing ) + return ; + bInitializing = TRUE; + + RTL_LOGFILE_CONTEXT_AUTHOR( aTimeLog, "svl", "er93726", "SvNumberFormatter::ImpInitCurrencyTable" ); + + LanguageType eSysLang = SvtSysLocale().GetLanguage(); + LocaleDataWrapper* pLocaleData = new LocaleDataWrapper( + ::comphelper::getProcessServiceFactory(), + MsLangId::convertLanguageToLocale( eSysLang ) ); + // get user configured currency + String aConfiguredCurrencyAbbrev; + LanguageType eConfiguredCurrencyLanguage = LANGUAGE_SYSTEM; + SvtSysLocaleOptions().GetCurrencyAbbrevAndLanguage( + aConfiguredCurrencyAbbrev, eConfiguredCurrencyLanguage ); + USHORT nSecondarySystemCurrencyPosition = 0; + USHORT nMatchingSystemCurrencyPosition = 0; + NfCurrencyEntryPtr pEntry; + + // first entry is SYSTEM + pEntry = new NfCurrencyEntry( *pLocaleData, LANGUAGE_SYSTEM ); + theCurrencyTable::get().Insert( pEntry, 0 ); + USHORT nCurrencyPos = 1; + + ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > xLoc = + LocaleDataWrapper::getInstalledLocaleNames(); + sal_Int32 nLocaleCount = xLoc.getLength(); + RTL_LOGFILE_CONTEXT_TRACE1( aTimeLog, "number of locales: %ld", nLocaleCount ); + Locale const * const pLocales = xLoc.getConstArray(); + NfCurrencyTable &rCurrencyTable = theCurrencyTable::get(); + NfCurrencyTable &rLegacyOnlyCurrencyTable = theLegacyOnlyCurrencyTable::get(); + USHORT nLegacyOnlyCurrencyPos = 0; + for ( sal_Int32 nLocale = 0; nLocale < nLocaleCount; nLocale++ ) + { + LanguageType eLang = MsLangId::convertLocaleToLanguage( + pLocales[nLocale]); +#if OSL_DEBUG_LEVEL > 1 + LanguageType eReal = MsLangId::getRealLanguage( eLang ); + if ( eReal != eLang ) { + BOOL bBreak; + bBreak = TRUE; + } +#endif + pLocaleData->setLocale( pLocales[nLocale] ); + Sequence< Currency2 > aCurrSeq = pLocaleData->getAllCurrencies(); + sal_Int32 nCurrencyCount = aCurrSeq.getLength(); + Currency2 const * const pCurrencies = aCurrSeq.getConstArray(); + + // one default currency for each locale, insert first so it is found first + sal_Int32 nDefault; + for ( nDefault = 0; nDefault < nCurrencyCount; nDefault++ ) + { + if ( pCurrencies[nDefault].Default ) + break; + } + if ( nDefault < nCurrencyCount ) + pEntry = new NfCurrencyEntry( pCurrencies[nDefault], *pLocaleData, eLang ); + else + pEntry = new NfCurrencyEntry( *pLocaleData, eLang ); // first or ShellsAndPebbles + + if (LocaleDataWrapper::areChecksEnabled()) + lcl_CheckCurrencySymbolPosition( *pEntry ); + + rCurrencyTable.Insert( pEntry, nCurrencyPos++ ); + if ( !nSystemCurrencyPosition && (aConfiguredCurrencyAbbrev.Len() ? + pEntry->GetBankSymbol() == aConfiguredCurrencyAbbrev && + pEntry->GetLanguage() == eConfiguredCurrencyLanguage : FALSE) ) + nSystemCurrencyPosition = nCurrencyPos-1; + if ( !nMatchingSystemCurrencyPosition && + pEntry->GetLanguage() == eSysLang ) + nMatchingSystemCurrencyPosition = nCurrencyPos-1; + + // all remaining currencies for each locale + if ( nCurrencyCount > 1 ) + { + sal_Int32 nCurrency; + for ( nCurrency = 0; nCurrency < nCurrencyCount; nCurrency++ ) + { + if (pCurrencies[nCurrency].LegacyOnly) + { + pEntry = new NfCurrencyEntry( pCurrencies[nCurrency], *pLocaleData, eLang ); + rLegacyOnlyCurrencyTable.Insert( pEntry, nLegacyOnlyCurrencyPos++ ); + } + else if ( nCurrency != nDefault ) + { + pEntry = new NfCurrencyEntry( pCurrencies[nCurrency], *pLocaleData, eLang ); + // no dupes + BOOL bInsert = TRUE; + NfCurrencyEntry const * const * pData = rCurrencyTable.GetData(); + USHORT n = rCurrencyTable.Count(); + pData++; // skip first SYSTEM entry + for ( USHORT j=1; j<n; j++ ) + { + if ( *(*pData++) == *pEntry ) + { + bInsert = FALSE; + break; // for + } + } + if ( !bInsert ) + delete pEntry; + else + { + rCurrencyTable.Insert( pEntry, nCurrencyPos++ ); + if ( !nSecondarySystemCurrencyPosition && + (aConfiguredCurrencyAbbrev.Len() ? + pEntry->GetBankSymbol() == aConfiguredCurrencyAbbrev : + pEntry->GetLanguage() == eConfiguredCurrencyLanguage) ) + nSecondarySystemCurrencyPosition = nCurrencyPos-1; + if ( !nMatchingSystemCurrencyPosition && + pEntry->GetLanguage() == eSysLang ) + nMatchingSystemCurrencyPosition = nCurrencyPos-1; + } + } + } + } + } + if ( !nSystemCurrencyPosition ) + nSystemCurrencyPosition = nSecondarySystemCurrencyPosition; + if ((aConfiguredCurrencyAbbrev.Len() && !nSystemCurrencyPosition) && + LocaleDataWrapper::areChecksEnabled()) + LocaleDataWrapper::outputCheckMessage( + "SvNumberFormatter::ImpInitCurrencyTable: configured currency not in I18N locale data."); + // match SYSTEM if no configured currency found + if ( !nSystemCurrencyPosition ) + nSystemCurrencyPosition = nMatchingSystemCurrencyPosition; + if ((!aConfiguredCurrencyAbbrev.Len() && !nSystemCurrencyPosition) && + LocaleDataWrapper::areChecksEnabled()) + LocaleDataWrapper::outputCheckMessage( + "SvNumberFormatter::ImpInitCurrencyTable: system currency not in I18N locale data."); + delete pLocaleData; + SvtSysLocaleOptions::SetCurrencyChangeLink( + STATIC_LINK( NULL, SvNumberFormatter, CurrencyChangeLink ) ); + bInitializing = FALSE; + bCurrencyTableInitialized = TRUE; +} + + +USHORT SvNumberFormatter::GetCurrencyFormatStrings( NfWSStringsDtor& rStrArr, + const NfCurrencyEntry& rCurr, BOOL bBank ) const +{ + USHORT nDefault = 0; + if ( bBank ) + { // nur Bankensymbole + String aPositiveBank, aNegativeBank; + rCurr.BuildPositiveFormatString( aPositiveBank, TRUE, *xLocaleData, 1 ); + rCurr.BuildNegativeFormatString( aNegativeBank, TRUE, *xLocaleData, 1 ); + + WSStringPtr pFormat1 = new String( aPositiveBank ); + *pFormat1 += ';'; + WSStringPtr pFormat2 = new String( *pFormat1 ); + + String aRed( '[' ); + aRed += pFormatScanner->GetRedString(); + aRed += ']'; + + *pFormat2 += aRed; + + *pFormat1 += aNegativeBank; + *pFormat2 += aNegativeBank; + + rStrArr.Insert( pFormat1, rStrArr.Count() ); + rStrArr.Insert( pFormat2, rStrArr.Count() ); + nDefault = rStrArr.Count() - 1; + } + else + { // gemischte Formate wie in SvNumberFormatter::ImpGenerateFormats + // aber keine doppelten, wenn keine Nachkommastellen in Waehrung + String aPositive, aNegative, aPositiveNoDec, aNegativeNoDec, + aPositiveDashed, aNegativeDashed; + WSStringPtr pFormat1, pFormat2, pFormat3, pFormat4, pFormat5; + + String aRed( '[' ); + aRed += pFormatScanner->GetRedString(); + aRed += ']'; + + rCurr.BuildPositiveFormatString( aPositive, FALSE, *xLocaleData, 1 ); + rCurr.BuildNegativeFormatString( aNegative, FALSE, *xLocaleData, 1 ); + if ( rCurr.GetDigits() ) + { + rCurr.BuildPositiveFormatString( aPositiveNoDec, FALSE, *xLocaleData, 0 ); + rCurr.BuildNegativeFormatString( aNegativeNoDec, FALSE, *xLocaleData, 0 ); + rCurr.BuildPositiveFormatString( aPositiveDashed, FALSE, *xLocaleData, 2 ); + rCurr.BuildNegativeFormatString( aNegativeDashed, FALSE, *xLocaleData, 2 ); + + pFormat1 = new String( aPositiveNoDec ); + *pFormat1 += ';'; + pFormat3 = new String( *pFormat1 ); + pFormat5 = new String( aPositiveDashed ); + *pFormat5 += ';'; + + *pFormat1 += aNegativeNoDec; + + *pFormat3 += aRed; + *pFormat5 += aRed; + + *pFormat3 += aNegativeNoDec; + *pFormat5 += aNegativeDashed; + } + else + { + pFormat1 = NULL; + pFormat3 = NULL; + pFormat5 = NULL; + } + + pFormat2 = new String( aPositive ); + *pFormat2 += ';'; + pFormat4 = new String( *pFormat2 ); + + *pFormat2 += aNegative; + + *pFormat4 += aRed; + *pFormat4 += aNegative; + + if ( pFormat1 ) + rStrArr.Insert( pFormat1, rStrArr.Count() ); + rStrArr.Insert( pFormat2, rStrArr.Count() ); + if ( pFormat3 ) + rStrArr.Insert( pFormat3, rStrArr.Count() ); + rStrArr.Insert( pFormat4, rStrArr.Count() ); + nDefault = rStrArr.Count() - 1; + if ( pFormat5 ) + rStrArr.Insert( pFormat5, rStrArr.Count() ); + } + return nDefault; +} + + +//--- NfCurrencyEntry ---------------------------------------------------- + +NfCurrencyEntry::NfCurrencyEntry() + : eLanguage( LANGUAGE_DONTKNOW ), + nPositiveFormat(3), + nNegativeFormat(8), + nDigits(2), + cZeroChar('0') +{ +} + + +NfCurrencyEntry::NfCurrencyEntry( const LocaleDataWrapper& rLocaleData, LanguageType eLang ) +{ + aSymbol = rLocaleData.getCurrSymbol(); + aBankSymbol = rLocaleData.getCurrBankSymbol(); + eLanguage = eLang; + nPositiveFormat = rLocaleData.getCurrPositiveFormat(); + nNegativeFormat = rLocaleData.getCurrNegativeFormat(); + nDigits = rLocaleData.getCurrDigits(); + cZeroChar = rLocaleData.getCurrZeroChar(); +} + + +NfCurrencyEntry::NfCurrencyEntry( const ::com::sun::star::i18n::Currency & rCurr, + const LocaleDataWrapper& rLocaleData, LanguageType eLang ) +{ + aSymbol = rCurr.Symbol; + aBankSymbol = rCurr.BankSymbol; + eLanguage = eLang; + nPositiveFormat = rLocaleData.getCurrPositiveFormat(); + nNegativeFormat = rLocaleData.getCurrNegativeFormat(); + nDigits = rCurr.DecimalPlaces; + cZeroChar = rLocaleData.getCurrZeroChar(); +} + + +BOOL NfCurrencyEntry::operator==( const NfCurrencyEntry& r ) const +{ + return aSymbol == r.aSymbol + && aBankSymbol == r.aBankSymbol + && eLanguage == r.eLanguage + ; +} + + +void NfCurrencyEntry::SetEuro() +{ + aSymbol = NfCurrencyEntry::GetEuroSymbol(); + aBankSymbol.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "EUR" ) ); + eLanguage = LANGUAGE_DONTKNOW; + nPositiveFormat = 3; + nNegativeFormat = 8; + nDigits = 2; + cZeroChar = '0'; +} + + +BOOL NfCurrencyEntry::IsEuro() const +{ + if ( aBankSymbol.EqualsAscii( "EUR" ) ) + return TRUE; + String aEuro( NfCurrencyEntry::GetEuroSymbol() ); + return aSymbol == aEuro; +} + + +void NfCurrencyEntry::ApplyVariableInformation( const NfCurrencyEntry& r ) +{ + nPositiveFormat = r.nPositiveFormat; + nNegativeFormat = r.nNegativeFormat; + cZeroChar = r.cZeroChar; +} + + +void NfCurrencyEntry::BuildSymbolString( String& rStr, BOOL bBank, + BOOL bWithoutExtension ) const +{ + rStr = '['; + rStr += '$'; + if ( bBank ) + rStr += aBankSymbol; + else + { + if ( aSymbol.Search( '-' ) != STRING_NOTFOUND || aSymbol.Search( ']' ) != STRING_NOTFOUND ) + { + rStr += '"'; + rStr += aSymbol; + rStr += '"'; + } + else + rStr += aSymbol; + if ( !bWithoutExtension && eLanguage != LANGUAGE_DONTKNOW && eLanguage != LANGUAGE_SYSTEM ) + { + rStr += '-'; + rStr += String::CreateFromInt32( sal_Int32( eLanguage ), 16 ).ToUpperAscii(); + } + } + rStr += ']'; +} + + +void NfCurrencyEntry::Impl_BuildFormatStringNumChars( String& rStr, + const LocaleDataWrapper& rLoc, USHORT nDecimalFormat ) const +{ + rStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###0" ) ); + rStr.Insert( rLoc.getNumThousandSep(), 1 ); + if ( nDecimalFormat && nDigits ) + { + rStr += rLoc.getNumDecimalSep(); + rStr.Expand( rStr.Len() + nDigits, (nDecimalFormat == 2 ? '-' : cZeroChar) ); + } +} + + +void NfCurrencyEntry::BuildPositiveFormatString( String& rStr, BOOL bBank, + const LocaleDataWrapper& rLoc, USHORT nDecimalFormat ) const +{ + Impl_BuildFormatStringNumChars( rStr, rLoc, nDecimalFormat ); + USHORT nPosiForm = NfCurrencyEntry::GetEffectivePositiveFormat( + rLoc.getCurrPositiveFormat(), nPositiveFormat, bBank ); + CompletePositiveFormatString( rStr, bBank, nPosiForm ); +} + + +void NfCurrencyEntry::BuildNegativeFormatString( String& rStr, BOOL bBank, + const LocaleDataWrapper& rLoc, USHORT nDecimalFormat ) const +{ + Impl_BuildFormatStringNumChars( rStr, rLoc, nDecimalFormat ); + USHORT nNegaForm = NfCurrencyEntry::GetEffectiveNegativeFormat( + rLoc.getCurrNegativeFormat(), nNegativeFormat, bBank ); + CompleteNegativeFormatString( rStr, bBank, nNegaForm ); +} + + +void NfCurrencyEntry::CompletePositiveFormatString( String& rStr, BOOL bBank, + USHORT nPosiForm ) const +{ + String aSymStr; + BuildSymbolString( aSymStr, bBank ); + NfCurrencyEntry::CompletePositiveFormatString( rStr, aSymStr, nPosiForm ); +} + + +void NfCurrencyEntry::CompleteNegativeFormatString( String& rStr, BOOL bBank, + USHORT nNegaForm ) const +{ + String aSymStr; + BuildSymbolString( aSymStr, bBank ); + NfCurrencyEntry::CompleteNegativeFormatString( rStr, aSymStr, nNegaForm ); +} + + +// static +void NfCurrencyEntry::CompletePositiveFormatString( String& rStr, + const String& rSymStr, USHORT nPositiveFormat ) +{ + switch( nPositiveFormat ) + { + case 0: // $1 + rStr.Insert( rSymStr , 0 ); + break; + case 1: // 1$ + rStr += rSymStr; + break; + case 2: // $ 1 + { + rStr.Insert( ' ', 0 ); + rStr.Insert( rSymStr, 0 ); + } + break; + case 3: // 1 $ + { + rStr += ' '; + rStr += rSymStr; + } + break; + default: + DBG_ERROR("NfCurrencyEntry::CompletePositiveFormatString: unknown option"); + break; + } +} + + +// static +void NfCurrencyEntry::CompleteNegativeFormatString( String& rStr, + const String& rSymStr, USHORT nNegativeFormat ) +{ + switch( nNegativeFormat ) + { + case 0: // ($1) + { + rStr.Insert( rSymStr, 0); + rStr.Insert('(',0); + rStr += ')'; + } + break; + case 1: // -$1 + { + rStr.Insert( rSymStr, 0); + rStr.Insert('-',0); + } + break; + case 2: // $-1 + { + rStr.Insert('-',0); + rStr.Insert( rSymStr, 0); + } + break; + case 3: // $1- + { + rStr.Insert( rSymStr, 0); + rStr += '-'; + } + break; + case 4: // (1$) + { + rStr.Insert('(',0); + rStr += rSymStr; + rStr += ')'; + } + break; + case 5: // -1$ + { + rStr += rSymStr; + rStr.Insert('-',0); + } + break; + case 6: // 1-$ + { + rStr += '-'; + rStr += rSymStr; + } + break; + case 7: // 1$- + { + rStr += rSymStr; + rStr += '-'; + } + break; + case 8: // -1 $ + { + rStr += ' '; + rStr += rSymStr; + rStr.Insert('-',0); + } + break; + case 9: // -$ 1 + { + rStr.Insert(' ',0); + rStr.Insert( rSymStr, 0); + rStr.Insert('-',0); + } + break; + case 10: // 1 $- + { + rStr += ' '; + rStr += rSymStr; + rStr += '-'; + } + break; + case 11: // $ -1 + { + String aTmp( rSymStr ); + aTmp += ' '; + aTmp += '-'; + rStr.Insert( aTmp, 0 ); + } + break; + case 12 : // $ 1- + { + rStr.Insert(' ', 0); + rStr.Insert( rSymStr, 0); + rStr += '-'; + } + break; + case 13 : // 1- $ + { + rStr += '-'; + rStr += ' '; + rStr += rSymStr; + } + break; + case 14 : // ($ 1) + { + rStr.Insert(' ',0); + rStr.Insert( rSymStr, 0); + rStr.Insert('(',0); + rStr += ')'; + } + break; + case 15 : // (1 $) + { + rStr.Insert('(',0); + rStr += ' '; + rStr += rSymStr; + rStr += ')'; + } + break; + default: + DBG_ERROR("NfCurrencyEntry::CompleteNegativeFormatString: unknown option"); + break; + } +} + + +// static +USHORT NfCurrencyEntry::GetEffectivePositiveFormat( USHORT +#if ! NF_BANKSYMBOL_FIX_POSITION + nIntlFormat +#endif + , USHORT nCurrFormat, BOOL bBank ) +{ + if ( bBank ) + { +#if NF_BANKSYMBOL_FIX_POSITION + return 3; +#else + switch ( nIntlFormat ) + { + case 0: // $1 + nIntlFormat = 2; // $ 1 + break; + case 1: // 1$ + nIntlFormat = 3; // 1 $ + break; + case 2: // $ 1 + break; + case 3: // 1 $ + break; + default: + DBG_ERROR("NfCurrencyEntry::GetEffectivePositiveFormat: unknown option"); + break; + } + return nIntlFormat; +#endif + } + else + return nCurrFormat; +} + + +// nur aufrufen, wenn nCurrFormat wirklich mit Klammern ist +USHORT lcl_MergeNegativeParenthesisFormat( USHORT nIntlFormat, USHORT nCurrFormat ) +{ + short nSign = 0; // -1:=Klammer 0:=links, 1:=mitte, 2:=rechts + switch ( nIntlFormat ) + { + case 0: // ($1) + case 4: // (1$) + case 14 : // ($ 1) + case 15 : // (1 $) + return nCurrFormat; + case 1: // -$1 + case 5: // -1$ + case 8: // -1 $ + case 9: // -$ 1 + nSign = 0; + break; + case 2: // $-1 + case 6: // 1-$ + case 11 : // $ -1 + case 13 : // 1- $ + nSign = 1; + break; + case 3: // $1- + case 7: // 1$- + case 10: // 1 $- + case 12 : // $ 1- + nSign = 2; + break; + default: + DBG_ERROR("lcl_MergeNegativeParenthesisFormat: unknown option"); + break; + } + + switch ( nCurrFormat ) + { + case 0: // ($1) + switch ( nSign ) + { + case 0: + return 1; // -$1 + case 1: + return 2; // $-1 + case 2: + return 3; // $1- + } + break; + case 4: // (1$) + switch ( nSign ) + { + case 0: + return 5; // -1$ + case 1: + return 6; // 1-$ + case 2: + return 7; // 1$- + } + break; + case 14 : // ($ 1) + switch ( nSign ) + { + case 0: + return 9; // -$ 1 + case 1: + return 11; // $ -1 + case 2: + return 12; // $ 1- + } + break; + case 15 : // (1 $) + switch ( nSign ) + { + case 0: + return 8; // -1 $ + case 1: + return 13; // 1- $ + case 2: + return 10; // 1 $- + } + break; + } + return nCurrFormat; +} + + +// static +USHORT NfCurrencyEntry::GetEffectiveNegativeFormat( USHORT nIntlFormat, + USHORT nCurrFormat, BOOL bBank ) +{ + if ( bBank ) + { +#if NF_BANKSYMBOL_FIX_POSITION + return 8; +#else + switch ( nIntlFormat ) + { + case 0: // ($1) +// nIntlFormat = 14; // ($ 1) + nIntlFormat = 9; // -$ 1 + break; + case 1: // -$1 + nIntlFormat = 9; // -$ 1 + break; + case 2: // $-1 + nIntlFormat = 11; // $ -1 + break; + case 3: // $1- + nIntlFormat = 12; // $ 1- + break; + case 4: // (1$) +// nIntlFormat = 15; // (1 $) + nIntlFormat = 8; // -1 $ + break; + case 5: // -1$ + nIntlFormat = 8; // -1 $ + break; + case 6: // 1-$ + nIntlFormat = 13; // 1- $ + break; + case 7: // 1$- + nIntlFormat = 10; // 1 $- + break; + case 8: // -1 $ + break; + case 9: // -$ 1 + break; + case 10: // 1 $- + break; + case 11: // $ -1 + break; + case 12 : // $ 1- + break; + case 13 : // 1- $ + break; + case 14 : // ($ 1) +// nIntlFormat = 14; // ($ 1) + nIntlFormat = 9; // -$ 1 + break; + case 15 : // (1 $) +// nIntlFormat = 15; // (1 $) + nIntlFormat = 8; // -1 $ + break; + default: + DBG_ERROR("NfCurrencyEntry::GetEffectiveNegativeFormat: unknown option"); + break; + } +#endif + } + else if ( nIntlFormat != nCurrFormat ) + { + switch ( nCurrFormat ) + { + case 0: // ($1) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 1: // -$1 + nIntlFormat = nCurrFormat; + break; + case 2: // $-1 + nIntlFormat = nCurrFormat; + break; + case 3: // $1- + nIntlFormat = nCurrFormat; + break; + case 4: // (1$) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 5: // -1$ + nIntlFormat = nCurrFormat; + break; + case 6: // 1-$ + nIntlFormat = nCurrFormat; + break; + case 7: // 1$- + nIntlFormat = nCurrFormat; + break; + case 8: // -1 $ + nIntlFormat = nCurrFormat; + break; + case 9: // -$ 1 + nIntlFormat = nCurrFormat; + break; + case 10: // 1 $- + nIntlFormat = nCurrFormat; + break; + case 11: // $ -1 + nIntlFormat = nCurrFormat; + break; + case 12 : // $ 1- + nIntlFormat = nCurrFormat; + break; + case 13 : // 1- $ + nIntlFormat = nCurrFormat; + break; + case 14 : // ($ 1) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + case 15 : // (1 $) + nIntlFormat = lcl_MergeNegativeParenthesisFormat( + nIntlFormat, nCurrFormat ); + break; + default: + DBG_ERROR("NfCurrencyEntry::GetEffectiveNegativeFormat: unknown option"); + break; + } + } + return nIntlFormat; +} + + +// we only support default encodings here +// static +sal_Char NfCurrencyEntry::GetEuroSymbol( rtl_TextEncoding eTextEncoding ) +{ + switch ( eTextEncoding ) + { + case RTL_TEXTENCODING_MS_1252 : // WNT Ansi + case RTL_TEXTENCODING_ISO_8859_1 : // UNX for use with TrueType fonts + return '\x80'; + case RTL_TEXTENCODING_ISO_8859_15 : // UNX real + return '\xA4'; + case RTL_TEXTENCODING_IBM_850 : // OS2 + return '\xD5'; + case RTL_TEXTENCODING_APPLE_ROMAN : // MAC + return '\xDB'; + default: // default system +#if WNT + return '\x80'; +#elif OS2 + return '\xD5'; +#elif UNX +// return '\xA4'; // #56121# 0xA4 waere korrekt fuer iso-8859-15 + return '\x80'; // aber Windoze-Code fuer die konvertierten TrueType-Fonts +#else +#error EuroSymbol is what? + return '\x80'; +#endif + } + return '\x80'; +} + + + diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx new file mode 100644 index 000000000000..52d37b9cd26f --- /dev/null +++ b/svl/source/numbers/zformat.cxx @@ -0,0 +1,4480 @@ +/************************************************************************* + * + * 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: zformat.cxx,v $ + * $Revision: 1.78.138.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <stdio.h> +#include <ctype.h> +#include <float.h> +// #include <math.h> +#include <errno.h> +#include <stdlib.h> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> +#include <rtl/math.hxx> +#include <rtl/instance.hxx> +#include <unotools/charclass.hxx> +#include <unotools/calendarwrapper.hxx> +#include <unotools/nativenumberwrapper.hxx> +#include <com/sun/star/i18n/CalendarFieldIndex.hpp> +#include <com/sun/star/i18n/CalendarDisplayIndex.hpp> +#include <com/sun/star/i18n/CalendarDisplayCode.hpp> +#include <com/sun/star/i18n/AmPmValue.hpp> + +#define _ZFORMAT_CXX +#include <svl/zformat.hxx> +#include "zforscan.hxx" + +#include "zforfind.hxx" +#include <svl/zforlist.hxx> +#include "numhead.hxx" +#include <unotools/digitgroupingiterator.hxx> +#include "nfsymbol.hxx" +using namespace svt; + +namespace { +struct Gregorian + : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> { + const ::rtl::OUString operator () () { + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("gregorian")); + } +}; +} + +const double _D_MAX_U_LONG_ = (double) 0xffffffff; // 4294967295.0 +const double _D_MAX_LONG_ = (double) 0x7fffffff; // 2147483647.0 +const USHORT _MAX_FRACTION_PREC = 3; +const double D_EPS = 1.0E-2; + +const double _D_MAX_D_BY_100 = 1.7E306; +const double _D_MIN_M_BY_1000 = 2.3E-305; + +static BYTE cCharWidths[ 128-32 ] = { + 1,1,1,2,2,3,2,1,1,1,1,2,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,1,1,2,2,2,2, + 3,2,2,2,2,2,2,3,2,1,2,2,2,3,3,3, + 2,3,2,2,2,2,2,3,2,2,2,1,1,1,2,2, + 1,2,2,2,2,2,1,2,2,1,1,2,1,3,2,2, + 2,2,1,2,1,2,2,2,2,2,2,1,1,1,2,1 +}; + +// static +xub_StrLen SvNumberformat::InsertBlanks( String& r, xub_StrLen nPos, sal_Unicode c ) +{ + if( c >= 32 ) + { + USHORT n = 2; // Default fuer Zeichen > 128 (HACK!) + if( c <= 127 ) + n = cCharWidths[ c - 32 ]; + while( n-- ) + r.Insert( ' ', nPos++ ); + } + return nPos; +} + +static long GetPrecExp( double fAbsVal ) +{ + DBG_ASSERT( fAbsVal > 0.0, "GetPrecExp: fAbsVal <= 0.0" ); + if ( fAbsVal < 1e-7 || fAbsVal > 1e7 ) + { // die Schere, ob's schneller ist oder nicht, liegt zwischen 1e6 und 1e7 + return (long) floor( log10( fAbsVal ) ) + 1; + } + else + { + long nPrecExp = 1; + while( fAbsVal < 1 ) + { + fAbsVal *= 10; + nPrecExp--; + } + while( fAbsVal >= 10 ) + { + fAbsVal /= 10; + nPrecExp++; + } + return nPrecExp; + } +} + +const USHORT nNewCurrencyVersionId = 0x434E; // "NC" +const sal_Unicode cNewCurrencyMagic = 0x01; // Magic for format code in comment +const USHORT nNewStandardFlagVersionId = 0x4653; // "SF" + +/***********************Funktion SvNumberformatInfo******************************/ + +void ImpSvNumberformatInfo::Copy( const ImpSvNumberformatInfo& rNumFor, USHORT nAnz ) +{ + for (USHORT i = 0; i < nAnz; i++) + { + sStrArray[i] = rNumFor.sStrArray[i]; + nTypeArray[i] = rNumFor.nTypeArray[i]; + } + eScannedType = rNumFor.eScannedType; + bThousand = rNumFor.bThousand; + nThousand = rNumFor.nThousand; + nCntPre = rNumFor.nCntPre; + nCntPost = rNumFor.nCntPost; + nCntExp = rNumFor.nCntExp; +} + +void ImpSvNumberformatInfo::Save(SvStream& rStream, USHORT nAnz) const +{ + for (USHORT i = 0; i < nAnz; i++) + { + rStream.WriteByteString( sStrArray[i], rStream.GetStreamCharSet() ); + short nType = nTypeArray[i]; + switch ( nType ) + { // der Krampf fuer Versionen vor SV_NUMBERFORMATTER_VERSION_NEW_CURR + case NF_SYMBOLTYPE_CURRENCY : + rStream << short( NF_SYMBOLTYPE_STRING ); + break; + case NF_SYMBOLTYPE_CURRDEL : + case NF_SYMBOLTYPE_CURREXT : + rStream << short(0); // werden ignoriert (hoffentlich..) + break; + default: + if ( nType > NF_KEY_LASTKEYWORD_SO5 ) + rStream << short( NF_SYMBOLTYPE_STRING ); // all new keywords are string + else + rStream << nType; + } + + } + rStream << eScannedType << bThousand << nThousand + << nCntPre << nCntPost << nCntExp; +} + +void ImpSvNumberformatInfo::Load(SvStream& rStream, USHORT nAnz) +{ + for (USHORT i = 0; i < nAnz; i++) + { + SvNumberformat::LoadString( rStream, sStrArray[i] ); + rStream >> nTypeArray[i]; + } + rStream >> eScannedType >> bThousand >> nThousand + >> nCntPre >> nCntPost >> nCntExp; +} + + +//============================================================================ + +// static +BYTE SvNumberNatNum::MapDBNumToNatNum( BYTE nDBNum, LanguageType eLang, BOOL bDate ) +{ + BYTE nNatNum = 0; + eLang = MsLangId::getRealLanguage( eLang ); // resolve SYSTEM etc. + eLang &= 0x03FF; // 10 bit primary language + if ( bDate ) + { + if ( nDBNum == 4 && eLang == LANGUAGE_KOREAN ) + nNatNum = 9; + else if ( nDBNum <= 3 ) + nNatNum = nDBNum; // known to be good for: zh,ja,ko / 1,2,3 + } + else + { + switch ( nDBNum ) + { + case 1: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 4; break; + case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 1; break; + case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 1; break; + } + break; + case 2: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 5; break; + case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 4; break; + case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 2; break; + } + break; + case 3: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nNatNum = 6; break; + case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 5; break; + case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 3; break; + } + break; + case 4: + switch ( eLang ) + { + case (LANGUAGE_JAPANESE & 0x03FF) : nNatNum = 7; break; + case (LANGUAGE_KOREAN & 0x03FF) : nNatNum = 9; break; + } + break; + } + } + return nNatNum; +} + + +// static +BYTE SvNumberNatNum::MapNatNumToDBNum( BYTE nNatNum, LanguageType eLang, BOOL bDate ) +{ + BYTE nDBNum = 0; + eLang = MsLangId::getRealLanguage( eLang ); // resolve SYSTEM etc. + eLang &= 0x03FF; // 10 bit primary language + if ( bDate ) + { + if ( nNatNum == 9 && eLang == LANGUAGE_KOREAN ) + nDBNum = 4; + else if ( nNatNum <= 3 ) + nDBNum = nNatNum; // known to be good for: zh,ja,ko / 1,2,3 + } + else + { + switch ( nNatNum ) + { + case 1: + switch ( eLang ) + { + case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 1; break; + case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 1; break; + } + break; + case 2: + switch ( eLang ) + { + case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 2; break; + } + break; + case 3: + switch ( eLang ) + { + case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 3; break; + } + break; + case 4: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 1; break; + case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 2; break; + } + break; + case 5: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 2; break; + case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 3; break; + } + break; + case 6: + switch ( eLang ) + { + case (LANGUAGE_CHINESE & 0x03FF) : nDBNum = 3; break; + } + break; + case 7: + switch ( eLang ) + { + case (LANGUAGE_JAPANESE & 0x03FF) : nDBNum = 4; break; + } + break; + case 8: + break; + case 9: + switch ( eLang ) + { + case (LANGUAGE_KOREAN & 0x03FF) : nDBNum = 4; break; + } + break; + case 10: + break; + case 11: + break; + } + } + return nDBNum; +} + +/***********************Funktionen SvNumFor******************************/ + +ImpSvNumFor::ImpSvNumFor() +{ + nAnzStrings = 0; + aI.nTypeArray = NULL; + aI.sStrArray = NULL; + aI.eScannedType = NUMBERFORMAT_UNDEFINED; + aI.bThousand = FALSE; + aI.nThousand = 0; + aI.nCntPre = 0; + aI.nCntPost = 0; + aI.nCntExp = 0; + pColor = NULL; +} + +ImpSvNumFor::~ImpSvNumFor() +{ + for (USHORT i = 0; i < nAnzStrings; i++) + aI.sStrArray[i].Erase(); + delete [] aI.sStrArray; + delete [] aI.nTypeArray; +} + +void ImpSvNumFor::Enlarge(USHORT nAnz) +{ + if ( nAnzStrings != nAnz ) + { + if ( aI.nTypeArray ) + delete [] aI.nTypeArray; + if ( aI.sStrArray ) + delete [] aI.sStrArray; + nAnzStrings = nAnz; + if ( nAnz ) + { + aI.nTypeArray = new short[nAnz]; + aI.sStrArray = new String[nAnz]; + } + else + { + aI.nTypeArray = NULL; + aI.sStrArray = NULL; + } + } +} + +void ImpSvNumFor::Copy( const ImpSvNumFor& rNumFor, ImpSvNumberformatScan* pSc ) +{ + Enlarge( rNumFor.nAnzStrings ); + aI.Copy( rNumFor.aI, nAnzStrings ); + sColorName = rNumFor.sColorName; + if ( pSc ) + pColor = pSc->GetColor( sColorName ); // #121103# don't copy pointer between documents + else + pColor = rNumFor.pColor; + aNatNum = rNumFor.aNatNum; +} + +void ImpSvNumFor::Save(SvStream& rStream) const +{ + rStream << nAnzStrings; + aI.Save(rStream, nAnzStrings); + rStream.WriteByteString( sColorName, rStream.GetStreamCharSet() ); +} + +void ImpSvNumFor::Load(SvStream& rStream, ImpSvNumberformatScan& rSc, + String& rLoadedColorName ) +{ + USHORT nAnz; + rStream >> nAnz; //! noch nicht direkt nAnzStrings wg. Enlarge + Enlarge( nAnz ); + aI.Load( rStream, nAnz ); + rStream.ReadByteString( sColorName, rStream.GetStreamCharSet() ); + rLoadedColorName = sColorName; + pColor = rSc.GetColor(sColorName); +} + + +BOOL ImpSvNumFor::HasNewCurrency() const +{ + for ( USHORT j=0; j<nAnzStrings; j++ ) + { + if ( aI.nTypeArray[j] == NF_SYMBOLTYPE_CURRENCY ) + return TRUE; + } + return FALSE; +} + + +BOOL ImpSvNumFor::GetNewCurrencySymbol( String& rSymbol, + String& rExtension ) const +{ + for ( USHORT j=0; j<nAnzStrings; j++ ) + { + if ( aI.nTypeArray[j] == NF_SYMBOLTYPE_CURRENCY ) + { + rSymbol = aI.sStrArray[j]; + if ( j < nAnzStrings-1 && aI.nTypeArray[j+1] == NF_SYMBOLTYPE_CURREXT ) + rExtension = aI.sStrArray[j+1]; + else + rExtension.Erase(); + return TRUE; + } + } + //! kein Erase an rSymbol, rExtension + return FALSE; +} + + +void ImpSvNumFor::SaveNewCurrencyMap( SvStream& rStream ) const +{ + USHORT j; + USHORT nCnt = 0; + for ( j=0; j<nAnzStrings; j++ ) + { + switch ( aI.nTypeArray[j] ) + { + case NF_SYMBOLTYPE_CURRENCY : + case NF_SYMBOLTYPE_CURRDEL : + case NF_SYMBOLTYPE_CURREXT : + nCnt++; + break; + } + } + rStream << nCnt; + for ( j=0; j<nAnzStrings; j++ ) + { + switch ( aI.nTypeArray[j] ) + { + case NF_SYMBOLTYPE_CURRENCY : + case NF_SYMBOLTYPE_CURRDEL : + case NF_SYMBOLTYPE_CURREXT : + rStream << j << aI.nTypeArray[j]; + break; + } + } +} + + +void ImpSvNumFor::LoadNewCurrencyMap( SvStream& rStream ) +{ + USHORT nCnt; + rStream >> nCnt; + for ( USHORT j=0; j<nCnt; j++ ) + { + USHORT nPos; + short nType; + rStream >> nPos >> nType; + if ( nPos < nAnzStrings ) + aI.nTypeArray[nPos] = nType; + } +} + + +/***********************Funktionen SvNumberformat************************/ + +enum BracketFormatSymbolType +{ + BRACKET_SYMBOLTYPE_FORMAT = -1, // subformat string + BRACKET_SYMBOLTYPE_COLOR = -2, // color + BRACKET_SYMBOLTYPE_ERROR = -3, // error + BRACKET_SYMBOLTYPE_DBNUM1 = -4, // DoubleByteNumber, represent numbers + BRACKET_SYMBOLTYPE_DBNUM2 = -5, // using CJK characters, Excel compatible. + BRACKET_SYMBOLTYPE_DBNUM3 = -6, + BRACKET_SYMBOLTYPE_DBNUM4 = -7, + BRACKET_SYMBOLTYPE_DBNUM5 = -8, + BRACKET_SYMBOLTYPE_DBNUM6 = -9, + BRACKET_SYMBOLTYPE_DBNUM7 = -10, + BRACKET_SYMBOLTYPE_DBNUM8 = -11, + BRACKET_SYMBOLTYPE_DBNUM9 = -12, + BRACKET_SYMBOLTYPE_LOCALE = -13, + BRACKET_SYMBOLTYPE_NATNUM0 = -14, // Our NativeNumber support, ASCII + BRACKET_SYMBOLTYPE_NATNUM1 = -15, // Our NativeNumber support, represent + BRACKET_SYMBOLTYPE_NATNUM2 = -16, // numbers using CJK, CTL, ... + BRACKET_SYMBOLTYPE_NATNUM3 = -17, + BRACKET_SYMBOLTYPE_NATNUM4 = -18, + BRACKET_SYMBOLTYPE_NATNUM5 = -19, + BRACKET_SYMBOLTYPE_NATNUM6 = -20, + BRACKET_SYMBOLTYPE_NATNUM7 = -21, + BRACKET_SYMBOLTYPE_NATNUM8 = -22, + BRACKET_SYMBOLTYPE_NATNUM9 = -23, + BRACKET_SYMBOLTYPE_NATNUM10 = -24, + BRACKET_SYMBOLTYPE_NATNUM11 = -25, + BRACKET_SYMBOLTYPE_NATNUM12 = -26, + BRACKET_SYMBOLTYPE_NATNUM13 = -27, + BRACKET_SYMBOLTYPE_NATNUM14 = -28, + BRACKET_SYMBOLTYPE_NATNUM15 = -29, + BRACKET_SYMBOLTYPE_NATNUM16 = -30, + BRACKET_SYMBOLTYPE_NATNUM17 = -31, + BRACKET_SYMBOLTYPE_NATNUM18 = -32, + BRACKET_SYMBOLTYPE_NATNUM19 = -33 +}; + +SvNumberformat::SvNumberformat( ImpSvNumberformatScan& rSc, LanguageType eLge ) + : + rScan(rSc), + eLnge(eLge), + nNewStandardDefined(0), + bStarFlag( FALSE ) +{ +} + +void SvNumberformat::ImpCopyNumberformat( const SvNumberformat& rFormat ) +{ + sFormatstring = rFormat.sFormatstring; + eType = rFormat.eType; + eLnge = rFormat.eLnge; + fLimit1 = rFormat.fLimit1; + fLimit2 = rFormat.fLimit2; + eOp1 = rFormat.eOp1; + eOp2 = rFormat.eOp2; + bStandard = rFormat.bStandard; + bIsUsed = rFormat.bIsUsed; + sComment = rFormat.sComment; + nNewStandardDefined = rFormat.nNewStandardDefined; + + // #121103# when copying between documents, get color pointers from own scanner + ImpSvNumberformatScan* pColorSc = ( &rScan != &rFormat.rScan ) ? &rScan : NULL; + + for (USHORT i = 0; i < 4; i++) + NumFor[i].Copy(rFormat.NumFor[i], pColorSc); +} + +SvNumberformat::SvNumberformat( SvNumberformat& rFormat ) + : rScan(rFormat.rScan), bStarFlag( rFormat.bStarFlag ) +{ + ImpCopyNumberformat( rFormat ); +} + +SvNumberformat::SvNumberformat( SvNumberformat& rFormat, ImpSvNumberformatScan& rSc ) + : rScan(rSc), bStarFlag( rFormat.bStarFlag ) +{ + ImpCopyNumberformat( rFormat ); +} + + +BOOL lcl_SvNumberformat_IsBracketedPrefix( short nSymbolType ) +{ + if ( nSymbolType > 0 ) + return TRUE; // conditions + switch ( nSymbolType ) + { + case BRACKET_SYMBOLTYPE_COLOR : + case BRACKET_SYMBOLTYPE_DBNUM1 : + case BRACKET_SYMBOLTYPE_DBNUM2 : + case BRACKET_SYMBOLTYPE_DBNUM3 : + case BRACKET_SYMBOLTYPE_DBNUM4 : + case BRACKET_SYMBOLTYPE_DBNUM5 : + case BRACKET_SYMBOLTYPE_DBNUM6 : + case BRACKET_SYMBOLTYPE_DBNUM7 : + case BRACKET_SYMBOLTYPE_DBNUM8 : + case BRACKET_SYMBOLTYPE_DBNUM9 : + case BRACKET_SYMBOLTYPE_LOCALE : + case BRACKET_SYMBOLTYPE_NATNUM0 : + case BRACKET_SYMBOLTYPE_NATNUM1 : + case BRACKET_SYMBOLTYPE_NATNUM2 : + case BRACKET_SYMBOLTYPE_NATNUM3 : + case BRACKET_SYMBOLTYPE_NATNUM4 : + case BRACKET_SYMBOLTYPE_NATNUM5 : + case BRACKET_SYMBOLTYPE_NATNUM6 : + case BRACKET_SYMBOLTYPE_NATNUM7 : + case BRACKET_SYMBOLTYPE_NATNUM8 : + case BRACKET_SYMBOLTYPE_NATNUM9 : + case BRACKET_SYMBOLTYPE_NATNUM10 : + case BRACKET_SYMBOLTYPE_NATNUM11 : + case BRACKET_SYMBOLTYPE_NATNUM12 : + case BRACKET_SYMBOLTYPE_NATNUM13 : + case BRACKET_SYMBOLTYPE_NATNUM14 : + case BRACKET_SYMBOLTYPE_NATNUM15 : + case BRACKET_SYMBOLTYPE_NATNUM16 : + case BRACKET_SYMBOLTYPE_NATNUM17 : + case BRACKET_SYMBOLTYPE_NATNUM18 : + case BRACKET_SYMBOLTYPE_NATNUM19 : + return TRUE; + } + return FALSE; +} + + +SvNumberformat::SvNumberformat(String& rString, + ImpSvNumberformatScan* pSc, + ImpSvNumberInputScan* pISc, + xub_StrLen& nCheckPos, + LanguageType& eLan, + BOOL bStan) + : + rScan(*pSc), + nNewStandardDefined(0), + bStarFlag( FALSE ) +{ + // If the group (AKA thousand) separator is a Non-Breaking Space (French) + // replace all occurences by a simple space. + // The tokens will be changed to the LocaleData separator again later on. + const sal_Unicode cNBSp = 0xA0; + const String& rThSep = GetFormatter().GetNumThousandSep(); + if ( rThSep.GetChar(0) == cNBSp && rThSep.Len() == 1 ) + { + xub_StrLen nIndex = 0; + do + nIndex = rString.SearchAndReplace( cNBSp, ' ', nIndex ); + while ( nIndex != STRING_NOTFOUND ); + } + + if (rScan.GetConvertMode()) + { + eLnge = rScan.GetNewLnge(); + eLan = eLnge; // Wechsel auch zurueckgeben + } + else + eLnge = eLan; + bStandard = bStan; + bIsUsed = FALSE; + fLimit1 = 0.0; + fLimit2 = 0.0; + eOp1 = NUMBERFORMAT_OP_NO; + eOp2 = NUMBERFORMAT_OP_NO; + eType = NUMBERFORMAT_DEFINED; + + BOOL bCancel = FALSE; + BOOL bCondition = FALSE; + short eSymbolType; + xub_StrLen nPos = 0; + xub_StrLen nPosOld; + nCheckPos = 0; + String aComment; + + // Split into 4 sub formats + USHORT nIndex; + for ( nIndex = 0; nIndex < 4 && !bCancel; nIndex++ ) + { + // Original language/country may have to be reestablished + if (rScan.GetConvertMode()) + (rScan.GetNumberformatter())->ChangeIntl(rScan.GetTmpLnge()); + + String sStr; + nPosOld = nPos; // Start position of substring + // first get bracketed prefixes; e.g. conditions, color + do + { + eSymbolType = ImpNextSymbol(rString, nPos, sStr); + if (eSymbolType > 0) // condition + { + if ( nIndex == 0 && !bCondition ) + { + bCondition = TRUE; + eOp1 = (SvNumberformatLimitOps) eSymbolType; + } + else if ( nIndex == 1 && bCondition ) + eOp2 = (SvNumberformatLimitOps) eSymbolType; + else // error + { + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + if (!bCancel) + { + double fNumber; + xub_StrLen nAnzChars = ImpGetNumber(rString, nPos, sStr); + if (nAnzChars > 0) + { + short F_Type; + if (!pISc->IsNumberFormat(sStr,F_Type,fNumber) || + ( F_Type != NUMBERFORMAT_NUMBER && + F_Type != NUMBERFORMAT_SCIENTIFIC) ) + { + fNumber = 0.0; + nPos = nPos - nAnzChars; + rString.Erase(nPos, nAnzChars); + rString.Insert('0',nPos); + nPos++; + } + } + else + { + fNumber = 0.0; + rString.Insert('0',nPos++); + } + if (nIndex == 0) + fLimit1 = fNumber; + else + fLimit2 = fNumber; + if ( rString.GetChar(nPos) == ']' ) + nPos++; + else + { + bCancel = TRUE; // break for + nCheckPos = nPos; + } + } + nPosOld = nPos; // position before string + } + else if ( lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ) + { + switch ( eSymbolType ) + { + case BRACKET_SYMBOLTYPE_COLOR : + { + if ( NumFor[nIndex].GetColor() != NULL ) + { // error, more than one color + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + else + { + Color* pColor = pSc->GetColor( sStr); + NumFor[nIndex].SetColor( pColor, sStr); + if (pColor == NULL) + { // error + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + } + } + break; + case BRACKET_SYMBOLTYPE_NATNUM0 : + case BRACKET_SYMBOLTYPE_NATNUM1 : + case BRACKET_SYMBOLTYPE_NATNUM2 : + case BRACKET_SYMBOLTYPE_NATNUM3 : + case BRACKET_SYMBOLTYPE_NATNUM4 : + case BRACKET_SYMBOLTYPE_NATNUM5 : + case BRACKET_SYMBOLTYPE_NATNUM6 : + case BRACKET_SYMBOLTYPE_NATNUM7 : + case BRACKET_SYMBOLTYPE_NATNUM8 : + case BRACKET_SYMBOLTYPE_NATNUM9 : + case BRACKET_SYMBOLTYPE_NATNUM10 : + case BRACKET_SYMBOLTYPE_NATNUM11 : + case BRACKET_SYMBOLTYPE_NATNUM12 : + case BRACKET_SYMBOLTYPE_NATNUM13 : + case BRACKET_SYMBOLTYPE_NATNUM14 : + case BRACKET_SYMBOLTYPE_NATNUM15 : + case BRACKET_SYMBOLTYPE_NATNUM16 : + case BRACKET_SYMBOLTYPE_NATNUM17 : + case BRACKET_SYMBOLTYPE_NATNUM18 : + case BRACKET_SYMBOLTYPE_NATNUM19 : + { + if ( NumFor[nIndex].GetNatNum().IsSet() ) + { + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + else + { + sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NatNum" ) ); + //! eSymbolType is negative + BYTE nNum = sal::static_int_cast< BYTE >(0 - (eSymbolType - BRACKET_SYMBOLTYPE_NATNUM0)); + sStr += String::CreateFromInt32( nNum ); + NumFor[nIndex].SetNatNumNum( nNum, FALSE ); + } + } + break; + case BRACKET_SYMBOLTYPE_DBNUM1 : + case BRACKET_SYMBOLTYPE_DBNUM2 : + case BRACKET_SYMBOLTYPE_DBNUM3 : + case BRACKET_SYMBOLTYPE_DBNUM4 : + case BRACKET_SYMBOLTYPE_DBNUM5 : + case BRACKET_SYMBOLTYPE_DBNUM6 : + case BRACKET_SYMBOLTYPE_DBNUM7 : + case BRACKET_SYMBOLTYPE_DBNUM8 : + case BRACKET_SYMBOLTYPE_DBNUM9 : + { + if ( NumFor[nIndex].GetNatNum().IsSet() ) + { + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + else + { + sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DBNum" ) ); + //! eSymbolType is negative + BYTE nNum = sal::static_int_cast< BYTE >(1 - (eSymbolType - BRACKET_SYMBOLTYPE_DBNUM1)); + sStr += static_cast< sal_Unicode >('0' + nNum); + NumFor[nIndex].SetNatNumNum( nNum, TRUE ); + } + } + break; + case BRACKET_SYMBOLTYPE_LOCALE : + { + if ( NumFor[nIndex].GetNatNum().GetLang() != LANGUAGE_DONTKNOW ) + { + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + else + { + xub_StrLen nTmp = 2; + LanguageType eLang = ImpGetLanguageType( sStr, nTmp ); + if ( eLang == LANGUAGE_DONTKNOW ) + { + bCancel = TRUE; // break for + nCheckPos = nPosOld; + } + else + { + sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "$-" ) ); + sStr += String::CreateFromInt32( sal_Int32( eLang ), 16 ).ToUpperAscii(); + NumFor[nIndex].SetNatNumLang( eLang ); + } + } + } + break; + } + if ( !bCancel ) + { + rString.Erase(nPosOld,nPos-nPosOld); + rString.Insert(sStr,nPosOld); + nPos = nPosOld + sStr.Len(); + rString.Insert(']', nPos); + rString.Insert('[', nPosOld); + nPos += 2; + nPosOld = nPos; // position before string + } + } + } while ( !bCancel && lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ); + + // The remaining format code string + if ( !bCancel ) + { + if (eSymbolType == BRACKET_SYMBOLTYPE_FORMAT) + { + if (nIndex == 1 && eOp1 == NUMBERFORMAT_OP_NO) + eOp1 = NUMBERFORMAT_OP_GT; // undefined condition, default: > 0 + else if (nIndex == 2 && eOp2 == NUMBERFORMAT_OP_NO) + eOp2 = NUMBERFORMAT_OP_LT; // undefined condition, default: < 0 + if (sStr.Len() == 0) + { // empty sub format + } + else + { + xub_StrLen nStrPos = pSc->ScanFormat( sStr, aComment ); + USHORT nAnz = pSc->GetAnzResStrings(); + if (nAnz == 0) // error + nStrPos = 1; + if (nStrPos == 0) // ok + { + // e.g. Thai T speciality + if (pSc->GetNatNumModifier() && !NumFor[nIndex].GetNatNum().IsSet()) + { + String aNat( RTL_CONSTASCII_USTRINGPARAM( "[NatNum")); + aNat += String::CreateFromInt32( pSc->GetNatNumModifier()); + aNat += ']'; + sStr.Insert( aNat, 0); + NumFor[nIndex].SetNatNumNum( pSc->GetNatNumModifier(), FALSE ); + } + // #i53826# #i42727# For the Thai T speciality we need + // to freeze the locale and immunize it against + // conversions during exports, just in case we want to + // save to Xcl. This disables the feature of being able + // to convert a NatNum to another locale. You can't + // have both. + // FIXME: implement a specialized export conversion + // that works on tokens (have to tokenize all first) + // and doesn't use the format string and + // PutandConvertEntry() to LANGUAGE_ENGLISH_US in + // sc/source/filter/excel/xestyle.cxx + // XclExpNumFmtBuffer::WriteFormatRecord(). + LanguageType eLanguage; + if (NumFor[nIndex].GetNatNum().GetNatNum() == 1 && + ((eLanguage = + MsLangId::getRealLanguage( eLan)) + == LANGUAGE_THAI) && + NumFor[nIndex].GetNatNum().GetLang() == + LANGUAGE_DONTKNOW) + { + String aLID( RTL_CONSTASCII_USTRINGPARAM( "[$-")); + aLID += String::CreateFromInt32( sal_Int32( + eLanguage), 16 ).ToUpperAscii(); + aLID += ']'; + sStr.Insert( aLID, 0); + NumFor[nIndex].SetNatNumLang( eLanguage); + } + rString.Erase(nPosOld,nPos-nPosOld); + rString.Insert(sStr,nPosOld); + nPos = nPosOld + sStr.Len(); + if (nPos < rString.Len()) + { + rString.Insert(';',nPos); + nPos++; + } + NumFor[nIndex].Enlarge(nAnz); + pSc->CopyInfo(&(NumFor[nIndex].Info()), nAnz); + // type check + if (nIndex == 0) + eType = (short) NumFor[nIndex].Info().eScannedType; + else if (nIndex == 3) + { // #77026# Everything recognized IS text + NumFor[nIndex].Info().eScannedType = NUMBERFORMAT_TEXT; + } + else if ( (short) NumFor[nIndex].Info().eScannedType != + eType) + eType = NUMBERFORMAT_DEFINED; + } + else + { + nCheckPos = nPosOld + nStrPos; // error in string + bCancel = TRUE; // break for + } + } + } + else if (eSymbolType == BRACKET_SYMBOLTYPE_ERROR) // error + { + nCheckPos = nPosOld; + bCancel = TRUE; + } + else if ( lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ) + { + nCheckPos = nPosOld+1; // error, prefix in string + bCancel = TRUE; // break for + } + } + if ( bCancel && !nCheckPos ) + nCheckPos = 1; // nCheckPos is used as an error condition + if ( !bCancel ) + { + if ( NumFor[nIndex].GetNatNum().IsSet() && + NumFor[nIndex].GetNatNum().GetLang() == LANGUAGE_DONTKNOW ) + NumFor[nIndex].SetNatNumLang( eLan ); + } + if (rString.Len() == nPos) + { + if ( nIndex == 2 && eSymbolType == BRACKET_SYMBOLTYPE_FORMAT && + rString.GetChar(nPos-1) == ';' ) + { // #83510# A 4th subformat explicitly specified to be empty + // hides any text. Need the type here for HasTextFormat() + NumFor[3].Info().eScannedType = NUMBERFORMAT_TEXT; + } + bCancel = TRUE; + } + if ( NumFor[nIndex].GetNatNum().IsSet() ) + NumFor[nIndex].SetNatNumDate( + (NumFor[nIndex].Info().eScannedType & NUMBERFORMAT_DATE) != 0 ); + } + + if ( bCondition && !nCheckPos ) + { + if ( nIndex == 1 && NumFor[0].GetnAnz() == 0 && + rString.GetChar(rString.Len()-1) != ';' ) + { // No format code => GENERAL but not if specified empty + String aAdd( pSc->GetStandardName() ); + String aTmp; + if ( !pSc->ScanFormat( aAdd, aTmp ) ) + { + USHORT nAnz = pSc->GetAnzResStrings(); + if ( nAnz ) + { + NumFor[0].Enlarge(nAnz); + pSc->CopyInfo( &(NumFor[0].Info()), nAnz ); + rString += aAdd; + } + } + } + else if ( nIndex == 1 && NumFor[nIndex].GetnAnz() == 0 && + rString.GetChar(rString.Len()-1) != ';' && + (NumFor[0].GetnAnz() > 1 || (NumFor[0].GetnAnz() == 1 && + NumFor[0].Info().nTypeArray[0] != NF_KEY_GENERAL)) ) + { // No trailing second subformat => GENERAL but not if specified empty + // and not if first subformat is GENERAL + String aAdd( pSc->GetStandardName() ); + String aTmp; + if ( !pSc->ScanFormat( aAdd, aTmp ) ) + { + USHORT nAnz = pSc->GetAnzResStrings(); + if ( nAnz ) + { + NumFor[nIndex].Enlarge(nAnz); + pSc->CopyInfo( &(NumFor[nIndex].Info()), nAnz ); + rString += ';'; + rString += aAdd; + } + } + } + else if ( nIndex == 2 && NumFor[nIndex].GetnAnz() == 0 && + rString.GetChar(rString.Len()-1) != ';' && + eOp2 != NUMBERFORMAT_OP_NO ) + { // No trailing third subformat => GENERAL but not if specified empty + String aAdd( pSc->GetStandardName() ); + String aTmp; + if ( !pSc->ScanFormat( aAdd, aTmp ) ) + { + USHORT nAnz = pSc->GetAnzResStrings(); + if ( nAnz ) + { + NumFor[nIndex].Enlarge(nAnz); + pSc->CopyInfo( &(NumFor[nIndex].Info()), nAnz ); + rString += ';'; + rString += aAdd; + } + } + } + } + sFormatstring = rString; + if ( aComment.Len() ) + { + SetComment( aComment ); // setzt sComment und sFormatstring + rString = sFormatstring; // geaenderten sFormatstring uebernehmen + } + if (NumFor[2].GetnAnz() == 0 && // kein 3. Teilstring + eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_NO && + fLimit1 == 0.0 && fLimit2 == 0.0) + eOp1 = NUMBERFORMAT_OP_GE; // 0 zum ersten Format dazu + +} + +SvNumberformat::~SvNumberformat() +{ +} + +//--------------------------------------------------------------------------- +// Next_Symbol +//--------------------------------------------------------------------------- +// Zerlegt die Eingabe in Symbole fuer die weitere +// Verarbeitung (Turing-Maschine). +//--------------------------------------------------------------------------- +// Ausgangs Zustand = SsStart +//---------------+-------------------+-----------------------+--------------- +// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand +//---------------+-------------------+-----------------------+--------------- +// SsStart | ; | Pos-- | SsGetString +// | [ | Symbol += Zeichen | SsGetBracketed +// | ] | Fehler | SsStop +// | BLANK | | +// | Sonst | Symbol += Zeichen | SsGetString +//---------------+-------------------+-----------------------+--------------- +// SsGetString | ; | | SsStop +// | Sonst | Symbol+=Zeichen | +//---------------+-------------------+-----------------------+--------------- +// SsGetBracketed| <, > = | del [ | +// | | Symbol += Zeichen | SsGetCon +// | BLANK | | +// | h, H, m, M, s, S | Symbol += Zeichen | SsGetTime +// | sonst | del [ | +// | | Symbol += Zeichen | SsGetPrefix +//---------------+-------------------+-----------------------+--------------- +// SsGetTime | ] | Symbol += Zeichen | SsGetString +// | h, H, m, M, s, S | Symbol += Zeichen, * | SsGetString +// | sonst | del [; Symbol+=Zeichen| SsGetPrefix +//---------------+-------------------+-----------------------+--------------- +// SsGetPrefix | ] | | SsStop +// | sonst | Symbol += Zeichen | +//---------------+-------------------+-----------------------+--------------- +// SsGetCon | >, = | Symbol+=Zeichen | +// | ] | | SsStop +// | sonst | Fehler | SsStop +//---------------+-------------------+-----------------------+--------------- +// * : Sonderbedingung + +enum ScanState +{ + SsStop, + SsStart, + SsGetCon, // condition + SsGetString, // format string + SsGetPrefix, // color or NatNumN + SsGetTime, // [HH] for time + SsGetBracketed // any [...] not decided yet +}; + + +// read a string until ']' and delete spaces in input +// static +xub_StrLen SvNumberformat::ImpGetNumber(String& rString, + xub_StrLen& nPos, + String& sSymbol) +{ + xub_StrLen nStartPos = nPos; + sal_Unicode cToken; + xub_StrLen nLen = rString.Len(); + sSymbol.Erase(); + while ( nPos < nLen && ((cToken = rString.GetChar(nPos)) != ']') ) + { + if (cToken == ' ') + { // delete spaces + rString.Erase(nPos,1); + nLen--; + } + else + { + nPos++; + sSymbol += cToken; + } + } + return nPos - nStartPos; +} + + +// static +LanguageType SvNumberformat::ImpGetLanguageType( const String& rString, + xub_StrLen& nPos ) +{ + sal_Int32 nNum = 0; + sal_Unicode cToken = 0; + xub_StrLen nLen = rString.Len(); + while ( nPos < nLen && ((cToken = rString.GetChar(nPos)) != ']') ) + { + if ( '0' <= cToken && cToken <= '9' ) + { + nNum *= 16; + nNum += cToken - '0'; + } + else if ( 'a' <= cToken && cToken <= 'f' ) + { + nNum *= 16; + nNum += cToken - 'a' + 10; + } + else if ( 'A' <= cToken && cToken <= 'F' ) + { + nNum *= 16; + nNum += cToken - 'A' + 10; + } + else + return LANGUAGE_DONTKNOW; + ++nPos; + } + return (nNum && (cToken == ']' || nPos == nLen)) ? (LanguageType)nNum : + LANGUAGE_DONTKNOW; +} + + +short SvNumberformat::ImpNextSymbol(String& rString, + xub_StrLen& nPos, + String& sSymbol) +{ + short eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + sal_Unicode cToken; + sal_Unicode cLetter = ' '; // Zwischenergebnis + xub_StrLen nLen = rString.Len(); + ScanState eState = SsStart; + sSymbol.Erase(); + const String* pKeywords = rScan.GetKeywords(); + while (nPos < nLen && eState != SsStop) + { + cToken = rString.GetChar(nPos); + nPos++; + switch (eState) + { + case SsStart: + { + if (cToken == '[') + { + eState = SsGetBracketed; + sSymbol += cToken; + } + else if (cToken == ';') + { + eState = SsGetString; + nPos--; + eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + } + else if (cToken == ']') + { + eState = SsStop; + eSymbolType = BRACKET_SYMBOLTYPE_ERROR; + } + else if (cToken == ' ') // Skip Blanks + { + rString.Erase(nPos-1,1); + nPos--; + nLen--; + } + else + { + sSymbol += cToken; + eState = SsGetString; + eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + } + } + break; + case SsGetBracketed: + { + switch (cToken) + { + case '<': + case '>': + case '=': + { + sSymbol.EraseAllChars('['); + sSymbol += cToken; + cLetter = cToken; + eState = SsGetCon; + switch (cToken) + { + case '<': eSymbolType = NUMBERFORMAT_OP_LT; break; + case '>': eSymbolType = NUMBERFORMAT_OP_GT; break; + case '=': eSymbolType = NUMBERFORMAT_OP_EQ; break; + default: break; + } + } + break; + case ' ': + { + rString.Erase(nPos-1,1); + nPos--; + nLen--; + } + break; + case '$' : + { + if ( rString.GetChar(nPos) == '-' ) + { // [$-xxx] locale + sSymbol.EraseAllChars('['); + eSymbolType = BRACKET_SYMBOLTYPE_LOCALE; + eState = SsGetPrefix; + } + else + { // currency as of SV_NUMBERFORMATTER_VERSION_NEW_CURR + eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + eState = SsGetString; + } + sSymbol += cToken; + } + break; + case '~' : + { // calendarID as of SV_NUMBERFORMATTER_VERSION_CALENDAR + eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + sSymbol += cToken; + eState = SsGetString; + } + break; + default: + { + static const String aNatNum( RTL_CONSTASCII_USTRINGPARAM( "NATNUM" ) ); + static const String aDBNum( RTL_CONSTASCII_USTRINGPARAM( "DBNUM" ) ); + String aUpperNatNum( rChrCls().toUpper( rString, nPos-1, aNatNum.Len() ) ); + String aUpperDBNum( rChrCls().toUpper( rString, nPos-1, aDBNum.Len() ) ); + sal_Unicode cUpper = aUpperNatNum.GetChar(0); + sal_Int32 nNatNumNum = rString.Copy( nPos-1+aNatNum.Len() ).ToInt32(); + sal_Unicode cDBNum = rString.GetChar( nPos-1+aDBNum.Len() ); + if ( aUpperNatNum == aNatNum && 0 <= nNatNumNum && nNatNumNum <= 19 ) + { + sSymbol.EraseAllChars('['); + sSymbol += rString.Copy( --nPos, aNatNum.Len()+1 ); + nPos += aNatNum.Len()+1; + //! SymbolType is negative + eSymbolType = (short) (BRACKET_SYMBOLTYPE_NATNUM0 - nNatNumNum); + eState = SsGetPrefix; + } + else if ( aUpperDBNum == aDBNum && '1' <= cDBNum && cDBNum <= '9' ) + { + sSymbol.EraseAllChars('['); + sSymbol += rString.Copy( --nPos, aDBNum.Len()+1 ); + nPos += aDBNum.Len()+1; + //! SymbolType is negative + eSymbolType = sal::static_int_cast< short >( + BRACKET_SYMBOLTYPE_DBNUM1 - (cDBNum - '1')); + eState = SsGetPrefix; + } + else if (cUpper == pKeywords[NF_KEY_H].GetChar(0) || // H + cUpper == pKeywords[NF_KEY_MI].GetChar(0) || // M + cUpper == pKeywords[NF_KEY_S].GetChar(0) ) // S + { + sSymbol += cToken; + eState = SsGetTime; + cLetter = cToken; + } + else + { + sSymbol.EraseAllChars('['); + sSymbol += cToken; + eSymbolType = BRACKET_SYMBOLTYPE_COLOR; + eState = SsGetPrefix; + } + } + break; + } + } + break; + case SsGetString: + { + if (cToken == ';') + eState = SsStop; + else + sSymbol += cToken; + } + break; + case SsGetTime: + { + if (cToken == ']') + { + sSymbol += cToken; + eState = SsGetString; + eSymbolType = BRACKET_SYMBOLTYPE_FORMAT; + } + else + { + sal_Unicode cUpper = rChrCls().toUpper( rString, nPos-1, 1 ).GetChar(0); + if (cUpper == pKeywords[NF_KEY_H].GetChar(0) || // H + cUpper == pKeywords[NF_KEY_MI].GetChar(0) || // M + cUpper == pKeywords[NF_KEY_S].GetChar(0) ) // S + { + if (cLetter == cToken) + { + sSymbol += cToken; + cLetter = ' '; + } + else + { + sSymbol.EraseAllChars('['); + sSymbol += cToken; + eState = SsGetPrefix; + } + } + else + { + sSymbol.EraseAllChars('['); + sSymbol += cToken; + eSymbolType = BRACKET_SYMBOLTYPE_COLOR; + eState = SsGetPrefix; + } + } + } + break; + case SsGetCon: + { + switch (cToken) + { + case '<': + { + eState = SsStop; + eSymbolType = BRACKET_SYMBOLTYPE_ERROR; + } + break; + case '>': + { + if (cLetter == '<') + { + sSymbol += cToken; + cLetter = ' '; + eState = SsStop; + eSymbolType = NUMBERFORMAT_OP_NE; + } + else + { + eState = SsStop; + eSymbolType = BRACKET_SYMBOLTYPE_ERROR; + } + } + break; + case '=': + { + if (cLetter == '<') + { + sSymbol += cToken; + cLetter = ' '; + eSymbolType = NUMBERFORMAT_OP_LE; + } + else if (cLetter == '>') + { + sSymbol += cToken; + cLetter = ' '; + eSymbolType = NUMBERFORMAT_OP_GE; + } + else + { + eState = SsStop; + eSymbolType = BRACKET_SYMBOLTYPE_ERROR; + } + } + break; + case ' ': + { + rString.Erase(nPos-1,1); + nPos--; + nLen--; + } + break; + default: + { + eState = SsStop; + nPos--; + } + break; + } + } + break; + case SsGetPrefix: + { + if (cToken == ']') + eState = SsStop; + else + sSymbol += cToken; + } + break; + default: + break; + } // of switch + } // of while + + return eSymbolType; +} + +NfHackConversion SvNumberformat::Load( SvStream& rStream, + ImpSvNumMultipleReadHeader& rHdr, SvNumberFormatter* pHackConverter, + ImpSvNumberInputScan& rISc ) +{ + rHdr.StartEntry(); + USHORT nOp1, nOp2; + SvNumberformat::LoadString( rStream, sFormatstring ); + rStream >> eType >> fLimit1 >> fLimit2 + >> nOp1 >> nOp2 >> bStandard >> bIsUsed; + NfHackConversion eHackConversion = NF_CONVERT_NONE; + BOOL bOldConvert = FALSE; + LanguageType eOldTmpLang = 0; + LanguageType eOldNewLang = 0; + if ( pHackConverter ) + { // werden nur hierbei gebraucht + bOldConvert = rScan.GetConvertMode(); + eOldTmpLang = rScan.GetTmpLnge(); + eOldNewLang = rScan.GetNewLnge(); + } + String aLoadedColorName; + for (USHORT i = 0; i < 4; i++) + { + NumFor[i].Load( rStream, rScan, aLoadedColorName ); + if ( pHackConverter && eHackConversion == NF_CONVERT_NONE ) + { + //! HACK! ER 29.07.97 13:52 + // leider wurde nicht gespeichert, was SYSTEM on Save wirklich war :-/ + // aber immerhin wird manchmal fuer einen Entry FARBE oder COLOR gespeichert.. + // System-German FARBE nach System-xxx COLOR umsetzen und vice versa, + //! geht davon aus, dass onSave nur GERMAN und ENGLISH KeyWords in + //! ImpSvNumberformatScan existierten + if ( aLoadedColorName.Len() && !NumFor[i].GetColor() + && aLoadedColorName != rScan.GetColorString() ) + { + if ( rScan.GetColorString().EqualsAscii( "FARBE" ) ) + { // English -> German + eHackConversion = NF_CONVERT_ENGLISH_GERMAN; + rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_ENGLISH_US ); + rScan.SetConvertMode( LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN ); + } + else + { // German -> English + eHackConversion = NF_CONVERT_GERMAN_ENGLISH; + rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_GERMAN ); + rScan.SetConvertMode( LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US ); + } + String aColorName = NumFor[i].GetColorName(); + const Color* pColor = rScan.GetColor( aColorName ); + if ( !pColor && aLoadedColorName == aColorName ) + eHackConversion = NF_CONVERT_NONE; + rScan.GetNumberformatter()->ChangeIntl( LANGUAGE_SYSTEM ); + rScan.SetConvertMode( eOldTmpLang, eOldNewLang ); + rScan.SetConvertMode( bOldConvert ); + } + } + } + eOp1 = (SvNumberformatLimitOps) nOp1; + eOp2 = (SvNumberformatLimitOps) nOp2; + String aComment; // wird nach dem NewCurrency-Geraffel richtig gesetzt + if ( rHdr.BytesLeft() ) + { // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD + SvNumberformat::LoadString( rStream, aComment ); + rStream >> nNewStandardDefined; + } + + xub_StrLen nNewCurrencyEnd = STRING_NOTFOUND; + BOOL bNewCurrencyComment = ( aComment.GetChar(0) == cNewCurrencyMagic && + (nNewCurrencyEnd = aComment.Search( cNewCurrencyMagic, 1 )) != STRING_NOTFOUND ); + BOOL bNewCurrencyLoaded = FALSE; + BOOL bNewCurrency = FALSE; + + BOOL bGoOn = TRUE; + while ( rHdr.BytesLeft() && bGoOn ) + { // as of SV_NUMBERFORMATTER_VERSION_NEW_CURR + USHORT nId; + rStream >> nId; + switch ( nId ) + { + case nNewCurrencyVersionId : + { + bNewCurrencyLoaded = TRUE; + rStream >> bNewCurrency; + if ( bNewCurrency ) + { + for ( USHORT j=0; j<4; j++ ) + { + NumFor[j].LoadNewCurrencyMap( rStream ); + } + } + } + break; + case nNewStandardFlagVersionId : + rStream >> bStandard; // the real standard flag + break; + default: + DBG_ERRORFILE( "SvNumberformat::Load: unknown header bytes left nId" ); + bGoOn = FALSE; // stop reading unknown stream left over of newer versions + // Would be nice to have multiple read/write headers instead + // but old versions wouldn't know it, TLOT. + } + } + rHdr.EndEntry(); + + if ( bNewCurrencyLoaded ) + { + if ( bNewCurrency && bNewCurrencyComment ) + { // original Formatstring und Kommentar wiederherstellen + sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); + aComment.Erase( 0, nNewCurrencyEnd+1 ); + } + } + else if ( bNewCurrencyComment ) + { // neu, aber mit Version vor SV_NUMBERFORMATTER_VERSION_NEW_CURR gespeichert + // original Formatstring und Kommentar wiederherstellen + sFormatstring = aComment.Copy( 1, nNewCurrencyEnd-1 ); + aComment.Erase( 0, nNewCurrencyEnd+1 ); + // Zustaende merken + short nDefined = ( eType & NUMBERFORMAT_DEFINED ); + USHORT nNewStandard = nNewStandardDefined; + // neu parsen etc. + String aStr( sFormatstring ); + xub_StrLen nCheckPos = 0; + SvNumberformat* pFormat = new SvNumberformat( aStr, &rScan, &rISc, + nCheckPos, eLnge, bStandard ); + DBG_ASSERT( !nCheckPos, "SvNumberformat::Load: NewCurrencyRescan nCheckPos" ); + ImpCopyNumberformat( *pFormat ); + delete pFormat; + // Zustaende wiederherstellen + eType |= nDefined; + if ( nNewStandard ) + SetNewStandardDefined( nNewStandard ); + } + SetComment( aComment ); + + if ( eHackConversion != NF_CONVERT_NONE ) + { //! und weiter mit dem HACK! + switch ( eHackConversion ) + { + case NF_CONVERT_ENGLISH_GERMAN : + ConvertLanguage( *pHackConverter, + LANGUAGE_ENGLISH_US, LANGUAGE_GERMAN, TRUE ); + break; + case NF_CONVERT_GERMAN_ENGLISH : + ConvertLanguage( *pHackConverter, + LANGUAGE_GERMAN, LANGUAGE_ENGLISH_US, TRUE ); + break; + default: + DBG_ERRORFILE( "SvNumberformat::Load: eHackConversion unknown" ); + } + } + return eHackConversion; +} + +void SvNumberformat::ConvertLanguage( SvNumberFormatter& rConverter, + LanguageType eConvertFrom, LanguageType eConvertTo, BOOL bSystem ) +{ + xub_StrLen nCheckPos; + sal_uInt32 nKey; + short nType = eType; + String aFormatString( sFormatstring ); + if ( bSystem ) + rConverter.PutandConvertEntrySystem( aFormatString, nCheckPos, nType, + nKey, eConvertFrom, eConvertTo ); + else + rConverter.PutandConvertEntry( aFormatString, nCheckPos, nType, + nKey, eConvertFrom, eConvertTo ); + const SvNumberformat* pFormat = rConverter.GetEntry( nKey ); + DBG_ASSERT( pFormat, "SvNumberformat::ConvertLanguage: Conversion ohne Format" ); + if ( pFormat ) + { + ImpCopyNumberformat( *pFormat ); + // aus Formatter/Scanner uebernommene Werte zuruecksetzen + if ( bSystem ) + eLnge = LANGUAGE_SYSTEM; + // pColor zeigt noch auf Tabelle in temporaerem Formatter/Scanner + for ( USHORT i = 0; i < 4; i++ ) + { + String aColorName = NumFor[i].GetColorName(); + Color* pColor = rScan.GetColor( aColorName ); + NumFor[i].SetColor( pColor, aColorName ); + } + } +} + + +// static +void SvNumberformat::LoadString( SvStream& rStream, String& rStr ) +{ + CharSet eStream = rStream.GetStreamCharSet(); + ByteString aStr; + rStream.ReadByteString( aStr ); + sal_Char cStream = NfCurrencyEntry::GetEuroSymbol( eStream ); + if ( aStr.Search( cStream ) == STRING_NOTFOUND ) + { // simple conversion to unicode + rStr = UniString( aStr, eStream ); + } + else + { + sal_Unicode cTarget = NfCurrencyEntry::GetEuroSymbol(); + register const sal_Char* p = aStr.GetBuffer(); + register const sal_Char* const pEnd = p + aStr.Len(); + register sal_Unicode* pUni = rStr.AllocBuffer( aStr.Len() ); + while ( p < pEnd ) + { + if ( *p == cStream ) + *pUni = cTarget; + else + *pUni = ByteString::ConvertToUnicode( *p, eStream ); + p++; + pUni++; + } + *pUni = 0; + } +} + + +void SvNumberformat::Save( SvStream& rStream, ImpSvNumMultipleWriteHeader& rHdr ) const +{ + String aFormatstring( sFormatstring ); + String aComment( sComment ); +#if NF_COMMENT_IN_FORMATSTRING + // der Kommentar im Formatstring wird nicht gespeichert, um in alten Versionen + // nicht ins schleudern zu kommen und spaeter getrennte Verarbeitung + // (z.B. im Dialog) zu ermoeglichen + SetComment( "", aFormatstring, aComment ); +#endif + + BOOL bNewCurrency = HasNewCurrency(); + if ( bNewCurrency ) + { // SV_NUMBERFORMATTER_VERSION_NEW_CURR im Kommentar speichern + aComment.Insert( cNewCurrencyMagic, 0 ); + aComment.Insert( cNewCurrencyMagic, 0 ); + aComment.Insert( aFormatstring, 1 ); + Build50Formatstring( aFormatstring ); // alten Formatstring generieren + } + + // old SO5 versions do behave strange (no output) if standard flag is set + // on formats not prepared for it (not having the following exact types) + BOOL bOldStandard = bStandard; + if ( bOldStandard ) + { + switch ( eType ) + { + case NUMBERFORMAT_NUMBER : + case NUMBERFORMAT_DATE : + case NUMBERFORMAT_TIME : + case NUMBERFORMAT_DATETIME : + case NUMBERFORMAT_PERCENT : + case NUMBERFORMAT_SCIENTIFIC : + // ok to save + break; + default: + bOldStandard = FALSE; + } + } + + rHdr.StartEntry(); + rStream.WriteByteString( aFormatstring, rStream.GetStreamCharSet() ); + rStream << eType << fLimit1 << fLimit2 << (USHORT) eOp1 << (USHORT) eOp2 + << bOldStandard << bIsUsed; + for (USHORT i = 0; i < 4; i++) + NumFor[i].Save(rStream); + // ab SV_NUMBERFORMATTER_VERSION_NEWSTANDARD + rStream.WriteByteString( aComment, rStream.GetStreamCharSet() ); + rStream << nNewStandardDefined; + // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR + rStream << nNewCurrencyVersionId; + rStream << bNewCurrency; + if ( bNewCurrency ) + { + for ( USHORT j=0; j<4; j++ ) + { + NumFor[j].SaveNewCurrencyMap( rStream ); + } + } + + // the real standard flag to load with versions >638 if different + if ( bStandard != bOldStandard ) + { + rStream << nNewStandardFlagVersionId; + rStream << bStandard; + } + + rHdr.EndEntry(); +} + + +BOOL SvNumberformat::HasNewCurrency() const +{ + for ( USHORT j=0; j<4; j++ ) + { + if ( NumFor[j].HasNewCurrency() ) + return TRUE; + } + return FALSE; +} + + +BOOL SvNumberformat::GetNewCurrencySymbol( String& rSymbol, + String& rExtension ) const +{ + for ( USHORT j=0; j<4; j++ ) + { + if ( NumFor[j].GetNewCurrencySymbol( rSymbol, rExtension ) ) + return TRUE; + } + rSymbol.Erase(); + rExtension.Erase(); + return FALSE; +} + + +// static +String SvNumberformat::StripNewCurrencyDelimiters( const String& rStr, + BOOL bQuoteSymbol ) +{ + String aTmp; + xub_StrLen nStartPos, nPos, nLen; + nLen = rStr.Len(); + nStartPos = 0; + while ( (nPos = rStr.SearchAscii( "[$", nStartPos )) != STRING_NOTFOUND ) + { + xub_StrLen nEnd; + if ( (nEnd = GetQuoteEnd( rStr, nPos )) < nLen ) + { + aTmp += rStr.Copy( nStartPos, ++nEnd - nStartPos ); + nStartPos = nEnd; + } + else + { + aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); + nStartPos = nPos + 2; + xub_StrLen nDash; + nEnd = nStartPos - 1; + do + { + nDash = rStr.Search( '-', ++nEnd ); + } while ( (nEnd = GetQuoteEnd( rStr, nDash )) < nLen ); + xub_StrLen nClose; + nEnd = nStartPos - 1; + do + { + nClose = rStr.Search( ']', ++nEnd ); + } while ( (nEnd = GetQuoteEnd( rStr, nClose )) < nLen ); + nPos = ( nDash < nClose ? nDash : nClose ); + if ( !bQuoteSymbol || rStr.GetChar( nStartPos ) == '"' ) + aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); + else + { + aTmp += '"'; + aTmp += rStr.Copy( nStartPos, nPos - nStartPos ); + aTmp += '"'; + } + nStartPos = nClose + 1; + } + } + if ( nLen > nStartPos ) + aTmp += rStr.Copy( nStartPos, nLen - nStartPos ); + return aTmp; +} + + +void SvNumberformat::Build50Formatstring( String& rStr ) const +{ + rStr = StripNewCurrencyDelimiters( sFormatstring, TRUE ); +} + + +void SvNumberformat::ImpGetOutputStandard(double& fNumber, String& OutString) +{ + USHORT nStandardPrec = rScan.GetStandardPrec(); + if ( fabs(fNumber) > 1.0E15 ) // #58531# war E16 + OutString = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_E, nStandardPrec /*2*/, + GetFormatter().GetNumDecimalSep().GetChar(0)); + else + { +#if 0 +{ + // debugger test case for ANSI standard correctness + ::rtl::OUString aTest; + // expect 0.00123 OK + aTest = ::rtl::math::doubleToUString( 0.001234567, + rtl_math_StringFormat_G, 3, '.', sal_True ); + // expect 123 OK + aTest = ::rtl::math::doubleToUString( 123.4567, + rtl_math_StringFormat_G, 3, '.', sal_True ); + // expect 123.5 OK + aTest = ::rtl::math::doubleToUString( 123.4567, + rtl_math_StringFormat_G, 4, '.', sal_True ); + // expect 1e+03 (as 999.6 rounded to 3 significant digits results in + // 1000 with an exponent equal to significant digits) + // Currently (24-Jan-2003) we do fail in this case and output 1000 + // instead, negligible. + aTest = ::rtl::math::doubleToUString( 999.6, + rtl_math_StringFormat_G, 3, '.', sal_True ); + // expect what? result is 1.2e+004 + aTest = ::rtl::math::doubleToUString( 12345.6789, + rtl_math_StringFormat_G, -3, '.', sal_True ); +} +#endif + + OutString = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_F, nStandardPrec /*2*/, + GetFormatter().GetNumDecimalSep().GetChar(0), sal_True ); + if (OutString.GetChar(0) == '-' && + OutString.GetTokenCount('0') == OutString.Len()) + OutString.EraseLeadingChars('-'); // nicht -0 + } + ImpTransliterate( OutString, NumFor[0].GetNatNum() ); + return; +} + +void SvNumberformat::ImpGetOutputInputLine(double fNumber, String& OutString) +{ + BOOL bModified = FALSE; + if ( (eType & NUMBERFORMAT_PERCENT) && (fabs(fNumber) < _D_MAX_D_BY_100)) + { + if (fNumber == 0.0) + { + OutString.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "0%" ) ); + return; + } + fNumber *= 100; + bModified = TRUE; + } + + if (fNumber == 0.0) + { + OutString = '0'; + return; + } + + OutString = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, + GetFormatter().GetNumDecimalSep().GetChar(0), sal_True ); + + if ( eType & NUMBERFORMAT_PERCENT && bModified) + OutString += '%'; + return; +} + +short SvNumberformat::ImpCheckCondition(double& fNumber, + double& fLimit, + SvNumberformatLimitOps eOp) +{ + switch(eOp) + { + case NUMBERFORMAT_OP_NO: return -1; + case NUMBERFORMAT_OP_EQ: return (short) (fNumber == fLimit); + case NUMBERFORMAT_OP_NE: return (short) (fNumber != fLimit); + case NUMBERFORMAT_OP_LT: return (short) (fNumber < fLimit); + case NUMBERFORMAT_OP_LE: return (short) (fNumber <= fLimit); + case NUMBERFORMAT_OP_GT: return (short) (fNumber > fLimit); + case NUMBERFORMAT_OP_GE: return (short) (fNumber >= fLimit); + default: return -1; + } +} + +BOOL SvNumberformat::GetOutputString(String& sString, + String& OutString, + Color** ppColor) +{ + OutString.Erase(); + USHORT nIx; + if (eType & NUMBERFORMAT_TEXT) + nIx = 0; + else if (NumFor[3].GetnAnz() > 0) + nIx = 3; + else + { + *ppColor = NULL; // no change of color + return FALSE; + } + *ppColor = NumFor[nIx].GetColor(); + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + if (rInfo.eScannedType == NUMBERFORMAT_TEXT) + { + BOOL bRes = FALSE; + const USHORT nAnz = NumFor[nIx].GetnAnz(); + for (USHORT i = 0; i < nAnz; i++) + { + switch (rInfo.nTypeArray[i]) + { + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + OutString += (sal_Unicode) 0x1B; + OutString += rInfo.sStrArray[i].GetChar(1); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + InsertBlanks( OutString, OutString.Len(), + rInfo.sStrArray[i].GetChar(1) ); + break; + case NF_KEY_GENERAL : // #77026# "General" is the same as "@" + case NF_SYMBOLTYPE_DEL : + OutString += sString; + break; + default: + OutString += rInfo.sStrArray[i]; + } + } + return bRes; + } + return FALSE; +} +/* +void SvNumberformat::GetNextFareyNumber(ULONG nPrec, ULONG x0, ULONG x1, + ULONG y0, ULONG y1, + ULONG& x2,ULONG& y2) +{ + x2 = ((y0+nPrec)/y1)*x1 - x0; + y2 = ((y0+nPrec)/y1)*y1 - y0; +} +*/ +ULONG SvNumberformat::ImpGGT(ULONG x, ULONG y) +{ + if (y == 0) + return x; + else + { + ULONG z = x%y; + while (z) + { + x = y; + y = z; + z = x%y; + } + return y; + } +} + +ULONG SvNumberformat::ImpGGTRound(ULONG x, ULONG y) +{ + if (y == 0) + return x; + else + { + ULONG z = x%y; + while ((double)z/(double)y > D_EPS) + { + x = y; + y = z; + z = x%y; + } + return y; + } +} + +BOOL SvNumberformat::GetOutputString(double fNumber, + String& OutString, + Color** ppColor) +{ + BOOL bRes = FALSE; + OutString.Erase(); // alles loeschen + *ppColor = NULL; // keine Farbaenderung + if (eType & NUMBERFORMAT_LOGICAL) + { + if (fNumber) + OutString = rScan.GetTrueString(); + else + OutString = rScan.GetFalseString(); + return FALSE; + } + if (eType & NUMBERFORMAT_TEXT && bStandard) + { + ImpGetOutputStandard(fNumber, OutString); + return FALSE; + } + BOOL bHadStandard = FALSE; + if (bStandard) // einzelne Standardformate + { + if (rScan.GetStandardPrec() == 300) // alle Zahlformate InputLine + { + ImpGetOutputInputLine(fNumber, OutString); + return FALSE; + } + switch (eType) + { + case NUMBERFORMAT_NUMBER: // Standardzahlformat + ImpGetOutputStandard(fNumber, OutString); + bHadStandard = TRUE; + break; + case NUMBERFORMAT_DATE: + bRes |= ImpGetDateOutput(fNumber, 0, OutString); + bHadStandard = TRUE; + break; + case NUMBERFORMAT_TIME: + bRes |= ImpGetTimeOutput(fNumber, 0, OutString); + bHadStandard = TRUE; + break; + case NUMBERFORMAT_DATETIME: + bRes |= ImpGetDateTimeOutput(fNumber, 0, OutString); + bHadStandard = TRUE; + break; + } + } + if ( !bHadStandard ) + { + USHORT nIx; // Index des Teilformats + short nCheck = ImpCheckCondition(fNumber, fLimit1, eOp1); + if (nCheck == -1 || nCheck == 1) // nur 1 String oder True + nIx = 0; + else + { + nCheck = ImpCheckCondition(fNumber, fLimit2, eOp2); + if (nCheck == -1 || nCheck == 1) + nIx = 1; + else + nIx = 2; + } + if (nIx == 1 && fNumber < 0.0 && // negatives Format + IsNegativeRealNegative() ) // ohne Vorzeichen + fNumber = -fNumber; // Vorzeichen eliminieren + *ppColor = NumFor[nIx].GetColor(); + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + const USHORT nAnz = NumFor[nIx].GetnAnz(); + if (nAnz == 0 && rInfo.eScannedType == NUMBERFORMAT_UNDEFINED) + return FALSE; // leer => nichts + else if (nAnz == 0) // sonst Standard-Format + { + ImpGetOutputStandard(fNumber, OutString); + return FALSE; + } + switch (rInfo.eScannedType) + { + case NUMBERFORMAT_TEXT: + case NUMBERFORMAT_DEFINED: + { + for (USHORT i = 0; i < nAnz; i++) + { + switch (rInfo.nTypeArray[i]) + { + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + OutString += (sal_Unicode) 0x1B; + OutString += rInfo.sStrArray[i].GetChar(1); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + InsertBlanks( OutString, OutString.Len(), + rInfo.sStrArray[i].GetChar(1) ); + break; + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + OutString += rInfo.sStrArray[i]; + break; + case NF_SYMBOLTYPE_THSEP: + if (rInfo.nThousand == 0) + OutString += rInfo.sStrArray[i]; + break; + default: + break; + } + } + } + break; + case NUMBERFORMAT_DATE: + bRes |= ImpGetDateOutput(fNumber, nIx, OutString); + break; + case NUMBERFORMAT_TIME: + bRes |= ImpGetTimeOutput(fNumber, nIx, OutString); + break; + case NUMBERFORMAT_DATETIME: + bRes |= ImpGetDateTimeOutput(fNumber, nIx, OutString); + break; + case NUMBERFORMAT_NUMBER: + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + bRes |= ImpGetNumberOutput(fNumber, nIx, OutString); + break; + case NUMBERFORMAT_FRACTION: + { + String sStr, sFrac, sDiv; // Strings, Wert fuer + ULONG nFrac, nDiv; // Vorkommaanteil + // Zaehler und Nenner + BOOL bSign = FALSE; + if (fNumber < 0) + { + if (nIx == 0) // nicht in hinteren + bSign = TRUE; // Formaten + fNumber = -fNumber; + } + double fNum = floor(fNumber); // Vorkommateil + fNumber -= fNum; // Nachkommateil + if (fNum > _D_MAX_U_LONG_ || rInfo.nCntExp > 9) + // zu gross + { + OutString = rScan.GetErrorString(); + return FALSE; + } + if (rInfo.nCntExp == 0) + { + DBG_ERROR("SvNumberformat:: Bruch, nCntExp == 0"); + return FALSE; + } + ULONG nBasis = ((ULONG)floor( // 9, 99, 999 ,... + pow(10.0,rInfo.nCntExp))) - 1; + ULONG x0, y0, x1, y1; + + if (rInfo.nCntExp <= _MAX_FRACTION_PREC) + { + BOOL bUpperHalf; + if (fNumber > 0.5) + { + bUpperHalf = TRUE; + fNumber -= (fNumber - 0.5) * 2.0; + } + else + bUpperHalf = FALSE; + // Einstieg in Farey-Serie + // finden: + x0 = (ULONG) floor(fNumber*nBasis); // z.B. 2/9 <= x < 3/9 + if (x0 == 0) // => x0 = 2 + { + y0 = 1; + x1 = 1; + y1 = nBasis; + } + else if (x0 == (nBasis-1)/2) // (b-1)/2, 1/2 + { // geht (nBasis ungerade) + y0 = nBasis; + x1 = 1; + y1 = 2; + } + else if (x0 == 1) + { + y0 = nBasis; // 1/n; 1/(n-1) + x1 = 1; + y1 = nBasis - 1; + } + else + { + y0 = nBasis; // z.B. 2/9 2/8 + x1 = x0; + y1 = nBasis - 1; + double fUg = (double) x0 / (double) y0; + double fOg = (double) x1 / (double) y1; + ULONG nGgt = ImpGGT(y0, x0); // x0/y0 kuerzen + x0 /= nGgt; + y0 /= nGgt; // Einschachteln: + ULONG x2 = 0; + ULONG y2 = 0; + BOOL bStop = FALSE; + while (!bStop) + { +#ifdef GCC + // #i21648# GCC over-optimizes something resulting + // in wrong fTest values throughout the loops. + volatile +#endif + double fTest = (double)x1/(double)y1; + while (!bStop) + { + while (fTest > fOg) + { + x1--; + fTest = (double)x1/(double)y1; + } + while (fTest < fUg && y1 > 1) + { + y1--; + fTest = (double)x1/(double)y1; + } + if (fTest <= fOg) + { + fOg = fTest; + bStop = TRUE; + } + else if (y1 == 1) + bStop = TRUE; + } // of while + nGgt = ImpGGT(y1, x1); // x1/y1 kuerzen + x2 = x1 / nGgt; + y2 = y1 / nGgt; + if (x2*y0 - x0*y2 == 1 || y1 <= 1) // Test, ob x2/y2 + bStop = TRUE; // naechste Farey-Zahl + else + { + y1--; + bStop = FALSE; + } + } // of while + x1 = x2; + y1 = y2; + } // of else + double fup, flow; + flow = (double)x0/(double)y0; + fup = (double)x1/(double)y1; + while (fNumber > fup) + { + ULONG x2 = ((y0+nBasis)/y1)*x1 - x0; // naechste Farey-Zahl + ULONG y2 = ((y0+nBasis)/y1)*y1 - y0; +// GetNextFareyNumber(nBasis, x0, x1, y0, y1, x2, y2); + x0 = x1; + y0 = y1; + x1 = x2; + y1 = y2; + flow = fup; + fup = (double)x1/(double)y1; + } + if (fNumber - flow < fup - fNumber) + { + nFrac = x0; + nDiv = y0; + } + else + { + nFrac = x1; + nDiv = y1; + } + if (bUpperHalf) // Original restaur. + { + if (nFrac == 0 && nDiv == 1) // 1/1 + fNum += 1.0; + else + nFrac = nDiv - nFrac; + } + } + else // grosse Nenner + { // 0,1234->123/1000 + ULONG nGgt; +/* + nDiv = nBasis+1; + nFrac = ((ULONG)floor(0.5 + fNumber * + pow(10.0,rInfo.nCntExp))); +*/ + nDiv = 10000000; + nFrac = ((ULONG)floor(0.5 + fNumber * 10000000.0)); + nGgt = ImpGGT(nDiv, nFrac); + if (nGgt > 1) + { + nDiv /= nGgt; + nFrac /= nGgt; + } + if (nDiv > nBasis) + { + nGgt = ImpGGTRound(nDiv, nFrac); + if (nGgt > 1) + { + nDiv /= nGgt; + nFrac /= nGgt; + } + } + if (nDiv > nBasis) + { + nDiv = nBasis; + nFrac = ((ULONG)floor(0.5 + fNumber * + pow(10.0,rInfo.nCntExp))); + nGgt = ImpGGTRound(nDiv, nFrac); + if (nGgt > 1) + { + nDiv /= nGgt; + nFrac /= nGgt; + } + } + } + + if (rInfo.nCntPre == 0) // unechter Bruch + { + double fNum1 = fNum * (double)nDiv + (double)nFrac; + if (fNum1 > _D_MAX_U_LONG_) + { + OutString = rScan.GetErrorString(); + return FALSE; + } + nFrac = (ULONG) floor(fNum1); + sStr.Erase(); + } + else if (fNum == 0.0 && nFrac != 0) + sStr.Erase(); + else + { + char aBuf[100]; + sprintf( aBuf, "%.f", fNum ); // simple rounded integer (#100211# - checked) + sStr.AssignAscii( aBuf ); + ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); + } + if (rInfo.nCntPre > 0 && nFrac == 0) + { + sFrac.Erase(); + sDiv.Erase(); + } + else + { + sFrac = ImpIntToString( nIx, nFrac ); + sDiv = ImpIntToString( nIx, nDiv ); + } + + USHORT j = nAnz-1; // letztes Symbol->rueckw. + xub_StrLen k; // Nenner: + bRes |= ImpNumberFill(sDiv, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRAC); + BOOL bCont = TRUE; + if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRAC) + { + if (rInfo.nCntPre > 0 && nFrac == 0) + sDiv.Insert(' ',0); + else + sDiv.Insert( rInfo.sStrArray[j].GetChar(0), 0 ); + if ( j ) + j--; + else + bCont = FALSE; + } + // weiter Zaehler: + if ( !bCont ) + sFrac.Erase(); + else + { + bRes |= ImpNumberFill(sFrac, fNumber, k, j, nIx, NF_SYMBOLTYPE_FRACBLANK); + if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_FRACBLANK) + { + sFrac.Insert(rInfo.sStrArray[j],0); + if ( j ) + j--; + else + bCont = FALSE; + } + } + // weiter Hauptzahl + if ( !bCont ) + sStr.Erase(); + else + { + k = sStr.Len(); // hinter letzter Ziffer + bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, + rInfo.nCntPre); + } + if (bSign && !(nFrac == 0 && fNum == 0.0)) + OutString.Insert('-',0); // nicht -0 + OutString += sStr; + OutString += sFrac; + OutString += sDiv; + } + break; + case NUMBERFORMAT_SCIENTIFIC: + { + BOOL bSign = FALSE; + if (fNumber < 0) + { + if (nIx == 0) // nicht in hinteren + bSign = TRUE; // Formaten + fNumber = -fNumber; + } + String sStr( ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_E, + rInfo.nCntPre + rInfo.nCntPost - 1, '.' )); + + String ExpStr; + short nExpSign = 1; + xub_StrLen nExPos = sStr.Search('E'); + if ( nExPos != STRING_NOTFOUND ) + { + // split into mantisse and exponent and get rid of "E+" or "E-" + xub_StrLen nExpStart = nExPos + 1; + switch ( sStr.GetChar( nExpStart ) ) + { + case '-' : + nExpSign = -1; + // fallthru + case '+' : + ++nExpStart; + break; + } + ExpStr = sStr.Copy( nExpStart ); // part following the "E+" + sStr.Erase( nExPos ); + sStr.EraseAllChars('.'); // cut any decimal delimiter + if ( rInfo.nCntPre != 1 ) // rescale Exp + { + sal_Int32 nExp = ExpStr.ToInt32() * nExpSign; + nExp -= sal_Int32(rInfo.nCntPre)-1; + if ( nExp < 0 ) + { + nExpSign = -1; + nExp = -nExp; + } + else + nExpSign = 1; + ExpStr = String::CreateFromInt32( nExp ); + } + } + USHORT j = nAnz-1; // last symbol + xub_StrLen k; // position in ExpStr + bRes |= ImpNumberFill(ExpStr, fNumber, k, j, nIx, NF_SYMBOLTYPE_EXP); + + xub_StrLen nZeros = 0; // erase leading zeros + while (nZeros < k && ExpStr.GetChar(nZeros) == '0') + ++nZeros; + if (nZeros) + ExpStr.Erase( 0, nZeros); + + BOOL bCont = TRUE; + if (rInfo.nTypeArray[j] == NF_SYMBOLTYPE_EXP) + { + const String& rStr = rInfo.sStrArray[j]; + if (nExpSign == -1) + ExpStr.Insert('-',0); + else if (rStr.Len() > 1 && rStr.GetChar(1) == '+') + ExpStr.Insert('+',0); + ExpStr.Insert(rStr.GetChar(0),0); + if ( j ) + j--; + else + bCont = FALSE; + } + // weiter Hauptzahl: + if ( !bCont ) + sStr.Erase(); + else + { + k = sStr.Len(); // hinter letzter Ziffer + bRes |= ImpNumberFillWithThousands(sStr,fNumber, k,j,nIx, + rInfo.nCntPre + + rInfo.nCntPost); + } + if (bSign) + sStr.Insert('-',0); + OutString = sStr; + OutString += ExpStr; + } + break; + } + } + return bRes; +} + +BOOL SvNumberformat::ImpGetTimeOutput(double fNumber, + USHORT nIx, + String& OutString) +{ + using namespace ::com::sun::star::i18n; + BOOL bCalendarSet = FALSE; + double fNumberOrig = fNumber; + BOOL bRes = FALSE; + BOOL bSign = FALSE; + if (fNumber < 0.0) + { + fNumber = -fNumber; + if (nIx == 0) + bSign = TRUE; + } + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + if (rInfo.bThousand) // []-Format + { + if (fNumber > 1.0E10) // zu gross + { + OutString = rScan.GetErrorString(); + return FALSE; + } + } + else + fNumber -= floor(fNumber); // sonst Datum abtrennen + BOOL bInputLine; + xub_StrLen nCntPost; + if ( rScan.GetStandardPrec() == 300 && + 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) + { // round at 7 decimals (+5 of 86400 == 12 significant digits) + bInputLine = TRUE; + nCntPost = 7; + } + else + { + bInputLine = FALSE; + nCntPost = xub_StrLen(rInfo.nCntPost); + } + if (bSign && !rInfo.bThousand) // kein []-Format + fNumber = 1.0 - fNumber; // "Kehrwert" + double fTime = fNumber * 86400.0; + fTime = ::rtl::math::round( fTime, int(nCntPost) ); + if (bSign && fTime == 0.0) + bSign = FALSE; // nicht -00:00:00 + + if( floor( fTime ) > _D_MAX_U_LONG_ ) + { + OutString = rScan.GetErrorString(); + return FALSE; + } + ULONG nSeconds = (ULONG)floor( fTime ); + + String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, + rtl_math_StringFormat_F, int(nCntPost), '.')); + sSecStr.EraseLeadingChars('0'); + sSecStr.EraseLeadingChars('.'); + if ( bInputLine ) + { + sSecStr.EraseTrailingChars('0'); + if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) + sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); + ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); + nCntPost = sSecStr.Len(); + } + else + ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); + + xub_StrLen nSecPos = 0; // Zum Ziffernweisen + // abarbeiten + ULONG nHour, nMin, nSec; + if (!rInfo.bThousand) // kein [] Format + { + nHour = (nSeconds/3600) % 24; + nMin = (nSeconds%3600) / 60; + nSec = nSeconds%60; + } + else if (rInfo.nThousand == 3) // [ss] + { + nHour = 0; + nMin = 0; + nSec = nSeconds; + } + else if (rInfo.nThousand == 2) // [mm]:ss + { + nHour = 0; + nMin = nSeconds / 60; + nSec = nSeconds % 60; + } + else if (rInfo.nThousand == 1) // [hh]:mm:ss + { + nHour = nSeconds / 3600; + nMin = (nSeconds%3600) / 60; + nSec = nSeconds%60; + } + else { + // TODO What should these be set to? + nHour = 0; + nMin = 0; + nSec = 0; + } + + sal_Unicode cAmPm = ' '; // a oder p + if (rInfo.nCntExp) // AM/PM + { + if (nHour == 0) + { + nHour = 12; + cAmPm = 'a'; + } + else if (nHour < 12) + cAmPm = 'a'; + else + { + cAmPm = 'p'; + if (nHour > 12) + nHour -= 12; + } + } + const USHORT nAnz = NumFor[nIx].GetnAnz(); + for (USHORT i = 0; i < nAnz; i++) + { + switch (rInfo.nTypeArray[i]) + { + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + OutString += (sal_Unicode) 0x1B; + OutString += rInfo.sStrArray[i].GetChar(1); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + InsertBlanks( OutString, OutString.Len(), + rInfo.sStrArray[i].GetChar(1) ); + break; + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_DATESEP: + case NF_SYMBOLTYPE_TIMESEP: + case NF_SYMBOLTYPE_TIME100SECSEP: + OutString += rInfo.sStrArray[i]; + break; + case NF_SYMBOLTYPE_DIGIT: + { + xub_StrLen nLen = ( bInputLine && i > 0 && + (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || + rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? + nCntPost : rInfo.sStrArray[i].Len() ); + for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) + { + OutString += sSecStr.GetChar(nSecPos); + nSecPos++; + } + } + break; + case NF_KEY_AMPM: // AM/PM + { + if ( !bCalendarSet ) + { + double fDiff = DateTime(*(rScan.GetNullDate())) - GetCal().getEpochStart(); + fDiff += fNumberOrig; + GetCal().setLocalDateTime( fDiff ); + bCalendarSet = TRUE; + } + if (cAmPm == 'a') + OutString += GetCal().getDisplayName( + CalendarDisplayIndex::AM_PM, AmPmValue::AM, 0 ); + else + OutString += GetCal().getDisplayName( + CalendarDisplayIndex::AM_PM, AmPmValue::PM, 0 ); + } + break; + case NF_KEY_AP: // A/P + { + if (cAmPm == 'a') + OutString += 'a'; + else + OutString += 'p'; + } + break; + case NF_KEY_MI: // M + OutString += ImpIntToString( nIx, nMin ); + break; + case NF_KEY_MMI: // MM + OutString += ImpIntToString( nIx, nMin, 2 ); + break; + case NF_KEY_H: // H + OutString += ImpIntToString( nIx, nHour ); + break; + case NF_KEY_HH: // HH + OutString += ImpIntToString( nIx, nHour, 2 ); + break; + case NF_KEY_S: // S + OutString += ImpIntToString( nIx, nSec ); + break; + case NF_KEY_SS: // SS + OutString += ImpIntToString( nIx, nSec, 2 ); + break; + default: + break; + } + } + if (bSign && rInfo.bThousand) + OutString.Insert('-',0); + return bRes; +} + + +BOOL SvNumberformat::ImpIsOtherCalendar( const ImpSvNumFor& rNumFor ) const +{ + if ( GetCal().getUniqueID() != Gregorian::get() ) + return FALSE; + const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); + const USHORT nAnz = rNumFor.GetnAnz(); + USHORT i; + for ( i = 0; i < nAnz; i++ ) + { + switch ( rInfo.nTypeArray[i] ) + { + case NF_SYMBOLTYPE_CALENDAR : + return FALSE; + case NF_KEY_EC : + case NF_KEY_EEC : + case NF_KEY_R : + case NF_KEY_RR : + case NF_KEY_AAA : + case NF_KEY_AAAA : + return TRUE; + } + } + return FALSE; +} + + +void SvNumberformat::SwitchToOtherCalendar( String& rOrgCalendar, + double& fOrgDateTime ) const +{ + CalendarWrapper& rCal = GetCal(); + const rtl::OUString &rGregorian = Gregorian::get(); + if ( rCal.getUniqueID() == rGregorian ) + { + using namespace ::com::sun::star::i18n; + ::com::sun::star::uno::Sequence< ::rtl::OUString > xCals + = rCal.getAllCalendars( rLoc().getLocale() ); + sal_Int32 nCnt = xCals.getLength(); + if ( nCnt > 1 ) + { + for ( sal_Int32 j=0; j < nCnt; j++ ) + { + if ( xCals[j] != rGregorian ) + { + if ( !rOrgCalendar.Len() ) + { + rOrgCalendar = rCal.getUniqueID(); + fOrgDateTime = rCal.getDateTime(); + } + rCal.loadCalendar( xCals[j], rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + break; // for + } + } + } + } +} + + +void SvNumberformat::SwitchToGregorianCalendar( const String& rOrgCalendar, + double fOrgDateTime ) const +{ + CalendarWrapper& rCal = GetCal(); + const rtl::OUString &rGregorian = Gregorian::get(); + if ( rOrgCalendar.Len() && rCal.getUniqueID() != rGregorian ) + { + rCal.loadCalendar( rGregorian, rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + } +} + + +BOOL SvNumberformat::ImpFallBackToGregorianCalendar( String& rOrgCalendar, double& fOrgDateTime ) +{ + using namespace ::com::sun::star::i18n; + CalendarWrapper& rCal = GetCal(); + const rtl::OUString &rGregorian = Gregorian::get(); + if ( rCal.getUniqueID() != rGregorian ) + { + sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); + if ( nVal == 0 && rCal.getLoadedCalendar().Eras[0].ID.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "Dummy" ) ) ) + { + if ( !rOrgCalendar.Len() ) + { + rOrgCalendar = rCal.getUniqueID(); + fOrgDateTime = rCal.getDateTime(); + } + else if ( rOrgCalendar == String(rGregorian) ) + rOrgCalendar.Erase(); + rCal.loadCalendar( rGregorian, rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + return TRUE; + } + } + return FALSE; +} + + +BOOL SvNumberformat::ImpSwitchToSpecifiedCalendar( String& rOrgCalendar, + double& fOrgDateTime, const ImpSvNumFor& rNumFor ) const +{ + const ImpSvNumberformatInfo& rInfo = rNumFor.Info(); + const USHORT nAnz = rNumFor.GetnAnz(); + for ( USHORT i = 0; i < nAnz; i++ ) + { + if ( rInfo.nTypeArray[i] == NF_SYMBOLTYPE_CALENDAR ) + { + CalendarWrapper& rCal = GetCal(); + if ( !rOrgCalendar.Len() ) + { + rOrgCalendar = rCal.getUniqueID(); + fOrgDateTime = rCal.getDateTime(); + } + rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + return TRUE; + } + } + return FALSE; +} + + +// static +void SvNumberformat::ImpAppendEraG( String& OutString, + const CalendarWrapper& rCal, sal_Int16 nNatNum ) +{ + using namespace ::com::sun::star::i18n; + if ( rCal.getUniqueID().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "gengou" ) ) ) + { + sal_Unicode cEra; + sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::ERA ); + switch ( nVal ) + { + case 1 : cEra = 'M'; break; + case 2 : cEra = 'T'; break; + case 3 : cEra = 'S'; break; + case 4 : cEra = 'H'; break; + default: + cEra = '?'; + } + OutString += cEra; + } + else + OutString += rCal.getDisplayString( CalendarDisplayCode::SHORT_ERA, nNatNum ); +} + + +BOOL SvNumberformat::ImpGetDateOutput(double fNumber, + USHORT nIx, + String& OutString) +{ + using namespace ::com::sun::star::i18n; + BOOL bRes = FALSE; + CalendarWrapper& rCal = GetCal(); + double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); + fNumber += fDiff; + rCal.setLocalDateTime( fNumber ); + String aOrgCalendar; // empty => not changed yet + double fOrgDateTime; + BOOL bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) + bOtherCalendar = FALSE; + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + const USHORT nAnz = NumFor[nIx].GetnAnz(); + sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); + for (USHORT i = 0; i < nAnz; i++) + { + switch (rInfo.nTypeArray[i]) + { + case NF_SYMBOLTYPE_CALENDAR : + if ( !aOrgCalendar.Len() ) + { + aOrgCalendar = rCal.getUniqueID(); + fOrgDateTime = rCal.getDateTime(); + } + rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + break; + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + OutString += (sal_Unicode) 0x1B; + OutString += rInfo.sStrArray[i].GetChar(1); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + InsertBlanks( OutString, OutString.Len(), + rInfo.sStrArray[i].GetChar(1) ); + break; + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_DATESEP: + case NF_SYMBOLTYPE_TIMESEP: + case NF_SYMBOLTYPE_TIME100SECSEP: + OutString += rInfo.sStrArray[i]; + break; + case NF_KEY_M: // M + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_MONTH, nNatNum ); + break; + case NF_KEY_MM: // MM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH, nNatNum ); + break; + case NF_KEY_MMM: // MMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); + break; + case NF_KEY_MMMM: // MMMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); + break; + case NF_KEY_MMMMM: // MMMMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); + break; + case NF_KEY_Q: // Q + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_QUARTER, nNatNum ); + break; + case NF_KEY_QQ: // QQ + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_QUARTER, nNatNum ); + break; + case NF_KEY_D: // D + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY, nNatNum ); + break; + case NF_KEY_DD: // DD + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY, nNatNum ); + break; + case NF_KEY_DDD: // DDD + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_DDDD: // DDDD + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_YY: // YY + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_YEAR, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_YYYY: // YYYY + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_EC: // E + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_YEAR, nNatNum ); + break; + case NF_KEY_EEC: // EE + case NF_KEY_R: // R + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR, nNatNum ); + break; + case NF_KEY_NN: // NN + case NF_KEY_AAA: // AAA + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); + break; + case NF_KEY_NNN: // NNN + case NF_KEY_AAAA: // AAAA + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + break; + case NF_KEY_NNNN: // NNNN + { + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + OutString += rLoc().getLongDateDayOfWeekSep(); + } + break; + case NF_KEY_WW : // WW + { + sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); + OutString += ImpIntToString( nIx, nVal ); + } + break; + case NF_KEY_G: // G + ImpAppendEraG( OutString, rCal, nNatNum ); + break; + case NF_KEY_GG: // GG + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_ERA, nNatNum ); + break; + case NF_KEY_GGG: // GGG + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_ERA, nNatNum ); + break; + case NF_KEY_RR: // RR => GGGEE + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); + break; + } + } + if ( aOrgCalendar.Len() ) + rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar + return bRes; +} + +BOOL SvNumberformat::ImpGetDateTimeOutput(double fNumber, + USHORT nIx, + String& OutString) +{ + using namespace ::com::sun::star::i18n; + BOOL bRes = FALSE; + + CalendarWrapper& rCal = GetCal(); + double fDiff = DateTime(*(rScan.GetNullDate())) - rCal.getEpochStart(); + fNumber += fDiff; + + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + BOOL bInputLine; + xub_StrLen nCntPost; + if ( rScan.GetStandardPrec() == 300 && + 0 < rInfo.nCntPost && rInfo.nCntPost < 7 ) + { // round at 7 decimals (+5 of 86400 == 12 significant digits) + bInputLine = TRUE; + nCntPost = 7; + } + else + { + bInputLine = FALSE; + nCntPost = xub_StrLen(rInfo.nCntPost); + } + double fTime = (fNumber - floor( fNumber )) * 86400.0; + fTime = ::rtl::math::round( fTime, int(nCntPost) ); + if (fTime >= 86400.0) + { + // result of fNumber==x.999999999... rounded up, use correct date/time + fTime -= 86400.0; + fNumber = floor( fNumber + 0.5) + fTime; + } + rCal.setLocalDateTime( fNumber ); + + String aOrgCalendar; // empty => not changed yet + double fOrgDateTime; + BOOL bOtherCalendar = ImpIsOtherCalendar( NumFor[nIx] ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + if ( ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ) ) + bOtherCalendar = FALSE; + sal_Int16 nNatNum = NumFor[nIx].GetNatNum().GetNatNum(); + + ULONG nSeconds = (ULONG)floor( fTime ); + String sSecStr( ::rtl::math::doubleToUString( fTime-nSeconds, + rtl_math_StringFormat_F, int(nCntPost), '.')); + sSecStr.EraseLeadingChars('0'); + sSecStr.EraseLeadingChars('.'); + if ( bInputLine ) + { + sSecStr.EraseTrailingChars('0'); + if ( sSecStr.Len() < xub_StrLen(rInfo.nCntPost) ) + sSecStr.Expand( xub_StrLen(rInfo.nCntPost), '0' ); + ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); + nCntPost = sSecStr.Len(); + } + else + ImpTransliterate( sSecStr, NumFor[nIx].GetNatNum() ); + + xub_StrLen nSecPos = 0; // Zum Ziffernweisen + // abarbeiten + ULONG nHour, nMin, nSec; + if (!rInfo.bThousand) // [] Format + { + nHour = (nSeconds/3600) % 24; + nMin = (nSeconds%3600) / 60; + nSec = nSeconds%60; + } + else if (rInfo.nThousand == 3) // [ss] + { + nHour = 0; + nMin = 0; + nSec = nSeconds; + } + else if (rInfo.nThousand == 2) // [mm]:ss + { + nHour = 0; + nMin = nSeconds / 60; + nSec = nSeconds % 60; + } + else if (rInfo.nThousand == 1) // [hh]:mm:ss + { + nHour = nSeconds / 3600; + nMin = (nSeconds%3600) / 60; + nSec = nSeconds%60; + } + else { + nHour = 0; // TODO What should these values be? + nMin = 0; + nSec = 0; + } + sal_Unicode cAmPm = ' '; // a oder p + if (rInfo.nCntExp) // AM/PM + { + if (nHour == 0) + { + nHour = 12; + cAmPm = 'a'; + } + else if (nHour < 12) + cAmPm = 'a'; + else + { + cAmPm = 'p'; + if (nHour > 12) + nHour -= 12; + } + } + const USHORT nAnz = NumFor[nIx].GetnAnz(); + for (USHORT i = 0; i < nAnz; i++) + { + switch (rInfo.nTypeArray[i]) + { + case NF_SYMBOLTYPE_CALENDAR : + if ( !aOrgCalendar.Len() ) + { + aOrgCalendar = rCal.getUniqueID(); + fOrgDateTime = rCal.getDateTime(); + } + rCal.loadCalendar( rInfo.sStrArray[i], rLoc().getLocale() ); + rCal.setDateTime( fOrgDateTime ); + ImpFallBackToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + break; + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + OutString += (sal_Unicode) 0x1B; + OutString += rInfo.sStrArray[i].GetChar(1); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + InsertBlanks( OutString, OutString.Len(), + rInfo.sStrArray[i].GetChar(1) ); + break; + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_DATESEP: + case NF_SYMBOLTYPE_TIMESEP: + case NF_SYMBOLTYPE_TIME100SECSEP: + OutString += rInfo.sStrArray[i]; + break; + case NF_SYMBOLTYPE_DIGIT: + { + xub_StrLen nLen = ( bInputLine && i > 0 && + (rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_STRING || + rInfo.nTypeArray[i-1] == NF_SYMBOLTYPE_TIME100SECSEP) ? + nCntPost : rInfo.sStrArray[i].Len() ); + for (xub_StrLen j = 0; j < nLen && nSecPos < nCntPost; j++) + { + OutString += sSecStr.GetChar(nSecPos); + nSecPos++; + } + } + break; + case NF_KEY_AMPM: // AM/PM + { + if (cAmPm == 'a') + OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, + AmPmValue::AM, 0 ); + else + OutString += rCal.getDisplayName( CalendarDisplayIndex::AM_PM, + AmPmValue::PM, 0 ); + } + break; + case NF_KEY_AP: // A/P + { + if (cAmPm == 'a') + OutString += 'a'; + else + OutString += 'p'; + } + break; + case NF_KEY_MI: // M + OutString += ImpIntToString( nIx, nMin ); + break; + case NF_KEY_MMI: // MM + OutString += ImpIntToString( nIx, nMin, 2 ); + break; + case NF_KEY_H: // H + OutString += ImpIntToString( nIx, nHour ); + break; + case NF_KEY_HH: // HH + OutString += ImpIntToString( nIx, nHour, 2 ); + break; + case NF_KEY_S: // S + OutString += ImpIntToString( nIx, nSec ); + break; + case NF_KEY_SS: // SS + OutString += ImpIntToString( nIx, nSec, 2 ); + break; + case NF_KEY_M: // M + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_MONTH, nNatNum ); + break; + case NF_KEY_MM: // MM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH, nNatNum ); + break; + case NF_KEY_MMM: // MMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_MONTH_NAME, nNatNum ); + break; + case NF_KEY_MMMM: // MMMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ); + break; + case NF_KEY_MMMMM: // MMMMM + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_MONTH_NAME, nNatNum ).GetChar(0); + break; + case NF_KEY_Q: // Q + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_QUARTER, nNatNum ); + break; + case NF_KEY_QQ: // QQ + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_QUARTER, nNatNum ); + break; + case NF_KEY_D: // D + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY, nNatNum ); + break; + case NF_KEY_DD: // DD + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY, nNatNum ); + break; + case NF_KEY_DDD: // DDD + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_DDDD: // DDDD + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_YY: // YY + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_YEAR, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_YYYY: // YYYY + { + if ( bOtherCalendar ) + SwitchToGregorianCalendar( aOrgCalendar, fOrgDateTime ); + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR, nNatNum ); + if ( bOtherCalendar ) + SwitchToOtherCalendar( aOrgCalendar, fOrgDateTime ); + } + break; + case NF_KEY_EC: // E + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_YEAR, nNatNum ); + break; + case NF_KEY_EEC: // EE + case NF_KEY_R: // R + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR, nNatNum ); + break; + case NF_KEY_NN: // NN + case NF_KEY_AAA: // AAA + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_DAY_NAME, nNatNum ); + break; + case NF_KEY_NNN: // NNN + case NF_KEY_AAAA: // AAAA + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + break; + case NF_KEY_NNNN: // NNNN + { + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_DAY_NAME, nNatNum ); + OutString += rLoc().getLongDateDayOfWeekSep(); + } + break; + case NF_KEY_WW : // WW + { + sal_Int16 nVal = rCal.getValue( CalendarFieldIndex::WEEK_OF_YEAR ); + OutString += ImpIntToString( nIx, nVal ); + } + break; + case NF_KEY_G: // G + ImpAppendEraG( OutString, rCal, nNatNum ); + break; + case NF_KEY_GG: // GG + OutString += rCal.getDisplayString( + CalendarDisplayCode::SHORT_ERA, nNatNum ); + break; + case NF_KEY_GGG: // GGG + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_ERA, nNatNum ); + break; + case NF_KEY_RR: // RR => GGGEE + OutString += rCal.getDisplayString( + CalendarDisplayCode::LONG_YEAR_AND_ERA, nNatNum ); + break; + } + } + if ( aOrgCalendar.Len() ) + rCal.loadCalendar( aOrgCalendar, rLoc().getLocale() ); // restore calendar + return bRes; +} + +BOOL SvNumberformat::ImpGetNumberOutput(double fNumber, + USHORT nIx, + String& OutString) +{ + BOOL bRes = FALSE; + BOOL bSign; + if (fNumber < 0.0) + { + if (nIx == 0) // nicht in hinteren + bSign = TRUE; // Formaten + else + bSign = FALSE; + fNumber = -fNumber; + } + else + { + bSign = FALSE; + if ( ::rtl::math::isSignBitSet( fNumber ) ) + fNumber = -fNumber; // yes, -0.0 is possible, eliminate '-' + } + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + if (rInfo.eScannedType == NUMBERFORMAT_PERCENT) + { + if (fNumber < _D_MAX_D_BY_100) + fNumber *= 100.0; + else + { + OutString = rScan.GetErrorString(); + return FALSE; + } + } + USHORT i, j; + xub_StrLen k; + String sStr; + long nPrecExp; + BOOL bInteger = FALSE; + if ( rInfo.nThousand != FLAG_STANDARD_IN_FORMAT ) + { // special formatting only if no GENERAL keyword in format code + const USHORT nThousand = rInfo.nThousand; + for (i = 0; i < nThousand; i++) + { + if (fNumber > _D_MIN_M_BY_1000) + fNumber /= 1000.0; + else + fNumber = 0.0; + } + if (fNumber > 0.0) + nPrecExp = GetPrecExp( fNumber ); + else + nPrecExp = 0; + if (rInfo.nCntPost) // NachkommaStellen + { + if (rInfo.nCntPost + nPrecExp > 15 && nPrecExp < 15) + { + sStr = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_F, 15-nPrecExp, '.'); + for (long l = 15-nPrecExp; l < (long) rInfo.nCntPost; l++) + sStr += '0'; + } + else + sStr = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_F, rInfo.nCntPost, '.' ); + sStr.EraseLeadingChars('0'); // fuehrende Nullen weg + } + else if (fNumber == 0.0) // Null + { + // nothing to be done here, keep empty string sStr, + // ImpNumberFillWithThousands does the rest + } + else // Integer + { + sStr = ::rtl::math::doubleToUString( fNumber, + rtl_math_StringFormat_F, 0, '.'); + sStr.EraseLeadingChars('0'); // fuehrende Nullen weg + } + xub_StrLen nPoint = sStr.Search( '.' ); + if ( nPoint != STRING_NOTFOUND ) + { + register const sal_Unicode* p = sStr.GetBuffer() + nPoint; + while ( *++p == '0' ) + ; + if ( !*p ) + bInteger = TRUE; + sStr.Erase( nPoint, 1 ); // . herausnehmen + } + if (bSign && + (sStr.Len() == 0 || sStr.GetTokenCount('0') == sStr.Len()+1)) // nur 00000 + bSign = FALSE; // nicht -0.00 + } // End of != FLAG_STANDARD_IN_FORMAT + + // von hinten nach vorn + // editieren: + k = sStr.Len(); // hinter letzter Ziffer + j = NumFor[nIx].GetnAnz()-1; // letztes Symbol + // Nachkommastellen: + if (rInfo.nCntPost > 0) + { + BOOL bTrailing = TRUE; // ob Endnullen? + BOOL bFilled = FALSE; // ob aufgefuellt wurde ? + short nType; + while (j > 0 && // rueckwaerts + (nType = rInfo.nTypeArray[j]) != NF_SYMBOLTYPE_DECSEP) + { + switch ( nType ) + { + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + sStr.Insert( (sal_Unicode) 0x1B, k /*++*/ ); + sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); + break; + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_PERCENT: + sStr.Insert(rInfo.sStrArray[j],k); + break; + case NF_SYMBOLTYPE_THSEP: + if (rInfo.nThousand == 0) + sStr.Insert(rInfo.sStrArray[j],k); + break; + case NF_SYMBOLTYPE_DIGIT: + { + const String& rStr = rInfo.sStrArray[j]; + const sal_Unicode* p1 = rStr.GetBuffer(); + register const sal_Unicode* p = p1 + rStr.Len(); + while ( p1 < p-- ) + { + const sal_Unicode c = *p; + k--; + if ( sStr.GetChar(k) != '0' ) + bTrailing = FALSE; + if (bTrailing) + { + if ( c == '0' ) + bFilled = TRUE; + else if ( c == '-' ) + { + if ( bInteger ) + sStr.SetChar( k, '-' ); + bFilled = TRUE; + } + else if ( c == '?' ) + { + sStr.SetChar( k, ' ' ); + bFilled = TRUE; + } + else if ( !bFilled ) // # + sStr.Erase(k,1); + } + } // of for + } // of case digi + break; + case NF_KEY_CCC: // CCC-Waehrung + sStr.Insert(rScan.GetCurAbbrev(), k); + break; + case NF_KEY_GENERAL: // Standard im String + { + String sNum; + ImpGetOutputStandard(fNumber, sNum); + sNum.EraseLeadingChars('-'); + sStr.Insert(sNum, k); + } + break; + default: + break; + } // of switch + j--; + } // of while + } // of Nachkomma + + bRes |= ImpNumberFillWithThousands(sStr, fNumber, k, j, nIx, // ggfs Auffuellen mit . + rInfo.nCntPre); + if ( rInfo.nCntPost > 0 ) + { + const String& rDecSep = GetFormatter().GetNumDecimalSep(); + xub_StrLen nLen = rDecSep.Len(); + if ( sStr.Len() > nLen && sStr.Equals( rDecSep, sStr.Len() - nLen, nLen ) ) + sStr.Erase( sStr.Len() - nLen ); // no decimals => strip DecSep + } + if (bSign) + sStr.Insert('-',0); + ImpTransliterate( sStr, NumFor[nIx].GetNatNum() ); + OutString = sStr; + return bRes; +} + +BOOL SvNumberformat::ImpNumberFillWithThousands( + String& sStr, // number string + double& rNumber, // number + xub_StrLen k, // position within string + USHORT j, // symbol index within format code + USHORT nIx, // subformat index + USHORT nDigCnt) // count of integer digits in format +{ + BOOL bRes = FALSE; + xub_StrLen nLeadingStringChars = 0; // inserted StringChars before number + xub_StrLen nDigitCount = 0; // count of integer digits from the right + BOOL bStop = FALSE; + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + // no normal thousands separators if number divided by thousands + BOOL bDoThousands = (rInfo.nThousand == 0); + utl::DigitGroupingIterator aGrouping( + GetFormatter().GetLocaleData()->getDigitGrouping()); + while (!bStop) // backwards + { + if (j == 0) + bStop = TRUE; + switch (rInfo.nTypeArray[j]) + { + case NF_SYMBOLTYPE_DECSEP: + aGrouping.reset(); + // fall thru + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_PERCENT: + sStr.Insert(rInfo.sStrArray[j],k); + if ( k == 0 ) + nLeadingStringChars = + nLeadingStringChars + rInfo.sStrArray[j].Len(); + break; + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + sStr.Insert( (sal_Unicode) 0x1B, k/*++*/ ); + sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + /*k = */ InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); + break; + case NF_SYMBOLTYPE_THSEP: + { + // #i7284# #102685# Insert separator also if number is divided + // by thousands and the separator is specified somewhere in + // between and not only at the end. + // #i12596# But do not insert if it's a parenthesized negative + // format like (#,) + // In fact, do not insert if divided and regex [0#,],[^0#] and + // no other digit symbol follows (which was already detected + // during scan of format code, otherwise there would be no + // division), else do insert. Same in ImpNumberFill() below. + if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) + bDoThousands = ((j == 0) || + (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && + rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || + (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); + if ( bDoThousands ) + { + if (k > 0) + sStr.Insert(rInfo.sStrArray[j],k); + else if (nDigitCount < nDigCnt) + { + // Leading '#' displays nothing (e.g. no leading + // separator for numbers <1000 with #,##0 format). + // Leading '?' displays blank. + // Everything else, including nothing, displays the + // separator. + sal_Unicode cLeader = 0; + if (j > 0 && rInfo.nTypeArray[j-1] == NF_SYMBOLTYPE_DIGIT) + { + const String& rStr = rInfo.sStrArray[j-1]; + xub_StrLen nLen = rStr.Len(); + if (nLen) + cLeader = rStr.GetChar(nLen-1); + } + switch (cLeader) + { + case '#': + ; // nothing + break; + case '?': + // erAck: 2008-04-03T16:24+0200 + // Actually this currently isn't executed + // because the format scanner in the context of + // "?," doesn't generate a group separator but + // a literal ',' character instead that is + // inserted unconditionally. Should be changed + // on some occasion. + sStr.Insert(' ',k); + break; + default: + sStr.Insert(rInfo.sStrArray[j],k); + } + } + aGrouping.advance(); + } + } + break; + case NF_SYMBOLTYPE_DIGIT: + { + const String& rStr = rInfo.sStrArray[j]; + const sal_Unicode* p1 = rStr.GetBuffer(); + register const sal_Unicode* p = p1 + rStr.Len(); + while ( p1 < p-- ) + { + nDigitCount++; + if (k > 0) + k--; + else + { + switch (*p) + { + case '0': + sStr.Insert('0',0); + break; + case '?': + sStr.Insert(' ',0); + break; + } + } + if (nDigitCount == nDigCnt && k > 0) + { // more digits than specified + ImpDigitFill(sStr, 0, k, nIx, nDigitCount, aGrouping); + } + } + } + break; + case NF_KEY_CCC: // CCC currency + sStr.Insert(rScan.GetCurAbbrev(), k); + break; + case NF_KEY_GENERAL: // "General" in string + { + String sNum; + ImpGetOutputStandard(rNumber, sNum); + sNum.EraseLeadingChars('-'); + sStr.Insert(sNum, k); + } + break; + + default: + break; + } // switch + j--; // next format code string + } // while + k = k + nLeadingStringChars; // MSC converts += to int and then warns, so ... + if (k > nLeadingStringChars) + ImpDigitFill(sStr, nLeadingStringChars, k, nIx, nDigitCount, aGrouping); + return bRes; +} + +void SvNumberformat::ImpDigitFill( + String& sStr, // number string + xub_StrLen nStart, // start of digits + xub_StrLen& k, // position within string + USHORT nIx, // subformat index + xub_StrLen & nDigitCount, // count of integer digits from the right so far + utl::DigitGroupingIterator & rGrouping ) // current grouping +{ + if (NumFor[nIx].Info().bThousand) // only if grouping + { // fill in separators + const String& rThousandSep = GetFormatter().GetNumThousandSep(); + while (k > nStart) + { + if (nDigitCount == rGrouping.getPos()) + { + sStr.Insert( rThousandSep, k ); + rGrouping.advance(); + } + nDigitCount++; + k--; + } + } + else // simply skip + k = nStart; +} + +BOOL SvNumberformat::ImpNumberFill( String& sStr, // number string + double& rNumber, // number for "General" format + xub_StrLen& k, // position within string + USHORT& j, // symbol index within format code + USHORT nIx, // subformat index + short eSymbolType ) // type of stop condition +{ + BOOL bRes = FALSE; + k = sStr.Len(); // behind last digit + const ImpSvNumberformatInfo& rInfo = NumFor[nIx].Info(); + // no normal thousands separators if number divided by thousands + BOOL bDoThousands = (rInfo.nThousand == 0); + short nType; + while (j > 0 && (nType = rInfo.nTypeArray[j]) != eSymbolType ) + { // rueckwaerts: + switch ( nType ) + { + case NF_SYMBOLTYPE_STAR: + if( bStarFlag ) + { + sStr.Insert( sal_Unicode(0x1B), k++ ); + sStr.Insert(rInfo.sStrArray[j].GetChar(1),k); + bRes = TRUE; + } + break; + case NF_SYMBOLTYPE_BLANK: + k = InsertBlanks( sStr,k,rInfo.sStrArray[j].GetChar(1) ); + break; + case NF_SYMBOLTYPE_THSEP: + { + // Same as in ImpNumberFillWithThousands() above, do not insert + // if divided and regex [0#,],[^0#] and no other digit symbol + // follows (which was already detected during scan of format + // code, otherwise there would be no division), else do insert. + if ( !bDoThousands && j < NumFor[nIx].GetnAnz()-1 ) + bDoThousands = ((j == 0) || + (rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_DIGIT && + rInfo.nTypeArray[j-1] != NF_SYMBOLTYPE_THSEP) || + (rInfo.nTypeArray[j+1] == NF_SYMBOLTYPE_DIGIT)); + if ( bDoThousands && k > 0 ) + { + sStr.Insert(rInfo.sStrArray[j],k); + } + } + break; + case NF_SYMBOLTYPE_DIGIT: + { + const String& rStr = rInfo.sStrArray[j]; + const sal_Unicode* p1 = rStr.GetBuffer(); + register const sal_Unicode* p = p1 + rStr.Len(); + while ( p1 < p-- ) + { + if (k > 0) + k--; + else + { + switch (*p) + { + case '0': + sStr.Insert('0',0); + break; + case '?': + sStr.Insert(' ',0); + break; + } + } + } + } + break; + case NF_KEY_CCC: // CCC-Waehrung + sStr.Insert(rScan.GetCurAbbrev(), k); + break; + case NF_KEY_GENERAL: // Standard im String + { + String sNum; + ImpGetOutputStandard(rNumber, sNum); + sNum.EraseLeadingChars('-'); // Vorzeichen weg!! + sStr.Insert(sNum, k); + } + break; + + default: + sStr.Insert(rInfo.sStrArray[j],k); + break; + } // of switch + j--; // naechster String + } // of while + return bRes; +} + +void SvNumberformat::GetFormatSpecialInfo(BOOL& bThousand, + BOOL& IsRed, + USHORT& nPrecision, + USHORT& nAnzLeading) const +{ + // as before: take info from nNumFor=0 for whole format (for dialog etc.) + + short nDummyType; + GetNumForInfo( 0, nDummyType, bThousand, nPrecision, nAnzLeading ); + + // "negative in red" is only useful for the whole format + + const Color* pColor = NumFor[1].GetColor(); + if (fLimit1 == 0.0 && fLimit2 == 0.0 && pColor + && (*pColor == rScan.GetRedColor())) + IsRed = TRUE; + else + IsRed = FALSE; +} + +void SvNumberformat::GetNumForInfo( USHORT nNumFor, short& rScannedType, + BOOL& bThousand, USHORT& nPrecision, USHORT& nAnzLeading ) const +{ + // take info from a specified sub-format (for XML export) + + if ( nNumFor > 3 ) + return; // invalid + + const ImpSvNumberformatInfo& rInfo = NumFor[nNumFor].Info(); + rScannedType = rInfo.eScannedType; + bThousand = rInfo.bThousand; + nPrecision = rInfo.nCntPost; + if (bStandard && rInfo.eScannedType == NUMBERFORMAT_NUMBER) + // StandardFormat + nAnzLeading = 1; + else + { + nAnzLeading = 0; + BOOL bStop = FALSE; + USHORT i = 0; + const USHORT nAnz = NumFor[nNumFor].GetnAnz(); + while (!bStop && i < nAnz) + { + short nType = rInfo.nTypeArray[i]; + if ( nType == NF_SYMBOLTYPE_DIGIT) + { + register const sal_Unicode* p = rInfo.sStrArray[i].GetBuffer(); + while ( *p == '#' ) + p++; + while ( *p++ == '0' ) + nAnzLeading++; + } + else if (nType == NF_SYMBOLTYPE_DECSEP || nType == NF_SYMBOLTYPE_EXP) + bStop = TRUE; + i++; + } + } +} + +const String* SvNumberformat::GetNumForString( USHORT nNumFor, USHORT nPos, + BOOL bString /* = FALSE */ ) const +{ + if ( nNumFor > 3 ) + return NULL; + USHORT nAnz = NumFor[nNumFor].GetnAnz(); + if ( !nAnz ) + return NULL; + if ( nPos == 0xFFFF ) + { + nPos = nAnz - 1; + if ( bString ) + { // rueckwaerts + short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; + while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && + (*pType != NF_SYMBOLTYPE_CURRENCY) ) + { + pType--; + nPos--; + } + if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) + return NULL; + } + } + else if ( nPos > nAnz - 1 ) + return NULL; + else if ( bString ) + { // vorwaerts + short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; + while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && + (*pType != NF_SYMBOLTYPE_CURRENCY) ) + { + pType++; + nPos++; + } + if ( nPos >= nAnz || ((*pType != NF_SYMBOLTYPE_STRING) && + (*pType != NF_SYMBOLTYPE_CURRENCY)) ) + return NULL; + } + return &NumFor[nNumFor].Info().sStrArray[nPos]; +} + + +short SvNumberformat::GetNumForType( USHORT nNumFor, USHORT nPos, + BOOL bString /* = FALSE */ ) const +{ + if ( nNumFor > 3 ) + return 0; + USHORT nAnz = NumFor[nNumFor].GetnAnz(); + if ( !nAnz ) + return 0; + if ( nPos == 0xFFFF ) + { + nPos = nAnz - 1; + if ( bString ) + { // rueckwaerts + short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; + while ( nPos > 0 && (*pType != NF_SYMBOLTYPE_STRING) && + (*pType != NF_SYMBOLTYPE_CURRENCY) ) + { + pType--; + nPos--; + } + if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) + return 0; + } + } + else if ( nPos > nAnz - 1 ) + return 0; + else if ( bString ) + { // vorwaerts + short* pType = NumFor[nNumFor].Info().nTypeArray + nPos; + while ( nPos < nAnz && (*pType != NF_SYMBOLTYPE_STRING) && + (*pType != NF_SYMBOLTYPE_CURRENCY) ) + { + pType++; + nPos++; + } + if ( (*pType != NF_SYMBOLTYPE_STRING) && (*pType != NF_SYMBOLTYPE_CURRENCY) ) + return 0; + } + return NumFor[nNumFor].Info().nTypeArray[nPos]; +} + + +BOOL SvNumberformat::IsNegativeWithoutSign() const +{ + if ( IsNegativeRealNegative() ) + { + const String* pStr = GetNumForString( 1, 0, TRUE ); + if ( pStr ) + return !HasStringNegativeSign( *pStr ); + } + return FALSE; +} + + +DateFormat SvNumberformat::GetDateOrder() const +{ + if ( (eType & NUMBERFORMAT_DATE) == NUMBERFORMAT_DATE ) + { + short const * const pType = NumFor[0].Info().nTypeArray; + USHORT nAnz = NumFor[0].GetnAnz(); + for ( USHORT j=0; j<nAnz; j++ ) + { + switch ( pType[j] ) + { + case NF_KEY_D : + case NF_KEY_DD : + return DMY; + case NF_KEY_M : + case NF_KEY_MM : + case NF_KEY_MMM : + case NF_KEY_MMMM : + case NF_KEY_MMMMM : + return MDY; + case NF_KEY_YY : + case NF_KEY_YYYY : + case NF_KEY_EC : + case NF_KEY_EEC : + case NF_KEY_R : + case NF_KEY_RR : + return YMD; + } + } + } + else + { + DBG_ERROR( "SvNumberformat::GetDateOrder: no date" ); + } + return rLoc().getDateFormat(); +} + + +sal_uInt32 SvNumberformat::GetExactDateOrder() const +{ + sal_uInt32 nRet = 0; + if ( (eType & NUMBERFORMAT_DATE) != NUMBERFORMAT_DATE ) + { + DBG_ERROR( "SvNumberformat::GetExactDateOrder: no date" ); + return nRet; + } + short const * const pType = NumFor[0].Info().nTypeArray; + USHORT nAnz = NumFor[0].GetnAnz(); + int nShift = 0; + for ( USHORT j=0; j<nAnz && nShift < 3; j++ ) + { + switch ( pType[j] ) + { + case NF_KEY_D : + case NF_KEY_DD : + nRet = (nRet << 8) | 'D'; + ++nShift; + break; + case NF_KEY_M : + case NF_KEY_MM : + case NF_KEY_MMM : + case NF_KEY_MMMM : + case NF_KEY_MMMMM : + nRet = (nRet << 8) | 'M'; + ++nShift; + break; + case NF_KEY_YY : + case NF_KEY_YYYY : + case NF_KEY_EC : + case NF_KEY_EEC : + case NF_KEY_R : + case NF_KEY_RR : + nRet = (nRet << 8) | 'Y'; + ++nShift; + break; + } + } + return nRet; +} + + +void SvNumberformat::GetConditions( SvNumberformatLimitOps& rOper1, double& rVal1, + SvNumberformatLimitOps& rOper2, double& rVal2 ) const +{ + rOper1 = eOp1; + rOper2 = eOp2; + rVal1 = fLimit1; + rVal2 = fLimit2; +} + + +Color* SvNumberformat::GetColor( USHORT nNumFor ) const +{ + if ( nNumFor > 3 ) + return NULL; + + return NumFor[nNumFor].GetColor(); +} + + +void lcl_SvNumberformat_AddLimitStringImpl( String& rStr, + SvNumberformatLimitOps eOp, double fLimit, const String& rDecSep ) +{ + if ( eOp != NUMBERFORMAT_OP_NO ) + { + switch ( eOp ) + { + case NUMBERFORMAT_OP_EQ : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[=" ) ); + break; + case NUMBERFORMAT_OP_NE : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<>" ) ); + break; + case NUMBERFORMAT_OP_LT : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<" ) ); + break; + case NUMBERFORMAT_OP_LE : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[<=" ) ); + break; + case NUMBERFORMAT_OP_GT : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>" ) ); + break; + case NUMBERFORMAT_OP_GE : + rStr.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "[>=" ) ); + break; + default: + OSL_ASSERT( "unsupported number format" ); + break; + } + rStr += String( ::rtl::math::doubleToUString( fLimit, + rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max, + rDecSep.GetChar(0), sal_True)); + rStr += ']'; + } +} + + +String SvNumberformat::GetMappedFormatstring( + const NfKeywordTable& rKeywords, const LocaleDataWrapper& rLocWrp, + BOOL bDontQuote ) const +{ + String aStr; + BOOL bDefault[4]; + // 1 subformat matches all if no condition specified, + bDefault[0] = ( NumFor[1].GetnAnz() == 0 && eOp1 == NUMBERFORMAT_OP_NO ); + // with 2 subformats [>=0];[<0] is implied if no condition specified + bDefault[1] = ( !bDefault[0] && NumFor[2].GetnAnz() == 0 && + eOp1 == NUMBERFORMAT_OP_GE && fLimit1 == 0.0 && + eOp2 == NUMBERFORMAT_OP_NO && fLimit2 == 0.0 ); + // with 3 or more subformats [>0];[<0];[=0] is implied if no condition specified, + // note that subformats may be empty (;;;) and NumFor[2].GetnAnz()>0 is not checked. + bDefault[2] = ( !bDefault[0] && !bDefault[1] && + eOp1 == NUMBERFORMAT_OP_GT && fLimit1 == 0.0 && + eOp2 == NUMBERFORMAT_OP_LT && fLimit2 == 0.0 ); + BOOL bDefaults = bDefault[0] || bDefault[1] || bDefault[2]; + // from now on bDefault[] values are used to append empty subformats at the end + bDefault[3] = FALSE; + if ( !bDefaults ) + { // conditions specified + if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 == NUMBERFORMAT_OP_NO ) + bDefault[0] = bDefault[1] = TRUE; // [];x + else if ( eOp1 != NUMBERFORMAT_OP_NO && eOp2 != NUMBERFORMAT_OP_NO && + NumFor[2].GetnAnz() == 0 ) + bDefault[0] = bDefault[1] = bDefault[2] = bDefault[3] = TRUE; // [];[];; + // nothing to do if conditions specified for every subformat + } + else if ( bDefault[0] ) + bDefault[0] = FALSE; // a single unconditional subformat is never delimited + else + { + if ( bDefault[2] && NumFor[2].GetnAnz() == 0 && NumFor[1].GetnAnz() > 0 ) + bDefault[3] = TRUE; // special cases x;x;; and ;x;; + for ( int i=0; i<3 && !bDefault[i]; ++i ) + bDefault[i] = TRUE; + } + int nSem = 0; // needed ';' delimiters + int nSub = 0; // subformats delimited so far + for ( int n=0; n<4; n++ ) + { + if ( n > 0 ) + nSem++; + + String aPrefix; + + if ( !bDefaults ) + { + switch ( n ) + { + case 0 : + lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp1, + fLimit1, rLocWrp.getNumDecimalSep() ); + break; + case 1 : + lcl_SvNumberformat_AddLimitStringImpl( aPrefix, eOp2, + fLimit2, rLocWrp.getNumDecimalSep() ); + break; + } + } + + const String& rColorName = NumFor[n].GetColorName(); + if ( rColorName.Len() ) + { + const String* pKey = rScan.GetKeywords() + NF_KEY_FIRSTCOLOR; + for ( int j=NF_KEY_FIRSTCOLOR; j<=NF_KEY_LASTCOLOR; j++, pKey++ ) + { + if ( *pKey == rColorName ) + { + aPrefix += '['; + aPrefix += rKeywords[j]; + aPrefix += ']'; + break; // for + } + } + } + + const SvNumberNatNum& rNum = NumFor[n].GetNatNum(); + // The Thai T NatNum modifier during Xcl export. + if (rNum.IsSet() && rNum.GetNatNum() == 1 && + rKeywords[NF_KEY_THAI_T].EqualsAscii( "T") && + MsLangId::getRealLanguage( rNum.GetLang()) == + LANGUAGE_THAI) + { + aPrefix += 't'; // must be lowercase, otherwise taken as literal + } + + USHORT nAnz = NumFor[n].GetnAnz(); + if ( nSem && (nAnz || aPrefix.Len()) ) + { + for ( ; nSem; --nSem ) + aStr += ';'; + for ( ; nSub <= n; ++nSub ) + bDefault[nSub] = FALSE; + } + + if ( aPrefix.Len() ) + aStr += aPrefix; + + if ( nAnz ) + { + const short* pType = NumFor[n].Info().nTypeArray; + const String* pStr = NumFor[n].Info().sStrArray; + for ( USHORT j=0; j<nAnz; j++ ) + { + if ( 0 <= pType[j] && pType[j] < NF_KEYWORD_ENTRIES_COUNT ) + { + aStr += rKeywords[pType[j]]; + if( NF_KEY_NNNN == pType[j] ) + aStr += rLocWrp.getLongDateDayOfWeekSep(); + } + else + { + switch ( pType[j] ) + { + case NF_SYMBOLTYPE_DECSEP : + aStr += rLocWrp.getNumDecimalSep(); + break; + case NF_SYMBOLTYPE_THSEP : + aStr += rLocWrp.getNumThousandSep(); + break; + case NF_SYMBOLTYPE_DATESEP : + aStr += rLocWrp.getDateSep(); + break; + case NF_SYMBOLTYPE_TIMESEP : + aStr += rLocWrp.getTimeSep(); + break; + case NF_SYMBOLTYPE_TIME100SECSEP : + aStr += rLocWrp.getTime100SecSep(); + break; + case NF_SYMBOLTYPE_STRING : + if( bDontQuote ) + aStr += pStr[j]; + else if ( pStr[j].Len() == 1 ) + { + aStr += '\\'; + aStr += pStr[j]; + } + else + { + aStr += '"'; + aStr += pStr[j]; + aStr += '"'; + } + break; + default: + aStr += pStr[j]; + } + + } + } + } + } + for ( ; nSub<4 && bDefault[nSub]; ++nSub ) + { // append empty subformats + aStr += ';'; + } + return aStr; +} + + +String SvNumberformat::ImpGetNatNumString( const SvNumberNatNum& rNum, + sal_Int32 nVal, USHORT nMinDigits ) const +{ + String aStr; + if ( nMinDigits ) + { + if ( nMinDigits == 2 ) + { // speed up the most common case + if ( 0 <= nVal && nVal < 10 ) + { + sal_Unicode* p = aStr.AllocBuffer( 2 ); + *p++ = '0'; + *p = sal_Unicode( '0' + nVal ); + } + else + aStr = String::CreateFromInt32( nVal ); + } + else + { + String aValStr( String::CreateFromInt32( nVal ) ); + if ( aValStr.Len() >= nMinDigits ) + aStr = aValStr; + else + { + aStr.Fill( nMinDigits - aValStr.Len(), '0' ); + aStr += aValStr; + } + } + } + else + aStr = String::CreateFromInt32( nVal ); + ImpTransliterate( aStr, rNum ); + return aStr; +} + + +void SvNumberformat::ImpTransliterateImpl( String& rStr, + const SvNumberNatNum& rNum ) const +{ + com::sun::star::lang::Locale aLocale( + MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); + rStr = GetFormatter().GetNatNum()->getNativeNumberString( rStr, + aLocale, rNum.GetNatNum() ); +} + + +void SvNumberformat::GetNatNumXml( + com::sun::star::i18n::NativeNumberXmlAttributes& rAttr, + USHORT nNumFor ) const +{ + if ( nNumFor <= 3 ) + { + const SvNumberNatNum& rNum = NumFor[nNumFor].GetNatNum(); + if ( rNum.IsSet() ) + { + com::sun::star::lang::Locale aLocale( + MsLangId::convertLanguageToLocale( rNum.GetLang() ) ); + rAttr = GetFormatter().GetNatNum()->convertToXmlAttributes( + aLocale, rNum.GetNatNum() ); + } + else + rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); + } + else + rAttr = com::sun::star::i18n::NativeNumberXmlAttributes(); +} + +// static +BOOL SvNumberformat::HasStringNegativeSign( const String& rStr ) +{ + // fuer Sign muss '-' am Anfang oder am Ende des TeilStrings sein (Blanks ignored) + xub_StrLen nLen = rStr.Len(); + if ( !nLen ) + return FALSE; + const sal_Unicode* const pBeg = rStr.GetBuffer(); + const sal_Unicode* const pEnd = pBeg + nLen; + register const sal_Unicode* p = pBeg; + do + { // Anfang + if ( *p == '-' ) + return TRUE; + } while ( *p == ' ' && ++p < pEnd ); + p = pEnd - 1; + do + { // Ende + if ( *p == '-' ) + return TRUE; + } while ( *p == ' ' && pBeg < --p ); + return FALSE; +} + + +// static +void SvNumberformat::SetComment( const String& rStr, String& rFormat, + String& rComment ) +{ + if ( rComment.Len() ) + { // alten Kommentar aus Formatstring loeschen + //! nicht per EraseComment, der Kommentar muss matchen + String aTmp( '{' ); + aTmp += ' '; + aTmp += rComment; + aTmp += ' '; + aTmp += '}'; + xub_StrLen nCom = 0; + do + { + nCom = rFormat.Search( aTmp, nCom ); + } while ( (nCom != STRING_NOTFOUND) && (nCom + aTmp.Len() != rFormat.Len()) ); + if ( nCom != STRING_NOTFOUND ) + rFormat.Erase( nCom ); + } + if ( rStr.Len() ) + { // neuen Kommentar setzen + rFormat += '{'; + rFormat += ' '; + rFormat += rStr; + rFormat += ' '; + rFormat += '}'; + rComment = rStr; + } +} + + +// static +void SvNumberformat::EraseCommentBraces( String& rStr ) +{ + xub_StrLen nLen = rStr.Len(); + if ( nLen && rStr.GetChar(0) == '{' ) + { + rStr.Erase( 0, 1 ); + --nLen; + } + if ( nLen && rStr.GetChar(0) == ' ' ) + { + rStr.Erase( 0, 1 ); + --nLen; + } + if ( nLen && rStr.GetChar( nLen-1 ) == '}' ) + rStr.Erase( --nLen, 1 ); + if ( nLen && rStr.GetChar( nLen-1 ) == ' ' ) + rStr.Erase( --nLen, 1 ); +} + + +// static +void SvNumberformat::EraseComment( String& rStr ) +{ + register const sal_Unicode* p = rStr.GetBuffer(); + BOOL bInString = FALSE; + BOOL bEscaped = FALSE; + BOOL bFound = FALSE; + xub_StrLen nPos = 0; + while ( !bFound && *p ) + { + switch ( *p ) + { + case '\\' : + bEscaped = !bEscaped; + break; + case '\"' : + if ( !bEscaped ) + bInString = !bInString; + break; + case '{' : + if ( !bEscaped && !bInString ) + { + bFound = TRUE; + nPos = sal::static_int_cast< xub_StrLen >( + p - rStr.GetBuffer()); + } + break; + } + if ( bEscaped && *p != '\\' ) + bEscaped = FALSE; + ++p; + } + if ( bFound ) + rStr.Erase( nPos ); +} + + +// static +BOOL SvNumberformat::IsInQuote( const String& rStr, xub_StrLen nPos, + sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) +{ + xub_StrLen nLen = rStr.Len(); + if ( nPos >= nLen ) + return FALSE; + register const sal_Unicode* p0 = rStr.GetBuffer(); + register const sal_Unicode* p = p0; + register const sal_Unicode* p1 = p0 + nPos; + BOOL bQuoted = FALSE; + while ( p <= p1 ) + { + if ( *p == cQuote ) + { + if ( p == p0 ) + bQuoted = TRUE; + else if ( bQuoted ) + { + if ( *(p-1) != cEscIn ) + bQuoted = FALSE; + } + else + { + if ( *(p-1) != cEscOut ) + bQuoted = TRUE; + } + } + p++; + } + return bQuoted; +} + + +// static +xub_StrLen SvNumberformat::GetQuoteEnd( const String& rStr, xub_StrLen nPos, + sal_Unicode cQuote, sal_Unicode cEscIn, sal_Unicode cEscOut ) +{ + xub_StrLen nLen = rStr.Len(); + if ( nPos >= nLen ) + return STRING_NOTFOUND; + if ( !IsInQuote( rStr, nPos, cQuote, cEscIn, cEscOut ) ) + { + if ( rStr.GetChar( nPos ) == cQuote ) + return nPos; // schliessendes cQuote + return STRING_NOTFOUND; + } + register const sal_Unicode* p0 = rStr.GetBuffer(); + register const sal_Unicode* p = p0 + nPos; + register const sal_Unicode* p1 = p0 + nLen; + while ( p < p1 ) + { + if ( *p == cQuote && p > p0 && *(p-1) != cEscIn ) + return sal::static_int_cast< xub_StrLen >(p - p0); + p++; + } + return nLen; // String Ende +} + + +USHORT SvNumberformat::ImpGetNumForStringElementCount( USHORT nNumFor ) const +{ + USHORT nCnt = 0; + USHORT nAnz = NumFor[nNumFor].GetnAnz(); + short const * const pType = NumFor[nNumFor].Info().nTypeArray; + for ( USHORT j=0; j<nAnz; ++j ) + { + switch ( pType[j] ) + { + case NF_SYMBOLTYPE_STRING: + case NF_SYMBOLTYPE_CURRENCY: + case NF_SYMBOLTYPE_DATESEP: + case NF_SYMBOLTYPE_TIMESEP: + case NF_SYMBOLTYPE_TIME100SECSEP: + case NF_SYMBOLTYPE_PERCENT: + ++nCnt; + break; + } + } + return nCnt; +} + diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx new file mode 100644 index 000000000000..5c0d45a53ed2 --- /dev/null +++ b/svl/source/numbers/zforscan.cxx @@ -0,0 +1,2812 @@ +/************************************************************************* + * + * 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: zforscan.cxx,v $ + * $Revision: 1.49.140.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifndef GCC +#endif + +#include <stdlib.h> +#include <tools/debug.hxx> +#include <i18npool/mslangid.hxx> +#include <unotools/charclass.hxx> +#include <unotools/localedatawrapper.hxx> +#include <unotools/numberformatcodewrapper.hxx> +#include <rtl/instance.hxx> + +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <unotools/digitgroupingiterator.hxx> + +#define _ZFORSCAN_CXX +#include "zforscan.hxx" +#undef _ZFORSCAN_CXX +#include "nfsymbol.hxx" +using namespace svt; + +const sal_Unicode cNonBreakingSpace = 0xA0; + +namespace +{ + struct ImplEnglishColors + { + const String* operator()() + { + static const String aEnglishColors[NF_MAX_DEFAULT_COLORS] = + { + String( RTL_CONSTASCII_USTRINGPARAM( "BLACK" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "BLUE" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "GREEN" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "CYAN" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "RED" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "MAGENTA" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "BROWN" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "GREY" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "YELLOW" ) ), + String( RTL_CONSTASCII_USTRINGPARAM( "WHITE" ) ) + }; + return &aEnglishColors[0]; + } + }; + + struct theEnglishColors + : public rtl::StaticAggregate< const String, ImplEnglishColors> {}; + +} + +ImpSvNumberformatScan::ImpSvNumberformatScan( SvNumberFormatter* pFormatterP ) +{ + pFormatter = pFormatterP; + bConvertMode = FALSE; + //! All keywords MUST be UPPERCASE! + sKeyword[NF_KEY_E].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) ); // Exponent + sKeyword[NF_KEY_AMPM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AM/PM" ) ); // AM/PM + sKeyword[NF_KEY_AP].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "A/P" ) ); // AM/PM short + sKeyword[NF_KEY_MI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // Minute + sKeyword[NF_KEY_MMI].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // Minute 02 + sKeyword[NF_KEY_S].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "S" ) ); // Second + sKeyword[NF_KEY_SS].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SS" ) ); // Second 02 + sKeyword[NF_KEY_Q].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "Q" ) ); // Quarter short 'Q' + sKeyword[NF_KEY_QQ].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "QQ" ) ); // Quarter long + sKeyword[NF_KEY_NN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NN" ) ); // Day of week short + sKeyword[NF_KEY_NNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNN" ) ); // Day of week long + sKeyword[NF_KEY_NNNN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NNNN" ) ); // Day of week long incl. separator + sKeyword[NF_KEY_WW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WW" ) ); // Week of year + sKeyword[NF_KEY_CCC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CCC" ) ); // Currency abbreviation + bKeywordsNeedInit = TRUE; // locale dependent keywords + bCompatCurNeedInit = TRUE; // locale dependent compatibility currency strings + + StandardColor[0] = Color(COL_BLACK); + StandardColor[1] = Color(COL_LIGHTBLUE); + StandardColor[2] = Color(COL_LIGHTGREEN); + StandardColor[3] = Color(COL_LIGHTCYAN); + StandardColor[4] = Color(COL_LIGHTRED); + StandardColor[5] = Color(COL_LIGHTMAGENTA); + StandardColor[6] = Color(COL_BROWN); + StandardColor[7] = Color(COL_GRAY); + StandardColor[8] = Color(COL_YELLOW); + StandardColor[9] = Color(COL_WHITE); + + pNullDate = new Date(30,12,1899); + nStandardPrec = 2; + + sErrStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "###" ) ); + Reset(); +} + +ImpSvNumberformatScan::~ImpSvNumberformatScan() +{ + delete pNullDate; + Reset(); +} + + +void ImpSvNumberformatScan::ChangeIntl() +{ + bKeywordsNeedInit = TRUE; + bCompatCurNeedInit = TRUE; + // may be initialized by InitSpecialKeyword() + sKeyword[NF_KEY_TRUE].Erase(); + sKeyword[NF_KEY_FALSE].Erase(); +} + + +void ImpSvNumberformatScan::InitSpecialKeyword( NfKeywordIndex eIdx ) const +{ + switch ( eIdx ) + { + case NF_KEY_TRUE : + ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE] = + pFormatter->GetCharClass()->upper( + pFormatter->GetLocaleData()->getTrueWord() ); + if ( !sKeyword[NF_KEY_TRUE].Len() ) + { + DBG_ERRORFILE( "InitSpecialKeyword: TRUE_WORD?" ); + ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_TRUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TRUE" ) ); + } + break; + case NF_KEY_FALSE : + ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE] = + pFormatter->GetCharClass()->upper( + pFormatter->GetLocaleData()->getFalseWord() ); + if ( !sKeyword[NF_KEY_FALSE].Len() ) + { + DBG_ERRORFILE( "InitSpecialKeyword: FALSE_WORD?" ); + ((ImpSvNumberformatScan*)this)->sKeyword[NF_KEY_FALSE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FALSE" ) ); + } + break; + default: + DBG_ERRORFILE( "InitSpecialKeyword: unknown request" ); + } +} + + +void ImpSvNumberformatScan::InitCompatCur() const +{ + ImpSvNumberformatScan* pThis = (ImpSvNumberformatScan*)this; + // currency symbol for old style ("automatic") compatibility format codes + pFormatter->GetCompatibilityCurrency( pThis->sCurSymbol, pThis->sCurAbbrev ); + // currency symbol upper case + pThis->sCurString = pFormatter->GetCharClass()->upper( sCurSymbol ); + bCompatCurNeedInit = FALSE; +} + + +void ImpSvNumberformatScan::InitKeywords() const +{ + if ( !bKeywordsNeedInit ) + return ; + ((ImpSvNumberformatScan*)this)->SetDependentKeywords(); + bKeywordsNeedInit = FALSE; +} + + +/** Extract the name of General, Standard, Whatever, ignoring leading modifiers + such as [NatNum1]. */ +static String lcl_extractStandardGeneralName( const ::rtl::OUString & rCode ) +{ + String aStr; + const sal_Unicode* p = rCode.getStr(); + const sal_Unicode* const pStop = p + rCode.getLength(); + const sal_Unicode* pBeg = p; // name begins here + bool bMod = false; + bool bDone = false; + while (p < pStop && !bDone) + { + switch (*p) + { + case '[': + bMod = true; + break; + case ']': + if (bMod) + { + bMod = false; + pBeg = p+1; + } + // else: would be a locale data error, easily to be spotted in + // UI dialog + break; + case ';': + if (!bMod) + { + bDone = true; + --p; // put back, increment by one follows + } + break; + } + ++p; + if (bMod) + pBeg = p; + } + if (pBeg < p) + aStr = rCode.copy( pBeg - rCode.getStr(), p - pBeg); + return aStr; +} + + +void ImpSvNumberformatScan::SetDependentKeywords() +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + + const CharClass* pCharClass = pFormatter->GetCharClass(); + const LocaleDataWrapper* pLocaleData = pFormatter->GetLocaleData(); + // #80023# be sure to generate keywords for the loaded Locale, not for the + // requested Locale, otherwise number format codes might not match + lang::Locale aLoadedLocale = pLocaleData->getLoadedLocale(); + LanguageType eLang = MsLangId::convertLocaleToLanguage( aLoadedLocale ); + NumberFormatCodeWrapper aNumberFormatCode( pFormatter->GetServiceManager(), aLoadedLocale ); + + i18n::NumberFormatCode aFormat = aNumberFormatCode.getFormatCode( NF_NUMBER_STANDARD ); + sNameStandardFormat = lcl_extractStandardGeneralName( aFormat.Code); + sKeyword[NF_KEY_GENERAL] = pCharClass->upper( sNameStandardFormat ); + + // preset new calendar keywords + sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAA" ) ); + sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) ); + sKeyword[NF_KEY_EC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "E" ) ); + sKeyword[NF_KEY_EEC].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "EE" ) ); + sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) ); + sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) ); + sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) ); + sKeyword[NF_KEY_R].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "R" ) ); + sKeyword[NF_KEY_RR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RR" ) ); + + // Thai T NatNum special. Other locale's small letter 't' results in upper + // case comparison not matching but length does in conversion mode. Ugly. + if (eLang == LANGUAGE_THAI) + sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T")); + else + sKeyword[NF_KEY_THAI_T].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "t")); + + switch ( eLang ) + { + case LANGUAGE_GERMAN: + case LANGUAGE_GERMAN_SWISS: + case LANGUAGE_GERMAN_AUSTRIAN: + case LANGUAGE_GERMAN_LUXEMBOURG: + case LANGUAGE_GERMAN_LIECHTENSTEIN: + { + //! all capital letters + sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); // month 1 + sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); // month 01 + sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) ); // month Jan + sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) ); // month Januar + sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) );// month J + sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) ); // hour 2 + sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) ); // hour 02 + sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) ); + sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) ); + sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTT" ) ); + sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TTTT" ) ); + sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) ); + sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) ); + sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "LOGISCH" ) ); + sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "FARBE" ) ); + sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "SCHWARZ" ) ); + sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLAU" ) ); + sKeyword[NF_KEY_GREEN] = UniString( "GR" "\xDC" "N", RTL_TEXTENCODING_ISO_8859_1 ); + sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) ); + sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "ROT" ) ); + sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) ); + sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BRAUN" ) ); + sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GRAU" ) ); + sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GELB" ) ); + sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WEISS" ) ); + } + break; + default: + { + // day + switch ( eLang ) + { + case LANGUAGE_ITALIAN : + case LANGUAGE_ITALIAN_SWISS : + sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "G" ) ); + sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GG" ) ); + sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGG" ) ); + sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GGGG" ) ); + // must exchange the era code, same as Xcl + sKeyword[NF_KEY_G].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "X" ) ); + sKeyword[NF_KEY_GG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XX" ) ); + sKeyword[NF_KEY_GGG].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "XXX" ) ); + break; + case LANGUAGE_FRENCH : + case LANGUAGE_FRENCH_BELGIAN : + case LANGUAGE_FRENCH_CANADIAN : + case LANGUAGE_FRENCH_SWISS : + case LANGUAGE_FRENCH_LUXEMBOURG : + case LANGUAGE_FRENCH_MONACO : + sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "J" ) ); + sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) ); + sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJ" ) ); + sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) ); + break; + case LANGUAGE_FINNISH : + sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "P" ) ); + sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PP" ) ); + sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPP" ) ); + sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "PPPP" ) ); + break; + default: + sKeyword[NF_KEY_D].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "D" ) ); + sKeyword[NF_KEY_DD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DD" ) ); + sKeyword[NF_KEY_DDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDD" ) ); + sKeyword[NF_KEY_DDDD].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDDD" ) ); + } + // month + switch ( eLang ) + { + case LANGUAGE_FINNISH : + sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "K" ) ); + sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KK" ) ); + sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKK" ) ); + sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKK" ) ); + sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "KKKKK" ) ); + break; + default: + sKeyword[NF_KEY_M].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "M" ) ); + sKeyword[NF_KEY_MM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MM" ) ); + sKeyword[NF_KEY_MMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMM" ) ); + sKeyword[NF_KEY_MMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMM" ) ); + sKeyword[NF_KEY_MMMMM].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MMMMM" ) ); + } + // year + switch ( eLang ) + { + case LANGUAGE_ITALIAN : + case LANGUAGE_ITALIAN_SWISS : + case LANGUAGE_FRENCH : + case LANGUAGE_FRENCH_BELGIAN : + case LANGUAGE_FRENCH_CANADIAN : + case LANGUAGE_FRENCH_SWISS : + case LANGUAGE_FRENCH_LUXEMBOURG : + case LANGUAGE_FRENCH_MONACO : + case LANGUAGE_PORTUGUESE : + case LANGUAGE_PORTUGUESE_BRAZILIAN : + case LANGUAGE_SPANISH_MODERN : + case LANGUAGE_SPANISH_DATED : + case LANGUAGE_SPANISH_MEXICAN : + case LANGUAGE_SPANISH_GUATEMALA : + case LANGUAGE_SPANISH_COSTARICA : + case LANGUAGE_SPANISH_PANAMA : + case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC : + case LANGUAGE_SPANISH_VENEZUELA : + case LANGUAGE_SPANISH_COLOMBIA : + case LANGUAGE_SPANISH_PERU : + case LANGUAGE_SPANISH_ARGENTINA : + case LANGUAGE_SPANISH_ECUADOR : + case LANGUAGE_SPANISH_CHILE : + case LANGUAGE_SPANISH_URUGUAY : + case LANGUAGE_SPANISH_PARAGUAY : + case LANGUAGE_SPANISH_BOLIVIA : + case LANGUAGE_SPANISH_EL_SALVADOR : + case LANGUAGE_SPANISH_HONDURAS : + case LANGUAGE_SPANISH_NICARAGUA : + case LANGUAGE_SPANISH_PUERTO_RICO : + sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AA" ) ); + sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "AAAA" ) ); + // must exchange the day of week name code, same as Xcl + sKeyword[NF_KEY_AAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOO" ) ); + sKeyword[NF_KEY_AAAA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "OOOO" ) ); + break; + case LANGUAGE_DUTCH : + case LANGUAGE_DUTCH_BELGIAN : + sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJ" ) ); + sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "JJJJ" ) ); + break; + case LANGUAGE_FINNISH : + sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VV" ) ); + sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "VVVV" ) ); + break; + default: + sKeyword[NF_KEY_YY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YY" ) ); + sKeyword[NF_KEY_YYYY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YYYY" ) ); + } + // hour + switch ( eLang ) + { + case LANGUAGE_DUTCH : + case LANGUAGE_DUTCH_BELGIAN : + sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "U" ) ); + sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "UU" ) ); + break; + case LANGUAGE_FINNISH : + case LANGUAGE_SWEDISH : + case LANGUAGE_SWEDISH_FINLAND : + case LANGUAGE_DANISH : + case LANGUAGE_NORWEGIAN : + case LANGUAGE_NORWEGIAN_BOKMAL : + case LANGUAGE_NORWEGIAN_NYNORSK : + sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "T" ) ); + sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "TT" ) ); + break; + default: + sKeyword[NF_KEY_H].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "H" ) ); + sKeyword[NF_KEY_HH].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "HH" ) ); + } + // boolean + sKeyword[NF_KEY_BOOLEAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BOOLEAN" ) ); + // colours + sKeyword[NF_KEY_COLOR].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "COLOR" ) ); + sKeyword[NF_KEY_BLACK].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLACK" ) ); + sKeyword[NF_KEY_BLUE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BLUE" ) ); + sKeyword[NF_KEY_GREEN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREEN" ) ); + sKeyword[NF_KEY_CYAN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "CYAN" ) ); + sKeyword[NF_KEY_RED].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "RED" ) ); + sKeyword[NF_KEY_MAGENTA].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "MAGENTA" ) ); + sKeyword[NF_KEY_BROWN].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "BROWN" ) ); + sKeyword[NF_KEY_GREY].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "GREY" ) ); + sKeyword[NF_KEY_YELLOW].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "YELLOW" ) ); + sKeyword[NF_KEY_WHITE].AssignAscii( RTL_CONSTASCII_STRINGPARAM( "WHITE" ) ); + } + break; + } + + // boolean keyords + InitSpecialKeyword( NF_KEY_TRUE ); + InitSpecialKeyword( NF_KEY_FALSE ); + + // compatibility currency strings + InitCompatCur(); +} + + +void ImpSvNumberformatScan::ChangeNullDate(USHORT nDay, USHORT nMonth, USHORT nYear) +{ + if ( pNullDate ) + *pNullDate = Date(nDay, nMonth, nYear); + else + pNullDate = new Date(nDay, nMonth, nYear); +} + +void ImpSvNumberformatScan::ChangeStandardPrec(short nPrec) +{ + nStandardPrec = nPrec; +} + +Color* ImpSvNumberformatScan::GetColor(String& sStr) +{ + String sString = pFormatter->GetCharClass()->upper(sStr); + const String* pKeyword = GetKeywords(); + size_t i = 0; + while (i < NF_MAX_DEFAULT_COLORS && + sString != pKeyword[NF_KEY_FIRSTCOLOR+i] ) + i++; + if ( i >= NF_MAX_DEFAULT_COLORS ) + { + const String* pEnglishColors = theEnglishColors::get(); + size_t j = 0; + while ( j < NF_MAX_DEFAULT_COLORS && + sString != pEnglishColors[j] ) + ++j; + if ( j < NF_MAX_DEFAULT_COLORS ) + i = j; + } + + Color* pResult = NULL; + if (i >= NF_MAX_DEFAULT_COLORS) + { + const String& rColorWord = pKeyword[NF_KEY_COLOR]; + xub_StrLen nPos = sString.Match(rColorWord); + if (nPos > 0) + { + sStr.Erase(0, nPos); + sStr.EraseLeadingChars(); + sStr.EraseTrailingChars(); + if (bConvertMode) + { + pFormatter->ChangeIntl(eNewLnge); + sStr.Insert( GetKeywords()[NF_KEY_COLOR], 0 ); // Color -> FARBE + pFormatter->ChangeIntl(eTmpLnge); + } + else + sStr.Insert(rColorWord,0); + sString.Erase(0, nPos); + sString.EraseLeadingChars(); + sString.EraseTrailingChars(); + + if ( CharClass::isAsciiNumeric( sString ) ) + { + long nIndex = sString.ToInt32(); + if (nIndex > 0 && nIndex <= 64) + pResult = pFormatter->GetUserDefColor((USHORT)nIndex-1); + } + } + } + else + { + sStr.Erase(); + if (bConvertMode) + { + pFormatter->ChangeIntl(eNewLnge); + sStr = GetKeywords()[NF_KEY_FIRSTCOLOR+i]; // red -> rot + pFormatter->ChangeIntl(eTmpLnge); + } + else + sStr = pKeyword[NF_KEY_FIRSTCOLOR+i]; + + pResult = &(StandardColor[i]); + } + return pResult; +} + + +short ImpSvNumberformatScan::GetKeyWord( const String& sSymbol, xub_StrLen nPos ) +{ + String sString = pFormatter->GetCharClass()->toUpper( sSymbol, nPos, sSymbol.Len() - nPos ); + const String* pKeyword = GetKeywords(); + // #77026# for the Xcl perverts: the GENERAL keyword is recognized anywhere + if ( sString.Search( pKeyword[NF_KEY_GENERAL] ) == 0 ) + return NF_KEY_GENERAL; + //! MUST be a reverse search to find longer strings first + short i = NF_KEYWORD_ENTRIES_COUNT-1; + BOOL bFound = FALSE; + for ( ; i > NF_KEY_LASTKEYWORD_SO5; --i ) + { + bFound = sString.Search(pKeyword[i]) == 0; + if ( bFound ) + { + break; + } + } + // new keywords take precedence over old keywords + if ( !bFound ) + { // skip the gap of colors et al between new and old keywords and search on + i = NF_KEY_LASTKEYWORD; + while ( i > 0 && sString.Search(pKeyword[i]) != 0 ) + i--; + if ( i > NF_KEY_LASTOLDKEYWORD && sString != pKeyword[i] ) + { // found something, but maybe it's something else? + // e.g. new NNN is found in NNNN, for NNNN we must search on + short j = i - 1; + while ( j > 0 && sString.Search(pKeyword[j]) != 0 ) + j--; + if ( j && pKeyword[j].Len() > pKeyword[i].Len() ) + return j; + } + } + // The Thai T NatNum modifier during Xcl import. + if (i == 0 && bConvertMode && sString.GetChar(0) == 'T' && eTmpLnge == + LANGUAGE_ENGLISH_US && MsLangId::getRealLanguage( eNewLnge) == + LANGUAGE_THAI) + i = NF_KEY_THAI_T; + return i; // 0 => not found +} + +//--------------------------------------------------------------------------- +// Next_Symbol +//--------------------------------------------------------------------------- +// Zerlegt die Eingabe in Symbole fuer die weitere +// Verarbeitung (Turing-Maschine). +//--------------------------------------------------------------------------- +// Ausgangs Zustand = SsStart +//---------------+-------------------+-----------------------+--------------- +// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand +//---------------+-------------------+-----------------------+--------------- +// SsStart | Buchstabe | Symbol=Zeichen | SsGetWord +// | " | Typ = String | SsGetString +// | \ | Typ = String | SsGetChar +// | * | Typ = Star | SsGetStar +// | _ | Typ = Blank | SsGetBlank +// | @ # 0 ? / . , % [ | Symbol = Zeichen; | +// | ] ' Blank | Typ = Steuerzeichen | SsStop +// | $ - + ( ) : | Typ = String; | +// | | | Typ = Comment | SsStop +// | Sonst | Symbol = Zeichen | SsStop +//---------------|-------------------+-----------------------+--------------- +// SsGetChar | Sonst | Symbol=Zeichen | SsStop +//---------------+-------------------+-----------------------+--------------- +// GetString | " | | SsStop +// | Sonst | Symbol+=Zeichen | GetString +//---------------+-------------------+-----------------------+--------------- +// SsGetWord | Buchstabe | Symbol += Zeichen | +// | + - (E+ E-)| Symbol += Zeichen | SsStop +// | / (AM/PM)| Symbol += Zeichen | +// | Sonst | Pos--, if Key Typ=Word| SsStop +//---------------+-------------------+-----------------------+--------------- +// SsGetStar | Sonst | Symbol+=Zeichen | SsStop +// | | markiere Sonderfall * | +//---------------+-------------------+-----------------------+--------------- +// SsGetBlank | Sonst | Symbol+=Zeichen | SsStop +// | | markiere Sonderfall _ | +//---------------+-------------------+-----------------------+--------------- +// Wurde im State SsGetWord ein Schluesselwort erkannt (auch als +// Anfangsteilwort des Symbols) +// so werden die restlichen Buchstaben zurueckgeschrieben !! + +enum ScanState +{ + SsStop = 0, + SsStart = 1, + SsGetChar = 2, + SsGetString = 3, + SsGetWord = 4, + SsGetStar = 5, + SsGetBlank = 6 +}; + +short ImpSvNumberformatScan::Next_Symbol( const String& rStr, + xub_StrLen& nPos, String& sSymbol ) +{ + if ( bKeywordsNeedInit ) + InitKeywords(); + const CharClass* pChrCls = pFormatter->GetCharClass(); + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + const xub_StrLen nStart = nPos; + short eType = 0; + ScanState eState = SsStart; + sSymbol.Erase(); + while ( nPos < rStr.Len() && eState != SsStop ) + { + sal_Unicode cToken = rStr.GetChar( nPos++ ); + switch (eState) + { + case SsStart: + { + // Fetch any currency longer than one character and don't get + // confused later on by "E/" or other combinations of letters + // and meaningful symbols. Necessary for old automatic currency. + // #96158# But don't do it if we're starting a "[...]" section, + // for example a "[$...]" new currency symbol to not parse away + // "$U" (symbol) of "[$UYU]" (abbreviation). + if ( nCurrPos != STRING_NOTFOUND && sCurString.Len() > 1 && + nPos-1 + sCurString.Len() <= rStr.Len() && + !(nPos > 1 && rStr.GetChar( nPos-2 ) == '[') ) + { + String aTest( rStr.Copy( nPos-1, sCurString.Len() ) ); + pChrCls->toUpper( aTest ); + if ( aTest == sCurString ) + { + sSymbol = rStr.Copy( --nPos, sCurString.Len() ); + nPos = nPos + sSymbol.Len(); + eState = SsStop; + eType = NF_SYMBOLTYPE_STRING; + return eType; + } + } + switch (cToken) + { + case '#': + case '0': + case '?': + case '%': + case '@': + case '[': + case ']': + case ',': + case '.': + case '/': + case '\'': + case ' ': + case ':': + case '-': + { + eType = NF_SYMBOLTYPE_DEL; + sSymbol += cToken; + eState = SsStop; + } + break; + case '*': + { + eType = NF_SYMBOLTYPE_STAR; + sSymbol += cToken; + eState = SsGetStar; + } + break; + case '_': + { + eType = NF_SYMBOLTYPE_BLANK; + sSymbol += cToken; + eState = SsGetBlank; + } + break; +#if NF_COMMENT_IN_FORMATSTRING + case '{': + eType = NF_SYMBOLTYPE_COMMENT; + eState = SsStop; + sSymbol.Append( rStr.GetBuffer() + (nPos-1), rStr.Len() - (nPos-1) ); + nPos = rStr.Len(); + break; +#endif + case '"': + eType = NF_SYMBOLTYPE_STRING; + eState = SsGetString; + sSymbol += cToken; + break; + case '\\': + eType = NF_SYMBOLTYPE_STRING; + eState = SsGetChar; + sSymbol += cToken; + break; + case '$': + case '+': + case '(': + case ')': + eType = NF_SYMBOLTYPE_STRING; + eState = SsStop; + sSymbol += cToken; + break; + default : + { + if (StringEqualsChar( pFormatter->GetNumDecimalSep(), cToken) || + StringEqualsChar( pFormatter->GetNumThousandSep(), cToken) || + StringEqualsChar( pFormatter->GetDateSep(), cToken) || + StringEqualsChar( pLoc->getTimeSep(), cToken) || + StringEqualsChar( pLoc->getTime100SecSep(), cToken)) + { + // Another separator than pre-known ASCII + eType = NF_SYMBOLTYPE_DEL; + sSymbol += cToken; + eState = SsStop; + } + else if ( pChrCls->isLetter( rStr, nPos-1 ) ) + { + short nTmpType = GetKeyWord( rStr, nPos-1 ); + if ( nTmpType ) + { + BOOL bCurrency = FALSE; + // "Automatic" currency may start with keyword, + // like "R" (Rand) and 'R' (era) + if ( nCurrPos != STRING_NOTFOUND && + nPos-1 + sCurString.Len() <= rStr.Len() && + sCurString.Search( sKeyword[nTmpType] ) == 0 ) + { + String aTest( rStr.Copy( nPos-1, sCurString.Len() ) ); + pChrCls->toUpper( aTest ); + if ( aTest == sCurString ) + bCurrency = TRUE; + } + if ( bCurrency ) + { + eState = SsGetWord; + sSymbol += cToken; + } + else + { + eType = nTmpType; + xub_StrLen nLen = sKeyword[eType].Len(); + sSymbol = rStr.Copy( nPos-1, nLen ); + if ( eType == NF_KEY_E || IsAmbiguousE( eType ) ) + { + sal_Unicode cNext = rStr.GetChar(nPos); + switch ( cNext ) + { + case '+' : + case '-' : // E+ E- combine to one symbol + sSymbol += cNext; + eType = NF_KEY_E; + nPos++; + break; + case '0' : + case '#' : // scientific E without sign + eType = NF_KEY_E; + break; + } + } + nPos--; + nPos = nPos + nLen; + eState = SsStop; + } + } + else + { + eState = SsGetWord; + sSymbol += cToken; + } + } + else + { + eType = NF_SYMBOLTYPE_STRING; + eState = SsStop; + sSymbol += cToken; + } + } + break; + } + } + break; + case SsGetChar: + { + sSymbol += cToken; + eState = SsStop; + } + break; + case SsGetString: + { + if (cToken == '"') + eState = SsStop; + sSymbol += cToken; + } + break; + case SsGetWord: + { + if ( pChrCls->isLetter( rStr, nPos-1 ) ) + { + short nTmpType = GetKeyWord( rStr, nPos-1 ); + if ( nTmpType ) + { // beginning of keyword, stop scan and put back + eType = NF_SYMBOLTYPE_STRING; + eState = SsStop; + nPos--; + } + else + sSymbol += cToken; + } + else + { + BOOL bDontStop = FALSE; + switch (cToken) + { + case '/': // AM/PM, A/P + { + sal_Unicode cNext = rStr.GetChar(nPos); + if ( cNext == 'P' || cNext == 'p' ) + { + xub_StrLen nLen = sSymbol.Len(); + if ( 1 <= nLen + && (sSymbol.GetChar(0) == 'A' || sSymbol.GetChar(0) == 'a') + && (nLen == 1 || (nLen == 2 + && (sSymbol.GetChar(1) == 'M' || sSymbol.GetChar(1) == 'm') + && (rStr.GetChar(nPos+1) == 'M' || rStr.GetChar(nPos+1) == 'm'))) ) + { + sSymbol += cToken; + bDontStop = TRUE; + } + } + } + break; + } + // anything not recognized will stop the scan + if ( eState != SsStop && !bDontStop ) + { + eState = SsStop; + nPos--; + eType = NF_SYMBOLTYPE_STRING; + } + } + } + break; + case SsGetStar: + { + eState = SsStop; + sSymbol += cToken; + nRepPos = (nPos - nStart) - 1; // everytime > 0!! + } + break; + case SsGetBlank: + { + eState = SsStop; + sSymbol += cToken; + } + break; + default: + break; + } // of switch + } // of while + if (eState == SsGetWord) + eType = NF_SYMBOLTYPE_STRING; + return eType; +} + +xub_StrLen ImpSvNumberformatScan::Symbol_Division(const String& rString) +{ + nCurrPos = STRING_NOTFOUND; + // Ist Waehrung im Spiel? + String sString = pFormatter->GetCharClass()->upper(rString); + xub_StrLen nCPos = 0; + while (nCPos != STRING_NOTFOUND) + { + nCPos = sString.Search(GetCurString(),nCPos); + if (nCPos != STRING_NOTFOUND) + { + // in Quotes? + xub_StrLen nQ = SvNumberformat::GetQuoteEnd( sString, nCPos ); + if ( nQ == STRING_NOTFOUND ) + { + sal_Unicode c; + if ( nCPos == 0 || + ((c = sString.GetChar(xub_StrLen(nCPos-1))) != '"' + && c != '\\') ) // dm kann durch "dm + { // \d geschuetzt werden + nCurrPos = nCPos; + nCPos = STRING_NOTFOUND; // Abbruch + } + else + nCPos++; // weitersuchen + } + else + nCPos = nQ + 1; // weitersuchen + } + } + nAnzStrings = 0; + BOOL bStar = FALSE; // wird bei '*'Detektion gesetzt + Reset(); + + xub_StrLen nPos = 0; + const xub_StrLen nLen = rString.Len(); + while (nPos < nLen && nAnzStrings < NF_MAX_FORMAT_SYMBOLS) + { + nTypeArray[nAnzStrings] = Next_Symbol(rString, nPos, sStrArray[nAnzStrings]); + if (nTypeArray[nAnzStrings] == NF_SYMBOLTYPE_STAR) + { // Ueberwachung des '*' + if (bStar) + return nPos; // Fehler: doppelter '*' + else + bStar = TRUE; + } + nAnzStrings++; + } + + return 0; // 0 => ok +} + +void ImpSvNumberformatScan::SkipStrings(USHORT& i, xub_StrLen& nPos) +{ + while (i < nAnzStrings && ( nTypeArray[i] == NF_SYMBOLTYPE_STRING + || nTypeArray[i] == NF_SYMBOLTYPE_BLANK + || nTypeArray[i] == NF_SYMBOLTYPE_STAR) ) + { + nPos = nPos + sStrArray[i].Len(); + i++; + } +} + + +USHORT ImpSvNumberformatScan::PreviousKeyword(USHORT i) +{ + short res = 0; + if (i > 0 && i < nAnzStrings) + { + i--; + while (i > 0 && nTypeArray[i] <= 0) + i--; + if (nTypeArray[i] > 0) + res = nTypeArray[i]; + } + return res; +} + +USHORT ImpSvNumberformatScan::NextKeyword(USHORT i) +{ + short res = 0; + if (i < nAnzStrings-1) + { + i++; + while (i < nAnzStrings-1 && nTypeArray[i] <= 0) + i++; + if (nTypeArray[i] > 0) + res = nTypeArray[i]; + } + return res; +} + +short ImpSvNumberformatScan::PreviousType( USHORT i ) +{ + if ( i > 0 && i < nAnzStrings ) + { + do + { + i--; + } while ( i > 0 && nTypeArray[i] == NF_SYMBOLTYPE_EMPTY ); + return nTypeArray[i]; + } + return 0; +} + +sal_Unicode ImpSvNumberformatScan::PreviousChar(USHORT i) +{ + sal_Unicode res = ' '; + if (i > 0 && i < nAnzStrings) + { + i--; + while (i > 0 && ( nTypeArray[i] == NF_SYMBOLTYPE_EMPTY + || nTypeArray[i] == NF_SYMBOLTYPE_STRING + || nTypeArray[i] == NF_SYMBOLTYPE_STAR + || nTypeArray[i] == NF_SYMBOLTYPE_BLANK ) ) + i--; + if (sStrArray[i].Len() > 0) + res = sStrArray[i].GetChar(xub_StrLen(sStrArray[i].Len()-1)); + } + return res; +} + +sal_Unicode ImpSvNumberformatScan::NextChar(USHORT i) +{ + sal_Unicode res = ' '; + if (i < nAnzStrings-1) + { + i++; + while (i < nAnzStrings-1 && + ( nTypeArray[i] == NF_SYMBOLTYPE_EMPTY + || nTypeArray[i] == NF_SYMBOLTYPE_STRING + || nTypeArray[i] == NF_SYMBOLTYPE_STAR + || nTypeArray[i] == NF_SYMBOLTYPE_BLANK)) + i++; + if (sStrArray[i].Len() > 0) + res = sStrArray[i].GetChar(0); + } + return res; +} + +BOOL ImpSvNumberformatScan::IsLastBlankBeforeFrac(USHORT i) +{ + BOOL res = TRUE; + if (i < nAnzStrings-1) + { + BOOL bStop = FALSE; + i++; + while (i < nAnzStrings-1 && !bStop) + { + i++; + if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL && + sStrArray[i].GetChar(0) == '/') + bStop = TRUE; + else if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL && + sStrArray[i].GetChar(0) == ' ') + res = FALSE; + } + if (!bStop) // kein '/' + res = FALSE; + } + else + res = FALSE; // kein '/' mehr + + return res; +} + +void ImpSvNumberformatScan::Reset() +{ + nAnzStrings = 0; + nAnzResStrings = 0; +#if 0 +// ER 20.06.97 14:05 nicht noetig, wenn nAnzStrings beachtet wird + for (size_t i = 0; i < NF_MAX_FORMAT_SYMBOLS; i++) + { + sStrArray[i].Erase(); + nTypeArray[i] = 0; + } +#endif + eScannedType = NUMBERFORMAT_UNDEFINED; + nRepPos = 0; + bExp = FALSE; + bThousand = FALSE; + nThousand = 0; + bDecSep = FALSE; + nDecPos = -1; + nExpPos = (USHORT) -1; + nBlankPos = (USHORT) -1; + nCntPre = 0; + nCntPost = 0; + nCntExp = 0; + bFrac = FALSE; + bBlank = FALSE; + nNatNumModifier = 0; +} + + +BOOL ImpSvNumberformatScan::Is100SecZero( USHORT i, BOOL bHadDecSep ) +{ + USHORT nIndexPre = PreviousKeyword( i ); + return (nIndexPre == NF_KEY_S || nIndexPre == NF_KEY_SS) + && (bHadDecSep // S, SS ',' + || (i>0 && nTypeArray[i-1] == NF_SYMBOLTYPE_STRING)); + // SS"any"00 take "any" as a valid decimal separator +} + + +xub_StrLen ImpSvNumberformatScan::ScanType(const String&) +{ + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + + xub_StrLen nPos = 0; + USHORT i = 0; + short eNewType; + BOOL bMatchBracket = FALSE; + bool bHaveGeneral = false; // if General/Standard encountered + + SkipStrings(i, nPos); + while (i < nAnzStrings) + { + if (nTypeArray[i] > 0) + { // keyword + switch (nTypeArray[i]) + { + case NF_KEY_E: // E + eNewType = NUMBERFORMAT_SCIENTIFIC; + break; + case NF_KEY_AMPM: // AM,A,PM,P + case NF_KEY_AP: + case NF_KEY_H: // H + case NF_KEY_HH: // HH + case NF_KEY_S: // S + case NF_KEY_SS: // SS + eNewType = NUMBERFORMAT_TIME; + break; + case NF_KEY_M: // M + case NF_KEY_MM: // MM + { // minute or month + USHORT nIndexPre = PreviousKeyword(i); + USHORT nIndexNex = NextKeyword(i); + sal_Unicode cChar = PreviousChar(i); + if (nIndexPre == NF_KEY_H || // H + nIndexPre == NF_KEY_HH || // HH + nIndexNex == NF_KEY_S || // S + nIndexNex == NF_KEY_SS || // SS + cChar == '[' ) // [M + { + eNewType = NUMBERFORMAT_TIME; + nTypeArray[i] -= 2; // 6 -> 4, 7 -> 5 + } + else + eNewType = NUMBERFORMAT_DATE; + } + break; + case NF_KEY_MMM: // MMM + case NF_KEY_MMMM: // MMMM + case NF_KEY_MMMMM: // MMMMM + case NF_KEY_Q: // Q + case NF_KEY_QQ: // QQ + case NF_KEY_D: // D + case NF_KEY_DD: // DD + case NF_KEY_DDD: // DDD + case NF_KEY_DDDD: // DDDD + case NF_KEY_YY: // YY + case NF_KEY_YYYY: // YYYY + case NF_KEY_NN: // NN + case NF_KEY_NNN: // NNN + case NF_KEY_NNNN: // NNNN + case NF_KEY_WW : // WW + case NF_KEY_AAA : // AAA + case NF_KEY_AAAA : // AAAA + case NF_KEY_EC : // E + case NF_KEY_EEC : // EE + case NF_KEY_G : // G + case NF_KEY_GG : // GG + case NF_KEY_GGG : // GGG + case NF_KEY_R : // R + case NF_KEY_RR : // RR + eNewType = NUMBERFORMAT_DATE; + break; + case NF_KEY_CCC: // CCC + eNewType = NUMBERFORMAT_CURRENCY; + break; + case NF_KEY_GENERAL: // Standard + eNewType = NUMBERFORMAT_NUMBER; + bHaveGeneral = true; + break; + default: + eNewType = NUMBERFORMAT_UNDEFINED; + break; + } + } + else + { // control character + switch ( sStrArray[i].GetChar(0) ) + { + case '#': + case '?': + eNewType = NUMBERFORMAT_NUMBER; + break; + case '0': + { + if ( (eScannedType & NUMBERFORMAT_TIME) == NUMBERFORMAT_TIME ) + { + if ( Is100SecZero( i, bDecSep ) ) + { + bDecSep = TRUE; // subsequent 0's + eNewType = NUMBERFORMAT_TIME; + } + else + return nPos; // Error + } + else + eNewType = NUMBERFORMAT_NUMBER; + } + break; + case '%': + eNewType = NUMBERFORMAT_PERCENT; + break; + case '/': + eNewType = NUMBERFORMAT_FRACTION; + break; + case '[': + { + if ( i < nAnzStrings-1 && + nTypeArray[i+1] == NF_SYMBOLTYPE_STRING && + sStrArray[i+1].GetChar(0) == '$' ) + { // as of SV_NUMBERFORMATTER_VERSION_NEW_CURR + eNewType = NUMBERFORMAT_CURRENCY; + bMatchBracket = TRUE; + } + else if ( i < nAnzStrings-1 && + nTypeArray[i+1] == NF_SYMBOLTYPE_STRING && + sStrArray[i+1].GetChar(0) == '~' ) + { // as of SV_NUMBERFORMATTER_VERSION_CALENDAR + eNewType = NUMBERFORMAT_DATE; + bMatchBracket = TRUE; + } + else + { + USHORT nIndexNex = NextKeyword(i); + if (nIndexNex == NF_KEY_H || // H + nIndexNex == NF_KEY_HH || // HH + nIndexNex == NF_KEY_M || // M + nIndexNex == NF_KEY_MM || // MM + nIndexNex == NF_KEY_S || // S + nIndexNex == NF_KEY_SS ) // SS + eNewType = NUMBERFORMAT_TIME; + else + return nPos; // Error + } + } + break; + case '@': + eNewType = NUMBERFORMAT_TEXT; + break; + default: + if ( sStrArray[i] == pLoc->getTime100SecSep() ) + bDecSep = TRUE; // for SS,0 + eNewType = NUMBERFORMAT_UNDEFINED; + break; + } + } + if (eScannedType == NUMBERFORMAT_UNDEFINED) + eScannedType = eNewType; + else if (eScannedType == NUMBERFORMAT_TEXT || eNewType == NUMBERFORMAT_TEXT) + eScannedType = NUMBERFORMAT_TEXT; // Text bleibt immer Text + else if (eNewType == NUMBERFORMAT_UNDEFINED) + { // bleibt wie bisher + } + else if (eScannedType != eNewType) + { + switch (eScannedType) + { + case NUMBERFORMAT_DATE: + { + switch (eNewType) + { + case NUMBERFORMAT_TIME: + eScannedType = NUMBERFORMAT_DATETIME; + break; + case NUMBERFORMAT_FRACTION: // DD/MM + break; + default: + { + if (nCurrPos != STRING_NOTFOUND) + eScannedType = NUMBERFORMAT_UNDEFINED; + else if ( sStrArray[i] != pFormatter->GetDateSep() ) + return nPos; + } + } + } + break; + case NUMBERFORMAT_TIME: + { + switch (eNewType) + { + case NUMBERFORMAT_DATE: + eScannedType = NUMBERFORMAT_DATETIME; + break; + case NUMBERFORMAT_FRACTION: // MM/SS + break; + default: + { + if (nCurrPos != STRING_NOTFOUND) + eScannedType = NUMBERFORMAT_UNDEFINED; + else if ( sStrArray[i] != pLoc->getTimeSep() ) + return nPos; + } + } + } + break; + case NUMBERFORMAT_DATETIME: + { + switch (eNewType) + { + case NUMBERFORMAT_TIME: + case NUMBERFORMAT_DATE: + break; + case NUMBERFORMAT_FRACTION: // DD/MM + break; + default: + { + if (nCurrPos != STRING_NOTFOUND) + eScannedType = NUMBERFORMAT_UNDEFINED; + else if ( sStrArray[i] != pFormatter->GetDateSep() + && sStrArray[i] != pLoc->getTimeSep() ) + return nPos; + } + } + } + break; + case NUMBERFORMAT_PERCENT: + { + switch (eNewType) + { + case NUMBERFORMAT_NUMBER: // nur Zahl nach Prozent + break; + default: + return nPos; + } + } + break; + case NUMBERFORMAT_SCIENTIFIC: + { + switch (eNewType) + { + case NUMBERFORMAT_NUMBER: // nur Zahl nach E + break; + default: + return nPos; + } + } + break; + case NUMBERFORMAT_NUMBER: + { + switch (eNewType) + { + case NUMBERFORMAT_SCIENTIFIC: + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_FRACTION: + case NUMBERFORMAT_CURRENCY: + eScannedType = eNewType; + break; + default: + if (nCurrPos != STRING_NOTFOUND) + eScannedType = NUMBERFORMAT_UNDEFINED; + else + return nPos; + } + } + break; + case NUMBERFORMAT_FRACTION: + { + switch (eNewType) + { + case NUMBERFORMAT_NUMBER: // nur Zahl nach Bruch + break; + default: + return nPos; + } + } + break; + default: + break; + } + } + nPos = nPos + sStrArray[i].Len(); // Korrekturposition + i++; + if ( bMatchBracket ) + { // no type detection inside of matching brackets if [$...], [~...] + while ( bMatchBracket && i < nAnzStrings ) + { + if ( nTypeArray[i] == NF_SYMBOLTYPE_DEL + && sStrArray[i].GetChar(0) == ']' ) + bMatchBracket = FALSE; + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + if ( bMatchBracket ) + return nPos; // missing closing bracket at end of code + } + SkipStrings(i, nPos); + } + + if ((eScannedType == NUMBERFORMAT_NUMBER || eScannedType == NUMBERFORMAT_UNDEFINED) + && nCurrPos != STRING_NOTFOUND && !bHaveGeneral) + eScannedType = NUMBERFORMAT_CURRENCY; // old "automatic" currency + if (eScannedType == NUMBERFORMAT_UNDEFINED) + eScannedType = NUMBERFORMAT_DEFINED; + return 0; // Alles ok +} + + +bool ImpSvNumberformatScan::InsertSymbol( USHORT & nPos, svt::NfSymbolType eType, const String& rStr ) +{ + if (nAnzStrings >= NF_MAX_FORMAT_SYMBOLS || nPos > nAnzStrings) + return false; + ++nAnzResStrings; + if (nPos > 0 && nTypeArray[nPos-1] == NF_SYMBOLTYPE_EMPTY) + --nPos; // reuse position + else + { + ++nAnzStrings; + for (size_t i = nAnzStrings; i > nPos; --i) + { + nTypeArray[i] = nTypeArray[i-1]; + sStrArray[i] = sStrArray[i-1]; + } + } + nTypeArray[nPos] = static_cast<short>(eType); + sStrArray[nPos] = rStr; + return true; +} + + +int ImpSvNumberformatScan::FinalScanGetCalendar( xub_StrLen& nPos, USHORT& i, + USHORT& rAnzResStrings ) +{ + if ( sStrArray[i].GetChar(0) == '[' && + i < nAnzStrings-1 && + nTypeArray[i+1] == NF_SYMBOLTYPE_STRING && + sStrArray[i+1].GetChar(0) == '~' ) + { // [~calendarID] + // as of SV_NUMBERFORMATTER_VERSION_CALENDAR + nPos = nPos + sStrArray[i].Len(); // [ + nTypeArray[i] = NF_SYMBOLTYPE_CALDEL; + nPos = nPos + sStrArray[++i].Len(); // ~ + sStrArray[i-1] += sStrArray[i]; // [~ + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + rAnzResStrings--; + if ( ++i >= nAnzStrings ) + return -1; // error + nPos = nPos + sStrArray[i].Len(); // calendarID + String& rStr = sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_CALENDAR; // convert + i++; + while ( i < nAnzStrings && + sStrArray[i].GetChar(0) != ']' ) + { + nPos = nPos + sStrArray[i].Len(); + rStr += sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + rAnzResStrings--; + i++; + } + if ( rStr.Len() && i < nAnzStrings && + sStrArray[i].GetChar(0) == ']' ) + { + nTypeArray[i] = NF_SYMBOLTYPE_CALDEL; + nPos = nPos + sStrArray[i].Len(); + i++; + } + else + return -1; // error + return 1; + } + return 0; +} + +xub_StrLen ImpSvNumberformatScan::FinalScan( String& rString, String& rComment ) +{ + const LocaleDataWrapper* pLoc = pFormatter->GetLocaleData(); + + // save values for convert mode + String sOldDecSep = pFormatter->GetNumDecimalSep(); + String sOldThousandSep = pFormatter->GetNumThousandSep(); + String sOldDateSep = pFormatter->GetDateSep(); + String sOldTimeSep = pLoc->getTimeSep(); + String sOldTime100SecSep= pLoc->getTime100SecSep(); + String sOldCurSymbol = GetCurSymbol(); + String sOldCurString = GetCurString(); + sal_Unicode cOldKeyH = sKeyword[NF_KEY_H].GetChar(0); + sal_Unicode cOldKeyMI = sKeyword[NF_KEY_MI].GetChar(0); + sal_Unicode cOldKeyS = sKeyword[NF_KEY_S].GetChar(0); + + // If the group separator is a Non-Breaking Space (French) continue with a + // normal space instead so queries on space work correctly. + // The format string is adjusted to allow both. + // For output of the format code string the LocaleData characters are used. + if ( sOldThousandSep.GetChar(0) == cNonBreakingSpace && sOldThousandSep.Len() == 1 ) + sOldThousandSep = ' '; + + // change locale data et al + if (bConvertMode) + { + pFormatter->ChangeIntl(eNewLnge); + //! pointer may have changed + pLoc = pFormatter->GetLocaleData(); + //! init new keywords + InitKeywords(); + } + const CharClass* pChrCls = pFormatter->GetCharClass(); + + xub_StrLen nPos = 0; // error correction position + USHORT i = 0; // symbol loop counter + USHORT nCounter = 0; // counts digits + nAnzResStrings = nAnzStrings; // counts remaining symbols + bDecSep = FALSE; // reset in case already used in TypeCheck + bool bThaiT = false; // Thai T NatNum modifier present + + switch (eScannedType) + { + case NUMBERFORMAT_TEXT: + case NUMBERFORMAT_DEFINED: + { + while (i < nAnzStrings) + { + switch (nTypeArray[i]) + { + case NF_SYMBOLTYPE_BLANK: + case NF_SYMBOLTYPE_STAR: + break; + case NF_SYMBOLTYPE_COMMENT: + { + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + SvNumberformat::EraseCommentBraces( rStr ); + rComment += rStr; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + break; + case NF_KEY_GENERAL : // #77026# "General" is the same as "@" + break; + default: + { + if ( nTypeArray[i] != NF_SYMBOLTYPE_DEL || + sStrArray[i].GetChar(0) != '@' ) + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + } + break; + } + nPos = nPos + sStrArray[i].Len(); + i++; + } // of while + } + break; + case NUMBERFORMAT_NUMBER: + case NUMBERFORMAT_PERCENT: + case NUMBERFORMAT_CURRENCY: + case NUMBERFORMAT_SCIENTIFIC: + case NUMBERFORMAT_FRACTION: + { + sal_Unicode cThousandFill = ' '; + while (i < nAnzStrings) + { + if (eScannedType == NUMBERFORMAT_FRACTION && // special case + nTypeArray[i] == NF_SYMBOLTYPE_DEL && // # ### #/# + StringEqualsChar( sOldThousandSep, ' ' ) && // e.g. France or Sweden + StringEqualsChar( sStrArray[i], ' ' ) && + !bFrac && + IsLastBlankBeforeFrac(i) ) + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; // del->string + } // kein Taus.p. + + + if (nTypeArray[i] == NF_SYMBOLTYPE_BLANK || + nTypeArray[i] == NF_SYMBOLTYPE_STAR || + nTypeArray[i] == NF_KEY_CCC || // CCC + nTypeArray[i] == NF_KEY_GENERAL ) // Standard + { + if (nTypeArray[i] == NF_KEY_GENERAL) + { + nThousand = FLAG_STANDARD_IN_FORMAT; + if ( bConvertMode ) + sStrArray[i] = sNameStandardFormat; + } + nPos = nPos + sStrArray[i].Len(); + i++; + } + else if (nTypeArray[i] == NF_SYMBOLTYPE_STRING || // Strings oder + nTypeArray[i] > 0) // Keywords + { + if (eScannedType == NUMBERFORMAT_SCIENTIFIC && + nTypeArray[i] == NF_KEY_E) // E+ + { + if (bExp) // doppelt + return nPos; + bExp = TRUE; + nExpPos = i; + if (bDecSep) + nCntPost = nCounter; + else + nCntPre = nCounter; + nCounter = 0; + nTypeArray[i] = NF_SYMBOLTYPE_EXP; + } + else if (eScannedType == NUMBERFORMAT_FRACTION && + sStrArray[i].GetChar(0) == ' ') + { + if (!bBlank && !bFrac) // nicht doppelt oder hinter / + { + if (bDecSep && nCounter > 0) // Nachkommastellen + return nPos; // Fehler + bBlank = TRUE; + nBlankPos = i; + nCntPre = nCounter; + nCounter = 0; + } + nTypeArray[i] = NF_SYMBOLTYPE_FRACBLANK; + } + else if (nTypeArray[i] == NF_KEY_THAI_T) + { + bThaiT = true; + sStrArray[i] = sKeyword[nTypeArray[i]]; + } + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + else if (nTypeArray[i] == NF_SYMBOLTYPE_DEL) + { + sal_Unicode cHere = sStrArray[i].GetChar(0); + // Handle not pre-known separators in switch. + sal_Unicode cSimplified; + if (StringEqualsChar( pFormatter->GetNumThousandSep(), cHere)) + cSimplified = ','; + else if (StringEqualsChar( pFormatter->GetNumDecimalSep(), cHere)) + cSimplified = '.'; + else + cSimplified = cHere; + switch ( cSimplified ) + { + case '#': + case '0': + case '?': + { + if (nThousand > 0) // #... # + return nPos; // Fehler + else if (bFrac && cHere == '0') + return nPos; // 0 im Nenner + nTypeArray[i] = NF_SYMBOLTYPE_DIGIT; + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + i++; + nCounter++; + while (i < nAnzStrings && + (sStrArray[i].GetChar(0) == '#' || + sStrArray[i].GetChar(0) == '0' || + sStrArray[i].GetChar(0) == '?') + ) + { + nTypeArray[i] = NF_SYMBOLTYPE_DIGIT; + nPos = nPos + sStrArray[i].Len(); + nCounter++; + i++; + } + } + break; + case '-': + { + if ( bDecSep && nDecPos+1 == i && + nTypeArray[nDecPos] == NF_SYMBOLTYPE_DECSEP ) + { // "0.--" + nTypeArray[i] = NF_SYMBOLTYPE_DIGIT; + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + i++; + nCounter++; + while (i < nAnzStrings && + (sStrArray[i].GetChar(0) == '-') ) + { + // If more than two dashes are present in + // currency formats the last dash will be + // interpreted literally as a minus sign. + // Has to be this ugly. Period. + if ( eScannedType == NUMBERFORMAT_CURRENCY + && rStr.Len() >= 2 && + (i == nAnzStrings-1 || + sStrArray[i+1].GetChar(0) != '-') ) + break; + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + nCounter++; + i++; + } + } + else + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + } + break; + case '.': + case ',': + case '\'': + case ' ': + { + sal_Unicode cSep = cHere; // remember + if ( StringEqualsChar( sOldThousandSep, cSep ) ) + { + // previous char with skip empty + sal_Unicode cPre = PreviousChar(i); + sal_Unicode cNext; + if (bExp || bBlank || bFrac) + { // after E, / or ' ' + if ( !StringEqualsChar( sOldThousandSep, ' ' ) ) + { + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; // eat it + } + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + } + else if (i > 0 && i < nAnzStrings-1 && + (cPre == '#' || cPre == '0') && + ((cNext = NextChar(i)) == '#' || cNext == '0') + ) // #,# + { + nPos = nPos + sStrArray[i].Len(); + if (!bThousand) // only once + { + bThousand = TRUE; + cThousandFill = sStrArray[i+1].GetChar(0); + } + // Eat it, will be reinserted at proper + // grouping positions further down. + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + else if (i > 0 && (cPre == '#' || cPre == '0') + && PreviousType(i) == NF_SYMBOLTYPE_DIGIT + && nThousand < FLAG_STANDARD_IN_FORMAT ) + { // #,,,, + if ( StringEqualsChar( sOldThousandSep, ' ' ) ) + { // strange, those French.. + BOOL bFirst = TRUE; + String& rStr = sStrArray[i]; + // set a hard Non-Breaking Space or ConvertMode + const String& rSepF = pFormatter->GetNumThousandSep(); + while ( i < nAnzStrings + && sStrArray[i] == sOldThousandSep + && StringEqualsChar( sOldThousandSep, NextChar(i) ) ) + { // last was a space or another space + // is following => separator + nPos = nPos + sStrArray[i].Len(); + if ( bFirst ) + { + bFirst = FALSE; + rStr = rSepF; + nTypeArray[i] = NF_SYMBOLTYPE_THSEP; + } + else + { + rStr += rSepF; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + nThousand++; + i++; + } + if ( i < nAnzStrings-1 + && sStrArray[i] == sOldThousandSep ) + { // something following last space + // => space if currency contained, + // else separator + nPos = nPos + sStrArray[i].Len(); + if ( (nPos <= nCurrPos && + nCurrPos < nPos + sStrArray[i+1].Len()) + || nTypeArray[i+1] == NF_KEY_CCC + || (i < nAnzStrings-2 && + sStrArray[i+1].GetChar(0) == '[' && + sStrArray[i+2].GetChar(0) == '$') ) + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + } + else + { + if ( bFirst ) + { + bFirst = FALSE; + rStr = rSepF; + nTypeArray[i] = NF_SYMBOLTYPE_THSEP; + } + else + { + rStr += rSepF; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + nThousand++; + } + i++; + } + } + else + { + do + { + nThousand++; + nTypeArray[i] = NF_SYMBOLTYPE_THSEP; + nPos = nPos + sStrArray[i].Len(); + sStrArray[i] = pFormatter->GetNumThousandSep(); + i++; + } while (i < nAnzStrings && + sStrArray[i] == sOldThousandSep); + } + } + else // any grsep + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + i++; + while ( i < nAnzStrings && + sStrArray[i] == sOldThousandSep ) + { + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + } + } + else if ( StringEqualsChar( sOldDecSep, cSep ) ) + { + if (bBlank || bFrac) // . behind / or ' ' + return nPos; // error + else if (bExp) // behind E + { + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; // eat it + } + else if (bDecSep) // any . + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + i++; + while ( i < nAnzStrings && + sStrArray[i] == sOldDecSep ) + { + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + } + else + { + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_DECSEP; + sStrArray[i] = pFormatter->GetNumDecimalSep(); + bDecSep = TRUE; + nDecPos = i; + nCntPre = nCounter; + nCounter = 0; + + i++; + } + } // of else = DecSep + else // . without meaning + { + if (cSep == ' ' && + eScannedType == NUMBERFORMAT_FRACTION && + StringEqualsChar( sStrArray[i], ' ' ) ) + { + if (!bBlank && !bFrac) // no dups + { // or behind / + if (bDecSep && nCounter > 0)// dec. + return nPos; // error + bBlank = TRUE; + nBlankPos = i; + nCntPre = nCounter; + nCounter = 0; + } + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + } + else + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + i++; + while (i < nAnzStrings && + StringEqualsChar( sStrArray[i], cSep ) ) + { + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + } + } + } + break; + case '/': + { + if (eScannedType == NUMBERFORMAT_FRACTION) + { + if ( i == 0 || + (nTypeArray[i-1] != NF_SYMBOLTYPE_DIGIT && + nTypeArray[i-1] != NF_SYMBOLTYPE_EMPTY) ) + return nPos ? nPos : 1; // /? not allowed + else if (!bFrac || (bDecSep && nCounter > 0)) + { + bFrac = TRUE; + nCntPost = nCounter; + nCounter = 0; + nTypeArray[i] = NF_SYMBOLTYPE_FRAC; + nPos = nPos + sStrArray[i].Len(); + i++; + } + else // / doppelt od. , imZaehl + return nPos; // Fehler + } + else + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + } + break; + case '[' : + { + if ( eScannedType == NUMBERFORMAT_CURRENCY && + i < nAnzStrings-1 && + nTypeArray[i+1] == NF_SYMBOLTYPE_STRING && + sStrArray[i+1].GetChar(0) == '$' ) + { // [$DM-xxx] + // ab SV_NUMBERFORMATTER_VERSION_NEW_CURR + nPos = nPos + sStrArray[i].Len(); // [ + nTypeArray[i] = NF_SYMBOLTYPE_CURRDEL; + nPos = nPos + sStrArray[++i].Len(); // $ + sStrArray[i-1] += sStrArray[i]; // [$ + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + if ( ++i >= nAnzStrings ) + return nPos; // Fehler + nPos = nPos + sStrArray[i].Len(); // DM + String& rStr = sStrArray[i]; + String* pStr = &sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_CURRENCY; // wandeln + BOOL bHadDash = FALSE; + i++; + while ( i < nAnzStrings && + sStrArray[i].GetChar(0) != ']' ) + { + nPos = nPos + sStrArray[i].Len(); + if ( bHadDash ) + { + *pStr += sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + else + { + if ( sStrArray[i].GetChar(0) == '-' ) + { + bHadDash = TRUE; + pStr = &sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_CURREXT; + } + else + { + *pStr += sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + } + i++; + } + if ( rStr.Len() && i < nAnzStrings && + sStrArray[i].GetChar(0) == ']' ) + { + nTypeArray[i] = NF_SYMBOLTYPE_CURRDEL; + nPos = nPos + sStrArray[i].Len(); + i++; + } + else + return nPos; // Fehler + } + else + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + } + break; + default: // andere Dels + { + if (eScannedType == NUMBERFORMAT_PERCENT && + cHere == '%') + nTypeArray[i] = NF_SYMBOLTYPE_PERCENT; + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + } // of switch (Del) + } // of else Del + else if ( nTypeArray[i] == NF_SYMBOLTYPE_COMMENT ) + { + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + SvNumberformat::EraseCommentBraces( rStr ); + rComment += rStr; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + else + { + DBG_ERRORFILE( "unknown NF_SYMBOLTYPE_..." ); + nPos = nPos + sStrArray[i].Len(); + i++; + } + } // of while + if (eScannedType == NUMBERFORMAT_FRACTION) + { + if (bFrac) + nCntExp = nCounter; + else if (bBlank) + nCntPost = nCounter; + else + nCntPre = nCounter; + } + else + { + if (bExp) + nCntExp = nCounter; + else if (bDecSep) + nCntPost = nCounter; + else + nCntPre = nCounter; + } + if (bThousand) // Expansion of grouping separators + { + USHORT nMaxPos; + if (bFrac) + { + if (bBlank) + nMaxPos = nBlankPos; + else + nMaxPos = 0; // no grouping + } + else if (bDecSep) // decimal separator present + nMaxPos = nDecPos; + else if (bExp) // 'E' exponent present + nMaxPos = nExpPos; + else // up to end + nMaxPos = i; + // Insert separators at proper positions. + xub_StrLen nCount = 0; + utl::DigitGroupingIterator aGrouping( pLoc->getDigitGrouping()); + size_t nFirstDigitSymbol = nMaxPos; + size_t nFirstGroupingSymbol = nMaxPos; + i = nMaxPos; + while (i-- > 0) + { + if (nTypeArray[i] == NF_SYMBOLTYPE_DIGIT) + { + nFirstDigitSymbol = i; + nCount = nCount + sStrArray[i].Len(); // MSC converts += to int and then warns, so ... + // Insert separator only if not leftmost symbol. + if (i > 0 && nCount >= aGrouping.getPos()) + { + DBG_ASSERT( sStrArray[i].Len() == 1, + "ImpSvNumberformatScan::FinalScan: combined digits in group separator insertion"); + if (!InsertSymbol( i, NF_SYMBOLTYPE_THSEP, + pFormatter->GetNumThousandSep())) + // nPos isn't correct here, but signals error + return nPos; + // i may have been decremented by 1 + nFirstDigitSymbol = i + 1; + nFirstGroupingSymbol = i; + aGrouping.advance(); + } + } + } + // Generated something like "string",000; remove separator again. + if (nFirstGroupingSymbol < nFirstDigitSymbol) + { + nTypeArray[nFirstGroupingSymbol] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + } + // Combine digits into groups to save memory (Info will be copied + // later, taking only non-empty symbols). + for (i = 0; i < nAnzStrings; ++i) + { + if (nTypeArray[i] == NF_SYMBOLTYPE_DIGIT) + { + String& rStr = sStrArray[i]; + while (++i < nAnzStrings && + nTypeArray[i] == NF_SYMBOLTYPE_DIGIT) + { + rStr += sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + } + } + } + break; // of NUMBERFORMAT_NUMBER + case NUMBERFORMAT_DATE: + { + while (i < nAnzStrings) + { + switch (nTypeArray[i]) + { + case NF_SYMBOLTYPE_BLANK: + case NF_SYMBOLTYPE_STAR: + case NF_SYMBOLTYPE_STRING: + nPos = nPos + sStrArray[i].Len(); + i++; + break; + case NF_SYMBOLTYPE_COMMENT: + { + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + SvNumberformat::EraseCommentBraces( rStr ); + rComment += rStr; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + break; + case NF_SYMBOLTYPE_DEL: + { + int nCalRet; + if (sStrArray[i] == sOldDateSep) + { + nTypeArray[i] = NF_SYMBOLTYPE_DATESEP; + nPos = nPos + sStrArray[i].Len(); + if (bConvertMode) + sStrArray[i] = pFormatter->GetDateSep(); + i++; + } + else if ( (nCalRet = FinalScanGetCalendar( nPos, i, nAnzResStrings )) != 0 ) + { + if ( nCalRet < 0 ) + return nPos; // error + } + else + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + } + break; + case NF_KEY_THAI_T : + bThaiT = true; + // fall thru + case NF_KEY_M: // M + case NF_KEY_MM: // MM + case NF_KEY_MMM: // MMM + case NF_KEY_MMMM: // MMMM + case NF_KEY_MMMMM: // MMMMM + case NF_KEY_Q: // Q + case NF_KEY_QQ: // QQ + case NF_KEY_D: // D + case NF_KEY_DD: // DD + case NF_KEY_DDD: // DDD + case NF_KEY_DDDD: // DDDD + case NF_KEY_YY: // YY + case NF_KEY_YYYY: // YYYY + case NF_KEY_NN: // NN + case NF_KEY_NNN: // NNN + case NF_KEY_NNNN: // NNNN + case NF_KEY_WW : // WW + case NF_KEY_AAA : // AAA + case NF_KEY_AAAA : // AAAA + case NF_KEY_EC : // E + case NF_KEY_EEC : // EE + case NF_KEY_G : // G + case NF_KEY_GG : // GG + case NF_KEY_GGG : // GGG + case NF_KEY_R : // R + case NF_KEY_RR : // RR + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + break; + default: // andere Keywords + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + break; + } + } // of while + } + break; // of NUMBERFORMAT_DATE + case NUMBERFORMAT_TIME: + { + while (i < nAnzStrings) + { + switch (nTypeArray[i]) + { + case NF_SYMBOLTYPE_BLANK: + case NF_SYMBOLTYPE_STAR: + { + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + case NF_SYMBOLTYPE_DEL: + { + switch( sStrArray[i].GetChar(0) ) + { + case '0': + { + if ( Is100SecZero( i, bDecSep ) ) + { + bDecSep = TRUE; + nTypeArray[i] = NF_SYMBOLTYPE_DIGIT; + String& rStr = sStrArray[i]; + i++; + nPos = nPos + sStrArray[i].Len(); + nCounter++; + while (i < nAnzStrings && + sStrArray[i].GetChar(0) == '0') + { + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + nCounter++; + i++; + } + } + else + return nPos; + } + break; + case '#': + case '?': + return nPos; + case '[': + { + if (bThousand) // doppelt + return nPos; + bThousand = TRUE; // bei Time frei + sal_Unicode cChar = pChrCls->upper( NextChar(i) ).GetChar(0); + if ( cChar == cOldKeyH ) + nThousand = 1; // H + else if ( cChar == cOldKeyMI ) + nThousand = 2; // M + else if ( cChar == cOldKeyS ) + nThousand = 3; // S + else + return nPos; + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + case ']': + { + if (!bThousand) // kein [ vorher + return nPos; + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + default: + { + nPos = nPos + sStrArray[i].Len(); + if ( sStrArray[i] == sOldTimeSep ) + { + nTypeArray[i] = NF_SYMBOLTYPE_TIMESEP; + if ( bConvertMode ) + sStrArray[i] = pLoc->getTimeSep(); + } + else if ( sStrArray[i] == sOldTime100SecSep ) + { + bDecSep = TRUE; + nTypeArray[i] = NF_SYMBOLTYPE_TIME100SECSEP; + if ( bConvertMode ) + sStrArray[i] = pLoc->getTime100SecSep(); + } + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + i++; + } + break; + } + } + break; + case NF_SYMBOLTYPE_STRING: + { + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + case NF_SYMBOLTYPE_COMMENT: + { + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + SvNumberformat::EraseCommentBraces( rStr ); + rComment += rStr; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + break; + case NF_KEY_AMPM: // AM/PM + case NF_KEY_AP: // A/P + { + bExp = TRUE; // missbraucht fuer A/P + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + case NF_KEY_THAI_T : + bThaiT = true; + // fall thru + case NF_KEY_MI: // M + case NF_KEY_MMI: // MM + case NF_KEY_H: // H + case NF_KEY_HH: // HH + case NF_KEY_S: // S + case NF_KEY_SS: // SS + { + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + default: // andere Keywords + { + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + } + } // of while + nCntPost = nCounter; // Zaehler der Nullen + if (bExp) + nCntExp = 1; // merkt AM/PM + } + break; // of NUMBERFORMAT_TIME + case NUMBERFORMAT_DATETIME: + { + BOOL bTimePart = FALSE; + while (i < nAnzStrings) + { + switch (nTypeArray[i]) + { + case NF_SYMBOLTYPE_BLANK: + case NF_SYMBOLTYPE_STAR: + case NF_SYMBOLTYPE_STRING: + nPos = nPos + sStrArray[i].Len(); + i++; + break; + case NF_SYMBOLTYPE_COMMENT: + { + String& rStr = sStrArray[i]; + nPos = nPos + rStr.Len(); + SvNumberformat::EraseCommentBraces( rStr ); + rComment += rStr; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + i++; + } + break; + case NF_SYMBOLTYPE_DEL: + { + int nCalRet; + if ( (nCalRet = FinalScanGetCalendar( nPos, i, nAnzResStrings )) != 0 ) + { + if ( nCalRet < 0 ) + return nPos; // error + } + else + { + switch( sStrArray[i].GetChar(0) ) + { + case '0': + { + if ( bTimePart && Is100SecZero( i, bDecSep ) ) + { + bDecSep = TRUE; + nTypeArray[i] = NF_SYMBOLTYPE_DIGIT; + String& rStr = sStrArray[i]; + i++; + nPos = nPos + sStrArray[i].Len(); + nCounter++; + while (i < nAnzStrings && + sStrArray[i].GetChar(0) == '0') + { + rStr += sStrArray[i]; + nPos = nPos + sStrArray[i].Len(); + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + nCounter++; + i++; + } + } + else + return nPos; + } + break; + case '#': + case '?': + return nPos; + default: + { + nPos = nPos + sStrArray[i].Len(); + if (bTimePart) + { + if ( sStrArray[i] == sOldTimeSep ) + { + nTypeArray[i] = NF_SYMBOLTYPE_TIMESEP; + if ( bConvertMode ) + sStrArray[i] = pLoc->getTimeSep(); + } + else if ( sStrArray[i] == sOldTime100SecSep ) + { + bDecSep = TRUE; + nTypeArray[i] = NF_SYMBOLTYPE_TIME100SECSEP; + if ( bConvertMode ) + sStrArray[i] = pLoc->getTime100SecSep(); + } + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + } + else + { + if ( sStrArray[i] == sOldDateSep ) + { + nTypeArray[i] = NF_SYMBOLTYPE_DATESEP; + if (bConvertMode) + sStrArray[i] = pFormatter->GetDateSep(); + } + else + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + } + i++; + } + } + } + } + break; + case NF_KEY_AMPM: // AM/PM + case NF_KEY_AP: // A/P + { + bTimePart = TRUE; + bExp = TRUE; // missbraucht fuer A/P + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + } + break; + case NF_KEY_MI: // M + case NF_KEY_MMI: // MM + case NF_KEY_H: // H + case NF_KEY_HH: // HH + case NF_KEY_S: // S + case NF_KEY_SS: // SS + bTimePart = TRUE; + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + break; + case NF_KEY_M: // M + case NF_KEY_MM: // MM + case NF_KEY_MMM: // MMM + case NF_KEY_MMMM: // MMMM + case NF_KEY_MMMMM: // MMMMM + case NF_KEY_Q: // Q + case NF_KEY_QQ: // QQ + case NF_KEY_D: // D + case NF_KEY_DD: // DD + case NF_KEY_DDD: // DDD + case NF_KEY_DDDD: // DDDD + case NF_KEY_YY: // YY + case NF_KEY_YYYY: // YYYY + case NF_KEY_NN: // NN + case NF_KEY_NNN: // NNN + case NF_KEY_NNNN: // NNNN + case NF_KEY_WW : // WW + case NF_KEY_AAA : // AAA + case NF_KEY_AAAA : // AAAA + case NF_KEY_EC : // E + case NF_KEY_EEC : // EE + case NF_KEY_G : // G + case NF_KEY_GG : // GG + case NF_KEY_GGG : // GGG + case NF_KEY_R : // R + case NF_KEY_RR : // RR + bTimePart = FALSE; + sStrArray[i] = sKeyword[nTypeArray[i]]; // tTtT -> TTTT + nPos = nPos + sStrArray[i].Len(); + i++; + break; + case NF_KEY_THAI_T : + bThaiT = true; + sStrArray[i] = sKeyword[nTypeArray[i]]; + nPos = nPos + sStrArray[i].Len(); + i++; + break; + default: // andere Keywords + nTypeArray[i] = NF_SYMBOLTYPE_STRING; + nPos = nPos + sStrArray[i].Len(); + i++; + break; + } + } // of while + nCntPost = nCounter; // decimals (100th seconds) + if (bExp) + nCntExp = 1; // merkt AM/PM + } + break; // of NUMBERFORMAT_DATETIME + default: + break; + } + if (eScannedType == NUMBERFORMAT_SCIENTIFIC && + (nCntPre + nCntPost == 0 || nCntExp == 0)) + return nPos; + else if (eScannedType == NUMBERFORMAT_FRACTION && (nCntExp > 8 || nCntExp == 0)) + return nPos; + + if (bThaiT && !GetNatNumModifier()) + SetNatNumModifier(1); + + if ( bConvertMode ) + { // strings containing keywords of the target locale must be quoted, so + // the user sees the difference and is able to edit the format string + for ( i=0; i < nAnzStrings; i++ ) + { + if ( nTypeArray[i] == NF_SYMBOLTYPE_STRING && + sStrArray[i].GetChar(0) != '\"' ) + { + if ( bConvertSystemToSystem && eScannedType == NUMBERFORMAT_CURRENCY ) + { // don't stringize automatic currency, will be converted + if ( sStrArray[i] == sOldCurSymbol ) + continue; // for + // DM might be splitted into D and M + if ( sStrArray[i].Len() < sOldCurSymbol.Len() && + pChrCls->toUpper( sStrArray[i], 0, 1 ).GetChar(0) == + sOldCurString.GetChar(0) ) + { + String aTmp( sStrArray[i] ); + USHORT j = i + 1; + while ( aTmp.Len() < sOldCurSymbol.Len() && + j < nAnzStrings && + nTypeArray[j] == NF_SYMBOLTYPE_STRING ) + { + aTmp += sStrArray[j++]; + } + if ( pChrCls->upper( aTmp ) == sOldCurString ) + { + sStrArray[i++] = aTmp; + for ( ; i<j; i++ ) + { + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + i = j - 1; + continue; // for + } + } + } + String& rStr = sStrArray[i]; + xub_StrLen nLen = rStr.Len(); + for ( xub_StrLen j=0; j<nLen; j++ ) + { + if ( (j == 0 || rStr.GetChar(j-1) != '\\') && GetKeyWord( rStr, j ) ) + { + rStr.Insert( '\"', 0 ); + rStr += '\"'; + break; // for + } + } + } + } + } + // concatenate strings, remove quotes for output, and rebuild the format string + rString.Erase(); + i = 0; + while (i < nAnzStrings) + { + switch ( nTypeArray[i] ) + { + case NF_SYMBOLTYPE_STRING : + { + xub_StrLen nStringPos = rString.Len(); + xub_StrLen nArrPos = 0; + USHORT iPos = i; + do + { + if (sStrArray[i].Len() == 2 && + sStrArray[i].GetChar(0) == '\\') + { + // Unescape some simple forms of symbols even in the UI + // visible string to prevent duplicates that differ + // only in notation, originating from import. + // e.g. YYYY-MM-DD and YYYY\-MM\-DD are identical, + // but 0\ 000 0 and 0 000 0 in a French locale are not. + sal_Unicode c = sStrArray[i].GetChar(1); + switch (c) + { + case '+': + case '-': + rString += c; + break; + case ' ': + case '.': + case '/': + if (((eScannedType & NUMBERFORMAT_DATE) == 0) + && (StringEqualsChar( + pFormatter->GetNumThousandSep(), + c) || StringEqualsChar( + pFormatter->GetNumDecimalSep(), + c) || (c == ' ' && + StringEqualsChar( + pFormatter->GetNumThousandSep(), + cNonBreakingSpace)))) + rString += sStrArray[i]; + else if ((eScannedType & NUMBERFORMAT_DATE) && + StringEqualsChar( + pFormatter->GetDateSep(), c)) + rString += sStrArray[i]; + else if ((eScannedType & NUMBERFORMAT_TIME) && + (StringEqualsChar( pLoc->getTimeSep(), + c) || + StringEqualsChar( + pLoc->getTime100SecSep(), c))) + rString += sStrArray[i]; + else if (eScannedType & NUMBERFORMAT_FRACTION) + rString += sStrArray[i]; + else + rString += c; + break; + default: + rString += sStrArray[i]; + } + } + else + rString += sStrArray[i]; + if ( RemoveQuotes( sStrArray[i] ) > 0 ) + { // update currency up to quoted string + if ( eScannedType == NUMBERFORMAT_CURRENCY ) + { // dM -> DM or DM -> $ in old automatic + // currency formats, oh my ..., why did we ever + // introduce them? + String aTmp( pChrCls->toUpper( + sStrArray[iPos], nArrPos, + sStrArray[iPos].Len()-nArrPos ) ); + xub_StrLen nCPos = aTmp.Search( sOldCurString ); + if ( nCPos != STRING_NOTFOUND ) + { + const String& rCur = + bConvertMode && bConvertSystemToSystem ? + GetCurSymbol() : sOldCurSymbol; + sStrArray[iPos].Replace( nArrPos+nCPos, + sOldCurString.Len(), rCur ); + rString.Replace( nStringPos+nCPos, + sOldCurString.Len(), rCur ); + } + nStringPos = rString.Len(); + if ( iPos == i ) + nArrPos = sStrArray[iPos].Len(); + else + nArrPos = sStrArray[iPos].Len() + sStrArray[i].Len(); + } + } + if ( iPos != i ) + { + sStrArray[iPos] += sStrArray[i]; + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + i++; + } while ( i < nAnzStrings && nTypeArray[i] == NF_SYMBOLTYPE_STRING ); + if ( i < nAnzStrings ) + i--; // enter switch on next symbol again + if ( eScannedType == NUMBERFORMAT_CURRENCY && nStringPos < rString.Len() ) + { // same as above, since last RemoveQuotes + String aTmp( pChrCls->toUpper( + sStrArray[iPos], nArrPos, + sStrArray[iPos].Len()-nArrPos ) ); + xub_StrLen nCPos = aTmp.Search( sOldCurString ); + if ( nCPos != STRING_NOTFOUND ) + { + const String& rCur = + bConvertMode && bConvertSystemToSystem ? + GetCurSymbol() : sOldCurSymbol; + sStrArray[iPos].Replace( nArrPos+nCPos, + sOldCurString.Len(), rCur ); + rString.Replace( nStringPos+nCPos, + sOldCurString.Len(), rCur ); + } + } + } + break; + case NF_SYMBOLTYPE_CURRENCY : + { + rString += sStrArray[i]; + RemoveQuotes( sStrArray[i] ); + } + break; + case NF_KEY_THAI_T: + if (bThaiT && GetNatNumModifier() == 1) + { // Remove T from format code, will be replaced with a [NatNum1] prefix. + nTypeArray[i] = NF_SYMBOLTYPE_EMPTY; + nAnzResStrings--; + } + else + rString += sStrArray[i]; + break; + case NF_SYMBOLTYPE_EMPTY : + // nothing + break; + default: + rString += sStrArray[i]; + } + i++; + } + return 0; +} + + +xub_StrLen ImpSvNumberformatScan::RemoveQuotes( String& rStr ) +{ + if ( rStr.Len() > 1 ) + { + sal_Unicode c = rStr.GetChar(0); + xub_StrLen n; + if ( c == '"' && rStr.GetChar( (n = xub_StrLen(rStr.Len()-1)) ) == '"' ) + { + rStr.Erase(n,1); + rStr.Erase(0,1); + return 2; + } + else if ( c == '\\' ) + { + rStr.Erase(0,1); + return 1; + } + } + return 0; +} + + +xub_StrLen ImpSvNumberformatScan::ScanFormat( String& rString, String& rComment ) +{ + xub_StrLen res = Symbol_Division(rString); //lexikalische Analyse + if (!res) + res = ScanType(rString); // Erkennung des Formattyps + if (!res) + res = FinalScan( rString, rComment ); // Typabhaengige Endanalyse + return res; // res = Kontrollposition + // res = 0 => Format ok +} + +void ImpSvNumberformatScan::CopyInfo(ImpSvNumberformatInfo* pInfo, USHORT nAnz) +{ + size_t i,j; + j = 0; + i = 0; + while (i < nAnz && j < NF_MAX_FORMAT_SYMBOLS) + { + if (nTypeArray[j] != NF_SYMBOLTYPE_EMPTY) + { + pInfo->sStrArray[i] = sStrArray[j]; + pInfo->nTypeArray[i] = nTypeArray[j]; + i++; + } + j++; + } + pInfo->eScannedType = eScannedType; + pInfo->bThousand = bThousand; + pInfo->nThousand = nThousand; + pInfo->nCntPre = nCntPre; + pInfo->nCntPost = nCntPost; + pInfo->nCntExp = nCntExp; +} + + diff --git a/svl/source/numbers/zforscan.hxx b/svl/source/numbers/zforscan.hxx new file mode 100644 index 000000000000..300715dfeaa5 --- /dev/null +++ b/svl/source/numbers/zforscan.hxx @@ -0,0 +1,278 @@ +/************************************************************************* + * + * 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: zforscan.hxx,v $ + * $Revision: 1.24.136.1 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ZFORSCAN_HXX +#define _ZFORSCAN_HXX + +#include <tools/string.hxx> +#include <tools/date.hxx> +#include <i18npool/lang.h> +#include <tools/color.hxx> +#include <svl/nfkeytab.hxx> +#include "nfsymbol.hxx" + +class SvNumberFormatter; +struct ImpSvNumberformatInfo; + + +const size_t NF_MAX_FORMAT_SYMBOLS = 100; +const size_t NF_MAX_DEFAULT_COLORS = 10; + +// Hack: nThousand==1000 => "Default" occurs in format string +const USHORT FLAG_STANDARD_IN_FORMAT = 1000; + +class ImpSvNumberformatScan +{ +public: + + ImpSvNumberformatScan( SvNumberFormatter* pFormatter ); + ~ImpSvNumberformatScan(); + void ChangeIntl(); // tauscht Keywords aus + + void ChangeNullDate(USHORT nDay, USHORT nMonth, USHORT nYear); + // tauscht Referenzdatum aus + void ChangeStandardPrec(short nPrec); // tauscht Standardprecision aus + + xub_StrLen ScanFormat( String& rString, String& rComment ); // Aufruf der Scan-Analyse + + void CopyInfo(ImpSvNumberformatInfo* pInfo, + USHORT nAnz); // Kopiert die FormatInfo + USHORT GetAnzResStrings() const { return nAnzResStrings; } + + const CharClass& GetChrCls() const { return *pFormatter->GetCharClass(); } + const LocaleDataWrapper& GetLoc() const { return *pFormatter->GetLocaleData(); } + CalendarWrapper& GetCal() const { return *pFormatter->GetCalendar(); } + + const String* GetKeywords() const + { + if ( bKeywordsNeedInit ) + InitKeywords(); + return sKeyword; + } + // Keywords used in output like TRUE and FALSE + const String& GetSpecialKeyword( NfKeywordIndex eIdx ) const + { + if ( !sKeyword[eIdx].Len() ) + InitSpecialKeyword( eIdx ); + return sKeyword[eIdx]; + } + const String& GetTrueString() const { return GetSpecialKeyword( NF_KEY_TRUE ); } + const String& GetFalseString() const { return GetSpecialKeyword( NF_KEY_FALSE ); } + const String& GetColorString() const { return GetKeywords()[NF_KEY_COLOR]; } + const String& GetRedString() const { return GetKeywords()[NF_KEY_RED]; } + const String& GetBooleanString() const { return GetKeywords()[NF_KEY_BOOLEAN]; } + const String& GetErrorString() const { return sErrStr; } + + Date* GetNullDate() const { return pNullDate; } + const String& GetStandardName() const + { + if ( bKeywordsNeedInit ) + InitKeywords(); + return sNameStandardFormat; + } + short GetStandardPrec() const { return nStandardPrec; } + const Color& GetRedColor() const { return StandardColor[4]; } + Color* GetColor(String& sStr); // Setzt Hauptfarben oder + // definierte Farben + + // the compatibility currency symbol for old automatic currency formats + const String& GetCurSymbol() const + { + if ( bCompatCurNeedInit ) + InitCompatCur(); + return sCurSymbol; + } + + // the compatibility currency abbreviation for CCC format code + const String& GetCurAbbrev() const + { + if ( bCompatCurNeedInit ) + InitCompatCur(); + return sCurAbbrev; + } + + // the compatibility currency symbol upper case for old automatic currency formats + const String& GetCurString() const + { + if ( bCompatCurNeedInit ) + InitCompatCur(); + return sCurString; + } + + void SetConvertMode(LanguageType eTmpLge, LanguageType eNewLge, + BOOL bSystemToSystem = FALSE ) + { + bConvertMode = TRUE; + eNewLnge = eNewLge; + eTmpLnge = eTmpLge; + bConvertSystemToSystem = bSystemToSystem; + } + void SetConvertMode(BOOL bMode) { bConvertMode = bMode; } + // Veraendert nur die Bool-Variable + // (zum temporaeren Unterbrechen des + // Convert-Modus) + BOOL GetConvertMode() const { return bConvertMode; } + LanguageType GetNewLnge() const { return eNewLnge; } + // Lesezugriff auf ConvertMode + // und Konvertierungsland/Spr. + LanguageType GetTmpLnge() const { return eTmpLnge; } + // Lesezugriff auf + // und Ausgangsland/Spr. + + /// get Thai T speciality + BYTE GetNatNumModifier() const { return nNatNumModifier; } + /// set Thai T speciality + void SetNatNumModifier( BYTE n ) { nNatNumModifier = n; } + + SvNumberFormatter* GetNumberformatter() { return pFormatter; } + // Zugriff auf Formatierer + // (fuer zformat.cxx) + + +private: // ---- privater Teil + NfKeywordTable sKeyword; // Schluesselworte der Syntax + Color StandardColor[NF_MAX_DEFAULT_COLORS]; + // Array der Standardfarben + Date* pNullDate; // 30Dec1899 + String sNameStandardFormat; // "Standard" + short nStandardPrec; // default Precision fuer Standardformat (2) + SvNumberFormatter* pFormatter; // Pointer auf die Formatliste + + String sStrArray[NF_MAX_FORMAT_SYMBOLS]; // Array der Symbole + short nTypeArray[NF_MAX_FORMAT_SYMBOLS]; // Array der Infos + // externe Infos: + USHORT nAnzResStrings; // Anzahl der Ergebnissymbole +#if !(defined SOLARIS && defined X86) + short eScannedType; // Typ gemaess Scan +#else + int eScannedType; // wg. Optimierung +#endif + BOOL bThousand; // Mit Tausenderpunkt + USHORT nThousand; // Zaehlt ....-Folgen + USHORT nCntPre; // Zaehlt Vorkommastellen + USHORT nCntPost; // Zaehlt Nachkommastellen + USHORT nCntExp; // Zaehlt Exp.Stellen, AM/PM + // interne Infos: + USHORT nAnzStrings; // Anzahl der Symbole + USHORT nRepPos; // Position eines '*' + USHORT nExpPos; // interne Position des E + USHORT nBlankPos; // interne Position des Blank + short nDecPos; // interne Pos. des , + BOOL bExp; // wird bei Lesen des E gesetzt + BOOL bFrac; // wird bei Lesen des / gesetzt + BOOL bBlank; // wird bei ' '(Fraction) ges. + BOOL bDecSep; // Wird beim ersten , gesetzt + mutable BOOL bKeywordsNeedInit; // Locale dependent keywords need to be initialized + mutable BOOL bCompatCurNeedInit; // Locale dependent compatibility currency need to be initialized + String sCurSymbol; // Currency symbol for compatibility format codes + String sCurString; // Currency symbol in upper case + String sCurAbbrev; // Currency abbreviation + String sErrStr; // String fuer Fehlerausgaben + + BOOL bConvertMode; // Wird im Convert-Mode gesetzt + // Land/Sprache, in die der + LanguageType eNewLnge; // gescannte String konvertiert + // wird (fuer Excel Filter) + // Land/Sprache, aus der der + LanguageType eTmpLnge; // gescannte String konvertiert + // wird (fuer Excel Filter) + BOOL bConvertSystemToSystem; // Whether the conversion is + // from one system locale to + // another system locale (in + // this case the automatic + // currency symbol is converted + // too). + + xub_StrLen nCurrPos; // Position des Waehrungssymbols + + BYTE nNatNumModifier; // Thai T speciality + + void InitKeywords() const; + void InitSpecialKeyword( NfKeywordIndex eIdx ) const; + void InitCompatCur() const; + +#ifdef _ZFORSCAN_CXX // ----- private Methoden ----- + void SetDependentKeywords(); + // Setzt die Sprachabh. Keyw. + void SkipStrings(USHORT& i,xub_StrLen& nPos);// Ueberspringt StringSymbole + USHORT PreviousKeyword(USHORT i); // Gibt Index des vorangeh. + // Schluesselworts oder 0 + USHORT NextKeyword(USHORT i); // Gibt Index des naechsten + // Schluesselworts oder 0 + sal_Unicode PreviousChar(USHORT i); // Gibt letzten Buchstaben + // vor der Position, + // skipt EMPTY, STRING, STAR, BLANK + sal_Unicode NextChar(USHORT i); // Gibt ersten Buchst. danach + short PreviousType( USHORT i ); // Gibt Typ vor Position, + // skipt EMPTY + BOOL IsLastBlankBeforeFrac(USHORT i); // True <=> es kommt kein ' ' + // mehr bis zum '/' + void Reset(); // Reset aller Variablen + // vor Analysestart + short GetKeyWord( const String& sSymbol, // determine keyword at nPos + xub_StrLen nPos ); // return 0 <=> not found + + inline BOOL IsAmbiguousE( short nKey ) // whether nKey is ambiguous E of NF_KEY_E/NF_KEY_EC + { + return (nKey == NF_KEY_EC || nKey == NF_KEY_E) && + (GetKeywords()[NF_KEY_EC] == GetKeywords()[NF_KEY_E]); + } + + // if 0 at strArray[i] is of S,00 or SS,00 or SS"any"00 in ScanType() or FinalScan() + BOOL Is100SecZero( USHORT i, BOOL bHadDecSep ); + + short Next_Symbol(const String& rStr, + xub_StrLen& nPos, + String& sSymbol); // Naechstes Symbol + xub_StrLen Symbol_Division(const String& rString);// lexikalische Voranalyse + xub_StrLen ScanType(const String& rString); // Analyse des Formattyps + xub_StrLen FinalScan( String& rString, String& rComment ); // Endanalyse mit Vorgabe + // des Typs + // -1:= error, return nPos in FinalScan; 0:= no calendar, 1:= calendar found + int FinalScanGetCalendar( xub_StrLen& nPos, USHORT& i, USHORT& nAnzResStrings ); + + /** Insert symbol into nTypeArray and sStrArray, e.g. grouping separator. + If at nPos-1 a symbol type NF_SYMBOLTYPE_EMPTY is present, that is + reused instead of shifting all one up and nPos is decremented! */ + bool InsertSymbol( USHORT & nPos, svt::NfSymbolType eType, const String& rStr ); + + static inline BOOL StringEqualsChar( const String& rStr, sal_Unicode ch ) + { return rStr.GetChar(0) == ch && rStr.Len() == 1; } + // Yes, for efficiency get the character first and then compare length + // because in most places where this is used the string is one char. + + // remove "..." and \... quotes from rStr, return how many chars removed + static xub_StrLen RemoveQuotes( String& rStr ); + +#endif //_ZFORSCAN_CXX +}; + + + +#endif // _ZFORSCAN_HXX diff --git a/svl/source/passwordcontainer/exports.map b/svl/source/passwordcontainer/exports.map new file mode 100644 index 000000000000..f4ed78b9e970 --- /dev/null +++ b/svl/source/passwordcontainer/exports.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + local: + *; +}; diff --git a/svl/source/passwordcontainer/makefile.mk b/svl/source/passwordcontainer/makefile.mk new file mode 100644 index 000000000000..3c74246ee3ed --- /dev/null +++ b/svl/source/passwordcontainer/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=svl +TARGET=passwordcontainer.uno +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +DLLPRE= + +# --- Files ------------------------------------- + +SLOFILES= \ + $(SLO)$/passwordcontainer.obj\ + $(SLO)$/syscreds.obj + +SHL1TARGET= $(TARGET) +SHL1IMPLIB= i$(TARGET) +SHL1OBJS= $(SLOFILES) +SHL1STDLIBS=\ + $(UNOTOOLSLIB) \ + $(UCBHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1VERSIONMAP=exports.map +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/passwordcontainer/passwordcontainer.cxx b/svl/source/passwordcontainer/passwordcontainer.cxx new file mode 100644 index 000000000000..4d629958e5bf --- /dev/null +++ b/svl/source/passwordcontainer/passwordcontainer.cxx @@ -0,0 +1,1588 @@ +/************************************************************************* + * + * 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: passwordcontainer.cxx,v $ + * $Revision: 1.17 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "passwordcontainer.hxx" + +#include <unotools/pathoptions.hxx> +#include "cppuhelper/factory.hxx" +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/task/MasterPasswordRequest.hpp> +#include <com/sun/star/task/NoMasterException.hpp> + +#include <rtl/cipher.h> +#include <rtl/digest.h> +#include <rtl/byteseq.hxx> + +#ifndef _TOOLS_INETSTRM_HXX +// @@@ #include <inetstrm.hxx> +#endif + +using namespace std; +using namespace osl; +using namespace utl; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace com::sun::star::lang; +using namespace com::sun::star::task; +using namespace com::sun::star::ucb; + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +static ::rtl::OUString createIndex( vector< ::rtl::OUString > lines ) +{ + ::rtl::OString aResult; + const sal_Char* pLine; + + for( unsigned int i = 0; i < lines.size(); i++ ) + { + if( i ) + aResult += ::rtl::OString( "__" ); + ::rtl::OString line = ::rtl::OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 ); + pLine = line.getStr(); + + while( *pLine ) + { + if( ( *pLine >= 'A' && *pLine <= 'Z' ) + || ( *pLine >= 'a' && *pLine <= 'z' ) + || ( *pLine >= '0' && *pLine <= '9' ) ) + { + aResult += ::rtl::OString::valueOf( *pLine ); + } + else + { + aResult += ::rtl::OString("_"); + aResult += ::rtl::OString::valueOf( (sal_Int32) *pLine, 16 ); + } + + pLine++; + } + } + + return ::rtl::OUString::createFromAscii( aResult.getStr() ); +} + +//------------------------------------------------------------------------- + +static vector< ::rtl::OUString > getInfoFromInd( ::rtl::OUString aInd ) +{ + vector< ::rtl::OUString > aResult; + sal_Bool aStart = sal_True; + + ::rtl::OString line = ::rtl::OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US ); + const sal_Char* pLine = line.getStr(); + do + { + ::rtl::OUString newItem; + if( !aStart ) + pLine += 2; + else + aStart = sal_False; + + while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' )) + if( *pLine != '_' ) + { + newItem += ::rtl::OUString::valueOf( (sal_Unicode) *pLine ); + pLine++; + } + else + { + ::rtl::OUString aNum; + for( int i = 1; i < 3; i++ ) + { + if( !pLine[i] + || ( ( pLine[i] < '0' || pLine[i] > '9' ) + && ( pLine[i] < 'a' || pLine[i] > 'f' ) + && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) ) + { + OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); + return aResult; + } + + aNum += ::rtl::OUString::valueOf( (sal_Unicode) pLine[i] ); + } + + newItem += ::rtl::OUString::valueOf( (sal_Unicode) aNum.toInt32( 16 ) ); + pLine += 3; + } + + aResult.push_back( newItem ); + } while( pLine[0] == '_' && pLine[1] == '_' ); + + if( *pLine ) + OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); + + return aResult; +} + +//------------------------------------------------------------------------- + +static sal_Bool shorterUrl( ::rtl::OUString& aURL ) +{ + sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) ); + if( aInd > 0 && aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) != aInd-2 ) + { + aURL = aURL.copy( 0, aInd ); + return sal_True; + } + + return sal_False; +} + +//------------------------------------------------------------------------- + +static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf ) +{ + ::rtl::OUString aResult; + + ::rtl::ByteSequence outbuf( buf.getLength()*2+1 ); + + for( int ind = 0; ind < buf.getLength(); ind++ ) + { + outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a'; + outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a'; + } + outbuf[buf.getLength()*2] = '\0'; + + aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() ); + + return aResult; +} + +//------------------------------------------------------------------------- + +static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line ) +{ + OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" ); + ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US ); + ::rtl::ByteSequence aResult(line.getLength()/2); + + for( int ind = 0; ind < tmpLine.getLength()/2; ind++ ) + { + aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' ); + } + + return aResult; +} + +//------------------------------------------------------------------------- + +static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original ) +{ + Sequence< ::rtl::OUString > newOne ( original.size() ); + for( unsigned int i = 0; i < original.size() ; i++ ) + newOne[i] = original[i]; + + return newOne; +} + +static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original ) +{ + vector< ::rtl::OUString > newOne ( original.getLength() ); + for( int i = 0; i < original.getLength() ; i++ ) + newOne[i] = original[i]; + + return newOne; +} + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +PassMap StorageItem::getInfo() +{ + PassMap aResult; + + Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") ); + sal_Int32 aNodeCount = aNodeNames.getLength(); + Sequence< ::rtl::OUString > aPropNames( aNodeCount ); + sal_Int32 aNodeInd; + + for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) + { + aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); + aPropNames[aNodeInd] += aNodeNames[aNodeInd]; + aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" ); + } + + Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames ); + + if( aPropertyValues.getLength() != aNodeNames.getLength() ) + { + OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); + return aResult; + } + + for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) + { + vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] ); + + if( aUrlUsr.size() == 2 ) + { + ::rtl::OUString aUrl = aUrlUsr[0]; + ::rtl::OUString aName = aUrlUsr[1]; + + ::rtl::OUString aEPasswd; + aPropertyValues[aNodeInd] >>= aEPasswd; + + PassMap::iterator aIter = aResult.find( aUrl ); + if( aIter != aResult.end() ) + aIter->second.push_back( NamePassRecord( aName, aEPasswd ) ); + else + { + NamePassRecord aNewRecord( aName, aEPasswd ); + list< NamePassRecord > listToAdd( 1, aNewRecord ); + + aResult.insert( PairUrlRecord( aUrl, listToAdd ) ); + } + } + else + OSL_ENSURE( sal_False, "Wrong index sintax!\n" ); + } + + return aResult; +} + +//------------------------------------------------------------------------- + +void StorageItem::setUseStorage( sal_Bool bUse ) +{ + Sequence< ::rtl::OUString > sendNames(1); + Sequence< uno::Any > sendVals(1); + + sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); + + sendVals[0] <<= bUse; + + ConfigItem::SetModified(); + ConfigItem::PutProperties( sendNames, sendVals ); +} + +//------------------------------------------------------------------------- + +sal_Bool StorageItem::useStorage() +{ + Sequence< ::rtl::OUString > aNodeNames( 1 ); + aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); + + Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); + + if( aPropertyValues.getLength() != aNodeNames.getLength() ) + { + OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); + return sal_False; + } + + sal_Bool aResult = false; + aPropertyValues[0] >>= aResult; + + return aResult; +} + +//------------------------------------------------------------------------- + +sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult ) +{ + if( hasEncoded ) + { + aResult = mEncoded; + return sal_True; + } + + Sequence< ::rtl::OUString > aNodeNames( 2 ); + aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); + aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" ); + + Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); + + if( aPropertyValues.getLength() != aNodeNames.getLength() ) + { + OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); + return sal_False; + } + + aPropertyValues[0] >>= hasEncoded; + aPropertyValues[1] >>= mEncoded; + + aResult = mEncoded; + + return hasEncoded; +} + +//------------------------------------------------------------------------- + +void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty ) +{ + Sequence< ::rtl::OUString > sendNames(2); + Sequence< uno::Any > sendVals(2); + + sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); + sendNames[1] = ::rtl::OUString::createFromAscii( "Master" ); + + sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty ); + sendVals[0] <<= bHasMaster; + sendVals[1] <<= aEncoded; + + ConfigItem::SetModified(); + ConfigItem::PutProperties( sendNames, sendVals ); + + hasEncoded = bHasMaster; + mEncoded = aEncoded; +} + +//------------------------------------------------------------------------- + +void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) +{ + vector < ::rtl::OUString > forIndex; + forIndex.push_back( aURL ); + forIndex.push_back( aName ); + + Sequence< ::rtl::OUString > sendSeq(1); + + sendSeq[0] = createIndex( forIndex ); + // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); + // sendSeq[0] += createIndex( forIndex ); + // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" ); + + ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); +} + +//------------------------------------------------------------------------- + +void StorageItem::clear() +{ + Sequence< ::rtl::OUString > sendSeq(1); + + ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) ); +} + +//------------------------------------------------------------------------- + +void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord ) +{ + if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) ) + { + OSL_ASSERT( "Unexpected storing of a record!" ); + return; + } + + vector < ::rtl::OUString > forIndex; + forIndex.push_back( aURL ); + forIndex.push_back( aRecord.GetUserName() ); + + Sequence< beans::PropertyValue > sendSeq(1); + + sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); + sendSeq[0].Name += createIndex( forIndex ); + sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" ); + + sendSeq[0].Value <<= aRecord.GetPersPasswords(); + + ConfigItem::SetModified(); + ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); +} + +//------------------------------------------------------------------------- + +void StorageItem::Notify( const Sequence< ::rtl::OUString >& ) +{ + // this feature still should not be used + if( mainCont ) + mainCont->Notify(); +} + +//------------------------------------------------------------------------- + +void StorageItem::Commit() +{ + // Do nothing, we stored everything we want already +} + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ): + m_pStorageFile( NULL ) +{ + // m_pStorageFile->Notify() can be called + ::osl::MutexGuard aGuard( mMutex ); + + mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY ); + mComponent->addEventListener( this ); + + m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) ); + if( m_pStorageFile ) + if( m_pStorageFile->useStorage() ) + m_aContainer = m_pStorageFile->getInfo(); +} + +//------------------------------------------------------------------------- + +PasswordContainer::~PasswordContainer() +{ + ::osl::MutexGuard aGuard( mMutex ); + + if( m_pStorageFile ) + { + delete m_pStorageFile; + m_pStorageFile = NULL; + } + + if( mComponent.is() ) + { + mComponent->removeEventListener(this); + mComponent = Reference< XComponent >(); + } +} + +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if( m_pStorageFile ) + { + delete m_pStorageFile; + m_pStorageFile = NULL; + } + + if( mComponent.is() ) + { + //mComponent->removeEventListener(this); + mComponent = Reference< XComponent >(); + } +} + +//------------------------------------------------------------------------- + +vector< ::rtl::OUString > PasswordContainer::DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) +{ + if( aMasterPasswd.getLength() ) + { + rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); + OSL_ENSURE( aDecoder, "Can't create decoder\n" ); + + if( aDecoder ) + { + OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); + + unsigned char code[RTL_DIGEST_LENGTH_MD5]; + for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) + code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); + + rtlCipherError result = rtl_cipher_init ( + aDecoder, rtl_Cipher_DirectionDecode, + code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); + + if( result == rtl_Cipher_E_None ) + { + ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine ); + + ::rtl::ByteSequence resSeq( aSeq.getLength() ); + + result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(), + (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); + + ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 ); + + rtl_cipher_destroy (aDecoder); + + return getInfoFromInd( aPasswd ); + } + + rtl_cipher_destroy (aDecoder); + } + } + else + { + OSL_ENSURE( sal_False, "No master password provided!\n" ); + // throw special exception + } + + // problems with decoding + OSL_ENSURE( sal_False, "Problem with decoding\n" ); + throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() ); +} + + +//------------------------------------------------------------------------- + +::rtl::OUString PasswordContainer::EncodePasswords( vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) +{ + if( aMasterPasswd.getLength() ) + { + ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 ); + + rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); + OSL_ENSURE( aEncoder, "Can't create encoder\n" ); + + if( aEncoder ) + { + OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); + + unsigned char code[RTL_DIGEST_LENGTH_MD5]; + for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) + code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); + + rtlCipherError result = rtl_cipher_init ( + aEncoder, rtl_Cipher_DirectionEncode, + code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); + + if( result == rtl_Cipher_E_None ) + { + ::rtl::ByteSequence resSeq(aSeq.getLength()+1); + + result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1, + (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); + +/* + //test + rtlCipherError result = rtl_cipher_init ( + aEncoder, rtl_Cipher_DirectionDecode, + code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); + + + if( result == rtl_Cipher_E_None ) + { + ::rtl::OUString testOU = getAsciiLine( resSeq ); + ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU ); + + ::rtl::ByteSequence resSeq1( aSeq1.getLength() ); + + if( resSeq.getLength() == aSeq1.getLength() ) + { + for( int ind = 0; ind < aSeq1.getLength(); ind++ ) + if( resSeq[ind] != aSeq1[ind] ) + testOU = ::rtl::OUString(); + } + + result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(), + (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() ); + + ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 ); + } +*/ + + rtl_cipher_destroy (aEncoder); + + if( result == rtl_Cipher_E_None ) + return getAsciiLine( resSeq ); + + } + + rtl_cipher_destroy (aEncoder); + } + } + else + { + OSL_ENSURE( sal_False, "No master password provided!\n" ); + // throw special exception + } + + // problems with encoding + OSL_ENSURE( sal_False, "Problem with encoding\n" ); + throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() ); +} + +//------------------------------------------------------------------------- + +void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException) +{ + for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ ) + if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) ) + { + if( aRecord.HasPasswords( MEMORY_RECORD ) ) + aNPIter->SetMemPasswords( aRecord.GetMemPasswords() ); + + if( aRecord.HasPasswords( PERSISTENT_RECORD ) ) + { + aNPIter->SetPersPasswords( aRecord.GetPersPasswords() ); + + if( writeFile ) + { + // the password must be already encoded + m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile + } + } + + return; + } + + + if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile ) + { + // the password must be already encoded + m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url + } + + toUpdate.insert( toUpdate.begin(), aRecord ); +} + +//------------------------------------------------------------------------- + +UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler ) +{ + ::std::vector< ::rtl::OUString > aPasswords; + if( aRecord.HasPasswords( MEMORY_RECORD ) ) + aPasswords = aRecord.GetMemPasswords(); + + if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) ) + { + try + { + ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) ); + aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() ); + } + catch( NoMasterException& ) + { + // if master password could not be detected the entry will be just ignored + io_bTryToDecode = sal_False; + } + } + + return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) ); +} + +//------------------------------------------------------------------------- + +Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + Sequence< UserRecord > aResult( original.size() ); + sal_uInt32 nInd = 0; + sal_Bool bTryToDecode = sal_True; + + for( list< NamePassRecord >::const_iterator aNPIter = original.begin(); + aNPIter != original.end(); + aNPIter++, nInd++ ) + { + aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); + } + + return aResult; +} + +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler ); +} + +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler ); +} + +//------------------------------------------------------------------------- + +void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + NamePassRecord aRecord( UserName ); + ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords ); + + if( Mode == PERSISTENT_RECORD ) + aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) ); + else if( Mode == MEMORY_RECORD ) + aRecord.SetMemPasswords( aStorePass ); + else + { + OSL_ASSERT( "Unexpected persistence status!" ); + return; + } + + if( !m_aContainer.empty() ) + { + PassMap::iterator aIter = m_aContainer.find( Url ); + + if( aIter != m_aContainer.end() ) + { + UpdateVector( aIter->first, aIter->second, aRecord, sal_True ); + return; + } + } + + list< NamePassRecord > listToAdd( 1, aRecord ); + m_aContainer.insert( PairUrlRecord( Url, listToAdd ) ); + + if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() ) + m_pStorageFile->update( Url, aRecord ); + +} + +//------------------------------------------------------------------------- + + +UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + return find( aURL, rtl::OUString(), false, aHandler ); +} + +//------------------------------------------------------------------------- + +UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + return find( aURL, aName, true, aHandler ); +} + +//------------------------------------------------------------------------- + +Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + sal_uInt32 nInd = 0; + for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin(); + aNPIter != userlist.end(); + aNPIter++, nInd++ ) + { + if( aNPIter->GetUserName().equals( aName ) ) + { + Sequence< UserRecord > aResult(1); + sal_Bool bTryToDecode = sal_True; + aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); + + return aResult; + } + } + + return Sequence< UserRecord >(); +} + +//------------------------------------------------------------------------- + +bool PasswordContainer::createUrlRecord( + const PassMap::iterator & rIter, + bool bName, + const ::rtl::OUString & aName, + const Reference< XInteractionHandler >& aHandler, + UrlRecord & rRec ) + throw( RuntimeException ) +{ + if ( bName ) + { + Sequence< UserRecord > aUsrRec + = FindUsr( rIter->second, aName, aHandler ); + if( aUsrRec.getLength() ) + { + rRec = UrlRecord( rIter->first, aUsrRec ); + return true; + } + } + else + { + rRec = UrlRecord( + rIter->first, + CopyToUserRecordSequence( rIter->second, aHandler ) ); + return true; + } + return false; +} + +//------------------------------------------------------------------------- + +UrlRecord PasswordContainer::find( + const ::rtl::OUString& aURL, + const ::rtl::OUString& aName, + bool bName, // only needed to support empty user names + const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if( !m_aContainer.empty() && aURL.getLength() ) + { + ::rtl::OUString aUrl( aURL ); + + // each iteration remove last '/...' section from the aUrl + // while it's possible, up to the most left '://' + do + { + // first look for <url>/somename and then look for <url>/somename/... + PassMap::iterator aIter = m_aContainer.find( aUrl ); + if( aIter != m_aContainer.end() ) + { + UrlRecord aRec; + if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) ) + return aRec; + } + else + { + ::rtl::OUString tmpUrl( aUrl ); + if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) + tmpUrl += ::rtl::OUString::createFromAscii( "/" ); + + aIter = m_aContainer.lower_bound( tmpUrl ); + if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) ) + { + UrlRecord aRec; + if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) ) + return aRec; + } + } + } + while( shorterUrl( aUrl ) && aUrl.getLength() ); + } + + return UrlRecord(); +} + +//------------------------------------------------------------------------- +::rtl::OUString PasswordContainer::GetDefaultMasterPassword() +{ + ::rtl::OUString aResult; + for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ ) + aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) ); + + return aResult; +} + +//------------------------------------------------------------------------- +::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler ) +{ + // empty string means that the call was cancelled or just failed + ::rtl::OUString aResult; + + if ( xHandler.is() ) + { + ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode ); + + xHandler->handle( xRequest.get() ); + + ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection(); + + if ( xSelection.is() ) + { + Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY ); + if ( !xAbort.is() ) + { + const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp + = xRequest->getAuthenticationSupplier(); + + aResult = xSupp->getPassword(); + } + } + } + + return aResult; +} + +//------------------------------------------------------------------------- + +::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) +{ + PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; + if( !m_pStorageFile || !m_pStorageFile->useStorage() ) + throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode ); + + if( !m_aMasterPasswd.getLength() && aHandler.is() ) + { + ::rtl::OUString aEncodedMP; + sal_Bool bAskAgain = sal_False; + sal_Bool bDefaultPassword = sal_False; + + if( !m_pStorageFile->getEncodedMP( aEncodedMP ) ) + aRMode = PasswordRequestMode_PASSWORD_CREATE; + else if ( !aEncodedMP.getLength() ) + { + m_aMasterPasswd = GetDefaultMasterPassword(); + bDefaultPassword = sal_True; + } + + if ( !bDefaultPassword ) + { + do { + bAskAgain = sal_False; + + ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler ); + if ( aPass.getLength() ) + { + if( aRMode == PasswordRequestMode_PASSWORD_CREATE ) + { + m_aMasterPasswd = aPass; + vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); + + m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) ); + } + else + { + vector< ::rtl::OUString > aRM( DecodePasswords( aEncodedMP, aPass ) ); + if( !aRM.size() || !aPass.equals( aRM[0] ) ) + { + bAskAgain = sal_True; + aRMode = PasswordRequestMode_PASSWORD_REENTER; + } + else + m_aMasterPasswd = aPass; + } + } + + } while( bAskAgain ); + } + } + + if ( !m_aMasterPasswd.getLength() ) + throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode ); + + return m_aMasterPasswd; +} + +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + ::rtl::OUString aUrl( aURL ); + if( !m_aContainer.empty() ) + { + PassMap::iterator aIter = m_aContainer.find( aUrl ); + + if( aIter == m_aContainer.end() ) + { + sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); + if( aInd > 0 && aUrl.getLength()-1 == aInd ) + aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); + else + aUrl += ::rtl::OUString::createFromAscii( "/" ); + + aIter = m_aContainer.find( aUrl ); + } + + if( aIter != m_aContainer.end() ) + { + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) + if( aNPIter->GetUserName().equals( aName ) ) + { + if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile ) + m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) + + // the iterator will not be used any more so it can be removed directly + aIter->second.erase( aNPIter ); + + if( aIter->second.begin() == aIter->second.end() ) + m_aContainer.erase( aIter ); + + return; + } + } + } +} + +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + ::rtl::OUString aUrl( aURL ); + if( !m_aContainer.empty() ) + { + PassMap::iterator aIter = m_aContainer.find( aUrl ); + + if( aIter == m_aContainer.end() ) + { + sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); + if( aInd > 0 && aUrl.getLength()-1 == aInd ) + aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); + else + aUrl += ::rtl::OUString::createFromAscii( "/" ); + + aIter = m_aContainer.find( aUrl ); + } + + if( aIter != m_aContainer.end() ) + { + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) + if( aNPIter->GetUserName().equals( aName ) ) + { + if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) + { + // TODO/LATER: should the password be converted to MemoryPassword? + aNPIter->RemovePasswords( PERSISTENT_RECORD ); + + if ( m_pStorageFile ) + m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) + } + + if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) + aIter->second.erase( aNPIter ); + + if( aIter->second.begin() == aIter->second.end() ) + m_aContainer.erase( aIter ); + + return; + } + } + } +} +//------------------------------------------------------------------------- + +void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if( m_pStorageFile ) + m_pStorageFile->clear(); + + for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ) + { + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) + { + if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) + { + // TODO/LATER: should the password be converted to MemoryPassword? + aNPIter->RemovePasswords( PERSISTENT_RECORD ); + + if ( m_pStorageFile ) + m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) + } + + if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) + { + list< NamePassRecord >::iterator aIterToDelete( aNPIter ); + aNPIter++; + aIter->second.erase( aIterToDelete ); + } + else + aNPIter++; + } + + if( aIter->second.begin() == aIter->second.end() ) + { + PassMap::iterator aIterToDelete( aIter ); + aIter++; + m_aContainer.erase( aIterToDelete ); + } + else + aIter++; + } +} +//------------------------------------------------------------------------- + +Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException) +{ + Sequence< UrlRecord > aResult; + + ::osl::MutexGuard aGuard( mMutex ); + for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) + { + Sequence< UserRecord > aUsers; + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) + if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) + { + sal_Int32 oldLen = aUsers.getLength(); + aUsers.realloc( oldLen + 1 ); + aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) ); + } + + if( aUsers.getLength() ) + { + sal_Int32 oldLen = aResult.getLength(); + aResult.realloc( oldLen + 1 ); + aResult[ oldLen ] = UrlRecord( aIter->first, aUsers ); + } + } + + return aResult; +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) + throw (uno::RuntimeException) +{ + sal_Bool bResult = sal_False; + ::rtl::OUString aEncodedMP; + uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; + ::osl::MutexGuard aGuard( mMutex ); + + // the method should fail if there is no master password + if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ) + { + if ( !aEncodedMP.getLength() ) + { + // this is a default master password + // no UI is necessary + bResult = sal_True; + } + else + { + if ( !xTmpHandler.is() ) + { + uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); + xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); + } + + if ( m_aMasterPasswd.getLength() ) + { + // there is a password, it should be just rechecked + PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; + ::rtl::OUString aPass; + + do { + aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); + bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) ); + aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification + } while( !bResult && aPass.getLength() ); + } + else + { + try + { + // ask for the password, if user provide no correct password an exception will be thrown + bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 ); + } + catch( uno::Exception& ) + {} + } + } + } + + return bResult; +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) + throw (uno::RuntimeException) +{ + sal_Bool bResult = sal_False; + uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; + ::osl::MutexGuard aGuard( mMutex ); + + if ( m_pStorageFile && m_pStorageFile->useStorage() ) + { + if ( !xTmpHandler.is() ) + { + uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); + xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); + } + + sal_Bool bCanChangePassword = sal_True; + // if there is already a stored master password it should be entered by the user before the change happen + ::rtl::OUString aEncodedMP; + if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) ) + bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); + + if ( bCanChangePassword ) + { + // ask for the new password, but do not set it + PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE; + ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); + + if ( aPass.getLength() ) + { + // get all the persistent entries if it is possible + Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); + + // remove the master password and the entries persistence + removeMasterPassword(); + + // store the new master password + m_aMasterPasswd = aPass; + vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); + m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) ); + + // store all the entries with the new password + for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) + for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) + addPersistent( aPersistent[nURLInd].Url, + aPersistent[nURLInd].UserList[nNameInd].UserName, + aPersistent[nURLInd].UserList[nNameInd].Passwords, + uno::Reference< task::XInteractionHandler >() ); + + bResult = sal_True; + } + } + } + + return bResult; +} + +//------------------------------------------------------------------------- +void SAL_CALL PasswordContainer::removeMasterPassword() + throw (uno::RuntimeException) +{ + // remove all the stored passwords and the master password + removeAllPersistent(); + + ::osl::MutexGuard aGuard( mMutex ); + if ( m_pStorageFile ) + { + m_aMasterPasswd = ::rtl::OUString(); + m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration + } +} + +//------------------------------------------------------------------------- +::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( ) + throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if ( !m_pStorageFile ) + throw uno::RuntimeException(); + + ::rtl::OUString aEncodedMP; + return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ); +} + +//------------------------------------------------------------------------- +::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow ) + throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if ( !m_pStorageFile ) + throw uno::RuntimeException(); + + if ( !bAllow ) + removeMasterPassword(); + + if ( m_pStorageFile->useStorage() == bAllow ) + return bAllow; + + m_pStorageFile->setUseStorage( bAllow ); + return !bAllow; +} + +//------------------------------------------------------------------------- +::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed() + throw (::com::sun::star::uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if ( !m_pStorageFile ) + throw uno::RuntimeException(); + + return m_pStorageFile->useStorage(); +} + +//------------------------------------------------------------------------- +::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) + throw ( uno::RuntimeException ) +{ + sal_Bool bResult = sal_False; + uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; + ::osl::MutexGuard aGuard( mMutex ); + + if ( m_pStorageFile && m_pStorageFile->useStorage() ) + { + if ( !xTmpHandler.is() ) + { + uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); + xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); + } + + sal_Bool bCanChangePassword = sal_True; + // if there is already a stored nondefault master password it should be entered by the user before the change happen + ::rtl::OUString aEncodedMP; + if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() ) + bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); + + if ( bCanChangePassword ) + { + // generate the default password + ::rtl::OUString aPass = GetDefaultMasterPassword(); + if ( aPass.getLength() ) + { + // get all the persistent entries if it is possible + Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); + + // remove the master password and the entries persistence + removeMasterPassword(); + + // store the empty string to flag the default master password + m_aMasterPasswd = aPass; + m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True ); + + // store all the entries with the new password + for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) + for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) + addPersistent( aPersistent[nURLInd].Url, + aPersistent[nURLInd].UserList[nNameInd].UserName, + aPersistent[nURLInd].UserList[nNameInd].Passwords, + uno::Reference< task::XInteractionHandler >() ); + + bResult = sal_True; + } + } + } + + return bResult; + +} + +//------------------------------------------------------------------------- +::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( mMutex ); + + if ( !m_pStorageFile ) + throw uno::RuntimeException(); + + ::rtl::OUString aEncodedMP; + return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() ); +} + + +//------------------------------------------------------------------------- +void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) + throw (uno::RuntimeException) +{ + mUrlContainer.add( Url, MakePersistent ); +} + +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url ) + throw (uno::RuntimeException) +{ + return mUrlContainer.find( Url ); +} + +//------------------------------------------------------------------------- +void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url ) + throw (uno::RuntimeException) +{ + mUrlContainer.remove( Url ); +} + +//------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent ) + throw (uno::RuntimeException) +{ + return mUrlContainer.list( OnlyPersistent ); +} + +//------------------------------------------------------------------------- + +void PasswordContainer::Notify() +{ + ::osl::MutexGuard aGuard( mMutex ); + + PassMap::iterator aIter; + + // remove the cached persistent values in the memory + for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) + { + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) + { + if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) + { + aNPIter->RemovePasswords( PERSISTENT_RECORD ); + + if ( m_pStorageFile ) + m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) + } + + if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) + { + list< NamePassRecord >::iterator aIterToDelete( aNPIter ); + aNPIter++; + aIter->second.erase( aIterToDelete ); + } + else + aNPIter++; + } + } + + PassMap addon; + if( m_pStorageFile ) + addon = m_pStorageFile->getInfo(); + + for( aIter = addon.begin(); aIter != addon.end(); aIter++ ) + { + PassMap::iterator aSearchIter = m_aContainer.find( aIter->first ); + if( aSearchIter != m_aContainer.end() ) + for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) + UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False ); + else + m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) ); + } +} + +//------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException) +{ + return impl_getStaticImplementationName(); +} + +//------------------------------------------------------------------------- + +sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException) +{ + if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 ) + return sal_True; + else + return sal_False; +} + +//------------------------------------------------------------------------- + +Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException) +{ + return impl_getStaticSupportedServiceNames(); +} + +//------------------------------------------------------------------------- + +Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException) +{ + Sequence< ::rtl::OUString > aRet(1); + *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"); + return aRet; +} + +//------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii("stardiv.svl.PasswordContainer"); +} + +//------------------------------------------------------------------------- + +Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException ) +{ + return Reference< XInterface >( *new PasswordContainer( xServiceManager ) ); +} + +//------------------------------------------------------------------------- + +Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException) +{ + Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager, + PasswordContainer::impl_getStaticImplementationName(), + PasswordContainer::impl_createInstance, + PasswordContainer::impl_getStaticSupportedServiceNames())); + return xReturn ; + +} + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode ) +{ + MasterPasswordRequest aRequest; + + aRequest.Classification = InteractionClassification_ERROR; + aRequest.Mode = Mode; + + setRequest( makeAny( aRequest ) ); + + // Fill continuations... + Sequence< RememberAuthentication > aRememberModes( 1 ); + aRememberModes[ 0 ] = RememberAuthentication_NO; + + m_xAuthSupplier + = new ::ucbhelper::InteractionSupplyAuthentication( + this, + sal_False, // bCanSetRealm + sal_False, // bCanSetUserName + sal_True, // bCanSetPassword + sal_False, // bCanSetAccount + aRememberModes, // rRememberPasswordModes + RememberAuthentication_NO, // eDefaultRememberPasswordMode + aRememberModes, // rRememberAccountModes + RememberAuthentication_NO, // eDefaultRememberAccountMode + sal_False, // bCanUseSystemCredentials + sal_False // bDefaultUseSystemCredentials + ); + + Sequence< + Reference< XInteractionContinuation > > aContinuations( 3 ); + aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this ); + aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this ); + aContinuations[ 2 ] = m_xAuthSupplier.get(); + + setContinuations( aContinuations ); +} + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- + +extern "C" +{ +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( + const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo ( + void * /* pServiceManager */, void * pRegistryKey) +{ + if (pRegistryKey) + { + Reference< XRegistryKey > xRegistryKey ( + reinterpret_cast< XRegistryKey* >( pRegistryKey )); + Reference< XRegistryKey > xNewKey; + + xNewKey = xRegistryKey->createKey( + ::rtl::OUString::createFromAscii( "/stardiv.svl.PasswordContainer/UNO/SERVICES" )); + xNewKey->createKey( ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer")); + + return sal_True; + } + return sal_False; +} + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( + const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */) +{ + void * pResult = 0; + if (pServiceManager) + { + Reference< XSingleServiceFactory > xFactory; + if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0) + { + xFactory = PasswordContainer::impl_createFactory ( + reinterpret_cast< XMultiServiceFactory* >(pServiceManager)); + } + if (xFactory.is()) + { + xFactory->acquire(); + pResult = xFactory.get(); + } + } + return pResult; +} + +} // extern "C" diff --git a/svl/source/passwordcontainer/syscreds.cxx b/svl/source/passwordcontainer/syscreds.cxx new file mode 100644 index 000000000000..faf086e369bd --- /dev/null +++ b/svl/source/passwordcontainer/syscreds.cxx @@ -0,0 +1,303 @@ +/************************************************************************* + * + * 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: $ + * $Revision: $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "syscreds.hxx" +#include "com/sun/star/beans/PropertyValue.hpp" + +using namespace com::sun::star; + +SysCredentialsConfigItem::SysCredentialsConfigItem( + SysCredentialsConfig * pOwner ) +: utl::ConfigItem( rtl::OUString::createFromAscii( "Office.Common/Passwords" ), + CONFIG_MODE_IMMEDIATE_UPDATE ), + m_bInited( false ), + m_pOwner( pOwner ) +{ + uno::Sequence< ::rtl::OUString > aNode( 1 ); + aNode[ 0 ] = rtl::OUString::createFromAscii( + "Office.Common/Passwords/AuthenticateUsingSystemCredentials" ); + EnableNotification( aNode ); +} + +//virtual +void SysCredentialsConfigItem::Notify( + const uno::Sequence< rtl::OUString > & /*seqPropertyNames*/ ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_bInited = false; + // rebuild m_seqURLs + getSystemCredentialsURLs(); + } + m_pOwner->persistentConfigChanged(); +} + +void SysCredentialsConfigItem::Commit() +{ + // does nothing +} + +uno::Sequence< rtl::OUString > +SysCredentialsConfigItem::getSystemCredentialsURLs() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_bInited ) + { + // read config item + uno::Sequence< ::rtl::OUString > aPropNames( 1 ); + aPropNames[ 0 ] = rtl::OUString::createFromAscii( + "AuthenticateUsingSystemCredentials" ); + uno::Sequence< uno::Any > aAnyValues( + utl::ConfigItem::GetProperties( aPropNames ) ); + + OSL_ENSURE( + aAnyValues.getLength() == 1, + "SysCredentialsConfigItem::getSystemCredentialsURLs: " + "Error reading config item!" ); + + uno::Sequence< rtl::OUString > aValues; + if ( ( aAnyValues[ 0 ] >>= aValues ) || + ( !aAnyValues[ 0 ].hasValue() ) ) + { + m_seqURLs = aValues; + m_bInited = true; + } + } + return m_seqURLs; +} + +void SysCredentialsConfigItem::setSystemCredentialsURLs( + const uno::Sequence< rtl::OUString > & seqURLList ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + // write config item. + uno::Sequence< rtl::OUString > aPropNames( 1 ); + uno::Sequence< uno::Any > aPropValues( 1 ); + aPropNames[ 0 ] + = ::rtl::OUString::createFromAscii( + "AuthenticateUsingSystemCredentials" ); + aPropValues[ 0 ] <<= seqURLList; + + utl::ConfigItem::SetModified(); + utl::ConfigItem::PutProperties( aPropNames, aPropValues ); + + m_seqURLs = seqURLList; + m_bInited = true; +} + +//============================================================================ + +namespace +{ + // TODO: This code is actually copied from svl/source/passwordcontainer.cxx + bool removeLastSegment( ::rtl::OUString & aURL ) + { + sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) ); + + if( aInd > 0 ) + { + sal_Int32 aPrevInd = aURL.lastIndexOf( sal_Unicode( '/' ), aInd ); + if ( aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) + != aPrevInd - 2 || + aInd != aURL.getLength() - 1 ) + { + aURL = aURL.copy( 0, aInd ); + return true; + } + } + + return false; + } + + bool findURL( StringSet const & rContainer, rtl::OUString const & aURL, rtl::OUString & aResult ) + { + // TODO: This code is actually copied from svl/source/passwordcontainer.cxx + if( !rContainer.empty() && aURL.getLength() ) + { + ::rtl::OUString aUrl( aURL ); + + // each iteration remove last '/...' section from the aUrl + // while it's possible, up to the most left '://' + do + { + // first look for <url>/somename and then look for <url>/somename/... + StringSet::const_iterator aIter = rContainer.find( aUrl ); + if( aIter != rContainer.end() ) + { + aResult = *aIter; + return true; + } + else + { + ::rtl::OUString tmpUrl( aUrl ); + if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) + tmpUrl += ::rtl::OUString::createFromAscii( "/" ); + + aIter = rContainer.lower_bound( tmpUrl ); + if( aIter != rContainer.end() && aIter->match( tmpUrl ) ) + { + aResult = *aIter; + return true; + } + } + } + while( removeLastSegment( aUrl ) && aUrl.getLength() ); + } + aResult = rtl::OUString(); + return false; + } + +} // namespace + +SysCredentialsConfig::SysCredentialsConfig() +: m_aConfigItem( this ), + m_bCfgInited( false ) +{ +} + +void SysCredentialsConfig::initCfg() +{ + osl::MutexGuard aGuard( m_aMutex ); + if ( !m_bCfgInited ) + { + uno::Sequence< rtl::OUString > aURLs( + m_aConfigItem.getSystemCredentialsURLs() ); + for ( sal_Int32 n = 0; n < aURLs.getLength(); ++n ) + m_aCfgContainer.insert( aURLs[ n ] ); + + m_bCfgInited = true; + } +} + +void SysCredentialsConfig::writeCfg() +{ + osl::MutexGuard aGuard( m_aMutex ); + + OSL_ENSURE( m_bCfgInited, "SysCredentialsConfig::writeCfg : not initialized!" ); + + uno::Sequence< rtl::OUString > aURLs( m_aCfgContainer.size() ); + StringSet::const_iterator it = m_aCfgContainer.begin(); + const StringSet::const_iterator end = m_aCfgContainer.end(); + sal_Int32 n = 0; + + while ( it != end ) + { + aURLs[ n ] = *it; + ++it; + ++n; + } + + m_aConfigItem.setSystemCredentialsURLs( aURLs ); +} + +rtl::OUString SysCredentialsConfig::find( rtl::OUString const & aURL ) +{ + osl::MutexGuard aGuard( m_aMutex ); + rtl::OUString aResult; + if ( findURL( m_aMemContainer, aURL, aResult ) ) + return aResult; + + initCfg(); + if ( findURL( m_aCfgContainer, aURL, aResult ) ) + return aResult; + + return rtl::OUString(); +} + +void SysCredentialsConfig::add( rtl::OUString const & rURL, bool bPersistent ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( bPersistent ) + { + m_aMemContainer.erase( rURL ); + + initCfg(); + m_aCfgContainer.insert( rURL ); + writeCfg(); + } + else + { + initCfg(); + if ( m_aCfgContainer.erase( rURL ) > 0 ) + writeCfg(); + + m_aMemContainer.insert( rURL ); + } +} + +void SysCredentialsConfig::remove( rtl::OUString const & rURL ) +{ + m_aMemContainer.erase( rURL ); + + initCfg(); + if ( m_aCfgContainer.erase( rURL ) > 0 ) + writeCfg(); +} + +uno::Sequence< rtl::OUString > SysCredentialsConfig::list( bool bOnlyPersistent ) +{ + initCfg(); + sal_Int32 nCount = m_aCfgContainer.size() + + ( bOnlyPersistent ? 0 : m_aMemContainer.size() ); + uno::Sequence< rtl::OUString > aResult( nCount ); + + StringSet::const_iterator it = m_aCfgContainer.begin(); + StringSet::const_iterator end = m_aCfgContainer.end(); + sal_Int32 n = 0; + + while ( it != end ) + { + aResult[ n ] = *it; + ++it; + ++n; + } + + if ( !bOnlyPersistent ) + { + it = m_aMemContainer.begin(); + end = m_aMemContainer.end(); + + while ( it != end ) + { + aResult[ n ] = *it; + ++it; + ++n; + } + } + return aResult; +} + +void SysCredentialsConfig::persistentConfigChanged() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_bCfgInited = false; // re-init on demand. +} diff --git a/svl/source/passwordcontainer/syscreds.hxx b/svl/source/passwordcontainer/syscreds.hxx new file mode 100644 index 000000000000..68de21049fdc --- /dev/null +++ b/svl/source/passwordcontainer/syscreds.hxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * 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: $ + * $Revision: $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_SYSCREDS_HXX +#define INCLUDED_SVTOOLS_SYSCREDS_HXX + +#include <set> +#include <memory> +#include "osl/mutex.hxx" +#include "rtl/ustring.hxx" +#include "com/sun/star/uno/Sequence.hxx" +#include "unotools/configitem.hxx" + +class SysCredentialsConfig; + +class SysCredentialsConfigItem : public utl::ConfigItem +{ + public: + SysCredentialsConfigItem( SysCredentialsConfig * pOwner ); + //virtual ~SysCredentialsConfigItem(); + + virtual void Notify( + const com::sun::star::uno::Sequence< rtl::OUString > & + seqPropertyNames ); + virtual void Commit(); + + com::sun::star::uno::Sequence< rtl::OUString > + getSystemCredentialsURLs(); + + void setSystemCredentialsURLs( + const com::sun::star::uno::Sequence< rtl::OUString > & + seqURLList ); + + //bool isSystemCredentialsURL( const rtl::OUString & rURL ) const; + +private: + ::osl::Mutex m_aMutex; + bool m_bInited; + com::sun::star::uno::Sequence< rtl::OUString > m_seqURLs; + SysCredentialsConfig * m_pOwner; +}; + +typedef std::set< rtl::OUString > StringSet; + +class SysCredentialsConfig +{ + public: + SysCredentialsConfig(); + + rtl::OUString find( rtl::OUString const & rURL ); + void add( rtl::OUString const & rURL, bool bPersistent ); + void remove( rtl::OUString const & rURL ); + com::sun::star::uno::Sequence< rtl::OUString > list( bool bOnlyPersistent ); + + void persistentConfigChanged(); + + private: + void initCfg(); + void writeCfg(); + + ::osl::Mutex m_aMutex; + StringSet m_aMemContainer; + StringSet m_aCfgContainer; + SysCredentialsConfigItem m_aConfigItem; + bool m_bCfgInited; +}; + +#endif // INCLUDED_SVTOOLS_SYSCREDS_HXX diff --git a/svl/source/svdde/ddecli.cxx b/svl/source/svdde/ddecli.cxx new file mode 100644 index 000000000000..dd3c9c237f9a --- /dev/null +++ b/svl/source/svdde/ddecli.cxx @@ -0,0 +1,476 @@ +/************************************************************************* + * + * 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: ddecli.cxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define UNICODE +#include <string.h> // memset +#include "ddeimp.hxx" +#include <svl/svdde.hxx> + +#include <osl/thread.h> +#include <tools/debug.hxx> +#include <tools/solarmutex.hxx> +#include <vos/mutex.hxx> + +// static DWORD hDdeInst = NULL; +// static short nInstance = 0; + +// DdeConnections* DdeConnection::pConnections = NULL; + +DdeInstData* ImpInitInstData() +{ + DdeInstData* pData = new DdeInstData; + memset( pData,0,sizeof(DdeInstData) ); + DdeInstData** ppInst = (DdeInstData**)GetAppData( SHL_SVDDE ); + *ppInst = pData; + return pData; +} + +void ImpDeinitInstData() +{ + DdeInstData** ppInst = (DdeInstData**)GetAppData( SHL_SVDDE ); + delete (*ppInst); + *ppInst = 0; +} + + +struct DdeImp +{ + HCONV hConv; + long nStatus; +}; + +// --- DdeInternat::CliCallback() ---------------------------------- + +HDDEDATA CALLBACK DdeInternal::CliCallback( + WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2, + HDDEDATA hData, DWORD nInfo1, DWORD ) +{ + HDDEDATA nRet = DDE_FNOTPROCESSED; + DdeConnections& rAll = (DdeConnections&)DdeConnection::GetConnections(); + DdeConnection* self = 0; + + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + + for ( self = rAll.First(); self; self = rAll.Next() ) + if ( self->pImp->hConv == hConv ) + break; + + if( self ) + { + DdeTransaction* t; + BOOL bFound = FALSE; + for( t = self->aTransactions.First(); t; t = self->aTransactions.Next() ) + { + switch( nCode ) + { + case XTYP_XACT_COMPLETE: + if( (DWORD)t->nId == nInfo1 ) + { + nCode = t->nType & (XCLASS_MASK | XTYP_MASK); + t->bBusy = FALSE; + t->Done( 0 != hData ); + bFound = TRUE; + } + break; + + case XTYP_DISCONNECT: + self->pImp->hConv = DdeReconnect( hConv ); + self->pImp->nStatus = self->pImp->hConv + ? DMLERR_NO_ERROR + : DdeGetLastError( pInst->hDdeInstCli ); + t = 0; + nRet = 0; + bFound = TRUE; + break; + + case XTYP_ADVDATA: + bFound = BOOL( *t->pName == hText2 ); + break; + } + if( bFound ) + break; + } + + if( t ) + { + switch( nCode ) + { + case XTYP_ADVDATA: + if( !hData ) + { + ((DdeLink*) t)->Notify(); + nRet = (HDDEDATA)DDE_FACK; + break; + } + // kein break; + + case XTYP_REQUEST: + if( !hData && XTYP_REQUEST == nCode ) + { + + } + + DdeData d; + d.pImp->hData = hData; + d.pImp->nFmt = DdeData::GetInternalFormat( nCbType ); + d.Lock(); + t->Data( &d ); + nRet = (HDDEDATA)DDE_FACK; + break; + } + } + } + return nRet; +} + +// --- DdeConnection::DdeConnection() ------------------------------ + +DdeConnection::DdeConnection( const String& rService, const String& rTopic ) +{ + pImp = new DdeImp; + pImp->nStatus = DMLERR_NO_ERROR; + pImp->hConv = NULL; + + DdeInstData* pInst = ImpGetInstData(); + if( !pInst ) + pInst = ImpInitInstData(); + pInst->nRefCount++; + pInst->nInstanceCli++; + if ( !pInst->hDdeInstCli ) + { + pImp->nStatus = DdeInitialize( &pInst->hDdeInstCli, + (PFNCALLBACK)DdeInternal::CliCallback, + APPCLASS_STANDARD | APPCMD_CLIENTONLY | + CBF_FAIL_ALLSVRXACTIONS | + CBF_SKIP_REGISTRATIONS | + CBF_SKIP_UNREGISTRATIONS, 0L ); + pInst->pConnections = new DdeConnections; + } + + pService = new DdeString( pInst->hDdeInstCli, rService ); + pTopic = new DdeString( pInst->hDdeInstCli, rTopic ); + + if ( pImp->nStatus == DMLERR_NO_ERROR ) + { + pImp->hConv = DdeConnect( pInst->hDdeInstCli,*pService,*pTopic, NULL); + if( !pImp->hConv ) + pImp->nStatus = DdeGetLastError( pInst->hDdeInstCli ); + } + + if ( pInst->pConnections ) + pInst->pConnections->Insert( this ); +} + +// --- DdeConnection::~DdeConnection() ----------------------------- + +DdeConnection::~DdeConnection() +{ + if ( pImp->hConv ) + DdeDisconnect( pImp->hConv ); + + delete pService; + delete pTopic; + + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + if ( pInst->pConnections ) + pInst->pConnections->Remove( this ); + + pInst->nInstanceCli--; + pInst->nRefCount--; + if ( !pInst->nInstanceCli && pInst->hDdeInstCli ) + { + if( DdeUninitialize( pInst->hDdeInstCli ) ) + { + pInst->hDdeInstCli = NULL; + delete pInst->pConnections; + pInst->pConnections = NULL; + if( pInst->nRefCount == 0 ) + ImpDeinitInstData(); + } + } + delete pImp; +} + +// --- DdeConnection::IsConnected() -------------------------------- + +BOOL DdeConnection::IsConnected() +{ + CONVINFO c; +#ifdef OS2 + c.nSize = sizeof( c ); +#else + c.cb = sizeof( c ); +#endif + if ( DdeQueryConvInfo( pImp->hConv, QID_SYNC, &c ) ) + return TRUE; + else + { + DdeInstData* pInst = ImpGetInstData(); + pImp->hConv = DdeReconnect( pImp->hConv ); + pImp->nStatus = pImp->hConv ? DMLERR_NO_ERROR : DdeGetLastError( pInst->hDdeInstCli ); + return BOOL( pImp->nStatus == DMLERR_NO_ERROR ); + } +} + +// --- DdeConnection::GetServiceName() ----------------------------- + +const String& DdeConnection::GetServiceName() +{ + return (const String&)*pService; +} + +// --- DdeConnection::GetTopicName() ------------------------------- + +const String& DdeConnection::GetTopicName() +{ + return (const String&)*pTopic; +} + +// --- DdeConnection::GetConvId() ---------------------------------- + +long DdeConnection::GetConvId() +{ + return (long)pImp->hConv; +} + +const DdeConnections& DdeConnection::GetConnections() +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + return *(pInst->pConnections); +} + +// --- DdeTransaction::DdeTransaction() ---------------------------- + +DdeTransaction::DdeTransaction( DdeConnection& d, const String& rItemName, + long n ) : + rDde( d ) +{ + DdeInstData* pInst = ImpGetInstData(); + pName = new DdeString( pInst->hDdeInstCli, rItemName ); + nTime = n; + nId = 0; + nType = 0; + bBusy = FALSE; + + rDde.aTransactions.Insert( this ); +} + +// --- DdeTransaction::~DdeTransaction() --------------------------- + +DdeTransaction::~DdeTransaction() +{ + if ( nId && rDde.pImp->hConv ) + { + DdeInstData* pInst = ImpGetInstData(); + DdeAbandonTransaction( pInst->hDdeInstCli, rDde.pImp->hConv, nId ); + } + + delete pName; + rDde.aTransactions.Remove( this ); +} + +// --- DdeTransaction::Execute() ----------------------------------- + +void DdeTransaction::Execute() +{ + HSZ hItem = *pName; + void* pData = (void*)(const void *)aDdeData; + DWORD nData = (DWORD)(long)aDdeData; + ULONG nIntFmt = aDdeData.pImp->nFmt; + UINT nExtFmt = DdeData::GetExternalFormat( nIntFmt ); + DdeInstData* pInst = ImpGetInstData(); + + if ( nType == XTYP_EXECUTE ) + hItem = NULL; + if ( nType != XTYP_EXECUTE && nType != XTYP_POKE ) + { + pData = NULL; + nData = 0L; + } + if ( nTime ) + { + HDDEDATA hData = DdeClientTransaction( (unsigned char*)pData, + nData, rDde.pImp->hConv, + hItem, nExtFmt, (UINT)nType, + (DWORD)nTime, (DWORD FAR*)NULL ); + + rDde.pImp->nStatus = DdeGetLastError( pInst->hDdeInstCli ); + if( hData && nType == XTYP_REQUEST ) + { + { + DdeData d; + d.pImp->hData = hData; + d.pImp->nFmt = nIntFmt; + d.Lock(); + Data( &d ); + } + DdeFreeDataHandle( hData ); + } + } + else + { + if ( nId && rDde.pImp->hConv ) + DdeAbandonTransaction( pInst->hDdeInstCli, rDde.pImp->hConv, nId); + nId = 0; + bBusy = TRUE; + HDDEDATA hRet = DdeClientTransaction( (unsigned char*)pData, nData, + rDde.pImp->hConv, hItem, nExtFmt, + (UINT)nType, TIMEOUT_ASYNC, + (DWORD FAR *) ((long*) &nId) ); + rDde.pImp->nStatus = hRet ? DMLERR_NO_ERROR + : DdeGetLastError( pInst->hDdeInstCli ); + } +} + +// --- DdeTransaction::GetName() ----------------------------------- + +const String& DdeTransaction::GetName() const +{ + return *pName; +} + +// --- DdeTransaction::Data() -------------------------------------- + + +void __EXPORT DdeTransaction::Data( const DdeData* p ) +{ + if ( ::tools::SolarMutex::Acquire() ) + { + aData.Call( (void*)p ); + ::tools::SolarMutex::Release(); + } +} + +// --- DdeTransaction::Done() -------------------------------------- + +void __EXPORT DdeTransaction::Done( BOOL bDataValid ) +{ + aDone.Call( (void*)bDataValid ); +} + +// --- DdeLink::DdeLink() ------------------------------------------ + +DdeLink::DdeLink( DdeConnection& d, const String& aItemName, long n ) : + DdeTransaction (d, aItemName, n) +{ +} + +// --- DdeLink::~DdeLink() ----------------------------------------- + +DdeLink::~DdeLink() +{ + nType = (USHORT)XTYP_ADVSTOP; + nTime = 0; +} + +// --- DdeLink::Notify() ----------------------------------------- + +void __EXPORT DdeLink::Notify() +{ + aNotify.Call( NULL ); +} + +// --- DdeRequest::DdeRequest() ------------------------------------ + +DdeRequest::DdeRequest( DdeConnection& d, const String& i, long n ) : + DdeTransaction( d, i, n ) +{ + nType = XTYP_REQUEST; +} + +// --- DdeWarmLink::DdeWarmLink() ---------------------------------- + +DdeWarmLink::DdeWarmLink( DdeConnection& d, const String& i, long n ) : + DdeLink( d, i, n ) +{ + nType = XTYP_ADVSTART | XTYPF_NODATA; +} + +// --- DdeHotLink::DdeHotLink() ------------------------------------ + +DdeHotLink::DdeHotLink( DdeConnection& d, const String& i, long n ) : + DdeLink( d, i, n ) +{ + nType = XTYP_ADVSTART; +} + +// --- DdePoke::DdePoke() ------------------------------------------ + +DdePoke::DdePoke( DdeConnection& d, const String& i, const char* p, + long l, ULONG f, long n ) : + DdeTransaction( d, i, n ) +{ + aDdeData = DdeData( p, l, f ); + nType = XTYP_POKE; +} + +// --- DdePoke::DdePoke() ------------------------------------------ + +DdePoke::DdePoke( DdeConnection& d, const String& i, const String& rData, + long n ) : + DdeTransaction( d, i, n ) +{ +// ByteString aByteStr( rData, osl_getThreadTextEncoding() ); + aDdeData = DdeData( (void*) rData.GetBuffer(), sizeof(sal_Unicode) * (rData.Len()), CF_TEXT ); + nType = XTYP_POKE; +} + +// --- DdePoke::DdePoke() ------------------------------------------ + +DdePoke::DdePoke( DdeConnection& d, const String& i, const DdeData& rData, + long n ) : + DdeTransaction( d, i, n ) +{ + aDdeData = rData; + nType = XTYP_POKE; +} + +// --- DdeExecute::DdeExecute() ------------------------------------ + +DdeExecute::DdeExecute( DdeConnection& d, const String& rData, long n ) : + DdeTransaction( d, String(), n ) +{ +// ByteString aByteStr( rData, osl_getThreadTextEncoding() ); + aDdeData = DdeData( (void*)rData.GetBuffer(), sizeof(sal_Unicode) * (rData.Len() + 1), CF_TEXT ); + nType = XTYP_EXECUTE; +} + +// --- DdeConnection::GetError() ----------------------------------- + +long DdeConnection::GetError() +{ + return pImp->nStatus; +} diff --git a/svl/source/svdde/ddedata.cxx b/svl/source/svdde/ddedata.cxx new file mode 100644 index 000000000000..8ae22a8cfb20 --- /dev/null +++ b/svl/source/svdde/ddedata.cxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * 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: ddedata.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +// ACHTUNG: es wird angenommen, dass StarView-Clipboard-Foamatnummern +// und Windows-Formatnummern identisch sind! Ist dies einmal nicht der +// Fall, muessen die Routinen hier angepasst werden. Die Implementation +// verwendet die hier defineirten Konversionen. + +#define UNICODE + +#include <string.h> +#include "ddeimp.hxx" +#include <svl/svdde.hxx> + +#include <osl/thread.h> + +#if defined( WIN ) && defined( MSC ) +#pragma code_seg( "SVDDE_MISC_CODE" ) +#endif + +// --- DdeData::DdeData() ------------------------------------------ + +DdeData::DdeData() +{ + pImp = new DdeDataImp; + pImp->hData = NULL; + pImp->nData = 0; + pImp->pData = NULL; + pImp->nFmt = CF_TEXT; +} + +// --- DdeData::DdeData() ------------------------------------------ + +DdeData::DdeData( const void* p, long n, ULONG f ) +{ + pImp = new DdeDataImp; + pImp->hData = NULL; + pImp->pData = (LPBYTE)p; + pImp->nData = n; + pImp->nFmt = f; +} + +// --- DdeData::DdeData() ------------------------------------------ + +DdeData::DdeData( const String& s ) +{ + pImp = new DdeDataImp; + pImp->hData = NULL; + pImp->pData = (LPBYTE)s.GetBuffer(); + pImp->nData = s.Len()+1; + pImp->nFmt = CF_TEXT; +} + +// --- DdeData::DdeData() ------------------------------------------ + +DdeData::DdeData( const DdeData& rData ) +{ + pImp = new DdeDataImp; + pImp->hData = rData.pImp->hData; + pImp->nData = rData.pImp->nData; + pImp->pData = rData.pImp->pData; + pImp->nFmt = rData.pImp->nFmt; + Lock(); +} + +// --- DdeData::~DdeData() ----------------------------------------- + +DdeData::~DdeData() +{ + if ( pImp && pImp->hData ) + DdeUnaccessData( pImp->hData ); + delete pImp; +} + +// --- DdeData::Lock() --------------------------------------------- + +void DdeData::Lock() +{ + if ( pImp->hData ) + pImp->pData = DdeAccessData( pImp->hData, (LPDWORD) &pImp->nData ); +} + +// --- DdeData::GetFormat() ---------------------------------------- + +ULONG DdeData::GetFormat() const +{ + return pImp->nFmt; +} + +void DdeData::SetFormat( ULONG nFmt ) +{ + pImp->nFmt = nFmt; +} + +// --- DdeData::operator const char*() ----------------------------- + +DdeData::operator const void*() const +{ + return pImp->pData; +} + +// --- DdeData::operator long() ------------------------------------ + +DdeData::operator long() const +{ + return pImp->nData; +} + +// --- DdeData::operator =() --------------------------------------- + +DdeData& DdeData::operator = ( const DdeData& rData ) +{ + if ( &rData != this ) + { + DdeData tmp( rData ); + delete pImp; + pImp = tmp.pImp; + tmp.pImp = NULL; + } + + return *this; +} + +ULONG DdeData::GetExternalFormat( ULONG nFmt ) +{ + switch( nFmt ) + { + case FORMAT_STRING: + nFmt = CF_TEXT; + break; + case FORMAT_BITMAP: + nFmt = CF_BITMAP; + break; + case FORMAT_GDIMETAFILE: + nFmt = CF_METAFILEPICT; + break; + + default: + { +#if defined(WNT) || defined(WIN) || defined( PM2 ) + String aName( SotExchange::GetFormatName( nFmt ) ); + +#if defined(WNT) || defined(WIN) + + if( aName.Len() ) + nFmt = RegisterClipboardFormat( reinterpret_cast<LPCWSTR>(aName.GetBuffer()) ); +#endif +#if defined( PM2 ) + + if( aName.Len() ) + { + HATOMTBL hSysTable = WinQuerySystemAtomTable(); + nFmt = (ULONG)WinAddAtom( hSysTable, (PSZ)aName.GetBuffer() ); + } +#endif +#endif + } + } + return nFmt; +} + +ULONG DdeData::GetInternalFormat( ULONG nFmt ) +{ + switch( nFmt ) + { + case CF_TEXT: + nFmt = FORMAT_STRING; + break; + + case CF_BITMAP: + nFmt = FORMAT_BITMAP; + break; + + case CF_METAFILEPICT: + nFmt = FORMAT_GDIMETAFILE; + break; + + default: +#if defined(WIN) || defined(WNT) + if( nFmt >= CF_MAX ) + { + TCHAR szName[ 256 ]; + + if( GetClipboardFormatName( nFmt, szName, sizeof(szName) ) ) + nFmt = SotExchange::RegisterFormatName( String(reinterpret_cast<const sal_Unicode*>(szName)) ); + } +#endif +#if defined(PM2) + if( nFmt > CF_PALETTE ) + { + char szName[ 256 ]; + + HATOMTBL hSysTable = WinQuerySystemAtomTable(); + WinQueryAtomName( hSysTable, (ATOM)nFmt, (PSZ)szName, + sizeof( szName ) ); + nFmt = SotExchange::RegisterFormatName( String( szName ) ); + } +#endif + break; + } + return nFmt; +} + diff --git a/svl/source/svdde/ddedll.cxx b/svl/source/svdde/ddedll.cxx new file mode 100644 index 000000000000..b27272a2a910 --- /dev/null +++ b/svl/source/svdde/ddedll.cxx @@ -0,0 +1,67 @@ +/************************************************************************* + * + * 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: ddedll.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#ifdef WIN + + +#include <sysdep.hxx> // included svwin.h + +// Statische DLL-Verwaltungs-Variablen +static HINSTANCE hDLLInst = 0; // HANDLE der DLL + +/*************************************************************************** +|* LibMain() +|* Beschreibung Initialisierungsfunktion der DLL +***************************************************************************/ +extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR ) +{ +#ifndef WNT + if ( nHeap ) + UnlockData( 0 ); +#endif + + hDLLInst = hDLL; + + return TRUE; +} + +/*************************************************************************** +|* WEP() +|* Beschreibung DLL-Deinitialisierung +***************************************************************************/ +extern "C" int CALLBACK WEP( int ) +{ + return 1; +} + +#endif + diff --git a/svl/source/svdde/ddeimp.hxx b/svl/source/svdde/ddeimp.hxx new file mode 100644 index 000000000000..dcdf5b3be33c --- /dev/null +++ b/svl/source/svdde/ddeimp.hxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * 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: ddeimp.hxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DDEIMP_HXX +#define _DDEIMP_HXX + +#ifdef OS2 + +#include "ddemlos2.h" + +#define WORD USHORT +#define DWORD ULONG +#define LPBYTE BYTE* +#define LPWORD USHORT* +#define LPDWORD ULONG* +#define LPCTSTR PCSZ + +#else + +#include <tools/prewin.h> +#include <ddeml.h> +#include <tools/postwin.h> +#include "ddewrap.hxx" + +/* +extern "C" +{ +#define BOOL WIN_BOOL +#define BYTE WIN_BYTE +#undef BOOL +#undef BYTE +}; +*/ + +#endif +#include <tools/string.hxx> +#include <tools/list.hxx> +#include <tools/shl.hxx> + +class DdeService; +class DdeTopic; +class DdeItem; +class DdeTopics; +class DdeItems; + +// ---------------- +// - Conversation - +// ---------------- + +struct Conversation +{ + HCONV hConv; + DdeTopic* pTopic; +}; + +DECLARE_LIST( ConvList, Conversation* ); + +// --------------- +// - DdeInternal - +// --------------- + +class DdeInternal +{ +public: +#ifdef WNT + static HDDEDATA CALLBACK CliCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK SvrCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK InfCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); +#else +#if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC ) + static HDDEDATA CALLBACK __EXPORT CliCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK __EXPORT SvrCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK __EXPORT InfCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); +#else + static HDDEDATA CALLBACK _export CliCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK _export SvrCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); + static HDDEDATA CALLBACK _export InfCallback + ( WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ); +#endif +#endif + static DdeService* FindService( HSZ ); + static DdeTopic* FindTopic( DdeService&, HSZ ); + static DdeItem* FindItem( DdeTopic&, HSZ ); +}; + +// ------------- +// - DdeString - +// ------------- + +class DdeString : public String +{ +protected: + HSZ hString; + DWORD hInst; + +public: + DdeString( DWORD, const sal_Unicode* ); + DdeString( DWORD, const String& ); + ~DdeString(); + + int operator==( HSZ ); + operator HSZ(); +}; + +// -------------- +// - DdeDataImp - +// -------------- + +struct DdeDataImp +{ + HDDEDATA hData; + LPBYTE pData; + long nData; + ULONG nFmt; +}; + +class DdeConnections; +class DdeServices; + +struct DdeInstData +{ + USHORT nRefCount; + DdeConnections* pConnections; + // Server + long hCurConvSvr; + ULONG hDdeInstSvr; + short nInstanceSvr; + DdeServices* pServicesSvr; + // Client + ULONG hDdeInstCli; + short nInstanceCli; +}; + +#ifndef SHL_SVDDE +#define SHL_SVDDE SHL_SHL2 +#endif + +inline DdeInstData* ImpGetInstData() +{ + return (DdeInstData*)(*GetAppData( SHL_SVDDE )); +} +DdeInstData* ImpInitInstData(); +void ImpDeinitInstData(); + +#endif // _DDEIMP_HXX diff --git a/svl/source/svdde/ddeinf.cxx b/svl/source/svdde/ddeinf.cxx new file mode 100644 index 000000000000..b5154e1f7530 --- /dev/null +++ b/svl/source/svdde/ddeinf.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * 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: ddeinf.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define UNICODE + +#include <string.h> +#include "ddeimp.hxx" +#include <svl/svdde.hxx> + +// --- DdeInternal::InfCallback() ---------------------------------- + +#ifdef WNT +HDDEDATA CALLBACK DdeInternal::InfCallback( + WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ) +#else +#if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC ) +HDDEDATA CALLBACK __EXPORT DdeInternal::InfCallback( + WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ) +#else +HDDEDATA CALLBACK _export DdeInternal::InfCallback( + WORD, WORD, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD ) +#endif +#endif +{ + return (HDDEDATA)DDE_FNOTPROCESSED; +} + +// --- DdeServiceList::DdeServiceList() ---------------------------- + +DdeServiceList::DdeServiceList( const String* pTopic ) +{ + DWORD hDdeInst = NULL; + HCONVLIST hConvList = NULL; + HCONV hConv = NULL; + UINT nStatus = DMLERR_NO_ERROR; + HSZ hTopic = NULL; + +#ifndef OS2 // YD FIXME + + nStatus = DdeInitialize( &hDdeInst, (PFNCALLBACK) DdeInternal::InfCallback, + APPCLASS_STANDARD | APPCMD_CLIENTONLY | + CBF_FAIL_ALLSVRXACTIONS | + CBF_SKIP_ALLNOTIFICATIONS, 0L ); + + if ( nStatus == DMLERR_NO_ERROR ) + { + if ( pTopic ) + { + LPCTSTR p = reinterpret_cast<LPCTSTR>(pTopic->GetBuffer()); +#ifdef __MINGW32__ + hTopic = DdeCreateStringHandle( hDdeInst, const_cast<LPTSTR>(p), CP_WINUNICODE ); +#else + hTopic = DdeCreateStringHandle( hDdeInst, p, CP_WINUNICODE ); +#endif + } + + hConvList = DdeConnectList( hDdeInst, NULL, hTopic, NULL, NULL ); + nStatus = DdeGetLastError( hDdeInst ); + } + + if ( nStatus == DMLERR_NO_ERROR ) + { + while ( ( hConv = DdeQueryNextServer( hConvList, hConv ) ) != NULL) + { + CONVINFO aInf; + TCHAR buf[256], *p; + HSZ h; +#ifdef OS2 + aInf.nSize = sizeof( aInf ); +#else + aInf.cb = sizeof( aInf ); +#endif + if( DdeQueryConvInfo( hConv, QID_SYNC, &aInf)) + { + h = aInf.hszServiceReq; + if ( !h ) +#ifndef OS2 + h = aInf.hszSvcPartner; +#else + h = aInf.hszPartner; +#endif + DdeQueryString( hDdeInst, h, buf, sizeof(buf) / sizeof(TCHAR), CP_WINUNICODE ); + p = buf + lstrlen( buf ); + *p++ = '|'; *p = 0; + DdeQueryString( hDdeInst, aInf.hszTopic, p, sizeof(buf)/sizeof(TCHAR)-lstrlen( buf ), + CP_WINUNICODE ); + aServices.Insert( new String( reinterpret_cast<const sal_Unicode*>(buf) ) ); + } + } + DdeDisconnectList( hConvList ); + } + + if ( hTopic) + DdeFreeStringHandle( hDdeInst, hTopic ); + if ( hDdeInst ) + DdeUninitialize( hDdeInst ); + +#endif + +} + +// --- DdeServiceList::~DdeServiceList() --------------------------- + +DdeServiceList::~DdeServiceList() +{ + String* s; + while ( ( s = aServices.First() ) != NULL ) + { + aServices.Remove( s ); + delete s; + } +} + +// --- DdeTopicList::DdeTopicList() -------------------------------- + +DdeTopicList::DdeTopicList( const String& rService ) +{ + DdeConnection aSys( rService, String( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) ) ); + + if ( !aSys.GetError() ) + { + DdeRequest aReq( aSys, String( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ), 500 ); + aReq.SetDataHdl( LINK( this, DdeTopicList, Data ) ); + aReq.Execute(); + } +} + +// --- DdeTopicList::~DdeTopicList() ------------------------------- + +DdeTopicList::~DdeTopicList() +{ + String* s; + while ( ( s = aTopics.First() ) != NULL ) + { + aTopics.Remove( s ); + delete s; + } +} + +// --- DdeTopicList::Data() -------------------------------------------- + +IMPL_LINK( DdeTopicList, Data, DdeData*, pData ) +{ + char* p = (char*) (const void *) *pData; + char* q = p; + short i; + char buf[256]; + + while ( *p && *p != '\r' && *p != '\n' ) + { + q = buf; i = 0; + while ( i < 255 && *p && *p != '\r' && *p != '\n' && *p != '\t' ) + *q++ = *p++, i++; + *q = 0; + while ( *p && *p != '\r' && *p != '\n' && *p != '\t' ) + p++; + aTopics.Insert( new String( String::CreateFromAscii(buf) ) ); + if ( *p == '\t' ) + p++; + } + return 0; +} + diff --git a/svl/source/svdde/ddeml1.cxx b/svl/source/svdde/ddeml1.cxx new file mode 100644 index 000000000000..9d1351b17f16 --- /dev/null +++ b/svl/source/svdde/ddeml1.cxx @@ -0,0 +1,2661 @@ +/************************************************************************* + * + * 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: ddeml1.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +/* + ToDo / Bugs: + + - DdeInitiate: Eigener Thread? + - Timeout bei Disconnects (IBM:nicht auf Ack warten!) + - Konzept Errorhandling (globale/lokale Fehler) + - Bedeutung/Anwendung Conversation-Contexte + - Bei Zugriffen auf ConversationHandles WindowHandles checken + - Namen der Partner-App ermitteln + - Codepage-Geraffel +*/ +#define INCL_DOSPROCESS + +#include "ddemlimp.hxx" + +#define LOGFILE +#define STATUSFILE +#define DDEDATAFILE +#include "ddemldeb.hxx" + + +#if defined (OS2) && defined (__BORLANDC__) +#pragma option -w-par +#endif + +// static +inline BOOL ImpDdeMgr::MyWinDdePostMsg( HWND hWndTo, HWND hWndFrom, + USHORT nMsg, PDDESTRUCT pData, ULONG nFlags ) +{ + BOOL bSuccess = WinDdePostMsg( hWndTo,hWndFrom,nMsg,pData,nFlags); + if( !bSuccess ) + { + WRITELOG("WinDdePostMsg:Failed!") + if ( !(nFlags & DDEPM_NOFREE) ) + { + MyDosFreeMem( pData,"MyWinDdePostMsg" ); + } + } + return bSuccess; +} + + +// ********************************************************************* +// ImpDdeMgr +// ********************************************************************* + +USHORT ImpDdeMgr::nLastErrInstance = 0; + +// +// Conversation-WndProc +// Steuert Transaktionen eines Conversationhandles +// +MRESULT EXPENTRY ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2) +{ +#if defined(DBG_UTIL) && defined(OV_DEBUG) + if( nMsg >= WM_DDE_FIRST && nMsg <= WM_DDE_LAST) + { + ////WRITELOG("::ConvWndProc:DDE-Msg received") + } +#endif + ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 ); + return pObj->pThis->ConvWndProc( hWnd, nMsg, nPar1, nPar2 ); +} + +// +// Server-WndProc +// DDE-Server-Window der App +// +MRESULT EXPENTRY ServerWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2) +{ +#if defined(DBG_UTIL) && defined(OV_DEBUG) + if( nMsg >= WM_DDE_FIRST && nMsg <= WM_DDE_LAST) + { + ////WRITELOG("::ServerWndProc:DDE-Msg received") + } +#endif + ImpDdeMgr* pObj = (ImpDdeMgr*)WinQueryWindowULong( hWnd, 0 ); + return pObj->SrvWndProc( hWnd, nMsg, nPar1, nPar2 ); +} + + +inline HDDEDATA ImpDdeMgr::Callback( USHORT nTransactionType, + USHORT nClipboardFormat, HCONV hConversationHandle, HSZ hsz1, + HSZ hsz2, HDDEDATA hData, ULONG nData1, ULONG nData2 ) +{ + HDDEDATA hRet = (HDDEDATA)0; + if( pCallback ) + hRet = (*pCallback)(nTransactionType, nClipboardFormat, + hConversationHandle, hsz1, hsz2, hData, nData1, nData2); + return hRet; +} + + + +ImpDdeMgr::ImpDdeMgr() +{ + nLastErrInstance = DMLERR_NO_ERROR; + pCallback = 0; + nTransactFilter = 0; + nServiceCount = 0; + pServices = 0; + pAppTable = 0; + pConvTable = 0; + pTransTable = 0; + bServFilterOn = TRUE; + bInSyncTrans = FALSE; + + CreateServerWnd(); + pData = InitAll(); + if ( !pData ) + nLastErrInstance = DMLERR_MEMORY_ERROR; + else + RegisterDDEMLApp(); +} + +ImpDdeMgr::~ImpDdeMgr() +{ + CleanUp(); + DestroyServerWnd(); +// Named Shared Mem vom BS loeschen lassen, da nicht bekannt ist, +// wieviele DDEML-Instanzen die App erzeugt hat, und OS/2 +// keinen App-Referenzzaehler fuer shared mem fuehrt. +// if ( pData ) +// DosFreeMem( pData ); +} + + +BOOL ImpDdeMgr::IsSameInstance( HWND hWnd ) +{ + TID tid; PID pid; + WinQueryWindowProcess( hWnd, &pid, &tid ); + return (BOOL)(pid == pidThis); +} + +HSZ ImpDdeMgr::GetAppName( HWND hWnd ) +{ + return 0; +} + +// static +ImpDdeMgr* ImpDdeMgr::GetImpDdeMgrInstance( HWND hWnd ) +{ + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if( !pData ) + return 0; + + ImpDdeMgr* pResult = 0; + TID tid; PID pidApp; + WinQueryWindowProcess( hWnd, &pidApp, &tid ); + HWND* pApp = ImpDdeMgr::GetAppTable( pData ); + USHORT nCurApp = 0; + while( nCurApp < pData->nMaxAppCount ) + { + HWND hCurWin = *pApp; + if( hCurWin ) + { + PID pidCurApp; + WinQueryWindowProcess( hCurWin, &pidCurApp, &tid ); + if( pidCurApp == pidApp ) + { + pResult = (ImpDdeMgr*)WinQueryWindowULong( hCurWin, 0 ); + break; + } + } + pApp++; + nCurApp++; + } + return pResult; +} + + + + + +void ImpDdeMgr::CleanUp() +{ + DisconnectAll(); + ImpService* pPtr = pServices; + if( pPtr ) + { + for( USHORT nIdx = 0; nIdx < nServiceCount; nIdx++, pPtr++ ) + { + HSZ hStr = pPtr->hBaseServName; + if( hStr ) + DdeFreeStringHandle( hStr ); + hStr = pPtr->hInstServName; + if( hStr ) + DdeFreeStringHandle( hStr ); + } + nServiceCount = 0; + delete pServices; + pServices = 0; + } + bServFilterOn = TRUE; // default setting DDEML + UnregisterDDEMLApp(); +} + +void ImpDdeMgr::RegisterDDEMLApp() +{ + HWND* pPtr = pAppTable; + HWND hCur; + USHORT nPos = 0; + while( nPos < pData->nMaxAppCount ) + { + hCur = *pPtr; + if (hCur == (HWND)0 ) + { + // in Tabelle stellen + *pPtr = hWndServer; + break; + } + nPos++; + pPtr++; + } +} + +void ImpDdeMgr::UnregisterDDEMLApp() +{ + HWND* pPtr = pAppTable; + USHORT nPos = 0; + while( nPos < pData->nMaxAppCount ) + { + if (*pPtr == hWndServer ) + { + *pPtr = 0; + break; + } + nPos++; + pPtr++; + } +} + +// static +ImpDdeMgrData* ImpDdeMgr::AccessMgrData() +{ + ImpDdeMgrData* pData = 0; + APIRET nRet = DosGetNamedSharedMem((PPVOID)&pData,DDEMLDATA,PAG_READ|PAG_WRITE); + DBG_ASSERT(!nRet,"DDE:AccessMgrData failed"); + return pData; +} + +USHORT ImpDdeMgr::DdeGetLastError() +{ + USHORT nErr; + if ( !pData ) + nErr = DMLERR_DLL_NOT_INITIALIZED; + else if ( nLastErrInstance ) + nErr = nLastErrInstance; + else + nErr = pData->nLastErr; + + nLastErrInstance = 0; + pData->nLastErr = 0; + return nErr; +} + + + +USHORT ImpDdeMgr::DdeInitialize( PFNCALLBACK pCallbackProc, ULONG nTransactionFilter ) +{ + if ( !nLastErrInstance ) + { + if ( !pCallbackProc ) + { + nLastErrInstance = DMLERR_INVALIDPARAMETER; + return nLastErrInstance; + } + pCallback = pCallbackProc; + nTransactFilter = nTransactionFilter; + nTransactFilter |= CBF_FAIL_SELFCONNECTIONS; + } + return nLastErrInstance; +} + + +// static +HWND ImpDdeMgr::NextFrameWin( HENUM hEnum ) +{ + char aBuf[ 10 ]; + + HWND hWnd = WinGetNextWindow( hEnum ); + while( hWnd ) + { + WinQueryClassName( hWnd, sizeof(aBuf)-1, (PCH)aBuf ); + // Frame-Window ? + if( !strcmp( aBuf, "#1" ) ) // #define WC_FRAME ((PSZ)0xffff0001L) + break; + hWnd = WinGetNextWindow( hEnum ); + } + return hWnd; +} + + +HCONV ImpDdeMgr::DdeConnectImp( HSZ hszService,HSZ hszTopic,CONVCONTEXT* pCC) +{ + hCurConv = 0; + if( !pCC ) + pCC = &aDefaultContext; + + ULONG nBufLen; + PSZ pService = AllocAtomName( (ATOM)hszService, nBufLen ); + PSZ pTopic = AllocAtomName( (ATOM)hszTopic, nBufLen ); +#if 0 && defined(OV_DEBUG) + String aStr("DdeConnectImp Service:"); + aStr += pService; + aStr += " Topic:"; + aStr += pTopic; + WRITELOG((char*)(const char*)aStr) +#endif + +#if defined(OV_DEBUG) + if( !strcmp(pService,"oliver voeltz") ) + { + WRITESTATUS("Table of connections"); + MyDosFreeMem( pTopic,"DdeConnectImp" ); + MyDosFreeMem( pService,"DdeConnectImp" ); + return 0; + } +#endif + +#if 0 + // original pm-fkt benutzen + HWND hWndCurClient = CreateConversationWnd(); + WinDdeInitiate( hWndCurClient, pService, pTopic, pCC ); + if( GetConversationWndRefCount(hWndCurClient) == 0) + DestroyConversationWnd( hWndCurClient ); +#else + // eigener Verbindungsaufbau + HENUM hEnum = WinBeginEnumWindows( HWND_DESKTOP ); + HWND hWndCurSrv = NextFrameWin( hEnum ); + HWND hWndCurClient = CreateConversationWnd(); + while( hWndCurSrv && !hCurConv ) + { + if( hWndCurSrv != hWndServer || + ((nTransactFilter & CBF_FAIL_SELFCONNECTIONS)==0 )) + { + // pro DDE-Server ein Conversation-Window erzeugen + if( GetConversationWndRefCount(hWndCurClient) >= 2) + { + DestroyConversationWnd( hWndCurClient ); + hWndCurClient = CreateConversationWnd(); + } + MyInitiateDde(hWndCurSrv,hWndCurClient,hszService,hszTopic,pCC); + if( !bListConnect && hCurConv ) + break; + } + hWndCurSrv = NextFrameWin( hEnum ); + } + + if( GetConversationWndRefCount(hWndCurClient) == 0) + DestroyConversationWnd( hWndCurClient ); + WinEndEnumWindows( hEnum ); +#endif + + if( !hCurConv ) + nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; + +#if 0 && defined(OV_DEBUG) + String aCStr( "DdeConnectImp:End "); + if( nLastErrInstance != DMLERR_NO_CONV_ESTABLISHED ) + aCStr += "(Success)"; + else + aCStr += "(Failed)"; + WRITELOG((char*)aCStr.GetStr()) +#endif + + MyDosFreeMem( pTopic,"DdeConnectImp" ); + MyDosFreeMem( pService,"DdeConnectImp" ); + return hCurConv; +} + +HCONV ImpDdeMgr::DdeConnect( HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC) +{ + ////WRITELOG("DdeConnect:Start") + bListConnect = FALSE; + HCONV hResult = DdeConnectImp( hszService, hszTopic, pCC ); + ////WRITELOG("DdeConnect:End") + ////WRITESTATUS("DdeConnect:End") + return hResult; +} + + +HCONVLIST ImpDdeMgr::DdeConnectList( HSZ hszService, HSZ hszTopic, + HCONVLIST hConvList, CONVCONTEXT* pCC ) +{ + nPrevConv = 0; + ////WRITESTATUS("Before DdeConnectList") + if( hConvList ) + { + HCONV hLastConvInList; + + hCurListId = hConvList; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConvList; + if( (USHORT)hConvList >= pData->nMaxConvCount ||pConv->hWndThis==0 ) + { + nLastErrInstance = DMLERR_INVALIDPARAMETER; + return 0; + } + GetLastServer(pData, hConvList, hLastConvInList); + nPrevConv = (USHORT)hLastConvInList; + } + else + hCurListId = (HCONVLIST)WinCreateWindow( HWND_OBJECT, WC_FRAME, + CONVLISTNAME, 0,0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0,0,0); + + bListConnect = TRUE; + DdeConnectImp( hszService, hszTopic, pCC ); +#if 0 && defined(OV_DEBUG) + WRITELOG("DdeConnectList:ConnectionList:") + HCONV hDebug = 0; + do + { + hDebug = DdeQueryNextServer( hCurListId, hDebug); + String aStr( (ULONG)hDebug ); + WRITELOG((char*)(const char*)aStr) + } while( hDebug ); +#endif + ////WRITESTATUS("After DdeConnectList") + return (HCONVLIST)hCurListId; +} + +DDEINIT* ImpDdeMgr::CreateDDEInitData( HWND hWndDestination, HSZ hszService, + HSZ hszTopic, CONVCONTEXT* pCC ) +{ + ULONG nLen1 = 0, nLen2 = 0; + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); + + if( hszService ) + nLen1 = WinQueryAtomLength( hAtomTable, hszService ); + if( hszTopic ) + nLen2 = WinQueryAtomLength( hAtomTable, hszTopic ); + nLen1++; nLen2++; + + DDEINIT* pBuf = 0; + + ULONG nLen = sizeof(DDEINIT) + nLen1+ nLen2 + sizeof(CONVCONTEXT); + if( !(MyDosAllocSharedMem((PPVOID)&pBuf, NULL, nLen, + PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | OBJ_ANY, + "CreateDDEInitData"))) + { + memset( pBuf, 0, nLen ); + + /* + PID pid; TID tid; + WinQueryWindowProcess( hWndDestination, &pid, &tid ); + APIRET nRet = DosGiveSharedMem( pBuf, pid, PAG_READ | PAG_WRITE ); + */ + + pBuf->cb = nLen; + pBuf->offConvContext = sizeof( DDEINIT ); + char* pBase = (char*)pBuf; + pBase += sizeof(DDEINIT); + if( pCC ) + memcpy( pBase, pCC, sizeof(CONVCONTEXT) ); + pBase += sizeof(CONVCONTEXT); + pBuf->pszAppName = pBase; + if( hszService ) + WinQueryAtomName( hAtomTable, hszService, pBase, nLen1 ); + pBase += nLen1; + pBuf->pszTopic = pBase; + if( hszTopic ) + WinQueryAtomName( hAtomTable, hszTopic, pBase, nLen2 ); + } + return pBuf; +} + + + +void ImpDdeMgr::MyInitiateDde( HWND hWndSrv, HWND hWndClient, + HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC ) +{ + DDEINIT* pBuf = CreateDDEInitData( hWndSrv, hszService, hszTopic, pCC ); + if( pBuf ) + { + PID pid; TID tid; + WinQueryWindowProcess( hWndSrv, &pid, &tid ); + APIRET nRet = DosGiveSharedMem( pBuf, pid, PAG_READ | PAG_WRITE ); + WinSendMsg( hWndSrv,WM_DDE_INITIATE,(MPARAM)hWndClient,(MPARAM)pBuf); + MyDosFreeMem( pBuf,"MyInitiateDde" ); + } +} + +// static +ImpHCONV* ImpDdeMgr::GetFirstServer(ImpDdeMgrData* pData, HCONVLIST hConvList, + HCONV& rhConv ) +{ + ImpHCONV* pPtr = GetConvTable( pData ); + HCONV hConv; + if( !rhConv ) + { + pPtr++; + hConv = 1; + } + else + { + // Startposition + pPtr += (USHORT)rhConv; + hConv = rhConv; + pPtr++; hConv++; // auf den naechsten + } + while( hConv < pData->nMaxConvCount ) + { + if( pPtr->hConvList == hConvList ) + { + rhConv = hConv; + return pPtr; + } + pPtr++; + hConv++; + } + rhConv = 0; + return 0; +} + +// static +ImpHCONV* ImpDdeMgr::GetLastServer(ImpDdeMgrData* pData, HCONVLIST hConvList, + HCONV& rhConv ) +{ + ImpHCONV* pPtr = GetConvTable( pData ); + pPtr += pData->nMaxConvCount; + pPtr--; + HCONV hConv = pData->nMaxConvCount; + hConv--; + while( hConv > 0 ) + { + if( pPtr->hConvList == hConvList ) + { + rhConv = hConv; + return pPtr; + } + pPtr--; + hConv--; + } + rhConv = 0; + return 0; +} + +// static +BOOL ImpDdeMgr::CheckConvListId( HCONVLIST hConvListId ) +{ + HAB hAB = WinQueryAnchorBlock( (HWND)hConvListId ); + if( hAB ) + return WinIsWindow( hAB, (HWND)hConvListId ); + return FALSE; + /* + HAB hAB = WinQueryAnchorBlock( (HWND)hConvListId ); + if( hAB ) + { + char aBuf[ 16 ]; + WinQueryWindowText( (HWND)hConvListId, sizeof(aBuf), aBuf ); + if( strcmp(aBuf, CONVLISTNAME ) == 0 ) + return TRUE; + } + return FALSE; + */ +} + +// static +HCONV ImpDdeMgr::DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev) +{ + if( !CheckConvListId( hConvList ) ) + return (HCONV)0; + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + GetFirstServer( pData, hConvList, hConvPrev ); + return hConvPrev; +} + +// static + +// Idee: DisconnectAll uebergibt das ServerWindow. Zu jedem HCONV +// wird das Creator-Server-Wnd gespeichert. Disconnect braucht +// dann nur noch die Window-Handles zu vergleichen +BOOL ImpDdeMgr::DdeDisconnect( HCONV hConv ) +{ + WRITELOG("DdeDisconnect:Start") + ////WRITESTATUS("DdeDisconnect:Start") + + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return FALSE; + } + ImpHCONV* pConv = GetConvTable(pData) + (USHORT)hConv; + + if( (USHORT)hConv >= pData->nMaxConvCount || pConv->hWndThis==0 ) + { + nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; + return FALSE; + } + + PID pidApp; TID tid; + HWND hWndDummy = WinCreateWindow( HWND_OBJECT, WC_FRAME, + "Bla", 0, 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 ); + WinQueryWindowProcess( hWndDummy, &pidApp, &tid ); + WinDestroyWindow( hWndDummy ); + PID pidThis; PID pidPartner; + + HWND hWndThis = pConv->hWndThis; + HWND hWndPartner = pConv->hWndPartner; + + WinQueryWindowProcess( hWndThis, &pidThis, &tid ); + WinQueryWindowProcess( hWndPartner, &pidPartner, &tid ); + if( pidApp != pidThis && pidApp != pidPartner ) + return TRUE; // gehoert nicht der App -> ueberspringen + + HCONV hConvPartner = pConv->hConvPartner; + + // die App benachrichtigen, dass alle offenen Advise-Loops + // beendet werden, egal ob sie vom Server oder Client + // initiiert wurden. Die Dinger aber nicht loeschen, da sie evtl. + // noch vom Partner gebraucht werden. + ImpConvWndData* pObj = + (ImpConvWndData*)WinQueryWindowULong( pConv->hWndThis, 0 ); + ImpDdeMgr* pThis = pObj->pThis; + pThis->SendUnadvises( hConv, 0, FALSE ); // alle Formate & NICHT loeschen + pThis->SendUnadvises( hConvPartner, 0, FALSE ); // alle Formate & NICHT loeschen + + pConv->nStatus |= ST_TERMINATED; + + HAB hAB = WinQueryAnchorBlock( pConv->hWndThis ); + // um die MessageQueue inne Gaenge zu halten + ULONG nTimerId = WinStartTimer( hAB, 0, 0, 50 ); + + /* + Die Partner-App muss ein DDE_TERMINATE posten, auf das + wir warten muessen, um alle Messages zu bearbeiten, die + _vor_ dem DdeDisconnect von der Partner-App gepostet + wurden. + */ + WRITELOG("DdeDisconnect:Waiting for acknowledge...") + WinDdePostMsg( hWndPartner, hWndThis, WM_DDE_TERMINATE, + (PDDESTRUCT)0,DDEPM_RETRY); + + QMSG aQueueMsg; + BOOL bContinue = TRUE; + while( bContinue ) + { + if( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 )) + { + WinDispatchMsg( hAB, &aQueueMsg ); + if( (!WinIsWindow( hAB, hWndPartner)) || + (pConv->nStatus & ST_TERMACKREC) ) + { + bContinue = FALSE; + if( pConv->nStatus & ST_TERMACKREC ) + { + WRITELOG("DdeDisconnect: TermAck received") + } + else + { + WRITELOG("DdeDisconnect: Partner died") + } + } + } + else + bContinue = FALSE; + } + + WinStopTimer( hAB, 0, nTimerId ); + + // WRITELOG("DdeDisconnect:Freeing data") + // Transaktionstabelle aufraeumen + FreeTransactions( pData, hConv ); + if( hConvPartner ) + FreeTransactions( pData, hConvPartner ); + + FreeConvHandle( pData, hConv ); + + WRITELOG("DdeDisconnect:End") + //WRITESTATUS("DdeDisconnect:End") + return TRUE; +} + +// static +BOOL ImpDdeMgr::DdeDisconnectList( HCONVLIST hConvList ) +{ + if( !CheckConvListId( hConvList ) ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + return FALSE; + } + + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return FALSE; + } + HCONV hConv = 0; + GetFirstServer( pData, hConvList, hConv ); + while( hConv ) + { + DdeDisconnect( hConv ); + GetFirstServer( pData, hConvList, hConv ); + } + WinDestroyWindow( (HWND)hConvList ); + return TRUE; +} + + + +// static +HCONV ImpDdeMgr::DdeReconnect(HCONV hConv) +{ + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return 0; + } + return 0; +} + +// static +USHORT ImpDdeMgr::DdeQueryConvInfo(HCONV hConv, ULONG nTransId, CONVINFO* pCI) +{ + if( !pCI || pCI->nSize == 0) + return 0; + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return 0; + } + Transaction* pTrans; + if( nTransId != QID_SYNC ) + { + pTrans = ImpDdeMgr::GetTransTable( pData ); + pTrans += nTransId; + if( nTransId >= pData->nMaxTransCount || pTrans->hConvOwner == 0 ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; + return 0; + } + } + else + pTrans = 0; + + ImpHCONV* pConv = ImpDdeMgr::GetConvTable( pData ); + pConv += (ULONG)hConv; + if( hConv >= pData->nMaxConvCount || pConv->hWndThis == 0 ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; + return 0; + } + + USHORT nSize = pCI->nSize; + if( nSize > sizeof(CONVINFO) ) + nSize = sizeof(CONVINFO); + CONVINFO aTempInfo; + memset( &aTempInfo, 0, sizeof(CONVINFO) ); + aTempInfo.nSize = pCI->nSize; + aTempInfo.hConvPartner = pConv->hConvPartner; + aTempInfo.hszPartner = pConv->hszPartner; + aTempInfo.hszServiceReq = pConv->hszServiceReq; + aTempInfo.hszTopic = pConv->hszTopic; + aTempInfo.nStatus = pConv->nStatus; + aTempInfo.hConvList = pConv->hConvList; + aTempInfo.aConvCtxt = pConv->aConvContext; + if( pTrans ) + { + aTempInfo.nUser = pTrans->nUser; + aTempInfo.hszItem = pTrans->hszItem; + aTempInfo.nFormat = pTrans->nFormat; + aTempInfo.nType = pTrans->nType; + aTempInfo.nConvst = pTrans->nConvst; + aTempInfo.nLastError= pTrans->nLastError; + } + memcpy( pCI, &aTempInfo, nSize ); + + return nSize; +} + +// static +BOOL ImpDdeMgr::DdeSetUserHandle(HCONV hConv, ULONG nTransId, ULONG hUser) +{ + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return FALSE; + } + Transaction* pTrans = GetTransTable( pData ); + pTrans += nTransId; + if( !nTransId || !hConv || nTransId >= pData->nMaxTransCount || + pTrans->hConvOwner != hConv ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + return FALSE; + } + if( !pTrans->hConvOwner) + { + ImpDdeMgr::nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; + return FALSE; + } + pTrans->nUser = hUser; + return TRUE; +} + +BOOL ImpDdeMgr::DdeAbandonTransaction( HCONV hConv, ULONG nTransId ) +{ + ////WRITELOG("DdeAbandonTransaction:Start") + if( !pData ) + { + nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return FALSE; + } + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + if( nTransId < 1 || nTransId >= pData->nMaxTransCount || + hConv < 1 || hConv >= pData->nMaxConvCount || !pConv->hWndThis) + { + nLastErrInstance = DMLERR_INVALIDPARAMETER; + return FALSE; + } + if( !hConv ) + { + DBG_ASSERT(0,"DdeAbandonTransaction:NULL-hConv not supported"); + nLastErrInstance = DMLERR_INVALIDPARAMETER; + return FALSE; + } + Transaction* pTrans = pTransTable; + pTrans += (USHORT)nTransId; + if( pTrans->hConvOwner != hConv ) + { + nLastErrInstance = DMLERR_UNFOUND_QUEUE_ID; + return FALSE; + } + + if( bInSyncTrans && nTransId == nSyncTransId ) + { + bSyncAbandonTrans = TRUE; + return TRUE; + } + USHORT nTempType = pTrans->nType; + nTempType &= (~XTYPF_MASK); + if( nTempType == (XTYP_ADVREQ & ~(XTYPF_NOBLOCK))) + { + ////WRITELOG("DdeAbandTrans:Advise Loop") + +// ---------------------------------------------------------------------- +// Der von der Deutschen Bank eingesetzte DDE-Server +// "Invision V2.71 Build 36 Mar 12 1999 V4.8.2" hat einen Bug, der +// dazu fuehrt, dass auf per WM_DDE_TERMINATE geschlossene Verbindungen +// nicht mit einem WM_DDE_TERMINATE geantwortet wird, wenn der +// entsprechende Link vorher per WM_DDE_UNADVISE beendet wurde. Dieser +// Bug tritt ab zwei parallel laufenden Links auf. Auf Wunsch der DB +// wurde das folgende Workaround eingebaut. +// ---------------------------------------------------------------------- +#define DEUTSCHE_BANK +#ifndef DEUTSCHE_BANK + +// Acknowledge ist beim Unadvise nicht ueblich +//#define SO_DDE_ABANDON_TRANSACTION_WAIT_ACK +#ifdef SO_DDE_ABANDON_TRANSACTION_WAIT_ACK + DDESTRUCT* pOutDDEData = MakeDDEObject( pConv->hWndPartner, + pTrans->hszItem, DDE_FACKREQ, 0 /*pTrans->nFormat*/, 0, 0); +#else + DDESTRUCT* pOutDDEData = MakeDDEObject( pConv->hWndPartner, + pTrans->hszItem, 0, 0 /*pTrans->nFormat*/, 0, 0); +#endif + WRITELOG("DdeAbandTrans:Waiting for acknowledge...") + pTrans->nConvst = XST_UNADVSENT; + if ( !MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, + WM_DDE_UNADVISE, pOutDDEData, DDEPM_RETRY ) ) + { + WRITELOG("DdeAbandTrans:PostMsg Failed") + return FALSE; + } +#ifdef SO_DDE_ABANDON_TRANSACTION_WAIT_ACK + WaitTransState( pTrans, nTransId, XST_UNADVACKRCVD, 0 ); +#else + pTrans->nConvst = XST_UNADVACKRCVD; +#endif + +#endif // DEUTSCHE_BANK + + WRITELOG("DdeAbandTrans:Ack received->Freeing transaction") + FreeTransaction( pData, nTransId ); + } + WRITELOG("DdeAbandonTransaction:End") + return TRUE; +} + +// wird von einem Server aufgerufen, wenn sich die Daten des +// Topic/Item-Paars geaendert haben. Diese Funktion fordert +// dann den Server auf, die Daten zu rendern (bei Hotlinks) und +// benachrichtigt die Clients +BOOL ImpDdeMgr::DdePostAdvise( HSZ hszTopic, HSZ hszItem) +{ + ////WRITELOG("DdePostAdvise:Start") + ////WRITESTATUS("DdePostAdvise:Start") + +#if 0 && defined( OV_DEBUG ) + String aDebStr("DdePostAdvise:Item "); + aDebStr += (ULONG)hszItem; + WRITELOG((char*)(const char*)aDebStr) +#endif + + Transaction* pTrans = pTransTable; + pTrans++; + USHORT nCurTrans = 1; + USHORT nUsedTransactions = pData->nCurTransCount; + while( nUsedTransactions && nCurTrans < pData->nMaxTransCount ) + { + HCONV hOwner = pTrans->hConvOwner; + if( hOwner ) + { + nUsedTransactions--; + USHORT nTempType = pTrans->nType; + nTempType &= (~XTYPF_MASK); + if( nTempType == (XTYP_ADVREQ & (~XTYPF_NOBLOCK) ) ) + { + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hOwner; + if(hszItem == pTrans->hszItem && pConv->hszTopic == hszTopic) + { + if( pConv->hConvPartner ) + { + // Transaktionen werden immer vom Client erzeugt + // -> auf Server-HCONV umschalten + hOwner = pConv->hConvPartner; + pConv = pConvTable; + pConv += (USHORT)hOwner; + } + HWND hWndClient = pConv->hWndPartner; + HWND hWndServer = pConv->hWndThis; +#if 0 && defined( OV_DEBUG ) + String aDebStr("DdePostAdvise: Server:"); + aDebStr += (ULONG)hWndServer; + aDebStr += " Client:"; + aDebStr += (ULONG)hWndClient; + WRITELOG((char*)(const char*)aDebStr) +#endif + DDESTRUCT* pOutDDEData; + if ( pTrans->nType & XTYPF_NODATA ) + { + // Warm link + ////WRITELOG("DdePostAdvise:Warm link found") + pOutDDEData = MakeDDEObject( hWndClient, hszItem, + DDE_FNODATA, pTrans->nFormat, 0, 0 ); + } + else + { + // Hot link + ////WRITELOG("DdePostAdvise:Hot link found") + pOutDDEData = Callback( XTYP_ADVREQ, + pTrans->nFormat, hOwner, hszTopic, + hszItem, (HDDEDATA)0, 1, 0 ); + } + if( pOutDDEData ) + { + // todo: FACK_REQ in Out-Data setzen, wenn pTrans->nType & XTYPF_ACKREQ + ////WRITELOG("DdePostAdvise:Sending data/notification") + BOOL bSuccess = MyWinDdePostMsg( hWndClient, + hWndServer,WM_DDE_DATA, pOutDDEData, DDEPM_RETRY); + if( bSuccess ) + { + // auf Acknowledge des Partners warten ? + if( pTrans->nType & XTYPF_ACKREQ ) + { + pTrans->nConvst = XST_ADVDATASENT; + // Impl. ist falsch! => korrekt: XST_ADVDATAACKRCVD + WaitTransState(pTrans, nCurTrans, + XST_UNADVACKRCVD, 0); + } + } + else + { + ////WRITELOG("DdePostAdvise:PostMsg failed") + nLastErrInstance = DMLERR_POSTMSG_FAILED; + } + } + else + { + ////WRITELOG("DdePostAdvise:No data to send") + } + } + } + } + nCurTrans++; + pTrans++; + } + ////WRITELOG("DdePostAdvise:End") + return TRUE; +} + +BOOL ImpDdeMgr::DdeEnableCallback( HCONV hConv, USHORT wCmd) +{ + return FALSE; +} + +// Rueckgabe: 0==Service nicht registriert; sonst Pointer auf Service-Eintrag +ImpService* ImpDdeMgr::GetService( HSZ hszService ) +{ + ImpService* pPtr = pServices; + if( !pPtr || !hszService ) + return 0; + for( ULONG nIdx = 0; nIdx < nServiceCount; nIdx++, pPtr++ ) + { + if(( hszService == pPtr->hBaseServName ) || + ( hszService == pPtr->hInstServName ) ) + return pPtr; + } + return 0; +} + + +// legt Service in Service-Tabelle ab. Tabelle wird ggf. expandiert +ImpService* ImpDdeMgr::PutService( HSZ hszService ) +{ + if( !pServices ) + { + DBG_ASSERT(nServiceCount==0,"DDE:Bad ServiceCount"); + pServices = new ImpService[ DDEMLSERVICETABLE_INISIZE ]; + memset( pServices, 0, DDEMLSERVICETABLE_INISIZE* sizeof(ImpService)); + nServiceCount = DDEMLSERVICETABLE_INISIZE; + } + ImpService* pPtr = pServices; + USHORT nCurPos = 0; + while( pPtr ) + { + if( pPtr->hBaseServName == 0 ) + break; + nCurPos++; + if( nCurPos < nServiceCount ) + pPtr++; + else + pPtr = 0; + } + if( !pPtr ) + { + // Tabelle vergroessern + pPtr = new ImpService[ nServiceCount + DDEMLSERVICETABLE_INISIZE ]; + memset( pPtr, 0, DDEMLSERVICETABLE_INISIZE* sizeof(ImpService)); + memcpy( pPtr, pServices, nServiceCount * sizeof(ImpService) ); +#ifdef DBG_UTIL + memset( pServices, 0, nServiceCount * sizeof(ImpService) ); +#endif + delete pServices; + pServices = pPtr; + pPtr += nServiceCount; // zeigt auf erste neue Position + nServiceCount += DDEMLSERVICETABLE_INISIZE; + } + DBG_ASSERT(pPtr->hBaseServName==0,"DDE:Service not empty"); + DBG_ASSERT(pPtr->hInstServName==0,"DDE:Service not empty"); + + DdeKeepStringHandle( hszService ); + + USHORT nStrLen = (USHORT)DdeQueryString( hszService, 0, 0, 0); + char* pBuf = new char[ nStrLen + 1 ]; + DdeQueryString(hszService, pBuf, nStrLen, 850 /* CodePage*/ ); + pBuf[ nStrLen ] = 0; + String aStr( (ULONG)hWndServer ); + aStr += pBuf; + HSZ hszInstServ = DdeCreateStringHandle( (PSZ)(const char*)pBuf, 850 ); + delete [] pBuf; + + pPtr->hBaseServName = hszService; + pPtr->hInstServName = hszInstServ; + return pPtr; +} + +void ImpDdeMgr::BroadcastService( ImpService* pService, BOOL bRegistered ) +{ + DBG_ASSERT(pService,"DDE:No Service"); + if( !pService ) + return; + MPARAM aMp1 = (MPARAM)(pService->hBaseServName); + MPARAM aMp2 = (MPARAM)(pService->hInstServName); + ULONG nMsg; + if( bRegistered ) + nMsg = WM_DDEML_REGISTER; + else + nMsg = WM_DDEML_UNREGISTER; + + HWND* pPtr = pAppTable; + for( USHORT nPos = 0; nPos < pData->nMaxAppCount; nPos++, pPtr++ ) + { + HWND hWndCurWin = *pPtr; + if ( hWndCurWin && hWndCurWin != hWndServer ) + WinSendMsg( hWndCurWin, nMsg, aMp1, aMp2 ); + } +} + +HDDEDATA ImpDdeMgr::DdeNameService( HSZ hszService, USHORT afCmd ) +{ + HDDEDATA hRet = (HDDEDATA)1; + + if( afCmd & DNS_FILTERON ) + bServFilterOn = TRUE; + else if( afCmd & DNS_FILTEROFF ) + bServFilterOn = FALSE; + ImpService* pService = GetService( hszService ); + BOOL bRegister = (BOOL)(afCmd & DNS_REGISTER); + if( bRegister ) + { + if( !pService ) + { + pService = PutService( hszService ); + BroadcastService( pService, TRUE ); + } + } + else + { + if( pService ) + { + BroadcastService( pService, FALSE ); + DdeFreeStringHandle( pService->hBaseServName ); + pService->hBaseServName = 0; + DdeFreeStringHandle( pService->hInstServName ); + pService->hInstServName = 0; + } + hRet = (HDDEDATA)0; // Service nicht gefunden + } + return hRet; +} + + +// static +HDDEDATA ImpDdeMgr::DdeClientTransaction(void* pDdeData, ULONG cbData, + HCONV hConv, HSZ hszItem, USHORT nFormat, USHORT nType, + ULONG nTimeout, ULONG* pResult) +{ + //WRITELOG("DdeClientTransaction:Start") + +#if 0 && defined(OV_DEBUG) + if( nType == XTYP_REQUEST ) + { + WRITELOG("Start XTYP_REQUEST"); + WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, + "Start XTYP_REQUEST","DdeClientTransaction", + HWND_DESKTOP,MB_OK); + } +#endif + + if( pResult ) + *pResult = 0; + + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if ( !pData ) + { + ImpDdeMgr::nLastErrInstance = DMLERR_DLL_NOT_INITIALIZED; + return (HDDEDATA)0; + } + + BOOL bIsDdeHandle = (BOOL)(pDdeData && cbData==0xffffffff); + BOOL bAppOwnsHandle = (BOOL)( bIsDdeHandle && + (((DDESTRUCT*)pDdeData)->fsStatus & IMP_HDATAAPPOWNED) ); + + BOOL bNoData = (BOOL)(nType & XTYPF_NODATA)!=0; + BOOL bAckReq = (BOOL)(nType & XTYPF_ACKREQ)!=0; + USHORT nTypeFlags = nType & XTYPF_MASK; + nType &= (~XTYPF_MASK); + + BOOL bSync = (BOOL)( nTimeout != TIMEOUT_ASYNC ) != 0; + if( nType == XTYP_ADVSTART ) + bSync = TRUE; + + // Mapping transaction -> OS/2-Message + USHORT nTimeoutErr, nMsg; + switch ( nType ) + { + case XTYP_ADVSTART: + nMsg = WM_DDE_ADVISE; + nTimeoutErr = DMLERR_ADVACKTIMEOUT; +{ + nTimeout = 60000; +#if 0 && defined(OV_DEBUG) + char aBuf[ 128 ]; + ImpDdeMgr::DdeQueryString( hszItem,aBuf,127,850); + String aXXStr("Establishing hotlink "); + aXXStr += aBuf; + WRITELOG((char*)aXXStr.GetStr()); +#endif + +} + break; + + case XTYP_ADVSTOP: + nMsg = WM_DDE_UNADVISE; + nTimeoutErr = DMLERR_UNADVACKTIMEOUT; + break; + + case XTYP_REQUEST: + nMsg = WM_DDE_REQUEST; + nTimeoutErr = DMLERR_DATAACKTIMEOUT; + break; + + case XTYP_POKE: + nMsg = WM_DDE_POKE; + nTimeoutErr = DMLERR_POKEACKTIMEOUT; + break; + + case XTYP_EXECUTE: + nMsg = WM_DDE_EXECUTE; + nTimeoutErr = DMLERR_EXECACKTIMEOUT; + break; + + default: + nMsg = 0; + } + if(!hConv || (USHORT)hConv>= pData->nMaxConvCount || !nType || !nMsg || + (nType != XTYP_EXECUTE && (!hszItem || !nFormat)) ) + { + WRITELOG("DdeClientTransaction:Invalid parameter") + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + if( bIsDdeHandle && !bAppOwnsHandle ) + DdeFreeDataHandle( (HDDEDATA)pDdeData ); + return (HDDEDATA)0; + } + + // ueber den Conversation handle das ImpDdeMgr-Objekt holen + ImpHCONV* pConv = GetConvTable( pData ); + pConv += (USHORT)hConv; + ImpConvWndData* pObj = + (ImpConvWndData*)WinQueryWindowULong( pConv->hWndThis, 0 ); + ImpDdeMgr* pThis = pObj->pThis; + + if( bSync && pThis->bInSyncTrans ) + { + WRITELOG("DdeClientTransaction:Already in sync. transaction") + ImpDdeMgr::nLastErrInstance = DMLERR_REENTRANCY; + if( bIsDdeHandle && !bAppOwnsHandle ) + DdeFreeDataHandle( (HDDEDATA)pDdeData ); + return (HDDEDATA)0; + } + + Transaction* pTrans; + + BOOL bReqOnAdvLoop = FALSE; + ULONG nTransId = GetTransaction( pData, hConv, hszItem, nFormat ); + if( nTransId ) + { + // WRITELOG("DdeClientTransaction:Transaction found") + pTrans = GetTransTable( pData ); + pTrans += (USHORT)nTransId; + USHORT nTransType = pTrans->nType; + nTransType &= (~XTYPF_MASK); + if( (nType != XTYP_REQUEST && nTransType == nType) || + // wird Advise-Loop schon zum requesten missbraucht ? + (nType == XTYP_REQUEST && + nTransType == XTYP_ADVREQ && + pTrans->nConvst == XST_WAITING_REQDATA)) + { + // dieser Kanal ist dicht! + WRITELOG("DdeClientTransaction:Transaction already used") + ImpDdeMgr::nLastErrInstance = DMLERR_REENTRANCY; + if( bIsDdeHandle && !bAppOwnsHandle ) + DdeFreeDataHandle( (HDDEDATA)pDdeData ); + return (HDDEDATA)0; + } + else if( nTransType == XTYP_ADVREQ ) + { + switch( nType ) + { + case XTYP_ADVSTOP: + //WRITELOG("DdeClientTransaction:Stopping advise trans") + pTrans->nType = XTYP_ADVSTOP; + break; + + case XTYP_ADVSTART: + //WRITELOG("DdeClientTransaction:Adj. Advise-Params") + pTrans->nType = XTYP_ADVREQ; + if( bNoData ) + pTrans->nType |= XTYPF_NODATA; + if( bAckReq ) + pTrans->nType |= XTYPF_ACKREQ; + if( pResult ) + *pResult = nTransId; + return (HDDEDATA)TRUE; + + case XTYP_REQUEST: + // WRITELOG("DdeClientTransaction:Using adv trans for req") + // nConvst wird unten auf XST_WAITING_REQDATA gesetzt + bReqOnAdvLoop = TRUE; + break; + + default: + WRITELOG("DdeClientTransaction:Invalid parameter") + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + if( bIsDdeHandle && !bAppOwnsHandle ) + DdeFreeDataHandle( (HDDEDATA)pDdeData ); + return (HDDEDATA)FALSE; + } + } + } + else + { + // WRITELOG("DdeClientTransaction:Creating transaction") + nTransId = CreateTransaction(pData, hConv, hszItem, nFormat, nType); + } + + pTrans = GetTransTable( pData ); + pTrans += (USHORT)nTransId; + pTrans->nConvst = XST_WAITING_ACK; + if( nType == XTYP_REQUEST ) + pTrans->nConvst = XST_WAITING_REQDATA; + + HWND hWndServer = pConv->hWndPartner; + HWND hWndClient = pConv->hWndThis; + + HDDEDATA pOutDDEData; + if( bIsDdeHandle ) + { + if( bAppOwnsHandle ) + { + // wir muessen leider leider duplizieren, da uns OS/2 + // keine Chance laesst, diesen Status im Datenobjekt + // zu versenken. + ////WRITELOG("DdeClientTransaction:Copying handle") + HDDEDATA pNew; + HDDEDATA pData = (HDDEDATA)pDdeData; + if( !(MyDosAllocSharedMem((PPVOID)&pNew, NULL, pData->cbData, + PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | OBJ_ANY, + "MakeDDEObject"))) + { + memcpy( pNew, pData, pData->cbData ); + pOutDDEData = pNew; + } + else + { + WRITELOG("DdeClientTransaction:No Memory") + ImpDdeMgr::nLastErrInstance = DMLERR_LOW_MEMORY; + return (HDDEDATA)0; + } + } + else + pOutDDEData = (HDDEDATA)pDdeData; + } + else + pOutDDEData=MakeDDEObject(hWndServer,hszItem,0,nFormat,pDdeData,cbData); + + pOutDDEData->fsStatus |= nTypeFlags; + + HDDEDATA pDDEInData = 0; + if( bSync ) + { + if( nType != XTYP_REQUEST ) + pOutDDEData->fsStatus |= DDE_FACKREQ; + + // WRITELOG("DdeClientTransaction:Starting sync. trans.") + pThis->hSyncResponseData = (HDDEDATA)0; + pThis->nSyncResponseMsg = 0; + pThis->bInSyncTrans = TRUE; + pThis->nSyncTransId = nTransId; + pThis->bSyncAbandonTrans = FALSE; + + if ( !MyWinDdePostMsg( hWndServer, hWndClient, nMsg, pOutDDEData, + DDEPM_RETRY) ) + { + WRITELOG("DdeClientTransaction:PostMsg failed") + nLastErrInstance = DMLERR_POSTMSG_FAILED; + if( !bReqOnAdvLoop ) + FreeTransaction( pData, nTransId ); + else + { + DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Error!") + pTrans->nConvst = 0; + } + return FALSE; + } + HAB hAB = WinQueryAnchorBlock( hWndClient ); + ULONG nDummyTimer = WinStartTimer( hAB, 0, 0, 50 ); + ULONG nTimeoutId = TID_USERMAX - nTransId; + WinStartTimer( hAB, hWndClient, nTimeoutId, nTimeout ); + QMSG aQueueMsg; + BOOL bLoop = TRUE; + while( bLoop ) + { + if( pThis->nSyncResponseMsg ) + bLoop = FALSE; + else + { + if( WinGetMsg(hAB,&aQueueMsg,0,0,0 )) + { + WinDispatchMsg( hAB, &aQueueMsg ); + } + else + bLoop = FALSE; + } + } + + WinStopTimer( hAB, hWndClient, nTimeoutId ); + WinStopTimer( hAB, 0, nDummyTimer ); + + // + // Der Speicherblock pOutDDEData muss vom Server geloescht worden sein! + // Ueberlegen: Nochmal loeschen, falls Server buggy ist, ansonsten + // platzt uns bald der Adressraum! + // + if( !pThis->nSyncResponseMsg ) + { + // unsere App wurde beendet + ////WRITELOG("DdeClientTransaction:App terminated") + return 0; + } + pDDEInData = pThis->hSyncResponseData; + nMsg = pThis->nSyncResponseMsg; + pThis->hSyncResponseData= 0; + pThis->nSyncResponseMsg = 0; + pThis->bInSyncTrans = FALSE; + pThis->nSyncTransId = 0; + if( !pDDEInData && nMsg != WM_TIMER ) + { + DBG_ASSERT(0,"Dde:No data!"); + WRITELOG("DdeClientTransaction: No Data!") + return (HDDEDATA)0; + } + switch( nMsg ) + { + case WM_TIMER: + WRITELOG("DdeClientTransaction:Timeout!") + nLastErrInstance = nTimeoutErr; + if( bReqOnAdvLoop ) + // auf normalen Loop-Betrieb zurueckschalten + pTrans->nConvst = XST_WAITING_ADVDATA; + break; + + case WM_DDE_ACK: + { + // WRITELOG("DdeClientTransaction:Ack received") + BOOL bPositive = (BOOL)(pDDEInData->fsStatus & DDE_FACK); + MyDosFreeMem( pDDEInData,"DdeClientTransaction" ); + pDDEInData = (HDDEDATA)bPositive; + if( nType == XTYP_ADVSTART && pDDEInData ) + { + +#if 0 && defined(OV_DEBUG) + char aBuf[ 128 ]; + ImpDdeMgr::DdeQueryString( pTrans->hszItem,aBuf,128,850); + String aXXStr("Hotlink "); +#endif + + if( bPositive ) + { + pTrans->nType = XTYP_ADVREQ; + // Hot/Warmlink, Ack + pTrans->nType |= nTypeFlags; + // XST_WAITING_ACK ==> XST_WAITING_ADVDATA + pTrans->nConvst = XST_WAITING_ADVDATA; + +#if 0 && defined(OV_DEBUG) + aXXStr += "established "; + aXXStr += aBuf; +#endif + + } + +#if 0 && defined(OV_DEBUG) + else + { + aXXStr += "failed "; + aXXStr += aBuf; + } + WRITELOG((char*)aXXStr.GetStr()); +#endif + + } + } + break; + + case WM_DDE_DATA: + // WRITELOG("DdeClientTransaction:Data received") + // WRITEDATA(pDDEInData) + if( bReqOnAdvLoop ) + { + DBG_ASSERT(pTrans->nConvst==XST_WAITING_REQDATA,"DDE:Bad state"); + DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Bad state"); + // auf Loop-Betrieb umschalten + pTrans->nConvst = XST_WAITING_ADVDATA; + } + break; + + default: + WRITELOG("DdeClientTransaction:Unexpected msg") + MyDosFreeMem( pDDEInData,"DdeClientTransaction" ); + pDDEInData = 0; + } + pThis->bSyncAbandonTrans = FALSE; + pThis->bInSyncTrans = FALSE; + if( pThis->bSyncAbandonTrans && bReqOnAdvLoop ) + pThis->DdeAbandonTransaction( hConv, nTransId ); + } + else + { + // WRITELOG("DdeClientTransaction:Starting async. trans.") + pDDEInData = (HDDEDATA)MyWinDdePostMsg( hWndServer, hWndClient, nMsg, + pOutDDEData, DDEPM_RETRY); + if( !pDDEInData ) + { + WRITELOG("DdeClientTransaction:PostMsg failed") + nLastErrInstance = DMLERR_POSTMSG_FAILED; + if( !bReqOnAdvLoop ) + FreeTransaction( pData, nTransId ); + else + { + DBG_ASSERT(pTrans->nType==XTYP_ADVREQ,"DDE:Error!") + pTrans->nConvst = 0; + } + } + else + { + // WRITELOG("DdeClientTransaction:Async trans. success") + if( pResult ) + *pResult = nTransId; + } + } +#if 0 && defined( OV_DEBUG ) + if( nType == XTYP_REQUEST ) + { + WRITELOG("End XTYP_REQUEST"); + WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, + "End XTYP_REQUEST","DdeClientTransaction", + HWND_DESKTOP,MB_OK); + } +#endif + //WRITELOG("DdeClientTransaction:End") + //WRITESTATUS("DdeClientTransaction:End") + return pDDEInData; +} + +MRESULT ImpDdeMgr::DdeRegister( ImpWndProcParams* pParams ) +{ + MRESULT nRet = (MRESULT)0; + if ( !(nTransactFilter & CBF_SKIP_REGISTRATIONS) ) + { + HSZ hSBaseName = (HSZ)pParams->nPar1; + HSZ hIBaseName = (HSZ)pParams->nPar2; + nRet=(MRESULT)Callback(XTYP_REGISTER,0,0,hSBaseName,hIBaseName,0,0,0); + } + return nRet; +} + +MRESULT ImpDdeMgr::DdeUnregister( ImpWndProcParams* pParams ) +{ + MRESULT nRet = (MRESULT)0; + if ( !(nTransactFilter & CBF_SKIP_UNREGISTRATIONS) ) + { + HSZ hSBaseName = (HSZ)pParams->nPar1; + HSZ hIBaseName = (HSZ)pParams->nPar2; + nRet=(MRESULT)Callback(XTYP_UNREGISTER,0,0,hSBaseName,hIBaseName,0,0,0); + } + return nRet; +} + +MRESULT ImpDdeMgr::DdeTimeout( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeTimeout:Received") + if( nSyncResponseMsg ) + { + ////WRITELOG("DdeTimeout:Trans already processed->ignoring timeout") + return (MRESULT)1; + } + ULONG nTimerId = (ULONG)pParams->nPar1; + ULONG nTransId = TID_USERMAX - nTimerId; + Transaction* pTrans = pTransTable; + pTrans += (USHORT)nTransId; + if( nTransId < 1 || nTransId >= pData->nMaxTransCount || + pTrans->hConvOwner == 0 ) + { + DBG_ASSERT(0,"DdeTimeout:Invalid TransactionId"); + return (MRESULT)1; + } + if( bInSyncTrans && nTransId == nSyncTransId ) + { + USHORT nTempType = pTrans->nType; + nTempType &= (~XTYPF_MASK); + // advise-loops koennen nur innerhalb synchroner + // requests timeouts bekommen. die transaktion wird + // in diesem fall nicht geloescht. + if( nTempType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK) )) + { + ////WRITELOG("DdeTimeout:Freeing transaction") + FreeTransaction( pData, nTransId ); + } + nSyncResponseMsg = WM_TIMER; +#if 0 && defined( OV_DEBUG ) + String aMsg("DdeTimeout:Transaction="); + aMsg += nTransId; + WRITELOG((char*)(const char*)aMsg) +#endif + } + else + { + ////WRITELOG("DdeTimeout:Async transaction timed out") + pTrans->nConvst = XST_TIMEOUT; + } + return (MRESULT)1; +} + + + +MRESULT ImpDdeMgr::DdeTerminate( ImpWndProcParams* pParams ) +{ + WRITELOG("DdeTerminate:Received") + HWND hWndThis = pParams->hWndReceiver; + HWND hWndPartner = (HWND)(pParams->nPar1); + + HCONV hConv = GetConvHandle( pData, hWndThis, hWndPartner ); +#if 0 && defined( OV_DEBUG ) + String strDebug("DdeTerminate:ConvHandle="); + strDebug += (USHORT)hConv; + WRITELOG((char*)(const char*)strDebug) +#endif + ImpHCONV* pConv = pConvTable + (USHORT)hConv; + if( hConv ) + { + // warten wir auf ein DDE_TERMINATE Acknowledge ? + if( pConv->nStatus & ST_TERMINATED ) + { + ////WRITELOG("DdeTerminate:TERMINATE-Ack received") + pConv->nStatus |= ST_TERMACKREC; + return (MRESULT)0; // DdeDisconnect raeumt jetzt auf + } + + // sind wir Server?, wenn ja: die App benachrichtigen, + // dass die Advise loops gestoppt wurden und die + // Transaktionen loeschen + + // OV 26.07.96: Die das TERMINATE empfangende App muss + // die Transaction-Tabelle abraeumen, egal ob Server oder Client!! + // Es muessen alle Trans geloescht werden, die als Owner den + // Client oder den Server haben! + // if( !(pConv->nStatus & ST_CLIENT ) ) + SendUnadvises( hConv, 0, FALSE ); // alle Formate & nicht loeschen + SendUnadvises( pConv->hConvPartner, 0, FALSE ); + + // wir werden von draussen gekillt + if ( !(nTransactFilter & CBF_SKIP_DISCONNECTS) ) + { + Callback( XTYP_DISCONNECT, 0, hConv, 0, 0, 0, + 0, (ULONG)IsSameInstance(hWndPartner)); + } + + // kann unsere Partner-App DDEML ? + if( !(pConv->hConvPartner) ) + { + // nein, deshalb Transaktionstabelle selbst loeschen + ////WRITELOG("DdeTerminate:Freeing transactions") + FreeTransactions( pData, hConv ); + } + } + else + nLastErrInstance = DMLERR_NO_CONV_ESTABLISHED; + +#if 0 && defined(OV_DEBUG) + if( !WinIsWindow(0,hWndPartner)) + { + WRITELOG("DdeTerminate:hWndPartner not valid") + } + if(!WinIsWindow(0,hWndThis)) + { + WRITELOG("DdeTerminate:hWndThis not valid") + } +#endif + + if( hConv ) + { + // hWndThis nicht loeschen, da wir den Handle noch fuer + // das Acknowledge brauchen + ////WRITELOG("DdeTerminate:Freeing conversation") + FreeConvHandle( pData, hConv, FALSE ); + } + + ////WRITELOG("DdeTerminate:Acknowledging DDE_TERMINATE") + +#ifdef OV_DEBUG + DBG_ASSERT(WinIsWindow( 0, hWndThis ),"hWndThis not valid"); +#endif + + if( !WinDdePostMsg( hWndPartner, hWndThis, WM_DDE_TERMINATE, 0, DDEPM_RETRY )) + { + ////WRITELOG("DdeTerminate:Acknowledging DDE_TERMINATE failed") + } + // jetzt hWndThis loeschen + DestroyConversationWnd( hWndThis ); + + return (MRESULT)0; +} + + +/* + Zuordnung des Conversationhandles: + + Verbindungsaufbau: + Client: DdeInitiate( HWNDClient ) + Server: Post( WM_DDE_INITIATEACK( HWNDServer )) + Client: CreateConvHandle( HWNDClient, HWNDServer ) + + Datenaustausch: + Server: Post(WM_DDE_ACK( HWNDSender )) + Client: GetConvHandle( HWNDClient, HWNDSender ) +*/ + +MRESULT ImpDdeMgr::ConvWndProc( HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2 ) +{ + ImpWndProcParams aParams; + + MRESULT nRet = (MRESULT)0; + aParams.hWndReceiver= hWnd; + aParams.nPar1 = nPar1; + aParams.nPar2 = nPar2; + + switch( nMsg ) + { + +#ifdef DBG_UTIL + case WM_DDE_INITIATE : + DBG_ASSERT(0,"dde:unexpected msg"); + nRet = (MRESULT)TRUE; + break; +#endif + + case WM_DDE_INITIATEACK : nRet = DdeInitiateAck(&aParams); break; + case WM_DDE_ACK : nRet = DdeAck( &aParams ); break; + case WM_DDE_ADVISE : nRet = DdeAdvise( &aParams ); break; + case WM_DDE_DATA : nRet = DdeData( &aParams ); break; + case WM_DDE_EXECUTE : nRet = DdeExecute( &aParams ); break; + case WM_DDE_POKE : nRet = DdePoke( &aParams ); break; + case WM_DDE_REQUEST : nRet = DdeRequest( &aParams ); break; + case WM_DDE_TERMINATE : nRet = DdeTerminate( &aParams ); break; + case WM_DDE_UNADVISE : nRet = DdeUnadvise( &aParams ); break; + case WM_TIMER : nRet = DdeTimeout( &aParams ); break; + } + return nRet; +} + +MRESULT ImpDdeMgr::SrvWndProc( HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2 ) +{ + MRESULT nRet = (MRESULT)0; + + ImpWndProcParams aParams; + aParams.hWndReceiver= hWnd; + aParams.nPar1 = nPar1; + aParams.nPar2 = nPar2; + + switch( nMsg ) + { +#ifdef DBG_UTIL + case WM_DDE_ACK : + case WM_DDE_ADVISE : + case WM_DDE_EXECUTE : + case WM_DDE_POKE : + case WM_DDE_REQUEST : + case WM_DDE_UNADVISE : + case WM_DDE_DATA : + case WM_DDE_INITIATEACK : + DBG_ASSERT(0,"dde:unexpected msg"); + nRet = (MRESULT)TRUE; + break; +#endif + + case WM_DDE_TERMINATE : + break; // DDE_INITIATE wurde im DDE_INITIATEACK terminiert + + // ein Client will was von uns + case WM_DDE_INITIATE : + nRet = DdeInitiate( &aParams ); + break; + + // eine ddeml-faehige App. hat einen Service (typ. AppName) [de]reg. + case WM_DDEML_REGISTER : + nRet = DdeRegister( &aParams ); + break; + + case WM_DDEML_UNREGISTER : + nRet = DdeUnregister( &aParams ); + break; + }; + return nRet; +} + + +MRESULT ImpDdeMgr::DdeAck( ImpWndProcParams* pParams ) +{ + //WRITELOG("DdeAck:Start") + HSZ hszItem; + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + if( pInDDEData ) + { + BOOL bPositive = (BOOL)(pInDDEData->fsStatus & DDE_FACK ) != 0; + BOOL bBusy = bPositive ? FALSE : (BOOL)(pInDDEData->fsStatus & DDE_FBUSY ) != 0; + BOOL bNotProcessed = (BOOL)(pInDDEData->fsStatus & DDE_NOTPROCESSED ) != 0; +#if 0 && defined( OV_DEBUG ) + String aDebStr("DdeAck:Received "); + if( bPositive ) + aDebStr += "(positive)"; + else + aDebStr += "(negative)"; + if( bBusy ) + aDebStr += "(busy)"; + if( bNotProcessed ) + aDebStr += "(not processed)"; + WRITELOG((char*)(const char*)aDebStr) +#endif + // ein DDE_ACK niemals bestaetigen (um endlosschleifen zu vermeiden) + pInDDEData->fsStatus &= (~DDE_FACKREQ); + } + else + { + //WRITELOG("DdeAck:Received (no data!)") + return (MRESULT)0; + } + + HCONV hConv = CheckIncoming(pParams, 0, hszItem); +#ifdef OV_DEBUG + if( !hConv ) + { + WRITELOG("DdeAck:HCONV not found") + } +#endif + ULONG nTransId=GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); + if( !nTransId ) + { + WRITELOG("DdeAck:Transaction not found") + MyDosFreeMem( pInDDEData,"DdeAck" ); + return (MRESULT)0; + } + + BOOL bThisIsSync = (BOOL)( bInSyncTrans && nTransId == nSyncTransId ); +#if 0 && defined( OV_DEBUG ) + if( bThisIsSync) + WRITELOG("DdeAck: sync transaction") + else + WRITELOG("DdeAck: async transaction") +#endif + // pruefen, ob die Transaktion abgeschlossen ist. + Transaction* pTrans = pTransTable; + pTrans += (USHORT)nTransId; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + + if( pTrans->nConvst == XST_UNADVSENT ) + { + //WRITELOG("DdeAck:Unadvise-Ack received") + pTrans->nConvst = XST_UNADVACKRCVD; + MyDosFreeMem( pInDDEData,"DdeAck" ); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + if( pTrans->nConvst == XST_ADVDATASENT ) + { + //WRITELOG("DdeAck:AdvData-Ack received") + pTrans->nConvst = XST_ADVDATAACKRCVD; + MyDosFreeMem( pInDDEData,"DdeAck" ); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + + USHORT nType = pTrans->nType; + nType &= (~XTYPF_MASK); + // beginn einer advise-loop oder request auf advise-loop ? + // wenn ja: transaktion nicht loeschen + BOOL bFinished = (BOOL)(nType != XTYP_ADVSTART && + nType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK)) ); + if( bFinished ) + { + if( !bThisIsSync ) + { + ////WRITELOG("DdeAck:Transaction completed") + Callback( XTYP_XACT_COMPLETE, pInDDEData->usFormat, hConv, + pConv->hszTopic, hszItem, (HDDEDATA)0, nTransId, 0 ); + } + ////WRITELOG("DdeAck:Freeing transaction") + FreeTransaction( pData, nTransId ); + } + + if( bThisIsSync ) + { + hSyncResponseData = pInDDEData; + nSyncResponseMsg = WM_DDE_ACK; + } + else + { + MyDosFreeMem( pInDDEData,"DdeAck" ); + } + + DdeFreeStringHandle( hszItem ); + + return (MRESULT)0; +} + + +USHORT ImpDdeMgr::SendUnadvises(HCONV hConvServer,USHORT nFormat,BOOL bFree) +{ + USHORT nTransFound = 0; + BOOL bCallApp = (BOOL)(!(nTransactFilter & CBF_FAIL_ADVISES)); +#if 0 && defined( OV_DEBUG ) + String aStr("Unadvising transactions for HCONV="); + aStr += (ULONG)hConvServer; + aStr += " CallApp:"; aStr += (USHORT)bCallApp; + WRITELOG((char*)aStr.GetStr()) +#endif + + + // wenn wir weder loeschen noch die App benachrichtigen sollen, + // koennen wir gleich wieder returnen + if( !hConvServer || ( !bFree && !bCallApp ) ) + return 0; + + ImpHCONV* pConvSrv = pConvTable; + pConvSrv += (USHORT)hConvServer; + HSZ hszTopic = pConvSrv->hszTopic; + + Transaction* pTrans = pTransTable; + pTrans++; + USHORT nCurTransId = 1; + USHORT nCurTransactions = pData->nCurTransCount; + while( nCurTransactions && nCurTransId < pData->nMaxTransCount ) + { + if( pTrans->hConvOwner ) + nCurTransactions--; + if( pTrans->hConvOwner == hConvServer && + (pTrans->nType & XTYP_ADVREQ) ) + { + if( !nFormat || (nFormat == pTrans->nFormat) ) + { + nTransFound++; + if( bCallApp ) + { + //WRITELOG("SendUnadvises:Notifying App") + Callback( XTYP_ADVSTOP, pTrans->nFormat, hConvServer, + hszTopic, pTrans->hszItem, 0,0,0 ); + } + if( bFree ) + FreeTransaction( pData, (ULONG)nCurTransId ); + } + } + nCurTransId++; + pTrans++; + } + return nTransFound; +} + + + +HCONV ImpDdeMgr::CheckIncoming( ImpWndProcParams* pParams, ULONG nTransMask, + HSZ& rhszItem ) +{ +// ////WRITELOG("CheckIncoming") + rhszItem = 0; + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + if( !pInDDEData ) + { + // ////WRITELOG("CheckIncoming:PDDESTRUCT==0") + return (HCONV)0; + } + + HWND hWndThis = pParams->hWndReceiver; + HWND hWndClient = (HWND)pParams->nPar1; + + BOOL bReject = (BOOL)(nTransactFilter & nTransMask); + HCONV hConv; + if( !bReject ) + hConv = GetConvHandle( pData, hWndThis, hWndClient ); + if ( bReject || !hConv ) + return (HCONV)0; + + rhszItem = DdeCreateStringHandle( + ((char*)(pInDDEData)+pInDDEData->offszItemName), 850 ); + + // ////WRITELOG("CheckIncoming:OK"); + return hConv; +} + + +MRESULT ImpDdeMgr::DdeAdvise( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeAdvise:Received") + HSZ hszItem; + HCONV hConv = CheckIncoming(pParams, CBF_FAIL_ADVISES, hszItem); + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + HWND hWndThis = pParams->hWndReceiver; + HWND hWndClient = (HWND)pParams->nPar1; + if( !hConv ) + { + ////WRITELOG("DdeAdvise:Conversation not found") + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + + Transaction* pTrans = pTransTable; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + + // existiert schon ein Link auf Topic/Item/Format-Vektor ? + + ULONG nTransId=GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); + if( nTransId ) + { + ////WRITELOG("DdeAdvise:Transaction already exists") + pTrans += (USHORT)nTransId; + // ist es eine AdviseLoop ? + USHORT nTempType = pTrans->nType; + nTempType &= (~XTYPF_MASK); + if( nTempType == XTYP_ADVREQ ) + { + // Flags der laufenden Advise-Loop aktualisieren + ////WRITELOG("DdeAdvise:Adjusting Advise-Params") + pTrans->nType = XTYP_ADVREQ; + if( pInDDEData->fsStatus & DDE_FNODATA ) + pTrans->nType |= XTYPF_NODATA; + if( pInDDEData->fsStatus & DDE_FACKREQ ) + pTrans->nType |= XTYPF_ACKREQ; + pInDDEData->fsStatus |= DDE_FACK; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + else if( nTempType != XTYP_ADVSTART ) + { + ////WRITELOG("DdeAdvise:Not a advise transaction") + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + } + + if( !nTransId ) + { + ////WRITELOG("DdeAdvise:Creating Transaction") + ////WRITESTATUS("DdeAdvise:Creating Transaction") + nTransId = CreateTransaction( pData, hConv, hszItem, + pInDDEData->usFormat, XTYP_ADVREQ ); + ////WRITESTATUS("DdeAdvise:Created Transaction") + } + if( nTransId ) + { + pTrans = pTransTable; + pTrans += (USHORT)nTransId; + if( pInDDEData->fsStatus & DDE_FNODATA ) + pTrans->nType |= XTYPF_NODATA; + if( pInDDEData->fsStatus & DDE_FACKREQ ) + pTrans->nType |= XTYPF_ACKREQ; + } + else + { + ////WRITELOG("DdeAdvise:Cannot create Transaction") + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; + } + + ////WRITELOG("DdeAdvise:Calling Server") + + if ( Callback( XTYP_ADVSTART, pInDDEData->usFormat, + hConv, pConv->hszTopic, hszItem, (HDDEDATA)0, 0, 0 ) ) + { + // + // ServerApp erlaubt AdviseLoop + // + ////WRITELOG("DdeAdvise:Advise loop established") + pInDDEData->fsStatus |= DDE_FACK; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + else + { + ////WRITELOG("DdeAdvise:Advise loop not established") + FreeTransaction( pData, nTransId ); + pInDDEData->fsStatus &= (~DDE_FACK); // DDE_FNOTPROCESSED; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + ////WRITESTATUS("DdeAdvise:End") + ////WRITELOG("DdeAdvise:End") + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; +} + +MRESULT ImpDdeMgr::DdeData( ImpWndProcParams* pParams ) +{ + WRITELOG("DdeData:Received") + HSZ hszItem; + HCONV hConv = CheckIncoming(pParams, 0, hszItem); + HWND hWndThis = pParams->hWndReceiver; + HWND hWndClient = (HWND)pParams->nPar1; + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); +#if 0 && defined( OV_DEBUG ) + { + String aStr("DdeData Address:"); + aStr += (ULONG)pInDDEData; + WRITELOG((char*)aStr.GetStr()) + } +#endif + + BOOL bSendAck; + if( pInDDEData && (pInDDEData->fsStatus & DDE_FACKREQ )) + { + WRITELOG("DdeData: Ackn requested") + bSendAck = TRUE; + } + else + { + WRITELOG("DdeData: Ackn not requested") + bSendAck = FALSE; + } + + ULONG nTransId = GetTransaction(pData,hConv,hszItem,pInDDEData->usFormat); + if( !nTransId ) + { + WRITELOG("DdeData:Transaction not found") + WRITEDATA(pInDDEData) + if( bSendAck ) + { + WRITELOG("DdeData: Posting Ackn") + pInDDEData->fsStatus &= (~DDE_FACK); // NOTPROCESSED; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + else + { + MyDosFreeMem( pInDDEData,"DdeData" ); + } + return (MRESULT)0; + } + +#if 0 && defined( OV_DEBUG ) + if( pInDDEData ) + { + WRITEDATA(pInDDEData) + } +#endif + + BOOL bThisIsSync = (BOOL)( bInSyncTrans && nTransId == nSyncTransId ); + + // pruefen, ob die Transaktion abgeschlossen ist. + Transaction* pTrans = pTransTable; + pTrans += (USHORT)nTransId; + + if( pTrans->nConvst == XST_WAITING_ACK ) + { + // dieser Fall kann eintreten, wenn ein Server innerhalb + // einer WM_DDE_ADVISE-Msg. oder bevor beim Client das + // Ack eintrifft, Advise-Daten sendet. + WRITELOG("DdeData:Ignoring unexpected data") + if( bSendAck ) + { + WRITELOG("DdeData: Posting Ackn") + pInDDEData->fsStatus &= (~DDE_FACK); // NOTPROCESSED; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + else + { + MyDosFreeMem( pInDDEData,"DdeData" ); + } + return (MRESULT)0; + } + + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + + USHORT nType = pTrans->nType; + nType &= (~XTYPF_MASK); + BOOL bNotAdviseLoop = (BOOL)(nType != (XTYP_ADVREQ & (~XTYPF_NOBLOCK))); + if( !bThisIsSync ) + { + // WRITELOG("DdeData:Is async transaction") + if( bNotAdviseLoop ) + { + // WRITELOG("DdeData:Transaction completed -> calling client") + Callback( XTYP_XACT_COMPLETE, pInDDEData->usFormat, hConv, + pConv->hszTopic, hszItem, pInDDEData, nTransId, 0 ); + // WRITELOG("DdeData:Freeing transaction") + FreeTransaction( pData, nTransId ); + } + else + { + WRITELOG("DdeData:Advise-Loop -> calling client") + HDDEDATA pToSend = pInDDEData; + if( pTrans->nType & XTYPF_NODATA ) + { + pToSend = 0; + // WRITELOG("DdeData:Is warm link") + } + Callback( XTYP_ADVDATA, pInDDEData->usFormat, hConv, + pConv->hszTopic, hszItem, pToSend, nTransId, 0 ); + } + if( bSendAck ) + { + WRITELOG("DdeData: Posting Ackn") + pInDDEData->fsStatus = DDE_FACK; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + else + MyDosFreeMem( pInDDEData,"DdeData" ); + } + else // synchrone Transaktion (Datenhandle nicht freigeben!) + { + // WRITELOG("DdeData:Is sync transaction") + hSyncResponseData = pInDDEData; + nSyncResponseMsg = WM_DDE_DATA; + if( bSendAck ) + { + pInDDEData->fsStatus |= DDE_FACK; + WRITELOG("DdeData: Posting Ackn") + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData, + DDEPM_RETRY | DDEPM_NOFREE ); + } + } + + DdeFreeStringHandle( hszItem ); + // WRITELOG("DdeData:End") + return (MRESULT)0; +} + +MRESULT ImpDdeMgr::DdeExecute( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeExecute:Received") + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + HSZ hszItem; + HCONV hConv = CheckIncoming(pParams, 0, hszItem); + BOOL bSuccess = FALSE; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + if ( hConv && !(nTransactFilter & CBF_FAIL_EXECUTES) && pInDDEData ) + { + if ( Callback( XTYP_EXECUTE, pInDDEData->usFormat, hConv, + pConv->hszTopic, hszItem, pInDDEData, 0, 0 ) + == (DDESTRUCT*)DDE_FACK ) + bSuccess = TRUE; + } + else + { + ////WRITELOG("DdeExecute:Not processed") + } + if( pInDDEData ) + { + if( bSuccess ) + pInDDEData->fsStatus |= DDE_FACK; + else + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, WM_DDE_ACK, + pInDDEData, DDEPM_RETRY ); + } + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; +} + +HCONV ImpDdeMgr::ConnectWithClient( HWND hWndClient, + HSZ hszPartner, HSZ hszService, HSZ hszTopic, BOOL bSameInst, + DDEINIT* pDDEData, CONVCONTEXT* pCC ) +{ + ////WRITELOG("ConnectWithClient:Start") + HWND hWndSrv = CreateConversationWnd(); + IncConversationWndRefCount( hWndSrv ); + HCONV hConv = CreateConvHandle( pData, pidThis, hWndSrv, hWndClient, + hszPartner, hszService, hszTopic ); + if(!hConv ) + return 0; + BOOL bFreeDdeData = FALSE; + if( !pDDEData ) + { + bFreeDdeData = TRUE; + pDDEData = CreateDDEInitData( hWndClient,hszService,hszTopic, pCC ); + PID pid; TID tid; + WinQueryWindowProcess( hWndClient, &pid, &tid ); + DosGiveSharedMem( pDDEData, pid, PAG_READ | PAG_WRITE); + } + HAB hAB = WinQueryAnchorBlock( hWndSrv ); + WinGetLastError( hAB ); // fehlercode zuruecksetzen + WinSendMsg(hWndClient,WM_DDE_INITIATEACK,(MPARAM)hWndSrv,(MPARAM)pDDEData); + if( WinGetLastError( hAB ) ) + { + // ////WRITELOG("DdeConnectWithClient:Client died") + if( bFreeDdeData ) + { + MyDosFreeMem( pDDEData,"ConnectWithClient" ); + } + FreeConvHandle( pData, hConv ); + return (HCONV)0; + } + + if( !(nTransactFilter & CBF_SKIP_CONNECT_CONFIRMS) ) + { + Callback( XTYP_CONNECT_CONFIRM, 0, hConv, hszTopic, hszService, + 0, 0, (ULONG)bSameInst ); + } + + if( bFreeDdeData ) + { + MyDosFreeMem( pDDEData,"ConnectWithClient" ); + } + // HCONV der PartnerApp suchen & bei uns eintragen + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + pConv->hConvPartner = GetConvHandle( pData, hWndClient, hWndSrv ); +#if 0 && defined(OV_DEBUG) + if( !pConv->hConvPartner ) + { + WRITELOG("DdeConnectWithClient:Partner not found") + } +#endif + pConv->nStatus = ST_CONNECTED; + //WRITESTATUS("Server:Connected with client") + //WRITELOG("ConnectWithClient:End") + return hConv; +} + +MRESULT ImpDdeMgr::DdeInitiate( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeInitiate:Received") + HWND hWndClient = (HWND)(pParams->nPar1); +// BOOL bSameInst = IsSameInstance( hWndClient ); + BOOL bSameInst = (BOOL)(hWndClient==hWndServer); + DDEINIT* pDDEData = (DDEINIT*)pParams->nPar2; + + if ( ( nTransactFilter & (CBF_FAIL_CONNECTIONS | APPCMD_CLIENTONLY)) || + (( nTransactFilter & CBF_FAIL_SELFCONNECTIONS) && bSameInst ) + ) + { + MyDosFreeMem( pDDEData,"DdeInitiate" ); + return (MRESULT)FALSE; // narda + } + + HSZ hszService = (HSZ)0; + if( *(pDDEData->pszAppName) != '\0' ) + { + hszService = DdeCreateStringHandle( pDDEData->pszAppName, 850 ); + ////WRITELOG(pDDEData->pszAppName); + } + HSZ hszTopic = (HSZ)0; + if( *(pDDEData->pszTopic) != '\0' ) + { + hszTopic = DdeCreateStringHandle( pDDEData->pszTopic, 850 ); + ////WRITELOG(pDDEData->pszTopic); + } + HSZ hszPartner = GetAppName( hWndClient ); + + // nur weitermachen, wenn Service registriert oder + // Service-Name-Filtering ausgeschaltet. + if( !bServFilterOn || GetService(hszService) ) + { + // XTYP_CONNECT-Transaktionen erfolgen nur mit + // Services & Topics ungleich 0! + if( hszService && hszTopic ) + { + if( IsConvHandleAvailable(pData) && Callback( XTYP_CONNECT, + 0, 0, hszTopic,hszService, 0, 0, (ULONG)bSameInst)) + { + // App erlaubt Verbindung mit Client + ConnectWithClient( hWndClient, hszPartner, + hszService, hszTopic, bSameInst, pDDEData ); + } + } + else + { + // ** Wildcard-Connect ** + ////WRITELOG("DdeInitiate:Wildconnect") + // vom Server eine Liste aller Service/Topic-Paare anfordern + CONVCONTEXT* pCC=(CONVCONTEXT*)(pDDEData+pDDEData->offConvContext); + DDESTRUCT* hList = Callback( XTYP_WILDCONNECT, 0, (HCONV)0, + hszTopic,hszService, (HDDEDATA)0, (ULONG)pCC, (ULONG)bSameInst ); + if( hList ) + { + HSZPAIR* pPairs = (HSZPAIR*)((char*)hList+hList->offabData); + while( pPairs->hszSvc ) + { + ////WRITELOG("DdeInitiate:Wildconnect.Connecting") + ConnectWithClient( hWndClient, hszPartner, + pPairs->hszSvc, pPairs->hszTopic, bSameInst, 0, pCC); + // Stringhandles gehoeren der App! (nicht free-en) + pPairs++; + } + DdeFreeDataHandle( hList ); + } + } + } +#if 0 && defined(OV_DEBUG) + else + { + WRITELOG("DdeInitiate:Service filtered") + } +#endif + DdeFreeStringHandle( hszTopic ); + DdeFreeStringHandle( hszService ); + DdeFreeStringHandle( hszPartner ); + MyDosFreeMem( pDDEData,"DdeInitiate" ); + ////WRITELOG("DdeInitiate:End") + return (MRESULT)TRUE; +} + +MRESULT ImpDdeMgr::DdeInitiateAck( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeInitiateAck:Received") + DDEINIT* pDDEData = (DDEINIT*)(pParams->nPar2); + + if( !bListConnect && hCurConv ) + { + ////WRITELOG("DdeInitiateAck:Already connected") + MyDosFreeMem( pDDEData,"DdeInitiateAck" ); + WinPostMsg( hWndServer, WM_DDE_TERMINATE, (MPARAM)hWndServer, 0 ); + return (MRESULT)FALSE; + } + + HWND hWndThis = pParams->hWndReceiver; + // Referenz-Count unseres Client-Windows inkrementieren + IncConversationWndRefCount( hWndThis ); + + HWND hWndSrv = (HWND)(pParams->nPar1); + HSZ hszService = DdeCreateStringHandle( pDDEData->pszAppName, 850 ); + HSZ hszTopic = DdeCreateStringHandle( pDDEData->pszTopic, 850 ); + HSZ hszPartnerApp = GetAppName( hWndSrv ); + + hCurConv = CreateConvHandle( pData, pidThis, hWndThis, hWndSrv, + hszPartnerApp, hszService, hszTopic, 0 ); + + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hCurConv; + + // HCONV der PartnerApp suchen & bei uns eintragen + pConv->hConvPartner = GetConvHandle( pData, hWndSrv, hWndThis ); + // nicht asserten, da ja non-ddeml-Partner moeglich + // DBG_ASSERT(pConv->hConvPartner,"DDE:Partner not found"); + pConv->nStatus = ST_CONNECTED | ST_CLIENT; + + if( bListConnect ) + { + ////WRITELOG("DdeInitiateAck:ListConnect/Connecting hConvs") + // Status setzen & verketten + pConv->hConvList = hCurListId; + pConv->nPrevHCONV = nPrevConv; + pConv->nStatus |= ST_INLIST; + if( nPrevConv ) + { + pConv = pConvTable; + pConv += nPrevConv; + pConv->nNextHCONV = (USHORT)hCurConv; + } + nPrevConv = (USHORT)hCurConv; + } + + DdeFreeStringHandle( hszService ); + DdeFreeStringHandle( hszTopic ); + DdeFreeStringHandle( hszPartnerApp ); + MyDosFreeMem( pDDEData,"DdeInitiateAck" ); + ////WRITESTATUS("After DdeInitiateAck") + ////WRITELOG("DdeInitiateAck:End") + return (MRESULT)TRUE; +} + +MRESULT ImpDdeMgr::DdePoke( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdePoke:Received") + HSZ hszItem = 0; + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + HCONV hConv = CheckIncoming( pParams, CBF_FAIL_REQUESTS, hszItem ); + BOOL bSuccess =FALSE; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + if ( hConv && !(nTransactFilter & CBF_FAIL_POKES) && pInDDEData ) + { + if( Callback( XTYP_POKE, pInDDEData->usFormat, hConv, + pConv->hszTopic, hszItem, pInDDEData, 0, 0 ) + == (DDESTRUCT*)DDE_FACK ) + bSuccess = TRUE; + } +#if 0 && defined( OV_DEBUG ) + else + { + WRITELOG("DdePoke:Not processed") + } +#endif + if( pInDDEData ) + { + if( bSuccess ) + pInDDEData->fsStatus |= DDE_FACK; + else + pInDDEData->fsStatus &= (~DDE_FACK); + + MyWinDdePostMsg( pConv->hWndPartner, pConv->hWndThis, WM_DDE_ACK, + pInDDEData, DDEPM_RETRY ); + } + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; +} + +MRESULT ImpDdeMgr::DdeRequest( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeRequest:Received") + HSZ hszItem = 0; + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + if( pInDDEData ) + // ist fuer Requests nicht definiert + pInDDEData->fsStatus = 0; + HCONV hConv = CheckIncoming( pParams, CBF_FAIL_REQUESTS, hszItem ); + HWND hWndThis = pParams->hWndReceiver; + HWND hWndClient = (HWND)pParams->nPar1; + if( hConv ) + { + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + + DDESTRUCT* pOutDDEData = Callback( XTYP_REQUEST, pInDDEData->usFormat, + hConv, pConv->hszTopic, hszItem, (HDDEDATA)0, 0, 0 ); + + if ( !pOutDDEData ) + { + ////WRITELOG("DdeRequest:Not processed") + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + else + { + ////WRITELOG("DdeRequest:Success") + MyDosFreeMem( pInDDEData,"DdeRequest" ); + pOutDDEData->fsStatus |= DDE_FRESPONSE; + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_DATA,pOutDDEData,DDEPM_RETRY); + } + } + else + { + pInDDEData->fsStatus &= (~DDE_FACK); + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + } + + DdeFreeStringHandle( hszItem ); + ////WRITELOG("DdeRequest:End") + return (MRESULT)0; +} + + +MRESULT ImpDdeMgr::DdeUnadvise( ImpWndProcParams* pParams ) +{ + ////WRITELOG("DdeUnadvise:Received") + + HSZ hszItem; + HCONV hConv = CheckIncoming( pParams, 0, hszItem ); + DDESTRUCT* pInDDEData = (DDESTRUCT*)(pParams->nPar2); + HWND hWndThis = pParams->hWndReceiver; + HWND hWndClient = (HWND)pParams->nPar1; + USHORT nClosedTransactions = 0; + if( hConv ) + { + USHORT nFormat = pInDDEData->usFormat; + // alle Transaktionen des HCONVs loeschen ? + if( !hszItem ) + { + // App benachrichtigen & Transaktionen loeschen + nClosedTransactions = SendUnadvises( hConv, nFormat, TRUE ); + } + else + { + ULONG nTransId = GetTransaction(pData, hConv, hszItem, nFormat); + if( nTransId ) + { + ////WRITELOG("DdeUnadvise:Transaction found") + Transaction* pTrans = pTransTable; + pTrans += (USHORT)nTransId; + ImpHCONV* pConv = pConvTable; + pConv += (USHORT)hConv; + nClosedTransactions = 1; + if( !(nTransactFilter & CBF_FAIL_ADVISES) ) + Callback( XTYP_ADVSTOP, nFormat, hConv, + pConv->hszTopic, hszItem, 0, 0, 0 ); + if( !pConv->hConvPartner ) + FreeTransaction( pData, nTransId ); + } +#if defined(OV_DEBUG) + else + { + WRITELOG("DdeUnadvise:Transaction not found") + } +#endif + } + } +#if defined(OV_DEBUG) + else + { + WRITELOG("DdeUnadvise:Conversation not found") + } +#endif + + if( !nClosedTransactions ) + pInDDEData->fsStatus &= (~DDE_FACK); + else + pInDDEData->fsStatus |= DDE_FACK; + + MyWinDdePostMsg(hWndClient,hWndThis,WM_DDE_ACK,pInDDEData,DDEPM_RETRY); + DdeFreeStringHandle( hszItem ); + return (MRESULT)0; +} + +BOOL ImpDdeMgr::WaitTransState( Transaction* pTrans, ULONG nTransId, + USHORT nNewState, ULONG nTimeout ) +{ + ////WRITELOG("WaitTransState:Start") + ImpHCONV* pConv = pConvTable; + pConv += pTrans->hConvOwner; + HAB hAB = WinQueryAnchorBlock( pConv->hWndThis ); + ULONG nTimerId = WinStartTimer( hAB, 0, 0, 50 ); + QMSG aQueueMsg; + +// while( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 ) && +// WinIsWindow( hAB, pConv->hWndPartner) && +// pTrans->nConvst != nNewState ) +// { +// WinDispatchMsg( hAB, &aQueueMsg ); +// } + + BOOL bContinue = TRUE; + while( bContinue ) + { + if( WinGetMsg( hAB, &aQueueMsg, 0, 0, 0 )) + { + WinDispatchMsg( hAB, &aQueueMsg ); + if( (!WinIsWindow( hAB, pConv->hWndPartner)) || + (pTrans->nConvst == nNewState) ) + { + bContinue = FALSE; + } + } + else + bContinue = FALSE; + } + + WinStopTimer( hAB, 0, nTimerId ); + ////WRITELOG("WaitTransState:End") + return TRUE; +} + + + + diff --git a/svl/source/svdde/ddeml2.cxx b/svl/source/svdde/ddeml2.cxx new file mode 100644 index 000000000000..e0cdee2d52d1 --- /dev/null +++ b/svl/source/svdde/ddeml2.cxx @@ -0,0 +1,1014 @@ +/************************************************************************* + * + * 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: ddeml2.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define INCL_DOS +#include <stdlib.h> + +#include "ddemlimp.hxx" +#define LOGFILE +#define STATUSFILE +#define DDEDATAFILE +#include "ddemldeb.hxx" + +#if defined (OS2) && defined (__BORLANDC__) +#pragma option -w-par +#endif + + +// ************************************************************************ +// Hilfsfunktionen Speicherverwaltung +// ************************************************************************ + +// +// AllocAtomName +// + +PSZ ImpDdeMgr::AllocAtomName( ATOM hString, ULONG& rBufLen ) +{ + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); + ULONG nLen = WinQueryAtomLength( hAtomTable, hString ); + nLen++; + PSZ pBuf = 0; + if ( !MyDosAllocMem( (PPVOID)&pBuf, nLen, PAG_READ|PAG_WRITE|PAG_COMMIT | OBJ_ANY,"Atom" ) ) + { + WinQueryAtomName( hAtomTable, hString, pBuf, nLen ); + rBufLen = nLen; + } + return pBuf; +} + + +// +// MakeDDEObject +// + +PDDESTRUCT ImpDdeMgr::MakeDDEObject( HWND hwnd, ATOM hItemName, + USHORT fsStatus, USHORT usFormat, PVOID pabData, ULONG usDataLen ) +{ + PDDESTRUCT pddes = 0; + ULONG usItemLen; + PULONG pulSharedObj; + //WRITELOG("MakeDDEObject: Start") + + PSZ pItemName = 0; + if( hItemName != NULL ) + pItemName = AllocAtomName( hItemName, usItemLen ); + else + usItemLen = 1; + + ULONG nTotalSize = sizeof(DDESTRUCT) + usItemLen + usDataLen; + + if( !(MyDosAllocSharedMem((PPVOID)&pulSharedObj, NULL, + nTotalSize, + PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GETTABLE | OBJ_GIVEABLE | OBJ_ANY, + "MakeDDEObject"))) + { + pddes = (PDDESTRUCT) pulSharedObj; + // siehe "Glenn Puchtel, DDE for OS/2" p.60 + pddes->cbData = (ULONG)usDataLen; + pddes->fsStatus = fsStatus; + pddes->usFormat = usFormat; + pddes->offszItemName = sizeof( DDESTRUCT ); + if( (usDataLen) && (pabData != NULL ) ) + pddes->offabData = sizeof(DDESTRUCT) + usItemLen; + else + pddes->offabData = 0; + + if( pItemName != NULL ) + memcpy(DDES_PSZITEMNAME(pddes), pItemName, usItemLen ); + else + *(DDES_PSZITEMNAME(pddes)) = '\0'; + + if( pabData != NULL ) + memcpy( DDES_PABDATA(pddes), pabData, usDataLen ); + } + + if ( pItemName ) + { + MyDosFreeMem( pItemName,"MakeDDEObject" ); + } + return pddes; +} + +// +// AllocNamedSharedMem +// + +APIRET ImpDdeMgr::AllocNamedSharedMem( PPVOID ppBaseAddress, PSZ pName, + ULONG nElementSize, ULONG nElementCount ) +{ + ULONG nObjSize = (ULONG)(nElementSize * nElementCount ); + nObjSize += sizeof( ULONG ); // fuer ElementCount am Anfang des Blocks + + *ppBaseAddress = 0; + APIRET nRet = MyDosAllocSharedMem( ppBaseAddress, pName, nObjSize, + PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY, + "AllocNamedSharedMem" ); + if ( !nRet ) + { + memset( *ppBaseAddress, 0, nObjSize ); + ULONG* pULONG = (ULONG*)*ppBaseAddress; + *pULONG = nObjSize; + } + return nRet; +} + +void ImpDdeMgr::CreateServerWnd() +{ + hWndServer = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "DDEServer", 0, + 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 ); + WinSetWindowULong( hWndServer, 0, (ULONG)this ); + WinSubclassWindow( hWndServer, ::ServerWndProc ); + TID tidDummy; + WinQueryWindowProcess( hWndServer, &pidThis, &tidDummy ); +} + +void ImpDdeMgr::DestroyServerWnd() +{ + WinDestroyWindow( hWndServer ); + hWndServer = NULLHANDLE; +} + +HWND ImpDdeMgr::CreateConversationWnd() +{ + HWND hWnd = WinCreateWindow( HWND_OBJECT, WC_FRAME, "DDEConvWnd", 0, + 0,0,0,0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 ); + if ( hWnd ) + { + ImpConvWndData* pWndData = new ImpConvWndData; + pWndData->pThis = this; + pWndData->nRefCount = 0; + WinSetWindowULong( hWnd, 0, (ULONG)pWndData ); + WinSubclassWindow( hWnd, ::ConvWndProc ); +#if 0 && defined( OV_DEBUG ) + String aStr("ConvWnd created:"); + aStr += (ULONG)hWnd; + WRITELOG((char*)aStr.GetStr()) +#endif + } + else + nLastErrInstance = DMLERR_SYS_ERROR; + + return hWnd; +} + +// static +void ImpDdeMgr::DestroyConversationWnd( HWND hWnd ) +{ + ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 ); + if( pObj ) + { + pObj->nRefCount--; + if( pObj->nRefCount == 0 + // auch Windows mit Refcount vonm loeschen, da dieser in initial + // auf 0 gesetzt wird + || pObj->nRefCount == (USHORT)-1 ) + { + delete pObj; + WinDestroyWindow( hWnd ); +#if 0 && defined( OV_DEBUG ) + String aStr("ConvWnd destroyed:"); + aStr += (ULONG)hWnd; + WRITELOG((char*)aStr.GetStr()) +#endif + } + else + { +#if 0 && defined( OV_DEBUG ) + String aStr("ConvWnd not destroyed (Refcount="); + aStr += pObj->nRefCount; + aStr += ") "; aStr += (ULONG)hWnd; + WRITELOG((char*)aStr.GetStr()) +#endif + } + } +#if defined( OV_DEBUG ) + else + { + WRITELOG("DestroyCnvWnd:Already destroyed/No win data/Partner died") + } +#endif +} + +// static +USHORT ImpDdeMgr::GetConversationWndRefCount( HWND hWnd ) +{ + ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 ); + DBG_ASSERT(pObj,"Dde:ConvWnd has no data"); + if( pObj ) + return pObj->nRefCount; + return 0; +} + +// static +USHORT ImpDdeMgr::IncConversationWndRefCount( HWND hWnd ) +{ +#if 0 && defined( OV_DEBUG ) + String aStr("IncConversationWndRefCount "); + aStr += (ULONG)hWnd; + WRITELOG((char*)aStr.GetStr()) +#endif + ImpConvWndData* pObj = (ImpConvWndData*)WinQueryWindowULong( hWnd, 0 ); + DBG_ASSERT(pObj,"Dde:ConvWnd has no data"); + if( pObj ) + { + pObj->nRefCount++; + return pObj->nRefCount; + } + return 0; +} + +ImpDdeMgrData* ImpDdeMgr::InitAll() +{ + ImpDdeMgrData* pBase = 0; + // nur dann neu anlegen, wenn die Tabelle nicht existiert + APIRET nRet=DosGetNamedSharedMem((PPVOID)&pBase,DDEMLDATA,PAG_READ| PAG_WRITE); + if ( nRet ) + { + if ( nRet == 2 ) // ERROR_FILE_NOT_FOUND ) + { + // DDECONVERSATIONCOUNT=4096 + USHORT nConvTransCount = 128; + PSZ pResult; + nRet = DosScanEnv( "SOMAXDDECONN", (const char**)&pResult ); + if( !nRet ) + { + int nTemp = 0; + nTemp = atoi( pResult ); + nTemp++; // der nullte Eintrag wird nicht benutzt + if( nTemp > 128 ) + nConvTransCount = (USHORT)nTemp; + } + ULONG nSize = sizeof(ImpDdeMgrData); + nSize += sizeof(ImpHCONV) * nConvTransCount; + nSize += sizeof(Transaction) * nConvTransCount; + nSize += sizeof(HWND) * DDEMLAPPCOUNT; + + nRet = ImpDdeMgr::AllocNamedSharedMem( (PPVOID)&pBase, + DDEMLDATA, nSize, 1 ); + if ( !nRet ) + { + pBase->nTotalSize = nSize; + ULONG nAppTable = (ULONG)&(pBase->aAppTable); + ULONG nCharBase = (ULONG)pBase; + pBase->nOffsAppTable = nAppTable - nCharBase; + pBase->nOffsConvTable = pBase->nOffsAppTable; + pBase->nOffsConvTable += sizeof(HWND) * DDEMLAPPCOUNT; + pBase->nOffsTransTable = pBase->nOffsConvTable; + pBase->nOffsTransTable += sizeof(ImpHCONV) * nConvTransCount; + + pBase->nMaxAppCount = DDEMLAPPCOUNT; + pBase->nMaxConvCount = nConvTransCount; + pBase->nMaxTransCount = nConvTransCount; + } + } + } + + if( pBase ) + { + pConvTable = ImpDdeMgr::GetConvTable( pBase ); + pTransTable = ImpDdeMgr::GetTransTable( pBase ); + pAppTable = ImpDdeMgr::GetAppTable( pBase ); + } + + memset( &aDefaultContext, 0, sizeof(CONVCONTEXT) ); + aDefaultContext.cb = sizeof(CONVCONTEXT); + aDefaultContext.idCountry = 49; // ?? + aDefaultContext.usCodepage = 850; // ?? + + return pBase; +} + +// static +HCONV ImpDdeMgr::CreateConvHandle( ImpDdeMgrData* pData, + PID pidOwner, + HWND hWndMe, HWND hWndPartner, + HSZ hszPartner, HSZ hszServiceReq, HSZ hszTopic, + HCONV hPrevHCONV ) +{ + DBG_ASSERT(pData,"DDE:Invalid data"); + if( !pData ) + return (HCONV)0; + + ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pData ); + USHORT nCount = pData->nMaxConvCount; + pPtr++; + nCount--; // ersten Handle (NULLHANDLE) ueberspringen + USHORT nIdx = 1; + DBG_ASSERT(pPtr,"No ConvTable"); + if( !pPtr ) + return (HCONV)0; + + while( nCount && pPtr->hWndThis != (HWND)NULL ) + { + nCount--; + pPtr++; + nIdx++; + } + if( !nCount ) + return (HCONV)0; + + DdeKeepStringHandle( hszPartner ); + DdeKeepStringHandle( hszServiceReq ); + DdeKeepStringHandle( hszTopic ); + pPtr->hszPartner = hszPartner; + pPtr->hszServiceReq = hszServiceReq; + pPtr->hszTopic = hszTopic; + + pPtr->hWndThis = hWndMe; + pPtr->hWndPartner = hWndPartner; + pPtr->pidOwner = pidOwner; + pPtr->hConvPartner = (HCONV)0; + pPtr->nPrevHCONV = (USHORT)hPrevHCONV; + pPtr->nNextHCONV = 0; + pPtr->nStatus = ST_CONNECTED; + + pData->nCurConvCount++; + + return (HCONV)nIdx; +} + +// static +void ImpDdeMgr::FreeConvHandle( ImpDdeMgrData* pBase, HCONV hConv, + BOOL bDestroyHWndThis ) +{ + DBG_ASSERT(pBase,"DDE:No data"); +#if 0 && defined( OV_DEBUG ) + String aStr("FreeConvHandle: Start "); + aStr += (ULONG)hConv; + aStr += " Destroy: "; aStr += (USHORT)bDestroyHWndThis; + WRITELOG((char*)aStr.GetStr()); + WRITESTATUS("FreeConvHandle: Start"); +#endif + if( !pBase ) + { + WRITELOG("FreeConvHandle: FAIL"); + return; + } + DBG_ASSERT(hConv&&hConv<pBase->nMaxConvCount,"DDE:Invalid Conv-Handle"); + if( hConv && hConv < pBase->nMaxConvCount ) + { + ImpHCONV* pTable = ImpDdeMgr::GetConvTable( pBase ); + ImpHCONV* pPtr = pTable + (USHORT)hConv; + if( pPtr->nStatus & ST_INLIST ) + { + // Verkettung umsetzen + USHORT nPrev = pPtr->nPrevHCONV; + USHORT nNext = pPtr->nNextHCONV; + if( nPrev ) + { + pPtr = pTable + nPrev; + pPtr->nNextHCONV = nNext; + } + if( nNext ) + { + pPtr = pTable + nNext; + pPtr->nPrevHCONV = nPrev; + } + pPtr = pTable + (USHORT)hConv; + } + + DdeFreeStringHandle( pPtr->hszPartner ); + DdeFreeStringHandle( pPtr->hszServiceReq ); + DdeFreeStringHandle( pPtr->hszTopic ); + if( bDestroyHWndThis ) + DestroyConversationWnd( pPtr->hWndThis ); + memset( pPtr, 0, sizeof(ImpHCONV) ); + DBG_ASSERT(pBase->nCurConvCount,"Dde:Invalid Trans. count"); + pBase->nCurConvCount--; + } +#if defined(OV_DEBUG) + else + { + WRITELOG("FreeConvHandle: FAIL"); + } +#endif + //WRITELOG("FreeConvHandle: END"); + //WRITESTATUS("FreeConvHandle: End"); +} + +// static +HCONV ImpDdeMgr::IsConvHandleAvailable( ImpDdeMgrData* pBase ) +{ + DBG_ASSERT(pBase,"DDE:No data"); + if( !pBase ) + return 0; + + ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pBase ); + USHORT nCurPos = pBase->nMaxConvCount - 1; + pPtr += nCurPos; // von hinten aufrollen + while( nCurPos >= 1 ) + { + if( pPtr->hWndThis == 0 ) + return TRUE; + pPtr--; + nCurPos--; + } + return FALSE; +} + +// static +HCONV ImpDdeMgr::GetConvHandle( ImpDdeMgrData* pBase, HWND hWndThis, + HWND hWndPartner ) +{ + DBG_ASSERT(pBase,"DDE:No data"); + if( !pBase ) + return 0; + ImpHCONV* pPtr = ImpDdeMgr::GetConvTable( pBase ); + USHORT nCurPos = 1; + pPtr++; // ersten Handle ueberspringen + USHORT nCurConvCount = pBase->nCurConvCount; + while( nCurConvCount && nCurPos < pBase->nMaxConvCount ) + { + if( pPtr->hWndThis ) + { + if(pPtr->hWndThis == hWndThis && pPtr->hWndPartner == hWndPartner) + return (HCONV)nCurPos; + nCurConvCount--; + if( !nCurConvCount ) + return (HCONV)0; + } + nCurPos++; + pPtr++; + } + return (HCONV)0; +} + + + +// static +ULONG ImpDdeMgr::CreateTransaction( ImpDdeMgrData* pBase, HCONV hOwner, + HSZ hszItem, USHORT nFormat, USHORT nTransactionType ) +{ + DBG_ASSERT(pBase,"DDE:No Data"); + DBG_ASSERT(hOwner!=0,"DDE:No Owner"); + + if( pBase && hOwner ) + { + Transaction* pPtr = ImpDdeMgr::GetTransTable( pBase ); + DBG_ASSERT(pPtr->hConvOwner==0,"DDE:Data corrupted"); + USHORT nId = 1; + pPtr++; + while( nId < pBase->nMaxTransCount ) + { + if( pPtr->hConvOwner == (HCONV)0 ) + { + pPtr->hConvOwner = hOwner; + DdeKeepStringHandle( hszItem ); + pPtr->hszItem = hszItem; + pPtr->nType = nTransactionType; + pPtr->nConvst = XST_CONNECTED; + pPtr->nFormat = nFormat; + pBase->nCurTransCount++; + return (ULONG)nId; + } + nId++; + pPtr++; + } + } + return 0; +} + +// static +void ImpDdeMgr::FreeTransaction( ImpDdeMgrData* pBase, ULONG nTransId ) +{ + DBG_ASSERT(pBase,"DDE:No Data"); + if( !pBase ) + return; + + DBG_ASSERT(nTransId<pBase->nMaxTransCount,"DDE:Invalid TransactionId"); + if( nTransId >= pBase->nMaxTransCount ) + return; + + Transaction* pPtr = ImpDdeMgr::GetTransTable( pBase ); + pPtr += nTransId; + DBG_ASSERT(pPtr->hConvOwner!=0,"DDE:TransId has no owner"); + if( pPtr->hConvOwner ) + { + //WRITELOG("Freeing transaction"); + DdeFreeStringHandle( pPtr->hszItem ); + memset( pPtr, 0, sizeof(Transaction) ); + DBG_ASSERT(pBase->nCurTransCount,"Dde:Invalid Trans. count"); + pBase->nCurTransCount--; + } +} + +// static +ULONG ImpDdeMgr::GetTransaction( ImpDdeMgrData* pBase, + HCONV hOwner, HSZ hszItem, USHORT nFormat ) +{ + DBG_ASSERT(pBase,"DDE:No Data"); + if( !pBase || !hOwner ) + return 0; + + Transaction* pTrans = ImpDdeMgr::GetTransTable( pBase ); + DBG_ASSERT(pTrans,"DDE:No TransactionTable"); + if( !pTrans ) + return 0; + pTrans++; // NULLHANDLE ueberspringen + + ImpHCONV* pConv = ImpDdeMgr::GetConvTable( pBase ); + pConv += (USHORT)hOwner; + HCONV hConvPartner = pConv->hConvPartner; + + USHORT nCurTransCount = pBase->nCurTransCount; + for( USHORT nTrans=1; nTrans< pBase->nMaxTransCount; nTrans++, pTrans++ ) + { + if( pTrans->hConvOwner ) + { + if(( pTrans->hConvOwner == hOwner || + pTrans->hConvOwner == hConvPartner) && + pTrans->nFormat == nFormat && + pTrans->hszItem == hszItem ) + { + // gefunden! + return (ULONG)nTrans; + } + nCurTransCount--; + if( !nCurTransCount ) + return 0; + } + } + return 0; // narda +} + +// static +HSZ ImpDdeMgr::DdeCreateStringHandle( PSZ pszString, int iCodePage) +{ + if( !pszString || *pszString == '\0' ) + return (HSZ)0; + // Atom-Table beachtet Gross/Kleinschreibung, DDEML aber nicht + + // OV 12.4.96: Services,Topics,Items case-sensitiv!!! + // (Grosskundenanforderung (Reuter-DDE)) + //strlwr( pszString ); + //*pszString = (char)toupper(*pszString); + + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); + ATOM aAtom = WinAddAtom( hAtomTable, pszString ); + return (HSZ)aAtom; +} + +// static +ULONG ImpDdeMgr::DdeQueryString( HSZ hszStr, PSZ pszStr, ULONG cchMax, int iCodePage) +{ + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); + if ( !pszStr ) + return WinQueryAtomLength( hAtomTable, (ATOM)hszStr); + else + { + *pszStr = 0; + return WinQueryAtomName( hAtomTable, (ATOM)hszStr, pszStr, cchMax ); + } +} + +// static +BOOL ImpDdeMgr::DdeFreeStringHandle( HSZ hsz ) +{ + if( !hsz ) + return FALSE; + ATOM aResult = WinDeleteAtom( WinQuerySystemAtomTable(),(ATOM)hsz ); + return (BOOL)(aResult==0); +} + +// static +BOOL ImpDdeMgr::DdeKeepStringHandle( HSZ hsz ) +{ + if( !hsz ) + return TRUE; + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); +#ifdef DBG_UTIL + ULONG nUsageCount=WinQueryAtomUsage(hAtomTable,(ATOM)hsz); +#endif + ULONG nAtom = 0xFFFF0000; + ULONG nPar = (ULONG)hsz; + nAtom |= nPar; + ATOM aAtom = WinAddAtom( hAtomTable, (PSZ)nAtom ); +#ifdef DBG_UTIL + if ( aAtom ) + DBG_ASSERT(WinQueryAtomUsage(hAtomTable,(ATOM)hsz)==nUsageCount+1,"Keep failed"); +#endif + return (BOOL)(aAtom!=0); +} + + +// static +int ImpDdeMgr::DdeCmpStringHandles(HSZ hsz1, HSZ hsz2) +{ + if ( hsz1 == hsz2 ) + return 0; + if ( hsz1 < hsz2 ) + return -1; + return 1; +} + +HDDEDATA ImpDdeMgr::DdeCreateDataHandle( void* pSrc, ULONG cb, + ULONG cbOff, HSZ hszItem, USHORT wFmt, USHORT afCmd) +{ + char* pData = (char*)pSrc; + pData += cbOff; + USHORT nStatus; + if( afCmd & HDATA_APPOWNED ) + nStatus = IMP_HDATAAPPOWNED; + else + nStatus = 0; + PDDESTRUCT hData=MakeDDEObject(0,(ATOM)hszItem,nStatus,wFmt,pData,cb); +// WRITEDATA(hData) + if ( !hData ) + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + return (HDDEDATA)hData; +} + +// static +BYTE* ImpDdeMgr::DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize) +{ + BYTE* pRet = 0; + *pcbDataSize = 0; + if ( hData ) + { + pRet = (BYTE*)hData; + pRet += hData->offabData; + ULONG nLen = hData->cbData; + // nLen -= hData->offabData; + *pcbDataSize = nLen; + } + else + ImpDdeMgr::nLastErrInstance = DMLERR_INVALIDPARAMETER; + return pRet; +} + +// static +BOOL ImpDdeMgr::DdeUnaccessData(HDDEDATA hData) +{ + return TRUE; // nothing to do for us +} + +// static +BOOL ImpDdeMgr::DdeFreeDataHandle(HDDEDATA hData) +{ + DdeUnaccessData( hData ); + MyDosFreeMem( (PSZ)hData, "DdeFreeDataHandle" ); + return TRUE; +} + +// static +HDDEDATA ImpDdeMgr::DdeAddData(HDDEDATA hData,void* pSrc,ULONG cb,ULONG cbOff) +{ + return (HDDEDATA)0; +} + +// static +ULONG ImpDdeMgr::DdeGetData(HDDEDATA hData,void* pDst,ULONG cbMax,ULONG cbOff) +{ + return 0; +} + +BOOL ImpDdeMgr::DisconnectAll() +{ + //WRITESTATUS("Before DisconnectAll()") + USHORT nCurConvCount = pData->nCurConvCount; + if( !nCurConvCount ) + return TRUE; + + BOOL bRet = TRUE; + ImpHCONV* pPtr = pConvTable; + pPtr++; + + for( USHORT nPos=1; nPos < pData->nMaxConvCount; nPos++, pPtr++ ) + { + if( pPtr->hWndThis ) + { + if( !DdeDisconnect( (HCONV)nPos ) ) + bRet = FALSE; + nCurConvCount--; + if( !nCurConvCount ) + break; + } + } + //WRITESTATUS("After DisconnectAll()") + return bRet; +} + +// static +void ImpDdeMgr::FreeTransactions( ImpDdeMgrData* pData,HWND hWndThis, + HWND hWndPartner ) +{ + USHORT nCurTransCount = pData->nCurTransCount; + if( !nCurTransCount ) + return; + + Transaction* pTrans = GetTransTable( pData ); + ImpHCONV* pConvTable = GetConvTable( pData ); + pTrans++; + for( USHORT nPos=1; nPos < pData->nMaxTransCount; nPos++, pTrans++ ) + { + if( pTrans->hConvOwner ) + { + ImpHCONV* pConv = pConvTable + (USHORT)(pTrans->hConvOwner); + if((pConv->hWndThis==hWndThis&& pConv->hWndPartner==hWndPartner)|| + (pConv->hWndThis==hWndPartner && pConv->hWndPartner==hWndThis)) + { + FreeTransaction( pData, (ULONG)nPos ); + } + nCurTransCount--; + if( !nCurTransCount ) + return; + } + } +} + +// static +void ImpDdeMgr::FreeTransactions( ImpDdeMgrData* pData, HCONV hConvOwner ) +{ + USHORT nCurTransCount = pData->nCurTransCount; + if( !nCurTransCount ) + return; + + Transaction* pTrans = GetTransTable( pData ); +// ImpHCONV* pConvTable = GetConvTable( pData ); + pTrans++; + for( USHORT nPos=1; nPos < pData->nMaxTransCount; nPos++, pTrans++ ) + { + if( pTrans->hConvOwner == hConvOwner ) + { + FreeTransaction( pData, (ULONG)nPos ); + nCurTransCount--; + if( !nCurTransCount ) + return; + } + } +} + +// static +void ImpDdeMgr::FreeConversations( ImpDdeMgrData* pData, HWND hWndThis, + HWND hWndPartner ) +{ + USHORT nCurCount = pData->nCurConvCount; + if( !nCurCount ) + return; + + ImpHCONV* pPtr = GetConvTable( pData ); + pPtr++; + for( USHORT nPos=1; nPos < pData->nMaxConvCount; nPos++, pPtr++ ) + { + if( pPtr->hWndThis ) + { + if( hWndThis && pPtr->hWndPartner==hWndPartner ) + FreeConvHandle( pData, (HCONV)nPos ); + nCurCount--; + if( !nCurCount ) + return; + } + } +} + + +BOOL ImpDdeMgr::OwnsConversationHandles() +{ + //WRITESTATUS("OwnsConversationHandles()"); +#if 0 && defined( OV_DEBUG ) + String aStr("OwnsConversationHandles Server:"); + aStr += (ULONG)hWndServer; + WRITELOG((char*)aStr.GetStr()) +#endif + ImpHCONV* pPtr = GetConvTable( pData ); + for( USHORT nCur = 1; nCur < pData->nMaxConvCount; nCur++, pPtr++ ) + { + if( pPtr->hWndThis && pPtr->pidOwner == pidThis ) + { + //WRITELOG("OwnsConversationHandles: TRUE"); + return TRUE; + } + } + // WRITELOG("OwnsConversationHandles: FALSE"); + return FALSE; +} + + + +// ********************************************************************* +// ********************************************************************* +// ********************************************************************* + +USHORT DdeInitialize(ULONG* pidInst, PFNCALLBACK pfnCallback, + ULONG afCmd, ULONG ulRes) +{ + if( (*pidInst)!=0 ) + { + // Reinitialize wird noch nicht unterstuetzt + DBG_ASSERT(0,"DDEML:Reinitialize not supported"); + return DMLERR_INVALIDPARAMETER; + } + + ImpDdeMgr* pMgr = new ImpDdeMgr; + *pidInst = (ULONG)pMgr; + return pMgr->DdeInitialize( pfnCallback, afCmd ); +} + +BOOL DdeUninitialize(ULONG idInst) +{ + if( !idInst ) + return FALSE; + ImpDdeMgr* pMgr = (ImpDdeMgr*)idInst; + // nur loeschen, wenn wir nicht mehr benutzt werden! + if( !pMgr->OwnsConversationHandles() ) + { + WRITELOG("DdeUninitialize: TRUE"); + delete pMgr; + return TRUE; + } + WRITELOG("DdeUninitialize: FALSE"); + return FALSE; +} + + +HCONVLIST DdeConnectList(ULONG idInst, HSZ hszService, HSZ hszTopic, + HCONVLIST hConvList, CONVCONTEXT* pCC) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeConnectList(hszService,hszTopic, + hConvList, pCC ); +} + +HCONV DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev) +{ + return ImpDdeMgr::DdeQueryNextServer( hConvList, hConvPrev ); +} + +BOOL DdeDisconnectList(HCONVLIST hConvList) +{ + return ImpDdeMgr::DdeDisconnectList( hConvList ); +} + +HCONV DdeConnect(ULONG idInst, HSZ hszService, HSZ hszTopic, + CONVCONTEXT* pCC) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeConnect( hszService, hszTopic, pCC ); +} + +BOOL DdeDisconnect(HCONV hConv) +{ + return ImpDdeMgr::DdeDisconnect( hConv ); +} + +HCONV DdeReconnect(HCONV hConv) +{ + return ImpDdeMgr::DdeReconnect( hConv ); +} + + +USHORT DdeQueryConvInfo(HCONV hConv, ULONG idTransact, CONVINFO* pCI ) +{ + return ImpDdeMgr::DdeQueryConvInfo( hConv, idTransact, pCI ); +} + +BOOL DdeSetUserHandle(HCONV hConv, ULONG id, ULONG hUser) +{ + return ImpDdeMgr::DdeSetUserHandle( hConv, id, hUser ); +} + +BOOL DdeAbandonTransaction(ULONG idInst, HCONV hConv, ULONG idTransaction) +{ + if( !idInst ) + return FALSE; + return ((ImpDdeMgr*)idInst)->DdeAbandonTransaction(hConv,idTransaction); +} + +BOOL DdePostAdvise(ULONG idInst, HSZ hszTopic, HSZ hszItem) +{ + if( !idInst ) + return FALSE; + return ((ImpDdeMgr*)idInst)->DdePostAdvise( hszTopic, hszItem ); +} + +BOOL DdeEnableCallback(ULONG idInst, HCONV hConv, USHORT wCmd) +{ + if( !idInst ) + return FALSE; + return ((ImpDdeMgr*)idInst)->DdeEnableCallback( hConv, wCmd ); +} + +HDDEDATA DdeClientTransaction(void* pData, ULONG cbData, + HCONV hConv, HSZ hszItem, USHORT wFmt, USHORT wType, + ULONG dwTimeout, ULONG* pdwResult) +{ + return ImpDdeMgr::DdeClientTransaction( pData, cbData, + hConv, hszItem, wFmt, wType, dwTimeout, pdwResult ); +} + +HDDEDATA DdeCreateDataHandle(ULONG idInst, void* pSrc, ULONG cb, + ULONG cbOff, HSZ hszItem, USHORT wFmt, USHORT afCmd) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeCreateDataHandle( pSrc, cb, + cbOff, hszItem, wFmt, afCmd ); +} + +HDDEDATA DdeAddData(HDDEDATA hData, void* pSrc, ULONG cb, ULONG cbOff) +{ + return ImpDdeMgr::DdeAddData( hData, pSrc, cb, cbOff ); +} + +ULONG DdeGetData(HDDEDATA hData, void* pDst, ULONG cbMax, ULONG cbOff) +{ + return ImpDdeMgr::DdeGetData( hData, pDst, cbMax, cbOff ); +} + +BYTE* DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize) +{ + return ImpDdeMgr::DdeAccessData( hData, pcbDataSize ); +} + +BOOL DdeUnaccessData(HDDEDATA hData) +{ + return ImpDdeMgr::DdeUnaccessData( hData ); +} + +BOOL DdeFreeDataHandle(HDDEDATA hData) +{ + return ImpDdeMgr::DdeFreeDataHandle( hData ); +} + +USHORT DdeGetLastError(ULONG idInst) +{ + if( !idInst ) + return DMLERR_DLL_NOT_INITIALIZED; + return ((ImpDdeMgr*)idInst)->DdeGetLastError(); +} + +HSZ DdeCreateStringHandle(ULONG idInst, PSZ pszString,int iCodePage ) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeCreateStringHandle(pszString,iCodePage); +} + +ULONG DdeQueryString( ULONG idInst, HSZ hsz, PSZ pBuf, + ULONG cchMax, int iCodePage ) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeQueryString( hsz,pBuf,cchMax,iCodePage); +} + +BOOL DdeFreeStringHandle( ULONG idInst, HSZ hsz) +{ + if( !idInst ) + return FALSE; + return ((ImpDdeMgr*)idInst)->DdeFreeStringHandle( hsz ); +} + +BOOL DdeKeepStringHandle( ULONG idInst, HSZ hsz ) +{ + if( !idInst ) + return FALSE; + return ((ImpDdeMgr*)idInst)->DdeKeepStringHandle( hsz ); +} + +int DdeCmpStringHandles(HSZ hsz1, HSZ hsz2) +{ + return ImpDdeMgr::DdeCmpStringHandles( hsz1, hsz2 ); +} + +HDDEDATA DdeNameService( ULONG idInst, HSZ hsz1, HSZ hszRes, USHORT afCmd ) +{ + if( !idInst ) + return 0; + return ((ImpDdeMgr*)idInst)->DdeNameService( hsz1, afCmd ); +} + + diff --git a/svl/source/svdde/ddemldeb.cxx b/svl/source/svdde/ddemldeb.cxx new file mode 100644 index 000000000000..18da7c07fd3c --- /dev/null +++ b/svl/source/svdde/ddemldeb.cxx @@ -0,0 +1,283 @@ +/************************************************************************* + * + * 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: ddemldeb.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include "ddemlimp.hxx" + +#ifdef OV_DEBUG +#include <svgen.hxx> +#endif + +#if defined(OV_DEBUG) + +void ImpAddHSZ( HSZ hszString, String& rStr ) +{ + char aBuf[ 128 ]; + ImpDdeMgr::DdeQueryString( hszString,aBuf,sizeof(aBuf),850); + rStr += " (\""; rStr += aBuf; rStr += "\","; + HATOMTBL hAtomTable = WinQuerySystemAtomTable(); + ULONG nRefCount = 0; + if( hszString ) + nRefCount = WinQueryAtomUsage(hAtomTable, (ATOM)hszString ); + rStr += nRefCount; rStr += ')'; +} + + +void ImpWriteDdeStatus(char* aFilename, char* pAppContext) +{ + char aBuf[ 128 ]; + USHORT nCtr; + HWND* pAppPtr; + ImpHCONV* pConvPtr; + Transaction* pTransPtr; + + ImpDdeMgrData* pData = ImpDdeMgr::AccessMgrData(); + if( !pData ) + return; + SvFileStream aStrm(aFilename, STREAM_READWRITE ); + String aLine; + aStrm.Seek( STREAM_SEEK_TO_END ); + aStrm << endl; + aStrm.WriteLine("********************** DDEML-Log ***********************"); + aStrm << endl; + if( pAppContext ) + { + aLine = Application::GetAppName(); + aLine += ':'; + aLine += "App-Context:"; aLine += pAppContext; + aStrm.WriteLine( aLine ); aStrm << endl; + } + aStrm.WriteLine("----------------- ImpDdeMgrData -------------------"); + aStrm << endl; + aLine= "TotalSize :"; aLine+= pData->nTotalSize; aStrm.WriteLine(aLine); + aLine= "nOffsAppTable :"; aLine+= pData->nOffsAppTable; aStrm.WriteLine(aLine); + aLine= "nOffsConvTable :"; aLine+= pData->nOffsConvTable; aStrm.WriteLine(aLine); + aLine= "nOffsTransTable:"; aLine+= pData->nOffsTransTable; aStrm.WriteLine(aLine); + aLine= "nMaxAppCount :"; aLine+= pData->nMaxAppCount; aStrm.WriteLine(aLine); + aLine= "nMaxConvCount :"; aLine+= pData->nMaxConvCount; aStrm.WriteLine(aLine); + aLine= "nMaxTransCount :"; aLine+= pData->nMaxTransCount; aStrm.WriteLine(aLine); + aLine= "nLastErr :"; aLine+= pData->nLastErr; aStrm.WriteLine(aLine); + aLine= "nCurConvCount :"; aLine+= pData->nCurConvCount; aStrm.WriteLine(aLine); + aLine= "nCurTransCount :"; aLine+= pData->nCurTransCount; aStrm.WriteLine(aLine); + aStrm << endl; + aStrm.WriteLine("---------- Registered DDEML-Applications -----------"); + aStrm << endl; + pAppPtr = ImpDdeMgr::GetAppTable( pData ); + for( nCtr = 0; nCtr < pData->nMaxAppCount; nCtr++, pAppPtr++ ) + { + if( *pAppPtr ) + { + aLine = "App."; aLine += nCtr; aLine += " HWND:"; + aLine += (ULONG)*pAppPtr; aStrm.WriteLine(aLine); + } + } + + aStrm << endl; + aStrm.WriteLine("-------------- Conversation handles ----------------"); + aStrm << endl; + + USHORT nCurCount = pData->nCurConvCount; + + if( nCurCount ) + { + pConvPtr = ImpDdeMgr::GetConvTable( pData ); + for( nCtr = 0; nCtr < pData->nMaxConvCount; nCtr++, pConvPtr++ ) + { + if( pConvPtr->hWndThis ) + { + aLine = "HCONV:"; aLine += nCtr; + aLine += " HCONVpartner: "; aLine += (USHORT)pConvPtr->hConvPartner; + if( !pConvPtr->hConvPartner ) aLine += "(Non-DDEML-App)"; + aLine += " hszPartner: "; aLine += (USHORT)pConvPtr->hszPartner; + ImpAddHSZ( pConvPtr->hszPartner, aLine ); + aStrm.WriteLine( aLine ); + + aLine = "hszService: "; aLine += (USHORT)pConvPtr->hszServiceReq; + ImpAddHSZ( pConvPtr->hszServiceReq, aLine ); + aLine += " hszTopic: "; aLine += (USHORT)pConvPtr->hszTopic; + ImpAddHSZ( pConvPtr->hszTopic, aLine ); + aStrm.WriteLine( aLine ); + + aLine= "Status: "; aLine+= pConvPtr->nStatus; + if( pConvPtr->nStatus & ST_CLIENT ) aLine += " (Client)"; + if( pConvPtr->nStatus & ST_INLIST ) aLine += " (Inlist)"; + aStrm.WriteLine(aLine); + + aLine = "pidOwner: "; aLine += (ULONG)pConvPtr->pidOwner; + aStrm.WriteLine( aLine ); + aLine = "hWndThis: "; aLine += (ULONG)pConvPtr->hWndThis; + aStrm.WriteLine( aLine ); + aLine = "hWndPartner: "; aLine += (ULONG)pConvPtr->hWndPartner; + aStrm.WriteLine( aLine ); + + aLine = "hConvList: "; aLine += (ULONG)pConvPtr->hConvList; + aLine += " Prev: "; aLine += pConvPtr->nPrevHCONV; + aLine += " Next: "; aLine += pConvPtr->nNextHCONV; + aStrm.WriteLine( aLine ); + aStrm.WriteLine("----------------------------------------------------"); + + nCurCount--; + if( !nCurCount ) + break; + } + } + } + + aStrm.WriteLine("----------------- Transaction Ids ------------------"); + + nCurCount = pData->nCurTransCount; + if( nCurCount ) + { + pTransPtr = ImpDdeMgr::GetTransTable( pData ); + for( nCtr = 0; nCtr < pData->nMaxTransCount; nCtr++, pTransPtr++ ) + { + + if( pTransPtr->hConvOwner ) + { + aLine = "TransactionId:"; aLine += nCtr; + aLine += " hConvOwner: "; aLine += (USHORT)pTransPtr->hConvOwner; + aStrm.WriteLine( aLine ); + aLine = "Item: "; aLine += (USHORT)pTransPtr->hszItem; + ImpAddHSZ( pTransPtr->hszItem, aLine ); + aLine += " Format: "; aLine += pTransPtr->nFormat; + aStrm.WriteLine( aLine ); + aLine = "TransactionType: "; aLine += pTransPtr->nType; + aLine += " Convst: "; aLine += pTransPtr->nConvst; + aLine += " LastErr: "; aLine += pTransPtr->nLastError; + aLine += " Userhandle: "; aLine += pTransPtr->nUser; + aStrm.WriteLine( aLine ); + aStrm.WriteLine("--------------------------------------------------"); + + nCurCount--; + if( !nCurCount ) + break; + } + } + } + aStrm << endl; + aStrm.WriteLine("******************* End of DDEML-Log *******************"); +} + +void ImpWriteDdeData(char* aFilename, DDESTRUCT* pData) +{ + char aBuf[ 128 ]; + USHORT nCtr; + SvFileStream aStrm(aFilename, STREAM_READWRITE ); + aStrm.Seek( STREAM_SEEK_TO_END ); + String aLine; + aStrm << endl; + aLine = "cbData:"; aLine += pData->cbData; aStrm.WriteLine( aLine ); + aLine = "fsStatus:"; aLine += pData->fsStatus; aStrm.WriteLine( aLine ); + aLine = "usFormat:"; aLine += pData->usFormat; aStrm.WriteLine( aLine ); + aLine = "ItemName:"; aLine += (char*)((char*)pData+pData->offszItemName); + aStrm.WriteLine( aLine ); + aLine = "offabData:"; aLine += pData->offabData; aStrm.WriteLine(aLine); + char* pBuf = (char*)pData+pData->offabData; + USHORT nLen = pData->cbData; // - pData->offabData; + while( nLen ) + { + aStrm << *pBuf; + nLen--; + pBuf++; + } + aStrm << endl; +} + +void ImpWriteLogFile(char* pFilename, char* pStr) +{ + SvFileStream aStrm(pFilename, STREAM_READWRITE ); + aStrm.Seek( STREAM_SEEK_TO_END ); + String aStr( Application::GetAppName() ); + aStr += ':'; aStr += pStr; + aStrm.WriteLine( (char*)aStr.GetStr() ); +} + +#else + +void ImpWriteDdeStatus(char*, char* ) {} +void ImpWriteDdeData(char*, DDESTRUCT*) {} +void ImpWriteLogFile(char*, char*) {} + +#endif + +APIRET MyDosAllocSharedMem(void** ppBaseAddress, char* pszName, unsigned long ulObjectSize, + unsigned long ulFlags, char* pContextStr ) +{ + APIRET nRet = DosAllocSharedMem(ppBaseAddress,pszName,ulObjectSize,ulFlags ); +#if 0 && defined(OV_DEBUG) && defined(LOGFILE) + String aStr("DosAllocSharedMem:"); + aStr += pContextStr; + aStr += ": "; + aStr += ulObjectSize; + aStr += " ("; + aStr += (ULONG)*((char**)ppBaseAddress); + aStr += ')'; + ImpWriteLogFile("\\ddeml.mem", (char*)aStr.GetStr() ); +#endif + return nRet; +} + +APIRET MyDosAllocMem(void** ppBaseAddress, unsigned long ulObjectSize, + unsigned long ulFlags, char* pContextStr ) +{ + APIRET nRet = DosAllocMem(ppBaseAddress, ulObjectSize,ulFlags ); +#if 0 && defined(OV_DEBUG) && defined(LOGFILE) + String aStr("DosAllocMem:"); + aStr += pContextStr; + aStr += ": "; + aStr += ulObjectSize; + aStr += " ("; + aStr += (ULONG)*((char**)ppBaseAddress); + aStr += ')'; + ImpWriteLogFile("\\ddeml.mem", (char*)aStr.GetStr() ); +#endif + return nRet; +} + + +APIRET MyDosFreeMem( void* pBaseAddress, char* pContextStr ) +{ + APIRET nRet = DosFreeMem( pBaseAddress ); +#if 0 && defined(OV_DEBUG) && defined(LOGFILE) + String aStr("DosFreeMem:"); + aStr += pContextStr; + aStr += ": "; + aStr += (ULONG)pBaseAddress; + ImpWriteLogFile("\\ddeml.mem", (char*)aStr.GetStr()); +#endif + return nRet; +} + + + + + diff --git a/svl/source/svdde/ddemldeb.hxx b/svl/source/svdde/ddemldeb.hxx new file mode 100644 index 000000000000..39d3d836882a --- /dev/null +++ b/svl/source/svdde/ddemldeb.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * 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: ddemldeb.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if defined(OV_DEBUG) + +void ImpWriteLogFile(char*,char*); +void ImpAddHSZ( HSZ, String& ); +void ImpWriteDdeStatus(char*, char* ); +void ImpWriteDdeData(char*, DDESTRUCT*); + +#ifdef LOGFILE +#define WRITELOG(aString) ImpWriteLogFile("\\ddeml.log",aString); +#else +#define WRITELOG(bla) +#endif +#ifdef STATUSFILE +#define WRITESTATUS(aContext) ImpWriteDdeStatus("\\ddeml.sts",aContext); +#else +#define WRITESTATUS(bla) +#endif +#ifdef DDEDATAFILE +#define WRITEDATA(data) ImpWriteDdeData("\\ddeml.dat",data); +#else +#define WRITEDATA(bla) +#endif + +#else + +#define WRITELOG(bla) +#define WRITESTATUS(bla) +#define WRITEDATA(bla) + +#endif + +APIRET MyDosAllocSharedMem(void** ppBaseAddress, char* pszName, unsigned long ulObjectSize, + unsigned long ulFlags, char* pContextStr ); + +APIRET MyDosAllocMem(void** ppBaseAddress, unsigned long ulObjectSize, + unsigned long ulFlags, char* pContextStr ); + +APIRET MyDosFreeMem( void* pBaseAddress, char* pContextStr ); + diff --git a/svl/source/svdde/ddemlimp.hxx b/svl/source/svdde/ddemlimp.hxx new file mode 100644 index 000000000000..47ad53d0b9fe --- /dev/null +++ b/svl/source/svdde/ddemlimp.hxx @@ -0,0 +1,436 @@ +/************************************************************************* + * + * 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: ddemlimp.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DDEMLIMP_HXX +#define _DDEMLIMP_HXX + + +#include <string.h> +#include <ctype.h> +#include "ddemlos2.h" + +#define DDEMLSERVICETABLE_INISIZE 8 + +// Bezeichner der systemglobalen DDEML-Tabelle +#define DDEMLDATA "\\SHAREMEM\\OV_DDEML.DAT" + +// vorlaeufig konstante Tabellengroessen +#define CONVTABLECOUNT 2048 /* max count conversations */ +#define TRANSTABLECOUNT 2048 /* transactions */ +#define DDEMLAPPCOUNT 16 /* max count simultaniously running */ + /* ddeml (StarDivision) applications */ + +#define ST_TERMACKREC 0x8000 /* wird im Conversationhandle gesetzt, */ + /* wenn die Partner-App DDE_TERMINATE */ + /* bestaetigt hat */ + +#define XST_TIMEOUT 17 /* Trans. hat Timeout ueberschritten */ +#define XST_WAITING_ACK 18 /* Trans. wartet auf Acknowledge */ +#define XST_WAITING_ADVDATA 19 /* Trans. wartet auf Advise-Daten */ +#define XST_WAITING_REQDATA 20 /* Trans. wartet auf angeforderte Daten */ + + +/* User-Flags DDESTRUCT */ +#define IMP_HDATAAPPOWNED 0x8000 + +#define CONVLISTNAME "DdeConvListId" + +#define XTYPF_MASK (XTYPF_NOBLOCK | XTYPF_NODATA | XTYPF_ACKREQ) + +// +// DDEML-Messages; werden nur an registrierte DDEML-Apps gesendet +// + +// Msg: WM_DDEML_REGISTER +// Empfaenger: wird allen DDEML-Applikationen nach Registrierung +// eines neuen Services gesendet +// Params: nPar1: hszBaseServName +// nPar2: hszInstServName +#define WM_DDEML_REGISTER WM_USER+1 + +// Msg: WM_DDEML_UNREGISTER +// Empfaenger: wird allen DDEML-Applikationen nach Deregistrierung +// eines Services gesendet +// Params: nPar1: hszBaseServName +// nPar2: hszInstServName +#define WM_DDEML_UNREGISTER WM_USER+2 + +// +// +// + +struct ImpHCONV +{ + HCONV hConvPartner; + HSZ hszPartner; // Name of partner application + HSZ hszServiceReq; // Service name + HSZ hszTopic; // Topic name + USHORT nStatus; // ST_* of conversation + HCONVLIST hConvList; // ConvListId , wenn in ConvList + CONVCONTEXT aConvContext; // Conversation context + + // private + HWND hWndThis; // 0 == Handle not used + HWND hWndPartner; + PID pidOwner; // PID des DdeManagers, der + // den Conv-Handle erzeugt hat. + USHORT nPrevHCONV; // 0 == no previous hConv or not in list + USHORT nNextHCONV; // 0 == no next hconv or not in list +}; + +struct Transaction +{ + HSZ hszItem; // Item name + USHORT nFormat; // Data format + USHORT nType; // Transaction type (XTYP_*) + // XTYP_ADVREQ [|XTYPF_NODATA] == Advise-Loop + // [|XTYPF_ACKREQ] + // XTYP_EXECUTE == laufendes Execute + // XTYP_REQUEST + // XTYP_POKE + // XTYP_ADVSTOP + // XTYP_ADVSTART + USHORT nConvst; // Conversation state (XST_*) + // 0 == idle + // XST_REQSENT (fuer XTYP_ADVREQ) + // XST_TIMEOUT (fuer alle Typen!) + // XST_WAITING (alle ausser XTYP_ADVREQ) + USHORT nLastError; // last err in transaction + ULONG nUser; // Userhandle + // private + HCONV hConvOwner; // 0 == Transaction not used +}; + + +struct ImpWndProcParams +{ + HWND hWndReceiver; + MPARAM nPar1; + MPARAM nPar2; +}; + +struct ImpService +{ + HSZ hBaseServName; // Basis-Name des Service + HSZ hInstServName; // Basis-Name + DDEML-Server-HWND der App +}; + +class ImpDdeMgr; + +// Daten eines Conversation-Windows +struct ImpConvWndData +{ + ImpDdeMgr* pThis; + USHORT nRefCount; // Zahl Conversations auf diesem Window +}; + + +// systemglobale Daten der Library (liegen in named shared memory) +struct ImpDdeMgrData +{ + ULONG nTotalSize; + ULONG nOffsAppTable; + ULONG nOffsConvTable; + ULONG nOffsTransTable; + USHORT nMaxAppCount; + USHORT nMaxConvCount; + USHORT nMaxTransCount; + USHORT nLastErr; + USHORT nReserved; + USHORT nCurTransCount; + USHORT nCurConvCount; + HWND aAppTable[ 1 ]; // fuer Broadcast-Messages + ImpHCONV aConvTable[ 1 ]; + Transaction aTransTable[ 1 ]; +}; + + + +class ImpDdeMgr +{ + friend MRESULT EXPENTRY ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2); + friend MRESULT EXPENTRY ServerWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2); + friend void ImpWriteDdeStatus(char*,char*); + friend void ImpAddHSZ( HSZ, String& ); + + static PSZ AllocAtomName( ATOM hString, ULONG& rBufLen ); + static PDDESTRUCT MakeDDEObject( HWND hwnd, ATOM hItemName, + USHORT fsStatus, USHORT usFormat, PVOID pabData, ULONG usDataLen ); + static APIRET AllocNamedSharedMem( PPVOID ppBaseAddress, PSZ pName, + ULONG nElementSize, ULONG nElementCount ); + + HWND hWndServer; + PID pidThis; + PFNCALLBACK pCallback; + ULONG nTransactFilter; + CONVCONTEXT aDefaultContext; + ImpDdeMgrData* pData; + ImpService* pServices; + USHORT nServiceCount; + + ImpHCONV* pConvTable; // liegt in pData (nicht deleten!) + Transaction* pTransTable; // liegt in pData (nicht deleten!) + HWND* pAppTable; // liegt in pData (nicht deleten!) + + static ImpHCONV* GetConvTable( ImpDdeMgrData* ); + static Transaction* GetTransTable( ImpDdeMgrData* ); + static HWND* GetAppTable( ImpDdeMgrData* ); + + + static HWND NextFrameWin( HENUM hEnum ); + void CreateServerWnd(); + void DestroyServerWnd(); + HWND CreateConversationWnd(); + // Fktn. duerfen nur fuer HCONVs aufgerufen werden, die + // in der eigenen Applikation erzeugt wurden + static void DestroyConversationWnd( HWND hWndConv ); + static USHORT GetConversationWndRefCount( HWND hWndConv ); + static USHORT IncConversationWndRefCount( HWND hWndConv ); + + MRESULT SrvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2); + MRESULT ConvWndProc(HWND hWnd,ULONG nMsg,MPARAM nPar1,MPARAM nPar2); + void RegisterDDEMLApp(); + void UnregisterDDEMLApp(); + void CleanUp(); + ImpDdeMgrData* InitAll(); + static BOOL MyWinDdePostMsg( HWND, HWND, USHORT, PDDESTRUCT, ULONG ); + void MyInitiateDde( HWND hWndServer, HWND hWndClient, + HSZ hszService, HSZ hszTopic, CONVCONTEXT* pCC ); + DDEINIT* CreateDDEInitData( HWND hWndDest, HSZ hszService, + HSZ hszTopic, CONVCONTEXT* pCC ); + // wenn pDDEData==0, muss pCC gesetzt sein + HCONV ConnectWithClient( HWND hWndClient, HSZ hszPartner, + HSZ hszService, HSZ hszTopic, BOOL bSameInst, + DDEINIT* pDDEData, CONVCONTEXT* pCC = 0); + + HCONV CheckIncoming( ImpWndProcParams*, ULONG nTransMask, + HSZ& rhszItem ); + // fuer Serverbetrieb. Ruft Callback-Fkt fuer alle offenen Advises + // auf, deren Owner der uebergebene HCONV ist. + // bFreeTransactions==TRUE: loescht die Transaktionen + // gibt Anzahl der getrennten Transaktionen zurueck + USHORT SendUnadvises( HCONV hConv, + USHORT nFormat, // 0==alle + BOOL bFreeTransactions ); + + BOOL WaitTransState( + Transaction* pTrans, ULONG nTransId, + USHORT nNewState, + ULONG nTimeout ); + + // DDEML ruft Callback mit XTYP_CONNECT-Transaction nur auf, + // wenn die App den angeforderten Service registriert hat + // Standardeinstellung: TRUE + BOOL bServFilterOn; + + // Fehlercode muss noch systemglobal werden (Atom o. ae.) + static USHORT nLastErrInstance; // wenn 0, dann gilt globaler Fehlercode + + static ImpDdeMgrData* AccessMgrData(); + + static HCONV CreateConvHandle( ImpDdeMgrData* pBase, + PID pidOwner, + HWND hWndThis, HWND hWndPartner, + HSZ hszPartner, HSZ hszServiceReq, HSZ hszTopic, + HCONV hPrevHCONV = 0 ); + + static HCONV IsConvHandleAvailable( ImpDdeMgrData* pBase ); + static HCONV GetConvHandle( ImpDdeMgrData* pBase, + HWND hWndThis, HWND hWndPartner ); + static void FreeConvHandle( ImpDdeMgrData*, HCONV, + BOOL bDestroyHWndThis = TRUE ); + + static ULONG CreateTransaction( ImpDdeMgrData* pBase, + HCONV hOwner, HSZ hszItem, USHORT nFormat, + USHORT nTransactionType ); + static ULONG GetTransaction( ImpDdeMgrData* pBase, + HCONV hOwner, HSZ hszItem, USHORT nFormat ); + + static void FreeTransaction( ImpDdeMgrData*, ULONG nTransId ); + + BOOL DisconnectAll(); + // Transaktionen muessen _vor_ den Konversationen geloescht werden! + static void FreeTransactions( ImpDdeMgrData*, HWND hWndThis, + HWND hWndPartner ); + static void FreeTransactions( ImpDdeMgrData*, HCONV hConvOwner ); + + static void FreeConversations( ImpDdeMgrData*,HWND hWndThis, + HWND hWndPartner ); + + ImpService* GetService( HSZ hszService ); + ImpService* PutService( HSZ hszService ); + void BroadcastService( ImpService*, BOOL bRegistered ); + + // rh: Startposition(!) & gefundener Handle + static ImpHCONV* GetFirstServer( ImpDdeMgrData*, HCONVLIST, HCONV& rh); + static ImpHCONV* GetLastServer( ImpDdeMgrData*, HCONVLIST, HCONV& ); + static BOOL CheckConvListId( HCONVLIST hConvListId ); + + BOOL IsSameInstance( HWND hWnd ); + HSZ GetAppName( HWND hWnd ); + + + // Transactions + MRESULT DdeAck( ImpWndProcParams* pParams ); + MRESULT DdeAdvise( ImpWndProcParams* pParams ); + MRESULT DdeData( ImpWndProcParams* pParams ); + MRESULT DdeExecute( ImpWndProcParams* pParams ); + MRESULT DdeInitiate( ImpWndProcParams* pParams ); + MRESULT DdeInitiateAck( ImpWndProcParams* pParams ); + MRESULT DdePoke( ImpWndProcParams* pParams ); + MRESULT DdeRequest( ImpWndProcParams* pParams ); + MRESULT DdeTerminate( ImpWndProcParams* pParams ); + MRESULT DdeUnadvise( ImpWndProcParams* pParams ); + MRESULT DdeRegister( ImpWndProcParams* pParams ); + MRESULT DdeUnregister( ImpWndProcParams* pParams ); + MRESULT DdeTimeout( ImpWndProcParams* pParams ); + + HDDEDATA Callback( + USHORT nTransactionType, + USHORT nClipboardFormat, + HCONV hConversationHandle, + HSZ hsz1, + HSZ hsz2, + HDDEDATA hData, + ULONG nData1, + ULONG nData2 ); + + HCONV DdeConnectImp( HSZ hszService,HSZ hszTopic,CONVCONTEXT* pCC); + + // connection data + HCONV hCurConv; // wird im DdeInitiateAck gesetzt + HCONVLIST hCurListId; // fuer DdeConnectList + USHORT nPrevConv; // .... "" .... + BOOL bListConnect; + + // synchr. transaction data + BOOL bInSyncTrans; + ULONG nSyncTransId; + HDDEDATA hSyncResponseData; + ULONG nSyncResponseMsg; // WM_DDE_ACK, WM_DDE_DATA, WM_TIMER + // TRUE==nach Ende der synchronen Transaktion eine evtl. benutzte + // asynchrone Transaktion beenden (typisch synchroner Request auf + // Advise-Loop) + BOOL bSyncAbandonTrans; + +public: + ImpDdeMgr(); + ~ImpDdeMgr(); + + USHORT DdeInitialize( PFNCALLBACK pCallbackProc, ULONG nTransactionFilter ); + USHORT DdeGetLastError(); + + HCONV DdeConnect( HSZ hszService, HSZ hszTopic, CONVCONTEXT* ); + HCONVLIST DdeConnectList( HSZ hszService, HSZ hszTopic, + HCONVLIST hConvList, CONVCONTEXT* ); + static BOOL DdeDisconnect( HCONV hConv ); + static BOOL DdeDisconnectList( HCONVLIST hConvList ); + static HCONV DdeReconnect(HCONV hConv); + static HCONV DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev); + static USHORT DdeQueryConvInfo(HCONV hConv, ULONG idTrans,CONVINFO* pCI); + static BOOL DdeSetUserHandle(HCONV hConv, ULONG id, ULONG hUser); + BOOL DdeAbandonTransaction( HCONV hConv, ULONG idTransaction); + + BOOL DdePostAdvise( HSZ hszTopic, HSZ hszItem); + BOOL DdeEnableCallback( HCONV hConv, USHORT wCmd); + + HDDEDATA DdeNameService( HSZ hszService, USHORT afCmd); + + static HDDEDATA DdeClientTransaction(void* pData, ULONG cbData, + HCONV hConv, HSZ hszItem, USHORT wFmt, USHORT wType, + ULONG dwTimeout, ULONG* pdwResult); + + // Data handles + + HDDEDATA DdeCreateDataHandle( void* pSrc, ULONG cb, ULONG cbOff, + HSZ hszItem, USHORT wFmt, USHORT afCmd); + static BYTE* DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize); + static BOOL DdeUnaccessData(HDDEDATA hData); + static BOOL DdeFreeDataHandle(HDDEDATA hData); + static HDDEDATA DdeAddData(HDDEDATA hData,void* pSrc,ULONG cb,ULONG cbOff); + static ULONG DdeGetData(HDDEDATA hData,void* pDst,ULONG cbMax,ULONG cbOff); + + // String handles + + static HSZ DdeCreateStringHandle( PSZ pStr, int iCodePage); + static ULONG DdeQueryString(HSZ hsz,PSZ pStr,ULONG cchMax,int iCPage); + static BOOL DdeFreeStringHandle( HSZ hsz ); + static BOOL DdeKeepStringHandle( HSZ hsz ); + static int DdeCmpStringHandles(HSZ hsz1, HSZ hsz2); + + // mit dieser Funktion kann geprueft werden, ob eine + // Applikation schon eine DDEML-Instanz angelegt hat. + // Die aktuelle Impl. unterstuetzt nur eine DDEML-Instanz + // pro Applikation (wg. synchroner Transaktionen) + static ImpDdeMgr* GetImpDdeMgrInstance( HWND hWnd ); + + // gibt TRUE zurueck, wenn mind. ein lebender HCONV + // von diesem DdeMgr erzeugt wurde + BOOL OwnsConversationHandles(); +}; + +// static +inline ImpHCONV* ImpDdeMgr::GetConvTable( ImpDdeMgrData* pData ) +{ + ImpHCONV* pRet; + if( pData ) + pRet = (ImpHCONV*)((ULONG)(pData) + pData->nOffsConvTable); + else + pRet = 0; + return pRet; +} + +// static +inline Transaction* ImpDdeMgr::GetTransTable( ImpDdeMgrData* pData ) +{ + Transaction* pRet; + if( pData ) + pRet = (Transaction*)((ULONG)(pData) + pData->nOffsTransTable); + else + pRet = 0; + return pRet; +} + +// static +inline HWND* ImpDdeMgr::GetAppTable( ImpDdeMgrData* pData ) +{ + HWND* pRet; + if( pData ) + pRet = (HWND*)((ULONG)(pData) + pData->nOffsAppTable); + else + pRet = 0; + return pRet; +} + + + + +#endif + diff --git a/svl/source/svdde/ddemlos2.h b/svl/source/svdde/ddemlos2.h new file mode 100644 index 000000000000..fe685e95fecf --- /dev/null +++ b/svl/source/svdde/ddemlos2.h @@ -0,0 +1,377 @@ +/************************************************************************* + * + * 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: ddemlos2.h,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _DDEML_H +#define _DDEML_H + +#define INCL_OS2 +#define INCL_WIN + +#include <tools/svpm.h> +#include <tools/solar.h> +#include <tools/debug.hxx> +#include <tools/stream.hxx> + +typedef LHANDLE HSTR; + +#ifndef CALLBACK +#define CALLBACK +#endif + + +typedef ULONG HCONVLIST; +typedef ULONG HCONV; +typedef ATOM HSZ; +typedef DDESTRUCT* HDDEDATA; + +struct CONVINFO +{ + USHORT nSize; // sizeof(CONVINFO) + ULONG nUser; // Userhandle + HCONV hConvPartner; // + HSZ hszPartner; // Name der Partnerapp + HSZ hszServiceReq; // Name des angeforderten Services + HSZ hszTopic; // -- " -- Topics + HSZ hszItem; // -- " -- Items + USHORT nFormat; // Datenformat der akt. Transaktion + USHORT nType; // Typ der akt. Transaktion (XTYP_*) + USHORT nStatus; // ST_* der Konversation + USHORT nConvst; // XST_* der akt. Transaktion + USHORT nLastError; // letzter Fehler der Transaktion + HCONVLIST hConvList; // ConvListId , wenn in ConvList + CONVCONTEXT aConvCtxt; // conversation context +}; + +/* the following structure is for use with XTYP_WILDCONNECT processing. */ + +struct HSZPAIR +{ + HSZ hszSvc; + HSZ hszTopic; +}; +typedef HSZPAIR *PHSZPAIR; + +/***** conversation states (usState) *****/ + +#define XST_NULL 0 /* quiescent states */ +#define XST_INCOMPLETE 1 +#define XST_CONNECTED 2 +#define XST_INIT1 3 /* mid-initiation states */ +#define XST_INIT2 4 +#define XST_REQSENT 5 /* active conversation states */ +#define XST_DATARCVD 6 +#define XST_POKESENT 7 +#define XST_POKEACKRCVD 8 +#define XST_EXECSENT 9 +#define XST_EXECACKRCVD 10 +#define XST_ADVSENT 11 +#define XST_UNADVSENT 12 +#define XST_ADVACKRCVD 13 +#define XST_UNADVACKRCVD 14 +#define XST_ADVDATASENT 15 +#define XST_ADVDATAACKRCVD 16 + +/* used in LOWORD(dwData1) of XTYP_ADVREQ callbacks... */ +#define CADV_LATEACK 0xFFFF + +/***** conversation status bits (fsStatus) *****/ + +#define ST_CONNECTED 0x0001 +#define ST_ADVISE 0x0002 +#define ST_ISLOCAL 0x0004 +#define ST_BLOCKED 0x0008 +#define ST_CLIENT 0x0010 +#define ST_TERMINATED 0x0020 +#define ST_INLIST 0x0040 +#define ST_BLOCKNEXT 0x0080 +#define ST_ISSELF 0x0100 + + +/* DDE constants for wStatus field */ + +//#define DDE_FACK 0x8000 +//#define DDE_FBUSY 0x4000 +//#define DDE_FDEFERUPD 0x4000 +//#define DDE_FACKREQ 0x8000 +//#define DDE_FRELEASE 0x2000 +//#define DDE_FREQUESTED 0x1000 +//#define DDE_FACKRESERVED 0x3ff0 +//#define DDE_FADVRESERVED 0x3fff +//#define DDE_FDATRESERVED 0x4fff +//#define DDE_FPOKRESERVED 0xdfff +//#define DDE_FAPPSTATUS 0x00ff +#define DDE_FNOTPROCESSED 0x0000 + +/***** message filter hook types *****/ + +#define MSGF_DDEMGR 0x8001 + +/***** codepage constants ****/ + +#define CP_WINANSI 1004 /* default codepage for windows & old DDE convs. */ + +/***** transaction types *****/ + +#define XTYPF_NOBLOCK 0x0002 /* CBR_BLOCK will not work */ +#define XTYPF_NODATA 0x0004 /* DDE_FDEFERUPD */ +#define XTYPF_ACKREQ 0x0008 /* DDE_FACKREQ */ + +#define XCLASS_MASK 0xFC00 +#define XCLASS_BOOL 0x1000 +#define XCLASS_DATA 0x2000 +#define XCLASS_FLAGS 0x4000 +#define XCLASS_NOTIFICATION 0x8000 + +#define XTYP_ERROR (0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) +#define XTYP_ADVDATA (0x0010 | XCLASS_FLAGS ) +#define XTYP_ADVREQ (0x0020 | XCLASS_DATA | XTYPF_NOBLOCK ) +#define XTYP_ADVSTART (0x0030 | XCLASS_BOOL ) +#define XTYP_ADVSTOP (0x0040 | XCLASS_NOTIFICATION) +#define XTYP_EXECUTE (0x0050 | XCLASS_FLAGS ) +#define XTYP_CONNECT (0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK) +#define XTYP_CONNECT_CONFIRM (0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) +#define XTYP_XACT_COMPLETE (0x0080 | XCLASS_NOTIFICATION ) +#define XTYP_POKE (0x0090 | XCLASS_FLAGS ) +#define XTYP_REGISTER (0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) +#define XTYP_REQUEST (0x00B0 | XCLASS_DATA ) +#define XTYP_DISCONNECT (0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) +#define XTYP_UNREGISTER (0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) +#define XTYP_WILDCONNECT (0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK) + +#define XTYP_MASK 0x00F0 +#define XTYP_SHIFT 4 /* shift to turn XTYP_ into an index */ + +/***** Timeout constants *****/ + +#define TIMEOUT_ASYNC -1L + +/***** Transaction ID constants *****/ + +#define QID_SYNC -1L + +/****** public strings used in DDE ******/ + +#define SZDDESYS_TOPIC "System" +#define SZDDESYS_ITEM_TOPICS "Topics" +#define SZDDESYS_ITEM_SYSITEMS "SysItems" +#define SZDDESYS_ITEM_RTNMSG "ReturnMessage" +#define SZDDESYS_ITEM_STATUS "Status" +#define SZDDESYS_ITEM_FORMATS "Formats" +#define SZDDESYS_ITEM_HELP "Help" +#define SZDDE_ITEM_ITEMLIST "TopicItemList" + + +/****** API entry points ******/ + +typedef HDDEDATA CALLBACK FNCALLBACK(USHORT wType, USHORT wFmt, HCONV hConv, + HSZ hsz1, HSZ hsz2, HDDEDATA hData, ULONG dwData1, ULONG dwData2); +typedef FNCALLBACK* PFNCALLBACK; + +#define CBR_BLOCK 0xffffffffL + +/* DLL registration functions */ + +USHORT DdeInitialize(ULONG* pidInst, PFNCALLBACK pfnCallback, + ULONG afCmd, ULONG ulRes); + +/* + * Callback filter flags for use with standard apps. + */ + +#define CBF_FAIL_SELFCONNECTIONS 0x00001000 +#define CBF_FAIL_CONNECTIONS 0x00002000 +#define CBF_FAIL_ADVISES 0x00004000 +#define CBF_FAIL_EXECUTES 0x00008000 +#define CBF_FAIL_POKES 0x00010000 +#define CBF_FAIL_REQUESTS 0x00020000 +#define CBF_FAIL_ALLSVRXACTIONS 0x0003f000 + +#define CBF_SKIP_CONNECT_CONFIRMS 0x00040000 +#define CBF_SKIP_REGISTRATIONS 0x00080000 +#define CBF_SKIP_UNREGISTRATIONS 0x00100000 +#define CBF_SKIP_DISCONNECTS 0x00200000 +#define CBF_SKIP_ALLNOTIFICATIONS 0x003c0000 + +/* + * Application command flags + */ +#define APPCMD_CLIENTONLY 0x00000010L +#define APPCMD_FILTERINITS 0x00000020L +#define APPCMD_MASK 0x00000FF0L + +/* + * Application classification flags + */ +#define APPCLASS_STANDARD 0x00000000L +#define APPCLASS_MASK 0x0000000FL + + +BOOL DdeUninitialize(ULONG idInst); + +/* conversation enumeration functions */ + +HCONVLIST DdeConnectList(ULONG idInst, HSZ hszService, HSZ hszTopic, + HCONVLIST hConvList, CONVCONTEXT* pCC); +HCONV DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev); +BOOL DdeDisconnectList(HCONVLIST hConvList); + +/* conversation control functions */ + +HCONV DdeConnect(ULONG idInst, HSZ hszService, HSZ hszTopic, + CONVCONTEXT* pCC); +BOOL DdeDisconnect(HCONV hConv); +HCONV DdeReconnect(HCONV hConv); + +USHORT DdeQueryConvInfo(HCONV hConv, ULONG idTransaction, CONVINFO* pConvInfo); +BOOL DdeSetUserHandle(HCONV hConv, ULONG id, ULONG hUser); + +BOOL DdeAbandonTransaction(ULONG idInst, HCONV hConv, ULONG idTransaction); + + +/* app server interface functions */ + +BOOL DdePostAdvise(ULONG idInst, HSZ hszTopic, HSZ hszItem); +BOOL DdeEnableCallback(ULONG idInst, HCONV hConv, USHORT wCmd); + +#define EC_ENABLEALL 0 +#define EC_ENABLEONE ST_BLOCKNEXT +#define EC_DISABLE ST_BLOCKED +#define EC_QUERYWAITING 2 + +HDDEDATA DdeNameService(ULONG idInst, HSZ hsz1, HSZ hsz2, USHORT afCmd); + +#define DNS_REGISTER 0x0001 +#define DNS_UNREGISTER 0x0002 +#define DNS_FILTERON 0x0004 +#define DNS_FILTEROFF 0x0008 + +/* app client interface functions */ + +HDDEDATA DdeClientTransaction(void* pData, ULONG cbData, + HCONV hConv, HSZ hszItem, USHORT wFmt, USHORT wType, + ULONG dwTimeout, ULONG* pdwResult); + +/* data transfer functions */ + +HDDEDATA DdeCreateDataHandle(ULONG idInst, void* pSrc, ULONG cb, + ULONG cbOff, HSZ hszItem, USHORT wFmt, USHORT afCmd); +// HDDEDATA DdeAddData(HDDEDATA hData, void* pSrc, ULONG cb, ULONG cbOff); +ULONG DdeGetData(HDDEDATA hData, void* pDst, ULONG cbMax, ULONG cbOff); +BYTE* DdeAccessData(HDDEDATA hData, ULONG* pcbDataSize); +BOOL DdeUnaccessData(HDDEDATA hData); +BOOL DdeFreeDataHandle(HDDEDATA hData); + +#define HDATA_APPOWNED 0x0001 + +USHORT DdeGetLastError(ULONG idInst); + +#define DMLERR_NO_ERROR 0 /* must be 0 */ + +#define DMLERR_FIRST 0x4000 + +#define DMLERR_ADVACKTIMEOUT 0x4000 +#define DMLERR_BUSY 0x4001 +#define DMLERR_DATAACKTIMEOUT 0x4002 +#define DMLERR_DLL_NOT_INITIALIZED 0x4003 +#define DMLERR_DLL_USAGE 0x4004 +#define DMLERR_EXECACKTIMEOUT 0x4005 +#define DMLERR_INVALIDPARAMETER 0x4006 +#define DMLERR_LOW_MEMORY 0x4007 +#define DMLERR_MEMORY_ERROR 0x4008 +#define DMLERR_NOTPROCESSED 0x4009 +#define DMLERR_NO_CONV_ESTABLISHED 0x400a +#define DMLERR_POKEACKTIMEOUT 0x400b +#define DMLERR_POSTMSG_FAILED 0x400c +#define DMLERR_REENTRANCY 0x400d +#define DMLERR_SERVER_DIED 0x400e +#define DMLERR_SYS_ERROR 0x400f +#define DMLERR_UNADVACKTIMEOUT 0x4010 +#define DMLERR_UNFOUND_QUEUE_ID 0x4011 + +#define DMLERR_LAST 0x4011 + +HSZ DdeCreateStringHandle(ULONG idInst, PSZ pStr, int iCodePage); +ULONG DdeQueryString(ULONG idInst, HSZ hsz, PSZ pStr, ULONG cchMax, + int iCodePage); +BOOL DdeFreeStringHandle(ULONG idInst, HSZ hsz); +BOOL DdeKeepStringHandle(ULONG idInst, HSZ hsz); +int DdeCmpStringHandles(HSZ hsz1, HSZ hsz2); + + + +/* von OS/2 nicht unterstuetzte Win3.1 Clipboard-Formate */ + +#define CF_NOTSUPPORTED_BASE 0xff00 + +#ifndef CF_DIB +#define CF_DIB CF_NOTSUPPORTED_BASE+1 +#endif + +#ifndef CF_DIF +#define CF_DIF CF_NOTSUPPORTED_BASE+2 +#endif + +#ifndef CF_DSPMETAFILEPICT +#define CF_DSPMETAFILEPICT CF_NOTSUPPORTED_BASE+3 +#endif + +#ifndef CF_METAFILEPICT +#define CF_METAFILEPICT CF_NOTSUPPORTED_BASE+4 +#endif + +#ifndef CF_OEMTEXT +#define CF_OEMTEXT CF_NOTSUPPORTED_BASE+5 +#endif + +#ifndef CF_OWNERDISPLAY +#define CF_OWNERDISPLAY CF_NOTSUPPORTED_BASE+6 +#endif + +#ifndef CF_PENDATA +#define CF_PENDATA CF_NOTSUPPORTED_BASE+7 +#endif + +#ifndef CF_RIFF +#define CF_RIFF CF_NOTSUPPORTED_BASE+8 +#endif + +#ifndef CF_SYLK +#define CF_SYLK CF_NOTSUPPORTED_BASE+9 +#endif + +#ifndef CF_TIFF +#define CF_TIFF CF_NOTSUPPORTED_BASE+10 +#endif + +#ifndef CF_WAVE +#define CF_WAVE CF_NOTSUPPORTED_BASE+11 +#endif + + +#endif /* _DDEML_HXX */ diff --git a/svl/source/svdde/ddestrg.cxx b/svl/source/svdde/ddestrg.cxx new file mode 100644 index 000000000000..9cd594a7920d --- /dev/null +++ b/svl/source/svdde/ddestrg.cxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * 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: ddestrg.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define UNICODE + +#include "ddeimp.hxx" +#include <svl/svdde.hxx> + +#if defined( WIN ) && defined( MSC ) +#pragma code_seg( "SVDDE_MISC_CODE" ) +#endif + +// --- DdeString::DdeString() -------------------------------------- + +DdeString::DdeString( DWORD hDdeInst, const sal_Unicode* p ) : + String( p ) +{ + hString = DdeCreateStringHandle( hDdeInst, (LPTSTR)p, CP_WINUNICODE ); + hInst = hDdeInst; +} + +// --- DdeString::DdeString() -------------------------------------- + +DdeString::DdeString( DWORD hDdeInst, const String& r) : + String( r ) +{ + hString = DdeCreateStringHandle( hDdeInst, (LPTSTR)r.GetBuffer(), CP_WINUNICODE ); + hInst = hDdeInst; +} + +// --- DdeString::~DdeString() ------------------------------------- + +DdeString::~DdeString() +{ + if ( hString ) + DdeFreeStringHandle( hInst, hString ); +} + +// --- DdeString::operator==() ------------------------------------- + +int DdeString::operator==( HSZ h ) +{ + return( !DdeCmpStringHandles( hString, h ) ); +} + +// --- DdeString::operator HSZ() ----------------------------------- + +DdeString::operator HSZ() +{ + return hString; +} diff --git a/svl/source/svdde/ddesvr.cxx b/svl/source/svdde/ddesvr.cxx new file mode 100644 index 000000000000..ec718d4e56ee --- /dev/null +++ b/svl/source/svdde/ddesvr.cxx @@ -0,0 +1,1107 @@ +/************************************************************************* + * + * 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: ddesvr.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#define UNICODE +#include "ddeimp.hxx" +#include <svl/svdde.hxx> +#include <svl/svarray.hxx> +#include <tools/debug.hxx> +#include <osl/thread.h> + +//static long hCurConv = 0; +//static DWORD hDdeInst = NULL; +//static short nInstance = 0; +//static DdeServices* pServices; + +enum DdeItemType +{ + DDEITEM, + DDEGETPUTITEM +}; + +struct DdeItemImpData +{ + ULONG nHCnv; + USHORT nCnt; + + DdeItemImpData( ULONG nH ) : nHCnv( nH ), nCnt( 1 ) {} +}; + +SV_DECL_VARARR( DdeItemImp, DdeItemImpData, 1, 1 ) +SV_IMPL_VARARR( DdeItemImp, DdeItemImpData ) + +// --- DdeInternat::SvrCallback() ---------------------------------- + +#ifdef WNT +HDDEDATA CALLBACK DdeInternal::SvrCallback( + WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, + HDDEDATA hData, DWORD, DWORD ) +#else +#if defined ( MTW ) || ( defined ( GCC ) && defined ( OS2 )) || defined( ICC ) +HDDEDATA CALLBACK __EXPORT DdeInternal::SvrCallback( + WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, + HDDEDATA hData, DWORD, DWORD ) +#else +HDDEDATA CALLBACK _export DdeInternal::SvrCallback( + WORD nCode, WORD nCbType, HCONV hConv, HSZ hText1, HSZ hText2, + HDDEDATA hData, DWORD, DWORD ) +#endif +#endif +{ + DdeServices& rAll = DdeService::GetServices(); + DdeService* pService; + DdeTopic* pTopic; + DdeItem* pItem; + DdeData* pData; + Conversation* pC; + + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + + switch( nCode ) + { + case XTYP_WILDCONNECT: + { + int nTopics = 0; + +#if 1 + TCHAR chTopicBuf[250]; + if( hText1 ) + DdeQueryString( pInst->hDdeInstSvr, hText1, chTopicBuf, + sizeof(chTopicBuf)/sizeof(TCHAR), CP_WINUNICODE ); + + for( pService = rAll.First();pService;pService = rAll.Next() ) + { + if ( !hText2 || ( *pService->pName == hText2 ) ) + { + String sTopics( pService->Topics() ); + if( sTopics.Len() ) + { + if( hText1 ) + { + USHORT n = 0; + while( STRING_NOTFOUND != n ) + { + String s( sTopics.GetToken( 0, '\t', n )); + if( s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) ) + ++nTopics; + } + } + else + nTopics += sTopics.GetTokenCount( '\t' ); + } + } + } + +#else + for( pService = rAll.First();pService;pService = rAll.Next() ) + { + if ( !hText2 || ( *pService->pName == hText2 ) ) + { + for( pTopic = pService->aTopics.First(); pTopic; + pTopic = pService->aTopics.Next() ) + { + if ( !hText1 || (*pTopic->pName == hText1) ) + nTopics++; + } + } + } +#endif + if( !nTopics ) + return (HDDEDATA)NULL; + + HSZPAIR* pPairs = new HSZPAIR [nTopics + 1]; + if ( !pPairs ) + return (HDDEDATA)NULL; + + HSZPAIR* q = pPairs; + for( pService = rAll.First(); pService; pService = rAll.Next() ) + { + if ( !hText2 || (*pService->pName == hText2 ) ) + { +#if 0 + for ( pTopic = pService->aTopics.First(); pTopic; + pTopic = pService->aTopics.Next() ) + { + if ( !hText1 || (*pTopic->pName == hText1) ) + { + q->hszSvc = *pService->pName; + q->hszTopic = *pTopic->pName; + q++; + } + } +#else + String sTopics( pService->Topics() ); + USHORT n = 0; + while( STRING_NOTFOUND != n ) + { + String s( sTopics.GetToken( 0, '\t', n )); + s.EraseAllChars( '\n' ).EraseAllChars( '\r' ); + if( !hText1 || s == reinterpret_cast<const sal_Unicode*>(chTopicBuf) ) + { + DdeString aDStr( pInst->hDdeInstSvr, s ); + pTopic = FindTopic( *pService, (HSZ)aDStr ); + if( pTopic ) + { + q->hszSvc = *pService->pName; + q->hszTopic = *pTopic->pName; + q++; + } + } + } + +#endif + } + } + + q->hszSvc = NULL; + q->hszTopic = NULL; + HDDEDATA h = DdeCreateDataHandle( + pInst->hDdeInstSvr, (LPBYTE) pPairs, + sizeof(HSZPAIR) * (nTopics+1), + 0, NULL, nCbType, 0); + delete [] pPairs; + return h; + } + + case XTYP_CONNECT: + pService = FindService( hText2 ); + if ( pService) + pTopic = FindTopic( *pService, hText1 ); + else + pTopic = NULL; + if ( pTopic ) + return (HDDEDATA)DDE_FACK; + else + return (HDDEDATA) NULL; + + case XTYP_CONNECT_CONFIRM: + pService = FindService( hText2 ); + if ( pService ) + { + pTopic = FindTopic( *pService, hText1 ); + if ( pTopic ) + { + pTopic->Connect( (long) hConv ); + pC = new Conversation; + pC->hConv = hConv; + pC->pTopic = pTopic; + pService->pConv->Insert( pC ); + } + } + return (HDDEDATA)NULL; + } + + for ( pService = rAll.First(); pService; pService = rAll.Next() ) + { + for( pC = pService->pConv->First(); pC; + pC = pService->pConv->Next() ) + { + if ( pC->hConv == hConv ) + goto found; + } + } + + return (HDDEDATA) DDE_FNOTPROCESSED; + +found: + if ( nCode == XTYP_DISCONNECT) + { + pC->pTopic->_Disconnect( (long) hConv ); + pService->pConv->Remove( pC ); + delete pC; + return (HDDEDATA)NULL; + } + + BOOL bExec = BOOL(nCode == XTYP_EXECUTE); + pTopic = pC->pTopic; + if ( pTopic && !bExec ) + pItem = FindItem( *pTopic, hText2 ); + else + pItem = NULL; + + if ( !bExec && !pService->HasCbFormat( nCbType ) ) + pItem = NULL; + if ( !pItem && !bExec ) + return (HDDEDATA)DDE_FNOTPROCESSED; + if ( pItem ) + pTopic->aItem = pItem->GetName(); + else + pTopic->aItem.Erase(); + + BOOL bRes = FALSE; + pInst->hCurConvSvr = (long)hConv; + switch( nCode ) + { + case XTYP_REQUEST: + case XTYP_ADVREQ: + { + String aRes; // darf erst am Ende freigegeben werden!! + if ( pTopic->IsSystemTopic() ) + { + if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) + aRes = pService->Topics(); + else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) + aRes = pService->SysItems(); + else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) + aRes = pService->Status(); + else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) + aRes = pService->Formats(); + else if ( pTopic->aItem == reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) + aRes = pService->GetHelp(); + else + aRes = pService->SysTopicGet( pTopic->aItem ); + + if ( aRes.Len() ) + pData = new DdeData( aRes ); + else + pData = NULL; + } + else if( DDEGETPUTITEM == pItem->nType ) + pData = ((DdeGetPutItem*)pItem)->Get( + DdeData::GetInternalFormat( nCbType ) ); + else + pData = pTopic->Get( DdeData::GetInternalFormat( nCbType )); + + if ( pData ) + return DdeCreateDataHandle( pInst->hDdeInstSvr, + (LPBYTE)pData->pImp->pData, + pData->pImp->nData, + 0, hText2, + DdeData::GetExternalFormat( + pData->pImp->nFmt ), + 0 ); + } + break; + + case XTYP_POKE: + if ( !pTopic->IsSystemTopic() ) + { + DdeData d; + d.pImp->hData = hData; + d.pImp->nFmt = DdeData::GetInternalFormat( nCbType ); + d.Lock(); + if( DDEGETPUTITEM == pItem->nType ) + bRes = ((DdeGetPutItem*)pItem)->Put( &d ); + else + bRes = pTopic->Put( &d ); + } + pInst->hCurConvSvr = NULL; + if ( bRes ) + return (HDDEDATA)DDE_FACK; + else + return (HDDEDATA) DDE_FNOTPROCESSED; + + case XTYP_ADVSTART: + { + // wird das Item zum erstenmal ein HotLink ? + if( !pItem->pImpData && pTopic->StartAdviseLoop() ) + { + // dann wurde das Item ausgewechselt + pTopic->aItems.Remove( pItem ); + DdeItem* pTmp; + for( pTmp = pTopic->aItems.First(); pTmp; + pTmp = pTopic->aItems.Next() ) + if( *pTmp->pName == hText2 ) + { + // es wurde tatsaechlich ausgewechselt + delete pItem; + pItem = 0; + break; + } + if( pItem ) + // es wurde doch nicht ausgewechselt, also wieder rein + pTopic->aItems.Insert( pItem ); + else + pItem = pTmp; + } + pItem->IncMonitor( (long)hConv ); + pInst->hCurConvSvr = NULL; + } + return (HDDEDATA)TRUE; + + case XTYP_ADVSTOP: + pItem->DecMonitor( (long)hConv ); + if( !pItem->pImpData ) + pTopic->StopAdviseLoop(); + pInst->hCurConvSvr = NULL; + return (HDDEDATA)TRUE; + + case XTYP_EXECUTE: + { + DdeData aExec; + aExec.pImp->hData = hData; + aExec.pImp->nFmt = DdeData::GetInternalFormat( nCbType ); + aExec.Lock(); + String aName; + + aName = (const sal_Unicode *)aExec.pImp->pData; + + if( pTopic->IsSystemTopic() ) + bRes = pService->SysTopicExecute( &aName ); + else + bRes = pTopic->Execute( &aName ); + } + pInst->hCurConvSvr = NULL; + if ( bRes ) + return (HDDEDATA)DDE_FACK; + else + return (HDDEDATA)DDE_FNOTPROCESSED; + } + + return (HDDEDATA)NULL; +} + +// --- DdeInternat::FindService() ---------------------------------- + +DdeService* DdeInternal::FindService( HSZ hService ) +{ + DdeService* s; + DdeServices& rSvc = DdeService::GetServices(); + for ( s = rSvc.First(); s; s = rSvc.Next() ) + { + if ( *s->pName == hService ) + return s; + } + + return NULL; +} + +// --- DdeInternat::FindTopic() ------------------------------------ + +DdeTopic* DdeInternal::FindTopic( DdeService& rService, HSZ hTopic ) +{ + DdeTopic* s; + DdeTopics& rTopics = rService.aTopics; + int bWeiter = FALSE; + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + + do { // middle check loop + for ( s = rTopics.First(); s; s = rTopics.Next() ) + { + if ( *s->pName == hTopic ) + return s; + } + + bWeiter = !bWeiter; + if( !bWeiter ) + break; + + // dann befragen wir doch mal unsere Ableitung: + TCHAR chBuf[250]; + DdeQueryString(pInst->hDdeInstSvr,hTopic,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE ); + bWeiter = rService.MakeTopic( reinterpret_cast<const sal_Unicode*>(chBuf) ); + // dann muessen wir noch mal suchen + } while( bWeiter ); + + return 0; +} + +// --- DdeInternal::FindItem() ------------------------------------- + +DdeItem* DdeInternal::FindItem( DdeTopic& rTopic, HSZ hItem ) +{ + DdeItem* s; + DdeItems& rItems = rTopic.aItems; + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + int bWeiter = FALSE; + + do { // middle check loop + + for ( s = rItems.First(); s; s = rItems.Next() ) + if ( *s->pName == hItem ) + return s; + + bWeiter = !bWeiter; + if( !bWeiter ) + break; + + // dann befragen wir doch mal unsere Ableitung: + TCHAR chBuf[250]; + DdeQueryString(pInst->hDdeInstSvr,hItem,chBuf,sizeof(chBuf)/sizeof(TCHAR),CP_WINUNICODE ); + bWeiter = rTopic.MakeItem( reinterpret_cast<const sal_Unicode*>(chBuf) ); + // dann muessen wir noch mal suchen + } while( bWeiter ); + + return 0; +} + +// --- DdeService::DdeService() ------------------------------------ + +DdeService::DdeService( const String& rService ) +{ + DdeInstData* pInst = ImpGetInstData(); + if( !pInst ) + pInst = ImpInitInstData(); + pInst->nRefCount++; + pInst->nInstanceSvr++; + + if ( !pInst->hDdeInstSvr ) + { + nStatus = sal::static_int_cast< short >( + DdeInitialize( &pInst->hDdeInstSvr, + (PFNCALLBACK)DdeInternal::SvrCallback, + APPCLASS_STANDARD | + CBF_SKIP_REGISTRATIONS | + CBF_SKIP_UNREGISTRATIONS, 0L ) ); + pInst->pServicesSvr = new DdeServices; + } + else + nStatus = DMLERR_NO_ERROR; + + pConv = new ConvList; + + if ( pInst->pServicesSvr ) + pInst->pServicesSvr->Insert( this ); + + pName = new DdeString( pInst->hDdeInstSvr, rService ); + if ( nStatus == DMLERR_NO_ERROR ) + if ( !DdeNameService( pInst->hDdeInstSvr, *pName, NULL, + DNS_REGISTER | DNS_FILTEROFF ) ) + nStatus = DMLERR_SYS_ERROR; + + AddFormat( FORMAT_STRING ); + pSysTopic = new DdeTopic( reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) ); + pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_TOPICS) ) ); + pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_SYSITEMS) ) ); + pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_STATUS) ) ); + pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_FORMATS) ) ); + pSysTopic->AddItem( DdeItem( reinterpret_cast<const sal_Unicode*>(SZDDESYS_ITEM_HELP) ) ); + AddTopic( *pSysTopic ); +} + +// --- DdeService::~DdeService() ----------------------------------- + +DdeService::~DdeService() +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + if ( pInst->pServicesSvr ) + pInst->pServicesSvr->Remove( this ); + + // MT: Im Auftrage des Herrn (AM) auskommentiert... + // Grund: + // Bei Client/Server werden die Server nicht beendet, wenn mehr + // als einer gestartet. + // Weil keine System-Messagequeue ?! + + delete pSysTopic; + delete pName; + + pInst->nInstanceSvr--; + pInst->nRefCount--; + if ( !pInst->nInstanceSvr && pInst->hDdeInstSvr ) + { + if( DdeUninitialize( pInst->hDdeInstSvr ) ) + { + pInst->hDdeInstSvr = NULL; + delete pInst->pServicesSvr; + pInst->pServicesSvr = NULL; + if( pInst->nRefCount == 0) + ImpDeinitInstData(); + } + } + delete pConv; +} + +// --- DdeService::GetName() --------------------------------------- + +const String& DdeService::GetName() const +{ + return *pName; +} + +// --- DdeService::GetServices() ----------------------------------- + +DdeServices& DdeService::GetServices() +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + return *(pInst->pServicesSvr); +} + +// --- DdeService::AddTopic() -------------------------------------- + +void DdeService::AddTopic( const DdeTopic& rTopic ) +{ + RemoveTopic( rTopic ); + aTopics.Insert( (DdeTopic*) &rTopic ); +} + +// --- DdeService::RemoveTopic() ----------------------------------- + +void DdeService::RemoveTopic( const DdeTopic& rTopic ) +{ + DdeTopic* t; + for ( t = aTopics.First(); t; t = aTopics.Next() ) + { + if ( !DdeCmpStringHandles (*t->pName, *rTopic.pName ) ) + { + aTopics.Remove( t ); + // JP 27.07.95: und alle Conversions loeschen !!! + // (sonst wird auf geloeschten Topics gearbeitet!!) + for( ULONG n = pConv->Count(); n; ) + { + Conversation* pC = pConv->GetObject( --n ); + if( pC->pTopic == &rTopic ) + { + pConv->Remove( pC ); + delete pC; + } + } + break; + } + } +} + +// --- DdeService::HasCbFormat() ----------------------------------- + +BOOL DdeService::HasCbFormat( USHORT nFmt ) +{ + return BOOL( aFormats.GetPos( nFmt ) != LIST_ENTRY_NOTFOUND ); +} + +// --- DdeService::HasFormat() ------------------------------------- + +BOOL DdeService::HasFormat( ULONG nFmt ) +{ + return HasCbFormat( (USHORT)DdeData::GetExternalFormat( nFmt )); +} + +// --- DdeService::AddFormat() ------------------------------------- + +void DdeService::AddFormat( ULONG nFmt ) +{ + nFmt = DdeData::GetExternalFormat( nFmt ); + aFormats.Remove( nFmt ); + aFormats.Insert( nFmt ); +} + +// --- DdeService::RemoveFormat() ---------------------------------- + +void DdeService::RemoveFormat( ULONG nFmt ) +{ + aFormats.Remove( DdeData::GetExternalFormat( nFmt ) ); +} + +// --- DdeTopic::DdeTopic() ---------------------------------------- + +DdeTopic::DdeTopic( const String& rName ) +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + pName = new DdeString( pInst->hDdeInstSvr, rName ); +} + +// --- DdeTopic::~DdeTopic() --------------------------------------- + +DdeTopic::~DdeTopic() +{ + DdeItem* t; + while( ( t = aItems.First() ) != NULL ) + { + aItems.Remove( t ); + t->pMyTopic = 0; + delete t; + } + delete pName; +} + +// --- DdeTopic::GetName() ----------------------------------------- + +const String& DdeTopic::GetName() const +{ + return *pName; +} + +// --- DdeTopic::IsSystemTopic() ----------------------------------- + +BOOL DdeTopic::IsSystemTopic() +{ + return BOOL (GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC)); +} + +// --- DdeTopic::AddItem() ----------------------------------------- + +DdeItem* DdeTopic::AddItem( const DdeItem& r ) +{ + DdeItem* s; + if( DDEGETPUTITEM == r.nType ) + s = new DdeGetPutItem( r ); + else + s = new DdeItem( r ); + if ( s ) + { + aItems.Insert( s ); + s->pMyTopic = this; + } + return s; +} + +// --- DdeTopic::InsertItem() ----------------------------------------- + +void DdeTopic::InsertItem( DdeItem* pNew ) +{ + if( pNew ) + { + aItems.Insert( pNew ); + pNew->pMyTopic = this; + } +} + +// --- DdeTopic::RemoveItem() -------------------------------------- + +void DdeTopic::RemoveItem( const DdeItem& r ) +{ + DdeItem* s; + for ( s = aItems.First(); s; s = aItems.Next() ) + { + if ( !DdeCmpStringHandles (*s->pName, *r.pName ) ) + break; + } + + if ( s ) + { + aItems.Remove( s ); + s->pMyTopic = 0; + delete s; + } +} + +// --- DdeTopic::NotifyClient() ------------------------------------ + +void DdeTopic::NotifyClient( const String& rItem ) +{ + DdeItem* pItem; + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + for ( pItem = aItems.First(); pItem; pItem = aItems.Next() ) + { + if ( pItem->GetName() == rItem ) + { + if ( pItem->pImpData ) + DdePostAdvise( pInst->hDdeInstSvr, *pName, *pItem->pName ); + } + break; + } +} + +// --- DdeTopic::Connect() ----------------------------------------- + +void __EXPORT DdeTopic::Connect( long nId ) +{ + aConnectLink.Call( (void*)nId ); +} + +// --- DdeTopic::Disconnect() -------------------------------------- + +void __EXPORT DdeTopic::Disconnect( long nId ) +{ + aDisconnectLink.Call( (void*)nId ); +} + +// --- DdeTopic::_Disconnect() -------------------------------------- + +void __EXPORT DdeTopic::_Disconnect( long nId ) +{ + for( DdeItem* pItem = aItems.First(); pItem; pItem = aItems.Next() ) + pItem->DecMonitor( nId ); + + Disconnect( nId ); +} + +// --- DdeTopic::Get() --------------------------------------------- + +DdeData* __EXPORT DdeTopic::Get( ULONG nFmt ) +{ + if ( aGetLink.IsSet() ) + return (DdeData*)aGetLink.Call( (void*)nFmt ); + else + return NULL; +} + +// --- DdeTopic::Put() --------------------------------------------- + +BOOL __EXPORT DdeTopic::Put( const DdeData* r ) +{ + if ( aPutLink.IsSet() ) + return (BOOL)aPutLink.Call( (void*) r ); + else + return FALSE; +} + +// --- DdeTopic::Execute() ----------------------------------------- + +BOOL __EXPORT DdeTopic::Execute( const String* r ) +{ + if ( aExecLink.IsSet() ) + return (BOOL)aExecLink.Call( (void*)r ); + else + return FALSE; +} + +// --- DdeTopic::GetConvId() --------------------------------------- + +long DdeTopic::GetConvId() +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + return pInst->hCurConvSvr; +} + +// --- DdeTopic::StartAdviseLoop() --------------------------------- + +BOOL DdeTopic::StartAdviseLoop() +{ + return FALSE; +} + +// --- DdeTopic::StopAdviseLoop() ---------------------------------- + +BOOL DdeTopic::StopAdviseLoop() +{ + return FALSE; +} + +// --- DdeItem::DdeItem() ------------------------------------------ + +DdeItem::DdeItem( const sal_Unicode* p ) +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + pName = new DdeString( pInst->hDdeInstSvr, p ); + nType = DDEITEM; + pMyTopic = 0; + pImpData = 0; +} + +// --- DdeItem::DdeItem() ------------------------------------------ + +DdeItem::DdeItem( const String& r) +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + pName = new DdeString( pInst->hDdeInstSvr, r ); + nType = DDEITEM; + pMyTopic = 0; + pImpData = 0; +} + +// --- DdeItem::DdeItem() ------------------------------------------ + +DdeItem::DdeItem( const DdeItem& r) +{ + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + pName = new DdeString( pInst->hDdeInstSvr, *r.pName ); + nType = DDEITEM; + pMyTopic = 0; + pImpData = 0; +} + +// --- DdeItem::~DdeItem() ----------------------------------------- + +DdeItem::~DdeItem() +{ + if( pMyTopic ) + pMyTopic->aItems.Remove( this ); + delete pName; + delete pImpData; +} + +// --- DdeItem::GetName() ------------------------------------------ + +const String& DdeItem::GetName() const +{ + return *pName; +} + +// --- DdeItem::NotifyClient() ------------------------------------------ + +void DdeItem::NotifyClient() +{ + if( pMyTopic && pImpData ) + { + DdeInstData* pInst = ImpGetInstData(); + DBG_ASSERT(pInst,"SVDDE:No instance data"); + DdePostAdvise( pInst->hDdeInstSvr, *pMyTopic->pName, *pName ); + } +} + +// --- DdeItem::IncMonitor() ------------------------------------------ + +void DdeItem::IncMonitor( ULONG nHCnv ) +{ + if( !pImpData ) + { + pImpData = new DdeItemImp; + if( DDEGETPUTITEM == nType ) + ((DdeGetPutItem*)this)->AdviseLoop( TRUE ); + } + else + { + for( USHORT n = pImpData->Count(); n; ) + if( (*pImpData)[ --n ].nHCnv == nHCnv ) + { + ++(*pImpData)[ n ].nHCnv; + return ; + } + } + + pImpData->Insert( DdeItemImpData( nHCnv ), pImpData->Count() ); +} + +// --- DdeItem::DecMonitor() ------------------------------------------ + +void DdeItem::DecMonitor( ULONG nHCnv ) +{ + if( pImpData ) + { + DdeItemImpData* pData = (DdeItemImpData*)pImpData->GetData(); + for( USHORT n = pImpData->Count(); n; --n, ++pData ) + if( pData->nHCnv == nHCnv ) + { + if( !pData->nCnt || !--pData->nCnt ) + { + if( 1 < pImpData->Count() ) + pImpData->Remove( pImpData->Count() - n ); + else + { + delete pImpData, pImpData = 0; + if( DDEGETPUTITEM == nType ) + ((DdeGetPutItem*)this)->AdviseLoop( FALSE ); + } + } + return ; + } + } +} + +// --- DdeItem::GetLinks() ------------------------------------------ + +short DdeItem::GetLinks() +{ + short nCnt = 0; + if( pImpData ) + for( USHORT n = pImpData->Count(); n; ) + nCnt = nCnt + (*pImpData)[ --n ].nCnt; + return nCnt; +} + +// --- DdeGetPutItem::DdeGetPutItem() ------------------------------ + +DdeGetPutItem::DdeGetPutItem( const sal_Unicode* p ) + : DdeItem( p ) +{ + nType = DDEGETPUTITEM; +} + +// --- DdeGetPutItem::DdeGetPutItem() ------------------------------ + +DdeGetPutItem::DdeGetPutItem( const String& rStr ) + : DdeItem( rStr ) +{ + nType = DDEGETPUTITEM; +} + +// --- DdeGetPutItem::DdeGetPutItem() ------------------------------ + +DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem ) + : DdeItem( rItem ) +{ + nType = DDEGETPUTITEM; +} + + +// --- DdeGetPutData::Get() ---------------------------------------- + +DdeData* DdeGetPutItem::Get( ULONG ) +{ + return 0; +} + +// --- DdeGetPutData::Put() ---------------------------------------- + +BOOL DdeGetPutItem::Put( const DdeData* ) +{ + return FALSE; +} + +// --- DdeGetPutData::AdviseLoop() --------------------------------- + +void DdeGetPutItem::AdviseLoop( BOOL ) +{ +} + + +// --- DdeService::SysItems() -------------------------------------- + +String DdeService::SysItems() +{ + String s; + DdeTopic* t; + for ( t = aTopics.First(); t; t = aTopics.Next() ) + { + if ( t->GetName() == reinterpret_cast<const sal_Unicode*>(SZDDESYS_TOPIC) ) + { + short n = 0; + DdeItem* pi; + for ( pi = t->aItems.First(); pi; pi = t->aItems.Next(), n++ ) + { + if ( n ) + s += '\t'; + s += pi->GetName(); + } + s += String::CreateFromAscii("\r\n"); + } + } + + return s; +} + +// --- DdeService::Topics() ---------------------------------------- + +String DdeService::Topics() +{ + String s; + DdeTopic* t; + short n = 0; + + for ( t = aTopics.First(); t; t = aTopics.Next(), n++ ) + { + if ( n ) + s += '\t'; + s += t->GetName(); + } + s += String::CreateFromAscii("\r\n"); + + return s; +} + +// --- DdeService::Formats() --------------------------------------- + +String DdeService::Formats() +{ + String s; + long f; + TCHAR buf[128]; + LPCTSTR p; + short n = 0; + + for ( f = aFormats.First(); f; f = aFormats.Next(), n++ ) + { + if ( n ) + s += '\t'; + p = buf; + + switch( (USHORT)f ) + { + case CF_TEXT: + p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("TEXT").GetBuffer()); + break; + case CF_BITMAP: + p = reinterpret_cast<LPCTSTR>(String::CreateFromAscii("BITMAP").GetBuffer()); + break; +#ifdef OS2 + case CF_DSPTEXT: + p = String::CreateFromAscii("TEXT").GetBuffer(); + break; + case CF_DSPBITMAP: + p = String::CreateFromAscii("BITMAP").GetBuffer(); + break; + case CF_METAFILE: + p = String::CreateFromAscii("METAFILE").GetBuffer(); + break; + case CF_DSPMETAFILE: + p = String::CreateFromAscii("METAFILE").GetBuffer(); + break; + case CF_PALETTE: + p = String::CreateFromAscii("PALETTE").GetBuffer(); + break; + default: + p= String::CreateFromAscii("PRIVATE").GetBuffer(); +#else + default: + GetClipboardFormatName( (UINT)f, buf, sizeof(buf) / sizeof(TCHAR) ); +#endif + } + s += String( reinterpret_cast<const sal_Unicode*>(p) ); + } + s += String::CreateFromAscii("\r\n"); + + return s; +} + +// --- DdeService::Status() ---------------------------------------- + +String DdeService::Status() +{ + return IsBusy() ? String::CreateFromAscii("Busy\r\n") : String::CreateFromAscii("Ready\r\n"); +} + +// --- DdeService::IsBusy() ---------------------------------------- + +BOOL __EXPORT DdeService::IsBusy() +{ + return FALSE; +} + +// --- DdeService::GetHelp() ---------------------------------------- + +String __EXPORT DdeService::GetHelp() +{ + return String(); +} + +BOOL DdeTopic::MakeItem( const String& ) +{ + return FALSE; +} + +BOOL DdeService::MakeTopic( const String& ) +{ + return FALSE; +} + +String DdeService::SysTopicGet( const String& ) +{ + return String(); +} + +BOOL DdeService::SysTopicExecute( const String* ) +{ + return FALSE; +} + diff --git a/svl/source/svdde/ddewrap.cxx b/svl/source/svdde/ddewrap.cxx new file mode 100644 index 000000000000..650ec5b1b31f --- /dev/null +++ b/svl/source/svdde/ddewrap.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * 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: ddewrap.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#define _SVTOOLS_SVDDE_DDEWRAP_CXX_ + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "ddewrap.hxx" + +//------------------------------------------------------------------------ + +HSZ WINAPI DdeCreateStringHandleW_9x( DWORD idInst, LPCWSTR pszString, int ) +{ + HSZ hszResult; + LPSTR pszANSIString; + int nSize; + + nSize = pszString ? WideCharToMultiByte( CP_ACP, 0, pszString, -1, NULL, 0, NULL, NULL ) : 0; + pszANSIString = nSize ? (LPSTR)HeapAlloc( GetProcessHeap(), 0, nSize * sizeof(CHAR) ) : NULL; + + if ( pszANSIString ) + WideCharToMultiByte( CP_ACP, 0, pszString, -1, pszANSIString, nSize, NULL, NULL ); + + hszResult = DdeCreateStringHandleA( idInst, pszANSIString, CP_WINANSI ); + + if ( pszANSIString ) + HeapFree( GetProcessHeap(), 0, pszANSIString ); + + return hszResult; +} + +//------------------------------------------------------------------------ + +DWORD WINAPI DdeQueryStringW_9x( DWORD idInst, HSZ hsz, LPWSTR pszString, DWORD cchMax, int ) +{ + DWORD dwResult; + LPSTR pszANSIString; + + pszANSIString = cchMax ? (LPSTR)HeapAlloc( GetProcessHeap(), 0, cchMax * sizeof(CHAR) ) : NULL; + + dwResult = DdeQueryStringA( idInst, hsz, pszANSIString, cchMax, CP_WINANSI ); + + if ( dwResult && pszANSIString ) + MultiByteToWideChar( CP_ACP, 0, pszANSIString, -1, pszString, cchMax ); + + if ( pszANSIString ) + HeapFree( GetProcessHeap(), 0, pszANSIString ); + + return dwResult; +} + +//------------------------------------------------------------------------ + +UINT WINAPI DdeInitializeW_9x( LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes ) +{ + return DdeInitializeA( pidInst, pfnCallback, afCmd, ulRes ); +} + +//------------------------------------------------------------------------ + +#define DEFINE_WAPI_FUNC(func) \ +func##_PROC lpfn##func = (LONG)GetVersion() >= 0 ? func : func##_9x; + + +DEFINE_WAPI_FUNC( DdeCreateStringHandleW ); +DEFINE_WAPI_FUNC( DdeQueryStringW ); +DEFINE_WAPI_FUNC( DdeInitializeW ); + diff --git a/svl/source/svdde/ddewrap.hxx b/svl/source/svdde/ddewrap.hxx new file mode 100644 index 000000000000..77d012ccbba5 --- /dev/null +++ b/svl/source/svdde/ddewrap.hxx @@ -0,0 +1,24 @@ +#ifndef _SVTOOLS_SVDDE_DDEWRAP_HXX_ +#define _SVTOOLS_SVDDE_DDEWRAP_HXX_ + +#define DECLARE_WAPI_FUNC(func) \ + extern func##_PROC lpfn##func; + +typedef HSZ (WINAPI *DdeCreateStringHandleW_PROC)( DWORD idInst, LPCWSTR pszString, int iCodePage ); +typedef DWORD (WINAPI *DdeQueryStringW_PROC)( DWORD idInst, HSZ hsz, LPWSTR pszString, DWORD cchMax, int iCodePage ); +typedef UINT (WINAPI *DdeInitializeW_PROC)( LPDWORD pidInst, PFNCALLBACK pfnCallback, DWORD afCmd, DWORD ulRes ); + + +DECLARE_WAPI_FUNC( DdeCreateStringHandleW ); +DECLARE_WAPI_FUNC( DdeQueryStringW ); +DECLARE_WAPI_FUNC( DdeInitializeW ); + + +#ifndef _SVTOOLS_SVDDE_DDEWRAP_CXX_ +#define DdeCreateStringHandleW lpfnDdeCreateStringHandleW +#define DdeQueryStringW lpfnDdeQueryStringW +#define DdeInitializeW lpfnDdeInitializeW +#endif + + +#endif diff --git a/svl/source/svdde/makefile.mk b/svl/source/svdde/makefile.mk new file mode 100644 index 000000000000..321a4b5ced03 --- /dev/null +++ b/svl/source/svdde/makefile.mk @@ -0,0 +1,64 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.10 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + + +.IF "$(GUIBASE)"=="WIN" + +PRJ=..$/.. + +PRJNAME=svl +TARGET=svdde + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + + +SLOFILES= $(SLO)$/ddecli.obj \ + $(SLO)$/ddesvr.obj \ + $(SLO)$/ddedata.obj \ + $(SLO)$/ddestrg.obj \ + $(SLO)$/ddewrap.obj \ + $(SLO)$/ddeinf.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.ELSE +dummy: + @echo GUI == "$(GUI)" - nothing to do + +.ENDIF + diff --git a/svl/source/svsql/converter.cxx b/svl/source/svsql/converter.cxx new file mode 100644 index 000000000000..826b64adc48d --- /dev/null +++ b/svl/source/svsql/converter.cxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * 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: converter.cxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "converter.hxx" + +INT32 SvDbaseConverter::ConvertPrecisionToDbase(INT32 _nLen, INT32 _nScale) +{ + return _nScale ? _nLen +2 : _nLen +1; +} +//------------------------------------------------------------------------ +INT32 SvDbaseConverter::ConvertPrecisionToOdbc(INT32 _nLen, INT32 _nScale) +{ + return _nScale ? _nLen -2 : _nLen -1; +} + + diff --git a/svl/source/svsql/makefile.mk b/svl/source/svsql/makefile.mk new file mode 100644 index 000000000000..ae3abf24db24 --- /dev/null +++ b/svl/source/svsql/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.6 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=svsql + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/converter.obj + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/undo/makefile.mk b/svl/source/undo/makefile.mk new file mode 100644 index 000000000000..7c51df3f17fc --- /dev/null +++ b/svl/source/undo/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.5 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=undo +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/undo.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx new file mode 100644 index 000000000000..a8442098237e --- /dev/null +++ b/svl/source/undo/undo.cxx @@ -0,0 +1,819 @@ +/************************************************************************* + * + * 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: undo.cxx,v $ + * $Revision: 1.11 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <com/sun/star/uno/Exception.hpp> + +#include <tools/debug.hxx> + +#include <svl/undo.hxx> + +using ::com::sun::star::uno::Exception; + +// STATIC DATA ----------------------------------------------------------- + +DBG_NAME(SfxUndoAction) + +//======================================================================== + +TYPEINIT0(SfxUndoAction); +TYPEINIT0(SfxListUndoAction); +TYPEINIT0(SfxLinkUndoAction); +TYPEINIT0(SfxRepeatTarget); + +//------------------------------------------------------------------------ + +SfxRepeatTarget::~SfxRepeatTarget() +{ +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoAction::IsLinked() +{ + return bLinked; +} + +//------------------------------------------------------------------------ + +void SfxUndoAction::SetLinked( BOOL bIsLinked ) +{ + bLinked = bIsLinked; +} + +//------------------------------------------------------------------------ + +SfxUndoAction::~SfxUndoAction() +{ + DBG_DTOR(SfxUndoAction, 0); + DBG_ASSERT( !IsLinked(), "Gelinkte Action geloescht" ); +} + + +SfxUndoAction::SfxUndoAction() +{ + DBG_CTOR(SfxUndoAction, 0); + SetLinked( FALSE ); +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoAction::Merge( SfxUndoAction * ) +{ + DBG_CHKTHIS(SfxUndoAction, 0); + return FALSE; +} + +//------------------------------------------------------------------------ + +XubString SfxUndoAction::GetComment() const +{ + DBG_CHKTHIS(SfxUndoAction, 0); + return XubString(); +} + +//------------------------------------------------------------------------ + + +USHORT SfxUndoAction::GetId() const +{ + DBG_CHKTHIS(SfxUndoAction, 0); + return 0; +} + +//------------------------------------------------------------------------ + +XubString SfxUndoAction::GetRepeatComment(SfxRepeatTarget&) const +{ + DBG_CHKTHIS(SfxUndoAction, 0); + return GetComment(); +} + +//------------------------------------------------------------------------ + + +void SfxUndoAction::Undo() +{ + // die sind nur konzeptuell pure virtual + DBG_ERROR( "pure virtual function called: SfxUndoAction::Undo()" ); +} + +//------------------------------------------------------------------------ + +void SfxUndoAction::Redo() +{ + // die sind nur konzeptuell pure virtual + DBG_ERROR( "pure virtual function called: SfxUndoAction::Redo()" ); +} + +//------------------------------------------------------------------------ + +void SfxUndoAction::Repeat(SfxRepeatTarget&) +{ + // die sind nur konzeptuell pure virtual + DBG_ERROR( "pure virtual function called: SfxUndoAction::Repeat()" ); +} + +//------------------------------------------------------------------------ + + +BOOL SfxUndoAction::CanRepeat(SfxRepeatTarget&) const +{ + return TRUE; +} + +//======================================================================== + + +SfxUndoManager::SfxUndoManager( USHORT nMaxUndoActionCount ) + : pFatherUndoArray(0) + , mbUndoEnabled( true ) +{ + pUndoArray=new SfxUndoArray(nMaxUndoActionCount); + pActUndoArray=pUndoArray; + +} + +//------------------------------------------------------------------------ + + +SfxUndoManager::~SfxUndoManager() +{ + delete pUndoArray; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::EnableUndo( bool bEnable ) +{ + mbUndoEnabled = bEnable; +} + +//------------------------------------------------------------------------ + + +void SfxUndoManager::SetMaxUndoActionCount( USHORT nMaxUndoActionCount ) +{ + // Remove entries from the pActUndoArray when we have to reduce + // the number of entries due to a lower nMaxUndoActionCount. + // Both redo and undo action entries will be removed until we reached the + // new nMaxUndoActionCount. + + long nNumToDelete = pActUndoArray->aUndoActions.Count() - nMaxUndoActionCount; + if ( nNumToDelete > 0 ) + { + while ( nNumToDelete > 0 ) + { + USHORT nPos = pActUndoArray->aUndoActions.Count(); + if ( nPos > pActUndoArray->nCurUndoAction ) + { + if ( !pActUndoArray->aUndoActions[nPos-1]->IsLinked() ) + { + delete pActUndoArray->aUndoActions[nPos-1]; + pActUndoArray->aUndoActions.Remove( nPos-1 ); + --nNumToDelete; + } + } + + if ( nNumToDelete > 0 && pActUndoArray->nCurUndoAction > 0 ) + { + if ( !pActUndoArray->aUndoActions[0]->IsLinked() ) + { + delete pActUndoArray->aUndoActions[0]; + pActUndoArray->aUndoActions.Remove(0); + --pActUndoArray->nCurUndoAction; + --nNumToDelete; + } + } + + if ( nPos == pActUndoArray->aUndoActions.Count() ) + break; // Cannot delete more entries + } + } + + pActUndoArray->nMaxUndoActions = nMaxUndoActionCount; +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetMaxUndoActionCount() const +{ + return pActUndoArray->nMaxUndoActions; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::Clear() +{ + while ( pActUndoArray->aUndoActions.Count() ) + { + SfxUndoAction *pAction= + pActUndoArray->aUndoActions[pActUndoArray->aUndoActions.Count() - 1]; + pActUndoArray->aUndoActions.Remove( pActUndoArray->aUndoActions.Count() - 1 ); + delete pAction; + } + + pActUndoArray->nCurUndoAction = 0; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::ClearRedo() +{ + while ( pActUndoArray->aUndoActions.Count() > pActUndoArray->nCurUndoAction ) + { + SfxUndoAction *pAction= + pActUndoArray->aUndoActions[pActUndoArray->aUndoActions.Count() - 1]; + pActUndoArray->aUndoActions.Remove( pActUndoArray->aUndoActions.Count() - 1 ); + delete pAction; + } +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerge ) +{ + if( mbUndoEnabled ) + { + // Redo-Actions loeschen + for ( USHORT nPos = pActUndoArray->aUndoActions.Count(); + nPos > pActUndoArray->nCurUndoAction; --nPos ) + delete pActUndoArray->aUndoActions[nPos-1]; + + pActUndoArray->aUndoActions.Remove( + pActUndoArray->nCurUndoAction, + pActUndoArray->aUndoActions.Count() - pActUndoArray->nCurUndoAction ); + + if ( pActUndoArray->nMaxUndoActions ) + { + SfxUndoAction *pTmpAction = pActUndoArray->nCurUndoAction ? + pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction-1] : 0; + + if ( !bTryMerge || !(pTmpAction && pTmpAction->Merge(pAction)) ) + { + // auf Max-Anzahl anpassen + if( pActUndoArray == pUndoArray ) + while( pActUndoArray->aUndoActions.Count() >= + pActUndoArray->nMaxUndoActions && + !pActUndoArray->aUndoActions[0]->IsLinked() ) + { + delete pActUndoArray->aUndoActions[0]; + pActUndoArray->aUndoActions.Remove(0); + --pActUndoArray->nCurUndoAction; + } + + // neue Action anh"angen + const SfxUndoAction* pTemp = pAction; + pActUndoArray->aUndoActions.Insert( + pTemp, pActUndoArray->nCurUndoAction++ ); + return; + } + } + } + delete pAction; +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetUndoActionCount() const +{ + return pActUndoArray->nCurUndoAction; +} + +//------------------------------------------------------------------------ + +XubString SfxUndoManager::GetUndoActionComment( USHORT nNo ) const +{ + DBG_ASSERT( nNo < pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoActionComment(), illegal id!" ); + if( nNo < pActUndoArray->nCurUndoAction ) + { + return pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction-1-nNo]->GetComment(); //! + } + else + { + XubString aEmpty; + return aEmpty; + } +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetUndoActionId( USHORT nNo ) const +{ + DBG_ASSERT( nNo < pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoActionId(), illegal id!" ); + if( nNo < pActUndoArray->nCurUndoAction ) + { + return pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction-1-nNo]->GetId(); //! + } + else + { + return 0; + } +} + +//------------------------------------------------------------------------ + +SfxUndoAction* SfxUndoManager::GetUndoAction( USHORT nNo ) const +{ + DBG_ASSERT( nNo < pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::GetUndoAction(), illegal id!" ); + if( nNo < pActUndoArray->nCurUndoAction ) + { + return pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction-1-nNo]; //! + } + else + { + return 0; + } +} + +//------------------------------------------------------------------------ + +/** clears the redo stack and removes the top undo action */ +void SfxUndoManager::RemoveLastUndoAction() +{ + DBG_ASSERT( pActUndoArray->nCurUndoAction, "svl::SfxUndoManager::RemoveLastUndoAction(), no action to remove?!" ); + if( pActUndoArray->nCurUndoAction ) + { + pActUndoArray->nCurUndoAction--; + + // delete redo-actions and top action + USHORT nPos; + for ( nPos = pActUndoArray->aUndoActions.Count(); nPos > pActUndoArray->nCurUndoAction; --nPos ) + delete pActUndoArray->aUndoActions[nPos-1]; + + pActUndoArray->aUndoActions.Remove( + pActUndoArray->nCurUndoAction, + pActUndoArray->aUndoActions.Count() - pActUndoArray->nCurUndoAction ); + } +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoManager::Undo( USHORT ) +{ + bool bUndoWasEnabled = mbUndoEnabled; + mbUndoEnabled = false; + + BOOL bRet = FALSE; + + try + { + DBG_ASSERT( pActUndoArray == pUndoArray, "svl::SfxUndoManager::Undo(), LeaveListAction() not yet called!" ); + if ( pActUndoArray->nCurUndoAction ) + { + Undo( *pActUndoArray->aUndoActions[ --pActUndoArray->nCurUndoAction ] ); + bRet = TRUE; + } + } + catch( Exception& e ) + { + mbUndoEnabled = bUndoWasEnabled; + throw e; + } + mbUndoEnabled = bUndoWasEnabled; + return bRet; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::Undo( SfxUndoAction &rAction ) +{ + bool bUndoWasEnabled = mbUndoEnabled; + mbUndoEnabled = false; + try + { + rAction.Undo(); + } + catch( Exception& e ) + { + mbUndoEnabled = bUndoWasEnabled; + throw e; + } + + mbUndoEnabled = bUndoWasEnabled; +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetRedoActionCount() const +{ + return pActUndoArray->aUndoActions.Count() - pActUndoArray->nCurUndoAction; //! +} + +//------------------------------------------------------------------------ + +XubString SfxUndoManager::GetRedoActionComment( USHORT nNo ) const +{ + return pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction+nNo]->GetComment(); //! +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetRedoActionId( USHORT nNo ) const +{ + return pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction+nNo]->GetId(); //! +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoManager::Redo( USHORT ) +{ + bool bUndoWasEnabled = mbUndoEnabled; + mbUndoEnabled = false; + + BOOL bRet = FALSE; + + try + { + if ( pActUndoArray->aUndoActions.Count() > pActUndoArray->nCurUndoAction ) + { + Redo( *pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction++] ); + bRet = TRUE; + } + } + catch( Exception& e ) + { + mbUndoEnabled = bUndoWasEnabled; + throw e; + } + + mbUndoEnabled = bUndoWasEnabled; + return bRet; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::Redo( SfxUndoAction &rAction ) +{ + bool bUndoWasEnabled = mbUndoEnabled; + mbUndoEnabled = false; + + try + { + rAction.Redo(); + } + catch( Exception& e ) + { + mbUndoEnabled = bUndoWasEnabled; + throw e; + } + + mbUndoEnabled = bUndoWasEnabled; +} + +//------------------------------------------------------------------------ + +USHORT SfxUndoManager::GetRepeatActionCount() const +{ + return pActUndoArray->aUndoActions.Count(); +} + +//------------------------------------------------------------------------ + +XubString SfxUndoManager::GetRepeatActionComment( SfxRepeatTarget &rTarget, USHORT nNo ) const +{ + return pActUndoArray->aUndoActions[ pActUndoArray->aUndoActions.Count() - 1 - nNo ] + ->GetRepeatComment(rTarget); +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoManager::Repeat( SfxRepeatTarget &rTarget, USHORT /*nFrom*/, USHORT /*nCount*/ ) +{ + if ( pActUndoArray->aUndoActions.Count() ) + { + Repeat( rTarget, *pActUndoArray->aUndoActions[ pActUndoArray->aUndoActions.Count() - 1 ] ); + return TRUE; + } + + return FALSE; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::Repeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction ) +{ + if ( rAction.CanRepeat(rTarget) ) + rAction.Repeat(rTarget); +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoManager::CanRepeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction ) const +{ + return rAction.CanRepeat(rTarget); +} + +//------------------------------------------------------------------------ + +BOOL SfxUndoManager::CanRepeat( SfxRepeatTarget &rTarget, USHORT nNo ) const +{ + if ( pActUndoArray->aUndoActions.Count() > nNo ) + { + USHORT nActionNo = pActUndoArray->aUndoActions.Count() - 1 - nNo; + return pActUndoArray->aUndoActions[nActionNo]->CanRepeat(rTarget); + } + + return FALSE; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::EnterListAction( + const XubString& rComment, const XubString &rRepeatComment, USHORT nId ) + +/* [Beschreibung] + + Fuegt eine ListUndoAction ein und setzt dessen UndoArray als aktuelles. +*/ + +{ + if( !mbUndoEnabled ) + return; + + if ( !pUndoArray->nMaxUndoActions ) + return; + + pFatherUndoArray=pActUndoArray; + SfxListUndoAction *pAction=new SfxListUndoAction( + rComment, rRepeatComment, nId, pActUndoArray); + AddUndoAction( pAction ); + pActUndoArray=pAction; +} + +//------------------------------------------------------------------------ + +void SfxUndoManager::LeaveListAction() + +/* [Beschreibung] + + Verlaesst die aktuelle ListAction und geht eine Ebene nach oben. +*/ +{ + if ( !mbUndoEnabled ) + return; + + if ( !pUndoArray->nMaxUndoActions ) + return; + + if( pActUndoArray == pUndoArray ) + { + DBG_ERROR( "svl::SfxUndoManager::LeaveListAction(), called without calling EnterListAction()!" ); + return; + } + + DBG_ASSERT(pActUndoArray->pFatherUndoArray,"svl::SfxUndoManager::LeaveListAction(), no father undo array!?"); + + SfxUndoArray* pTmp=pActUndoArray; + pActUndoArray=pActUndoArray->pFatherUndoArray; + + // If no undo action where added, delete the undo list action + SfxUndoAction *pTmpAction= pActUndoArray->aUndoActions[pActUndoArray->nCurUndoAction-1]; + if(!pTmp->nCurUndoAction) + { + pActUndoArray->aUndoActions.Remove( --pActUndoArray->nCurUndoAction); + delete pTmpAction; + } + else + { + // if the undo array has no comment, try to get it from its children + SfxListUndoAction* pList = dynamic_cast< SfxListUndoAction * >( pTmpAction ); + if( pList && pList->GetComment().Len() == 0 ) + { + USHORT n; + for( n = 0; n < pList->aUndoActions.Count(); n++ ) + { + if( pList->aUndoActions[n]->GetComment().Len() ) + { + pList->SetComment( pList->aUndoActions[n]->GetComment() ); + break; + } + } + } + } +} + +//------------------------------------------------------------------------ + +USHORT SfxListUndoAction::GetId() const +{ + return nId; +} + +//------------------------------------------------------------------------ + +XubString SfxListUndoAction::GetComment() const +{ + return aComment; +} + +//------------------------------------------------------------------------ + +void SfxListUndoAction::SetComment( const UniString& rComment ) +{ + aComment = rComment; +} + +//------------------------------------------------------------------------ + +XubString SfxListUndoAction::GetRepeatComment(SfxRepeatTarget &) const +{ + return aRepeatComment; +} + + +//------------------------------------------------------------------------ + +SfxListUndoAction::SfxListUndoAction +( + const XubString &rComment, + const XubString rRepeatComment, + USHORT Id, + SfxUndoArray *pFather +) +: nId(Id), aComment(rComment), aRepeatComment(rRepeatComment) +{ + pFatherUndoArray = pFather; + nMaxUndoActions = USHRT_MAX; +} + +//------------------------------------------------------------------------ + +void SfxListUndoAction::Undo() +{ + for(INT16 i=nCurUndoAction-1;i>=0;i--) + aUndoActions[i]->Undo(); + nCurUndoAction=0; +} + +//------------------------------------------------------------------------ + +void SfxListUndoAction::Redo() +{ + for(USHORT i=nCurUndoAction;i<aUndoActions.Count();i++) + aUndoActions[i]->Redo(); + nCurUndoAction = aUndoActions.Count(); +} + +//------------------------------------------------------------------------ + +void SfxListUndoAction::Repeat(SfxRepeatTarget&rTarget) +{ + for(USHORT i=0;i<nCurUndoAction;i++) + aUndoActions[i]->Repeat(rTarget); +} + +//------------------------------------------------------------------------ + +BOOL SfxListUndoAction::CanRepeat(SfxRepeatTarget&r) const +{ + for(USHORT i=0;i<nCurUndoAction;i++) + if(!aUndoActions[i]->CanRepeat(r)) + return FALSE; + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL SfxListUndoAction::Merge( SfxUndoAction *pNextAction ) +{ + return aUndoActions.Count() && aUndoActions[aUndoActions.Count()-1]->Merge( pNextAction ); +} + +//------------------------------------------------------------------------ + +SfxLinkUndoAction::SfxLinkUndoAction(SfxUndoManager *pManager) +/* [Beschreibung] + + Richtet eine LinkAction ein, die auf einen weiteren UndoManager zeigt. + Holt sich als zugehoerige Action des weiteren UndoManagers dessen + aktuelle Action. +*/ + +{ + pUndoManager = pManager; + if ( pManager->GetMaxUndoActionCount() ) + { + USHORT nPos = pManager->GetUndoActionCount()-1; + pAction = pManager->pActUndoArray->aUndoActions[nPos]; + pAction->SetLinked(); + } + else + pAction = 0; +} + +//------------------------------------------------------------------------ + +void SfxLinkUndoAction::Undo() +{ + if ( pAction ) + pUndoManager->Undo(1); +} + +//------------------------------------------------------------------------ + +void SfxLinkUndoAction::Redo() +{ + if ( pAction ) + pUndoManager->Redo(1); +} + +//------------------------------------------------------------------------ + + +BOOL SfxLinkUndoAction::CanRepeat(SfxRepeatTarget& r) const +{ + return pAction && pUndoManager->CanRepeat(r,*pAction); +} + + +//------------------------------------------------------------------------ + + +void SfxLinkUndoAction::Repeat(SfxRepeatTarget&r) +{ + if ( pAction ) + pUndoManager->Repeat(r,*pAction); +} + + +//------------------------------------------------------------------------ + +XubString SfxLinkUndoAction::GetComment() const +{ + if ( pAction ) + return pAction->GetComment(); + else + return XubString(); +} + + +//------------------------------------------------------------------------ + +XubString SfxLinkUndoAction::GetRepeatComment(SfxRepeatTarget&r) const +{ + if ( pAction ) + return pAction->GetRepeatComment(r); + else + return XubString(); +} + +//------------------------------------------------------------------------ + +SfxLinkUndoAction::~SfxLinkUndoAction() +{ + if( pAction ) + pAction->SetLinked( FALSE ); +} + + +//------------------------------------------------------------------------ + +SfxUndoArray::~SfxUndoArray() +{ + while ( aUndoActions.Count() ) + { + SfxUndoAction *pAction = + aUndoActions[ aUndoActions.Count() - 1 ]; + aUndoActions.Remove( aUndoActions.Count() - 1 ); + delete pAction; + } +} + + +USHORT SfxLinkUndoAction::GetId() const +{ + return pAction ? pAction->GetId() : 0; +} + + + diff --git a/svl/source/uno/makefile.mk b/svl/source/uno/makefile.mk new file mode 100644 index 000000000000..af26b20cd8df --- /dev/null +++ b/svl/source/uno/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.21 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=svl +TARGET=unoiface +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/registerservices.obj\ + $(SLO)$/pathservice.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/svl/source/uno/pathservice.cxx b/svl/source/uno/pathservice.cxx new file mode 100644 index 000000000000..78c339773aec --- /dev/null +++ b/svl/source/uno/pathservice.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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: pathservice.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" + +#include <unotools/pathoptions.hxx> +#include "sal/types.h" +#include "rtl/ustring.hxx" +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace css = com::sun::star; +using rtl::OUString; + +// ----------------------------------------------------------------------- + +class PathService : public ::cppu::WeakImplHelper2< css::frame::XConfigManager, css::lang::XServiceInfo > +{ + SvtPathOptions m_aOptions; + +public: + PathService() + {} + + virtual OUString SAL_CALL getImplementationName() + throw(css::uno::RuntimeException) + { + return OUString::createFromAscii("com.sun.star.comp.svl.PathService"); + } + + virtual sal_Bool SAL_CALL supportsService ( + const OUString & rName) + throw(css::uno::RuntimeException) + { + return (rName.compareToAscii("com.sun.star.config.SpecialConfigManager") == 0); + } + + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() + throw(css::uno::RuntimeException) + { + css::uno::Sequence< OUString > aRet(1); + aRet.getArray()[0] = OUString::createFromAscii("com.sun.star.config.SpecialConfigManager"); + return aRet; + } + + virtual OUString SAL_CALL substituteVariables ( + const OUString& sText) + throw(css::uno::RuntimeException) + { + return m_aOptions.SubstituteVariable( sText ); + } + + virtual void SAL_CALL addPropertyChangeListener ( + const OUString &, const css::uno::Reference< css::beans::XPropertyChangeListener > &) + throw(css::uno::RuntimeException) + {} + + virtual void SAL_CALL removePropertyChangeListener ( + const OUString &, const css::uno::Reference< css::beans::XPropertyChangeListener > &) + throw(css::uno::RuntimeException) + {} + + virtual void SAL_CALL flush() + throw(css::uno::RuntimeException) + {} +}; + +// ----------------------------------------------------------------------- + +css::uno::Reference< css::uno::XInterface > PathService_CreateInstance ( + const css::uno::Reference< css::lang::XMultiServiceFactory > &) +{ + return css::uno::Reference< css::uno::XInterface >( + static_cast< cppu::OWeakObject* >(new PathService())); +} + +// ----------------------------------------------------------------------- diff --git a/svl/source/uno/registerservices.cxx b/svl/source/uno/registerservices.cxx new file mode 100644 index 000000000000..39be9e177fea --- /dev/null +++ b/svl/source/uno/registerservices.cxx @@ -0,0 +1,154 @@ +/************************************************************************* + * + * 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: registerservices.cxx,v $ + * $Revision: 1.21 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include "sal/types.h" +#include "rtl/ustring.hxx" +#include <cppuhelper/factory.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <svl/svldllapi.h> + +namespace css = com::sun::star; +using css::uno::Reference; +using css::uno::Sequence; +using rtl::OUString; + +// ------------------------------------------------------------------------------------- + +#define DECLARE_CREATEINSTANCE( ImplName ) \ + Reference< css::uno::XInterface > SAL_CALL ImplName##_CreateInstance( const Reference< css::lang::XMultiServiceFactory >& ); + +DECLARE_CREATEINSTANCE( SvNumberFormatterServiceObj ) +DECLARE_CREATEINSTANCE( SvNumberFormatsSupplierServiceObject ) +DECLARE_CREATEINSTANCE( PathService ) + +// ------------------------------------------------------------------------------------- + +extern "C" +{ + +SVL_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment ( + const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SVL_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo ( + void * /* _pServiceManager */, void * _pRegistryKey) +{ + if (_pRegistryKey) + { + Reference< css::registry::XRegistryKey > xRegistryKey ( + reinterpret_cast< css::registry::XRegistryKey* >(_pRegistryKey)); + Reference< css::registry::XRegistryKey > xNewKey; + + xNewKey = xRegistryKey->createKey ( + OUString::createFromAscii( + "/com.sun.star.uno.util.numbers.SvNumberFormatsSupplierServiceObject/UNO/SERVICES" ) ); + xNewKey->createKey ( + OUString::createFromAscii( "com.sun.star.util.NumberFormatsSupplier" ) ); + + xNewKey = xRegistryKey->createKey ( + OUString::createFromAscii( + "/com.sun.star.uno.util.numbers.SvNumberFormatterServiceObject/UNO/SERVICES" ) ); + xNewKey->createKey ( + OUString::createFromAscii( "com.sun.star.util.NumberFormatter" ) ); + + xNewKey = xRegistryKey->createKey( + OUString::createFromAscii( "/com.sun.star.comp.svl.PathService/UNO/SERVICES" ) ); + xNewKey->createKey ( + OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ); + + return sal_True; + } + return sal_False; +} + +SVL_DLLPUBLIC void* SAL_CALL component_getFactory ( + const sal_Char * pImplementationName, void * _pServiceManager, void * /* _pRegistryKey*/) +{ + void * pResult = 0; + if ( _pServiceManager ) + { + Reference< css::lang::XSingleServiceFactory > xFactory; + if (rtl_str_compare( + pImplementationName, + "com.sun.star.uno.util.numbers.SvNumberFormatsSupplierServiceObject") == 0) + { + Sequence< OUString > aServiceNames(1); + aServiceNames.getArray()[0] = + OUString::createFromAscii( "com.sun.star.util.NumberFormatsSupplier" ); + + xFactory = ::cppu::createSingleFactory( + reinterpret_cast< css::lang::XMultiServiceFactory* >(_pServiceManager), + OUString::createFromAscii( pImplementationName ), + SvNumberFormatsSupplierServiceObject_CreateInstance, + aServiceNames); + } + else if (rtl_str_compare( + pImplementationName, + "com.sun.star.uno.util.numbers.SvNumberFormatterServiceObject") == 0) + { + Sequence< OUString > aServiceNames(1); + aServiceNames.getArray()[0] = + OUString::createFromAscii( "com.sun.star.util.NumberFormatter" ); + + xFactory = ::cppu::createSingleFactory( + reinterpret_cast< css::lang::XMultiServiceFactory* >(_pServiceManager), + OUString::createFromAscii( pImplementationName ), + SvNumberFormatterServiceObj_CreateInstance, + aServiceNames); + } + else if (rtl_str_compare ( + pImplementationName, "com.sun.star.comp.svl.PathService") == 0) + { + Sequence< OUString > aServiceNames(1); + aServiceNames.getArray()[0] = + OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ); + xFactory = ::cppu::createSingleFactory ( + reinterpret_cast< css::lang::XMultiServiceFactory* >( _pServiceManager ), + OUString::createFromAscii( pImplementationName ), + PathService_CreateInstance, + aServiceNames); + } + if ( xFactory.is() ) + { + xFactory->acquire(); + pResult = xFactory.get(); + } + } + return pResult; +} + +} // "C" + diff --git a/svl/unx/inc/convert.hxx b/svl/unx/inc/convert.hxx new file mode 100644 index 000000000000..e91ee4ed2791 --- /dev/null +++ b/svl/unx/inc/convert.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * 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: convert.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _CONVERT_HXX +#define _CONVERT_HXX + +/* +#define _SWAPSHORT(x) ((((x) & 0xFF00)>>8) | (((x) & 0x00FF)<<8)) +#define _SWAPLONG(x) ((((x) & 0xFF000000)>>24) | (((x) & 0x00FF0000)>>8) | \ + (((x) & 0x0000FF00)<<8) | (((x) & 0x000000FF)<<24)) +*/ +class Convert +{ +public: + static void Swap( long & nValue ) + { nValue = SWAPLONG( nValue ); } + static void Swap( ULONG & nValue ) + { nValue = SWAPLONG( nValue ); } + static void Swap( short & nValue ) + { nValue = SWAPSHORT( nValue ); } + static void Swap( USHORT & nValue ) + { nValue = SWAPSHORT( nValue ); } + static void Swap( Point & aPtr ) + { Swap( aPtr.X() ); Swap( aPtr.Y() ); } + static void Swap( Size & aSize ) + { Swap( aSize.Width() ); Swap( aSize.Height() ); } + static void Swap( Rectangle & rRect ) + { Swap( rRect.Top() ); Swap( rRect.Bottom() ); + Swap( rRect.Left() ); Swap( rRect.Right() ); } +/* + static USHORT AnsiFloatSize() const { return 6; } + static float AnsiToFloat( void * pAnsiFloat ) + { return 0; } + static USHORT AnsiDoubleSize() const { return 12; } + static double AnsiToDouble( void * pAnsiDouble ) + { return 0; } +*/ +}; + +#endif // _CONVERT_HXX diff --git a/svl/unx/source/svdde/ddedummy.cxx b/svl/unx/source/svdde/ddedummy.cxx new file mode 100644 index 000000000000..2aec705bc7ef --- /dev/null +++ b/svl/unx/source/svdde/ddedummy.cxx @@ -0,0 +1,341 @@ +/************************************************************************* + * + * 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: ddedummy.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svl.hxx" +#include <svl/svdde.hxx> +#include <rtl/instance.hxx> + +DdeData::DdeData() +{ +} + +DdeData::DdeData( const String& ) +{ +} + +DdeData::DdeData( const DdeData& ) +{ +} + +DdeData::DdeData( const void*, long, ULONG) +{ +} + +DdeData::~DdeData( void ) +{ +} + +void DdeData::SetFormat( ULONG ) +{ +} + +ULONG DdeData::GetFormat() const +{ + return 0L; +} + +DdeData& DdeData::operator = ( const DdeData& ) +{ + return *this; +} + +DdeData::operator long() const +{ + return 0L; +} + +DdeData::operator const void*() const +{ + return NULL; +} + +long DdeConnection::GetError() +{ + return 0L; +} + +DdeConnection::DdeConnection( const String&, const String& ) +{ +} + +DdeConnection::~DdeConnection( void ) +{ +} + +const String& DdeConnection::GetServiceName() +{ + return String::EmptyString(); +} + +const String& DdeConnection::GetTopicName() +{ + return String::EmptyString(); +} + +DdeTransaction::DdeTransaction( DdeConnection& rConnection, const String&, long ) : + rDde( rConnection ) +{ +} + +DdeTransaction::DdeTransaction( const DdeTransaction& rTransaction ) : + rDde( rTransaction.rDde ) +{ +} + +void DdeTransaction::Execute(void) +{ +} + +void DdeTransaction::Done( BOOL ) +{ +} + +void DdeTransaction::Data( const DdeData* ) +{ +} + +DdeTransaction::~DdeTransaction(void) +{ +} + +DdeRequest::DdeRequest(DdeConnection& rConnection, const String& rString, long lLong ) : + DdeTransaction( rConnection, rString, lLong ) +{ +} + +DdeExecute::DdeExecute( DdeConnection& rConnection, const String& rString, long lLong ) : + DdeTransaction( rConnection, rString, lLong ) +{ +} + +DdePoke::DdePoke( DdeConnection& rConnection, const String& rString, const DdeData&, long lLong ) : + DdeTransaction( rConnection, rString, lLong ) +{ +} + + +DdeTopic::DdeTopic( const String& ) +{ +} + +DdeTopic::~DdeTopic() +{ +} + +void DdeTopic::Connect (long ) +{ +} + +void DdeTopic::Disconnect( long ) +{ +} + +void DdeTopic::InsertItem( DdeItem* ) +{ +} + +DdeItem* DdeTopic::AddItem( const DdeItem& rDdeItem ) +{ + return (DdeItem*) &rDdeItem; +} + +void DdeTopic::RemoveItem( const DdeItem& ) +{ +} + +DdeData* DdeTopic::Get( ULONG ) +{ + return NULL; +} + +BOOL DdeTopic::MakeItem( const String& ) +{ + return FALSE; +} + +BOOL DdeTopic::StartAdviseLoop() +{ + return FALSE; +} + +BOOL DdeTopic::StopAdviseLoop() +{ + return FALSE; +} + +BOOL DdeTopic::Execute( const String* ) +{ + return FALSE; +} + +BOOL DdeTopic::Put( const DdeData* ) +{ + return FALSE; +} + +const String& DdeTopic::GetName() const +{ + return String::EmptyString(); +} + +DdeService::DdeService( const String& ) +{ + nStatus = 0; +} + +String DdeService::Topics() { + return String(); +} + +String DdeService::Formats() { + return String(); +} + +String DdeService::SysItems() { + return String(); +} + +String DdeService::Status() { + return String(); +} + +String DdeService::SysTopicGet(const String& rString) { + return rString; +} + +BOOL DdeService::SysTopicExecute(const String*) { + return FALSE; +} + +DdeService::~DdeService() +{ +} + +BOOL DdeService::IsBusy() +{ + return FALSE; +} + +String DdeService::GetHelp() +{ + return String::EmptyString(); +} + +void DdeService::AddFormat( ULONG ) +{ +} + +void DdeService::AddTopic( const DdeTopic& ) +{ +} + +void DdeService::RemoveTopic( const DdeTopic& ) +{ +} + +BOOL DdeService::MakeTopic( const String& ) +{ + return FALSE; +} + +const String& DdeService::GetName() const +{ + return String::EmptyString(); +} + +namespace +{ + struct theDdeServices + : public rtl::Static< DdeServices, theDdeServices > {}; +} + +DdeServices& DdeService::GetServices() +{ + return theDdeServices::get(); +} + +DdeItem::DdeItem( const String& ) +{ +} + +DdeItem::DdeItem( const DdeItem& ) +{ +} + +DdeItem::~DdeItem() +{ +} + +void DdeItem::NotifyClient() +{ +} + +DdeGetPutItem::DdeGetPutItem( const String& rStr ) : +DdeItem( rStr ) +{ +} + +DdeGetPutItem::DdeGetPutItem( const DdeItem& rItem ) : +DdeItem( rItem ) +{ +} + +DdeData* DdeGetPutItem::Get( ULONG ) +{ + return NULL; +} + +BOOL DdeGetPutItem::Put( const DdeData* ) +{ + return FALSE; +} + +void DdeGetPutItem::AdviseLoop( BOOL ) +{ +} + +DdeLink::DdeLink( DdeConnection& rConnection, const String& rString, long l ) : +DdeTransaction( rConnection, rString, l ) +{ +} + +DdeLink::~DdeLink() +{ +} + +void DdeLink::Notify() +{ +} + +DdeHotLink::DdeHotLink( DdeConnection& rConnection, const String& rString, long l ) : +DdeLink( rConnection, rString, l ) +{ +} diff --git a/svl/unx/source/svdde/makefile.mk b/svl/unx/source/svdde/makefile.mk new file mode 100644 index 000000000000..c6e89eaf2630 --- /dev/null +++ b/svl/unx/source/svdde/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.7 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=svl +TARGET=svdde + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svl.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/ddedummy.obj + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/svl/util/makefile.mk b/svl/util/makefile.mk new file mode 100644 index 000000000000..47a37a6e9173 --- /dev/null +++ b/svl/util/makefile.mk @@ -0,0 +1,126 @@ +#************************************************************************* +#* +# 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: makefile.mk,v $ +# +# $Revision: 1.67 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=svl +TARGET=svl +RESTARGETSIMPLE=svs +GEN_HID=TRUE +# GEN_HID_OTHER=TRUE +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- general section ---------------------------------------------------- + +.IF "$(GUI)"!="UNX" +LIB2TARGET= $(LB)$/isvl.lib +LIB2FILES= $(LB)$/_isvl.lib +.ENDIF + +LIB1TARGET= $(SLB)$/svl.lib +LIB1FILES= \ + $(SLB)$/config.lib \ + $(SLB)$/svdde.lib \ + $(SLB)$/undo.lib \ + $(SLB)$/numbers.lib \ + $(SLB)$/numbers.uno.lib \ + $(SLB)$/filerec.lib \ + $(SLB)$/filepicker.lib \ + $(SLB)$/items.lib \ + $(SLB)$/misc.lib \ + $(SLB)$/notify.lib \ + $(SLB)$/unoiface.lib \ + $(SLB)$/svarray.lib \ + $(SLB)$/svsql.lib + +# generation of resourcen-lib ---------------------------------------- + +RESLIB1NAME= $(RESTARGETSIMPLE) +RESLIB1SRSFILES=\ + $(SRS)$/items.srs \ + $(SRS)$/misc.srs + +# build the shared library -------------------------------------------------- + +SHL1TARGET= svl$(DLLPOSTFIX) +SHL1IMPLIB= _isvl +SHL1USE_EXPORTS=name +#Do not link with VCL or any other library that links with VCL +SHL1STDLIBS= \ + $(UNOTOOLSLIB) \ + $(TOOLSLIB) \ + $(I18NISOLANGLIB) \ + $(UCBHELPERLIB) \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(VOSLIB) \ + $(SOTLIB) \ + $(SALLIB) + +.IF "$(GUI)"=="WNT" +SHL1STDLIBS+= \ + $(UWINAPILIB) \ + $(ADVAPI32LIB) \ + $(GDI32LIB) +.ENDIF # WNT + +SHL1LIBS= $(SLB)$/svl.lib + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1DEPN= $(SLB)$/svl.lib +DEFLIB1NAME=svl +DEF1DES =SvTools lite + +# --- Targets ------------------------------------------------------ + +.IF "$(GUI)"=="UNX" +SVTTARGETS= $(LB)$/lib$(SHL1TARGET)$(DLLPOST) +.ELSE +SVTTARGETS= $(LB)$/isvl.lib +.ENDIF + +# just a quick fix - has to be cleaned up some day... +.IF "$(L10N-framework)"=="" +ALL: $(SLB)$/svl.lib \ + $(MISC)$/$(SHL1TARGET).def \ + $(SVTTARGETS) \ + ALLTAR +.ENDIF # "$(L10N-framework)"=="" + +.INCLUDE : target.mk + diff --git a/svl/util/svl.pmk b/svl/util/svl.pmk new file mode 100644 index 000000000000..aec76257e743 --- /dev/null +++ b/svl/util/svl.pmk @@ -0,0 +1,35 @@ +#************************************************************************* +# +# 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: svl.pmk,v $ +# +# $Revision: 1.4 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +# define SVL_DLLIMPLEMENTATION (see @ svldllapi.h) +CDEFS += -DSVL_DLLIMPLEMENTATION + +VISIBILITY_HIDDEN=TRUE |