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