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 
DirectoryTree(const Reference<XComponentContext> & xComponentContext)99 DirectoryTree::DirectoryTree( const Reference< XComponentContext >& xComponentContext )
100 : mxComponentContext( xComponentContext )
101 , mxMultiComponentFactoryServer( xComponentContext->getServiceManager() )
102 {
103 }
104 
~DirectoryTree()105 DirectoryTree::~DirectoryTree()
106 {
107 }
108 
display(const OUString & rURL)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 
fillNode(const Reference<XMutableTreeNode> & xNode)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
requestChildNodes(const TreeExpansionEvent & rEvent)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 
treeExpanding(const TreeExpansionEvent &)254 void SAL_CALL DirectoryTree::treeExpanding( const TreeExpansionEvent& /*rEvent*/ ) throw (ExpandVetoException, RuntimeException)
255 {
256 }
257 
treeCollapsing(const TreeExpansionEvent &)258 void SAL_CALL DirectoryTree::treeCollapsing( const TreeExpansionEvent&  ) throw (ExpandVetoException, RuntimeException)
259 {
260 }
261 
treeExpanded(const TreeExpansionEvent &)262 void SAL_CALL DirectoryTree::treeExpanded( const TreeExpansionEvent&  ) throw (RuntimeException)
263 {
264 }
265 
treeCollapsed(const TreeExpansionEvent &)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
nodeEditing(const Reference<XTreeNode> &)283 void SAL_CALL DirectoryTree::nodeEditing( const Reference< XTreeNode >&  ) throw (VetoException, RuntimeException)
284 {
285 }
286 
nodeEdited(const Reference<XTreeNode> &,const OUString &)287 void SAL_CALL DirectoryTree::nodeEdited( const Reference< XTreeNode >& , const OUString&  ) throw (RuntimeException)
288 {
289 }
290 
291 // XEventListener
disposing(const::com::sun::star::lang::EventObject &)292 void SAL_CALL DirectoryTree::disposing( const ::com::sun::star::lang::EventObject&  ) throw (RuntimeException)
293 {
294 }
295 
296 //============================================================================
main(int argc,char ** argv)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