1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucbhelper.hxx"
30 #include <cppuhelper/weak.hxx>
31 #include <cppuhelper/bootstrap.hxx>
32 #include <comphelper/processfactory.hxx>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <com/sun/star/beans/XPropertySetInfo.hpp>
35 #include <com/sun/star/io/XActiveDataSink.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/sdbc/XResultSet.hpp>
38 #include <com/sun/star/ucb/XCommandInfo.hpp>
39 #include <com/sun/star/ucb/XContentAccess.hpp>
40 #include <com/sun/star/ucb/CommandAbortedException.hpp>
41 #include <com/sun/star/ucb/ContentInfo.hpp>
42 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
43 
44 #include "rtl/ref.hxx"
45 #include <ucbhelper/content.hxx>
46 #include <ucbhelper/contentbroker.hxx>
47 #include <ucbhelper/commandenvironment.hxx>
48 #include <svtools/svtreebx.hxx>
49 #include <vcl/wrkwin.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/menu.hxx>
52 #include <vcl/dialog.hxx>
53 #include <vcl/fixed.hxx>
54 #include <vcl/group.hxx>
55 #include <vcl/button.hxx>
56 #include <vcl/msgbox.hxx>
57 #include <ucbhelper/macros.hxx>
58 #include <ucbhelper/configurationkeys.hxx>
59 
60 #ifndef _UCBEXPLORER_HRC
61 #include "ucbexplorer.hrc"
62 #endif
63 
64 using namespace com::sun::star;
65 using namespace com::sun::star::beans;
66 using namespace com::sun::star::io;
67 using namespace com::sun::star::lang;
68 using namespace com::sun::star::sdbc;
69 using namespace com::sun::star::task;
70 using namespace com::sun::star::ucb;
71 using namespace com::sun::star::uno;
72 using namespace rtl;
73 
74 //=========================================================================
75 //
76 // class TestDataSink.
77 //
78 //=========================================================================
79 
80 class TestDataSink : public cppu::OWeakObject, public XActiveDataSink
81 {
82     uno::Reference< XInputStream > m_xStream;
83 
84 public:
85 //    TestDataSink() {}
86 //    virtual ~TestDataSink();
87 
88     // XInterface methods
89     virtual Any SAL_CALL queryInterface( const Type & rType )
90         throw( RuntimeException );
91     virtual void SAL_CALL acquire()
92         throw ();
93     virtual void SAL_CALL release()
94         throw ();
95 
96     // XActiveDataSink methods.
97     virtual void SAL_CALL setInputStream(
98                                 const uno::Reference< XInputStream >& aStream )
99         throw( RuntimeException );
100     virtual uno::Reference< XInputStream > SAL_CALL getInputStream()
101         throw( RuntimeException );
102 };
103 
104 //=========================================================================
105 //
106 // class StringInputDialog.
107 //
108 //=========================================================================
109 
110 class StringInputDialog : public ModalDialog
111 {
112 private:
113     FixedText    m_aNameText;
114     Edit         m_aNameEdit;
115     GroupBox     m_aNameGroup;
116     OKButton     m_aOKBtn;
117     CancelButton m_aCancelBtn;
118     HelpButton   m_aHelpBtn;
119 
120     DECL_LINK( OKHdl, Button * );
121     DECL_LINK( NameHdl, Edit * );
122 
123 public:
124     StringInputDialog( ResMgr& rResMgr,
125                        const String& rTitle,
126                        const String& rDefaultText,
127                        String* pGroupName = 0 );
128     String GetValue() const { return m_aNameEdit.GetText(); }
129     void SetValue( const String& rNewName ) { m_aNameEdit.SetText( rNewName ); }
130 };
131 
132 //=========================================================================
133 //
134 // class UcbExplorerListBoxEntry.
135 //
136 //=========================================================================
137 
138 class UcbExplorerListBoxEntry : public SvLBoxEntry
139 {
140     friend class UcbExplorerTreeListBox;
141 
142     enum EntryType { FOLDER, DOCUMENT, LINK };
143 
144     ::ucbhelper::Content m_aContent;
145     EntryType            m_eType;
146 
147 public:
148     UcbExplorerListBoxEntry();
149     virtual ~UcbExplorerListBoxEntry();
150 
151     BOOL createNewContent( const ContentInfo& rInfo,
152                            ::ucbhelper::Content& rNewContent );
153 };
154 
155 //=========================================================================
156 //
157 // class UcbExplorerTreeListBox.
158 //
159 //=========================================================================
160 
161 class UcbExplorerTreeListBox : public SvTreeListBox
162 {
163     Bitmap  m_aFolderClosed;
164     Bitmap  m_aFolderOpened;
165     Bitmap  m_aDocument;
166     Bitmap  m_aLink;
167 
168 private:
169     virtual SvLBoxEntry* CreateEntry() const;
170     virtual void         RequestingChilds( SvLBoxEntry* pParent );
171 
172 public:
173     UcbExplorerTreeListBox( ResMgr & rResMgr, Window* pParent, WinBits nWinStyle = 0 );
174     virtual ~UcbExplorerTreeListBox();
175 
176     virtual void Command( const CommandEvent& rCEvt );
177 
178     UcbExplorerListBoxEntry*
179     InsertEntry( ::ucbhelper::Content& rContent, SvLBoxEntry* pParent );
180     UcbExplorerListBoxEntry*
181     InsertEntry( const String& rURL, SvLBoxEntry* pParent = 0 );
182 };
183 
184 //=========================================================================
185 //
186 // class UcbExplorerWindow.
187 //
188 //=========================================================================
189 
190 class UcbExplorerWindow : public WorkWindow
191 {
192     friend class MyApp;
193 
194     UcbExplorerTreeListBox m_aTree;
195 
196 public:
197     UcbExplorerWindow( ResMgr & rResMgr, Window *pParent, WinBits nWinStyle );
198     virtual ~UcbExplorerWindow();
199 
200     virtual void Resize();
201 };
202 
203 //=========================================================================
204 //
205 // class MyApp.
206 //
207 //=========================================================================
208 
209 class MyApp : public Application
210 {
211 public:
212     virtual void Main();
213 };
214 
215 //=========================================================================
216 //
217 // TestDataSink implementation.
218 //
219 //=========================================================================
220 
221 // virtual
222 Any SAL_CALL TestDataSink::queryInterface( const Type & rType )
223     throw( RuntimeException )
224 {
225     Any aRet = cppu::queryInterface(
226                         rType,
227                             static_cast< XActiveDataSink * >( this ) );
228     return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
229 }
230 
231 //=========================================================================
232 // virtual
233 void SAL_CALL TestDataSink::acquire()
234     throw()
235 {
236     OWeakObject::acquire();
237 }
238 
239 //=========================================================================
240 // virtual
241 void SAL_CALL TestDataSink::release()
242     throw()
243 {
244     OWeakObject::release();
245 }
246 
247 //=========================================================================
248 // virtual
249 void SAL_CALL TestDataSink::setInputStream(
250                                 const uno::Reference< XInputStream >& aStream )
251     throw( RuntimeException )
252 {
253     m_xStream = aStream;
254 }
255 
256 //=========================================================================
257 // virtual
258 uno::Reference< XInputStream > SAL_CALL TestDataSink::getInputStream()
259     throw( RuntimeException )
260 {
261     return m_xStream;
262 }
263 
264 //=========================================================================
265 //
266 // StringInputDialog implementation.
267 //
268 //=========================================================================
269 
270 StringInputDialog::StringInputDialog( ResMgr& rResMgr,
271                                       const String& rTitle,
272                                       const String& rDefaultText,
273                                       String* pGroupName )
274   : ModalDialog( 0, ResId( DLG_STRINGINPUT, rResMgr ) ),
275   m_aNameText ( this, ResId( FT_STRINGINPUT_DLG_NAME, rResMgr ) ),
276   m_aNameEdit ( this, ResId( ED_STRINGINPUT_DLG_NAME, rResMgr ) ),
277   m_aNameGroup( this, ResId( GB_STRINGINPUT_DLG_NAME, rResMgr ) ),
278   m_aOKBtn    ( this, ResId( BT_STRINGINPUT_DLG_OK, rResMgr ) ),
279   m_aCancelBtn( this, ResId( BT_STRINGINPUT_DLG_CANCEL, rResMgr ) ),
280   m_aHelpBtn  ( this, ResId( BT_STRINGINPUT_DLG_HELP, rResMgr ) )
281 {
282     FreeResource();
283     SetText( rTitle );
284     m_aNameEdit.SetText( rDefaultText );
285     m_aOKBtn.SetClickHdl( LINK( this, StringInputDialog, OKHdl ) );
286     m_aNameEdit.SetModifyHdl( LINK( this, StringInputDialog, NameHdl ) );
287 
288     if ( pGroupName )
289         m_aNameGroup.SetText( *pGroupName );
290 };
291 
292 //=========================================================================
293 IMPL_LINK( StringInputDialog, OKHdl, Button *, EMPTYARG )
294 {
295     // trim the strings
296     m_aNameEdit.SetText(
297         m_aNameEdit.GetText().EraseLeadingChars().EraseTrailingChars() );
298     EndDialog( RET_OK );
299     return 1;
300 }
301 
302 //=========================================================================
303 IMPL_LINK( StringInputDialog, NameHdl, Edit *, EMPTYARG )
304 {
305 /*
306     // trim the strings
307     String aName = m_aNameEdit.GetText();
308     aName.EraseLeadingChars().EraseTrailingChars();
309     if ( aName.Len() )
310     {
311         if ( !m_aOKBtn.IsEnabled() )
312             m_aOKBtn.Enable( TRUE );
313     }
314     else
315     {
316         if ( m_aOKBtn.IsEnabled() )
317             m_aOKBtn.Enable( FALSE );
318     }
319 */
320     return 0;
321 }
322 
323 //=========================================================================
324 //
325 // UcbExplorerListBoxEntry implementation.
326 //
327 //=========================================================================
328 
329 UcbExplorerListBoxEntry::UcbExplorerListBoxEntry()
330 {
331 }
332 
333 //=========================================================================
334 // virtual
335 UcbExplorerListBoxEntry::~UcbExplorerListBoxEntry()
336 {
337 }
338 
339 //=========================================================================
340 BOOL UcbExplorerListBoxEntry::createNewContent( const ContentInfo& rInfo,
341                                                 ::ucbhelper::Content& rNewContent )
342 {
343     sal_Int32 nCount = rInfo.Properties.getLength();
344     Sequence< Any > aPropValues( nCount );
345     Sequence< OUString > aPropNames( nCount );
346 
347     if ( nCount > 0 )
348     {
349         // Collect property values.
350 
351         Any* pValues = aPropValues.getArray();
352         const Property* pProps = rInfo.Properties.getConstArray();
353         for ( sal_Int32 n = 0; n < nCount; ++n )
354         {
355             const OUString& rName = pProps[ n ].Name;
356 
357             std::auto_ptr< ResMgr > xManager(
358                 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( ucbexplorer ) ) );
359             StringInputDialog* pDlg = new StringInputDialog( *xManager.get(), rName, rName );
360             USHORT nRet = pDlg->Execute();
361             if ( nRet == RET_OK )
362             {
363                 OUString aValue( pDlg->GetValue() );
364 
365                 // Convert value according to supplied type info...
366 
367                 const Type& rType = pProps[ n ].Type;
368 
369                 if ( rType == getCppuType(
370                                     static_cast< const OUString * >( 0 ) ) )
371                 {
372                     // string
373                     pValues[ n ] <<= aValue;
374                 }
375                 else if ( rType == getCppuType(
376                                     static_cast< const sal_Int32 * >( 0 ) ) )
377                 {
378                     // long
379                     pValues[ n ] <<= aValue.toInt32();
380                 }
381                 else if ( rType == getCppuType(
382                                     static_cast< const sal_Int16 * >( 0 ) ) )
383                 {
384                     // short
385                     pValues[ n ] <<= sal_Int16( aValue.toInt32() ) ;
386                 }
387                 else if ( rType == getCppuBooleanType() )
388                 {
389                     // boolean
390                     pValues[ n ] <<= sal_Bool( aValue.toChar() ) ;
391                 }
392                 else if ( rType == getCppuCharType() )
393                 {
394                     // char
395                     pValues[ n ] <<= aValue.toChar();
396                 }
397                 else if ( rType == getCppuType(
398                                     static_cast< const sal_Int8 * >( 0 ) ) )
399                 {
400                     // byte
401                     pValues[ n ] <<= sal_Int8( aValue.toChar() ) ;
402                 }
403                 else if ( rType == getCppuType(
404                                     static_cast< const sal_Int64 * >( 0 ) ) )
405                 {
406                     // hyper
407                     pValues[ n ] <<= aValue.toInt64();
408                 }
409                 else if ( rType == getCppuType(
410                                     static_cast< const float * >( 0 ) ) )
411                 {
412                     // float
413                     pValues[ n ] <<= aValue.toFloat();
414                 }
415                 else if ( rType == getCppuType(
416                                     static_cast< const double * >( 0 ) ) )
417                 {
418                     // double
419                     pValues[ n ] <<= aValue.toDouble();
420                 }
421                 else
422                 {
423                     // See com/sun/star/ucb/ContentInfo.idl
424                     DBG_ERROR( "UcbExplorerListBoxEntry::createNewContent - "
425                                "Invlid type for bootstrap property!" );
426                 }
427             }
428 
429             delete pDlg;
430 
431             if ( nRet != RET_OK )
432                 return FALSE;
433 
434             aPropNames[ n ] = rName;
435         }
436     }
437 
438     uno::Reference< XInputStream > xData;
439 
440     if ( rInfo.Attributes & ContentInfoAttribute::INSERT_WITH_INPUTSTREAM )
441     {
442         // Let the user specify the URL of a content containing the
443         // data to supply to the new content.
444 
445         std::auto_ptr< ResMgr > xManager(
446             ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( ucbexplorer ) ) );
447         StringInputDialog* pDlg = new StringInputDialog(
448                                             *xManager.get(),
449                                             OUString::createFromAscii(
450                                                 "Document Data Source URL" ),
451                                             OUString() );
452         USHORT nRet = pDlg->Execute();
453         if ( nRet == RET_OK )
454         {
455             // Create a content object for the given URL.
456 
457             OUString aSourceURL( pDlg->GetValue() );
458             if ( aSourceURL.getLength() == 0 )
459             {
460                 DBG_ERROR( "UcbExplorerListBoxEntry::createNewContent - "
461                                "No document data URL!" );
462                 return FALSE;
463             }
464 
465             try
466             {
467                 uno::Reference< XCommandEnvironment > xEnv;
468 
469                 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
470                 if ( pBroker )
471                 {
472                     uno::Reference< XInteractionHandler > xInteractionHandler(
473                         pBroker->getServiceManager()->createInstance(
474                                 OUString::createFromAscii(
475                                     "com.sun.star.task.InteractionHandler" ) ),
476                         UNO_QUERY );
477 
478                     uno::Reference< XProgressHandler > xProgressHandler
479                                     /* = new ProgressHandler( *pBroker ) */ ;
480 
481                     xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
482                                                                 xProgressHandler );
483                 }
484 
485                 ::ucbhelper::Content aSourceContent( aSourceURL, xEnv );
486 
487                 // Get source data.
488                 rtl::Reference< TestDataSink > xSourceData = new TestDataSink;
489                 aSourceContent.openStream( xSourceData.get() );
490                 xData = xSourceData->getInputStream();
491             }
492             catch ( ContentCreationException const & )
493             {
494                 DBG_ERROR( "UcbExplorerListBoxEntry::createNewContent - "
495                                "No content for document data!" );
496                 return FALSE;
497             }
498             catch ( CommandAbortedException const & )
499             {
500                 return FALSE;
501             }
502             catch ( RuntimeException const & )
503             {
504                 throw;
505             }
506             catch ( Exception const & )
507             {
508                 return FALSE;
509             }
510         }
511 
512         delete pDlg;
513 
514         if ( nRet != RET_OK )
515             return FALSE;
516     }
517 
518     // Create new content.
519 
520         ULONG n = Application::ReleaseSolarMutex();
521     BOOL bRet = sal_False;
522 
523     try
524     {
525         bRet = m_aContent.insertNewContent(
526                     rInfo.Type, aPropNames, aPropValues, xData, rNewContent );
527     }
528     catch ( CommandAbortedException const & )
529     {
530     }
531     catch ( RuntimeException const & )
532     {
533         throw;
534     }
535     catch ( Exception const & )
536     {
537     }
538 
539     Application::AcquireSolarMutex( n );
540     return bRet;
541 }
542 
543 //=========================================================================
544 //
545 // UcbExplorerTreeListBox implementation.
546 //
547 //=========================================================================
548 
549 UcbExplorerTreeListBox::UcbExplorerTreeListBox( ResMgr & rResMgr,
550                                                 Window* pParent,
551                                                 WinBits nWinStyle )
552 : SvTreeListBox( pParent, nWinStyle ),
553   m_aFolderClosed( ResId( BMP_FOLDER_CLOSED, rResMgr ) ),
554   m_aFolderOpened( ResId( BMP_FOLDER_OPENED, rResMgr ) ),
555   m_aDocument( ResId( BMP_DOCUMENT, rResMgr ) ),
556   m_aLink( ResId( BMP_LINK, rResMgr ) )
557 {
558 }
559 
560 //=========================================================================
561 // virtual
562 UcbExplorerTreeListBox::~UcbExplorerTreeListBox()
563 {
564 }
565 
566 //=========================================================================
567 // virtual
568 SvLBoxEntry* UcbExplorerTreeListBox::CreateEntry() const
569 {
570     return new UcbExplorerListBoxEntry();
571 }
572 
573 //=========================================================================
574 // virtual
575 void UcbExplorerTreeListBox::RequestingChilds( SvLBoxEntry* pParent )
576 {
577     UcbExplorerListBoxEntry* pEntry
578         = static_cast< UcbExplorerListBoxEntry * >( pParent );
579     if ( !pEntry->HasChilds() )
580     {
581         switch ( pEntry->m_eType )
582         {
583             case UcbExplorerListBoxEntry::FOLDER:
584             {
585                     ULONG n = Application::ReleaseSolarMutex();
586 
587                 try
588                 {
589                     Sequence< OUString > aPropertyNames( 0 );
590 //                    OUString* pNames = aPropertyNames.getArray();
591 //                    pNames[ 0 ] = OUString::createFromAscii( "Title" );
592 
593                     uno::Reference< XResultSet > xResultSet
594                         = pEntry->m_aContent.createCursor(
595                                     aPropertyNames,
596                                     ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS );
597                     uno::Reference< XContentAccess > xContentAccess(
598                                                     xResultSet, UNO_QUERY );
599 
600                     if ( xResultSet.is() && xContentAccess.is() )
601                     {
602                         while ( xResultSet->next() )
603                         {
604                             Application::AcquireSolarMutex( n );
605 
606                             InsertEntry(
607                                 xContentAccess->queryContentIdentifierString(),
608                                 pParent );
609 
610                             n = Application::ReleaseSolarMutex();
611                         }
612                     }
613                 }
614                 catch ( CommandAbortedException const & )
615                 {
616                 }
617                 catch ( RuntimeException const & )
618                 {
619                     throw;
620                 }
621                 catch ( Exception const & )
622                 {
623                 }
624 
625                 Application::AcquireSolarMutex( n );
626                 break;
627             }
628 
629             case UcbExplorerListBoxEntry::DOCUMENT:
630                 break;
631 
632             case UcbExplorerListBoxEntry::LINK:
633                 break;
634 
635             default:
636                 break;
637         }
638     }
639 }
640 
641 //=========================================================================
642 // virtual
643 void UcbExplorerTreeListBox::Command( const CommandEvent& rCEvt )
644 {
645     if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
646     {
647         const Point& rPos = rCEvt.GetMousePosPixel();
648         UcbExplorerListBoxEntry* pEntry
649             = static_cast< UcbExplorerListBoxEntry * >(
650                 GetEntry( rPos, TRUE ) );
651         if ( pEntry )
652         {
653            std::auto_ptr< ResMgr > xManager(
654                 ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( ucbexplorer ) ) );
655            PopupMenu* pMenu = new PopupMenu( ResId( MENU_POPUP, *xManager.get() ) );
656             PopupMenu* pNewMenu = 0;
657 
658 //            pMenu->SetSelectHdl( LINK( this,
659 //                                       SfxCommonTemplateDialog_Impl,
660 //                                       MenuSelectHdl ) );
661 
662             //////////////////////////////////////////////////////////////
663             // Configure "New"
664             //////////////////////////////////////////////////////////////
665 
666             Sequence< ContentInfo > aInfo
667                 = pEntry->m_aContent.queryCreatableContentsInfo();
668             const ContentInfo* pInfo = aInfo.getConstArray();
669             sal_Int32 nCount = aInfo.getLength();
670             BOOL bCanCreate =  ( nCount > 0 );
671 
672             pNewMenu = new PopupMenu;
673             pMenu->SetPopupMenu( MENU_NEW, pNewMenu );
674 
675             for ( sal_Int32 n = 0; n < nCount; ++n )
676             {
677                 const ContentInfo& rInfo = pInfo[ n ];
678                 pNewMenu->InsertItem( 20000 + n + 1, rInfo.Type );
679             }
680 
681             pMenu->EnableItem( MENU_NEW, bCanCreate );
682 
683             //////////////////////////////////////////////////////////////
684             // Configure "Rename"
685             //////////////////////////////////////////////////////////////
686 
687             sal_Bool bEnable = sal_False;
688 
689             try
690             {
691                 Property aProp =
692                     pEntry->m_aContent.getProperties()->getPropertyByName(
693                                         OUString::createFromAscii( "Title" ) );
694                 bEnable = !( aProp.Attributes & PropertyAttribute::READONLY );
695             }
696             catch( UnknownPropertyException const & )
697             {
698                 // getPropertyByName
699                 bEnable = sal_False;
700             }
701             catch ( CommandAbortedException const & )
702             {
703             }
704             catch ( RuntimeException const & )
705             {
706                 throw;
707             }
708             catch ( Exception const & )
709             {
710             }
711 
712             pMenu->EnableItem( MENU_RENAME, bEnable );
713 
714             //////////////////////////////////////////////////////////////
715             // Configure "Delete"
716             //////////////////////////////////////////////////////////////
717 
718             try
719             {
720                 pMenu->EnableItem( MENU_DELETE,
721                                    pEntry->m_aContent
722                                         .getCommands()->hasCommandByName(
723                                         OUString::createFromAscii(
724                                             "delete" ) ) );
725             }
726             catch ( CommandAbortedException const & )
727             {
728             }
729             catch ( RuntimeException const & )
730             {
731                 throw;
732             }
733             catch ( Exception const & )
734             {
735             }
736 
737             //////////////////////////////////////////////////////////////
738             // Execute menu.
739             //////////////////////////////////////////////////////////////
740 
741             USHORT nSelected = pMenu->Execute( this, rPos );
742             switch ( nSelected )
743             {
744 //                case MENU_NEW:
745 //                    break;
746 
747                 case MENU_RENAME:
748                 {
749                     OUString aNewTitle;
750 
751                     try
752                     {
753                         pEntry->m_aContent.getPropertyValue(
754                                     OUString::createFromAscii( "Title" ) )
755                                     >>= aNewTitle;
756                     }
757                     catch ( CommandAbortedException const & )
758                     {
759                     }
760                     catch ( RuntimeException const & )
761                     {
762                         throw;
763                     }
764                     catch ( Exception const & )
765                     {
766                     }
767 
768                     std::auto_ptr< ResMgr > xManager(
769                         ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( ucbexplorer ) ) );
770                     StringInputDialog* pDlg
771                             = new StringInputDialog(
772                                     *xManager.get(),
773                                     OUString::createFromAscii( "Title" ),
774                                     aNewTitle );
775 
776                     USHORT nRet = pDlg->Execute();
777 
778                     Any aValue;
779 
780                     if ( nRet == RET_OK )
781                     {
782                         aNewTitle = pDlg->GetValue();
783                         aValue <<= aNewTitle;
784                     }
785 
786                     delete pDlg;
787 
788                     if ( nRet != RET_OK )
789                         break;
790 
791                     sal_Bool bOK = sal_False;
792 
793                     ULONG n = Application::ReleaseSolarMutex();
794 
795                     try
796                     {
797                         pEntry->m_aContent.setPropertyValue(
798                                     OUString::createFromAscii( "Title" ),
799                                     aValue );
800                         bOK = sal_True;
801                     }
802                     catch ( CommandAbortedException const & )
803                     {
804                     }
805                     catch ( RuntimeException const & )
806                     {
807                         throw;
808                     }
809                     catch ( Exception const & )
810                     {
811                     }
812 
813                     Application::AcquireSolarMutex( n );
814 
815                     if ( bOK )
816                     {
817                         OUString aText( aNewTitle );
818                         OUString aTargetURL;
819                         try
820                         {
821                             pEntry->m_aContent.getPropertyValue(
822                                 OUString::createFromAscii( "TargetURL" ) )
823                                     >>= aTargetURL;
824                         }
825                         catch ( CommandAbortedException const & )
826                         {
827                         }
828                         catch ( RuntimeException const & )
829                         {
830                             throw;
831                         }
832                         catch ( Exception const & )
833                         {
834                             // The property is optional!
835                         }
836 
837                         if ( aTargetURL.getLength() > 0 )
838                         {
839                             // Insert link.
840                             aText += OUString::createFromAscii( " --> " );
841                             aText += aTargetURL;
842                         }
843 
844                         SetEntryText( pEntry, aText );
845                     }
846                     break;
847                 }
848 
849                 case MENU_DELETE:
850                 {
851                     ULONG n = Application::ReleaseSolarMutex();
852                     sal_Bool bOK = sal_True;
853 
854                     try
855                     {
856                         pEntry->m_aContent.executeCommand(
857                                     OUString::createFromAscii( "delete" ),
858                                     makeAny( sal_True ) );
859                     }
860                     catch ( CommandAbortedException const & )
861                     {
862                         bOK = sal_False;
863                     }
864                     catch ( RuntimeException const & )
865                     {
866                         throw;
867                     }
868                     catch ( Exception const & )
869                     {
870                         bOK = sal_False;
871                     }
872 
873                     Application::AcquireSolarMutex( n );
874 
875                     if ( bOK )
876                         RemoveSelection();
877 
878                     break;
879                 }
880 
881                 default:
882                 {
883                     if ( ( nSelected > 20000 ) &&
884                          ( ( nSelected - 20000 ) <= aInfo.getLength() ) )
885                     {
886                         // New-menu entry selected.
887 
888                         ::ucbhelper::Content aNewContent;
889                         if ( pEntry->createNewContent(
890                                     aInfo.getConstArray()[ nSelected - 20001 ],
891                                     aNewContent ) )
892                         {
893                             if ( !IsExpanded( pEntry ) )
894                                 Expand( pEntry );
895                             else
896                                 InsertEntry( aNewContent, pEntry );
897                         }
898                     }
899                     break;
900                 }
901             }
902 
903             delete pNewMenu;
904             delete pMenu;
905             return;
906         }
907     }
908 
909     SvTreeListBox::Command( rCEvt );
910 }
911 
912 //=========================================================================
913 UcbExplorerListBoxEntry* UcbExplorerTreeListBox::InsertEntry(
914                                                 ::ucbhelper::Content& rContent,
915                                                 SvLBoxEntry* pParent )
916 {
917     try
918     {
919         OUString aTitle;
920         rContent.getPropertyValue(
921                         OUString::createFromAscii( "Title" ) ) >>= aTitle;
922         if ( !aTitle.getLength() )
923             aTitle = OUString::createFromAscii( "/" );
924 
925             UcbExplorerListBoxEntry* pEntry = 0;
926 
927         if ( rContent.isFolder() )
928         {
929             // Insert folder.
930             pEntry = static_cast< UcbExplorerListBoxEntry * >(
931                             SvTreeListBox::InsertEntry( aTitle,
932                                                     m_aFolderOpened,
933                                                     m_aFolderClosed,
934                                                     pParent,
935                                                     TRUE ) );
936             pEntry->m_eType = UcbExplorerListBoxEntry::FOLDER;
937         }
938         else
939         {
940             OUString aTargetURL;
941             try
942             {
943                 rContent.getPropertyValue(
944                     OUString::createFromAscii( "TargetURL" ) ) >>= aTargetURL;
945             }
946             catch ( CommandAbortedException const & )
947             {
948             }
949             catch ( RuntimeException const & )
950             {
951                 throw;
952             }
953             catch ( Exception const & )
954             {
955                 // The property is optional!
956             }
957 
958             if ( aTargetURL.getLength() > 0 )
959             {
960                 // Insert link.
961                 aTitle += OUString::createFromAscii( " --> " );
962                 aTitle += aTargetURL;
963                 pEntry = static_cast< UcbExplorerListBoxEntry * >(
964                                 SvTreeListBox::InsertEntry( aTitle,
965                                                         m_aLink,
966                                                         m_aLink,
967                                                         pParent,
968                                                         TRUE ) );
969                 pEntry->m_eType = UcbExplorerListBoxEntry::LINK;
970             }
971             else
972             {
973                 // Insert Document
974                 pEntry = static_cast< UcbExplorerListBoxEntry * >(
975                                 SvTreeListBox::InsertEntry( aTitle,
976                                                         m_aDocument,
977                                                         m_aDocument,
978                                                         pParent,
979                                                         TRUE ) );
980                 pEntry->m_eType = UcbExplorerListBoxEntry::DOCUMENT;
981             }
982         }
983 
984         pEntry->m_aContent = rContent;
985         return pEntry;
986     }
987     catch ( CommandAbortedException const & )
988     {
989     }
990     catch ( Exception const & )
991     {
992     }
993 
994     return 0;
995 }
996 
997 //=========================================================================
998 UcbExplorerListBoxEntry* UcbExplorerTreeListBox::InsertEntry(
999                                                 const String& rURL,
1000                                                     SvLBoxEntry* pParent )
1001 {
1002     try
1003     {
1004         uno::Reference< XCommandEnvironment > xEnv;
1005 
1006         ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
1007         if ( pBroker )
1008         {
1009             uno::Reference< XInteractionHandler > xInteractionHandler(
1010                 pBroker->getServiceManager()->createInstance(
1011                         OUString::createFromAscii(
1012                             "com.sun.star.task.InteractionHandler" ) ),
1013                 UNO_QUERY );
1014 
1015             uno::Reference< XProgressHandler > xProgressHandler
1016                                 /* = new ProgressHandler( *pBroker ) */ ;
1017 
1018             xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler,
1019                                                         xProgressHandler );
1020         }
1021 
1022         ::ucbhelper::Content aContent( rURL, xEnv );
1023         return InsertEntry( aContent, pParent );
1024     }
1025     catch ( ContentCreationException const & )
1026     {
1027     }
1028 
1029     return 0;
1030 }
1031 
1032 //=========================================================================
1033 //
1034 // UcbExplorerWindow implementation.
1035 //
1036 //=========================================================================
1037 
1038 UcbExplorerWindow::UcbExplorerWindow( ResMgr & rResMgr, Window *pParent, WinBits nWinStyle )
1039 : WorkWindow( pParent, nWinStyle ),
1040   m_aTree( rResMgr, this, WB_HSCROLL )
1041 {
1042     Font aTreeFont( m_aTree.GetFont() );
1043     aTreeFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM("Courier") ) );
1044     aTreeFont.SetFamily( FAMILY_MODERN );
1045     aTreeFont.SetPitch( PITCH_FIXED );
1046     aTreeFont.SetSize( Size( 0, 12 ) );
1047 
1048     m_aTree.SetFont( aTreeFont );
1049     m_aTree.SetIndent( 20 );
1050     m_aTree.SetPosPixel( Point( 0, 0 ) );
1051 
1052     m_aTree.Show();
1053 }
1054 
1055 //-------------------------------------------------------------------------
1056 // virtual
1057 UcbExplorerWindow::~UcbExplorerWindow()
1058 {
1059 }
1060 
1061 //-------------------------------------------------------------------------
1062 // virtual
1063 void UcbExplorerWindow::Resize()
1064 {
1065     m_aTree.SetSizePixel( GetOutputSizePixel() );
1066 }
1067 
1068 //=========================================================================
1069 //
1070 // MyApp implementation.
1071 //
1072 //=========================================================================
1073 
1074 // virtual
1075 void MyApp::Main()
1076 {
1077     //////////////////////////////////////////////////////////////////////
1078     // Initialize local Service Manager and basic services.
1079     //////////////////////////////////////////////////////////////////////
1080 
1081     uno::Reference< XMultiServiceFactory > xFac;
1082     try
1083     {
1084         uno::Reference< XComponentContext > xCtx(
1085             cppu::defaultBootstrap_InitialComponentContext() );
1086         if ( !xCtx.is() )
1087         {
1088             DBG_ERROR( "Error creating initial component context!" );
1089             return;
1090         }
1091 
1092         xFac = uno::Reference< XMultiServiceFactory >(
1093             xCtx->getServiceManager(), UNO_QUERY );
1094 
1095         if ( !xFac.is() )
1096         {
1097             DBG_ERROR( "No service manager!" );
1098             return;
1099         }
1100     }
1101     catch ( com::sun::star::uno::Exception const & )
1102     {
1103         DBG_ERROR( "Exception during creation of initial component context!" );
1104         return;
1105     }
1106 
1107     comphelper::setProcessServiceFactory( xFac );
1108 
1109     uno::Reference< XComponent > xComponent( xFac, UNO_QUERY );
1110 
1111     //////////////////////////////////////////////////////////////////////
1112     // Create UCB.
1113     //////////////////////////////////////////////////////////////////////
1114 
1115 #if 1
1116     // Init UCB (Read configuration from registry)
1117     Sequence< Any > aArgs( 2 );
1118     aArgs[ 0 ] <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
1119     aArgs[ 1 ] <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
1120     sal_Bool bSuccess = ::ucbhelper::ContentBroker::initialize( xFac, aArgs );
1121 #else
1122     // Init UCB (Use provided configuration data)
1123     ::ucbhelper::ContentProviderDataList aProviders;
1124     aProviders.push_back(
1125         ::ucbhelper::ContentProviderData(
1126             OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ),
1127             OUString::createFromAscii( "file" ),
1128             OUString() ) );
1129     sal_Bool bSuccess = ::ucbhelper::ContentBroker::initialize( xFac, aProviders );
1130 #endif
1131 
1132     if ( !bSuccess )
1133     {
1134         DBG_ERROR( "Error creating UCB!" );
1135         return;
1136     }
1137 
1138     //////////////////////////////////////////////////////////////////////
1139     // Create/init/show app window.
1140     //////////////////////////////////////////////////////////////////////
1141 
1142     std::auto_ptr< ResMgr > xManager(
1143         ResMgr::CreateResMgr( CREATEVERSIONRESMGR_NAME( ucbexplorer ) ) );
1144 
1145     UcbExplorerWindow aAppWin( *xManager.get(), 0, WB_APP | WB_STDWORK );
1146 
1147     MenuBar aMBMain( ResId( MENU_MAIN, *xManager.get() ) );
1148 
1149     // Check for command line params
1150 #if 0
1151     for ( int i = 0; i < GetCommandLineParamCount(); ++i )
1152     {
1153         String aPara = GetCommandLineParam( i );
1154     }
1155 #endif
1156 
1157      String aRootURL = GetCommandLineParam( 0 );
1158      if ( aRootURL.Len() == 0 )
1159         aRootURL = UniString::CreateFromAscii(
1160                         RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.hier:/" ) );
1161 
1162      String aTitle( ResId( TEXT_TITLEBAR, *xManager.get() ) );
1163     aTitle.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) );
1164     aTitle += aRootURL;
1165 
1166     aAppWin.SetText( aTitle );
1167 
1168     aAppWin.SetPosSizePixel( 0, 0, 500, 750 );
1169 
1170     aAppWin.Show();
1171 
1172     aAppWin.m_aTree.InsertEntry( aRootURL );
1173 
1174     //////////////////////////////////////////////////////////////////////
1175     // Execute app.
1176     //////////////////////////////////////////////////////////////////////
1177 
1178     Execute();
1179 
1180     //////////////////////////////////////////////////////////////////////
1181     // Cleanup.
1182     //////////////////////////////////////////////////////////////////////
1183 
1184     // m_aTree holds UCB contents!
1185     aAppWin.m_aTree.Clear();
1186 
1187     ::ucbhelper::ContentBroker::deinitialize();
1188 
1189     if ( xComponent.is() )
1190         xComponent->dispose();
1191 }
1192 
1193 //=========================================================================
1194 //
1195 // The Application.
1196 //
1197 //=========================================================================
1198 
1199 MyApp aMyApp;
1200 
1201