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 void CalcActiveHeight( const long nPos ); 169 long GetTotalHeight() const; 170 void SetupScrollBar(); 171 void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry ); 172 bool HandleTabKey( bool bReverse ); 173 bool HandleCursorKey( sal_uInt16 nKeyCode ); 174 bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound ); 175 bool isHCMode(); 176 void DeleteRemoved(); 177 178 //----------------- 179 DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * ); 180 181 //Index starts with 1. 182 //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid. 183 void checkIndex(sal_Int32 pos) const; 184 185 186 public: 187 ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ); 188 ~ExtensionBox_Impl(); 189 190 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 191 virtual void Paint( const Rectangle &rPaintRect ); 192 virtual void Resize(); 193 virtual long Notify( NotifyEvent& rNEvt ); 194 195 const Size GetMinOutputSizePixel() const; 196 void SetExtraSize( long nSize ) { m_nExtraHeight = nSize; } 197 TEntry_Impl GetEntryData( long nPos ) { return m_vEntries[ nPos ]; } 198 long GetEntryCount() { return (long) m_vEntries.size(); } 199 Rectangle GetEntryRect( const long nPos ) const; 200 bool HasActive() { return m_bHasActive; } 201 long PointToPos( const Point& rPos ); 202 void SetScrollHdl( const Link& rLink ); 203 void DoScroll( long nDelta ); 204 void SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; } 205 virtual void RecalcAll(); 206 void RemoveUnlocked(); 207 208 //----------------- 209 virtual void selectEntry( const long nPos ); 210 long addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, 211 bool bLicenseMissing = false ); 212 void updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); 213 void removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); 214 215 void prepareChecking(); 216 void checkEntries(); 217 218 TheExtensionManager* getExtensionManager() const { return m_pManager; } 219 220 //=================================================================================== 221 //These functions are used for automatic testing 222 223 /** @return The count of the entries in the list box. */ 224 virtual sal_Int32 getItemCount() const; 225 226 /** @return The index of the first selected entry in the list box. 227 When nothing is selected, which is the case when getItemCount returns '0', 228 then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */ 229 virtual sal_Int32 getSelIndex() const; 230 231 /** @return The item name of the entry with the given index 232 The index starts with 0. 233 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 234 virtual ::rtl::OUString getItemName( sal_Int32 index ) const; 235 236 /** @return The version string of the entry with the given index 237 The index starts with 0. 238 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 239 virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const; 240 241 /** @return The description string of the entry with the given index 242 The index starts with 0. 243 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 244 virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const; 245 246 /** @return The publisher string of the entry with the given index 247 The index starts with 0. 248 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 249 virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const; 250 251 /** @return The link behind the publisher text of the entry with the given index 252 The index starts with 0. 253 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 254 virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const; 255 256 /** The entry at the given position will be selected 257 Index starts with 0. 258 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 259 virtual void select( sal_Int32 pos ); 260 261 /** The first found entry with the given name will be selected 262 When there was no entry found with the name, the selection doesn't change. 263 Please note that there might be more than one entry with the same 264 name, because: 265 1. the name is not unique 266 2. one extension can be installed as user and shared extension. 267 */ 268 virtual void select( const ::rtl::OUString & sName ); 269 }; 270 271 } 272