File indexing completed on 2025-02-16 09:47:18
0001 /* 0002 SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QCheckBox> 0008 #include <QMessageBox> 0009 #include <QFileDialog> 0010 #include "catalogsdbui.h" 0011 #include "ui_catalogsdbui.h" 0012 #include "catalogeditform.h" 0013 #include "catalogdetails.h" 0014 #include "catalogcoloreditor.h" 0015 0016 CatalogsDBUI::CatalogsDBUI(QWidget *parent, const QString &db_path) 0017 : QDialog(parent), ui{ new Ui::CatalogsDBUI }, m_manager{ db_path }, m_last_dir{ 0018 QDir::homePath() 0019 } 0020 { 0021 ui->setupUi(this); 0022 ui->objectsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); 0023 0024 const QStringList labels = { 0025 i18n("Enabled"), i18n("ID"), i18n("Name"), 0026 i18n("Precedence"), i18n("Author"), i18n("Mutable"), 0027 i18n("Version"), i18n("License"), i18n("Maintainer") 0028 }; 0029 0030 ui->objectsTable->setColumnCount(labels.size()); 0031 ui->objectsTable->setHorizontalHeaderLabels(labels); 0032 0033 refresh_db_table(); 0034 0035 connect(ui->objectsTable, &QTableWidget::cellClicked, this, 0036 &CatalogsDBUI::row_selected); 0037 0038 connect(ui->objectsTable, &QTableWidget::itemSelectionChanged, this, 0039 &CatalogsDBUI::disable_buttons); 0040 0041 connect(ui->activateButton, &QPushButton::clicked, this, 0042 &CatalogsDBUI::enable_disable_catalog); 0043 0044 connect(ui->importButton, &QPushButton::clicked, this, &CatalogsDBUI::import_catalog); 0045 0046 connect(ui->exportButton, &QPushButton::clicked, this, &CatalogsDBUI::export_catalog); 0047 0048 connect(ui->removeButton, &QPushButton::clicked, this, &CatalogsDBUI::remove_catalog); 0049 0050 connect(ui->createButton, &QPushButton::clicked, this, 0051 qOverload<>(&CatalogsDBUI::create_new_catalog)); 0052 0053 connect(ui->moreButton, &QPushButton::clicked, this, &CatalogsDBUI::show_more_dialog); 0054 0055 connect(ui->dublicateButton, &QPushButton::clicked, this, 0056 &CatalogsDBUI::dublicate_catalog); 0057 0058 connect(ui->colorButton, &QPushButton::clicked, this, 0059 &CatalogsDBUI::show_color_editor); 0060 } 0061 0062 CatalogsDBUI::~CatalogsDBUI() 0063 { 0064 delete ui; 0065 } 0066 0067 QWidget *centered_check_box_widget(bool checked) 0068 { 0069 auto *pWidget = new QWidget{}; // no parent as receiver takes posession 0070 auto *pLayout = new QHBoxLayout(pWidget); 0071 auto *pCheckBox = new QCheckBox(pWidget); 0072 0073 pCheckBox->setChecked(checked); 0074 pCheckBox->setEnabled(false); 0075 pLayout->addWidget(pCheckBox); 0076 pLayout->setAlignment(Qt::AlignCenter); 0077 pLayout->setContentsMargins(0, 0, 0, 0); 0078 0079 pWidget->setLayout(pLayout); 0080 0081 return pWidget; 0082 } 0083 0084 void CatalogsDBUI::refresh_db_table() 0085 { 0086 const auto catalogs = m_manager.get_catalogs(true); 0087 0088 m_catalogs.resize(catalogs.size()); 0089 0090 auto &table = *ui->objectsTable; 0091 table.setRowCount(catalogs.size()); 0092 0093 int row{ 0 }; 0094 for (const auto &catalog : catalogs) 0095 { 0096 m_catalogs[row] = catalog.id; 0097 0098 // the table takes ownership of its items 0099 table.setCellWidget(row, 0, centered_check_box_widget(catalog.enabled)); 0100 0101 table.setItem(row, 1, new QTableWidgetItem{ QString::number(catalog.id) }); 0102 table.setItem(row, 2, new QTableWidgetItem{ catalog.name }); 0103 table.setItem(row, 3, 0104 new QTableWidgetItem{ QString::number(catalog.precedence) }); 0105 table.setItem(row, 4, new QTableWidgetItem{ catalog.author }); 0106 table.setCellWidget(row, 5, centered_check_box_widget(catalog.mut)); 0107 table.setItem(row, 6, new QTableWidgetItem{ QString::number(catalog.version) }); 0108 table.setItem(row, 7, new QTableWidgetItem{ catalog.license }); 0109 table.setItem(row, 8, new QTableWidgetItem{ catalog.maintainer }); 0110 row++; 0111 } 0112 } 0113 0114 void CatalogsDBUI::row_selected(int row, int) 0115 { 0116 const auto &success = m_manager.get_catalog(m_catalogs[row]); 0117 if (!success.first) 0118 return; 0119 0120 const auto cat = success.second; 0121 ui->activateButton->setText(!cat.enabled ? i18n("Enable") : i18n("Disable")); 0122 ui->activateButton->setEnabled(true); 0123 ui->moreButton->setEnabled(true); 0124 ui->removeButton->setEnabled(true); 0125 ui->exportButton->setEnabled(true); 0126 ui->dublicateButton->setEnabled(true); 0127 ui->colorButton->setEnabled(true); 0128 } 0129 0130 void CatalogsDBUI::disable_buttons() 0131 { 0132 if (ui->objectsTable->selectedItems().length() > 0) 0133 return; 0134 0135 ui->activateButton->setText(i18n("Enable")); 0136 ui->activateButton->setEnabled(false); 0137 ui->moreButton->setEnabled(false); 0138 ui->removeButton->setEnabled(false); 0139 ui->exportButton->setEnabled(false); 0140 ui->dublicateButton->setEnabled(false); 0141 } 0142 0143 void CatalogsDBUI::enable_disable_catalog() 0144 { 0145 const auto catalog = get_selected_catalog(); 0146 if (!catalog.first) 0147 return; 0148 0149 const auto success = 0150 m_manager.set_catalog_enabled(catalog.second.id, !catalog.second.enabled); 0151 if (!success.first) 0152 QMessageBox::warning( 0153 this, i18n("Warning"), 0154 i18n("Could not enable/disable the catalog.<br>%1", success.second)); 0155 0156 refresh_db_table(); 0157 row_selected(ui->objectsTable->selectedItems().first()->row(), 0); 0158 } 0159 0160 const std::pair<bool, CatalogsDB::Catalog> CatalogsDBUI::get_selected_catalog() 0161 { 0162 const auto items = ui->objectsTable->selectedItems(); 0163 if (items.length() == 0) 0164 return { false, {} }; 0165 0166 return m_manager.get_catalog(m_catalogs[items.first()->row()]); 0167 } 0168 0169 void CatalogsDBUI::export_catalog() 0170 { 0171 const auto cat = get_selected_catalog(); 0172 if (!cat.first) 0173 return; 0174 0175 QFileDialog dialog(this, i18nc("@title:window", "Export Catalog"), m_last_dir, 0176 i18n("Catalog") + 0177 QString(" (*.%1);;").arg(CatalogsDB::db_file_extension)); 0178 dialog.setAcceptMode(QFileDialog::AcceptSave); 0179 dialog.setDefaultSuffix(CatalogsDB::db_file_extension); 0180 0181 if (dialog.exec() != QDialog::Accepted) 0182 return; 0183 0184 const auto fileName = dialog.selectedUrls().value(0).toLocalFile(); 0185 const auto success = m_manager.dump_catalog(cat.second.id, fileName); 0186 m_last_dir = QFileInfo(fileName).absolutePath(); 0187 0188 if (!success.first) 0189 QMessageBox::warning(this, i18n("Warning"), 0190 i18n("Could not export the catalog.<br>%1", success.second)); 0191 } 0192 0193 void CatalogsDBUI::import_catalog(bool force) 0194 { 0195 QFileDialog dialog(this, i18nc("@title:window", "Import Catalog"), m_last_dir, 0196 i18n("Catalog") + 0197 QString(" (*.%1);;").arg(CatalogsDB::db_file_extension)); 0198 dialog.setAcceptMode(QFileDialog::AcceptOpen); 0199 dialog.setDefaultSuffix(CatalogsDB::db_file_extension); 0200 0201 if (dialog.exec() != QDialog::Accepted) 0202 return; 0203 0204 const auto fileName = dialog.selectedUrls().value(0).toLocalFile(); 0205 const auto success = m_manager.import_catalog(fileName, force); 0206 m_last_dir = QFileInfo(fileName).absolutePath(); 0207 0208 if (!success.first && !force) 0209 { 0210 QMessageBox::warning(this, i18n("Warning"), 0211 i18n("Could not import the catalog.<br>%1", success.second)); 0212 0213 if (QMessageBox::question(this, "Retry", "Retry and overwrite?", 0214 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) 0215 import_catalog(true); 0216 } 0217 0218 refresh_db_table(); 0219 } 0220 0221 void CatalogsDBUI::remove_catalog() 0222 { 0223 const auto cat = get_selected_catalog(); 0224 if (!cat.first) 0225 return; 0226 0227 const auto success = m_manager.remove_catalog(cat.second.id); 0228 0229 if (!success.first) 0230 QMessageBox::warning(this, i18n("Warning"), 0231 i18n("Could not remove the catalog.<br>%1", success.second)); 0232 0233 refresh_db_table(); 0234 } 0235 0236 std::pair<bool, int> CatalogsDBUI::create_new_catalog(const CatalogsDB::Catalog &catalog) 0237 { 0238 auto *dialog = new CatalogEditForm(this, catalog); 0239 if (dialog->exec() != QDialog::Accepted) 0240 return { false, -1 }; 0241 0242 auto cat = dialog->getCatalog(); 0243 cat.mut = true; 0244 const auto &success = m_manager.register_catalog(cat); 0245 0246 if (!success.first) 0247 { 0248 QMessageBox::warning(this, i18n("Warning"), 0249 i18n("Could not create the catalog.<br>%1", success.second)); 0250 return create_new_catalog(cat); 0251 } 0252 0253 refresh_db_table(); 0254 return { true, cat.id }; 0255 } 0256 0257 void CatalogsDBUI::create_new_catalog() 0258 { 0259 create_new_catalog({ m_manager.find_suitable_catalog_id() }); 0260 } 0261 0262 void CatalogsDBUI::dublicate_catalog() 0263 { 0264 const auto &success = get_selected_catalog(); 0265 if (!success.first) 0266 return; 0267 0268 const auto &src = success.second; 0269 0270 auto src_new = src; 0271 src_new.id = m_manager.find_suitable_catalog_id(); 0272 src_new.enabled = false; 0273 src_new.precedence = 1; 0274 0275 const auto &create_success = create_new_catalog(src_new); 0276 0277 if (!create_success.first) 0278 return; 0279 0280 const auto copy_success = m_manager.copy_objects(src.id, create_success.second); 0281 if (!copy_success.first) 0282 { 0283 QMessageBox::warning(this, i18n("Warning"), 0284 i18n("Could not copy the objects to the new catalog.<br>%1") 0285 .arg(copy_success.second)); 0286 0287 const auto &remove_success = m_manager.remove_catalog(create_success.second); 0288 if (!remove_success.first) 0289 QMessageBox::critical( 0290 this, i18n("Critical error"), 0291 i18n("Could not clean up and remove the new catalog.<br>%1", 0292 remove_success.second)); 0293 }; 0294 } 0295 0296 void CatalogsDBUI::show_more_dialog() 0297 { 0298 const auto success = get_selected_catalog(); 0299 if (!success.first) 0300 return; 0301 0302 auto *dialog = new CatalogDetails(this, m_manager.db_file_name(), success.second.id); 0303 0304 connect(this, &QDialog::finished, dialog, &QDialog::done); 0305 connect(dialog, &QDialog::finished, this, &CatalogsDBUI::refresh_db_table); 0306 0307 dialog->show(); 0308 } 0309 0310 void CatalogsDBUI::show_color_editor() 0311 { 0312 const auto &success = get_selected_catalog(); 0313 if (!success.first) 0314 return; 0315 0316 auto *dialog = new CatalogColorEditor(success.second.id, this); 0317 0318 connect(this, &QDialog::finished, dialog, &QDialog::reject); 0319 dialog->show(); 0320 }