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 throw (::com::sun::star::uno::RuntimeException); 115 }; 116 117 //------------------------------------------------------------------------------ 118 class ExtensionBox_Impl : public ::svt::IExtensionListBox 119 { 120 bool m_bHasScrollBar; 121 bool m_bHasActive; 122 bool m_bNeedsRecalc; 123 bool m_bHasNew; 124 bool m_bInCheckMode; 125 bool m_bAdjustActive; 126 bool m_bInDelete; 127 //Must be guarded together with m_vEntries to ensure a valid index at all times. 128 //Use m_entriesMutex as guard. 129 long m_nActive; 130 long m_nTopIndex; 131 long m_nStdHeight; 132 long m_nActiveHeight; 133 long m_nExtraHeight; 134 Size m_aOutputSize; 135 Image m_aSharedImage; 136 Image m_aSharedImageHC; 137 Image m_aLockedImage; 138 Image m_aLockedImageHC; 139 Image m_aWarningImage; 140 Image m_aWarningImageHC; 141 Image m_aDefaultImage; 142 Image m_aDefaultImageHC; 143 Link m_aClickHdl; 144 145 ScrollBar *m_pScrollBar; 146 147 com::sun::star::uno::Reference< ExtensionRemovedListener > m_xRemoveListener; 148 149 TheExtensionManager *m_pManager; 150 //This mutex is used for synchronizing access to m_vEntries. 151 //Currently it is used to synchronize adding, removing entries and 152 //functions like getItemName, getItemDescription, etc. to prevent 153 //that m_vEntries is accessed at an invalid index. 154 //ToDo: There are many more places where m_vEntries is read and which may 155 //fail. For example the Paint method is probable called from the main thread 156 //while new entries are added / removed in a separate thread. 157 mutable ::osl::Mutex m_entriesMutex; 158 std::vector< TEntry_Impl > m_vEntries; 159 std::vector< TEntry_Impl > m_vRemovedEntries; 160 161 ::com::sun::star::lang::Locale *m_pLocale; 162 CollatorWrapper *m_pCollator; 163 164 //Holds weak references to extensions to which is we have added an XEventListener 165 std::vector< ::com::sun::star::uno::WeakReference< 166 ::com::sun::star::deployment::XPackage> > m_vListenerAdded; 167 //Removes the dead weak references from m_vListenerAdded 168 void cleanVecListenerAdded(); 169 void addEventListenerOnce( ::com::sun::star::uno::Reference< 170 ::com::sun::star::deployment::XPackage> const & extension); 171 172 void CalcActiveHeight( const long nPos ); 173 long GetTotalHeight() const; 174 void SetupScrollBar(); 175 void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry ); 176 bool HandleTabKey( bool bReverse ); 177 bool HandleCursorKey( sal_uInt16 nKeyCode ); 178 bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound ); 179 bool isHCMode(); 180 void DeleteRemoved(); 181 182 //----------------- 183 DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * ); 184 185 //Index starts with 1. 186 //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid. 187 void checkIndex(sal_Int32 pos) const; 188 189 190 public: 191 ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ); 192 ~ExtensionBox_Impl(); 193 194 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 195 virtual void Paint( const Rectangle &rPaintRect ); 196 virtual void Resize(); 197 virtual long Notify( NotifyEvent& rNEvt ); 198 199 const Size GetMinOutputSizePixel() const; SetExtraSize(long nSize)200 void SetExtraSize( long nSize ) { m_nExtraHeight = nSize; } GetEntryData(long nPos)201 TEntry_Impl GetEntryData( long nPos ) { return m_vEntries[ nPos ]; } GetEntryCount()202 long GetEntryCount() { return (long) m_vEntries.size(); } 203 Rectangle GetEntryRect( const long nPos ) const; HasActive()204 bool HasActive() { return m_bHasActive; } 205 long PointToPos( const Point& rPos ); 206 void SetScrollHdl( const Link& rLink ); 207 void DoScroll( long nDelta ); SetHyperlinkHdl(const Link & rLink)208 void SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; } 209 virtual void RecalcAll(); 210 void RemoveUnlocked(); 211 212 //----------------- 213 virtual void selectEntry( const long nPos ); 214 long addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage, 215 bool bLicenseMissing = false ); 216 void updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); 217 void removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ); 218 219 void prepareChecking(); 220 void checkEntries(); 221 getExtensionManager() const222 TheExtensionManager* getExtensionManager() const { return m_pManager; } 223 224 //=================================================================================== 225 //These functions are used for automatic testing 226 227 /** @return The count of the entries in the list box. */ 228 virtual sal_Int32 getItemCount() const; 229 230 /** @return The index of the first selected entry in the list box. 231 When nothing is selected, which is the case when getItemCount returns '0', 232 then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */ 233 virtual sal_Int32 getSelIndex() const; 234 235 /** @return The item name of the entry with the given index 236 The index starts with 0. 237 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 238 virtual ::rtl::OUString getItemName( sal_Int32 index ) const; 239 240 /** @return The version string of the entry with the given index 241 The index starts with 0. 242 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 243 virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const; 244 245 /** @return The description string of the entry with the given index 246 The index starts with 0. 247 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 248 virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const; 249 250 /** @return The publisher string of the entry with the given index 251 The index starts with 0. 252 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 253 virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const; 254 255 /** @return The link behind the publisher text of the entry with the given index 256 The index starts with 0. 257 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 258 virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const; 259 260 /** The entry at the given position will be selected 261 Index starts with 0. 262 Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */ 263 virtual void select( sal_Int32 pos ); 264 265 /** The first found entry with the given name will be selected 266 When there was no entry found with the name, the selection doesn't change. 267 Please note that there might be more than one entry with the same 268 name, because: 269 1. the name is not unique 270 2. one extension can be installed as user and shared extension. 271 */ 272 virtual void select( const ::rtl::OUString & sName ); 273 }; 274 275 } 276