diff --git a/libqf/libqfgui/src/dialogs/dialog.cpp b/libqf/libqfgui/src/dialogs/dialog.cpp index 6857ece3d..7deef3a88 100644 --- a/libqf/libqfgui/src/dialogs/dialog.cpp +++ b/libqf/libqfgui/src/dialogs/dialog.cpp @@ -113,8 +113,9 @@ void Dialog::done(int result) if(dw) { ok = dw->acceptDialogDone(result); } - if(ok) + if(ok) { Super::done(result); + } /* QVariant ok = true; QMetaObject::invokeMethod(this, "doneRequest_qml", diff --git a/libqf/libqfgui/src/model/sqltablemodel.cpp b/libqf/libqfgui/src/model/sqltablemodel.cpp index 88f78c403..276caf493 100644 --- a/libqf/libqfgui/src/model/sqltablemodel.cpp +++ b/libqf/libqfgui/src/model/sqltablemodel.cpp @@ -451,9 +451,26 @@ void SqlTableModel::revertRow(int row_no) Super::revertRow(row_no); } +QString SqlTableModel::reloadRowQuery(const QVariant &record_id) +{ + qf::core::sql::QueryBuilder qb = m_queryBuilder; + if(qb.isEmpty()) { + qfWarning() << "Empty queryBuilder"; + return {}; + } + auto sql_id_str = qMetaTypeId() == record_id.userType()? '\'' + record_id.toString() + '\'': QString::number(record_id.toInt()); + qb.where(idColumnName() + "=" + sql_id_str); + qfs::QueryBuilder::BuildOptions opts; + opts.setConnectionName(connectionName()); + QString query_str = qb.toString(opts); + query_str = replaceQueryParameters(query_str); + return query_str; +} + int SqlTableModel::reloadRow(int row_no) { qfLogFuncFrame() << "row:" << row_no << "row count:" << rowCount(); +#ifdef NO_RELOAD_ROW_QUERY qf::core::sql::QueryBuilder qb = m_queryBuilder; if(qb.isEmpty()) { qfWarning() << "Empty queryBuilder"; @@ -462,9 +479,9 @@ int SqlTableModel::reloadRow(int row_no) qfu::TableRow &row_ref = m_table.rowRef(row_no); qf::core::sql::Connection sql_conn = sqlConnection(); QSqlDriver *sqldrv = sql_conn.driver(); - Q_FOREACH(QString table_id, tableIds(m_table.fields())) { + for (const auto &table_id : tableIds(m_table.fields())) { qfDebug() << "\ttableid:" << table_id; - Q_FOREACH(QString fld_name, sql_conn.primaryIndexFieldNames(table_id)) { + for (const auto &fld_name : sql_conn.primaryIndexFieldNames(table_id)) { QString full_fld_name = table_id + '.' + fld_name; int fld_ix = m_table.fields().fieldIndex(full_fld_name); if(fld_ix < 0) { @@ -492,12 +509,18 @@ int SqlTableModel::reloadRow(int row_no) if(!isIncludeJoinedTablesIdsToReloadRowQuery()) break; } - qfs::Query q = qfs::Query(sql_conn); qfs::QueryBuilder::BuildOptions opts; opts.setConnectionName(connectionName()); QString query_str = qb.toString(opts); query_str = replaceQueryParameters(query_str); +#else + qfu::TableRow &row_ref = m_table.rowRef(row_no); + auto id = row_ref.value(idColumnName()); + auto query_str = reloadRowQuery(id); + qf::core::sql::Connection sql_conn = sqlConnection(); +#endif qfDebug() << "\t reload row query:" << query_str; + qfs::Query q = qfs::Query(sql_conn); bool ok = q.exec(query_str); QF_ASSERT(ok == true, QString("SQL Error: %1\n%2").arg(q.lastError().text()).arg(query_str), diff --git a/libqf/libqfgui/src/model/sqltablemodel.h b/libqf/libqfgui/src/model/sqltablemodel.h index 7c741dde8..95a2cbebd 100644 --- a/libqf/libqfgui/src/model/sqltablemodel.h +++ b/libqf/libqfgui/src/model/sqltablemodel.h @@ -50,6 +50,7 @@ class QFGUI_DECL_EXPORT SqlTableModel : public TableModel void revertRow(int row_no) Q_DECL_OVERRIDE; int reloadRow(int row_no) Q_DECL_OVERRIDE; int reloadInserts(const QString &id_column_name) Q_DECL_OVERRIDE; + QString reloadRowQuery(const QVariant &record_id); public: void setQueryBuilder(const qf::core::sql::QueryBuilder &qb, bool clear_columns = false); const qf::core::sql::QueryBuilder& queryBuilder() const; diff --git a/libqf/libqfgui/src/model/tablemodel.h b/libqf/libqfgui/src/model/tablemodel.h index 59d98e320..fe0c78809 100644 --- a/libqf/libqfgui/src/model/tablemodel.h +++ b/libqf/libqfgui/src/model/tablemodel.h @@ -20,6 +20,8 @@ class QFGUI_DECL_EXPORT TableModel : public QAbstractTableModel { Q_OBJECT Q_PROPERTY(bool nullReportedAsString READ isNullReportedAsString WRITE setNullReportedAsString NOTIFY nullReportedAsStringChanged) + + QF_PROPERTY_IMPL2(QString, i, I, dColumnName, QStringLiteral("id")) public: explicit TableModel(QObject *parent = nullptr); private: diff --git a/libqf/libqfgui/src/tableview.cpp b/libqf/libqfgui/src/tableview.cpp index b0583ff06..58cdc57de 100644 --- a/libqf/libqfgui/src/tableview.cpp +++ b/libqf/libqfgui/src/tableview.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -413,7 +414,7 @@ void TableView::cloneRow() cloneRowInline(); } else { - QVariant id = selectedRow().value(idColumnName()); + QVariant id = selectedRow().value(tableModel()->idColumnName()); qfDebug() << "\t emit editRowInExternalEditor(ModeCopy)"; emit editRowInExternalEditor(id, ModeCopy); emit editSelectedRowsInExternalEditor(ModeCopy); @@ -431,7 +432,7 @@ void TableView::removeSelectedRows() else { QList sel_rows = selectedRowsIndexes(); if(sel_rows.count() == 1) { - QVariant id = tableRow(sel_rows.value(0)).value(idColumnName()); + QVariant id = tableRow(sel_rows.value(0)).value(tableModel()->idColumnName()); if(id.isValid()) emit editRowInExternalEditor(id, ModeDelete); } @@ -584,14 +585,15 @@ void TableView::paste() int origin_view_row = origin_ix.row(); bool insert_rows = w->isInsert(); int dest_row = toTableModelRowNo(origin_view_row); - for(int src_row=0; src_rowrowCount(); src_row++) { + for(int src_row = 0; src_row < src_tm->rowCount(); src_row++) { if(insert_rows) { qfDebug() << "insert row:" << dest_row << "model row count:" << dest_tm->rowCount(); dest_tm->insertRow(++dest_row); } else { - if((origin_view_row + src_row) >= dest_tm->rowCount()) + if((origin_view_row + src_row) >= dest_tm->rowCount()) { break; + } dest_row = toTableModelRowNo(origin_view_row + src_row); } int dest_col = origin_ix.column(); @@ -1118,122 +1120,78 @@ QList TableView::selectedColumnsIndexes() const return ret; } -void TableView::rowExternallySaved(const QVariant &id, int mode) -{ - qfLogFuncFrame() << "id:" << id.toString() << "mode:" << mode; - qfm::TableModel *tmd = tableModel(); - if(tmd) { - if(mode == ModeInsert || mode == ModeCopy) { - /// ModeInsert or ModeCopy - qfDebug() << "\t ModeInsert or ModeCopy"; - //qfDebug() << "\tri:" << ri; - //qfDebug() << "\tmodel->rowCount():" << ri; - QModelIndex curr_ix = currentIndex(); - int ri = curr_ix.row() + 1; - if(ri >= 0 && ri < model()->rowCount()) - ri = toTableModelRowNo(ri); - else - ri = tmd->rowCount(); - ri = std::min(ri, tmd->rowCount()); - qfDebug() << "\tri:" << ri; - if(ri < 0) { - qfWarning() << "Invalid row number:" << ri; - ri = 0; - } - tmd->insertRow(ri); - tmd->setValue(ri, idColumnName(), id); - //qfu::TableRow &row_ref = tmd->table().rowRef(ri); - //row_ref.setValue(idColumnName(), id); - //row_ref.setInsert(false); - int reloaded_row_cnt = tmd->reloadRow(ri); - if(reloaded_row_cnt == 0) { - //inserted row cannot be reloaded, it can happen if it doesn't meet WHERE contition of query - // remove just inserted row from table - qfWarning() << "Inserted/Copied row id:" << id.toString() << "cannot be reloaded, it will be deleted in table."; - tmd->qfm::TableModel::removeRowNoOverload(ri, !qf::core::Exception::Throw); - return; - } - if(reloaded_row_cnt != 1) { - qfWarning() << "Inserted/Copied row id:" << id.toString() << "reloaded in" << reloaded_row_cnt << "instances."; - return; - } - if(curr_ix.isValid()) { - updateRow(curr_ix.row()); - setCurrentIndex(curr_ix.sibling(ri, curr_ix.column())); +void TableView::rowExternallySaved(const QVariant &id) +{ + qfLogFuncFrame() << "id:" << id.toString(); + auto table_model = qobject_cast(tableModel()); + if (!table_model) { + qfWarning() << "Not SqlTableModel."; + return; + } + if(table_model) { + std::optional row_with_id_index; + for(int ri = 0; ri < table_model->rowCount(); ri++) { + auto v = table_model->value(ri, tableModel()->idColumnName()); + //qfDebug() << "\t row" << ri << "id:" << v.toString(); + if(v == id) { + row_with_id_index = ri; + break; } - else { - setCurrentIndex(model()->index(ri, 0, QModelIndex())); + } + auto query_str = table_model->reloadRowQuery(id); + if (query_str.isEmpty()) { + return; + } + qf::core::sql::Query q; + bool ok = q.exec(query_str); + if (!ok) { + qfInfo() << "Query:" << query_str; + qfWarning() << "SQL error:" << q.lastErrorText(); + return; + } + int row_cnt = 0; + while (q.next()) { + row_cnt++; + } + if (row_cnt > 1) { + qfWarning() << "More rows returned for id:" << id; + return; + } + auto row_exists_in_db = row_cnt == 1; + + auto curr_col = currentIndex().column(); + auto curr_row = std::max(0, toTableModelRowNo(currentIndex().row())); + QModelIndex new_ix; + if (row_with_id_index && row_exists_in_db) { + // edit + table_model->reloadRow(row_with_id_index.value()); + } + else if (!row_with_id_index && row_exists_in_db) { + // insert + table_model->insertRow(curr_row); + table_model->setValue(curr_row, tableModel()->idColumnName(), id); + table_model->reloadRow(curr_row); + new_ix = table_model->index(curr_row, curr_col >= 0? curr_col: 0); + setCurrentIndex(m_proxyModel->mapFromSource(new_ix)); + } + else if (row_with_id_index && !row_exists_in_db) { + // delete + table_model->qfm::TableModel::removeRowNoOverload(row_with_id_index.value(), !qf::core::Exception::Throw); + auto row = currentIndex().row(); + if (row >= model()->rowCount()) { + row = model()->rowCount() - 1; } - updateRow(currentIndex().row()); + setCurrentIndex(model()->index(row, curr_col)); } else { - /// find row with id - /// start with currentRow, because id value is most probabbly here - int ri = currentIndex().row(); - if(ri >= 0) { - QVariant v = tmd->value(ri, idColumnName()); - //qfDebug() << "\t found id:" << v.toString(); - if(v != id) - ri = -1; - } - if(ri < 0) for(ri=0; rirowCount(); ri++) { - QVariant v = tmd->value(ri, idColumnName()); - //qfDebug() << "\t row" << ri << "id:" << v.toString(); - if(v == id) { - break; - } - } - if((ri < 0 || ri >= tmd->rowCount()) && currentIndex().row() >= 0) { - // this can happen if ID column value is changed - // reload current row to do the best - ri = currentIndex().row(); - // set ID value to the new one - tmd->setValue(ri, idColumnName(), id); - tmd->setDirty(ri, idColumnName(), false); - } - if(ri >= 0 && ri < tmd->rowCount()) { - if(mode == ModeEdit || mode == ModeView) { - int reloaded_row_cnt = tmd->reloadRow(ri); - if(reloaded_row_cnt != 1) { - qfWarning() << "Edited row index:" << ri << "id:" << id.toString() << "reloaded in" << reloaded_row_cnt << "instances."; - } - updateRow(currentIndex().row()); - } - else if(mode == ModeDelete) { - int reloaded_row_cnt = tmd->reloadRow(ri); - if(reloaded_row_cnt > 0) { - qfWarning() << "Deleted row id:" << id.toString() << "still exists."; - } - else { - tmd->qfm::TableModel::removeRowNoOverload(ri, !qf::core::Exception::Throw); - if(ri >= tmd->rowCount()) - ri = tmd->rowCount() - 1; - QModelIndex ix = currentIndex(); - if(ri >= 0) { - ix = tmd->index(ri, (ix.column() >= 0)? ix.column(): 0); - //qfInfo() << "ix row:" << ix.row() << "col:" << ix.column(); - setCurrentIndex(ix); - } - } - } - } + // nor in table neither in database } } else { qfError() << "Feature not defined for this model type:" << model(); } } -/* -qf::core::utils::Table::SortDef TableView::seekSortDefinition() const -{ - qfLogFuncFrame(); - qf::core::utils::Table::SortDef ret; - if(tableModel()) { - ret = tableModel()->table().tableProperties().sortDefinition().value(0); - } - return ret; -} -*/ + int TableView::seekColumn() const { int ret = -1; @@ -2249,7 +2207,7 @@ bool TableView::edit(const QModelIndex& index, EditTrigger trigger, QEvent* even if(trigger == QTableView::DoubleClicked || trigger == QTableView::EditKeyPressed) { if(!read_only) { emit editCellRequest(index); - QVariant id = selectedRow().value(idColumnName()); + QVariant id = selectedRow().value(tableModel()->idColumnName()); if(id.isValid()) { emit editRowInExternalEditor(id, ModeEdit); } diff --git a/libqf/libqfgui/src/tableview.h b/libqf/libqfgui/src/tableview.h index 56b8f81ca..c10279b79 100644 --- a/libqf/libqfgui/src/tableview.h +++ b/libqf/libqfgui/src/tableview.h @@ -28,7 +28,6 @@ class QFGUI_DECL_EXPORT TableView : public QTableView, public framework::IPersis Q_PROPERTY(qf::gui::model::TableModel* model READ tableModel WRITE setTableModel) Q_PROPERTY(RowEditorMode rowEditorMode READ rowEditorMode WRITE setRowEditorMode NOTIFY rowEditorModeChanged) Q_PROPERTY(InlineEditSaveStrategy inlineEditSaveStrategy READ inlineEditSaveStrategy WRITE setInlineEditSaveStrategy NOTIFY inlineEditSaveStrategyChanged) - Q_PROPERTY(QString idColumnName READ idColumnName WRITE setIdColumnName) Q_PROPERTY(bool showExceptionDialog READ isShowExceptionDialog WRITE setShowExceptionDialog NOTIFY showExceptionDialogChanged) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) private: @@ -61,7 +60,6 @@ class QFGUI_DECL_EXPORT TableView : public QTableView, public framework::IPersis QF_PROPERTY_IMPL2(InlineEditSaveStrategy, i, I, nlineEditSaveStrategy, OnEditedValueCommit) QF_PROPERTY_IMPL2(RowEditorMode, r, R, owEditorMode, EditRowsInline) - QF_PROPERTY_IMPL2(QString, i, I, dColumnName, QStringLiteral("id")) QF_PROPERTY_BOOL_IMPL2(s, S, howExceptionDialog, true) //QF_PROPERTY_BOOL_IMPL(r, R, eadOnly) @@ -141,7 +139,7 @@ class QFGUI_DECL_EXPORT TableView : public QTableView, public framework::IPersis Q_SIGNAL void editCellRequest(const QModelIndex &table_view_index); Q_SIGNAL void editRowInExternalEditor(const QVariant &id, int mode); Q_SIGNAL void editSelectedRowsInExternalEditor(int mode); - Q_SLOT virtual void rowExternallySaved(const QVariant &id, int mode); + Q_SLOT virtual void rowExternallySaved(const QVariant &id); Q_SIGNAL void filterDialogRequest(); Q_SLOT void filterByString(const QString &s); diff --git a/libquickevent/libquickeventgui/src/og/sqltablemodel.cpp b/libquickevent/libquickeventgui/src/og/sqltablemodel.cpp index 371dac3a5..c3daf2ed6 100644 --- a/libquickevent/libquickeventgui/src/og/sqltablemodel.cpp +++ b/libquickevent/libquickeventgui/src/og/sqltablemodel.cpp @@ -84,15 +84,24 @@ QVariant SqlTableModel::editValueToRaw(int column_index, const QVariant &val) co #endif } else if(type == qMetaTypeId()) { - auto id = (int)val.value(); - if(id == 0) + int siid = 0; + if (val.userType() == qMetaTypeId()) { + siid = val.toString().toInt(); + } + else if (val.userType() == qMetaTypeId()) { + siid = (int)val.value(); + } + else { + siid = val.toInt(); + } + if(siid == 0) #if QT_VERSION_MAJOR >= 6 ret = QVariant(QMetaType(QMetaType::Int)); #else ret = QVariant(QVariant::Int); #endif else - ret = id; + ret = siid; } //qfInfo() << val << ret; return ret; diff --git a/quickevent/app/quickevent/plugins/Classes/src/classestableview.cpp b/quickevent/app/quickevent/plugins/Classes/src/classestableview.cpp index 17498b6cd..af750fb1a 100644 --- a/quickevent/app/quickevent/plugins/Classes/src/classestableview.cpp +++ b/quickevent/app/quickevent/plugins/Classes/src/classestableview.cpp @@ -40,7 +40,7 @@ void ClassesTableView::removeSelectedRows() try { qf::core::sql::Transaction transaction; for(int i : selectedRowsIndexes()) { - int class_id = tableRow(i).value(idColumnName()).toInt(); + int class_id = tableRow(i).value(tableModel()->idColumnName()).toInt(); getPlugin()->dropClass(class_id); } transaction.commit(); diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp index 27fd738da..04d8b00a3 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.cpp @@ -29,6 +29,23 @@ CompetitorDocument::CompetitorDocument(QObject *parent) setQueryBuilder(qb); } +bool CompetitorDocument::loadData() +{ + m_runsIds.clear(); + if (Super::loadData()) { + if (auto competitor_id = dataId().toInt(); competitor_id > 0) { + qf::core::sql::Query q(sqlModel()->connectionName()); + q.exec(QStringLiteral("SELECT id FROM runs WHERE competitorId = %1 ORDER BY stageId").arg(competitor_id)); + while(q.next()) { + int run_id = q.value(0).toInt(); + m_runsIds << run_id; + } + } + return true; + } + return false; +} + bool CompetitorDocument::saveData() { qfLogFuncFrame(); @@ -57,18 +74,18 @@ bool CompetitorDocument::saveData() int stage_count = getPlugin()->stageCount(); qf::core::sql::Query q(sqlModel()->connectionName()); q.prepare("INSERT INTO runs (competitorId, stageId, siId) VALUES (:competitorId, :stageId, :siId)"); - m_lastInsertedRunsIds.clear(); - for(int i=0; i()->emitDbEvent(Event::EventPlugin::DBEVENT_COMPETITOR_COUNTS_CHANGED); - for (auto run_id : m_lastInsertedRunsIds) { + for (auto run_id : m_runsIds) { auto rec = runs_plugin->runsRecord(run_id); getPlugin()->emitDbEvent(Event::EventPlugin::DBEVENT_RUN_CHANGED, QVariantList {run_id, rec}); } @@ -168,3 +185,4 @@ QVariant CompetitorDocument::siid() const return value(SIID); } + diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.h b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.h index 997868fd8..a394edbe4 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.h +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitordocument.h @@ -21,13 +21,14 @@ class CompetitorDocument : public qf::gui::model::SqlDataDocument //void setSiid(const QVariant &siid, bool save_siid_to_runs); void setSiid(const QVariant &siid); QVariant siid() const; - const QVector& lastInsertedRunsIds() const {return m_lastInsertedRunsIds;} + const QVector& runsIds() const {return m_runsIds;} protected: - bool saveData() Q_DECL_OVERRIDE; - bool dropData() Q_DECL_OVERRIDE; + bool loadData() override; + bool saveData() override; + bool dropData() override; private: bool m_isEmitDbEventsOnSave = true; - QVector m_lastInsertedRunsIds; + QVector m_runsIds; }; } diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.cpp b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.cpp index 99ab498ff..62894230b 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.cpp +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.cpp @@ -49,7 +49,8 @@ class CompetitorRunsModel : public quickevent::gui::og::SqlTableModel CompetitorRunsModel(QObject *parent = nullptr); enum Columns { - col_runs_isRunning = 0, + col_runs_id = 0, + col_runs_isRunning, col_runs_stageId, col_classes_name, col_relays_name, @@ -134,6 +135,7 @@ CompetitorRunsModel::CompetitorRunsModel(QObject *parent) : Super(parent) { clearColumns(col_COUNT); + setColumn(col_runs_id, ColumnDefinition("runs.id", tr("Id", "runs.id")).setToolTip(tr("Run Id")).setReadOnly(true)); setColumn(col_runs_isRunning, ColumnDefinition("runs.isRunning", tr("Running", "runs.isRunning")).setToolTip(tr("Is running"))); setColumn(col_runs_stageId, ColumnDefinition("runs.stageId", tr("Stage")).setReadOnly(true)); setColumn(col_relays_name, ColumnDefinition("relayName", tr("Relay")).setReadOnly(true)); @@ -176,6 +178,7 @@ CompetitorWidget::CompetitorWidget(QWidget *parent) : connect(ui->edFind, &FindRegistrationEdit::registrationSelected, this, &CompetitorWidget::onRegistrationSelected); connect(ui->btnSwitchNames, &QPushButton::clicked, this, &CompetitorWidget::onSwitchNames); + connect(ui->btCreateRuns, &QPushButton::clicked, this, &CompetitorWidget::save); dataController()->setDocument(new Competitors::CompetitorDocument(this)); m_runsModel = new CompetitorRunsModel(this); @@ -220,7 +223,7 @@ CompetitorWidget::CompetitorWidget(QWidget *parent) : items << quickevent::core::og::TimeMs(t).toString(); } bool ok; - auto item = QInputDialog::getItem(this, tr("Quick Event get start time"), + auto item = QInputDialog::getItem(this, tr("Select competitor's start time"), tr("New start time:"), items, 0, false, &ok); if (ok && !item.isEmpty()) { auto ix = items.indexOf(item); @@ -312,14 +315,16 @@ void CompetitorWidget::onRunsTableCustomContextMenuRequest(const QPoint &pos) bool CompetitorWidget::load(const QVariant &id, int mode) { ui->chkFind->setChecked(mode == qf::gui::model::DataDocument::ModeInsert); + ui->btCreateRuns->setVisible(mode == qf::gui::model::DataDocument::ModeInsert); if(mode == qf::gui::model::DataDocument::ModeInsert) { ui->edFind->setFocus(); } else if(mode == qf::gui::model::DataDocument::ModeView || mode == qf::gui::model::DataDocument::ModeDelete) { ui->frmFind->hide(); } - if(Super::load(id, mode)) + if(Super::load(id, mode)) { return loadRunsTable(); + } return false; } @@ -531,8 +536,9 @@ bool CompetitorWidget::saveData() qf::gui::dialogs::MessageBox::showWarning(this, tr("Class should be entered.")); return false; } - if(Super::saveData()) + if(Super::saveData()) { return saveRunsTable(); + } } catch (const qf::core::Exception &e) { QMessageBox::warning(this, tr("SQL error"), e.message()); @@ -540,6 +546,20 @@ bool CompetitorWidget::saveData() return false; } +bool CompetitorWidget::acceptDialogDone(int result) +{ + if (result == QDialog::Accepted) { + auto *doc = qobject_cast(dataController()->document()); + if (doc->mode() != Competitors::CompetitorDocument::ModeDelete) { + if (doc->value("classId").toInt() == 0) { + QMessageBox::information(this, tr("Competitor form check"), tr("Class must be set.")); + return false; + } + } + } + return Super::acceptDialogDone(result); +} + void CompetitorWidget::onSwitchNames() { auto *doc = dataController()->document(); diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.h b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.h index df0ab370e..3970e254d 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.h +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.h @@ -22,15 +22,16 @@ class CompetitorWidget : public qf::gui::framework::DataDialogWidget bool load(const QVariant &id = QVariant(), int mode = qf::gui::model::DataDocument::ModeEdit) override; void loadFromRegistrations(int siid); void save(); -private slots: +private: void onRegistrationSelected(const QVariantMap &values); void onSwitchNames(); -private: bool loadRunsTable(); bool saveRunsTable(); // void onRunsTableCustomContextMenuRequest(const QPoint &pos); bool saveData() override; + bool acceptDialogDone(int result) override; + QString guessClassFromRegistration(const QString ®istration); static QList possibleStartTimesMs(int run_id); diff --git a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.ui b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.ui index c4dd46852..147f730cc 100644 --- a/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.ui +++ b/quickevent/app/quickevent/plugins/Competitors/src/competitorwidget.ui @@ -287,6 +287,30 @@ + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Create runs + + + + + diff --git a/quickevent/app/quickevent/plugins/Oris/src/xmlimporter.cpp b/quickevent/app/quickevent/plugins/Oris/src/xmlimporter.cpp index f2088f7d0..4df5252c9 100644 --- a/quickevent/app/quickevent/plugins/Oris/src/xmlimporter.cpp +++ b/quickevent/app/quickevent/plugins/Oris/src/xmlimporter.cpp @@ -370,7 +370,7 @@ bool XmlImporter::importEntries(QXmlStreamReader &reader, const XmlCreators crea if (!doc.save()) continue; items_processed++; - int run_id = doc.lastInsertedRunsIds().first(); + int run_id = doc.runsIds().first(); q.execThrow("UPDATE runs SET" " relayId=" + QString::number(relay_id) + "," " leg=" + QString::number(leg.first) + "," diff --git a/quickevent/app/quickevent/plugins/Relays/src/addlegdialogwidget.cpp b/quickevent/app/quickevent/plugins/Relays/src/addlegdialogwidget.cpp index f6cefa1de..3039218d8 100644 --- a/quickevent/app/quickevent/plugins/Relays/src/addlegdialogwidget.cpp +++ b/quickevent/app/quickevent/plugins/Relays/src/addlegdialogwidget.cpp @@ -138,7 +138,7 @@ void AddLegDialogWidget::onRegistrationSelected() doc.setValue("siid", row.value("siid")); doc.setValue("classId", classId()); doc.save(); - int run_id = doc.lastInsertedRunsIds().value(0); + int run_id = doc.runsIds().value(0); QF_ASSERT(run_id > 0, "Bad insert", return); int free_leg = findFreeLeg(); qf::core::sql::Query q; @@ -197,7 +197,7 @@ void AddLegDialogWidget::onUnregistredRunnerAdded() doc.setValue("classId", classId()); doc.save(); QString name = lastName + " " + firstName; - int run_id = doc.lastInsertedRunsIds().value(0); + int run_id = doc.runsIds().value(0); QF_ASSERT(run_id > 0, "Bad insert", return); int free_leg = findFreeLeg(); qf::core::sql::Query q; diff --git a/quickevent/app/quickevent/plugins/Relays/src/relayswidget.cpp b/quickevent/app/quickevent/plugins/Relays/src/relayswidget.cpp index 5fc8829e8..e4aa04b6d 100644 --- a/quickevent/app/quickevent/plugins/Relays/src/relayswidget.cpp +++ b/quickevent/app/quickevent/plugins/Relays/src/relayswidget.cpp @@ -285,7 +285,7 @@ void RelaysWidget::editRelays(int mode) qfs::Transaction transaction; int n = 0; for(int ix : sel_rows) { - int id = ui->tblRelays->tableRow(ix).value(ui->tblRelays->idColumnName()).toInt(); + int id = ui->tblRelays->tableRow(ix).value(ui->tblRelays->tableModel()->idColumnName()).toInt(); if(id > 0) { Relays:: RelayDocument doc; doc.load(id, qfm::DataDocument::ModeDelete); diff --git a/quickevent/app/quickevent/plugins/Runs/src/runstablemodel.cpp b/quickevent/app/quickevent/plugins/Runs/src/runstablemodel.cpp index c91d6fe4d..45775f89f 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runstablemodel.cpp +++ b/quickevent/app/quickevent/plugins/Runs/src/runstablemodel.cpp @@ -20,6 +20,8 @@ using Event::EventPlugin; RunsTableModel::RunsTableModel(QObject *parent) : Super(parent) { + setIdColumnName("runs.id"); + clearColumns(col_COUNT); setColumn(col_runs_isRunning, ColumnDefinition("runs.isRunning", tr("Running"))); setColumn(col_runs_id, ColumnDefinition("runs.id", tr("id")).setReadOnly(true)); diff --git a/quickevent/app/quickevent/plugins/Runs/src/runstablewidget.cpp b/quickevent/app/quickevent/plugins/Runs/src/runstablewidget.cpp index db1b4b8ed..302c8a7b5 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runstablewidget.cpp +++ b/quickevent/app/quickevent/plugins/Runs/src/runstablewidget.cpp @@ -290,7 +290,7 @@ void RunsTableWidget::onCustomContextMenuRequest(const QPoint &pos) QList rows = ui->tblRuns->selectedRowsIndexes(); for(int ix : rows) { qf::core::utils::TableRow row = ui->tblRuns->tableRow(ix); - int id = row.value(ui->tblRuns->idColumnName()).toInt(); + int id = row.value(ui->tblRuns->tableModel()->idColumnName()).toInt(); q.bindValue(QStringLiteral(":offset"), offset_msec); q.bindValue(QStringLiteral(":id"), id); //qfInfo() << id << "->" << offset_msec; @@ -312,7 +312,7 @@ void RunsTableWidget::onCustomContextMenuRequest(const QPoint &pos) QList rows = ui->tblRuns->selectedRowsIndexes(); for(int ix : rows) { qf::core::utils::TableRow row = ui->tblRuns->tableRow(ix); - int id = row.value(ui->tblRuns->idColumnName()).toInt(); + int id = row.value(ui->tblRuns->tableModel()->idColumnName()).toInt(); q.bindValue(QStringLiteral(":id"), id); //qfInfo() << id << "->" << offset_msec; q.exec(qf::core::Exception::Throw); diff --git a/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp b/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp index d1f87253b..7b19effd1 100644 --- a/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp +++ b/quickevent/app/quickevent/plugins/Runs/src/runswidget.cpp @@ -1050,7 +1050,7 @@ void RunsWidget::editCompetitors(int mode) qfs::Transaction transaction; int n = 0; for(int ix : sel_rows) { - int id = tv->tableRow(ix).value(tv->idColumnName()).toInt(); + int id = tv->tableRow(ix).value("competitors.id").toInt(); if(id > 0) { Competitors::CompetitorDocument doc; doc.load(id, qfm::DataDocument::ModeDelete); @@ -1156,13 +1156,7 @@ void RunsWidget::editCompetitor_helper(const QVariant &id, int mode, int siid) qfd::Dialog dlg(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); dlg.setDefaultButton(QDialogButtonBox::Ok); if(mode == qf::gui::model::DataDocument::ModeInsert || mode == qf::gui::model::DataDocument::ModeEdit) { - QPushButton *bt_save = dlg.buttonBox()->addButton(tr("Save"), QDialogButtonBox::ApplyRole); - connect(dlg.buttonBox(), &qf::gui::DialogButtonBox::clicked, &dlg, [w, bt_save](QAbstractButton *button) { - if (button == bt_save) { - w->save(); - } - }); - QPushButton *bt_save_and_next = dlg.buttonBox()->addButton(tr("Ok and &next"), QDialogButtonBox::AcceptRole); + QPushButton *bt_save_and_next = dlg.buttonBox()->addButton(tr("Ok and &next"), QDialogButtonBox::ActionRole); connect(dlg.buttonBox(), &qf::gui::DialogButtonBox::clicked, &dlg, [&save_and_next, bt_save_and_next](QAbstractButton *button) { save_and_next = (button == bt_save_and_next); }); @@ -1186,7 +1180,11 @@ void RunsWidget::editCompetitor_helper(const QVariant &id, int mode, int siid) w->loadFromRegistrations(siid); } } - connect(doc, &Competitors::CompetitorDocument::saved, ui->wRunsTableWidget->tableView(), &qf::gui::TableView::rowExternallySaved, Qt::QueuedConnection); + connect(doc, &Competitors::CompetitorDocument::saved, this, [this, doc]() { + if (auto run_id = doc->runsIds().value(selectedStageId() - 1); run_id > 0) { + ui->wRunsTableWidget->tableView()->rowExternallySaved(run_id); + } + }); ok = dlg.exec(); } diff --git a/quickevent/app/quickevent/src/appversion.h b/quickevent/app/quickevent/src/appversion.h index 671d579ef..2947efc5e 100644 --- a/quickevent/app/quickevent/src/appversion.h +++ b/quickevent/app/quickevent/src/appversion.h @@ -1,4 +1,4 @@ #pragma once -#define APP_VERSION "3.4.10" +#define APP_VERSION "3.4.11" diff --git a/quickevent/app/quickevent/src/mainwindow.cpp b/quickevent/app/quickevent/src/mainwindow.cpp index 88c8914a0..5c5105f20 100644 --- a/quickevent/app/quickevent/src/mainwindow.cpp +++ b/quickevent/app/quickevent/src/mainwindow.cpp @@ -67,11 +67,11 @@ void MainWindow::loadPlugins() // registerPlugin(plugin); // } { - auto *plugin = new Runs::RunsPlugin(this); + auto *plugin = new Classes::ClassesPlugin(this); registerPlugin(plugin); } { - auto *plugin = new Classes::ClassesPlugin(this); + auto *plugin = new Runs::RunsPlugin(this); registerPlugin(plugin); } {