1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
24 #include <boost/shared_ptr.hpp>
25 #include <sot/storage.hxx>
26 #include <svtools/svtools.hrc>
29 #include <vcl/event.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/wrkwin.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <vcl/fixed.hxx>
34 #include <vcl/edit.hxx>
35 #include <vcl/button.hxx>
36 #include <vcl/lstbox.hxx>
37 #include <svtools/filectrl.hxx>
38 #include <tools/urlobj.hxx>
39 #include <osl/file.hxx>
40 #include <vcl/unohelp2.hxx>
41 #include <svtools/treelistbox.hxx>
42 #include <svtools/svmedit.hxx>
43 #include <sfx2/filedlghelper.hxx>
45 #include <toolkit/helper/vclunohelper.hxx>
47 #include <tools/stream.hxx>
48 #include <tools/resmgr.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <cppuhelper/servicefactory.hxx>
52 #include <cppuhelper/bootstrap.hxx>
54 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56 #include <com/sun/star/awt/XWindowPeer.hpp>
57 #include <com/sun/star/awt/XToolkit.hpp>
58 #include <com/sun/star/awt/WindowDescriptor.hpp>
59 #include <com/sun/star/awt/WindowAttribute.hpp>
60 #include <svx/msdffdef.hxx>
62 #include <unotools/localfilehelper.hxx>
64 #include "xmlconfig.hxx"
67 using namespace ::com::sun::star
;
71 enum CompareStatus
{ CMP_NOTYET
= 0, CMP_EQUAL
= 1, CMP_NOTEQUAL
= 2, CMP_NOTAVAILABLE
= 3 };
72 static ColorData gColors
[] = { COL_BLACK
, COL_GREEN
, COL_RED
, COL_CYAN
};
79 /** imports this atom and its child atoms */
80 static Atom
* import( const DffRecordHeader
& rRootRecordHeader
, SvStream
& rStCtrl
);
81 static Atom
* import( UINT16 nRecType
, SvStream
& rStCtrl
);
83 inline const DffRecordHeader
& getHeader() const;
85 /** returns true if at least one atom with the given nRecType is found */
86 inline bool hasChildAtom( sal_uInt16 nRecType
) const;
88 /** returns true if at least one atom with the given nRecType and nRecInstnace is found */
89 inline bool hasChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const;
91 /** returns the first child atom with nRecType or NULL */
92 inline const Atom
* findFirstChildAtom( sal_uInt16 nRecType
) const;
94 /** returns the next child atom after pLast with nRecType or NULL */
95 const Atom
* findNextChildAtom( sal_uInt16 nRecType
, const Atom
* pLast
) const;
97 /** returns the first child atom with nRecType and nRecInstance or NULL */
98 inline const Atom
* findFirstChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const;
100 /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
101 const Atom
* findNextChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
, const Atom
* pLast
) const;
103 /** returns the first child atom or NULL */
104 inline const Atom
* findFirstChildAtom() const;
106 /** returns the next child atom after pLast or NULL */
107 inline const Atom
* findNextChildAtom( const Atom
* pLast
) const;
109 /** returns true if this atom is a container */
110 inline bool isContainer() const;
112 /** seeks to the contents of this atom */
113 inline bool seekToContent() const;
115 /** returns the record type */
116 inline sal_uInt16
getType() const;
118 /** returns the record instance */
119 inline sal_uInt16
getInstance() const;
121 /** returns the record length */
122 inline sal_uInt32
getLength() const;
124 SvStream
& getStream() const { return mrStream
; }
126 bool operator==( const Atom
& rAtom
) const;
128 CompareStatus
getCompareStatus() const { return meStatus
; }
130 void compare( Atom
* pAtom
);
131 bool compareContent( Atom
& rAtom
);
133 Atom
* getCompareAtom() const { return mpCompareAtom
; }
134 void setCompareAtom( Atom
* pAtom
) { mpCompareAtom
= pAtom
; }
137 Atom( const DffRecordHeader
& rRecordHeader
, SvStream
& rStCtrl
);
139 // statics for compare
140 static Atom
* skipAtoms( Atom
* pContainer
, Atom
* pAtom
, Atom
* pSkipTo
);
141 static Atom
* findFirstEqualAtom( Atom
* pCompare
, Atom
* pContainer
, Atom
* pSearch
, int& nDistance
);
144 DffRecordHeader maRecordHeader
;
148 CompareStatus meStatus
;
152 bool Atom::operator==( const Atom
& rAtom
) const
154 return ( maRecordHeader
.nRecType
== rAtom
.maRecordHeader
.nRecType
) &&
155 ( maRecordHeader
.nRecVer
== rAtom
.maRecordHeader
.nRecVer
) &&
156 ( maRecordHeader
.nRecInstance
== rAtom
.maRecordHeader
.nRecInstance
);
159 bool Atom::compareContent( Atom
& rAtom
)
161 if( maRecordHeader
.nRecLen
== rAtom
.maRecordHeader
.nRecLen
)
164 rAtom
.seekToContent();
166 SvStream
& rStream1
= getStream();
167 SvStream
& rStream2
= rAtom
.getStream();
169 const int nBufferSize
= 1024;
170 boost::shared_ptr
< char > buffer1( new char[nBufferSize
] );
171 boost::shared_ptr
< char > buffer2( new char[nBufferSize
] );
173 sal_uInt32 nLength
= maRecordHeader
.nRecLen
;
177 sal_Size nRead
= (nBufferSize
< nLength
) ? nBufferSize
: nLength
;
178 nRead
= rStream1
.Read( (void*)buffer1
.get(), nRead
);
181 if( rStream2
.Read( (void*)buffer2
.get(), nRead
) != nRead
)
183 if( memcmp( (void*)buffer1
.get(), (void*)buffer2
.get(), nRead
) != 0 )
195 inline bool Atom::hasChildAtom( sal_uInt16 nRecType
) const
197 return findFirstChildAtom( nRecType
) != NULL
;
200 inline bool Atom::hasChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const
202 return findFirstChildAtom( nRecType
, nRecInstance
) != NULL
;
205 inline const Atom
* Atom::findFirstChildAtom( sal_uInt16 nRecType
) const
207 return findNextChildAtom( nRecType
, NULL
);
210 inline const DffRecordHeader
& Atom::getHeader() const
212 return maRecordHeader
;
215 inline const Atom
* Atom::findFirstChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
) const
217 return findNextChildAtom( nRecType
, nRecInstance
, NULL
);
220 inline const Atom
* Atom::findFirstChildAtom() const
225 inline const Atom
* Atom::findNextChildAtom( const Atom
* pLast
) const
227 return pLast
? pLast
->mpNextAtom
: pLast
;
230 inline bool Atom::isContainer() const
232 return (bool)maRecordHeader
.IsContainer();
235 inline bool Atom::seekToContent() const
237 maRecordHeader
.SeekToContent( mrStream
);
238 return mrStream
.GetError() == 0;
241 inline sal_uInt16
Atom::getType() const
243 return maRecordHeader
.nRecType
;
246 inline sal_uInt16
Atom::getInstance() const
248 return maRecordHeader
.nRecInstance
;
251 inline sal_uInt32
Atom::getLength() const
253 return maRecordHeader
.nRecLen
;
256 Atom::Atom( const DffRecordHeader
& rRecordHeader
, SvStream
& rStream
)
257 : maRecordHeader( rRecordHeader
),
261 meStatus( CMP_NOTYET
),
264 // check if we need to force this to a container
265 if( maRecordHeader
.nRecVer
!= DFF_PSFLAG_CONTAINER
)
267 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
* >( gAtomConfigMap
[ maRecordHeader
.nRecType
].get() );
268 if( pAtomConfig
&& pAtomConfig
->isContainer() )
270 maRecordHeader
.nRecVer
= DFF_PSFLAG_CONTAINER
;
276 if( seekToContent() )
278 DffRecordHeader aChildHeader
;
280 Atom
* pLastAtom
= NULL
;
282 while( (mrStream
.GetError() == 0 ) && ( mrStream
.Tell() < maRecordHeader
.GetRecEndFilePos() ) )
284 mrStream
>> aChildHeader
;
286 if( mrStream
.GetError() == 0 )
288 Atom
* pAtom
= new Atom( aChildHeader
, mrStream
);
291 pLastAtom
->mpNextAtom
= pAtom
;
292 if( mpFirstChild
== NULL
)
293 mpFirstChild
= pAtom
;
301 maRecordHeader
.SeekToEndOfRecord( mrStream
);
306 Atom
* pChild
= mpFirstChild
;
309 Atom
* pNextChild
= pChild
->mpNextAtom
;
315 /** imports this atom and its child atoms */
316 Atom
* Atom::import( const DffRecordHeader
& rRootRecordHeader
, SvStream
& rStCtrl
)
318 Atom
* pRootAtom
= new Atom( rRootRecordHeader
, rStCtrl
);
320 if( rStCtrl
.GetError() == 0 )
331 /** imports this atom and its child atoms */
332 Atom
* Atom::import( UINT16 nRecType
, SvStream
& rStCtrl
)
334 rStCtrl
.Seek( STREAM_SEEK_TO_END
);
335 sal_Size nStreamLength
= rStCtrl
.Tell();
336 rStCtrl
.Seek( STREAM_SEEK_TO_BEGIN
);
338 DffRecordHeader aRootRecordHeader
;
339 aRootRecordHeader
.nRecVer
= DFF_PSFLAG_CONTAINER
;
340 aRootRecordHeader
.nRecInstance
= 0;
341 aRootRecordHeader
.nImpVerInst
= 0;
342 aRootRecordHeader
.nRecType
= nRecType
;
343 aRootRecordHeader
.nRecLen
= nStreamLength
;
344 aRootRecordHeader
.nFilePos
= 0;
346 return import( aRootRecordHeader
, rStCtrl
);
349 /** returns the next child atom after pLast with nRecType or NULL */
350 const Atom
* Atom::findNextChildAtom( sal_uInt16 nRecType
, const Atom
* pLast
) const
352 Atom
* pChild
= pLast
!= NULL
? pLast
->mpNextAtom
: mpFirstChild
;
353 while( pChild
&& pChild
->maRecordHeader
.nRecType
!= nRecType
)
355 pChild
= pChild
->mpNextAtom
;
361 /** returns the next child atom after pLast with nRecType and nRecInstance or NULL */
362 const Atom
* Atom::findNextChildAtom( sal_uInt16 nRecType
, sal_uInt16 nRecInstance
, const Atom
* pLast
) const
364 const Atom
* pChild
= pLast
!= NULL
? pLast
->mpNextAtom
: mpFirstChild
;
365 while( pChild
&& (pChild
->maRecordHeader
.nRecType
!= nRecType
) && (pChild
->maRecordHeader
.nRecInstance
!= nRecInstance
) )
367 pChild
= findNextChildAtom( pChild
);
373 Atom
* Atom::findFirstEqualAtom( Atom
* pCompare
, Atom
* pContainer
, Atom
* pSearch
, int& nDistance
)
379 if( *pSearch
== *pCompare
)
382 pSearch
= const_cast< Atom
* >( pContainer
->findNextChildAtom( pSearch
) );
389 Atom
* Atom::skipAtoms( Atom
* pContainer
, Atom
* pAtom
, Atom
* pSkipTo
)
391 while( pAtom
&& (pAtom
!= pSkipTo
) )
393 pAtom
->meStatus
= CMP_NOTAVAILABLE
;
394 pAtom
= const_cast< Atom
* >( pContainer
->findNextChildAtom( pAtom
) );
400 void Atom::compare( Atom
* pAtom
)
404 if( meStatus
== CMP_NOTYET
)
406 mpCompareAtom
= pAtom
;
407 pAtom
->mpCompareAtom
= this;
409 mpCompareAtom
= pAtom
;
410 pAtom
->mpCompareAtom
= this;
412 meStatus
= pAtom
->meStatus
= ( *this == *pAtom
) ? CMP_EQUAL
: CMP_NOTEQUAL
;
415 if(meStatus
== CMP_EQUAL
)
419 /** returns the first child atom or NULL */
420 Atom
* pChildAtom1
= const_cast< Atom
* >( findFirstChildAtom() );
422 if( pChildAtom1
&& (pChildAtom1
->meStatus
== CMP_NOTYET
) )
424 Atom
* pChildAtom2
= const_cast< Atom
* >( pAtom
->findFirstChildAtom() );
425 while( pChildAtom1
&& pChildAtom2
)
427 if( !(*pChildAtom1
== *pChildAtom2
) )
432 Atom
* pFind1
= findFirstEqualAtom( pChildAtom1
, pAtom
, const_cast< Atom
* >( pAtom
->findNextChildAtom( pChildAtom2
)), nDistance1
);
433 Atom
* pFind2
= findFirstEqualAtom( pChildAtom2
, this, const_cast< Atom
* >(findNextChildAtom( pChildAtom1
)), nDistance2
);
435 if( pFind1
&& (!pFind2
|| (nDistance1
< nDistance2
) ) )
437 pChildAtom2
= skipAtoms( pAtom
, pChildAtom2
, pFind1
);
441 pChildAtom1
= skipAtoms( this, pChildAtom1
, pFind2
);
445 pChildAtom1
= skipAtoms( this, pChildAtom1
, 0 );
446 pChildAtom2
= skipAtoms( pAtom
, pChildAtom2
, 0 );
450 if( pChildAtom1
&& pChildAtom2
)
452 pChildAtom1
->mpCompareAtom
= pChildAtom2
;
453 pChildAtom2
->mpCompareAtom
= pChildAtom1
;
455 pChildAtom1
->meStatus
= pChildAtom2
->meStatus
=
456 (pChildAtom1
->isContainer() || pChildAtom1
->compareContent( *pChildAtom2
)) ?
457 CMP_EQUAL
: CMP_NOTEQUAL
;
459 pChildAtom1
= const_cast< Atom
* >( findNextChildAtom( pChildAtom1
) );
460 pChildAtom2
= const_cast< Atom
* >( pAtom
->findNextChildAtom( pChildAtom2
) );
467 if( !compareContent( *pAtom
) )
469 meStatus
= pAtom
->meStatus
= CMP_NOTEQUAL
;
480 class AtomBoxString
: public SvLBoxString
483 AtomBoxString( SvTreeListEntry
* pEntry
, const String
& rStr
)
484 : SvLBoxString( pEntry
, 0, rStr
)
490 const Point
& rPos
, SvLBox
& rOutDev
, const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
)
492 Color aOldTextColor
= rOutDev
.GetTextColor();
494 if( pEntry
&& pEntry
->GetUserData() )
496 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
497 rOutDev
.SetTextColor( Color( gColors
[ pAtom
->getCompareStatus() ] ) );
500 SvLBoxString::Paint(rPos
, rOutDev
, pView
, pEntry
);
502 rOutDev
.SetTextColor( aOldTextColor
);
509 class AtomContainerTreeListBox
: public SvTreeListBox
512 AtomContainerTreeListBox( vcl::Window
* pParent
);
513 ~AtomContainerTreeListBox();
515 void SetRootAtom( const Atom
* pAtom
);
518 void SetCollapsingHdl(const Link
<>& rNewHdl
){maCollapsingHdl
=rNewHdl
;}
519 const Link
<>& GetCollapsingHdl() const { return maCollapsingHdl
; }
521 void SetExpandingHdl(const Link
<>& rNewHdl
){maExpandingHdl
=rNewHdl
;}
522 const Link
<>& GetExpandingHdl() const { return maExpandingHdl
; }
524 virtual BOOL
Expand( SvTreeListEntry
* pParent
);
525 virtual BOOL
Collapse( SvTreeListEntry
* pParent
);
527 SvTreeListEntry
* findAtom( Atom
* pAtom
);
529 virtual void InitEntry(SvTreeListEntry
*, const OUString
&, const Image
&, const Image
&);
530 virtual void SetTabs();
533 void InsertAtom( const Atom
* pAtom
, SvTreeListEntry
* pParent
= 0 );
534 const Atom
* mpRootAtom
;
539 Image maImgCollapsed
;
540 bool mbRecursiveGuard
;
541 Link
<> maCollapsingHdl
;
542 Link
<> maExpandingHdl
;
545 typedef std::pair
< AtomContainerTreeListBox
*, SvTreeListEntry
* > AtomContainerEntryPair
;
547 AtomContainerTreeListBox::AtomContainerTreeListBox( vcl::Window
* pParent
)
548 : SvTreeListBox( pParent
, WB_HASBUTTONS
|WB_HASLINES
|WB_HASBUTTONSATROOT
|WB_3DLOOK
|WB_BORDER
),
549 mpRootAtom( 0 ), mbRecursiveGuard( false )
551 mpResMgr
= ResMgr::CreateResMgr( "svt" );
552 maImgCollapsed
= Image( ResId( RID_IMG_TREENODE_COLLAPSED
, mpResMgr
) );
553 maImgExpanded
= Image( ResId( RID_IMG_TREENODE_EXPANDED
, mpResMgr
) );
555 // SetDefaultExpandedEntryBmp( aExpanded );
556 // SetDefaultCollapsedEntryBmp(aCollapsed );
558 maImgFolder
= Image( ResId( IMG_SVT_FOLDER
, mpResMgr
) );
559 maImgAtom
= Image( ResId( IMG_SVT_DOCTEMPLATE_DOCINFO_SMALL
, mpResMgr
) );
562 AtomContainerTreeListBox::~AtomContainerTreeListBox()
566 void AtomContainerTreeListBox::SetTabs()
568 if( IsEditingActive() )
573 short nIndent
= 0; GetIndent();
574 long nNodeWidthPixel
= maImgCollapsed
.GetSizePixel().Width();
575 long nContextWidthDIV2
= nNodeWidthPixel
>> 1;
577 long nStartPos
= 2 + ( nIndent
+ nContextWidthDIV2
);
578 AddTab( nStartPos
, SvLBoxTabFlags::DYNAMIC
| SvLBoxTabFlags::ADJUST_CENTER
);
579 nStartPos
+= nNodeWidthPixel
+ 5;
580 AddTab( nStartPos
, SvLBoxTabFlags::DYNAMIC
| SvLBoxTabFlags::ADJUST_CENTER
| SvLBoxTabFlags::SHOW_SELECTION
);
581 nStartPos
+= nContextWidthDIV2
+ 5;
582 AddTab( nStartPos
, SvLBoxTabFlags::DYNAMIC
|SvLBoxTabFlags::ADJUST_LEFT
| SvLBoxTabFlags::SHOW_SELECTION
);
585 void AtomContainerTreeListBox::InitEntry(SvTreeListEntry
* pEntry
, const OUString
& aStr
,
586 const Image
& aCollEntryBmp
, const Image
& aExpEntryBmp
)
588 pEntry
->AddItem( new SvLBoxContextBmp(pEntry
,0, aCollEntryBmp
,aExpEntryBmp
, true) );
589 pEntry
->AddItem( new SvLBoxContextBmp(pEntry
,0, maImgAtom
, maImgAtom
, true) );
590 pEntry
->AddItem( new AtomBoxString( pEntry
, aStr
) );
593 SvTreeListEntry
* AtomContainerTreeListBox::findAtom( Atom
* pAtom
)
595 SvTreeListEntry
* pEntry
= First();
598 if( pEntry
->GetUserData() == pAtom
)
601 pEntry
= Next( pEntry
);
607 BOOL
AtomContainerTreeListBox::Expand( SvTreeListEntry
* pParent
)
610 if( !mbRecursiveGuard
)
612 mbRecursiveGuard
= true;
613 AtomContainerEntryPair
aPair( this, pParent
);
614 maExpandingHdl
.Call( &aPair
);
616 bRet
= SvTreeListBox::Expand( pParent
);
617 mbRecursiveGuard
= false;
622 BOOL
AtomContainerTreeListBox::Collapse( SvTreeListEntry
* pParent
)
625 if( !mbRecursiveGuard
)
627 mbRecursiveGuard
= true;
628 AtomContainerEntryPair
aPair( this, pParent
);
629 maCollapsingHdl
.Call( &aPair
);
631 bRet
= SvTreeListBox::Collapse( pParent
);
632 mbRecursiveGuard
= false;
637 void AtomContainerTreeListBox::SetRootAtom( const Atom
* pAtom
)
640 InsertAtom( mpRootAtom
);
643 void AtomContainerTreeListBox::InsertAtom( const Atom
* pAtom
, SvTreeListEntry
* pParent
/* = 0 */ )
647 const DffRecordHeader
& rHeader
= pAtom
->getHeader();
652 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
*>( gAtomConfigMap
[rHeader
.nRecType
].get() );
655 aText
= pAtomConfig
->getName();
657 if( !aText
.getLength() )
659 sprintf( buffer
, "unknown_0x%04x", rHeader
.nRecType
);
660 aText
+= OUString::createFromAscii( buffer
);
663 sprintf( buffer
, " (I: %lu L: %lu)", (UINT32
)rHeader
.nRecVer
, (UINT32
)rHeader
.nRecLen
);
664 aText
+= String( OUString::createFromAscii( buffer
) );
666 SvTreeListEntry
* pEntry
= 0;
667 if( pAtom
->isContainer() && pAtom
->findFirstChildAtom() )
669 pEntry
= InsertEntry( aText
, maImgExpanded
, maImgCollapsed
, pParent
);
671 /** returns the first child atom or NULL */
672 const Atom
* pChildAtom
= pAtom
->findFirstChildAtom();
676 InsertAtom( pChildAtom
, pEntry
);
677 pChildAtom
= pAtom
->findNextChildAtom( pChildAtom
);
682 pEntry
= InsertEntry( aText
, pParent
);
687 pEntry
->SetUserData( (void*)pAtom
);
689 if( pAtom
->isContainer() )
691 SvLBoxContextBmp
* pBoxBmp
= dynamic_cast< SvLBoxContextBmp
* >( pEntry
->GetItem( pEntry
->ItemCount() - 2 ) );
694 pBoxBmp
->SetBitmap1( pEntry
, maImgFolder
);
695 pBoxBmp
->SetBitmap2( pEntry
, maImgFolder
);
701 new AtomBoxString( pEntry, aText, pImage ),
702 pEntry->ItemCount() - 1 );
710 extern void load_config( const OUString
& rPath
);
715 PPTDocument( const OUString
& rFilePath
);
718 Atom
* getRootAtom() const;
721 void Load( const OUString
& rFilePath
);
724 SvStream
* mpDocStream
;
725 tools::SvRef
<SotStorage
> maStorage
;
728 typedef boost::shared_ptr
< PPTDocument
> PPTDocumentPtr
;
730 PPTDocument::PPTDocument(const OUString
& rFilePath
)
731 : mpAtom(0), mpDocStream(0)
736 PPTDocument::~PPTDocument()
742 void PPTDocument::Load( const OUString
& rFilePath
)
744 maStorage
= new SotStorage( rFilePath
, STREAM_STD_READ
);
745 if( !maStorage
->GetError() )
747 mpDocStream
= maStorage
->OpenSotStream( String( "PowerPoint Document" ), STREAM_STD_READ
);
750 DffRecordHeader aRecordHeader
;
751 *mpDocStream
>> aRecordHeader
;
753 mpAtom
= Atom::import( 65530, *mpDocStream
);
758 Atom
* PPTDocument::getRootAtom() const
765 class MSViewerWorkWindow
: public WorkWindow
768 MSViewerWorkWindow();
769 ~MSViewerWorkWindow();
771 PPTDocumentPtr
Load();
776 void View( const PPTDocumentPtr
& pDocument
, int nPane
);
777 void Compare( const PPTDocumentPtr
& pDocument1
, const PPTDocumentPtr
& pDocument2
);
779 virtual void Resize();
782 void Sync( AtomContainerEntryPair
* pPair
, int nAction
);
784 AtomContainerTreeListBox
* mpListBox
[2];
785 MultiLineEdit
* mpEdit
[2];
786 PPTDocumentPtr mpDocument
[2];
788 PopupMenu
* mpFileMenu
;
789 bool mbSelectHdlGuard
;
790 DECL_LINK( implSelectHdl
, AtomContainerTreeListBox
* );
791 DECL_LINK( implExpandingHdl
, AtomContainerEntryPair
* );
792 DECL_LINK( implCollapsingHdl
, AtomContainerEntryPair
* );
793 DECL_LINK( implMenuHdl
, Menu
* );
798 void MSViewerWorkWindow::onView()
800 PPTDocumentPtr
pDocument( Load() );
801 if( pDocument
.get() )
804 View( pDocument
, 0 );
808 void MSViewerWorkWindow::onClose()
812 void MSViewerWorkWindow::onCompare()
814 PPTDocumentPtr
pDocument1( Load() );
815 if( pDocument1
.get() )
817 PPTDocumentPtr
pDocument2( Load() );
818 if( pDocument2
.get() )
821 Compare( pDocument1
, pDocument2
);
826 void MSViewerWorkWindow::Compare( const PPTDocumentPtr
& pDocument1
, const PPTDocumentPtr
& pDocument2
)
828 if( pDocument1
.get() && pDocument2
.get() )
830 Atom
* pAtom1
= pDocument1
->getRootAtom();
831 Atom
* pAtom2
= pDocument2
->getRootAtom();
832 pAtom1
->setCompareAtom( pAtom2
);
833 pAtom2
->setCompareAtom( pAtom1
);
836 View( pDocument1
, 0 );
837 View( pDocument2
, 1 );
840 void MSViewerWorkWindow::View( const PPTDocumentPtr
& pDocument
, int nPane
)
842 if( ((nPane
!= 0) && (nPane
!= 1)) || (pDocument
.get() == 0) )
845 mpDocument
[nPane
] = pDocument
;
847 mpListBox
[nPane
]->SetRootAtom( pDocument
->getRootAtom() );
848 mpListBox
[nPane
]->Expand( mpListBox
[nPane
]->GetEntry(0) );
849 mpListBox
[nPane
]->Show();
850 mpEdit
[nPane
]->Show();
855 PPTDocumentPtr
MSViewerWorkWindow::Load()
857 ::sfx2::FileDialogHelper
aDlg(
858 ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, 0 );
859 String
aStrFilterType( "*.ppt" );
860 aDlg
.AddFilter( aStrFilterType
, aStrFilterType
);
861 // INetURLObject aFile( SvtPathOptions().GetPalettePath() );
862 // aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) );
864 PPTDocumentPtr pDocument
;
865 if ( aDlg
.Execute() == ERRCODE_NONE
)
867 pDocument
.reset( new PPTDocument( aDlg
.GetPath() ) );
875 MSViewerWorkWindow::MSViewerWorkWindow() :
876 WorkWindow( 0, WB_APP
| WB_STDWORK
| WB_3DLOOK
),mbSelectHdlGuard(false)
878 Size
aOutputSize( 400, 600 );
879 SetOutputSizePixel( aOutputSize
);
880 SetText( String( "MSViewer" ) );
882 Size
aOutSize( GetOutputSizePixel() );
884 Font
aFont( String( "Courier" ), GetFont().GetSize() );
886 mpMenuBar
= new MenuBar();
887 mpMenuBar
->InsertItem( 1, String( "~File" ) );
888 mpFileMenu
= new PopupMenu();
889 mpFileMenu
->InsertItem( 2, String( "~View" ) );
890 mpFileMenu
->InsertItem( 3, String( "~Compare" ) );
891 mpFileMenu
->InsertSeparator();
892 mpFileMenu
->InsertItem( 4, String( "~Quit" ) );
893 mpFileMenu
->SetSelectHdl( LINK( this, MSViewerWorkWindow
, implMenuHdl
) );
895 mpMenuBar
->SetPopupMenu( 1, mpFileMenu
);
896 SetMenuBar( mpMenuBar
);
898 for( nPane
= 0; nPane
< 2; nPane
++ )
900 mpListBox
[nPane
] = new AtomContainerTreeListBox( this );
901 mpListBox
[nPane
]->SetSelectHdl( LINK( this, MSViewerWorkWindow
, implSelectHdl
) );
902 mpListBox
[nPane
]->SetExpandingHdl( LINK( this, MSViewerWorkWindow
, implExpandingHdl
) );
903 mpListBox
[nPane
]->SetCollapsingHdl( LINK( this, MSViewerWorkWindow
, implCollapsingHdl
) );
905 mpEdit
[nPane
] = VclPtr
<MultiLineEdit
>::Create(this, WB_3DLOOK
| WB_BORDER
| WB_LEFT
| WB_TOP
| WB_READONLY
| WB_HSCROLL
| WB_VSCROLL
);
906 mpEdit
[nPane
]->SetReadOnly( TRUE
);
907 mpEdit
[nPane
]->SetReadOnly( TRUE
);
908 mpEdit
[nPane
]->SetControlFont( aFont
);
914 static String
GetAtomText( const Atom
* pAtom
)
919 const DffRecordHeader
& rHeader
= pAtom
->getHeader();
921 sprintf( buffer
, "Version = %lu\n\rInstance = %lu\n\rVersionInstance = %lu\n\rLength = %lu\n\r",
922 (UINT32
)rHeader
.nRecVer
,
923 (UINT32
)rHeader
.nRecInstance
,
924 (UINT32
)rHeader
.nImpVerInst
,
925 (UINT32
)rHeader
.nRecLen
);
926 aText
= OUString::createFromAscii( buffer
);
927 if( pAtom
->isContainer() )
933 pAtom
->seekToContent();
934 AtomConfig
* pAtomConfig
= dynamic_cast< AtomConfig
* >( gAtomConfigMap
[pAtom
->getType()].get() );
937 sal_Size nLength
= pAtom
->getLength();
938 aText
+= String( pAtomConfig
->format( pAtom
->getStream(), nLength
) );
942 sal_Size nLength
= pAtom
->getLength();
943 aText
+= String( ElementConfig::dump_hex( pAtom
->getStream(), nLength
) );
951 IMPL_LINK(MSViewerWorkWindow
,implSelectHdl
, AtomContainerTreeListBox
*, pListBox
)
953 int nPane
= (pListBox
== mpListBox
[1]) ? 1 : 0;
954 SvTreeListEntry
* pEntry
= mpListBox
[nPane
]->FirstSelected();
955 if( pEntry
&& pEntry
->GetUserData() )
957 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
958 mpEdit
[nPane
]->SetText( GetAtomText( pAtom
) );
960 if(!mbSelectHdlGuard
)
962 mbSelectHdlGuard
= true;
964 AtomContainerEntryPair
aPair( pListBox
, pEntry
);
966 mbSelectHdlGuard
= false;
972 void MSViewerWorkWindow::Sync( AtomContainerEntryPair
* pPair
, int nAction
)
974 if( mpDocument
[0].get() && mpDocument
[1].get() && pPair
->first
&& pPair
->second
)
976 AtomContainerTreeListBox
* pDestinationListBox
= (pPair
->first
== mpListBox
[0]) ? mpListBox
[1] : mpListBox
[0];
978 Atom
* pAtom
= static_cast<Atom
*>(pPair
->second
->GetUserData());
979 if( pAtom
&& pAtom
->getCompareAtom() )
981 SvTreeListEntry
* pEntry
= pDestinationListBox
->findAtom( pAtom
->getCompareAtom() );
987 pDestinationListBox
->Expand( pEntry
);
989 else if( nAction
== 1 )
991 pDestinationListBox
->Collapse( pEntry
);
995 pDestinationListBox
->Select( pEntry
);
1002 IMPL_LINK(MSViewerWorkWindow
, implExpandingHdl
, AtomContainerEntryPair
*, pPair
)
1004 SvTreeListEntry
* pEntry
= pPair
->second
;
1005 if( pEntry
&& pEntry
->GetUserData() )
1007 Atom
* pAtom
= static_cast<Atom
*>( pEntry
->GetUserData() );
1008 pAtom
->compare( pAtom
->getCompareAtom() );
1016 IMPL_LINK(MSViewerWorkWindow
, implCollapsingHdl
, AtomContainerEntryPair
*, pPair
)
1023 IMPL_LINK( MSViewerWorkWindow
, implMenuHdl
, Menu
*, pMenu
)
1027 USHORT nId
= pMenu
->GetCurItemId();
1030 case 2: onView(); break;
1031 case 3: onCompare(); break;
1032 case 4: Application::Quit(); break;
1040 MSViewerWorkWindow::~MSViewerWorkWindow()
1043 for( nPane
= 0; nPane
< 2; nPane
++ )
1045 delete mpListBox
[nPane
];
1046 delete mpEdit
[nPane
];
1055 void MSViewerWorkWindow::Resize()
1057 int nPaneCount
= ((mpDocument
[0].get() != 0) ? 1 : 0) + ((mpDocument
[1].get() != 0) ? 1 : 0);
1059 Size
aOutputSize( GetOutputSizePixel() );
1060 int nHeight
= aOutputSize
.Height() >> 1;
1063 int nWidth
= aOutputSize
.Width();
1064 if( nPaneCount
== 2 )
1070 for( nPane
= 0; nPane
< 2; nPane
++ )
1072 mpListBox
[nPane
]->SetPosSizePixel( nPosX
,0, nWidth
, nHeight
);
1073 mpEdit
[nPane
]->SetPosSizePixel( nPosX
, nHeight
, nWidth
, aOutputSize
.Height() - nHeight
);
1083 SAL_IMPLEMENT_MAIN()
1088 uno::Reference
< lang::XMultiServiceFactory
> xMSF
;
1091 uno::Reference
< uno::XComponentContext
> xCtx( cppu::defaultBootstrap_InitialComponentContext() );
1094 OSL_FAIL( "Error creating initial component context!" );
1098 xMSF
= uno::Reference
< lang::XMultiServiceFactory
>(xCtx
->getServiceManager(), uno::UNO_QUERY
);
1102 OSL_FAIL( "No service manager!" );
1106 catch ( uno::Exception
const & )
1108 OSL_FAIL( "Exception during creation of initial component context!" );
1111 comphelper::setProcessServiceFactory( xMSF
);
1116 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aConfigURL
) )
1118 INetURLObject
aURL( aConfigURL
);
1120 aURL
.removeSegment();
1121 aURL
.removeFinalSlash();
1122 aURL
.Append( String( "msview.xml" ) );
1124 load_config( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
1128 MSViewerWorkWindow aMainWindow
;
1132 const OUString
aFile1( OUString::createFromAscii(argv
[1]) );
1133 PPTDocumentPtr
pDocument1( new PPTDocument( aFile1
) );
1137 const OUString
aFile2( OUString::createFromAscii(argv
[2]) );
1139 PPTDocumentPtr pDocument2
;
1140 pDocument2
.reset( new PPTDocument( aFile2
) );
1141 aMainWindow
.Compare( pDocument1
, pDocument2
);
1145 aMainWindow
.View( pDocument1
, 0 );
1151 Application::Execute();
1159 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */