00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef SIGNATURESELECTOR_H 00011 #define SIGNATURESELECTOR_H 00012 00013 #include <QtCore/QRegExp> 00014 #include <QtCore/QStringList> 00015 #include <QtGui/QAction> 00016 #include <QtGui/QDialog> 00017 #include <QtGui/QLayout> 00018 #include <QtGui/QListWidget> 00019 #include <QtGui/QPushButton> 00020 #include <QtGui/QTreeWidget> 00021 #include <QtGui/QTreeWidgetItem> 00022 00023 #include "ModelServices.h" 00024 #include "PlugInManagerServices.h" 00025 #include "UtilityServices.h" 00026 00027 #include <string> 00028 #include <vector> 00029 00030 class DynamicObject; 00031 class Progress; 00032 class SearchDlg; 00033 class Signature; 00034 class SignatureSet; 00035 00036 /** 00037 * A dialog to import and select signatures. 00038 * 00039 * The signature selector is a dialog that allows users to select one or more 00040 * signatures from a list. The dialog displays a list of signatures containing 00041 * all Signature objects currently loaded into the data model. The user has the 00042 * option of creating one or more filters that will reduce the number of 00043 * signatures displayed in the list. Filters can be created based on any 00044 * combination of the following signature attributes: 00045 * - %Signature Name 00046 * - Metadata Attribute Name 00047 * - Metadata Attribute Value 00048 * 00049 * When creating the filter, wildcarding and case sensitivity options can be 00050 * set separately on each of the filter criteria listed above. The filter can 00051 * also be applied to signature libraries as a whole, or to the individual 00052 * signatures contained within the library. 00053 * 00054 * If the user does not find the desired signature(s) in the list, an Import 00055 * button is provided for the user to import one or more signatures while the 00056 * dialog remains active. 00057 * 00058 * When the user clicks the Import button, the dialog is expanded to contain a 00059 * separate list of signature files from which the user can select one or more 00060 * signatures to import. After import, the main signature list is updated 00061 * appropriately. 00062 * 00063 * On signature import, the user can browse the disk for one or more signature 00064 * files in a single directory or the user can search one or more directories 00065 * for recognized signature files. 00066 * 00067 * When a single signature in the main signature list is selected, the user can 00068 * view the signature's properties by clicking on the %Properties button in the 00069 * dialog. 00070 * 00071 * By default, the dialog contains OK and Cancel buttons. For modeless 00072 * instantiations of the dialog an Apply button can be added by setting the 00073 * appropriate parameter in the constructor. When the dialog contains an Apply 00074 * button, it can be enabled and disabled by calling enableApplyButton(). A 00075 * custom button can also be added to the dialog by passing the button text 00076 * into the constructor. When the dialog contains a custom button, it can be 00077 * enabled and displayed by calling enableCustomButton(). 00078 * 00079 * @see Signature, SignatureSet 00080 */ 00081 class SignatureSelector : public QDialog 00082 { 00083 Q_OBJECT 00084 00085 public: 00086 /** 00087 * Creates the signature selector dialog. 00088 * 00089 * The constructor creates the widgets and initializes the signature list 00090 * based on all loaded signatures in the data model. 00091 * 00092 * @param pProgress 00093 * An optional Progress object that is used when searching for 00094 * signatures to import. 00095 * @param pParent 00096 * The dialog's parent widget. 00097 * @param mode 00098 * The selection mode to be used for the list of signatures. 00099 * @param addApply 00100 * If \c true, an Apply button will appear. 00101 * @param customButtonLabel 00102 * Label that will appear on the custom button. The custom button 00103 * will only be added to the dialog if \c customButtonLabel is not 00104 * empty. 00105 */ 00106 SignatureSelector(Progress* pProgress, QWidget* pParent = NULL, 00107 QAbstractItemView::SelectionMode mode = QAbstractItemView::ExtendedSelection, bool addApply = false, 00108 const std::string& customButtonLabel = std::string()); 00109 00110 /** 00111 * Destroys the signature selector dialog. 00112 */ 00113 ~SignatureSelector(); 00114 00115 /** 00116 * Returns a vector of currently selected signatures. 00117 * 00118 * This method returns a vector of all selected signatures in the list view. 00119 * If a signature set is selected, only the SignatureSet object is added to 00120 * the vector. %Any selected signatures contained in the selected signature 00121 * set are not added to the vector. 00122 * 00123 * To obtain a vector that includes Signature objects inside a selected 00124 * SignatureSet object, call getExtractedSignatures() instead. 00125 * 00126 * @return A vector of the selected Signature objects. 00127 */ 00128 virtual std::vector<Signature*> getSignatures() const; 00129 00130 /** 00131 * Returns a vector of currently selected signatures. 00132 * 00133 * This method returns a vector of each individual signature based on the 00134 * selected items in the list view. If a signature set is selected, the 00135 * SignatureSet object is not added to the vector, but each individual 00136 * signature contained in the SignatureSet object is added. Signatures 00137 * contained inside a selected signature set are only added to the vector 00138 * once, regardless of whether or not the signature inside the selected 00139 * signature set is also selected. If signatures are filtered out of a 00140 * selected signature set object, only the signatures in the set that pass 00141 * the filter are added to the vector. 00142 * 00143 * To obtain a vector of just the selected signature and signature set 00144 * objects, call getSignatures() instead. 00145 * 00146 * @return A vector containing the individual Signature objects based on 00147 * the selected items in the list view. 00148 */ 00149 std::vector<Signature*> getExtractedSignatures() const; 00150 00151 /** 00152 * Queries whether the Apply button is currently enabled. 00153 * 00154 * The dialog does not automatically enable or disable the Apply button. By default 00155 * the Apply button is enabled when it is created. So, this method is really only 00156 * useful after the enableApplyButton() method has been called. 00157 * 00158 * @return This method returns \c true if the Apply button is currently enabled, or 00159 * \c false if the Apply button is disabled. \c False is also returned if the 00160 * dialog is modal and therefore does not contain the Apply button. 00161 */ 00162 bool isApplyButtonEnabled() const; 00163 00164 public slots: 00165 /** 00166 * Stops the directory search for signatures to import. 00167 * 00168 * This method is typically used as a slot method to connect or a cancel button on 00169 * a progress dialog. The method simply registers an abort notification with the 00170 * search dialog, regardless of whether a search is currently in progress. If this 00171 * method is called independently from a user-instantiated event such as a button 00172 * click, the abort will be registered and afterward if the user attempts a search, 00173 * the abort will prevent that search from occurring. 00174 */ 00175 void abortSearch(); 00176 00177 signals: 00178 /** 00179 * Indicates a change of the selected signatures in the list view. 00180 */ 00181 void selectionChanged(); 00182 00183 protected: 00184 /** 00185 * Adds a top-level item to the signature display format tree widget. 00186 * 00187 * This is used by subclasses to add custom signature types. In addition to 00188 * calling this method, a subclass will usually need to implement 00189 * updateSignatureList() to populate the signature list when the custom type 00190 * is selected. Also, getSignatures() will need to be implemented to return 00191 * the selected signature when the custom type is selected. 00192 * 00193 * @param type 00194 * The type name to add. 00195 */ 00196 void addCustomType(const QString& type); 00197 00198 /** 00199 * Access the current signature format type. 00200 * 00201 * @return The current signature format type. 00202 */ 00203 QString getCurrentFormatType() const; 00204 00205 /** 00206 * Access the signature list. 00207 * 00208 * Used to add items to the signature list when a custom format type is selected. 00209 * 00210 * @return The signature list. 00211 */ 00212 QTreeWidget* getSignatureList() const; 00213 00214 /** 00215 * Returns the widget layout in the dialog. 00216 * 00217 * This method returns the layout in the dialog, which can be used by derived classes 00218 * to add their own custom widgets. 00219 * 00220 * @return The layout for the child widgets in the dialog. 00221 */ 00222 QGridLayout* getLayout() const; 00223 00224 /** 00225 * Sets the column text of the signature name column in the list view selection widget. 00226 * 00227 * @param strName 00228 * The new name for the signature name column. This method does nothing if 00229 * the given string is empty. 00230 */ 00231 void setNameText(const QString& strName); 00232 00233 /** 00234 * Returns the number of selected items in the signature list. 00235 * 00236 * This method returns the current number of selected items in the list view. This 00237 * does not necessarily equal the number of selected signatures returned by 00238 * getSignatures().size(). 00239 * 00240 * @return The number of selected signature items in the list view. 00241 */ 00242 int getNumSelectedSignatures() const; 00243 00244 /** 00245 * Enables or disables the Apply button. 00246 * 00247 * This method enables or disables the Apply button if the dialog was 00248 * set to contain an Apply button in the constructor. When the dialog is 00249 * created with an Apply button, it is disabled by default. This method 00250 * does nothing if the dialog is created without an Apply button. 00251 * 00252 * @param enable 00253 * Set this parameter to \c true to enable the Apply button or to 00254 * \c false to disable the Apply button. 00255 * 00256 * @see isApplyButtonEnabled() 00257 */ 00258 void enableApplyButton(bool enable); 00259 00260 /** 00261 * Enables or disables the custom button. 00262 * 00263 * This method enables or disables the custom button if the dialog was 00264 * set to contain a custom button in the constructor. When the dialog is 00265 * created with a custom button, it is enabled by default. This method does 00266 * nothing if the dialog is created without a custom button. 00267 * 00268 * @param enable 00269 * Set this parameter to \c true to enable the custom button or to 00270 * \c false to disable the custom button. 00271 */ 00272 void enableCustomButton(bool enable); 00273 00274 protected slots: 00275 /** 00276 * Applies actions based on the selected signatures. 00277 * 00278 * This method is called if the dialog is modeless and the user clicks the Apply button 00279 * or the OK button. The default implementation of the method does nothing. It is 00280 * provided for derived classes to override to perform actions when the user clicks the 00281 * button. If a modeless dialog is created without the need for an Apply button, the 00282 * button should be disabled. 00283 * 00284 * @see enableApplyButton() 00285 */ 00286 virtual void apply(); 00287 00288 /** 00289 * Sets the format type that is used to display signatures in the list. 00290 * 00291 * This method updates the signature list to display different sets of 00292 * signatures. By default, "Signatures" and the names of any created 00293 * filters are available format types. Custom format types are also 00294 * available if they have been added by calling addCustomType(). 00295 * 00296 * @warning To maintain compatibility with earlier versions, the following 00297 * strings are special types that perform special behavior. 00298 * Support for these strings may be removed in a future release, so 00299 * they should not be used in any new code. 00300 * - "Metadata..." - Invokes a dialog to create a new filter. This 00301 * is identical to clicking on the Create Filter button. 00302 * - "-----------------------" - Sets the current display type to 00303 * the top-level "Signatures" item. This is identical to 00304 * selecting the "Signatures" item directly. 00305 * 00306 * @param strFormat 00307 * The display format type for the signature list. 00308 */ 00309 void setDisplayType(const QString& strFormat); 00310 00311 /** 00312 * Enables or disables the %Properties, Export, and Delete buttons. 00313 * 00314 * This method enables or disables the %Properties, Export, and Delete 00315 * buttons based on the number of selected signature items in the list. 00316 */ 00317 void enableButtons(); 00318 00319 /** 00320 * Invokes a properties dialog for the currently selected signature. 00321 * 00322 * This method invokes an instance of a SignaturePropertiesDlg for the first selected 00323 * signature item in the list view. This method is called automatically when the user 00324 * clicks the %Properties button. 00325 */ 00326 void displaySignatureProperties(); 00327 00328 /** 00329 * Export currently selected signatures as a signature set. 00330 */ 00331 void exportSignatures(); 00332 00333 /** 00334 * Destroys currently selected signatures. 00335 * 00336 * This method destroys Signature objects in the data model from all 00337 * currently selected signature items in the list view. This method is 00338 * called automatically when the user clicks the Delete button. 00339 */ 00340 void unloadSignatures(); 00341 00342 /** 00343 * Toggles the display of the import extension widget. 00344 * 00345 * This method toggles the import extension widget, which changes the overall size of 00346 * the dialog. This method is called automatically when the user clicks the Import 00347 * button. 00348 */ 00349 void importSignatures(); 00350 00351 /** 00352 * Allows the user to browse for one or more signature files. 00353 * 00354 * This method invokes a file selection dialog in which the user can select one or more 00355 * signature files. The files are then added to the list in the import extension widget 00356 * of the dialog. This method is called automatically when the user clicks the Browse 00357 * button on the import extension widget. 00358 */ 00359 void browseFiles(); 00360 00361 /** 00362 * Invokes the search dialog for user to search the disk for signatures. 00363 * 00364 * This method invokes a search dialog in which the user can search multiple directories 00365 * for signature files to import. If the user accepts the search, all signature files 00366 * found during the search are added to the list in the import extension widget of the 00367 * dialog. This method is called automatically when the user clicks the Search button on 00368 * the import extension widget. 00369 */ 00370 void searchDirectories(); 00371 00372 /** 00373 * Loads selected signatures in the import extension widget. 00374 * 00375 * This method loads signatures from selected signature files in the import extension 00376 * widget of the dialog. The main signature list view widget is updated if necessary. 00377 * This method is called automatically when the user clicks the Load button on the import 00378 * extension widget. 00379 */ 00380 void loadSignatures(); 00381 00382 /** 00383 * Updates the main list view with the available signatures. 00384 * 00385 * This method updates the signature items in the list view based on the selected display 00386 * filter type. 00387 */ 00388 virtual void updateSignatureList(); 00389 00390 /** 00391 * Performs tasks associated with the custom button. 00392 * 00393 * This slot method displays a QMessageBox stating that the actions for the custom 00394 * button have not been set up. Classes derived from SignatureSelector need to override 00395 * this method with the actions for their custom button. 00396 */ 00397 virtual void customButtonClicked(); 00398 00399 private: 00400 SignatureSelector(const SignatureSelector& rhs); 00401 SignatureSelector& operator=(const SignatureSelector& rhs); 00402 00403 Progress* mpProgress; 00404 Service<PlugInManagerServices> mpManager; 00405 Service<ModelServices> mpModel; 00406 00407 static const QString sMetadataType; 00408 static const QString sDashType; 00409 00410 QTreeWidget* mpFormatTree; 00411 QTreeWidgetItem* mpSignaturesItem; 00412 QTreeWidget* mpSignatureList; 00413 QAction* mpCreateFilterAction; 00414 QAction* mpEditFilterAction; 00415 QAction* mpDeleteFilterAction; 00416 QAction* mpPropertiesAction; 00417 QAction* mpExportAction; 00418 QAction* mpDeleteAction; 00419 QGridLayout* mpEmptyLayout; 00420 QPushButton* mpImportButton; 00421 QPushButton* mpApplyButton; 00422 QPushButton* mpCustomButton; 00423 QWidget* mpImportWidget; 00424 QListWidget* mpFilesList; 00425 00426 QStringList mImporterFilters; 00427 SearchDlg* mpSearchDlg; 00428 00429 void addSignature(Signature* pSignature); 00430 QTreeWidgetItem* createSignatureItem(Signature* pSignature, QTreeWidgetItem* pParentItem = NULL, 00431 bool createLibraryItems = false); 00432 void createLibraryItems(SignatureSet* pSignatureSet, QTreeWidgetItem* pParentItem, 00433 const QRegExp& signatureNameFilter, const QRegExp& metadataNameFilter, const QRegExp& metadataValueFilter); 00434 bool matchLibrarySignatures(const SignatureSet* pSignatureSet, const QRegExp& signatureNameFilter, 00435 const QRegExp& metadataNameFilter, const QRegExp& metadataValueFilter); 00436 bool matchSignature(const Signature* pSignature, const QRegExp& signatureNameFilter, 00437 const QRegExp& metadataNameFilter, const QRegExp& metadataValueFilter); 00438 bool matchMetadata(const DynamicObject* pMetadata, const QRegExp& nameFilter, const QRegExp& valueFilter); 00439 void extractFromSigSets(const std::vector<Signature*>& sourceSigs, std::vector<Signature*>& destSigs) const; 00440 bool isFilterNameUnique(const QString& filterName, QTreeWidgetItem* pIgnoreItem = NULL) const; 00441 00442 private slots: 00443 void createFilter(); 00444 void editFilter(); 00445 void checkFilterName(QTreeWidgetItem* pItem, int column); 00446 void deleteFilter(); 00447 void formatChanged(); 00448 void displayFormatContextMenu(const QPoint& menuPoint); 00449 void displaySignatureContextMenu(const QPoint& menuPoint); 00450 }; 00451 00452 #endif