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_dbaccess.hxx"
30 
31 #ifndef DBACCESS_SOURCE_UI_INC_OPENDOCCONTROLS_HXX
32 #include "opendoccontrols.hxx"
33 #endif
34 
35 /** === begin UNO includes === **/
36 #ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
37 #include <com/sun/star/uno/Sequence.hxx>
38 #endif
39 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
40 #include <com/sun/star/beans/PropertyValue.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #endif
45 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
46 #include <com/sun/star/container/XNameAccess.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
49 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
50 #endif
51 #ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGER_HPP_
52 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
53 #endif
54 #ifndef _COM_SUN_STAR_GRAPHIC_XGRAPHIC_HPP_
55 #include <com/sun/star/graphic/XGraphic.hpp>
56 #endif
57 #ifndef _COM_SUN_STAR_UI_XIMAGEMANAGER_HPP_
58 #include <com/sun/star/ui/XImageManager.hpp>
59 #endif
60 /** === end UNO includes === **/
61 
62 #ifndef _COMPHELPER_PROCESSFACTORY_HXX_
63 #include <comphelper/processfactory.hxx>
64 #endif
65 #ifndef _SV_GRAPH_HXX
66 #include <vcl/graph.hxx>
67 #endif
68 #ifndef _SV_HELP_HXX
69 #include <vcl/help.hxx>
70 #endif
71 #ifndef INCLUDED_SVTOOLS_HISTORYOPTIONS_HXX
72 #include <unotools/historyoptions.hxx>
73 #endif
74 #ifndef _COMPHELPER_SEQUENCEASHASHMAP_HXX_
75 #include <comphelper/sequenceashashmap.hxx>
76 #endif
77 #ifndef _URLOBJ_HXX
78 #include <tools/urlobj.hxx>
79 #endif
80 #ifndef SVTOOLS_FILENOTATION_HXX
81 #include <svl/filenotation.hxx>
82 #endif
83 
84 //........................................................................
85 namespace dbaui
86 {
87 //........................................................................
88 
89     namespace
90     {
91         using ::com::sun::star::uno::Reference;
92         using ::com::sun::star::uno::Exception;
93         using ::com::sun::star::uno::Sequence;
94         using ::com::sun::star::uno::UNO_QUERY_THROW;
95         using ::com::sun::star::container::XNameAccess;
96         using ::com::sun::star::lang::XMultiServiceFactory;
97         using ::com::sun::star::beans::PropertyValue;
98         using ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier;
99         using ::com::sun::star::ui::XUIConfigurationManager;
100         using ::com::sun::star::ui::XImageManager;
101         using ::com::sun::star::graphic::XGraphic;
102 
103         String GetCommandText( const sal_Char* _pCommandURL, const ::rtl::OUString& _rModuleName )
104         {
105             ::rtl::OUString sLabel;
106             if ( !_pCommandURL || !*_pCommandURL )
107                 return sLabel;
108 
109             Reference< XNameAccess > xUICommandLabels;
110             ::rtl::OUString sCommandURL = ::rtl::OUString::createFromAscii( _pCommandURL );
111 
112             try
113             {
114                 do
115                 {
116                     // Retrieve popup menu labels
117                     Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
118                     if ( !xFactory.is() )
119                         break;
120 
121                     Reference< XNameAccess> xNameAccess;
122                     xNameAccess = xNameAccess.query( xFactory->createInstance(
123                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.UICommandDescription" ) )
124                     ) );
125                     if ( !xNameAccess.is() )
126                         break;
127 
128                     xNameAccess->getByName( _rModuleName ) >>= xUICommandLabels;
129                     if ( !xUICommandLabels.is() )
130                         break;
131 
132                     Sequence< PropertyValue > aProperties;
133                     if ( !( xUICommandLabels->getByName(sCommandURL) >>= aProperties ) )
134                         break;
135 
136                     sal_Int32 nCount( aProperties.getLength() );
137                     for ( sal_Int32 i=0; i<nCount; ++i )
138                     {
139                         ::rtl::OUString sPropertyName( aProperties[i].Name );
140                         if ( sPropertyName.equalsAscii("Label" ) )
141                         {
142                             aProperties[i].Value >>= sLabel;
143                             break;
144                         }
145                     }
146                 }
147                 while ( false );
148             }
149             catch( Exception& rException )
150             {
151                 (void)rException;
152             }
153 
154             return sLabel;
155         }
156 
157         Image GetCommandIcon( const sal_Char* _pCommandURL, const ::rtl::OUString& _rModuleName )
158         {
159             Image aIcon;
160             if ( !_pCommandURL || !*_pCommandURL )
161                 return aIcon;
162 
163             Reference< XNameAccess > xUICommandLabels;
164             ::rtl::OUString sCommandURL = ::rtl::OUString::createFromAscii( _pCommandURL );
165             try
166             {
167                 do
168                 {
169                     // Retrieve popup menu labels
170                     Reference< XMultiServiceFactory> xFactory( ::comphelper::getProcessServiceFactory() );
171                     if ( !xFactory.is() )
172                         break;
173 
174                     Reference< XModuleUIConfigurationManagerSupplier > xSupplier(
175                         xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
176                             "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) ) ),
177                         UNO_QUERY_THROW );
178 
179                     Reference< XUIConfigurationManager > xManager( xSupplier->getUIConfigurationManager( _rModuleName ) );
180                     Reference< XImageManager > xImageManager;
181                     if ( xManager.is() )
182                         xImageManager = xImageManager.query( xManager->getImageManager() );
183                     if ( !xImageManager.is() )
184                         break;
185 
186                     Sequence< ::rtl::OUString > aCommandList( &sCommandURL, 1 );
187                     Sequence<Reference< XGraphic> > xIconList( xImageManager->getImages( 0, aCommandList ) );
188                     if ( !xIconList.hasElements() )
189                         break;
190 
191                     aIcon = Graphic( xIconList[0] ).GetBitmapEx();
192                 }
193                 while ( false );
194             }
195             catch ( Exception& rException )
196             {
197                 (void)rException;
198             }
199 
200             return aIcon;
201         }
202 
203 
204     }
205 
206 	//====================================================================
207 	//= OpenButton
208 	//====================================================================
209 	//--------------------------------------------------------------------
210     OpenDocumentButton::OpenDocumentButton( Window* _pParent, const sal_Char* _pAsciiModuleName, const ResId& _rResId )
211         :PushButton( _pParent, _rResId )
212     {
213         impl_init( _pAsciiModuleName );
214     }
215 
216     //--------------------------------------------------------------------
217     void OpenDocumentButton::impl_init( const sal_Char* _pAsciiModuleName )
218     {
219         DBG_ASSERT( _pAsciiModuleName, "OpenDocumentButton::impl_init: invalid module name!" );
220         m_sModule = ::rtl::OUString::createFromAscii( _pAsciiModuleName );
221 
222         // our label should equal the UI text of the "Open" command
223         String sLabel( GetCommandText( ".uno:Open", m_sModule ) );
224         sLabel.SearchAndReplaceAllAscii( "~", String() );
225         sLabel.Insert( (sal_Unicode)' ', 0 );
226         SetText( sLabel );
227 
228         // Place icon left of text and both centered in the button.
229         SetModeImage( GetCommandIcon( ".uno:Open", m_sModule ), BMP_COLOR_NORMAL );
230         EnableImageDisplay( sal_True );
231         EnableTextDisplay( sal_True );
232         SetImageAlign( IMAGEALIGN_LEFT );
233         SetStyle( GetStyle() | WB_CENTER );
234     }
235 
236 	//====================================================================
237 	//= OpenDocumentListBox
238 	//====================================================================
239     //--------------------------------------------------------------------
240     OpenDocumentListBox::OpenDocumentListBox( Window* _pParent, const sal_Char* _pAsciiModuleName, const ResId& _rResId )
241         :ListBox( _pParent, _rResId )
242     {
243         impl_init( _pAsciiModuleName );
244     }
245 
246     //--------------------------------------------------------------------
247     void OpenDocumentListBox::impl_init( const sal_Char* _pAsciiModuleName )
248     {
249         DBG_ASSERT( _pAsciiModuleName, "OpenDocumentListBox::impl_init: invalid module name!" );
250 
251         Sequence< Sequence< PropertyValue> > aHistory = SvtHistoryOptions().GetList( ePICKLIST );
252         Reference< XNameAccess > xFilterFactory;
253         xFilterFactory = xFilterFactory.query( ::comphelper::getProcessServiceFactory()->createInstance(
254             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.FilterFactory" ) ) ) );
255 
256         sal_uInt32 nCount = aHistory.getLength();
257         for ( sal_uInt32 nItem = 0; nItem < nCount; ++nItem )
258         {
259             try
260             {
261                 //  Get the current history item's properties.
262                 ::comphelper::SequenceAsHashMap aItemProperties( aHistory[ nItem ] );
263                 ::rtl::OUString sURL = aItemProperties.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_URL, ::rtl::OUString() );
264                 ::rtl::OUString sFilter = aItemProperties.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_FILTER, ::rtl::OUString() );
265                 String          sTitle = aItemProperties.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_TITLE, ::rtl::OUString() );
266                 ::rtl::OUString sPassword = aItemProperties.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_PASSWORD, ::rtl::OUString() );
267 
268                 //  If the entry is an impress file then insert it into the
269                 //  history list and the list box.
270                 Sequence< PropertyValue > aProps;
271                 xFilterFactory->getByName( sFilter ) >>= aProps;
272 
273                 ::comphelper::SequenceAsHashMap aFilterProperties( aProps );
274                 ::rtl::OUString sDocumentService = aFilterProperties.getUnpackedValueOrDefault(
275                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentService" ) ), ::rtl::OUString() );
276                 if ( sDocumentService.equalsAscii( _pAsciiModuleName ) )
277                 {
278                     // yes, it's a Base document
279                     INetURLObject aURL;
280                     aURL.SetSmartURL( sURL );
281                     // The password is set only when it is not empty.
282                     if ( sPassword.getLength() > 0 )
283                         aURL.SetPass( sPassword );
284 
285                     if ( !sTitle.Len() )
286                         sTitle = aURL.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_UNAMBIGUOUS );
287 
288                     String sDecodedURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
289 
290                     sal_uInt16 nPos = InsertEntry( sTitle );
291                     m_aURLs.insert( MapIndexToStringPair::value_type( nPos, StringPair( sDecodedURL, sFilter ) ) );
292                 }
293             }
294             catch( Exception& rException )
295             {
296                 (void)rException;
297             }
298         }
299     }
300 
301     //--------------------------------------------------------------------
302     String OpenDocumentListBox::GetSelectedDocumentURL() const
303     {
304         String sURL;
305         sal_uInt16 nSelected = GetSelectEntryPos();
306         if ( LISTBOX_ENTRY_NOTFOUND != GetSelectEntryPos() )
307             sURL = impl_getDocumentAtIndex( nSelected ).first;
308         return sURL;
309     }
310 
311     //--------------------------------------------------------------------
312     String OpenDocumentListBox::GetSelectedDocumentFilter() const
313     {
314         String sFilter;
315         sal_uInt16 nSelected = GetSelectEntryPos();
316         if ( LISTBOX_ENTRY_NOTFOUND != GetSelectEntryPos() )
317             sFilter = impl_getDocumentAtIndex( nSelected ).second;
318         return sFilter;
319     }
320 
321     //--------------------------------------------------------------------
322     OpenDocumentListBox::StringPair OpenDocumentListBox::impl_getDocumentAtIndex( sal_uInt16 _nListIndex, bool _bSystemNotation ) const
323     {
324         MapIndexToStringPair::const_iterator pos = m_aURLs.find( _nListIndex );
325         DBG_ASSERT( pos != m_aURLs.end(), "OpenDocumentListBox::impl_getDocumentAtIndex: invalid index!" );
326 
327         StringPair aDocumentDescriptor;
328         if ( pos != m_aURLs.end() )
329         {
330             aDocumentDescriptor = pos->second;
331             if ( _bSystemNotation && aDocumentDescriptor.first.Len() )
332             {
333                 ::svt::OFileNotation aNotation( aDocumentDescriptor.first );
334                 aDocumentDescriptor.first = aNotation.get( ::svt::OFileNotation::N_SYSTEM );
335             }
336         }
337         return aDocumentDescriptor;
338     }
339 
340     //--------------------------------------------------------------------
341     void  OpenDocumentListBox::RequestHelp( const HelpEvent& _rHEvt )
342     {
343 	    if( !( _rHEvt.GetMode() & HELPMODE_QUICK ) )
344             return;
345         if ( !IsEnabled() )
346             return;
347 
348         Point aRequestPos( ScreenToOutputPixel( _rHEvt.GetMousePosPixel() ) );
349         sal_uInt16 nItemIndex = LISTBOX_ENTRY_NOTFOUND;
350         if ( GetIndexForPoint( aRequestPos, nItemIndex ) != -1 )
351         {
352             Rectangle aItemRect( GetBoundingRectangle( nItemIndex ) );
353             aItemRect = Rectangle(
354                 OutputToScreenPixel( aItemRect.TopLeft() ),
355                 OutputToScreenPixel( aItemRect.BottomRight() ) );
356             String sHelpText = impl_getDocumentAtIndex( nItemIndex, true ).first;
357             Help::ShowQuickHelp( this, aItemRect, sHelpText, QUICKHELP_LEFT | QUICKHELP_VCENTER );
358         }
359     }
360 
361 //........................................................................
362 } // namespace dbaui
363 //........................................................................
364