Kstars

catalogcsvimport.h
1 /*
2  SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #ifndef CATALOGCSVIMPORT_H
8 #define CATALOGCSVIMPORT_H
9 
10 #include <QDialog>
11 #include <QString>
12 #include <QComboBox>
13 #include <QFile>
14 #include "polyfills/qstring_hash.h"
15 #include <unordered_map>
16 #include <rapidcsv.h>
17 #include "catalogobject.h"
18 #include "skyobject.h"
19 #include "catalogobjectlistmodel.h"
20 
21 namespace Ui
22 {
23 class CatalogCSVImport;
24 }
25 
26 /**
27  * Custom Conversion Logic
28  *
29  * This requires some template magic to give the parser information
30  * wether to use degrees or hours.
31  */
32 enum coord_unit
33 {
34  deg = 0,
35  hours = 1,
36 };
37 
38 template <coord_unit unit_p>
39 struct typed_dms
40 {
41  dms data;
42 };
43 
44 namespace rapidcsv
45 {
46 template <>
47 inline void
48 Converter<typed_dms<coord_unit::deg>>::ToVal(const std::string &pStr,
49  typed_dms<coord_unit::deg> &pVal) const
50 {
51  if (!pVal.data.setFromString(pStr.c_str(), true))
52  throw std::exception();
53 }
54 
55 template <>
56 inline void
57 Converter<typed_dms<coord_unit::hours>>::ToVal(const std::string &pStr,
58  typed_dms<coord_unit::hours> &pVal) const
59 {
60  if (!pVal.data.setFromString(pStr.c_str(), false))
61  throw std::exception();
62 }
63 
64 template <>
65 inline void Converter<QString>::ToVal(const std::string &pStr, QString &pVal) const
66 {
67  pVal = QString(pStr.c_str());
68 }
69 } // namespace rapidcsv
70 
71 class CatalogCSVImport : public QDialog
72 {
73  Q_OBJECT
74 
75  public:
76  explicit CatalogCSVImport(QWidget *parent = nullptr);
77  ~CatalogCSVImport();
78 
79  /**
80  * Maps a string to a `SkyObject::TYPE`.
81  */
82  using type_map = std::unordered_map<std::string, SkyObject::TYPE>;
83 
84  /**
85  * Maps a field in the Catalog object to a column in the CSV.
86  *
87  * The first element of the tuple can take on the following values:
88  * - -2 :: Default initialize this value.
89  * - -1 :: Take the value in the second part of the string for every row.
90  * - everything else :: Read from the column indicated by the integer value.
91  */
92  using column_pair = std::pair<int, QString>;
93  using column_map = std::unordered_map<QString, column_pair>;
94 
95  inline const std::vector<CatalogObject> &get_objects() const { return m_objects; };
96  private slots:
97  /** Selects a CSV file and opens it. Calls `init_mapping_selectors`. */
98  void select_file();
99 
100  /** Reads the header of the CSV and initializes the mapping selectors. */
101  void init_mapping_selectors();
102 
103  /** Add a row to the type table. */
104  void type_table_add_map();
105 
106  /** Remove the selected row from the type table. */
107  void type_table_remove_map();
108 
109  /** Read all the objects from the csv */
110  inline void read_objects() { read_n_objects(); };
111 
112  private:
113  void init_column_mapping();
114  void init_type_table();
115  type_map get_type_mapping();
116  column_map get_column_mapping();
117  void read_n_objects(size_t n = std::numeric_limits<int>::max());
118 
119  // Parsing
120  SkyObject::TYPE parse_type(const std::string &type, const type_map &type_map);
121 
122  template <typename T>
123  T cell_or_default(const column_pair &config, const size_t row, const T &default_val)
124  {
125  if (config.first < 0)
126  return default_val;
127 
128  return m_doc.GetCell<T>(config.first, row);
129  };
130 
131  template <typename T>
132  T get_default(const column_pair &config, const T &default_val)
133  {
134  if (config.first != -1)
135  return default_val;
136 
138 
139  T res{};
140  converter.ToVal(config.second.toStdString(), res);
141 
142  return res;
143  }
144 
145  Ui::CatalogCSVImport *ui;
146 
147  /** Disables the mapping selection and resets everything. */
148  void reset_mapping();
149 
150  /** Maps the fields to a selector widget. */
151  std::map<QString, QComboBox *> m_selectors{};
152 
153  /** Rapidcsv Document */
154  rapidcsv::Document m_doc{};
155 
156  /** The Parsed Objects */
157  std::vector<CatalogObject> m_objects;
158 
159  /** The model to preview the import */
160  CatalogObjectListModel m_preview_model;
161 
162  static const char default_separator = ',';
163  static const char default_comment = '#';
164  static const int default_preview_size = 10;
165 };
166 
167 #endif // CATALOGCSVIMPORT_H
Q_OBJECTQ_OBJECT
void ToVal(const std::string &pStr, T &pVal) const
Converts string holding a numerical value to numerical datatype representation.
Definition: rapidcsv.h:137
std::tuple< bool, QString, CatalogsDB::CatalogObjectVector > get_objects(QSqlDatabase db, const std::list< int > &ids={ 1, 2 })
Class representing a CSV document.
Definition: rapidcsv.h:382
KSharedConfigPtr config()
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
Datastructure holding parameters controlling how invalid numbers (including empty strings) should be ...
Definition: rapidcsv.h:40
Class providing conversion to/from numerical datatypes and strings.
Definition: rapidcsv.h:95
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:49 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.