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