Skip to content

Commit

Permalink
Logbook: Performance tunning
Browse files Browse the repository at this point in the history
- logbook shows only the first 256 record - qtableview paging is enabled again
- reworked refresh Qtableview
  • Loading branch information
foldynl committed Sep 15, 2024
1 parent debc009 commit cc3fc22
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 113 deletions.
242 changes: 129 additions & 113 deletions ui/LogbookWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,9 @@ LogbookWidget::LogbookWidget(QWidget *parent) :
ui->contactTable->addAction(separator1);
ui->contactTable->addAction(ui->actionDeleteContact);

//ui->contactTable->sortByColumn(1, Qt::DescendingOrder);

ui->contactTable->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->contactTable->horizontalHeader(), &QHeaderView::customContextMenuRequested,
this, &LogbookWidget::showTableHeaderContextMenu);
connect(ui->contactTable, &QTableQSOView::dataCommitted, this, &LogbookWidget::updateTable);

ui->contactTable->setItemDelegateForColumn(LogbookModel::COLUMN_TIME_ON, new TimestampFormatDelegate(ui->contactTable));
ui->contactTable->setItemDelegateForColumn(LogbookModel::COLUMN_TIME_OFF, new TimestampFormatDelegate(ui->contactTable));
Expand Down Expand Up @@ -259,7 +256,7 @@ void LogbookWidget::filterCountryBand(const QString &countryName,
ui->countryFilter->blockSignals(false);
ui->bandFilter->blockSignals(false);

updateTable();
filterTable();
}

void LogbookWidget::lookupSelectedCallsign()
Expand Down Expand Up @@ -288,7 +285,7 @@ void LogbookWidget::callsignFilterChanged()
{
FCT_IDENTIFICATION;

updateTable();
filterTable();
}

void LogbookWidget::bandFilterChanged()
Expand All @@ -297,7 +294,7 @@ void LogbookWidget::bandFilterChanged()

colorsFilterWidget(ui->bandFilter);
saveBandFilter();
updateTable();
filterTable();;
}

void LogbookWidget::saveBandFilter()
Expand Down Expand Up @@ -334,7 +331,7 @@ void LogbookWidget::modeFilterChanged()

colorsFilterWidget(ui->modeFilter);
saveModeFilter();
updateTable();
filterTable();
}

void LogbookWidget::saveModeFilter()
Expand Down Expand Up @@ -370,7 +367,7 @@ void LogbookWidget::countryFilterChanged()

colorsFilterWidget(ui->countryFilter);
saveCountryFilter();
updateTable();
filterTable();
}

void LogbookWidget::saveCountryFilter()
Expand Down Expand Up @@ -407,7 +404,7 @@ void LogbookWidget::userFilterChanged()

colorsFilterWidget(ui->userFilter);
saveUserFilter();
updateTable();
filterTable();
}

void LogbookWidget::saveUserFilter()
Expand Down Expand Up @@ -443,7 +440,7 @@ void LogbookWidget::clubFilterChanged()

colorsFilterWidget(ui->clubFilter);
saveClubFilter();
updateTable();
filterTable();
}

void LogbookWidget::refreshClubFilter()
Expand Down Expand Up @@ -491,7 +488,7 @@ void LogbookWidget::restoreFilters()
restoreclubFilter();
restoreUserFilter();
externalFilter = QString();
updateTable();
filterTable();
}

