Tulip  5.1.0
Large graphs analysis and drawing
CSVImportConfigurationWidget.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
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 useStateChanged(int state);
91 
92 signals:
93  void stateChange(bool state);
94 };
95 
96 /**
97  * @brief Check if the property name already exist in the property list.
98  **/
99 class TLP_QT_SCOPE PropertyNameValidator: public QValidator {
100 public:
101  PropertyNameValidator(const std::vector<PropertyConfigurationWidget*>& widgets,QObject*parent=NULL) :
102  QValidator(parent), widgets(widgets) {
103  }
104  virtual ~PropertyNameValidator() {
105 
106  }
107 
108  /**
109  * Validate the new property name. Check if any property does not have the same name
110  */
111  QValidator::State validate(QString & input, int & pos) const;
112 
113 private:
114  const std::vector<PropertyConfigurationWidget*>& widgets;
115 };
116 
117 /**
118 * @brief Simple table preview of CSV file. Load in a QTableWidget the data send by a CSVContentHandler.
119 **/
120 class TLP_QT_SCOPE CSVTableWidget : public QTableWidget, public CSVContentHandler {
121 public:
122  CSVTableWidget(QWidget* parent=NULL);
123  bool begin();
124  bool line(unsigned int row,const std::vector<std::string>& lineTokens);
125  bool end(unsigned int rowNumber, unsigned int columnNumber);
126  /**
127  * @brief Limit the line number of the preview. Need to parse the file again to take this limit in account.
128  **/
129  void setMaxPreviewLineNumber(unsigned int lineNumber) {
130  maxLineNumber = lineNumber;
131  }
132 
133  /**
134  * @brief Get the preview line number.
135  **/
136  unsigned int getMaxPreviewLineNumber()const {
137  return maxLineNumber;
138  }
139 
140  unsigned int getFirstLineIndex() {
141  return firstLineIndex;
142  }
143 
144  void setFirstLineIndex(unsigned int index) {
145  firstLineIndex = index;
146  }
147 
148  int getNbCommentsLines() {
149  return nbCommentsLines;
150  }
151 
152 private:
153  unsigned int maxLineNumber;
154  unsigned int firstLineIndex;
155  bool checkCommentsLines;
156  int nbCommentsLines;
157 };
158 
159 
160 /**
161  * @brief Widget generating a CSVImportParameters object configuring the CSV import process.
162  *
163  * Use a CSV parser to fill this widget with previews and CSV file statistics like number of rows and columns.
164  **/
165 class TLP_QT_SCOPE CSVImportConfigurationWidget : public QWidget, public CSVContentHandler {
166  Q_OBJECT
167 public:
168  CSVImportConfigurationWidget(QWidget *parent = NULL);
169  ~CSVImportConfigurationWidget();
170  bool begin();
171  bool line(unsigned int row,const std::vector<std::string>& lineTokens);
172  bool end(unsigned int rowNumber, unsigned int columnNumber);
173  void setFirstLineIndex(int firstLine);
174 
175  /**
176  * @brief Update the widget contents with the new file parser.
177  **/
178  void setNewParser(tlp::CSVParser *parser);
179 
180  /**
181  * @brief Get the import parameters.
182  *
183  * Use this object to configure import process of the CSVImportGraph object.
184  **/
185  CSVImportParameters getImportParameters()const;
186 
187  bool eventFilter(QObject *, QEvent *);
188 
189 
190 protected:
191 
192  void updateWidget(const std::string& title = "Generating preview");
193 
194  std::vector<CSVColumn> getPropertiesToImport()const;
195 
196  void updateLineNumbers(bool resetValues);
197 
198  bool useFirstLineAsPropertyName()const;
199  void setUseFirstLineAsPropertyName(bool useFirstLineAsHeader)const;
200  unsigned int rowCount()const;
201  unsigned int columnCount()const;
202 
203 
204  /**
205  *@brief The index of the first line to get in the file.
206  *@brief A line number from 0 to LastLineIndex.
207  **/
208  unsigned int getFirstLineIndex()const;
209 
210  /**
211  * @brief The index of the last line to take in the file.
212  **/
213  unsigned int getLastLineIndex()const;
214  /**
215  * @brief The index of the first imported line. This index change if user use the first line as column names.
216  * 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.
217  **/
218  unsigned int getFirstImportedLineIndex()const;
219 
220  /**
221  * Empty the properties list.
222  */
223  void clearPropertiesTypeList();
224  /**
225  * Add a property to the current property list.
226  */
227  void addPropertyToPropertyList(const std::string& propertyName, bool isEditable, const std::string& propertyType=std::string(""));
228 
229  /**
230  * @brief Creates a property configuration widget.
231  *
232  * @param propertyNumber The property number.
233  * @param propertyName The name of the property.
234  * @param propertyNameIsEditable Whether the property's name is editable.
235  * @param propertyType The type of the property.
236  * @param parent This widget's parent.
237  * @return :PropertyConfigurationWidget*
238  **/
239  virtual PropertyConfigurationWidget *createPropertyConfigurationWidget(unsigned int propertyNumber,
240  const QString& propertyName, bool propertyNameIsEditable, const std::string& propertyType, QWidget* parent);
241 
242  /**
243  * @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.
244  **/
245  QString generateColumnName(unsigned int col)const;
246  /**
247  * @brief Compute the column data type. Take in account the first row only if it is not used as column label
248  **/
249  std::string getColumnType(unsigned int col)const;
250 
251  std::vector<PropertyConfigurationWidget*> propertyWidgets;
252 
253 protected slots:
254 
255  void filterPreviewLineNumber(bool filter);
256  void previewLineNumberChanged(int value);
257 
258  void toLineValueChanged(int value);
259 
260  void updateTableHeaders();
261 
262  void useFirstLineAsHeaderUpdated();
263  void propertyStateChanged(bool activated);
264 
265 private:
266 
267  /**
268  * @brief Try to guess the property datatype in function of the type of the previous tokens and the type of the current token.
269  **/
270  const std::string& guessPropertyDataType(const std::string& data,const std::string& previousType)const;
271 
272  /**
273  * @brief Return the type of the column in function of the old and new type.
274  **/
275  const std::string& combinePropertyDataType(const std::string& previousType,const std::string& newType)const;
276  /**
277  * @brief Try to guess the type of the data. Can recognize int, double, boolean or string. If the type is other return string.
278  * @return The property typename of the type
279  **/
280  const std::string& guessDataType(const std::string& data)const;
281 
282  void columnSizeChanged(unsigned int i);
283 
284  //The data type of the header
285  std::vector<std::string> columnHeaderType;
286  //The data type of the rest of the column;
287  std::vector<std::string> columnType;
288 
289  Ui::CSVImportConfigurationWidget *ui;
290  PropertyNameValidator* validator;
291  unsigned int maxLineNumber;
292  unsigned int headerColumnCount;
293  tlp::CSVParser* parser;
294  unsigned int firstLine;
295  bool guessFirstLineIsHeader;
296 };
297 
298 }
299 #endif // CSVIMPORTCONFIGURATIONWIDGET_H
300 ///@endcond