Tulip  6.0.0
Large graphs analysis and drawing
CSVImportConfigurationWidget.h
1 /*
2  *
3  * This file is part of Tulip (https://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 #include <QHeaderView>
28 
29 #include <tulip/CSVContentHandler.h>
30 #include <tulip/CSVGraphImport.h>
31 #include <tulip/tulipconf.h>
32 
33 class QPushButton;
34 class Ui_CSVPropertyDialog;
35 
36 namespace Ui {
37 class CSVImportConfigurationWidget;
38 }
39 namespace tlp {
40 class CSVParser;
41 class PropertyNameValidator;
42 
43 /**
44  * @brief Configuration widget for a property.
45  */
46 class TLP_QT_SCOPE PropertyConfigurationWidget : public QWidget, public CSVColumn {
47  Q_OBJECT
48 public:
49  PropertyConfigurationWidget(unsigned int propertyNumber, const QString &propertyName,
50  bool propertyNameIsEditable, const std::string &PropertyType,
51  PropertyNameValidator *validator, QWidget *parent = nullptr);
52  /**
53  * Return the selected property type.
54  * The property type is not the label displayed in the
55  * combobox but correspond to the Property::propertyTypename
56  * static string variable of the property class.
57  */
58  const std::string &getPropertyType() const;
59  /**
60  * @brief Change the type of the property. Use the PropertyClass::propertyTypename static var.
61  **/
62  void setPropertyType(const std::string &propertyType, bool defValue = false);
63 
64  QString getPropertyName() const;
65 
66  void setPropertyName(const QString &name, bool defValue = false);
67 
68  void toggleUsed();
69 
70  unsigned int getPropertyNumber() const;
71 
72 private:
73  PropertyNameValidator *propertyNameValidator;
74  QPushButton *propertyEditButton;
75  Ui_CSVPropertyDialog *ui;
76  bool nameEditable;
77  unsigned int propertyNumber;
78  void addException(const std::string &value, CSVColumn::Action action);
79 
80 private slots:
81  void showPropertyCreationDialog();
82  void typeCBChanged(const QString &index);
83  void addException();
84 
85  void delCurrentException();
86 
87 signals:
88  void stateChange(bool state);
89 };
90 
91 /**
92  * @brief Check if the property name already exist in the property list.
93  **/
94 class TLP_QT_SCOPE PropertyNameValidator : public QValidator {
95 public:
96  PropertyNameValidator(const std::vector<PropertyConfigurationWidget *> &widgets,
97  QObject *parent = nullptr)
98  : QValidator(parent), widgets(widgets) {}
99  ~PropertyNameValidator() override {}
100 
101  /**
102  * Validate the new property name. Check if any property does not have the same name
103  */
104  QValidator::State validate(QString &input, int &pos) const override;
105 
106  // set the index of the column/property currently edited
107  void setCurrentIndex(unsigned int index) {
108  currentIndex = index;
109  }
110 
111 private:
112  unsigned int currentIndex;
113  const std::vector<PropertyConfigurationWidget *> &widgets;
114 };
115 
116 class CSVTableHeader : public QHeaderView {
117  Q_OBJECT
118 
119  const std::vector<PropertyConfigurationWidget *> &widgets;
120 
121 public:
122  CSVTableHeader(QWidget *parent, std::vector<PropertyConfigurationWidget *> &propertyWidgets);
123 
124 protected:
125  void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override;
126 
127 protected slots:
128  void checkBoxPressed(int logicalIndex);
129 };
130 
131 /**
132  * @brief Simple table preview of CSV file. Load in a QTableWidget the data send by a
133  *CSVContentHandler.
134  **/
135 class TLP_QT_SCOPE CSVTableWidget : public QTableWidget, public CSVContentHandler {
136 public:
137  CSVTableWidget(QWidget *parent = nullptr);
138  bool begin() override;
139  bool line(unsigned int row, const std::vector<CSVToken> &lineTokens) override;
140  bool end(unsigned int rowNumber, unsigned int columnNumber) override;
141  /**
142  * @brief Limit the line number of the preview. Need to parse the file again to take this limit
143  *into account.
144  **/
145  void setMaxPreviewLineNumber(unsigned int lineNumber) {
146  // first row is used to display configuration widgets
147  maxLineNumber = lineNumber + 1;
148  }
149 
150  unsigned int getFirstLineIndex() {
151  return firstLineIndex;
152  }
153 
154  void setFirstLineIndex(unsigned int index) {
155  firstLineIndex = index;
156  }
157 
158  int getNbCommentsLines() {
159  return nbCommentsLines;
160  }
161 
162 private:
163  unsigned int maxLineNumber;
164  unsigned int firstLineIndex;
165  bool checkCommentsLines;
166  int nbCommentsLines;
167 };
168 
169 /**
170  * @brief Widget generating a CSVImportParameters object configuring the CSV import process.
171  *
172  * Use a CSV parser to fill this widget with previews and CSV file statistics like number of rows
173  *and columns.
174  **/
175 class TLP_QT_SCOPE CSVImportConfigurationWidget : public QWidget, public CSVContentHandler {
176  Q_OBJECT
177 public:
178  CSVImportConfigurationWidget(QWidget *parent = nullptr);
179  ~CSVImportConfigurationWidget() override;
180  bool begin() override;
181  bool line(unsigned int row, const std::vector<CSVToken> &lineTokens) override;
182  bool end(unsigned int rowNumber, unsigned int columnNumber) override;
183  void setFirstLineIndex(int firstLine);
184 
185  /**
186  * @brief Update the widget contents with the new file parser.
187  **/
188  void setNewParser(tlp::CSVParser *parser);
189 
190  /**
191  * @brief Get the import parameters.
192  *
193  * Use this object to configure import process of the CSVImportGraph object.
194  **/
195  CSVImportParameters getImportParameters() const;
196 
197  // return the sorted names of the existing properties of a known typename
198  // see PropertyInterface::getTypename()
199  static const std::set<std::string> &getPropsForTypename(const std::string &type);
200 
201 protected:
202  void updateWidget(const std::string &title = "Generating preview");
203 
204  const std::vector<CSVColumn *> getPropertiesToImport() const;
205 
206  void updateLineNumbers(bool resetValues);
207 
208  bool useFirstLineAsPropertyName() const;
209  void setUseFirstLineAsPropertyName(bool useFirstLineAsHeader) const;
210  unsigned int rowCount() const;
211  unsigned int columnCount() const;
212 
213  /**
214  *@brief The index of the first line to get in the file.
215  *@brief A line number from 0 to LastLineIndex.
216  **/
217  unsigned int getFirstLineIndex() const;
218 
219  /**
220  * @brief The index of the last line to take in the file.
221  **/
222  unsigned int getLastLineIndex() const;
223  /**
224  * @brief The index of the first imported line. This index change if user use the first line as
225  *column names.
226  * For example if the user wants to import all lines but uses the first line as column names this
227  *function will return 1 not 0.
228  **/
229  unsigned int getFirstImportedLineIndex() const;
230 
231  /**
232  * Empty the properties list.
233  */
234  void clearPropertiesTypeList();
235  /**
236  * Add a property to the current property list.
237  */
238  void addPropertyToPropertyList(const std::string &propertyName, bool isEditable,
239  const std::string &propertyType = std::string(""));
240 
241  /**
242  * @brief Creates a property configuration widget.
243  *
244  * @param propertyNumber The property number.
245  * @param propertyName The name of the property.
246  * @param propertyNameIsEditable Whether the property's name is editable.
247  * @param propertyType The type of the property.
248  * @param parent This widget's parent.
249  * @return :PropertyConfigurationWidget*
250  **/
251  virtual PropertyConfigurationWidget *
252  createPropertyConfigurationWidget(unsigned int propertyNumber, const QString &propertyName,
253  bool propertyNameIsEditable, const std::string &propertyType,
254  QWidget *parent);
255 
256  /**
257  * @brief Compute the name of the column. Return the first token for the column if the first line
258  *is used as header r Column_x xhere x is the column index.
259  **/
260  QString generateColumnName(unsigned int col) const;
261  /**
262  * @brief Compute the column data type. Take in account the first row only if it is not used as
263  *column label
264  **/
265  std::string getColumnType(unsigned int col) const;
266 
267  std::vector<PropertyConfigurationWidget *> propertyWidgets;
268 
269 protected slots:
270 
271  void filterPreviewLineNumber(bool filter);
272  void previewLineNumberChanged(int value);
273 
274  void toLineValueChanged(int value);
275 
276  void updateTableHeaders();
277 
278  void useFirstLineAsHeaderUpdated();
279  void propertyStateChanged(bool activated);
280 
281 private:
282  /**
283  * @brief Try to guess the property datatype in function of the type of the previous tokens and
284  *the type of the current token.
285  **/
286  const std::string &guessPropertyDataType(const std::string &data,
287  const std::string &previousType) const;
288 
289  /**
290  * @brief Return the type of the column in function of the old and new type.
291  **/
292  const std::string &combinePropertyDataType(const std::string &previousType,
293  const std::string &newType) const;
294  /**
295  * @brief Try to guess the type of the data. Can recognize int, double, Boolean or string. If the
296  *type is other return string.
297  * @return The property typename of the type
298  **/
299  const std::string &guessDataType(const std::string &data) const;
300 
301  // update the max line number of the preview table
302  void setMaxPreviewLineNumber(unsigned int lineNumber);
303 
304  // The data type of the header
305  std::vector<std::string> columnHeaderType;
306  // The data type of the rest of the column;
307  std::vector<std::string> columnType;
308 
309  Ui::CSVImportConfigurationWidget *ui;
310  PropertyNameValidator *validator;
311  unsigned int maxLineNumber;
312  unsigned int headerColumnCount;
313  tlp::CSVParser *parser;
314  unsigned int firstLine;
315  bool guessFirstLineIsHeader;
316  bool keepPropertyWidgets;
317 };
318 } // namespace tlp
319 #endif // CSVIMPORTCONFIGURATIONWIDGET_H
320 ///@endcond