void LogbookWidget::uploadClublog()
Expand Down Expand Up @@ -648,111 +645,22 @@ void LogbookWidget::updateTable()
{
FCT_IDENTIFICATION;

QStringList filterString;

const QString &callsignFilterValue = ui->callsignFilter->text();

if ( !callsignFilterValue.isEmpty() )
{
filterString.append(QString("callsign LIKE '%%1%'").arg(callsignFilterValue.toUpper()));
}

const QString &bandFilterValue = ui->bandFilter->currentText();

if ( ui->bandFilter->currentIndex() != 0 && !bandFilterValue.isEmpty())
{
filterString.append(QString("band = '%1'").arg(bandFilterValue));
}

const QString &modeFilterValue = ui->modeFilter->currentText();

if ( ui->modeFilter->currentIndex() != 0 && !modeFilterValue.isEmpty() )
{
filterString.append(QString("mode = '%1'").arg(modeFilterValue));
}

/* Refresh dynamic Country selection combobox */
/* It is important to block its signals */
ui->countryFilter->blockSignals(true);
const QString &country = ui->countryFilter->currentText();
countryModel->refresh();
ui->countryFilter->setCurrentText(country);
ui->countryFilter->blockSignals(false);

int row = ui->countryFilter->currentIndex();
const QModelIndex &idx = ui->countryFilter->model()->index(row,0);
QVariant data = ui->countryFilter->model()->data(idx);

if ( ui->countryFilter->currentIndex() != 0 )
{
filterString.append(QString("dxcc = '%1'").arg(data.toInt()));
}

if ( ui->clubFilter->currentIndex() != 0 )
{
filterString.append(QString("id in (SELECT contactid FROM contact_clubs_view WHERE clubid = '%1')").arg(ui->clubFilter->currentText()));
}

/* Refresh dynamic User Filter selection combobox */
/* block the signals !!! */
ui->userFilter->blockSignals(true);
const QString &userFilterString = ui->userFilter->currentText();
userFilterModel->refresh();
ui->userFilter->setCurrentText(userFilterString);
ui->userFilter->blockSignals(false);

if ( ui->userFilter->currentIndex() != 0 )
{
QSqlQuery userFilterQuery;
if ( ! userFilterQuery.prepare("SELECT "
"'(' || GROUP_CONCAT( ' ' || c.name || ' ' || CASE WHEN r.value IS NULL AND o.sql_operator IN ('=', 'like') THEN 'IS' "
" WHEN r.value IS NULL and r.operator_id NOT IN ('=', 'like') THEN 'IS NOT' "
" WHEN o.sql_operator = ('starts with') THEN 'like' "
" ELSE o.sql_operator END || "
"' (' || quote(CASE o.sql_operator WHEN 'like' THEN '%' || r.value || '%' "
" WHEN 'not like' THEN '%' || r.value || '%' "
" WHEN 'starts with' THEN r.value || '%' "
" ELSE r.value END) || ') ', m.sql_operator) || ')' "
"FROM qso_filters f, qso_filter_rules r, "
"qso_filter_operators o, qso_filter_matching_types m, "
"PRAGMA_TABLE_INFO('contacts') c "
"WHERE f.filter_name = :filterName "
" AND f.filter_name = r.filter_name "
" AND o.operator_id = r.operator_id "
" AND m.matching_id = f.matching_type "
" AND c.cid = r.table_field_index") )
{
qWarning() << "Cannot prepare select statement";
return;
}
model->select();
ui->contactTable->resizeColumnsToContents();

userFilterQuery.bindValue(":filterName", ui->userFilter->currentText());
// it is not possible to use mode->rowCount here because model contains only
// the first 256 records and rowCount has a value 256 here. Therefore, it is needed
// to run a QSL stateme with Count
QString countRecordsStmt(QLatin1String("SELECT COUNT(1) FROM contacts"));

qCDebug(runtime) << "User filter SQL: " << userFilterQuery.lastQuery();
if ( !model->filter().isEmpty() )
countRecordsStmt.append(QString(" WHERE %1").arg(model->filter()));

if ( userFilterQuery.exec() )
{
userFilterQuery.next();
filterString.append(QString("( ") + userFilterQuery.value(0).toString() + ")");
}
else
{
qCDebug(runtime) << "User filter error - " << userFilterQuery.lastError().text();
}
}

if ( !externalFilter.isEmpty() )
{
filterString.append(QString("( ") + externalFilter + ")");
}

qCDebug(runtime) << "SQL filter summary: " << filterString.join(" AND ");
model->setFilter(filterString.join(" AND "));
qCDebug(runtime) << model->query().lastQuery();
model->select();
QSqlQuery query(countRecordsStmt);

ui->contactTable->resizeColumnsToContents();
ui->filteredQSOsLabel->setText(tr("Count: %n", "", model->rowCount()));
ui->filteredQSOsLabel->setText(tr("Count: %n", "", query.first() ? query.value(0).toInt()
: 0));
ui->contactTable->scrollToTop();
emit logbookUpdated();
}

Expand Down Expand Up @@ -902,7 +810,7 @@ void LogbookWidget::sendDXCSpot()

bool LogbookWidget::eventFilter(QObject *obj, QEvent *event)
{
FCT_IDENTIFICATION;
//FCT_IDENTIFICATION;

if ( event->type() == QEvent::KeyPress && obj == ui->contactTable )
{
Expand All @@ -923,6 +831,114 @@ void LogbookWidget::colorsFilterWidget(QComboBox *widget)
: "");
}

