diff --git a/appver.h b/appver.h index f10c293..4aded7a 100644 --- a/appver.h +++ b/appver.h @@ -8,7 +8,7 @@ #define APP_MAJOR 0 #define APP_MINOR 0 #define APP_PATCH 0 -#define APP_COMMIT 291 +#define APP_COMMIT 293 #define FILE_VER APP_MAJOR,APP_MINOR,APP_PATCH,APP_COMMIT // обязательно запятые! #define PRODUCT_VER FILE_VER diff --git a/lang/snap_ru_RU.ts b/lang/snap_ru_RU.ts index 5da1738..e999d95 100644 --- a/lang/snap_ru_RU.ts +++ b/lang/snap_ru_RU.ts @@ -998,21 +998,21 @@ - + Фотовал - + Чип - + Ракель @@ -1064,59 +1064,59 @@ - + Заправка - + Повтор - + Гарантия - + Статус информирования клиента обновлён - + Ошибка - + Кол-во больше наличия, списание не возможно - + Информация - + Проверьте права доступа или обратитесь к администратору - + Примечание сохранено - - - + + + Успешно - + Данные сохранены @@ -4381,32 +4381,32 @@ p, li { white-space: pre-wrap; } STableViewBase - + Автоширина - + Размер по содержимому - + Вписать все - + Сделать значением по умолчанию - + Скрыть - + Выбрать столбцы @@ -6844,99 +6844,99 @@ p, li { white-space: pre-wrap; } - + Ремонт repair tab title - + Данные не сохранены - + Результат диагностики, согласованная сумма или список работ и деталей не сохранены! Сохранить перед закрытием? - + no permissions - + было в другом СЦ - + данные не важны - + срочный - + повтор - + гарантия - + чек при выдаче - + предоплата: %1 - - - - + + + + Информация - - + + Проверьте права доступа или обратитесь к администратору - + Поле с результатом диагностики не может быть пустым - + Не достаточно прав для открытия карточки чужого ремонта - + Не установлена согласованная сумма - + Успешно - + Статус информирования клиента обновлён diff --git a/models/ssqlfetchingmodel.cpp b/models/ssqlfetchingmodel.cpp index 0c37d56..31a81e6 100644 --- a/models/ssqlfetchingmodel.cpp +++ b/models/ssqlfetchingmodel.cpp @@ -113,6 +113,7 @@ void SSqlFetchingModel::fetchMore(const QModelIndex &parent) fetchMore(m_fetchSize, parent); } +// TODO: реализовать асинхронную загрузку void SSqlFetchingModel::fetchMore(const int fetchSize, const QModelIndex &parent) { if(!canFetchMore(parent)) diff --git a/widgets/scartridgeform.cpp b/widgets/scartridgeform.cpp index 27d0e4f..ddb5014 100644 --- a/widgets/scartridgeform.cpp +++ b/widgets/scartridgeform.cpp @@ -174,6 +174,7 @@ void SCartridgeForm::initWidgets() ui->pushButtonPreagreedRefill->setChecked(true); setRefill(true); // почему-то при вызове метода setChecked() слот setRefill() не вызывается } + m_initDone = 1; } /* Натсройка виджетов предварительно согласованных работ @@ -293,6 +294,9 @@ bool SCartridgeForm::eventFilter(QObject *watched, QEvent *event) if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) { + if(!m_initDone) // Если инициализация моделей и виджетов не выполнена, то обработка событий не должна выполняться + return false; + QPushButton *checkBoxWidget = dynamic_cast(watched); if(checkBoxWidget) { diff --git a/widgets/scartridgeform.h b/widgets/scartridgeform.h index 583964a..c8fd01b 100644 --- a/widgets/scartridgeform.h +++ b/widgets/scartridgeform.h @@ -95,6 +95,7 @@ class SCartridgeForm : public QFrame int m_prevRepairsCount = 0; QString m_lineEditStyleSheet = commonLineEditStyleSheet; QString m_spinBoxStyleSheet = commonSpinBoxStyleSheet; + bool m_initDone = 0; void updateHeader(); void updateWidgets(); void hideWidgetsOnReceiptForm(); diff --git a/widgets/stableviewbase.cpp b/widgets/stableviewbase.cpp index 2fcfda1..e36236a 100644 --- a/widgets/stableviewbase.cpp +++ b/widgets/stableviewbase.cpp @@ -437,17 +437,15 @@ void STableViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex & void STableViewBase::verticalScrollbarValueChanged(int value) { - bool flag = (verticalScrollBar()->maximum() > 0 && verticalScrollBar()->maximum() == value && !i_vspValue); // с пом. условия !i_vspValue фильтруются автообновления - if(flag) - saveSelection(); + restartAutorefreshTimer(); // чтобы во время прокрутки не срабатывало автообновление таблицы и интерфейс не подвисал QTableView::verticalScrollbarValueChanged(value); - if(flag) - restoreSelection(); } void STableViewBase::horizontalScrollbarValueChanged(int value) { Q_UNUSED(value); + + restartAutorefreshTimer(); // При прокрутке максимально вправо также вызываются методы canFetchMore и fetchMore // (см. qtbase\src\widgets\itemviews\qabstractitemview.cpp) // с пом. значения -1 вызов fetchMore блокируется, но остальные действия выполнятся @@ -903,23 +901,31 @@ void STableViewBase::vScrollCorrection() void STableViewBase::vsp_rangeChanged(const int min, const int max) { - if(max == 0 || !verticalScrollBar()->isVisible()) + if(max == 0) return; + restartAutorefreshTimer(); + while(model()->rowCount() < i_vspOldRowCount && (i_vspValue || hasSavedSelection())) + { + fetchMore(QModelIndex()); + return; + } + if(verticalScrollBar()->maximum() - i_vspValue < userDbData->rowHeight) + { + fetchMore(QModelIndex()); + } restoreVScrollPos(); } void STableViewBase::restoreVScrollPos() { - if(i_vspValue > 0) + if(i_vspValue >= 0) { vScrollCorrection(); verticalScrollBar()->setValue(i_vspValue); } - i_vspValue = 0; - - restoreSelection(); + i_vspValue = -1; } void STableViewBase::hsp_rangeChanged(const int min, const int max) @@ -955,7 +961,6 @@ QModelIndexList STableViewBase::selectionList() */ void STableViewBase::saveSelection() { - m_restoreSelectionTrig = 0; if(selectionBehavior() != QAbstractItemView::SelectRows) return; @@ -963,6 +968,8 @@ void STableViewBase::saveSelection() { m_selectionList.append(index.data()); } + m_currentIndexRow = currentIndex().row(); + m_currentIndexColumn = currentIndex().column(); } bool STableViewBase::hasSavedSelection() @@ -975,13 +982,6 @@ bool STableViewBase::hasSavedSelection() */ void STableViewBase::restoreSelection() { - // Метод вызывается из двух мест, а порядок вызова может изменяться, - // поэтому, чтобы восстановление работало корректно, используется примитивный фильтр - m_restoreSelectionTrig++; - if(m_restoreSelectionTrig != 2) - return; - m_restoreSelectionTrig = 0; - if(selectionBehavior() != QAbstractItemView::SelectRows) return; @@ -1003,6 +1003,15 @@ void STableViewBase::restoreSelection() } } selectionModel()->select(selection, QItemSelectionModel::Select); + + // При восстановлении текущего индекса также изменяется значение скролла; однако, посылка/обработка сигнала + // происходит в разное время (предположительно, зависит от события Paint), из-за чего после автообновления + // таблицы положение восстанавливается неправильно если таблица не на виду (например, пользователь переключился + // на другую вкладку). Чтобы положение восстанавливалось всегда сигналы блокируются. + selectionModel()->blockSignals(true); + selectionModel()->setCurrentIndex(model()->index(m_currentIndexRow, m_currentIndexColumn), QItemSelectionModel::Rows); + selectionModel()->blockSignals(false); + m_selectionList.clear(); // если вдруг в списке остались элементы } @@ -1044,6 +1053,11 @@ void STableViewBase::setModelQuery(const QString &query, const QSqlDatabase &dat m_model->setQuery(query, database); } +void STableViewBase::fetchMore(const QModelIndex &parent) +{ + m_model->fetchMore(QModelIndex()); +} + /* Очистка списка выделенных строк */ void STableViewBase::clearSelection() @@ -1102,6 +1116,18 @@ void STableViewBase::delayedRefresh(const int msec) m_autorefreshTimer->start(msec); } +/* Перезапуск таймера автообновления таблицы. + * Может быть полезен, например, при дозагрузке данных (fetchMore) или + * при при прокрутке таблицы — автообновление не будет "накладываться" + * и интерфейс программы не будет подвисать. + * TODO: но правльно будет реализовать асинхронную загрузку и обновление +*/ +void STableViewBase::restartAutorefreshTimer() +{ + if(m_autorefreshTimeout > 0) + m_autorefreshTimer->start(m_autorefreshTimeout); +} + void STableViewBase::autorefreshTable() { refresh(STableViewBase::ScrollPosPreserve, STableViewBase::SelectionPreserve); @@ -1126,6 +1152,9 @@ void STableViewBase::setUniqueIdColumn(int uniqueIdColumn) */ void STableViewBase::refresh(bool preserveScrollPos, bool preserveSelection) { + if(QApplication::queryKeyboardModifiers() & (Qt::ControlModifier | Qt::ShiftModifier)) + return; + if (m_query.isEmpty() || (!m_db.isValid())) return; @@ -1144,7 +1173,7 @@ void STableViewBase::refresh(bool preserveScrollPos, bool preserveSelection) if(m_queryConditionsChanged) { i_vspOldRowCount = 0; - i_vspValue = 0; + i_vspValue = -1; m_queryConditionsChanged = 0; } diff --git a/widgets/stableviewbase.h b/widgets/stableviewbase.h index 1335964..6e968fc 100644 --- a/widgets/stableviewbase.h +++ b/widgets/stableviewbase.h @@ -70,6 +70,7 @@ class STableViewBase : public QTableView void setLayoutVariant(const SLocalSettings::SettingsVariant &layoutVariant); void enableAutorefresh(const int msec); void delayedRefresh(const int msec); + void restartAutorefreshTimer(); protected: static const QRegularExpression queryPrepareRegexpPattern; QSqlQueryModel *m_model = nullptr; @@ -116,6 +117,7 @@ class STableViewBase : public QTableView bool initHeaders(); virtual void clearModel(); virtual void setModelQuery(const QString &query, const QSqlDatabase &database); + virtual void fetchMore(const QModelIndex &parent); virtual void layoutChanged(int,int,int); private: QFile m_layoutSettingsFileName; @@ -129,6 +131,8 @@ class STableViewBase : public QTableView QStringList *m_grouping = nullptr; int m_uniqueIdColumn = -1; QList m_selectionList; + int m_currentIndexRow = -1; + int m_currentIndexColumn = -1; QTimer *m_layoutSaveTimer = nullptr; int m_autorefreshTimeout = 0; int m_restoreSelectionTrig = 0; diff --git a/widgets/stableviewrepairs.cpp b/widgets/stableviewrepairs.cpp index 5dee71d..80064b0 100644 --- a/widgets/stableviewrepairs.cpp +++ b/widgets/stableviewrepairs.cpp @@ -120,7 +120,6 @@ void STableViewRepairs::readLayout() { i_gridLayout->$GridControl.Columns[i].Visible = false; } - } void STableViewRepairs::clearModel() @@ -139,24 +138,10 @@ void STableViewRepairs::setModelQuery(const QString &query, const QSqlDatabase & m_model->setQuery(query, database); } -void STableViewRepairs::vsp_rangeChanged(const int min, const int max) -{ - if(max == 0) // после очистки модели ничего не делаем - return; - - while(model()->rowCount() < i_vspOldRowCount && (i_vspValue || hasSavedSelection())) - { - m_model->fetchMore(i_vspOldRowCount - model()->rowCount(), QModelIndex()); - return; - } - if(verticalScrollBar()->maximum() - i_vspValue < userDbData->rowHeight) - { - m_model->fetchMore(QModelIndex()); - } - STableViewBase::vsp_rangeChanged(min, max); -} - -void STableViewRepairs::hsp_rangeChanged(const int min, const int max) +/* Переопределённый метод + * Загружает недостающие данные за один запрос +*/ +void STableViewRepairs::fetchMore(const QModelIndex &parent) { - STableViewBase::hsp_rangeChanged(min, max); + m_model->fetchMore(i_vspOldRowCount - model()->rowCount(), parent); } diff --git a/widgets/stableviewrepairs.h b/widgets/stableviewrepairs.h index 5389cbb..d1598cd 100644 --- a/widgets/stableviewrepairs.h +++ b/widgets/stableviewrepairs.h @@ -31,9 +31,7 @@ class STableViewRepairs : public STableViewBase void readLayout(); void clearModel() override; void setModelQuery(const QString &query, const QSqlDatabase &database) override; -private slots: - void vsp_rangeChanged(const int min, const int max) override; - void hsp_rangeChanged(const int min, const int max) override; + void fetchMore(const QModelIndex &parent) override; }; #endif // STABLEVIEWREPAIRS_H