summaryrefslogtreecommitdiff
path: root/svx/workben
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2005-09-23 09:49:58 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2005-09-23 09:49:58 +0000
commite34dd5c7c3fb9ed1ee02996cb2f0c92ec135e98b (patch)
tree3e949cf567fa55c74e852a0a74b0565f0767e7fb /svx/workben
parent1f3044b4ea734ab239dbafa81ef1de744aed8ee6 (diff)
INTEGRATION: CWS impress49 (1.1.2); FILE ADDED
2005/07/15 13:43:53 cl 1.1.2.1: new ms storage viewer helper app
Diffstat (limited to 'svx/workben')
-rw-r--r--svx/workben/msview/msview.cxx1267
1 files changed, 1267 insertions, 0 deletions
diff --git a/svx/workben/msview/msview.cxx b/svx/workben/msview/msview.cxx
new file mode 100644
index 000000000000..96dfbea1fc84
--- /dev/null
+++ b/svx/workben/msview/msview.cxx
@@ -0,0 +1,1267 @@
+/*************************************************************************
+ *
+ * $RCSfile: msview.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: hr $ $Date: 2005-09-23 10:49:58 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <boost/shared_ptr.hpp>
+
+#ifndef _SOT_STORAGE_HXX
+#include <sot/storage.hxx>
+#endif
+#ifndef _SVTOOLS_HRC
+#include <svtools/svtools.hrc>
+#endif
+
+#include <sal/main.h>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/button.hxx>
+#include <vcl/lstbox.hxx>
+#include <svtools/filectrl.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+#include <vcl/unohelp2.hxx>
+#include <svtools/svtreebx.hxx>
+#include <svtools/svmedit.hxx>
+
+#ifndef _FILEDLGHELPER_HXX
+#include <sfx2/filedlghelper.hxx>
+#endif
+
+#include <toolkit/unohlp.hxx>
+
+#include <tools/stream.hxx>
+
+#ifndef _TOOLS_RESMGR_HXX
+#include <tools/resmgr.hxx>
+#endif
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XToolkit.hpp>
+#include <com/sun/star/awt/WindowDescriptor.hpp>
+#include <com/sun/star/awt/WindowAttribute.hpp>
+
+#ifndef _MSDFFDEF_HXX
+#include "msdffdef.hxx"
+#endif
+
+#include <unotools/localfilehelper.hxx>
+
+#include "xmlconfig.hxx"
+
+using ::rtl::OUString;
+
+using namespace ::com::sun::star;
+
+///////////////////////////////////////////////////////////////////////
+
+enum CompareStatus { CMP_NOTYET = 0, CMP_EQUAL = 1, CMP_NOTEQUAL = 2, CMP_NOTAVAILABLE = 3 };
+static ColorData gColors[] = { COL_BLACK, COL_GREEN, COL_RED, COL_CYAN };
+
+class Atom
+{
+public:
+ ~Atom();
+
+ /** imports this atom and its child atoms */
+ static Atom* import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl );
+ static Atom* import( UINT16 nRecType, SvStream& rStCtrl );
+
+ inline const DffRecordHeader& getHeader() const;
+
+ /** returns true if at least one atim with the given nRecType is found */
+ inline bool hasChildAtom( sal_uInt16 nRecType ) const;
+
+ /** returns true if at least one atim with the given nRecType and nRecInstnace is found */
+ inline bool hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const;
+
+ /** returns the first child atom with nRecType or NULL */
+ inline const Atom* findFirstChildAtom( sal_uInt16 nRecType ) const;
+
+ /** returns the next child atom after pLast with nRecType or NULL */
+ const Atom* findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const;
+
+ /** returns the first child atom with nRecType and nRecInstance or NULL */
+ inline const Atom* findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const;
+
+ /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
+ const Atom* findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const;
+
+ /** returns the first child atom or NULL */
+ inline const Atom* findFirstChildAtom() const;
+
+ /** returns the next child atom after pLast or NULL */
+ inline const Atom* findNextChildAtom( const Atom* pLast ) const;
+
+ /** returns true if this atom is a container */
+ inline bool isContainer() const;
+
+ /** seeks to the contents of this atom */
+ inline bool seekToContent() const;
+
+ /** returns the record type */
+ inline sal_uInt16 getType() const;
+
+ /** returns the record instance */
+ inline sal_uInt16 getInstance() const;
+
+ /** returns the record length */
+ inline sal_uInt32 getLength() const;
+
+ SvStream& getStream() const { return mrStream; }
+
+ bool operator==( const Atom& rAtom ) const;
+
+ CompareStatus getCompareStatus() const { return meStatus; }
+
+ void compare( Atom* pAtom );
+ bool compareContent( Atom& rAtom );
+
+ Atom* getCompareAtom() const { return mpCompareAtom; }
+ void setCompareAtom( Atom* pAtom ) { mpCompareAtom = pAtom; }
+
+private:
+ Atom( const DffRecordHeader& rRecordHeader, SvStream& rStCtrl );
+
+ // statics for compare
+ static Atom* skipAtoms( Atom* pContainer, Atom* pAtom, Atom* pSkipTo );
+ static Atom* findFirstEqualAtom( Atom* pCompare, Atom* pContainer, Atom* pSearch, int& nDistance );
+
+ SvStream& mrStream;
+ DffRecordHeader maRecordHeader;
+ Atom* mpFirstChild;
+ Atom* mpNextAtom;
+
+ CompareStatus meStatus;
+ Atom* mpCompareAtom;
+};
+
+bool Atom::operator==( const Atom& rAtom ) const
+{
+ return ( maRecordHeader.nRecType == rAtom.maRecordHeader.nRecType ) &&
+ ( maRecordHeader.nRecVer == rAtom.maRecordHeader.nRecVer ) &&
+ ( maRecordHeader.nRecInstance == rAtom.maRecordHeader.nRecInstance );
+}
+
+bool Atom::compareContent( Atom& rAtom )
+{
+ if( maRecordHeader.nRecLen == rAtom.maRecordHeader.nRecLen )
+ {
+ seekToContent();
+ rAtom.seekToContent();
+
+ SvStream& rStream1 = getStream();
+ SvStream& rStream2 = rAtom.getStream();
+
+ const int nBufferSize = 1024;
+ boost::shared_ptr< char > buffer1( new char[nBufferSize] );
+ boost::shared_ptr< char > buffer2( new char[nBufferSize] );
+
+ sal_uInt32 nLength = maRecordHeader.nRecLen;
+ sal_Size nRead = 0;
+ while( nLength )
+ {
+ sal_Size nRead = (nBufferSize < nLength) ? nBufferSize : nLength;
+ nRead = rStream1.Read( (void*)buffer1.get(), nRead );
+ if( nRead == 0 )
+ break;
+ if( rStream2.Read( (void*)buffer2.get(), nRead ) != nRead )
+ break;
+ if( memcmp( (void*)buffer1.get(), (void*)buffer2.get(), nRead ) != 0 )
+ break;
+
+ nLength -= nRead;
+ }
+
+ return nLength == 0;
+ }
+
+ return false;
+}
+
+inline bool Atom::hasChildAtom( sal_uInt16 nRecType ) const
+{
+ return findFirstChildAtom( nRecType ) != NULL;
+}
+
+inline bool Atom::hasChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const
+{
+ return findFirstChildAtom( nRecType, nRecInstance ) != NULL;
+}
+
+inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType ) const
+{
+ return findNextChildAtom( nRecType, NULL );
+}
+
+inline const DffRecordHeader& Atom::getHeader() const
+{
+ return maRecordHeader;
+}
+
+inline const Atom* Atom::findFirstChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance ) const
+{
+ return findNextChildAtom( nRecType, nRecInstance, NULL );
+}
+
+inline const Atom* Atom::findFirstChildAtom() const
+{
+ return mpFirstChild;
+}
+
+inline const Atom* Atom::findNextChildAtom( const Atom* pLast ) const
+{
+ return pLast ? pLast->mpNextAtom : pLast;
+}
+
+inline bool Atom::isContainer() const
+{
+ return (bool)maRecordHeader.IsContainer();
+}
+
+inline bool Atom::seekToContent() const
+{
+ maRecordHeader.SeekToContent( mrStream );
+ return mrStream.GetError() == 0;
+}
+
+inline sal_uInt16 Atom::getType() const
+{
+ return maRecordHeader.nRecType;
+}
+
+inline sal_uInt16 Atom::getInstance() const
+{
+ return maRecordHeader.nRecInstance;
+}
+
+inline sal_uInt32 Atom::getLength() const
+{
+ return maRecordHeader.nRecLen;
+}
+
+Atom::Atom( const DffRecordHeader& rRecordHeader, SvStream& rStream )
+: maRecordHeader( rRecordHeader ),
+ mrStream( rStream ),
+ mpFirstChild( 0 ),
+ mpNextAtom( 0 ),
+ meStatus( CMP_NOTYET ),
+ mpCompareAtom( 0 )
+{
+ // check if we need to force this to a container
+ if( maRecordHeader.nRecVer != DFF_PSFLAG_CONTAINER )
+ {
+ AtomConfig* pAtomConfig = dynamic_cast< AtomConfig* >( gAtomConfigMap[ maRecordHeader.nRecType ].get() );
+ if( pAtomConfig && pAtomConfig->isContainer() )
+ {
+ maRecordHeader.nRecVer = DFF_PSFLAG_CONTAINER;
+ }
+ }
+
+ if( isContainer() )
+ {
+ if( seekToContent() )
+ {
+ DffRecordHeader aChildHeader;
+
+ Atom* pLastAtom = NULL;
+
+ while( (mrStream.GetError() == 0 ) && ( mrStream.Tell() < maRecordHeader.GetRecEndFilePos() ) )
+ {
+ mrStream >> aChildHeader;
+
+ if( mrStream.GetError() == 0 )
+ {
+ Atom* pAtom = new Atom( aChildHeader, mrStream );
+
+ if( pLastAtom )
+ pLastAtom->mpNextAtom = pAtom;
+ if( mpFirstChild == NULL )
+ mpFirstChild = pAtom;
+
+ pLastAtom = pAtom;
+ }
+ }
+ }
+ }
+
+ maRecordHeader.SeekToEndOfRecord( mrStream );
+}
+
+Atom::~Atom()
+{
+ Atom* pChild = mpFirstChild;
+ while( pChild )
+ {
+ Atom* pNextChild = pChild->mpNextAtom;
+ delete pChild;
+ pChild = pNextChild;
+ }
+}
+
+/** imports this atom and its child atoms */
+Atom* Atom::import( const DffRecordHeader& rRootRecordHeader, SvStream& rStCtrl )
+{
+ Atom* pRootAtom = new Atom( rRootRecordHeader, rStCtrl );
+
+ if( rStCtrl.GetError() == 0 )
+ {
+ return pRootAtom;
+ }
+ else
+ {
+ delete pRootAtom;
+ return NULL;
+ }
+}
+
+/** imports this atom and its child atoms */
+Atom* Atom::import( UINT16 nRecType, SvStream& rStCtrl )
+{
+ rStCtrl.Seek( STREAM_SEEK_TO_END );
+ sal_Size nStreamLength = rStCtrl.Tell();
+ rStCtrl.Seek( STREAM_SEEK_TO_BEGIN );
+
+ DffRecordHeader aRootRecordHeader;
+ aRootRecordHeader.nRecVer = DFF_PSFLAG_CONTAINER;
+ aRootRecordHeader.nRecInstance = 0;
+ aRootRecordHeader.nImpVerInst = 0;
+ aRootRecordHeader.nRecType = nRecType;
+ aRootRecordHeader.nRecLen = nStreamLength;
+ aRootRecordHeader.nFilePos = 0;
+
+ return import( aRootRecordHeader, rStCtrl );
+}
+
+/** returns the next child atom after pLast with nRecType or NULL */
+const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, const Atom* pLast ) const
+{
+ Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild;
+ while( pChild && pChild->maRecordHeader.nRecType != nRecType )
+ {
+ pChild = pChild->mpNextAtom;
+ }
+
+ return pChild;
+}
+
+/** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
+const Atom* Atom::findNextChildAtom( sal_uInt16 nRecType, sal_uInt16 nRecInstance, const Atom* pLast ) const
+{
+ const Atom* pChild = pLast != NULL ? pLast->mpNextAtom : mpFirstChild;
+ while( pChild && (pChild->maRecordHeader.nRecType != nRecType) && (pChild->maRecordHeader.nRecInstance != nRecInstance) )
+ {
+ pChild = findNextChildAtom( pChild );
+ }
+
+ return pChild;
+}
+
+Atom* Atom::findFirstEqualAtom( Atom* pCompare, Atom* pContainer, Atom* pSearch, int& nDistance )
+{
+ nDistance = 0;
+ Atom* pRet = 0;
+
+ while( pSearch )
+ {
+ if( *pSearch == *pCompare )
+ return pSearch;
+
+ pSearch = const_cast< Atom* >( pContainer->findNextChildAtom( pSearch ) );
+ nDistance++;
+ }
+
+ return 0;
+}
+
+Atom* Atom::skipAtoms( Atom* pContainer, Atom* pAtom, Atom* pSkipTo )
+{
+ while( pAtom && (pAtom != pSkipTo) )
+ {
+ pAtom->meStatus = CMP_NOTAVAILABLE;
+ pAtom = const_cast< Atom* >( pContainer->findNextChildAtom( pAtom ) );
+ }
+
+ return pAtom;
+}
+
+void Atom::compare( Atom* pAtom )
+{
+ if( pAtom )
+ {
+ if( meStatus == CMP_NOTYET )
+ {
+ mpCompareAtom = pAtom;
+ pAtom->mpCompareAtom = this;
+
+ mpCompareAtom = pAtom;
+ pAtom->mpCompareAtom = this;
+
+ meStatus = pAtom->meStatus = ( *this == *pAtom ) ? CMP_EQUAL : CMP_NOTEQUAL;
+ }
+
+ if(meStatus == CMP_EQUAL)
+ {
+ if( isContainer() )
+ {
+ /** returns the first child atom or NULL */
+ Atom* pChildAtom1 = const_cast< Atom* >( findFirstChildAtom() );
+
+ if( pChildAtom1 && (pChildAtom1->meStatus == CMP_NOTYET) )
+ {
+ Atom* pChildAtom2 = const_cast< Atom* >( pAtom->findFirstChildAtom() );
+ while( pChildAtom1 && pChildAtom2 )
+ {
+ if( !(*pChildAtom1 == *pChildAtom2) )
+ {
+ int nDistance1;
+ int nDistance2;
+
+ Atom* pFind1 = findFirstEqualAtom( pChildAtom1, pAtom, const_cast< Atom* >( pAtom->findNextChildAtom( pChildAtom2 )), nDistance1 );
+ Atom* pFind2 = findFirstEqualAtom( pChildAtom2, this, const_cast< Atom* >(findNextChildAtom( pChildAtom1 )), nDistance2 );
+
+ if( pFind1 && (!pFind2 || (nDistance1 < nDistance2) ) )
+ {
+ pChildAtom2 = skipAtoms( pAtom, pChildAtom2, pFind1 );
+ }
+ else if( pFind2 )
+ {
+ pChildAtom1 = skipAtoms( this, pChildAtom1, pFind2 );
+ }
+ else
+ {
+ pChildAtom1 = skipAtoms( this, pChildAtom1, 0 );
+ pChildAtom2 = skipAtoms( pAtom, pChildAtom2, 0 );
+ }
+ }
+
+ if( pChildAtom1 && pChildAtom2 )
+ {
+ pChildAtom1->mpCompareAtom = pChildAtom2;
+ pChildAtom2->mpCompareAtom = pChildAtom1;
+
+ pChildAtom1->meStatus = pChildAtom2->meStatus =
+ (pChildAtom1->isContainer() || pChildAtom1->compareContent( *pChildAtom2 )) ?
+ CMP_EQUAL : CMP_NOTEQUAL;
+
+ pChildAtom1 = const_cast< Atom* >( findNextChildAtom( pChildAtom1 ) );
+ pChildAtom2 = const_cast< Atom* >( pAtom->findNextChildAtom( pChildAtom2 ) );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( !compareContent( *pAtom ) )
+ {
+ meStatus = pAtom->meStatus = CMP_NOTEQUAL;
+ }
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+
+class AtomBoxString : public SvLBoxString
+{
+public:
+ AtomBoxString( SvLBoxEntry* pEntry, const String& rStr )
+ : SvLBoxString( pEntry, 0, rStr )
+ { }
+
+ ~AtomBoxString() { }
+
+ void Paint( const Point& rPos, SvLBox& rOutDev, USHORT nViewDataEntryFlags, SvLBoxEntry* pEntry )
+ {
+ Color aOldTextColor = rOutDev.GetTextColor();
+
+ if( pEntry && pEntry->GetUserData() )
+ {
+ Atom* pAtom = static_cast<Atom*>( pEntry->GetUserData() );
+ rOutDev.SetTextColor( Color( gColors[ pAtom->getCompareStatus() ] ) );
+ }
+
+ SvLBoxString::Paint( rPos, rOutDev, nViewDataEntryFlags, pEntry );
+
+ rOutDev.SetTextColor( aOldTextColor );
+
+/*
+ Color aOldFillColor = rOutDev.GetFillColor();
+
+ SvTreeListBox* pTreeBox = static_cast< SvTreeListBox* >( &rOutDev );
+ long nX = pTreeBox->GetSizePixel().Width();
+
+ ScrollBar* pVScroll = pTreeBox->GetVScroll();
+ if ( pVScroll->IsVisible() )
+ {
+ nX -= pVScroll->GetSizePixel().Width();
+ }
+
+ SvViewDataItem* pItem = rOutDev.GetViewDataItem( pEntry, this );
+ nX -= pItem->aSize.Height();
+
+ long nSize = pItem->aSize.Height() / 2;
+ long nHalfSize = nSize / 2;
+ long nY = rPos.Y() + nHalfSize;
+
+ if ( aOldFillColor == COL_WHITE )
+ {
+ rOutDev.SetFillColor( Color( COL_BLACK ) );
+ }
+ else
+ {
+ rOutDev.SetFillColor( Color( COL_WHITE ) );
+ }
+
+ long n = 0;
+ while ( n <= nHalfSize )
+ {
+ rOutDev.DrawRect( Rectangle( nX+n, nY+n, nX+n, nY+nSize-n ) );
+ n++;
+ }
+
+ rOutDev.SetFillColor( aOldFillColor );
+*/
+ }
+
+private:
+ Image* mpImage;
+};
+
+
+//////////////////////////////////////////////////////////////////////
+
+class AtomContainerTreeListBox : public SvTreeListBox
+{
+public:
+ AtomContainerTreeListBox( Window* pParent );
+ ~AtomContainerTreeListBox();
+
+ void SetRootAtom( const Atom* pAtom );
+
+
+ void SetCollapsingHdl(const Link& rNewHdl){maCollapsingHdl=rNewHdl;}
+ const Link& GetCollapsingHdl() const { return maCollapsingHdl; }
+
+ void SetExpandingHdl(const Link& rNewHdl){maExpandingHdl=rNewHdl;}
+ const Link& GetExpandingHdl() const { return maExpandingHdl; }
+
+ virtual BOOL Expand( SvLBoxEntry* pParent );
+ virtual BOOL Collapse( SvLBoxEntry* pParent );
+
+ SvLBoxEntry* findAtom( Atom* pAtom );
+
+ virtual void InitEntry(SvLBoxEntry*,const XubString&,const Image&,const Image&);
+ virtual void SetTabs();
+
+private:
+ void InsertAtom( const Atom* pAtom, SvLBoxEntry* pParent = 0 );
+ const Atom* mpRootAtom;
+ ResMgr* mpResMgr;
+ Image maImgFolder;
+ Image maImgAtom;
+ Image maImgExpanded;
+ Image maImgCollapsed;
+ bool mbRecursiveGuard;
+ Link maCollapsingHdl;
+ Link maExpandingHdl;
+};
+
+typedef std::pair< AtomContainerTreeListBox*, SvLBoxEntry* > AtomContainerEntryPair;
+
+AtomContainerTreeListBox::AtomContainerTreeListBox( Window* pParent )
+: SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_HASBUTTONSATROOT|WB_3DLOOK|WB_BORDER ),
+ mpRootAtom( 0 ), mbRecursiveGuard( false )
+{
+ mpResMgr = ResMgr::CreateResMgr( "svt" );
+ maImgCollapsed = Image( ResId( RID_IMG_TREENODE_COLLAPSED, mpResMgr ) );
+ maImgExpanded = Image( ResId( RID_IMG_TREENODE_EXPANDED, mpResMgr ) );
+
+// SetDefaultExpandedEntryBmp( aExpanded );
+// SetDefaultCollapsedEntryBmp(aCollapsed );
+
+ maImgFolder = Image( ResId( IMG_SVT_FOLDER, mpResMgr ) );
+ maImgAtom = Image( ResId( IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL, mpResMgr ) );
+}
+
+AtomContainerTreeListBox::~AtomContainerTreeListBox()
+{
+}
+
+void AtomContainerTreeListBox::SetTabs()
+{
+ if( IsEditingActive() )
+ EndEditing( TRUE );
+
+ ClearTabList();
+
+ short nIndent = 0; GetIndent();
+ long nNodeWidthPixel = maImgCollapsed.GetSizePixel().Width();
+ long nContextWidthDIV2 = nNodeWidthPixel >> 1;
+
+ long nStartPos = 2 + ( nIndent + nContextWidthDIV2 );
+ AddTab( nStartPos, SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER );
+ nStartPos += nNodeWidthPixel + 5;
+ AddTab( nStartPos, SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER | SV_LBOXTAB_SHOW_SELECTION );
+ nStartPos += nContextWidthDIV2 + 5;
+ AddTab( nStartPos, SV_LBOXTAB_DYNAMIC|SV_LBOXTAB_ADJUST_LEFT | SV_LBOXTAB_SHOW_SELECTION );
+}
+
+void AtomContainerTreeListBox::InitEntry(SvLBoxEntry* pEntry,const XubString& aStr,const Image& aCollEntryBmp,const Image& aExpEntryBmp)
+{
+ pEntry->AddItem( new SvLBoxContextBmp( pEntry,0, aCollEntryBmp,aExpEntryBmp, SVLISTENTRYFLAG_EXPANDED ) );
+ pEntry->AddItem( new SvLBoxContextBmp( pEntry,0, maImgAtom, maImgAtom, SVLISTENTRYFLAG_EXPANDED ) );
+ pEntry->AddItem( new AtomBoxString( pEntry, aStr ) );
+}
+
+SvLBoxEntry* AtomContainerTreeListBox::findAtom( Atom* pAtom )
+{
+ SvLBoxEntry* pEntry = First();
+ while( pEntry )
+ {
+ if( pEntry->GetUserData() == pAtom )
+ return pEntry;
+
+ pEntry = Next( pEntry );
+ }
+
+ return 0;
+}
+
+BOOL AtomContainerTreeListBox::Expand( SvLBoxEntry* pParent )
+{
+ BOOL bRet = FALSE;
+ if( !mbRecursiveGuard )
+ {
+ mbRecursiveGuard = true;
+ AtomContainerEntryPair aPair( this, pParent );
+ maExpandingHdl.Call( &aPair);
+
+ bRet = SvTreeListBox::Expand( pParent );
+ mbRecursiveGuard = false;
+ }
+ return bRet;
+}
+
+BOOL AtomContainerTreeListBox::Collapse( SvLBoxEntry* pParent )
+{
+ BOOL bRet = FALSE;
+ if( !mbRecursiveGuard )
+ {
+ mbRecursiveGuard = true;
+ AtomContainerEntryPair aPair( this, pParent );
+ maCollapsingHdl.Call( &aPair);
+
+ bRet = SvTreeListBox::Collapse( pParent );
+ mbRecursiveGuard = false;
+ }
+ return bRet;
+}
+
+void AtomContainerTreeListBox::SetRootAtom( const Atom* pAtom )
+{
+ mpRootAtom = pAtom;
+ InsertAtom( mpRootAtom );
+}
+
+void AtomContainerTreeListBox::InsertAtom( const Atom* pAtom, SvLBoxEntry* pParent /* = 0 */ )
+{
+ if( pAtom )
+ {
+ const DffRecordHeader& rHeader = pAtom->getHeader();
+
+ char buffer[1024];
+
+ rtl::OUString aText;
+ AtomConfig* pAtomConfig = dynamic_cast< AtomConfig*>( gAtomConfigMap[rHeader.nRecType].get() );
+
+ if( pAtomConfig )
+ aText = pAtomConfig->getName();
+
+ if( !aText.getLength() )
+ {
+ sprintf( buffer, "unknown_0x%04x", rHeader.nRecType );
+ aText += rtl::OUString::createFromAscii( buffer );
+ }
+
+ sprintf( buffer, " (I: %lu L: %lu)", (UINT32)rHeader.nRecVer, (UINT32)rHeader.nRecLen );
+ aText += String( rtl::OUString::createFromAscii( buffer ) );
+
+ SvLBoxEntry* pEntry = 0;
+ if( pAtom->isContainer() && pAtom->findFirstChildAtom() )
+ {
+ pEntry = InsertEntry( aText, maImgExpanded, maImgCollapsed, pParent );
+
+ /** returns the first child atom or NULL */
+ const Atom* pChildAtom = pAtom->findFirstChildAtom();
+
+ while( pChildAtom )
+ {
+ InsertAtom( pChildAtom, pEntry );
+ pChildAtom = pAtom->findNextChildAtom( pChildAtom );
+ }
+ }
+ else
+ {
+ pEntry = InsertEntry( aText, pParent );
+ }
+
+ if( pEntry )
+ {
+ pEntry->SetUserData( (void*)pAtom );
+
+ if( pAtom->isContainer() )
+ {
+ SvLBoxContextBmp* pBoxBmp = dynamic_cast< SvLBoxContextBmp* >( pEntry->GetItem( pEntry->ItemCount() - 2 ) );
+ if( pBoxBmp )
+ {
+ pBoxBmp->SetBitmap1( pEntry, maImgFolder );
+ pBoxBmp->SetBitmap2( pEntry, maImgFolder );
+ }
+ }
+
+/*
+ pEntry->ReplaceItem(
+ new AtomBoxString( pEntry, aText, pImage ),
+ pEntry->ItemCount() - 1 );
+*/
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+
+extern void load_config( const OUString& rPath );
+
+class PPTDocument
+{
+public:
+ PPTDocument( const rtl::OUString& rFilePath );
+ ~PPTDocument();
+
+ Atom* getRootAtom() const;
+
+private:
+ void Load( const rtl::OUString& rFilePath );
+
+ Atom* mpAtom;
+ SvStream* mpDocStream;
+ SotStorageRef maStorage;
+};
+
+typedef boost::shared_ptr< PPTDocument > PPTDocumentPtr;
+
+PPTDocument::PPTDocument(const rtl::OUString& rFilePath)
+: mpAtom(0), mpDocStream(0)
+{
+ Load( rFilePath );
+}
+
+PPTDocument::~PPTDocument()
+{
+ delete mpAtom;
+ delete mpDocStream;
+}
+
+void PPTDocument::Load( const rtl::OUString& rFilePath )
+{
+ maStorage = new SotStorage( rFilePath, STREAM_STD_READ );
+ if( !maStorage->GetError() )
+ {
+ mpDocStream = maStorage->OpenSotStream( String( RTL_CONSTASCII_USTRINGPARAM("PowerPoint Document") ), STREAM_STD_READ );
+ if( mpDocStream )
+ {
+ DffRecordHeader aRecordHeader;
+ *mpDocStream >> aRecordHeader;
+
+ mpAtom = Atom::import( 65530, *mpDocStream );
+ }
+ }
+}
+
+Atom* PPTDocument::getRootAtom() const
+{
+ return mpAtom;
+}
+
+///////////////////////////////////////////////////////////////////////
+
+class MSViewerWorkWindow : public WorkWindow
+{
+public:
+ MSViewerWorkWindow();
+ ~MSViewerWorkWindow();
+
+ PPTDocumentPtr Load();
+ void onView();
+ void onCompare();
+ void onClose();
+
+ void View( const PPTDocumentPtr& pDocument, int nPane );
+ void Compare( const PPTDocumentPtr& pDocument1, const PPTDocumentPtr& pDocument2 );
+
+ virtual void Resize();
+
+private:
+ void Sync( AtomContainerEntryPair* pPair, int nAction );
+
+ AtomContainerTreeListBox* mpListBox[2];
+ MultiLineEdit* mpEdit[2];
+ PPTDocumentPtr mpDocument[2];
+ MenuBar* mpMenuBar;
+ PopupMenu* mpFileMenu;
+ bool mbSelectHdlGuard;
+ DECL_LINK( implSelectHdl, AtomContainerTreeListBox* );
+ DECL_LINK( implExpandingHdl, AtomContainerEntryPair* );
+ DECL_LINK( implCollapsingHdl, AtomContainerEntryPair* );
+ DECL_LINK( implMenuHdl, Menu* );
+};
+
+// -----------------------------------------------------------------------
+
+void MSViewerWorkWindow::onView()
+{
+ PPTDocumentPtr pDocument( Load() );
+ if( pDocument.get() )
+ {
+ onClose();
+ View( pDocument, 0 );
+ }
+}
+
+void MSViewerWorkWindow::onClose()
+{
+}
+
+void MSViewerWorkWindow::onCompare()
+{
+ PPTDocumentPtr pDocument1( Load() );
+ if( pDocument1.get() )
+ {
+ PPTDocumentPtr pDocument2( Load() );
+ if( pDocument2.get() )
+ {
+ onClose();
+ Compare( pDocument1, pDocument2 );
+ }
+ }
+}
+
+void MSViewerWorkWindow::Compare( const PPTDocumentPtr& pDocument1, const PPTDocumentPtr& pDocument2 )
+{
+ if( pDocument1.get() && pDocument2.get() )
+ {
+ Atom* pAtom1 = pDocument1->getRootAtom();
+ Atom* pAtom2 = pDocument2->getRootAtom();
+ pAtom1->setCompareAtom( pAtom2 );
+ pAtom2->setCompareAtom( pAtom1 );
+ }
+
+ View( pDocument1, 0 );
+ View( pDocument2, 1 );
+}
+
+void MSViewerWorkWindow::View( const PPTDocumentPtr& pDocument, int nPane )
+{
+ if( ((nPane != 0) && (nPane != 1)) || (pDocument.get() == 0) )
+ return;
+
+ mpDocument[nPane] = pDocument;
+
+ mpListBox[nPane]->SetRootAtom( pDocument->getRootAtom() );
+ mpListBox[nPane]->Expand( mpListBox[nPane]->GetEntry(0) );
+ mpListBox[nPane]->Show();
+ mpEdit[nPane]->Show();
+ Resize();
+}
+
+
+PPTDocumentPtr MSViewerWorkWindow::Load()
+{
+ ::sfx2::FileDialogHelper aDlg( ::sfx2::FILEOPEN_SIMPLE, 0 );
+ String aStrFilterType( RTL_CONSTASCII_USTRINGPARAM( "*.ppt" ) );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+// INetURLObject aFile( SvtPathOptions().GetPalettePath() );
+// aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ PPTDocumentPtr pDocument;
+ if ( aDlg.Execute() == ERRCODE_NONE )
+ {
+ pDocument.reset( new PPTDocument( aDlg.GetPath() ) );
+ }
+
+ return pDocument;
+}
+
+// -----------------------------------------------------------------------
+
+MSViewerWorkWindow::MSViewerWorkWindow() :
+ WorkWindow( 0, WB_APP | WB_STDWORK | WB_3DLOOK ),mbSelectHdlGuard(false)
+{
+ Size aOutputSize( 400, 600 );
+ SetOutputSizePixel( aOutputSize );
+ SetText( String( RTL_CONSTASCII_USTRINGPARAM( "MSViewer" ) ) );
+
+ Size aOutSize( GetOutputSizePixel() );
+
+ Font aFont( String( RTL_CONSTASCII_USTRINGPARAM( "Courier" ) ), GetFont().GetSize() );
+
+ mpMenuBar = new MenuBar();
+ mpMenuBar->InsertItem( 1, String( RTL_CONSTASCII_USTRINGPARAM("~File" ) ) );
+ mpFileMenu = new PopupMenu();
+ mpFileMenu->InsertItem( 2, String( RTL_CONSTASCII_USTRINGPARAM("~View" ) ) );
+ mpFileMenu->InsertItem( 3, String( RTL_CONSTASCII_USTRINGPARAM("~Compare" ) ) );
+ mpFileMenu->InsertSeparator();
+ mpFileMenu->InsertItem( 4, String( RTL_CONSTASCII_USTRINGPARAM("~Quit" ) ) );
+ mpFileMenu->SetSelectHdl( LINK( this, MSViewerWorkWindow, implMenuHdl ) );
+
+ mpMenuBar->SetPopupMenu( 1, mpFileMenu );
+ SetMenuBar( mpMenuBar );
+ int nPane;
+ for( nPane = 0; nPane < 2; nPane++ )
+ {
+ mpListBox[nPane] = new AtomContainerTreeListBox( this );
+ mpListBox[nPane]->SetSelectHdl( LINK( this, MSViewerWorkWindow, implSelectHdl ) );
+ mpListBox[nPane]->SetExpandingHdl( LINK( this, MSViewerWorkWindow, implExpandingHdl ) );
+ mpListBox[nPane]->SetCollapsingHdl( LINK( this, MSViewerWorkWindow, implCollapsingHdl ) );
+
+ mpEdit[nPane] = new MultiLineEdit(this, WB_3DLOOK | WB_BORDER | WB_LEFT | WB_TOP | WB_READONLY | WB_HSCROLL | WB_VSCROLL );
+ mpEdit[nPane]->SetReadOnly( TRUE );
+ mpEdit[nPane]->SetReadOnly( TRUE );
+ mpEdit[nPane]->SetControlFont( aFont );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static String GetAtomText( const Atom* pAtom )
+{
+ String aText;
+ if( pAtom )
+ {
+ const DffRecordHeader& rHeader = pAtom->getHeader();
+ char buffer[512];
+ sprintf( buffer, "Version = %lu\n\rInstance = %lu\n\rVersionInstance = %lu\n\rLength = %lu\n\r",
+ (UINT32)rHeader.nRecVer,
+ (UINT32)rHeader.nRecInstance,
+ (UINT32)rHeader.nImpVerInst,
+ (UINT32)rHeader.nRecLen );
+ aText = rtl::OUString::createFromAscii( buffer );
+ if( pAtom->isContainer() )
+ {
+
+ }
+ else
+ {
+ pAtom->seekToContent();
+ AtomConfig* pAtomConfig = dynamic_cast< AtomConfig* >( gAtomConfigMap[pAtom->getType()].get() );
+ if( pAtomConfig )
+ {
+ sal_Size nLength = pAtom->getLength();
+ aText += String( pAtomConfig->format( pAtom->getStream(), nLength ) );
+ }
+ else
+ {
+ sal_Size nLength = pAtom->getLength();
+ aText += String( ElementConfig::dump_hex( pAtom->getStream(), nLength ) );
+ }
+ }
+ }
+
+ return aText;
+}
+
+IMPL_LINK(MSViewerWorkWindow,implSelectHdl, AtomContainerTreeListBox*, pListBox )
+{
+ int nPane = (pListBox == mpListBox[1]) ? 1 : 0;
+ SvLBoxEntry* pEntry = mpListBox[nPane]->FirstSelected();
+ if( pEntry && pEntry->GetUserData() )
+ {
+ Atom* pAtom = static_cast<Atom*>( pEntry->GetUserData() );
+ mpEdit[nPane]->SetText( GetAtomText( pAtom ) );
+
+ if(!mbSelectHdlGuard)
+ {
+ mbSelectHdlGuard = true;
+ // select other
+ AtomContainerEntryPair aPair( pListBox, pEntry );
+ Sync( &aPair, 2 );
+ mbSelectHdlGuard = false;
+ }
+ }
+ return 0;
+}
+
+void MSViewerWorkWindow::Sync( AtomContainerEntryPair* pPair, int nAction )
+{
+ if( mpDocument[0].get() && mpDocument[1].get() && pPair->first && pPair->second )
+ {
+ AtomContainerTreeListBox* pDestinationListBox = (pPair->first == mpListBox[0]) ? mpListBox[1] : mpListBox[0];
+
+ Atom* pAtom = static_cast<Atom*>(pPair->second->GetUserData());
+ if( pAtom && pAtom->getCompareAtom() )
+ {
+ SvLBoxEntry* pEntry = pDestinationListBox->findAtom( pAtom->getCompareAtom() );
+
+ if(pEntry )
+ {
+ if( nAction == 0 )
+ {
+ pDestinationListBox->Expand( pEntry );
+ }
+ else if( nAction == 1 )
+ {
+ pDestinationListBox->Collapse( pEntry );
+ }
+ else
+ {
+ pDestinationListBox->Select( pEntry );
+ }
+ }
+ }
+ }
+}
+
+IMPL_LINK(MSViewerWorkWindow, implExpandingHdl, AtomContainerEntryPair*, pPair )
+{
+ SvLBoxEntry* pEntry = pPair->second;
+ if( pEntry && pEntry->GetUserData() )
+ {
+ Atom* pAtom = static_cast<Atom*>( pEntry->GetUserData() );
+ pAtom->compare( pAtom->getCompareAtom() );
+ }
+
+ Sync( pPair, 0 );
+
+ return 0;
+}
+
+IMPL_LINK(MSViewerWorkWindow, implCollapsingHdl, AtomContainerEntryPair*, pPair )
+{
+ Sync( pPair, 1 );
+
+ return 0;
+}
+
+IMPL_LINK( MSViewerWorkWindow, implMenuHdl, Menu*, pMenu )
+{
+ if( pMenu )
+ {
+ USHORT nId = pMenu->GetCurItemId();
+ switch( nId )
+ {
+ case 2: onView(); break;
+ case 3: onCompare(); break;
+ case 4: Application::Quit(); break;
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+MSViewerWorkWindow::~MSViewerWorkWindow()
+{
+ int nPane;
+ for( nPane = 0; nPane < 2; nPane++ )
+ {
+ delete mpListBox[nPane];
+ delete mpEdit[nPane];
+ }
+
+ delete mpFileMenu;
+ delete mpMenuBar;
+}
+
+// -----------------------------------------------------------------------
+
+void MSViewerWorkWindow::Resize()
+{
+ int nPaneCount = ((mpDocument[0].get() != 0) ? 1 : 0) + ((mpDocument[1].get() != 0) ? 1 : 0);
+
+ Size aOutputSize( GetOutputSizePixel() );
+ int nHeight = aOutputSize.Height() >> 1;
+ if( nPaneCount )
+ {
+ int nWidth = aOutputSize.Width();
+ if( nPaneCount == 2 )
+ nWidth >>= 1;
+
+ int nPosX = 0;
+
+ int nPane;
+ for( nPane = 0; nPane < 2; nPane++ )
+ {
+ mpListBox[nPane]->SetPosSizePixel( nPosX,0, nWidth, nHeight );
+ mpEdit[nPane]->SetPosSizePixel( nPosX, nHeight, nWidth, aOutputSize.Height() - nHeight );
+ nPosX += nWidth;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+ SAL_IMPLEMENT_MAIN()
+{
+ if( argc > 3 )
+ return 0;
+
+ uno::Reference< lang::XMultiServiceFactory > xMSF;
+ try
+ {
+ uno::Reference< uno::XComponentContext > xCtx( cppu::defaultBootstrap_InitialComponentContext() );
+ if ( !xCtx.is() )
+ {
+ DBG_ERROR( "Error creating initial component context!" );
+ return -1;
+ }
+
+ xMSF = uno::Reference< lang::XMultiServiceFactory >(xCtx->getServiceManager(), uno::UNO_QUERY );
+
+ if ( !xMSF.is() )
+ {
+ DBG_ERROR( "No service manager!" );
+ return -1;
+ }
+
+ // Init UCB
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
+ aArgs[ 1 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
+ sal_Bool bSuccess = ::ucb::ContentBroker::initialize( xMSF, aArgs );
+ if ( !bSuccess )
+ {
+ DBG_ERROR( "Error creating UCB!" );
+ return -1;
+ }
+
+ }
+ catch ( uno::Exception const & )
+ {
+ DBG_ERROR( "Exception during creation of initial component context!" );
+ return -1;
+ }
+ comphelper::setProcessServiceFactory( xMSF );
+
+ InitVCL( xMSF );
+
+ String aConfigURL;
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aConfigURL ) )
+ {
+ INetURLObject aURL( aConfigURL );
+
+ aURL.removeSegment();
+ aURL.removeFinalSlash();
+ aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM( "msview.xml" ) ) );
+
+ load_config( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
+ }
+
+ {
+ MSViewerWorkWindow aMainWindow;
+
+ if( argc >= 2 )
+ {
+ const rtl::OUString aFile1( rtl::OUString::createFromAscii(argv[1]) );
+ PPTDocumentPtr pDocument1( new PPTDocument( aFile1 ) );
+
+ if( argc == 3 )
+ {
+ const rtl::OUString aFile2( rtl::OUString::createFromAscii(argv[2]) );
+
+ PPTDocumentPtr pDocument2;
+ pDocument2.reset( new PPTDocument( aFile2 ) );
+ aMainWindow.Compare( pDocument1, pDocument2 );
+ }
+ else
+ {
+ aMainWindow.View( pDocument1, 0 );
+ }
+ }
+
+ aMainWindow.Show();
+
+ Application::Execute();
+ }
+
+ DeInitVCL();
+
+ return 0;
+} \ No newline at end of file