void LogbookWidget::filterTable()
{
FCT_IDENTIFICATION;

QStringList filterString;

const QString &callsignFilterValue = ui->callsignFilter->text();

if ( !callsignFilterValue.isEmpty() )
{
filterString.append(QString("callsign LIKE '%%1%'").arg(callsignFilterValue.toUpper()));
}

const QString &bandFilterValue = ui->bandFilter->currentText();

if ( ui->bandFilter->currentIndex() != 0 && !bandFilterValue.isEmpty())
{
filterString.append(QString("band = '%1'").arg(bandFilterValue));
}

const QString &modeFilterValue = ui->modeFilter->currentText();

if ( ui->modeFilter->currentIndex() != 0 && !modeFilterValue.isEmpty() )
{
filterString.append(QString("mode = '%1'").arg(modeFilterValue));
}

/* Refresh dynamic Country selection combobox */
/* It is important to block its signals */
ui->countryFilter->blockSignals(true);
const QString &country = ui->countryFilter->currentText();
countryModel->refresh();
ui->countryFilter->setCurrentText(country);
ui->countryFilter->blockSignals(false);

int row = ui->countryFilter->currentIndex();
const QModelIndex &idx = ui->countryFilter->model()->index(row,0);
QVariant data = ui->countryFilter->model()->data(idx);

if ( ui->countryFilter->currentIndex() != 0 )
{
filterString.append(QString("dxcc = '%1'").arg(data.toInt()));
}

if ( ui->clubFilter->currentIndex() != 0 )
{
filterString.append(QString("id in (SELECT contactid FROM contact_clubs_view WHERE clubid = '%1')").arg(ui->clubFilter->currentText()));
}

/* Refresh dynamic User Filter selection combobox */
/* block the signals !!! */
ui->userFilter->blockSignals(true);
const QString &userFilterString = ui->userFilter->currentText();
userFilterModel->refresh();
ui->userFilter->setCurrentText(userFilterString);
ui->userFilter->blockSignals(false);

if ( ui->userFilter->currentIndex() != 0 )
{
QSqlQuery userFilterQuery;
if ( ! userFilterQuery.prepare("SELECT "
"'(' || GROUP_CONCAT( ' ' || c.name || ' ' || CASE WHEN r.value IS NULL AND o.sql_operator IN ('=', 'like') THEN 'IS' "
" WHEN r.value IS NULL and r.operator_id NOT IN ('=', 'like') THEN 'IS NOT' "
" WHEN o.sql_operator = ('starts with') THEN 'like' "
" ELSE o.sql_operator END || "
"' (' || quote(CASE o.sql_operator WHEN 'like' THEN '%' || r.value || '%' "
" WHEN 'not like' THEN '%' || r.value || '%' "
" WHEN 'starts with' THEN r.value || '%' "
" ELSE r.value END) || ') ', m.sql_operator) || ')' "
"FROM qso_filters f, qso_filter_rules r, "
"qso_filter_operators o, qso_filter_matching_types m, "
"PRAGMA_TABLE_INFO('contacts') c "
"WHERE f.filter_name = :filterName "
" AND f.filter_name = r.filter_name "
" AND o.operator_id = r.operator_id "
" AND m.matching_id = f.matching_type "
" AND c.cid = r.table_field_index") )
{
qWarning() << "Cannot prepare select statement";
return;
}

userFilterQuery.bindValue(":filterName", ui->userFilter->currentText());

qCDebug(runtime) << "User filter SQL: " << userFilterQuery.lastQuery();

if ( userFilterQuery.exec() )
{
userFilterQuery.next();
filterString.append(QString("( ") + userFilterQuery.value(0).toString() + ")");
}
else
{
qCDebug(runtime) << "User filter error - " << userFilterQuery.lastError().text();
}
}

if ( !externalFilter.isEmpty() )
{
filterString.append(QString("( ") + externalFilter + ")");
}

model->setFilter(filterString.join(" AND "));
qCDebug(runtime) << model->query().lastQuery();

updateTable();
}

LogbookWidget::~LogbookWidget() {
FCT_IDENTIFICATION;

Expand Down
1 change: 1 addition & 0 deletions ui/LogbookWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public slots:
bool eventFilter(QObject *obj, QEvent *event);

void colorsFilterWidget(QComboBox *widget);
void filterTable();
};

/* https://forum.qt.io/topic/90403/show-tooltip-immediatly/7/ */
Expand Down

0 comments on commit cc3fc22

Please sign in to comment.