Add initial project structure with essential files including .gitignore, application resources, and various model and view components for the application. Implemented asynchronous parsing support and database structure checks.

This commit is contained in:
2025-12-08 15:21:18 +03:00
parent 4f8c90c15b
commit 3467003721
110 changed files with 35406 additions and 0 deletions
+145
View File
@@ -0,0 +1,145 @@
#include "stickytableview.h"
#include <QScrollBar>
#include <QHeaderView>
#include <QPainter>
#include <QApplication>
#include <QDebug>
StickyTableView::StickyTableView(QWidget *parent)
: QTableView(parent)
, m_stickyColumns(1)
, m_stickyColumnWidth(0)
, m_isScrolling(false)
{
// Настройка горизонтального скроллбара
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
// Подключаем сигнал изменения скролла
connect(horizontalScrollBar(), &QScrollBar::valueChanged,
[this](int) {
if (!m_isScrolling) {
updateStickyColumnGeometry();
viewport()->update();
}
});
}
void StickyTableView::setStickyColumns(int count)
{
if (m_stickyColumns != count) {
m_stickyColumns = count;
updateStickyColumnGeometry();
viewport()->update();
}
}
void StickyTableView::paintEvent(QPaintEvent *event)
{
// Сначала рисуем обычную таблицу
QTableView::paintEvent(event);
// Затем рисуем липкие столбцы поверх
if (m_stickyColumns > 0 && model()) {
QPainter painter(viewport());
paintStickyColumns(&painter);
}
}
void StickyTableView::scrollContentsBy(int dx, int dy)
{
m_isScrolling = true;
QTableView::scrollContentsBy(dx, dy);
m_isScrolling = false;
// Обновляем геометрию липких столбцов после скролла
updateStickyColumnGeometry();
}
void StickyTableView::resizeEvent(QResizeEvent *event)
{
QTableView::resizeEvent(event);
updateStickyColumnGeometry();
}
void StickyTableView::updateStickyColumnGeometry()
{
if (!model() || m_stickyColumns <= 0)
return;
// Вычисляем ширину липких столбцов
m_stickyColumnWidth = 0;
for (int i = 0; i < m_stickyColumns && i < model()->columnCount(); ++i) {
m_stickyColumnWidth += columnWidth(i);
}
// Устанавливаем отступ для основного контента
setViewportMargins(m_stickyColumnWidth, 0, 0, 0);
}
void StickyTableView::paintStickyColumns(QPainter *painter)
{
if (!model() || m_stickyColumns <= 0)
return;
// Сохраняем состояние painter
painter->save();
// Настраиваем clipping для липких столбцов
QRect stickyRect = QRect(0, 0, m_stickyColumnWidth, viewport()->height());
painter->setClipRect(stickyRect);
// Получаем видимые строки
QRect visibleRect = viewport()->rect();
int topRow = rowAt(0);
int bottomRow = rowAt(visibleRect.height());
if (topRow < 0) topRow = 0;
if (bottomRow < 0) bottomRow = model()->rowCount() - 1;
// Рисуем липкие столбцы
for (int row = topRow; row <= bottomRow && row < model()->rowCount(); ++row) {
int y = rowViewportPosition(row);
int currentRowHeight = rowHeight(row);
for (int col = 0; col < m_stickyColumns && col < model()->columnCount(); ++col) {
int x = 0;
for (int i = 0; i < col; ++i) {
x += columnWidth(i);
}
QRect cellRect(x, y, columnWidth(col), currentRowHeight);
// Рисуем фон ячейки
QModelIndex index = model()->index(row, col);
QStyleOptionViewItem option;
option.initFrom(this);
option.rect = cellRect;
option.state = QStyle::State_Enabled;
if (selectionModel()->isSelected(index)) {
option.state |= QStyle::State_Selected;
}
if (index == currentIndex()) {
option.state |= QStyle::State_HasFocus;
}
style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter);
// Рисуем текст ячейки
QVariant data = model()->data(index, Qt::DisplayRole);
if (data.isValid()) {
painter->drawText(cellRect.adjusted(4, 0, -4, 0),
Qt::AlignVCenter | Qt::AlignLeft,
data.toString());
}
}
}
// Рисуем границы липких столбцов
painter->setPen(QPen(Qt::black, 1));
painter->drawLine(m_stickyColumnWidth - 1, 0, m_stickyColumnWidth - 1, viewport()->height());
// Восстанавливаем состояние painter
painter->restore();
}