Tulip  4.9.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
CSVImportConfigurationWidget.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef CSVIMPORTCONFIGURATIONWIDGET_H
22 #define CSVIMPORTCONFIGURATIONWIDGET_H
23 
24 #include <QWidget>
25 #include <QValidator>
26 #include <QTableWidget>
27 
28 #include <tulip/CSVContentHandler.h>
29 #include <tulip/tulipconf.h>
30 
31 class QComboBox;
32 class QCheckBox;
33 class QValidator;
34 class QLineEdit;
35 
36 namespace Ui {
37 class CSVImportConfigurationWidget;
38 }
39 
40 namespace tlp {
41 class CSVParser;
42 class CSVImportParameters;
43 class CSVColumn;
44 
45 /**
46  * @brief Configuration widget for a property.
47  */
48 class TLP_QT_SCOPE PropertyConfigurationWidget: public QWidget {
49  Q_OBJECT
50 public:
51  PropertyConfigurationWidget(unsigned int propertyNumber, const QString& propertyName, bool propertyNameIsEditable,
52  const std::string& PropertyType, QWidget* parent = NULL);
53  /**
54  * Return the selected property type. The property type is not the label displayed in the combobox but correspond to the Property::propertyTypename static string variable of the property class.
55  */
56  std::string getPropertyType() const;
57  /**
58  * @brief Change the type of the property. Use the PropertyClass::propertyTypename static var.
59  **/
60  void setPropertyType(const std::string& propertyType);
61 
62  QString getPropertyName() const;
63  bool getPropertyUsed() const;
64  /**
65  * @brief Set the property name validator. Use to chek if entered graph name is valid.
66  */
67  void setPropertyNameValidator(QValidator* validator);
68  unsigned int getPropertyNumber() const;
69 
70  QLineEdit *getNameLineEdit() {
71  return propertyNameLineEdit;
72  }
73  QComboBox *getTypeComboBox() {
74  return propertyTypeComboBox;
75  }
76 
77  QCheckBox *getCheckBox() {
78  return usedCheckBox;
79  }
80 
81 private:
82  void fillPropertyTypeComboBox();
83  QLineEdit *propertyNameLineEdit;
84  QComboBox *propertyTypeComboBox;
85  QCheckBox *usedCheckBox;
86  bool nameEditable;
87  unsigned int propertyNumber;
88 
89 private slots:
90  void nameEditFinished();
91  void useStateChanged(int state);
92 
93 signals:
94  void propertyNameChange(QString newName);
95  void stateChange(bool state);
96 };
97 
98 /**
99  * @brief Check if the property name already exist in the property list.
100  **/
101 class TLP_QT_SCOPE PropertyNameValidator: public QValidator {
102 public:
103  PropertyNameValidator(const std::vector<PropertyConfigurationWidget*>& widgets,QObject*parent=NULL) :
104  QValidator(parent), widgets(widgets) {
105  }
106  virtual ~PropertyNameValidator() {
107 
108  }
109 
110  /**
111  * Validate the new property name. Check if any property does not have the same name
112  */
113  QValidator::State validate(QString & input, int & pos) const;
114 
115 private:
116  const std::vector<PropertyConfigurationWidget*>& widgets;
117 };
118 
119 /**
120 * @brief Simple table preview of CSV file. Load in a QTableWidget the data send by a CSVContentHandler.
121 **/
122 class TLP_QT_SCOPE CSVTableWidget : public QTableWidget, public CSVContentHandler {
123 public:
124  CSVTableWidget(QWidget* parent=NULL);
125  bool begin();
126  bool line(unsigned int row,const std::vector<std::string>& lineTokens);
127  bool end(unsigned int rowNumber, unsigned int columnNumber);
128  /**
129  * @brief Limit the line number of the preview. Need to parse the file again to take this limit in account.
130  **/
131  void setMaxPreviewLineNumber(unsigned int lineNumber) {
132  maxLineNumber = lineNumber;
133  }
134 
135  /**
136  * @brief Get the preview line number.
137  **/
138  unsigned int getMaxPreviewLineNumber()const {
139  return maxLineNumber;
140  }
141 
142  unsigned int getFirstLineIndex() {
143  return firstLineIndex;
144  }
145 
146  void setFirstLineIndex(unsigned int index) {
147  firstLineIndex = index;
148  }
149 
150  int getNbCommentsLines() {
151  return nbCommentsLines;
152  }
153 
154 private:
155  unsigned int maxLineNumber;
156  unsigned int firstLineIndex;
157  bool checkCommentsLines;
158  int nbCommentsLines;
159 };
160 
161 
162 /**
163  * @brief Widget generating a CSVImportParameters object configuring the CSV import process.
164  *
165  * Use a CSV parser to fill this widget with previews and CSV file statistics like number of rows and columns.
166  **/
167 class TLP_QT_SCOPE CSVImportConfigurationWidget : public QWidget, public CSVContentHandler {
168  Q_OBJECT
169 public:
170  CSVImportConfigurationWidget(QWidget *parent = NULL);
171  ~CSVImportConfigurationWidget();
172  bool begin();
173  bool line(unsigned int row,const std::vector<std::string>& lineTokens);
174  bool end(unsigned int rowNumber, unsigned int columnNumber);
175  void setFirstLineIndex(int firstLine);
176 
177  /**
178  * @brief Update the widget contents with the new file parser.
179  **/
180  void setNewParser(tlp::CSVParser *parser);
181 
182  /**
183  * @brief Get the import parameters.
184  *
185  * Use this object to configure import process of the CSVImportGraph object.
186  **/
187  CSVImportParameters getImportParameters()const;
188 
189  bool eventFilter(QObject *, QEvent *);
190 
191 
192 protected:
193 
194  void updateWidget(const std::string& title = "Generating preview");
195 
196  std::vector<CSVColumn> getPropertiesToImport()const;
197 
198  void updateLineNumbers(bool resetValues);
199 
200  bool useFirstLineAsPropertyName()const;
201  void setUseFirstLineAsPropertyName(bool useFirstLineAsHeader)const;
202  unsigned int rowCount()const;
203  unsigned int columnCount()const;
204 
205 
206  /**
207  *@brief The index of the first line to get in the file.
208  *@brief A line number from 0 to LastLineIndex.
209  **/
210  unsigned int getFirstLineIndex()const;
211 
212  /**
213  * @brief The index of the last line to take in the file.
214  **/
215  unsigned int getLastLineIndex()const;
216  /**
217  * @brief The index of the first imported line. This index change if user use the first line as column names.
218  * For example if the user wants to import all lines but uses the first line as column names this function will return 1 not 0.
219  **/
220  unsigned int getFirstImportedLineIndex()const;
221 
222  /**
223  * Empty the properties list.
224  */
225  void clearPropertiesTypeList();
226  /**
227  * Add a property to the current property list.
228  */
229  void addPropertyToPropertyList(const std::string& propertyName, bool isEditable, const std::string& propertyType=std::string(""));
230 
231  /**
232  * @brief Creates a property configuration widget.
233  *
234  * @param propertyNumber The property number.
235  * @param propertyName The name of the property.
236  * @param propertyNameIsEditable Whether the property's name is editable.
237  * @param propertyType The type of the property.
238  * @param parent This widget's parent.
239  * @return :PropertyConfigurationWidget*
240  **/
241  virtual PropertyConfigurationWidget *createPropertyConfigurationWidget(unsigned int propertyNumber,
242  const QString& propertyName, bool propertyNameIsEditable, const std::string& propertyType, QWidget* parent);
243 
244  /**
245  * @brief Compute the name of the column. Return the first token fo the column if the first lline is used as header r Column_x xhere x is the column index.
246  **/
247  QString generateColumnName(unsigned int col)const;
248  /**
249  * @brief Compute the column data type. Take in account the first row only if it is not used as column label
250  **/
251  std::string getColumnType(unsigned int col)const;
252 
253  std::vector<PropertyConfigurationWidget*> propertyWidgets;
254 
255 protected slots:
256 
257  void filterPreviewLineNumber(bool filter);
258  void previewLineNumberChanged(int value);
259 
260  void toLineValueChanged(int value);
261 
262  void updateTableHeaders();
263 
264  void useFirstLineAsHeaderUpdated();
265  void propertyNameChanged(QString propertyName);
266  void propertyStateChanged(bool activated);
267 
268 signals:
269  void fileInfoChanged();
270 
271 private:
272 
273  /**
274  * @brief Try to guess the property datatype in function of the type of the previous tokens and the type of the current token.
275  **/
276  std::string guessPropertyDataType(const std::string& data,const std::string& previousType)const;
277 
278  /**
279  * @brief Return the type of the column in function of the old and new type.
280  **/
281  std::string combinePropertyDataType(const std::string& previousType,const std::string& newType)const;
282  /**
283  * @brief Try to guess the type of the data. Can recognize int, double, boolean or string. If the type is other return string.
284  * @return The property typename of the type
285  **/
286  std::string guessDataType(const std::string& data)const;
287 
288  void columnSizeChanged(unsigned int i);
289 
290  //The data type of the header
291  std::vector<std::string> columnHeaderType;
292  //The data type of the rest of the column;
293  std::vector<std::string> columnType;
294 
295  Ui::CSVImportConfigurationWidget *ui;
296  PropertyNameValidator* validator;
297  unsigned int maxLineNumber;
298  unsigned int headerColumnCount;
299  tlp::CSVParser* parser;
300  unsigned int firstLine;
301 };
302 
303 }
304 #endif // CSVIMPORTCONFIGURATIONWIDGET_H
305 ///@endcond