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