xref: /trunk/main/desktop/source/deployment/gui/dp_gui_extlistbox.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 "rtl/ustring.hxx"
25 #include "vcl/scrbar.hxx"
26 #include "vcl/fixed.hxx"
27 #include "vcl/dialog.hxx"
28 
29 #include "svtools/extensionlistbox.hxx"
30 #include "svtools/fixedhyper.hxx"
31 #include "cppuhelper/implbase1.hxx"
32 #include "unotools/collatorwrapper.hxx"
33 
34 #include "com/sun/star/lang/Locale.hpp"
35 #include "com/sun/star/lang/XEventListener.hpp"
36 #include "com/sun/star/deployment/XPackage.hpp"
37 
38 #include <boost/shared_ptr.hpp>
39 
40 namespace dp_gui {
41 
42 #define SMALL_ICON_SIZE     16
43 #define TOP_OFFSET           5
44 #define ICON_HEIGHT         42
45 #define ICON_WIDTH          47
46 #define ICON_OFFSET         72
47 #define RIGHT_ICON_OFFSET    5
48 #define SPACE_BETWEEN        3
49 
50 class TheExtensionManager;
51 
52 typedef ::boost::shared_ptr< svt::FixedHyperlink > TFixedHyperlink;
53 
54 //------------------------------------------------------------------------------
55 //                          struct Entry_Impl
56 //------------------------------------------------------------------------------
57 struct Entry_Impl;
58 
59 typedef ::boost::shared_ptr< Entry_Impl > TEntry_Impl;
60 
61 struct Entry_Impl
62 {
63     bool            m_bActive       :1;
64     bool            m_bLocked       :1;
65     bool            m_bHasOptions   :1;
66     bool            m_bUser         :1;
67     bool            m_bShared       :1;
68     bool            m_bNew          :1;
69     bool            m_bChecked      :1;
70     bool            m_bMissingDeps  :1;
71     bool            m_bHasButtons   :1;
72     bool            m_bMissingLic   :1;
73     PackageState    m_eState;
74     String          m_sTitle;
75     String          m_sVersion;
76     String          m_sDescription;
77     String          m_sPublisher;
78     String          m_sPublisherURL;
79     String          m_sErrorText;
80     String          m_sLicenseText;
81     Image           m_aIcon;
82     Image           m_aIconHC;
83     svt::FixedHyperlink *m_pPublisher;
84 
85     ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
86 
87     Entry_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
88                 const PackageState eState, const bool bReadOnly );
89    ~Entry_Impl();
90 
91     StringCompare CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const;
92     void          checkDependencies();
93 };
94 
95 //------------------------------------------------------------------------------
96 //                          class ExtensionBox_Impl
97 //------------------------------------------------------------------------------
98 
99 class ExtensionBox_Impl;
100 
101 //------------------------------------------------------------------------------
102 class ExtensionRemovedListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
103 {
104     ExtensionBox_Impl   *m_pParent;
105 
106 public:
107 
ExtensionRemovedListener(ExtensionBox_Impl * pParent)108     ExtensionRemovedListener( ExtensionBox_Impl *pParent ) { m_pParent = pParent; }
109    ~ExtensionRemovedListener();
110 
111     //===================================================================================
112     // XEventListener
113     virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt );
114 };
115 
116 //------------------------------------------------------------------------------
117 class ExtensionBox_Impl : public ::svt::IExtensionListBox
118 {
119     bool            m_bHasScrollBar;
120     bool            m_bHasActive;
121     bool            m_bNeedsRecalc;
122     bool            m_bHasNew;
123     bool            m_bInCheckMode;
124     bool            m_bAdjustActive;
125     bool            m_bInDelete;
126     //Must be guarded together with m_vEntries to ensure a valid index at all times.
127     //Use m_entriesMutex as guard.
128     long            m_nActive;
129     long            m_nTopIndex;
130     long            m_nStdHeight;
131     long            m_nActiveHeight;
132     long            m_nExtraHeight;
133     Size            m_aOutputSize;
134     Image           m_aSharedImage;
135     Image           m_aSharedImageHC;
136     Image           m_aLockedImage;
137     Image           m_aLockedImageHC;
138     Image           m_aWarningImage;
139     Image           m_aWarningImageHC;
140     Image           m_aDefaultImage;
141     Image           m_aDefaultImageHC;
142     Link            m_aClickHdl;
143 
144     ScrollBar      *m_pScrollBar;
145 
146     com::sun::star::uno::Reference< ExtensionRemovedListener > m_xRemoveListener;
147 
148     TheExtensionManager      *m_pManager;
149     //This mutex is used for synchronizing access to m_vEntries.
150     //Currently it is used to synchronize adding, removing entries and
151     //functions like getItemName, getItemDescription, etc. to prevent
152     //that m_vEntries is accessed at an invalid index.
153     //ToDo: There are many more places where m_vEntries is read and which may
154     //fail. For example the Paint method is probable called from the main thread
155     //while new entries are added / removed in a separate thread.
156     mutable ::osl::Mutex    m_entriesMutex;
157     std::vector< TEntry_Impl > m_vEntries;
158     std::vector< TEntry_Impl > m_vRemovedEntries;
159 
160     ::com::sun::star::lang::Locale    *m_pLocale;
161     CollatorWrapper *m_pCollator;
162 
163     //Holds weak references to extensions to which is we have added an XEventListener
164     std::vector< ::com::sun::star::uno::WeakReference<
165         ::com::sun::star::deployment::XPackage> > m_vListenerAdded;
166     //Removes the dead weak references from m_vListenerAdded
167     void cleanVecListenerAdded();
168     void addEventListenerOnce( ::com::sun::star::uno::Reference<
169                                ::com::sun::star::deployment::XPackage> const & extension);
170 
171     void            CalcActiveHeight( const long nPos );
172     long            GetTotalHeight() const;
173     void            SetupScrollBar();
174     void            DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry );
175     bool            HandleTabKey( bool bReverse );
176     bool            HandleCursorKey( sal_uInt16 nKeyCode );
177     bool            FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound );
178     bool            isHCMode();
179     void            DeleteRemoved();
180 
181     //-----------------
182     DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
183 
184     //Index starts with 1.
185     //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid.
186     void checkIndex(sal_Int32 pos) const;
187 
188 
189 public:
190                     ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager );
191                    ~ExtensionBox_Impl();
192 
193     virtual void    MouseButtonDown( const MouseEvent& rMEvt );
194     virtual void    Paint( const Rectangle &rPaintRect );
195     virtual void    Resize();
196     virtual long    Notify( NotifyEvent& rNEvt );
197 
198     const Size      GetMinOutputSizePixel() const;
SetExtraSize(long nSize)199     void            SetExtraSize( long nSize ) { m_nExtraHeight = nSize; }
GetEntryData(long nPos)200     TEntry_Impl     GetEntryData( long nPos ) { return m_vEntries[ nPos ]; }
GetEntryCount()201     long            GetEntryCount() { return (long) m_vEntries.size(); }
202     Rectangle       GetEntryRect( const long nPos ) const;
HasActive()203     bool            HasActive() { return m_bHasActive; }
204     long            PointToPos( const Point& rPos );
205     void            SetScrollHdl( const Link& rLink );
206     void            DoScroll( long nDelta );
SetHyperlinkHdl(const Link & rLink)207     void            SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; }
208     virtual void    RecalcAll();
209     void            RemoveUnlocked();
210 
211     //-----------------
212     virtual void    selectEntry( const long nPos );
213     long            addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
214                               bool bLicenseMissing = false );
215     void            updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
216     void            removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
217 
218     void            prepareChecking();
219     void            checkEntries();
220 
getExtensionManager() const221     TheExtensionManager*    getExtensionManager() const { return m_pManager; }
222 
223     //===================================================================================
224     //These functions are used for automatic testing
225 
226     /** @return  The count of the entries in the list box. */
227     virtual sal_Int32 getItemCount() const;
228 
229     /** @return  The index of the first selected entry in the list box.
230         When nothing is selected, which is the case when getItemCount returns '0',
231         then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */
232     virtual sal_Int32 getSelIndex() const;
233 
234     /** @return  The item name of the entry with the given index
235         The index starts with 0.
236         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
237     virtual ::rtl::OUString getItemName( sal_Int32 index ) const;
238 
239     /** @return  The version string of the entry with the given index
240         The index starts with 0.
241         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
242     virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const;
243 
244     /** @return  The description string of the entry with the given index
245         The index starts with 0.
246         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
247     virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const;
248 
249     /** @return  The publisher string of the entry with the given index
250         The index starts with 0.
251         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
252     virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const;
253 
254     /** @return  The link behind the publisher text of the entry with the given index
255         The index starts with 0.
256         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
257     virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const;
258 
259     /** The entry at the given position will be selected
260         Index starts with 0.
261         Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
262     virtual void select( sal_Int32 pos );
263 
264     /** The first found entry with the given name will be selected
265         When there was no entry found with the name, the selection doesn't change.
266         Please note that there might be more than one entry with the same
267         name, because:
268             1. the name is not unique
269             2. one extension can be installed as user and shared extension.
270     */
271     virtual void select( const ::rtl::OUString & sName );
272 };
273 
274 }
275