1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "opendoccontrols.hxx"
22 #include <com/sun/star/uno/Sequence.hxx>
23 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
27 #include <com/sun/star/frame/theUICommandDescription.hpp>
28 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
29 #include <com/sun/star/graphic/XGraphic.hpp>
30 #include <com/sun/star/ui/XImageManager.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <vcl/graph.hxx>
34 #include <vcl/help.hxx>
35 #include <unotools/historyoptions.hxx>
36 #include <comphelper/sequenceashashmap.hxx>
37 #include <tools/urlobj.hxx>
38 #include <svl/filenotation.hxx>
39 #include <osl/diagnose.h>
40 #include <vcl/builderfactory.hxx>
47 using ::com::sun::star::uno::Reference
;
48 using ::com::sun::star::uno::Exception
;
49 using ::com::sun::star::uno::Sequence
;
50 using ::com::sun::star::uno::UNO_QUERY_THROW
;
51 using ::com::sun::star::uno::XComponentContext
;
52 using ::com::sun::star::container::XNameAccess
;
53 using ::com::sun::star::lang::XMultiServiceFactory
;
54 using ::com::sun::star::beans::PropertyValue
;
55 using ::com::sun::star::ui::theModuleUIConfigurationManagerSupplier
;
56 using ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier
;
57 using ::com::sun::star::ui::XUIConfigurationManager
;
58 using ::com::sun::star::ui::XImageManager
;
59 using ::com::sun::star::frame::theUICommandDescription
;
60 using ::com::sun::star::graphic::XGraphic
;
62 OUString
GetCommandText( const sal_Char
* _pCommandURL
, const OUString
& _rModuleName
)
65 if ( !_pCommandURL
|| !*_pCommandURL
)
68 Reference
< XNameAccess
> xUICommandLabels
;
69 OUString sCommandURL
= OUString::createFromAscii( _pCommandURL
);
75 // Retrieve popup menu labels
76 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
80 Reference
< XNameAccess
> xNameAccess( theUICommandDescription::get(xContext
) );
82 xNameAccess
->getByName( _rModuleName
) >>= xUICommandLabels
;
83 if ( !xUICommandLabels
.is() )
86 Sequence
< PropertyValue
> aProperties
;
87 if ( !( xUICommandLabels
->getByName(sCommandURL
) >>= aProperties
) )
90 sal_Int32
nCount( aProperties
.getLength() );
91 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
93 OUString
sPropertyName( aProperties
[i
].Name
);
94 if ( sPropertyName
== "Label" )
96 aProperties
[i
].Value
>>= sLabel
;
103 catch( Exception
& rException
)
111 Image
GetCommandIcon( const sal_Char
* _pCommandURL
, const OUString
& _rModuleName
)
114 if ( !_pCommandURL
|| !*_pCommandURL
)
117 Reference
< XNameAccess
> xUICommandLabels
;
118 OUString sCommandURL
= OUString::createFromAscii( _pCommandURL
);
123 // Retrieve popup menu labels
124 Reference
< com::sun::star::uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
125 if ( !xContext
.is() )
128 Reference
< XModuleUIConfigurationManagerSupplier
> xSupplier(
129 theModuleUIConfigurationManagerSupplier::get(xContext
) );
131 Reference
< XUIConfigurationManager
> xManager( xSupplier
->getUIConfigurationManager( _rModuleName
) );
132 Reference
< XImageManager
> xImageManager
;
134 xImageManager
.set(xManager
->getImageManager(), css::uno::UNO_QUERY
);
135 if ( !xImageManager
.is() )
138 Sequence
< OUString
> aCommandList( &sCommandURL
, 1 );
139 Sequence
<Reference
< XGraphic
> > xIconList( xImageManager
->getImages( 0, aCommandList
) );
140 if ( !xIconList
.hasElements() )
143 aIcon
= Image(Graphic(xIconList
[0]).GetBitmapEx());
147 catch ( Exception
& rException
)
159 OpenDocumentButton::OpenDocumentButton( vcl::Window
* _pParent
, const sal_Char
* _pAsciiModuleName
)
160 :PushButton( _pParent
)
162 impl_init( _pAsciiModuleName
);
165 VCL_BUILDER_FACTORY_ARGS( OpenDocumentButton
, "com.sun.star.sdb.OfficeDatabaseDocument" );
167 void OpenDocumentButton::impl_init( const sal_Char
* _pAsciiModuleName
)
169 OSL_ENSURE( _pAsciiModuleName
, "OpenDocumentButton::impl_init: invalid module name!" );
170 m_sModule
= OUString::createFromAscii( _pAsciiModuleName
);
172 // our label should equal the UI text of the "Open" command
173 OUString
sLabel(GetCommandText(".uno:Open", m_sModule
));
174 SetText(" " + sLabel
.replaceAll("~", OUString()));
176 // Place icon left of text and both centered in the button.
177 SetModeImage( GetCommandIcon( ".uno:Open", m_sModule
) );
178 EnableImageDisplay( true );
179 EnableTextDisplay( true );
180 SetImageAlign( IMAGEALIGN_LEFT
);
181 SetStyle( GetStyle() | WB_CENTER
);
184 // OpenDocumentListBox
186 OpenDocumentListBox::OpenDocumentListBox( vcl::Window
* _pParent
, const sal_Char
* _pAsciiModuleName
)
187 :ListBox( _pParent
, WB_BORDER
| WB_DROPDOWN
)
189 impl_init( _pAsciiModuleName
);
192 VCL_BUILDER_FACTORY_ARGS( OpenDocumentListBox
, "com.sun.star.sdb.OfficeDatabaseDocument" );
194 void OpenDocumentListBox::impl_init( const sal_Char
* _pAsciiModuleName
)
196 OSL_ENSURE( _pAsciiModuleName
, "OpenDocumentListBox::impl_init: invalid module name!" );
198 Sequence
< Sequence
< PropertyValue
> > aHistory
= SvtHistoryOptions().GetList( ePICKLIST
);
199 Reference
< XNameAccess
> xFilterFactory
;
200 xFilterFactory
.set(::comphelper::getProcessServiceFactory()->createInstance(
201 OUString( "com.sun.star.document.FilterFactory" ) ), css::uno::UNO_QUERY
);
203 sal_uInt32 nCount
= aHistory
.getLength();
204 for ( sal_uInt32 nItem
= 0; nItem
< nCount
; ++nItem
)
208 // Get the current history item's properties.
209 ::comphelper::SequenceAsHashMap
aItemProperties( aHistory
[ nItem
] );
210 OUString sURL
= aItemProperties
.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_URL
, OUString() );
211 OUString sFilter
= aItemProperties
.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_FILTER
, OUString() );
212 OUString sTitle
= aItemProperties
.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_TITLE
, OUString() );
213 OUString sPassword
= aItemProperties
.getUnpackedValueOrDefault( HISTORY_PROPERTYNAME_PASSWORD
, OUString() );
215 // If the entry is an impress file then insert it into the
216 // history list and the list box.
217 Sequence
< PropertyValue
> aProps
;
218 xFilterFactory
->getByName( sFilter
) >>= aProps
;
220 ::comphelper::SequenceAsHashMap
aFilterProperties( aProps
);
221 OUString sDocumentService
= aFilterProperties
.getUnpackedValueOrDefault(
222 OUString( "DocumentService" ), OUString() );
223 if ( sDocumentService
.equalsAscii( _pAsciiModuleName
) )
225 // yes, it's a Base document
227 aURL
.SetSmartURL( sURL
);
228 // The password is set only when it is not empty.
229 if ( !sPassword
.isEmpty() )
230 aURL
.SetPass( sPassword
);
232 if ( sTitle
.isEmpty() )
233 sTitle
= aURL
.getBase( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_UNAMBIGUOUS
);
235 OUString sDecodedURL
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
237 sal_Int32 nPos
= InsertEntry( sTitle
);
238 m_aURLs
.insert( MapIndexToStringPair::value_type( nPos
, StringPair( sDecodedURL
, sFilter
) ) );
241 catch( Exception
& rException
)
248 OUString
OpenDocumentListBox::GetSelectedDocumentURL() const
251 sal_Int32 nSelected
= GetSelectEntryPos();
252 if ( LISTBOX_ENTRY_NOTFOUND
!= GetSelectEntryPos() )
253 sURL
= impl_getDocumentAtIndex( nSelected
).first
;
257 OUString
OpenDocumentListBox::GetSelectedDocumentFilter() const
260 sal_Int32 nSelected
= GetSelectEntryPos();
261 if ( LISTBOX_ENTRY_NOTFOUND
!= GetSelectEntryPos() )
262 sFilter
= impl_getDocumentAtIndex( nSelected
).second
;
266 OpenDocumentListBox::StringPair
OpenDocumentListBox::impl_getDocumentAtIndex( sal_uInt16 _nListIndex
, bool _bSystemNotation
) const
268 MapIndexToStringPair::const_iterator pos
= m_aURLs
.find( _nListIndex
);
269 OSL_ENSURE( pos
!= m_aURLs
.end(), "OpenDocumentListBox::impl_getDocumentAtIndex: invalid index!" );
271 StringPair aDocumentDescriptor
;
272 if ( pos
!= m_aURLs
.end() )
274 aDocumentDescriptor
= pos
->second
;
275 if ( _bSystemNotation
&& !aDocumentDescriptor
.first
.isEmpty() )
277 ::svt::OFileNotation
aNotation( aDocumentDescriptor
.first
);
278 aDocumentDescriptor
.first
= aNotation
.get( ::svt::OFileNotation::N_SYSTEM
);
281 return aDocumentDescriptor
;
284 void OpenDocumentListBox::RequestHelp( const HelpEvent
& _rHEvt
)
286 if( !( _rHEvt
.GetMode() & HelpEventMode::QUICK
) )
291 Point
aRequestPos( ScreenToOutputPixel( _rHEvt
.GetMousePosPixel() ) );
292 sal_Int32 nItemIndex
= LISTBOX_ENTRY_NOTFOUND
;
293 if ( GetIndexForPoint( aRequestPos
, nItemIndex
) != -1 )
295 Rectangle
aItemRect( GetBoundingRectangle( nItemIndex
) );
296 aItemRect
= Rectangle(
297 OutputToScreenPixel( aItemRect
.TopLeft() ),
298 OutputToScreenPixel( aItemRect
.BottomRight() ) );
299 OUString sHelpText
= impl_getDocumentAtIndex( nItemIndex
, true ).first
;
300 Help::ShowQuickHelp( this, aItemRect
, sHelpText
, QuickHelpFlags::Left
| QuickHelpFlags::VCenter
);
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */