1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
33 #include <boost/shared_ptr.hpp>
34 #include <sot/storage.hxx>
35 #include <svtools/svtools.hrc>
38 #include <vcl/event.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/wrkwin.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <vcl/fixed.hxx>
43 #include <vcl/edit.hxx>
44 #include <vcl/button.hxx>
45 #include <vcl/lstbox.hxx>
46 #include <svtools/filectrl.hxx>
47 #include <tools/urlobj.hxx>
48 #include <osl/file.hxx>
49 #include <vcl/unohelp2.hxx>
50 #include <svtools/svtreebx.hxx>
51 #include <svtools/svmedit.hxx>
52 #include <sfx2/filedlghelper.hxx>
54 #include <toolkit/unohlp.hxx>
56 #include <tools/stream.hxx>
57 #include <tools/resmgr.hxx>
59 #include <comphelper/processfactory.hxx>
60 #include <cppuhelper/servicefactory.hxx>
61 #include <cppuhelper/bootstrap.hxx>
63 #include <ucbhelper/contentbroker.hxx>
64 #include <ucbhelper/configurationkeys.hxx>
66 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
68 #include <com/sun/star/awt/XWindowPeer.hpp>
69 #include <com/sun/star/awt/XToolkit.hpp>
70 #include <com/sun/star/awt/WindowDescriptor.hpp>
71 #include <com/sun/star/awt/WindowAttribute.hpp>
72 #include <svx/msdffdef.hxx>
74 #include <unotools/localfilehelper.hxx>
76 #include "xmlconfig.hxx"
78 using ::rtl::OUString
;
80 using namespace ::com::sun::star
;
82 ///////////////////////////////////////////////////////////////////////
84 enum CompareStatus
{ CMP_NOTYET
= 0, CMP_EQUAL
= 1, CMP_NOTEQUAL
= 2, CMP_NOTAVAILABLE
= 3 };
85 static ColorData gColors
[] = { COL_BLACK
, COL_GREEN
, COL_RED
, COL_CYAN
};
92 /** imports this atom and its child atoms */
93 static Atom
* import( const DffRecordHeader
& rRootRecordHeader
, SvStream
& rStCtrl
);
94 static Atom
* import( UINT16 nRecType
, SvStream
& rStCtrl
);
96 inline const DffRecordHeader
& getHeader() const;
98 /** returns true if at least one atim with the given nRecType is found */
99 inline bool hasChildAtom( sal_uInt16 nRecType
) const;
101 /** returns true if at least one atim with the given nRecType and nRecInstnace is found */
102 inline bool hasChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const;
104 /** returns the first child atom with nRecType or NULL */
105 inline const Atom
* findFirstChildAtom( sal_uInt16 nRecType
) const;
107 /** returns the next child atom after pLast with nRecType or NULL */
108 const Atom
* findNextChildAtom( sal_uInt16 nRecType
, const Atom
* pLast
) const;
110 /** returns the first child atom with nRecType and nRecInstance or NULL */
111 inline const Atom
* findFirstChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const;
113 /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
114 const Atom
* findNextChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
, const Atom
* pLast
) const;
116 /** returns the first child atom or NULL */
117 inline const Atom
* findFirstChildAtom() const;
119 /** returns the next child atom after pLast or NULL */
120 inline const Atom
* findNextChildAtom( const Atom
* pLast
) const;
122 /** returns true if this atom is a container */
123 inline bool isContainer() const;
125 /** seeks to the contents of this atom */
126 inline bool seekToContent() const;
128 /** returns the record type */
129 inline sal_uInt16
getType() const;
131 /** returns the record instance */
132 inline sal_uInt16
getInstance() const;
134 /** returns the record length */
135 inline sal_uInt32
getLength() const;
137 SvStream
& getStream() const { return mrStream
; }
139 bool operator==( const Atom
& rAtom
) const;
141 CompareStatus
getCompareStatus() const { return meStatus
; }
143 void compare( Atom
* pAtom
);
144 bool compareContent( Atom
& rAtom
);
146 Atom
* getCompareAtom() const { return mpCompareAtom
; }
147 void setCompareAtom( Atom
* pAtom
) { mpCompareAtom
= pAtom
; }
150 Atom( const DffRecordHeader
& rRecordHeader
, SvStream
& rStCtrl
);
152 // statics for compare
153 static Atom
* skipAtoms( Atom
* pContainer
, Atom
* pAtom
, Atom
* pSkipTo
);
154 static Atom
* findFirstEqualAtom( Atom
* pCompare
, Atom
* pContainer
, Atom
* pSearch
, int& nDistance
);
157 DffRecordHeader maRecordHeader
;
161 CompareStatus meStatus
;
165 bool Atom::operator==( const Atom
& rAtom
) const
167 return ( maRecordHeader
.nRecType
== rAtom
.maRecordHeader
.nRecType
) &&
168 ( maRecordHeader
.nRecVer
== rAtom
.maRecordHeader
.nRecVer
) &&
169 ( maRecordHeader
.nRecInstance
== rAtom
.maRecordHeader
.nRecInstance
);
172 bool Atom::compareContent( Atom
& rAtom
)
174 if( maRecordHeader
.nRecLen
== rAtom
.maRecordHeader
.nRecLen
)
177 rAtom
.seekToContent();
179 SvStream
& rStream1
= getStream();
180 SvStream
& rStream2
= rAtom
.getStream();
182 const int nBufferSize
= 1024;
183 boost::shared_ptr
< char > buffer1( new char[nBufferSize
] );
184 boost::shared_ptr
< char > buffer2( new char[nBufferSize
] );
186 sal_uInt32 nLength
= maRecordHeader
.nRecLen
;
190 sal_Size nRead
= (nBufferSize
< nLength
) ? nBufferSize
: nLength
;
191 nRead
= rStream1
.Read( (void*)buffer1
.get(), nRead
);
194 if( rStream2
.Read( (void*)buffer2
.get(), nRead
) != nRead
)
196 if( memcmp( (void*)buffer1
.get(), (void*)buffer2
.get(), nRead
) != 0 )
208 inline bool Atom::hasChildAtom( sal_uInt16 nRecType
) const
210 return findFirstChildAtom( nRecType
) != NULL
;
213 inline bool Atom::hasChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const
215 return findFirstChildAtom( nRecType
, nRecInstance
) != NULL
;
218 inline const Atom
* Atom::findFirstChildAtom( sal_uInt16 nRecType
) const
220 return findNextChildAtom( nRecType
, NULL
);
223 inline const DffRecordHeader
& Atom::getHeader() const
225 return maRecordHeader
;
228 inline const Atom
* Atom::findFirstChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const
230 return findNextChildAtom( nRecType
, nRecInstance
, NULL
);
233 inline const Atom
* Atom::findFirstChildAtom() const
238 inline const Atom
* Atom::findNextChildAtom( const Atom
* pLast
) const
240 return pLast
? pLast
->mpNextAtom
: pLast
;
243 inline bool Atom::isContainer() const
245 return (bool)maRecordHeader
.IsContainer();
248 inline bool Atom::seekToContent() const
250 maRecordHeader
.SeekToContent( mrStream
);
251 return mrStream
.GetError() == 0;
254 inline sal_uInt16
Atom::getType() const
256 return maRecordHeader
.nRecType
;
259 inline sal_uInt16
Atom::getInstance() const
261 return maRecordHeader
.nRecInstance
;
264 inline sal_uInt32
Atom::getLength() const
266 return maRecordHeader
.nRecLen
;
269 Atom::Atom( const DffRecordHeader
& rRecordHeader
, SvStream
& rStream
)
270 : maRecordHeader( rRecordHeader
),
274 meStatus( CMP_NOTYET
),
277 // check if we need to force this to a container
278 if( maRecordHeader
.nRecVer
!= DFF_PSFLAG_CONTAINER
)
280 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
* >( gAtomConfigMap
[ maRecordHeader
.nRecType
].get() );
281 if( pAtomConfig
&& pAtomConfig
->isContainer() )
283 maRecordHeader
.nRecVer
= DFF_PSFLAG_CONTAINER
;
289 if( seekToContent() )
291 DffRecordHeader aChildHeader
;
293 Atom
* pLastAtom
= NULL
;
295 while( (mrStream
.GetError() == 0 ) && ( mrStream
.Tell() < maRecordHeader
.GetRecEndFilePos() ) )
297 mrStream
>> aChildHeader
;
299 if( mrStream
.GetError() == 0 )
301 Atom
* pAtom
= new Atom( aChildHeader
, mrStream
);
304 pLastAtom
->mpNextAtom
= pAtom
;
305 if( mpFirstChild
== NULL
)
306 mpFirstChild
= pAtom
;
314 maRecordHeader
.SeekToEndOfRecord( mrStream
);
319 Atom
* pChild
= mpFirstChild
;
322 Atom
* pNextChild
= pChild
->mpNextAtom
;
328 /** imports this atom and its child atoms */
329 Atom
* Atom::import( const DffRecordHeader
& rRootRecordHeader
, SvStream
& rStCtrl
)
331 Atom
* pRootAtom
= new Atom( rRootRecordHeader
, rStCtrl
);
333 if( rStCtrl
.GetError() == 0 )
344 /** imports this atom and its child atoms */
345 Atom
* Atom::import( UINT16 nRecType
, SvStream
& rStCtrl
)
347 rStCtrl
.Seek( STREAM_SEEK_TO_END
);
348 sal_Size nStreamLength
= rStCtrl
.Tell();
349 rStCtrl
.Seek( STREAM_SEEK_TO_BEGIN
);
351 DffRecordHeader aRootRecordHeader
;
352 aRootRecordHeader
.nRecVer
= DFF_PSFLAG_CONTAINER
;
353 aRootRecordHeader
.nRecInstance
= 0;
354 aRootRecordHeader
.nImpVerInst
= 0;
355 aRootRecordHeader
.nRecType
= nRecType
;
356 aRootRecordHeader
.nRecLen
= nStreamLength
;
357 aRootRecordHeader
.nFilePos
= 0;
359 return import( aRootRecordHeader
, rStCtrl
);
362 /** returns the next child atom after pLast with nRecType or NULL */
363 const Atom
* Atom::findNextChildAtom( sal_uInt16 nRecType
, const Atom
* pLast
) const
365 Atom
* pChild
= pLast
!= NULL
? pLast
->mpNextAtom
: mpFirstChild
;
366 while( pChild
&& pChild
->maRecordHeader
.nRecType
!= nRecType
)
368 pChild
= pChild
->mpNextAtom
;
374 /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
375 const Atom
* Atom::findNextChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
, const Atom
* pLast
) const
377 const Atom
* pChild
= pLast
!= NULL
? pLast
->mpNextAtom
: mpFirstChild
;
378 while( pChild
&& (pChild
->maRecordHeader
.nRecType
!= nRecType
) && (pChild
->maRecordHeader
.nRecInstance
!= nRecInstance
) )
380 pChild
= findNextChildAtom( pChild
);
386 Atom
* Atom::findFirstEqualAtom( Atom
* pCompare
, Atom
* pContainer
, Atom
* pSearch
, int& nDistance
)
392 if( *pSearch
== *pCompare
)
395 pSearch
= const_cast< Atom
* >( pContainer
->findNextChildAtom( pSearch
) );
402 Atom
* Atom::skipAtoms( Atom
* pContainer
, Atom
* pAtom
, Atom
* pSkipTo
)
404 while( pAtom
&& (pAtom
!= pSkipTo
) )
406 pAtom
->meStatus
= CMP_NOTAVAILABLE
;
407 pAtom
= const_cast< Atom
* >( pContainer
->findNextChildAtom( pAtom
) );
413 void Atom::compare( Atom
* pAtom
)
417 if( meStatus
== CMP_NOTYET
)
419 mpCompareAtom
= pAtom
;
420 pAtom
->mpCompareAtom
= this;
422 mpCompareAtom
= pAtom
;
423 pAtom
->mpCompareAtom
= this;
425 meStatus
= pAtom
->meStatus
= ( *this == *pAtom
) ? CMP_EQUAL
: CMP_NOTEQUAL
;
428 if(meStatus
== CMP_EQUAL
)
432 /** returns the first child atom or NULL */
433 Atom
* pChildAtom1
= const_cast< Atom
* >( findFirstChildAtom() );
435 if( pChildAtom1
&& (pChildAtom1
->meStatus
== CMP_NOTYET
) )
437 Atom
* pChildAtom2
= const_cast< Atom
* >( pAtom
->findFirstChildAtom() );
438 while( pChildAtom1
&& pChildAtom2
)
440 if( !(*pChildAtom1
== *pChildAtom2
) )
445 Atom
* pFind1
= findFirstEqualAtom( pChildAtom1
, pAtom
, const_cast< Atom
* >( pAtom
->findNextChildAtom( pChildAtom2
)), nDistance1
);
446 Atom
* pFind2
= findFirstEqualAtom( pChildAtom2
, this, const_cast< Atom
* >(findNextChildAtom( pChildAtom1
)), nDistance2
);
448 if( pFind1
&& (!pFind2
|| (nDistance1
< nDistance2
) ) )
450 pChildAtom2
= skipAtoms( pAtom
, pChildAtom2
, pFind1
);
454 pChildAtom1
= skipAtoms( this, pChildAtom1
, pFind2
);
458 pChildAtom1
= skipAtoms( this, pChildAtom1
, 0 );
459 pChildAtom2
= skipAtoms( pAtom
, pChildAtom2
, 0 );
463 if( pChildAtom1
&& pChildAtom2
)
465 pChildAtom1
->mpCompareAtom
= pChildAtom2
;
466 pChildAtom2
->mpCompareAtom
= pChildAtom1
;
468 pChildAtom1
->meStatus
= pChildAtom2
->meStatus
=
469 (pChildAtom1
->isContainer() || pChildAtom1
->compareContent( *pChildAtom2
)) ?
470 CMP_EQUAL
: CMP_NOTEQUAL
;
472 pChildAtom1
= const_cast< Atom
* >( findNextChildAtom( pChildAtom1
) );
473 pChildAtom2
= const_cast< Atom
* >( pAtom
->findNextChildAtom( pChildAtom2
) );
480 if( !compareContent( *pAtom
) )
482 meStatus
= pAtom
->meStatus
= CMP_NOTEQUAL
;
489 //////////////////////////////////////////////////////////////////////
491 //////////////////////////////////////////////////////////////////////
493 class AtomBoxString
: public SvLBoxString
496 AtomBoxString( SvLBoxEntry
* pEntry
, const String
& rStr
)
497 : SvLBoxString( pEntry
, 0, rStr
)
502 void Paint( const Point
& rPos
, SvLBox
& rOutDev
, USHORT nViewDataEntryFlags
, SvLBoxEntry
* pEntry
)
504 Color aOldTextColor
= rOutDev
.GetTextColor();
506 if( pEntry
&& pEntry
->GetUserData() )
508 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
509 rOutDev
.SetTextColor( Color( gColors
[ pAtom
->getCompareStatus() ] ) );
512 SvLBoxString::Paint( rPos
, rOutDev
, nViewDataEntryFlags
, pEntry
);
514 rOutDev
.SetTextColor( aOldTextColor
);
519 //////////////////////////////////////////////////////////////////////
521 class AtomContainerTreeListBox
: public SvTreeListBox
524 AtomContainerTreeListBox( Window
* pParent
);
525 ~AtomContainerTreeListBox();
527 void SetRootAtom( const Atom
* pAtom
);
530 void SetCollapsingHdl(const Link
& rNewHdl
){maCollapsingHdl
=rNewHdl
;}
531 const Link
& GetCollapsingHdl() const { return maCollapsingHdl
; }
533 void SetExpandingHdl(const Link
& rNewHdl
){maExpandingHdl
=rNewHdl
;}
534 const Link
& GetExpandingHdl() const { return maExpandingHdl
; }
536 virtual BOOL
Expand( SvLBoxEntry
* pParent
);
537 virtual BOOL
Collapse( SvLBoxEntry
* pParent
);
539 SvLBoxEntry
* findAtom( Atom
* pAtom
);
541 virtual void InitEntry(SvLBoxEntry
*,const XubString
&,const Image
&,const Image
&);
542 virtual void SetTabs();
545 void InsertAtom( const Atom
* pAtom
, SvLBoxEntry
* pParent
= 0 );
546 const Atom
* mpRootAtom
;
551 Image maImgCollapsed
;
552 bool mbRecursiveGuard
;
553 Link maCollapsingHdl
;
557 typedef std::pair
< AtomContainerTreeListBox
*, SvLBoxEntry
* > AtomContainerEntryPair
;
559 AtomContainerTreeListBox::AtomContainerTreeListBox( Window
* pParent
)
560 : SvTreeListBox( pParent
, WB_HASBUTTONS
|WB_HASLINES
|WB_HASBUTTONSATROOT
|WB_3DLOOK
|WB_BORDER
),
561 mpRootAtom( 0 ), mbRecursiveGuard( false )
563 mpResMgr
= ResMgr::CreateResMgr( "svt" );
564 maImgCollapsed
= Image( ResId( RID_IMG_TREENODE_COLLAPSED
, mpResMgr
) );
565 maImgExpanded
= Image( ResId( RID_IMG_TREENODE_EXPANDED
, mpResMgr
) );
567 // SetDefaultExpandedEntryBmp( aExpanded );
568 // SetDefaultCollapsedEntryBmp(aCollapsed );
570 maImgFolder
= Image( ResId( IMG_SVT_FOLDER
, mpResMgr
) );
571 maImgAtom
= Image( ResId( IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL
, mpResMgr
) );
574 AtomContainerTreeListBox::~AtomContainerTreeListBox()
578 void AtomContainerTreeListBox::SetTabs()
580 if( IsEditingActive() )
585 short nIndent
= 0; GetIndent();
586 long nNodeWidthPixel
= maImgCollapsed
.GetSizePixel().Width();
587 long nContextWidthDIV2
= nNodeWidthPixel
>> 1;
589 long nStartPos
= 2 + ( nIndent
+ nContextWidthDIV2
);
590 AddTab( nStartPos
, SV_LBOXTAB_DYNAMIC
| SV_LBOXTAB_ADJUST_CENTER
);
591 nStartPos
+= nNodeWidthPixel
+ 5;
592 AddTab( nStartPos
, SV_LBOXTAB_DYNAMIC
| SV_LBOXTAB_ADJUST_CENTER
| SV_LBOXTAB_SHOW_SELECTION
);
593 nStartPos
+= nContextWidthDIV2
+ 5;
594 AddTab( nStartPos
, SV_LBOXTAB_DYNAMIC
|SV_LBOXTAB_ADJUST_LEFT
| SV_LBOXTAB_SHOW_SELECTION
);
597 void AtomContainerTreeListBox::InitEntry(SvLBoxEntry
* pEntry
,const XubString
& aStr
,const Image
& aCollEntryBmp
,const Image
& aExpEntryBmp
)
599 pEntry
->AddItem( new SvLBoxContextBmp( pEntry
,0, aCollEntryBmp
,aExpEntryBmp
, SVLISTENTRYFLAG_EXPANDED
) );
600 pEntry
->AddItem( new SvLBoxContextBmp( pEntry
,0, maImgAtom
, maImgAtom
, SVLISTENTRYFLAG_EXPANDED
) );
601 pEntry
->AddItem( new AtomBoxString( pEntry
, aStr
) );
604 SvLBoxEntry
* AtomContainerTreeListBox::findAtom( Atom
* pAtom
)
606 SvLBoxEntry
* pEntry
= First();
609 if( pEntry
->GetUserData() == pAtom
)
612 pEntry
= Next( pEntry
);
618 BOOL
AtomContainerTreeListBox::Expand( SvLBoxEntry
* pParent
)
621 if( !mbRecursiveGuard
)
623 mbRecursiveGuard
= true;
624 AtomContainerEntryPair
aPair( this, pParent
);
625 maExpandingHdl
.Call( &aPair
);
627 bRet
= SvTreeListBox::Expand( pParent
);
628 mbRecursiveGuard
= false;
633 BOOL
AtomContainerTreeListBox::Collapse( SvLBoxEntry
* pParent
)
636 if( !mbRecursiveGuard
)
638 mbRecursiveGuard
= true;
639 AtomContainerEntryPair
aPair( this, pParent
);
640 maCollapsingHdl
.Call( &aPair
);
642 bRet
= SvTreeListBox::Collapse( pParent
);
643 mbRecursiveGuard
= false;
648 void AtomContainerTreeListBox::SetRootAtom( const Atom
* pAtom
)
651 InsertAtom( mpRootAtom
);
654 void AtomContainerTreeListBox::InsertAtom( const Atom
* pAtom
, SvLBoxEntry
* pParent
/* = 0 */ )
658 const DffRecordHeader
& rHeader
= pAtom
->getHeader();
663 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
*>( gAtomConfigMap
[rHeader
.nRecType
].get() );
666 aText
= pAtomConfig
->getName();
668 if( !aText
.getLength() )
670 sprintf( buffer
, "unknown_0x%04x", rHeader
.nRecType
);
671 aText
+= rtl::OUString::createFromAscii( buffer
);
674 sprintf( buffer
, " (I: %lu L: %lu)", (UINT32
)rHeader
.nRecVer
, (UINT32
)rHeader
.nRecLen
);
675 aText
+= String( rtl::OUString::createFromAscii( buffer
) );
677 SvLBoxEntry
* pEntry
= 0;
678 if( pAtom
->isContainer() && pAtom
->findFirstChildAtom() )
680 pEntry
= InsertEntry( aText
, maImgExpanded
, maImgCollapsed
, pParent
);
682 /** returns the first child atom or NULL */
683 const Atom
* pChildAtom
= pAtom
->findFirstChildAtom();
687 InsertAtom( pChildAtom
, pEntry
);
688 pChildAtom
= pAtom
->findNextChildAtom( pChildAtom
);
693 pEntry
= InsertEntry( aText
, pParent
);
698 pEntry
->SetUserData( (void*)pAtom
);
700 if( pAtom
->isContainer() )
702 SvLBoxContextBmp
* pBoxBmp
= dynamic_cast< SvLBoxContextBmp
* >( pEntry
->GetItem( pEntry
->ItemCount() - 2 ) );
705 pBoxBmp
->SetBitmap1( pEntry
, maImgFolder
);
706 pBoxBmp
->SetBitmap2( pEntry
, maImgFolder
);
712 new AtomBoxString( pEntry, aText, pImage ),
713 pEntry->ItemCount() - 1 );
719 ///////////////////////////////////////////////////////////////////////
721 extern void load_config( const OUString
& rPath
);
726 PPTDocument( const rtl::OUString
& rFilePath
);
729 Atom
* getRootAtom() const;
732 void Load( const rtl::OUString
& rFilePath
);
735 SvStream
* mpDocStream
;
736 SotStorageRef maStorage
;
739 typedef boost::shared_ptr
< PPTDocument
> PPTDocumentPtr
;
741 PPTDocument::PPTDocument(const rtl::OUString
& rFilePath
)
742 : mpAtom(0), mpDocStream(0)
747 PPTDocument::~PPTDocument()
753 void PPTDocument::Load( const rtl::OUString
& rFilePath
)
755 maStorage
= new SotStorage( rFilePath
, STREAM_STD_READ
);
756 if( !maStorage
->GetError() )
758 mpDocStream
= maStorage
->OpenSotStream( String( "PowerPoint Document" ), STREAM_STD_READ
);
761 DffRecordHeader aRecordHeader
;
762 *mpDocStream
>> aRecordHeader
;
764 mpAtom
= Atom::import( 65530, *mpDocStream
);
769 Atom
* PPTDocument::getRootAtom() const
774 ///////////////////////////////////////////////////////////////////////
776 class MSViewerWorkWindow
: public WorkWindow
779 MSViewerWorkWindow();
780 ~MSViewerWorkWindow();
782 PPTDocumentPtr
Load();
787 void View( const PPTDocumentPtr
& pDocument
, int nPane
);
788 void Compare( const PPTDocumentPtr
& pDocument1
, const PPTDocumentPtr
& pDocument2
);
790 virtual void Resize();
793 void Sync( AtomContainerEntryPair
* pPair
, int nAction
);
795 AtomContainerTreeListBox
* mpListBox
[2];
796 MultiLineEdit
* mpEdit
[2];
797 PPTDocumentPtr mpDocument
[2];
799 PopupMenu
* mpFileMenu
;
800 bool mbSelectHdlGuard
;
801 DECL_LINK( implSelectHdl
, AtomContainerTreeListBox
* );
802 DECL_LINK( implExpandingHdl
, AtomContainerEntryPair
* );
803 DECL_LINK( implCollapsingHdl
, AtomContainerEntryPair
* );
804 DECL_LINK( implMenuHdl
, Menu
* );
807 // -----------------------------------------------------------------------
809 void MSViewerWorkWindow::onView()
811 PPTDocumentPtr
pDocument( Load() );
812 if( pDocument
.get() )
815 View( pDocument
, 0 );
819 void MSViewerWorkWindow::onClose()
823 void MSViewerWorkWindow::onCompare()
825 PPTDocumentPtr
pDocument1( Load() );
826 if( pDocument1
.get() )
828 PPTDocumentPtr
pDocument2( Load() );
829 if( pDocument2
.get() )
832 Compare( pDocument1
, pDocument2
);
837 void MSViewerWorkWindow::Compare( const PPTDocumentPtr
& pDocument1
, const PPTDocumentPtr
& pDocument2
)
839 if( pDocument1
.get() && pDocument2
.get() )
841 Atom
* pAtom1
= pDocument1
->getRootAtom();
842 Atom
* pAtom2
= pDocument2
->getRootAtom();
843 pAtom1
->setCompareAtom( pAtom2
);
844 pAtom2
->setCompareAtom( pAtom1
);
847 View( pDocument1
, 0 );
848 View( pDocument2
, 1 );
851 void MSViewerWorkWindow::View( const PPTDocumentPtr
& pDocument
, int nPane
)
853 if( ((nPane
!= 0) && (nPane
!= 1)) || (pDocument
.get() == 0) )
856 mpDocument
[nPane
] = pDocument
;
858 mpListBox
[nPane
]->SetRootAtom( pDocument
->getRootAtom() );
859 mpListBox
[nPane
]->Expand( mpListBox
[nPane
]->GetEntry(0) );
860 mpListBox
[nPane
]->Show();
861 mpEdit
[nPane
]->Show();
866 PPTDocumentPtr
MSViewerWorkWindow::Load()
868 ::sfx2::FileDialogHelper
aDlg(
869 ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, 0 );
870 String
aStrFilterType( "*.ppt" );
871 aDlg
.AddFilter( aStrFilterType
, aStrFilterType
);
872 // INetURLObject aFile( SvtPathOptions().GetPalettePath() );
873 // aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) );
875 PPTDocumentPtr pDocument
;
876 if ( aDlg
.Execute() == ERRCODE_NONE
)
878 pDocument
.reset( new PPTDocument( aDlg
.GetPath() ) );
884 // -----------------------------------------------------------------------
886 MSViewerWorkWindow::MSViewerWorkWindow() :
887 WorkWindow( 0, WB_APP
| WB_STDWORK
| WB_3DLOOK
),mbSelectHdlGuard(false)
889 Size
aOutputSize( 400, 600 );
890 SetOutputSizePixel( aOutputSize
);
891 SetText( String( "MSViewer" ) );
893 Size
aOutSize( GetOutputSizePixel() );
895 Font
aFont( String( "Courier" ), GetFont().GetSize() );
897 mpMenuBar
= new MenuBar();
898 mpMenuBar
->InsertItem( 1, String( "~File" ) );
899 mpFileMenu
= new PopupMenu();
900 mpFileMenu
->InsertItem( 2, String( "~View" ) );
901 mpFileMenu
->InsertItem( 3, String( "~Compare" ) );
902 mpFileMenu
->InsertSeparator();
903 mpFileMenu
->InsertItem( 4, String( "~Quit" ) );
904 mpFileMenu
->SetSelectHdl( LINK( this, MSViewerWorkWindow
, implMenuHdl
) );
906 mpMenuBar
->SetPopupMenu( 1, mpFileMenu
);
907 SetMenuBar( mpMenuBar
);
909 for( nPane
= 0; nPane
< 2; nPane
++ )
911 mpListBox
[nPane
] = new AtomContainerTreeListBox( this );
912 mpListBox
[nPane
]->SetSelectHdl( LINK( this, MSViewerWorkWindow
, implSelectHdl
) );
913 mpListBox
[nPane
]->SetExpandingHdl( LINK( this, MSViewerWorkWindow
, implExpandingHdl
) );
914 mpListBox
[nPane
]->SetCollapsingHdl( LINK( this, MSViewerWorkWindow
, implCollapsingHdl
) );
916 mpEdit
[nPane
] = new MultiLineEdit(this, WB_3DLOOK
| WB_BORDER
| WB_LEFT
| WB_TOP
| WB_READONLY
| WB_HSCROLL
| WB_VSCROLL
);
917 mpEdit
[nPane
]->SetReadOnly( TRUE
);
918 mpEdit
[nPane
]->SetReadOnly( TRUE
);
919 mpEdit
[nPane
]->SetControlFont( aFont
);
923 // -----------------------------------------------------------------------
925 static String
GetAtomText( const Atom
* pAtom
)
930 const DffRecordHeader
& rHeader
= pAtom
->getHeader();
932 sprintf( buffer
, "Version = %lu\n\rInstance = %lu\n\rVersionInstance = %lu\n\rLength = %lu\n\r",
933 (UINT32
)rHeader
.nRecVer
,
934 (UINT32
)rHeader
.nRecInstance
,
935 (UINT32
)rHeader
.nImpVerInst
,
936 (UINT32
)rHeader
.nRecLen
);
937 aText
= rtl::OUString::createFromAscii( buffer
);
938 if( pAtom
->isContainer() )
944 pAtom
->seekToContent();
945 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
* >( gAtomConfigMap
[pAtom
->getType()].get() );
948 sal_Size nLength
= pAtom
->getLength();
949 aText
+= String( pAtomConfig
->format( pAtom
->getStream(), nLength
) );
953 sal_Size nLength
= pAtom
->getLength();
954 aText
+= String( ElementConfig::dump_hex( pAtom
->getStream(), nLength
) );
962 IMPL_LINK(MSViewerWorkWindow
,implSelectHdl
, AtomContainerTreeListBox
*, pListBox
)
964 int nPane
= (pListBox
== mpListBox
[1]) ? 1 : 0;
965 SvLBoxEntry
* pEntry
= mpListBox
[nPane
]->FirstSelected();
966 if( pEntry
&& pEntry
->GetUserData() )
968 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
969 mpEdit
[nPane
]->SetText( GetAtomText( pAtom
) );
971 if(!mbSelectHdlGuard
)
973 mbSelectHdlGuard
= true;
975 AtomContainerEntryPair
aPair( pListBox
, pEntry
);
977 mbSelectHdlGuard
= false;
983 void MSViewerWorkWindow::Sync( AtomContainerEntryPair
* pPair
, int nAction
)
985 if( mpDocument
[0].get() && mpDocument
[1].get() && pPair
->first
&& pPair
->second
)
987 AtomContainerTreeListBox
* pDestinationListBox
= (pPair
->first
== mpListBox
[0]) ? mpListBox
[1] : mpListBox
[0];
989 Atom
* pAtom
= static_cast<Atom
*>(pPair
->second
->GetUserData());
990 if( pAtom
&& pAtom
->getCompareAtom() )
992 SvLBoxEntry
* pEntry
= pDestinationListBox
->findAtom( pAtom
->getCompareAtom() );
998 pDestinationListBox
->Expand( pEntry
);
1000 else if( nAction
== 1 )
1002 pDestinationListBox
->Collapse( pEntry
);
1006 pDestinationListBox
->Select( pEntry
);
1013 IMPL_LINK(MSViewerWorkWindow
, implExpandingHdl
, AtomContainerEntryPair
*, pPair
)
1015 SvLBoxEntry
* pEntry
= pPair
->second
;
1016 if( pEntry
&& pEntry
->GetUserData() )
1018 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
1019 pAtom
->compare( pAtom
->getCompareAtom() );
1027 IMPL_LINK(MSViewerWorkWindow
, implCollapsingHdl
, AtomContainerEntryPair
*, pPair
)
1034 IMPL_LINK( MSViewerWorkWindow
, implMenuHdl
, Menu
*, pMenu
)
1038 USHORT nId
= pMenu
->GetCurItemId();
1041 case 2: onView(); break;
1042 case 3: onCompare(); break;
1043 case 4: Application::Quit(); break;
1049 // -----------------------------------------------------------------------
1051 MSViewerWorkWindow::~MSViewerWorkWindow()
1054 for( nPane
= 0; nPane
< 2; nPane
++ )
1056 delete mpListBox
[nPane
];
1057 delete mpEdit
[nPane
];
1064 // -----------------------------------------------------------------------
1066 void MSViewerWorkWindow::Resize()
1068 int nPaneCount
= ((mpDocument
[0].get() != 0) ? 1 : 0) + ((mpDocument
[1].get() != 0) ? 1 : 0);
1070 Size
aOutputSize( GetOutputSizePixel() );
1071 int nHeight
= aOutputSize
.Height() >> 1;
1074 int nWidth
= aOutputSize
.Width();
1075 if( nPaneCount
== 2 )
1081 for( nPane
= 0; nPane
< 2; nPane
++ )
1083 mpListBox
[nPane
]->SetPosSizePixel( nPosX
,0, nWidth
, nHeight
);
1084 mpEdit
[nPane
]->SetPosSizePixel( nPosX
, nHeight
, nWidth
, aOutputSize
.Height() - nHeight
);
1090 // -----------------------------------------------------------------------
1092 // -----------------------------------------------------------------------
1094 SAL_IMPLEMENT_MAIN()
1099 uno::Reference
< lang::XMultiServiceFactory
> xMSF
;
1102 uno::Reference
< uno::XComponentContext
> xCtx( cppu::defaultBootstrap_InitialComponentContext() );
1105 OSL_FAIL( "Error creating initial component context!" );
1109 xMSF
= uno::Reference
< lang::XMultiServiceFactory
>(xCtx
->getServiceManager(), uno::UNO_QUERY
);
1113 OSL_FAIL( "No service manager!" );
1118 uno::Sequence
< uno::Any
> aArgs( 2 );
1119 aArgs
[ 0 ] <<= rtl::OUString( UCB_CONFIGURATION_KEY1_LOCAL
);
1120 aArgs
[ 1 ] <<= rtl::OUString( UCB_CONFIGURATION_KEY2_OFFICE
);
1121 sal_Bool bSuccess
= ::ucb::ContentBroker::initialize( xMSF
, aArgs
);
1124 OSL_FAIL( "Error creating UCB!" );
1129 catch ( uno::Exception
const & )
1131 OSL_FAIL( "Exception during creation of initial component context!" );
1134 comphelper::setProcessServiceFactory( xMSF
);
1139 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aConfigURL
) )
1141 INetURLObject
aURL( aConfigURL
);
1143 aURL
.removeSegment();
1144 aURL
.removeFinalSlash();
1145 aURL
.Append( String( "msview.xml" ) );
1147 load_config( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
1151 MSViewerWorkWindow aMainWindow
;
1155 const rtl::OUString
aFile1( rtl::OUString::createFromAscii(argv
[1]) );
1156 PPTDocumentPtr
pDocument1( new PPTDocument( aFile1
) );
1160 const rtl::OUString
aFile2( rtl::OUString::createFromAscii(argv
[2]) );
1162 PPTDocumentPtr pDocument2
;
1163 pDocument2
.reset( new PPTDocument( aFile2
) );
1164 aMainWindow
.Compare( pDocument1
, pDocument2
);
1168 aMainWindow
.View( pDocument1
, 0 );
1174 Application::Execute();
1182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */