7#include "catalogcsvimport.h"
9#include "ui_catalogcsvimport.h"
22const std::vector<std::pair<QString, std::tuple<QString, QString, bool>>> fields{
23 {
"Type", {
"",
"",
true } },
24 {
"Right Ascension", {
"",
"",
false } },
25 {
"Declination", {
"",
"",
false } },
26 {
"Magnitude", {
"",
"",
false } },
27 {
"Name", {
"",
"",
false } },
28 {
"Long Name", {
"",
"",
true } },
29 {
"Identifier", {
"",
"",
true } },
30 {
"Major Axis", {
"",
"arcmin",
true } },
31 {
"Minor Axis", {
"",
"arcmin",
true } },
32 {
"Position Angle", {
"",
"°",
true } },
33 {
"Flux", {
"",
"",
true } },
42 for (
int i = 0; i < SkyObject::TYPE::NUMBER_OF_KNOWN_TYPES; i++)
48 pLayout->addWidget(pCombo);
49 pWidget->setLayout(pLayout);
54CatalogCSVImport::CatalogCSVImport(
QWidget *parent)
55 :
QDialog(parent), ui(new Ui::CatalogCSVImport)
60 ui->separator->setText(
QString(default_separator));
61 ui->comment_prefix->setText(
QString(default_comment));
63 ui->preview->setModel(&m_preview_model);
64 ui->preview->horizontalHeader()->setSectionResizeMode(
65 QHeaderView::ResizeMode::Stretch);
68 &CatalogCSVImport::select_file);
71 &CatalogCSVImport::type_table_add_map);
74 &CatalogCSVImport::read_objects);
77 &CatalogCSVImport::type_table_remove_map);
80 read_n_objects(default_preview_size);
81 m_preview_model.setObjects(m_objects);
84 init_column_mapping();
87 for (
auto *box : { ui->ra_units, ui->dec_units })
89 box->addItem(
i18n(
"Degrees"));
90 box->addItem(
i18n(
"Hours"));
94CatalogCSVImport::~CatalogCSVImport()
99void CatalogCSVImport::select_file()
105 dialog.setDefaultSuffix(
"csv");
110 const auto &fileName = dialog.selectedUrls().value(0).toLocalFile();
116 i18n(
"Could not open the csv file.<br>It does not exist."));
121 if (ui->separator->text().length() < 1)
123 ui->separator->setText(
QString(default_separator));
126 if (ui->comment_prefix->text().length() < 1)
128 ui->separator->setText(
QString(default_separator));
131 const auto &separator = ui->separator->text();
132 const auto &comment_prefix = ui->comment_prefix->text();
134 ui->file_path_label->setText(fileName);
141 init_mapping_selectors();
144void CatalogCSVImport::reset_mapping()
146 ui->column_mapping->setEnabled(
false);
147 ui->preview_button->setEnabled(
false);
148 ui->obj_count->setEnabled(
false);
150 ui->buttonBox->buttons()[0]->setEnabled(
false);
153void CatalogCSVImport::init_mapping_selectors()
157 for (
const auto &field : fields)
159 const auto can_be_ignored = std::get<2>(field.second);
160 auto *selector = m_selectors[field.first];
164 selector->setMaxCount(columns.size() + (can_be_ignored ? 0 : 1));
167 selector->addItem(
i18n(
"Ignore"), -2);
170 for (
const auto &col : columns)
171 selector->addItem(col.c_str(), i++);
174 ui->column_mapping->setEnabled(
true);
175 ui->buttonBox->buttons()[0]->setEnabled(
true);
176 ui->obj_count->setEnabled(
true);
177 ui->preview_button->setEnabled(
true);
178 ui->obj_count->setText(
i18np(
"%1 Object",
"%1 Objects", m_doc.
GetRowCount()));
181void CatalogCSVImport::init_type_table()
183 auto *
const table = ui->type_table;
186 table->setColumnCount(2);
187 table->setRowCount(1);
190 table->setItem(0, 0, item);
192 table->setCellWidget(0, 1, type_selector_widget());
193 table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Stretch);
196void CatalogCSVImport::type_table_add_map()
198 auto *
const table = ui->type_table;
199 const auto cur_row = table->rowCount();
201 table->setRowCount(cur_row + 1);
203 table->setCellWidget(cur_row, 1, type_selector_widget());
206void CatalogCSVImport::type_table_remove_map()
208 auto *
const table = ui->type_table;
210 for (
const auto *item : table->selectedItems())
212 const auto row = item->row();
214 table->removeRow(row);
218CatalogCSVImport::type_map CatalogCSVImport::get_type_mapping()
220 auto *
const table = ui->type_table;
223 for (
int i = 0; i <= table->rowCount(); i++)
225 const auto *key = table->item(i, 0);
226 const auto *
type = table->cellWidget(i, 1);
228 if (key ==
nullptr || type ==
nullptr)
232 dynamic_cast<QComboBox *
>(
type->layout()->itemAt(0)->widget())
240void CatalogCSVImport::init_column_mapping()
243 for (
const auto &field : fields)
246 const auto &tooltip = std::get<0>(field.second);
247 const auto &unit = std::get<1>(field.second);
249 if (unit.length() > 0)
253 label->setToolTip(tooltip);
256 selector->setEditable(
true);
257 m_selectors[field.first] = selector;
259 cmapping->addRow(label, selector);
262 ui->column_mapping->setLayout(cmapping);
265CatalogCSVImport::column_map CatalogCSVImport::get_column_mapping()
267 CatalogCSVImport::column_map
map{};
270 for (
const auto &item : m_selectors)
273 const auto *selector = item.second;
274 auto selected_value = selector->currentData().
toInt();
277 if (selected_value >= 0 &&
278 (selector->currentText() != names[selected_value].c_str()))
281 val_string = selector->currentText();
288 map[
name] = { selected_value, val_string };
294void CatalogCSVImport::read_n_objects(
size_t n)
296 const auto &type_map = get_type_mapping();
297 const auto &column_map = get_column_mapping();
301 m_objects.reserve(std::min(m_doc.
GetRowCount(), n));
304 const auto make_getter = [
this, &column_map](
const QString &field,
auto def) {
305 const auto &conf = column_map.at(field);
306 const auto &default_val = get_default(conf, def);
307 const auto index = conf.first;
309 std::function<
decltype(def)(
const size_t)> getter;
311 getter = [=](
const size_t row) {
314 return m_doc.
GetCell<
decltype(def)>(index, row);
322 getter = [=](
const size_t) {
return default_val; };
327 const auto make_coord_getter = [
this, &column_map](
const QString &field,
auto def,
329 const auto &conf = column_map.at(field);
330 const auto default_val =
331 (unit == coord_unit::deg) ?
332 get_default<typed_dms<coord_unit::deg>>(column_map.at(field), { def })
334 get_default<typed_dms<coord_unit::hours>>(column_map.at(field), { def })
336 const auto index = conf.first;
338 std::function<
decltype(def)(
const size_t)> getter;
341 if (unit == coord_unit::deg)
342 getter = [=](
const size_t row) {
345 return m_doc.
GetCell<typed_dms<coord_unit::deg>>(index, row).data;
353 getter = [=](
const size_t row) {
356 return m_doc.
GetCell<typed_dms<coord_unit::hours>>(index, row)
366 getter = [=](
const size_t) {
return default_val; };
371 const auto ra_type =
static_cast<coord_unit
>(ui->ra_units->currentIndex());
372 const auto dec_type =
static_cast<coord_unit
>(ui->dec_units->currentIndex());
374 const auto get_ra = make_coord_getter(
"Right Ascension",
defaults.ra(), ra_type);
375 const auto get_dec = make_coord_getter(
"Declination",
defaults.dec(), dec_type);
376 const auto get_mag = make_getter(
"Magnitude",
defaults.mag());
377 const auto get_name = make_getter(
"Name",
defaults.name());
378 const auto get_type = make_getter(
"Type", std::string{
"default" });
379 const auto get_long_name = make_getter(
"Long Name",
defaults.name());
380 const auto get_identifier = make_getter(
"Identifier",
defaults.catalogIdentifier());
381 const auto get_a = make_getter(
"Major Axis",
defaults.a());
382 const auto get_b = make_getter(
"Minor Axis",
defaults.b());
383 const auto get_pa = make_getter(
"Position Angle",
defaults.pa());
384 const auto get_flux = make_getter(
"Flux",
defaults.flux());
386 for (
size_t i = 0; i < std::min(m_doc.
GetRowCount(), n); i++)
388 const auto &raw_type = get_type(i);
390 const auto type = parse_type(raw_type, type_map);
392 const auto ra = get_ra(i);
393 const auto dec = get_dec(i);
394 const auto mag = get_mag(i);
395 const auto name = get_name(i);
396 const auto long_name = get_long_name(i);
397 const auto identifier = get_identifier(i);
398 const auto a = get_a(i);
399 const auto b = get_b(i);
400 const auto pa = get_pa(i);
401 const auto flux = get_flux(i);
404 identifier, -1, a, b, pa, flux);
409 const type_map &type_map)
411 if (type_map.count(type) == 0)
412 return type_map.at(
"default");
414 return type_map.at(type);
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
TYPE
The type classification of the SkyObject.
void Clear()
Clears loaded Document data.
std::vector< std::string > GetColumnNames()
Get column names.
T GetCell(const size_t pColumnIdx, const size_t pRowIdx) const
Get cell by index.
void Load(const std::string &pPath, const LabelParams &pLabelParams=LabelParams(), const SeparatorParams &pSeparatorParams=SeparatorParams(), const ConverterParams &pConverterParams=ConverterParams(), const LineReaderParams &pLineReaderParams=LineReaderParams())
Read Document data from file.
size_t GetRowCount() const
Get number of data rows (excluding label rows).
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
QString name(StandardAction id)
QString label(StandardShortcut id)
bool exists() const const
StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons, StandardButton defaultButton)
QString arg(Args &&... args) const const
QString first(qsizetype n) const const
int toInt(bool *ok, int base) const const
QTextStream & dec(QTextStream &stream)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setContentsMargins(const QMargins &margins)
Datastructure holding parameters controlling how invalid numbers (including empty strings) should be ...
Datastructure holding parameters controlling which row and column should be treated as labels.
Datastructure holding parameters controlling how special line formats should be treated.
Datastructure holding parameters controlling how the CSV data fields are separated.