1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <stdio.h> 25 #include <wchar.h> 26 27 #include <cppuhelper/bootstrap.hxx> 28 29 #include <osl/file.hxx> 30 #include <osl/process.h> 31 32 #include <com/sun/star/bridge/XUnoUrlResolver.hpp> 33 #include <com/sun/star/frame/XComponentLoader.hpp> 34 #include <com/sun/star/beans/XPropertySet.hpp> 35 #include <com/sun/star/awt/tree/XMutableTreeDataModel.hpp> 36 #include <com/sun/star/awt/tree/XTreeControl.hpp> 37 #include <com/sun/star/awt/tree/XTreeExpansionListener.hpp> 38 #include <com/sun/star/awt/tree/XTreeEditListener.hpp> 39 #include <com/sun/star/awt/XDialog.hpp> 40 #include <com/sun/star/awt/XControlModel.hpp> 41 #include <com/sun/star/container/XNameContainer.hpp> 42 #include <com/sun/star/awt/XControl.hpp> 43 #include <com/sun/star/awt/XControlContainer.hpp> 44 #include <com/sun/star/view/SelectionType.hpp> 45 46 #include <tools/urlobj.hxx> 47 #include <vcl/image.hxx> 48 #include <vcl/graph.hxx> 49 50 #include <cppuhelper/implbase2.hxx> 51 52 #include <string.h> 53 #include <rtl/ref.hxx> 54 55 #include "imagemgr.hxx" 56 57 using rtl::OUString; 58 using namespace com::sun::star::uno; 59 using namespace com::sun::star::lang; 60 using namespace com::sun::star::beans; 61 using namespace com::sun::star::bridge; 62 using namespace com::sun::star::frame; 63 using namespace com::sun::star::registry; 64 using namespace com::sun::star::awt; 65 using namespace com::sun::star::awt::tree; 66 using namespace com::sun::star::container; 67 using namespace com::sun::star::view; 68 using namespace com::sun::star::util; 69 70 class DirectoryTree : public ::cppu::WeakImplHelper2< XTreeExpansionListener, XTreeEditListener > 71 { 72 public: 73 DirectoryTree( const Reference< XComponentContext >& xComponentContext ); 74 virtual ~DirectoryTree(); 75 76 void fillNode( const Reference< XMutableTreeNode >& xNode ); 77 void display( const OUString& rURL ); 78 79 // XTreeExpansionListener 80 virtual void SAL_CALL requestChildNodes( const TreeExpansionEvent& Event ) throw (RuntimeException); 81 virtual void SAL_CALL treeExpanding( const TreeExpansionEvent& Event ) throw (ExpandVetoException, RuntimeException); 82 virtual void SAL_CALL treeCollapsing( const TreeExpansionEvent& Event ) throw (ExpandVetoException, RuntimeException); 83 virtual void SAL_CALL treeExpanded( const TreeExpansionEvent& Event ) throw (RuntimeException); 84 virtual void SAL_CALL treeCollapsed( const TreeExpansionEvent& Event ) throw (RuntimeException); 85 86 // XTreeEditListener 87 virtual void SAL_CALL nodeEditing( const Reference< XTreeNode >& Node ) throw (VetoException, RuntimeException); 88 virtual void SAL_CALL nodeEdited( const Reference< XTreeNode >& Node, const OUString& NewText ) throw (RuntimeException); 89 90 // XEventListener 91 virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (RuntimeException); 92 93 Reference< XMultiComponentFactory > mxMultiComponentFactoryServer; 94 Reference< XComponentContext > mxComponentContext; 95 Reference< XTreeControl > mxTreeControl; 96 Reference< XMutableTreeDataModel > mxTreeDataModel; 97 }; 98 99 DirectoryTree::DirectoryTree( const Reference< XComponentContext >& xComponentContext ) 100 : mxComponentContext( xComponentContext ) 101 , mxMultiComponentFactoryServer( xComponentContext->getServiceManager() ) 102 { 103 } 104 105 DirectoryTree::~DirectoryTree() 106 { 107 } 108 109 void DirectoryTree::display( const OUString& rURL ) 110 { 111 // some property names for later use 112 const OUString sPositionX( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ); 113 const OUString sPositionY( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ); 114 const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ); 115 const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ); 116 const OUString sDataModel( RTL_CONSTASCII_USTRINGPARAM( "DataModel" ) ); 117 const OUString sSelectionType( RTL_CONSTASCII_USTRINGPARAM( "SelectionType" ) ); 118 const OUString sShowsRootHandles( RTL_CONSTASCII_USTRINGPARAM( "ShowsRootHandles" ) ); 119 const OUString sShowsHandles( RTL_CONSTASCII_USTRINGPARAM( "ShowsHandles" ) ); 120 const OUString sRootDisplayed( RTL_CONSTASCII_USTRINGPARAM( "RootDisplayed" ) ); 121 const OUString sEditable( RTL_CONSTASCII_USTRINGPARAM( "Editable" ) ); 122 const OUString sTitle( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ); 123 const OUString sRowHeight( RTL_CONSTASCII_USTRINGPARAM( "RowHeight" ) ); 124 125 // first create a data model for our tree control 126 mxTreeDataModel = Reference< XMutableTreeDataModel >( 127 mxMultiComponentFactoryServer->createInstanceWithContext( 128 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.tree.MutableTreeDataModel" ) ), 129 mxComponentContext ), UNO_QUERY_THROW ); 130 131 // now fill it with some sample data 132 Reference< XMutableTreeNode > xNode( mxTreeDataModel->createNode( Any( rURL ), false ), UNO_QUERY_THROW ); 133 xNode->setDataValue( Any( rURL ) ); 134 xNode->setExpandedGraphicURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/sd/res/triangle_down.png" ) ) ); 135 xNode->setCollapsedGraphicURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/sd/res/triangle_right.png" ) ) ); 136 137 fillNode( xNode ); 138 mxTreeDataModel->setRoot( xNode ); 139 140 // now create the dialog 141 Reference< XControlModel > xDialogModel( 142 mxMultiComponentFactoryServer->createInstanceWithContext( 143 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialogModel" ) ), 144 mxComponentContext ), UNO_QUERY_THROW ); 145 146 Reference< XPropertySet > xDialogPropertySet( xDialogModel, UNO_QUERY_THROW ); 147 xDialogPropertySet->setPropertyValue( sPositionX, Any( sal_Int32(50) ) ); 148 xDialogPropertySet->setPropertyValue( sPositionY, Any( sal_Int32(50) ) ); 149 xDialogPropertySet->setPropertyValue( sWidth, Any( sal_Int32(256) ) ); 150 xDialogPropertySet->setPropertyValue( sHeight, Any( sal_Int32(256) ) ); 151 xDialogPropertySet->setPropertyValue( sTitle, Any( OUString( RTL_CONSTASCII_USTRINGPARAM( "Tree Control Test" ) ) ) ); 152 153 Reference< XMultiServiceFactory > xDialogMSF( xDialogModel, UNO_QUERY_THROW ); 154 155 // now create our tree control 156 Reference< XControlModel > xTreeControlModel( 157 xDialogMSF->createInstance( 158 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.tree.TreeControlModel" ) ) ), 159 UNO_QUERY_THROW ); 160 161 Reference< XPropertySet > XTreeControlModelSet( xTreeControlModel, UNO_QUERY_THROW ); 162 163 XTreeControlModelSet->setPropertyValue( sSelectionType, Any( SelectionType_NONE ) ); 164 XTreeControlModelSet->setPropertyValue( sPositionX, Any( sal_Int32(3) ) ); 165 XTreeControlModelSet->setPropertyValue( sPositionY, Any( sal_Int32(3) ) ); 166 XTreeControlModelSet->setPropertyValue( sWidth, Any( sal_Int32(253) ) ); 167 XTreeControlModelSet->setPropertyValue( sHeight, Any( sal_Int32(253) ) ); 168 XTreeControlModelSet->setPropertyValue( sDataModel, Any( mxTreeDataModel ) ); 169 XTreeControlModelSet->setPropertyValue( sShowsRootHandles,Any( sal_False ) ); 170 XTreeControlModelSet->setPropertyValue( sShowsHandles, Any( sal_False ) ); 171 XTreeControlModelSet->setPropertyValue( sRootDisplayed, Any( sal_True ) ); 172 XTreeControlModelSet->setPropertyValue( sEditable, Any( sal_True ) ); 173 // XTreeControlModelSet->setPropertyValue( sRowHeight, Any( sal_Int32( 12 ) ) ); 174 175 Reference< XNameContainer > xDialogModelContainer( xDialogModel, UNO_QUERY_THROW ); 176 177 const OUString sTreeControlName( RTL_CONSTASCII_USTRINGPARAM( "tree" ) ); 178 179 xDialogModelContainer->insertByName( sTreeControlName, Any( xTreeControlModel ) ); 180 181 // now create the peers 182 Reference< XControl > xDialogControl( 183 mxMultiComponentFactoryServer->createInstanceWithContext( 184 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialog" ) ), 185 mxComponentContext ), UNO_QUERY_THROW ); 186 187 xDialogControl->setModel( xDialogModel ); 188 189 Reference< XToolkit > xToolkit( 190 mxMultiComponentFactoryServer->createInstanceWithContext( 191 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit" ) ), 192 mxComponentContext ), UNO_QUERY_THROW ); 193 xDialogControl->createPeer( xToolkit, 0 ); 194 195 // get the peers of the sub controls from the dialog peer container 196 Reference< XControlContainer > xDialogContainer( xDialogControl, UNO_QUERY_THROW ); 197 mxTreeControl = Reference< XTreeControl >( xDialogContainer->getControl( sTreeControlName ), UNO_QUERY_THROW ); 198 199 Reference< XTreeExpansionListener > xListener( static_cast<XWeak*>(this), UNO_QUERY_THROW ); 200 mxTreeControl->addTreeExpansionListener( xListener ); 201 Reference< XDialog > xDialog( xDialogControl, UNO_QUERY_THROW ); 202 xDialog->execute(); 203 } 204 205 void DirectoryTree::fillNode( const Reference< XMutableTreeNode >& xNode ) 206 { 207 if( xNode->getChildCount() == 0 ) 208 { 209 OUString sParentPath; 210 xNode->getDataValue() >>= sParentPath; 211 212 osl::Directory aDirectory( sParentPath ); 213 if( aDirectory.open() == osl::Directory::E_None ) 214 { 215 osl::DirectoryItem aItem; 216 osl::FileStatus fs( FileStatusMask_Type | FileStatusMask_FileURL); 217 while( aDirectory.getNextItem( aItem, 0xffffffff ) == osl::Directory::E_None ) 218 { 219 if (aItem.getFileStatus(fs) == osl::FileBase::E_None) 220 { 221 bool bDirectory = fs.getFileType() == osl::FileStatus::Directory; 222 Reference< XMutableTreeNode > xChildNode( mxTreeDataModel->createNode( Any( fs.getFileName() ), bDirectory ), UNO_QUERY_THROW ); 223 xChildNode->setDataValue( Any( fs.getFileURL() ) ); 224 if( bDirectory ) 225 { 226 xChildNode->setExpandedGraphicURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/sd/res/triangle_down.png" ) ) ); 227 xChildNode->setCollapsedGraphicURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:graphicrepository/sd/res/triangle_right.png" ) ) ); 228 } 229 else 230 { 231 xChildNode->setNodeGraphicURL( OUString( RTL_CONSTASCII_USTRINGPARAM("private:graphicrepository/sw/imglst/nc20010.png") ) ); 232 } 233 xNode->appendChild( xChildNode ); 234 } 235 } 236 } 237 } 238 } 239 240 // XTreeExpansionListener 241 void SAL_CALL DirectoryTree::requestChildNodes( const TreeExpansionEvent& rEvent ) throw (RuntimeException) 242 { 243 if( rEvent.Node.is() && rEvent.Node->hasChildsOnDemand() ) 244 { 245 Reference< XMutableTreeNode > xNode( rEvent.Node, UNO_QUERY ); 246 if( xNode.is() ) 247 { 248 fillNode( xNode ); 249 xNode->setHasChildsOnDemand( sal_False ); 250 } 251 } 252 } 253 254 void SAL_CALL DirectoryTree::treeExpanding( const TreeExpansionEvent& /*rEvent*/ ) throw (ExpandVetoException, RuntimeException) 255 { 256 } 257 258 void SAL_CALL DirectoryTree::treeCollapsing( const TreeExpansionEvent& ) throw (ExpandVetoException, RuntimeException) 259 { 260 } 261 262 void SAL_CALL DirectoryTree::treeExpanded( const TreeExpansionEvent& ) throw (RuntimeException) 263 { 264 } 265 266 void SAL_CALL DirectoryTree::treeCollapsed( const TreeExpansionEvent& /*rEvent*/ ) throw (RuntimeException) 267 { 268 /* 269 if( rEvent.Node != mxTreeDataModel->getRoot() ) 270 { 271 Reference< XMutableTreeNode > xNode( rEvent.Node, UNO_QUERY ); 272 if( xNode.is() ) 273 { 274 while( xNode->getChildCount() ) 275 xNode->removeChildByIndex(0); 276 xNode->setHasChildsOnDemand( sal_True ); 277 } 278 } 279 */ 280 } 281 282 // XTreeEditListener 283 void SAL_CALL DirectoryTree::nodeEditing( const Reference< XTreeNode >& ) throw (VetoException, RuntimeException) 284 { 285 } 286 287 void SAL_CALL DirectoryTree::nodeEdited( const Reference< XTreeNode >& , const OUString& ) throw (RuntimeException) 288 { 289 } 290 291 // XEventListener 292 void SAL_CALL DirectoryTree::disposing( const ::com::sun::star::lang::EventObject& ) throw (RuntimeException) 293 { 294 } 295 296 //============================================================================ 297 int SAL_CALL main( int argc, char **argv ) 298 { 299 OUString sConnectionString(RTL_CONSTASCII_USTRINGPARAM("uno:socket,host=localhost,port=5678;urp;StarOffice.ServiceManager")); 300 301 if (argc < 2) 302 { 303 printf("using: treetest <directory> [<uno_connection_url>]\n\n" 304 #ifdef WNT 305 "example: treetest \"c:\" \"uno:socket,host=localhost,port=5678;urp;StarOffice.ServiceManager\"\n"); 306 #else 307 "example: treetest \"/etc\" \"uno:socket,host=localhost,port=5678;urp;StarOffice.ServiceManager\"\n"); 308 #endif 309 exit(1); 310 } 311 if (argc == 3) 312 { 313 sConnectionString = OUString::createFromAscii(argv[2]); 314 } 315 316 // Creates a simple registry service instance. 317 Reference< XSimpleRegistry > xSimpleRegistry(::cppu::createSimpleRegistry() ); 318 319 // Connects the registry to a persistent data source represented by an URL. 320 xSimpleRegistry->open( 321 OUString( RTL_CONSTASCII_USTRINGPARAM("treetest.rdb") ), sal_True, sal_False ); 322 323 /* Bootstraps an initial component context with service manager upon a given 324 registry. This includes insertion of initial services: 325 - (registry) service manager, shared lib loader, 326 - simple registry, nested registry, 327 - implementation registration 328 - registry typedescription provider, typedescription manager (also 329 installs it into cppu core) 330 */ 331 Reference< XComponentContext > xComponentContext( 332 ::cppu::bootstrap_InitialComponentContext( xSimpleRegistry ) ); 333 334 /* Gets the service manager instance to be used (or null). This method has 335 been added for convenience, because the service manager is a often used 336 object. 337 */ 338 Reference< XMultiComponentFactory > xMultiComponentFactoryClient( 339 xComponentContext->getServiceManager() ); 340 341 /* Creates an instance of a component which supports the services specified 342 by the factory. 343 */ 344 Reference< XInterface > xInterface = 345 xMultiComponentFactoryClient->createInstanceWithContext( 346 OUString::createFromAscii( "com.sun.star.bridge.UnoUrlResolver" ), 347 xComponentContext ); 348 349 Reference< XUnoUrlResolver > resolver( xInterface, UNO_QUERY ); 350 351 // Resolves the component context from the office, on the uno URL given by argv[1]. 352 try 353 { 354 xInterface = Reference< XInterface >( 355 resolver->resolve( sConnectionString ), UNO_QUERY ); 356 } 357 catch ( Exception& e ) 358 { 359 printf("Error: cannot establish a connection using '%s':\n %s\n", 360 OUStringToOString(sConnectionString, RTL_TEXTENCODING_ASCII_US).getStr(), 361 OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr()); 362 exit(1); 363 } 364 365 // gets the server component context as property of the office component factory 366 Reference< XPropertySet > xPropSet( xInterface, UNO_QUERY ); 367 xPropSet->getPropertyValue( OUString::createFromAscii("DefaultContext") ) >>= xComponentContext; 368 369 // gets the service manager from the office 370 Reference< XMultiComponentFactory > xMultiComponentFactoryServer( 371 xComponentContext->getServiceManager() ); 372 373 try 374 { 375 OUString ustrFileURL; 376 osl::FileBase::getFileURLFromSystemPath( OUString::createFromAscii(argv[1]), ustrFileURL ); 377 378 rtl::Reference< DirectoryTree >( 379 new DirectoryTree( xComponentContext ) )->display(ustrFileURL); 380 } 381 catch( Exception& e ) 382 { 383 printf("Error: exception caught during test:\n %s\n", 384 OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr()); 385 exit(1); 386 } 387 388 // dispose the local service manager 389 Reference< XComponent >::query( xMultiComponentFactoryClient )->dispose(); 390 391 return 0; 392 } 393