• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17556919945

08 Sep 2025 04:04PM UTC coverage: 71.521% (-0.001%) from 71.522%
17556919945

push

github

paulmthompson
Merge branch 'main' of https://github.com/paulmthompson/WhiskerToolbox

36445 of 50957 relevant lines covered (71.52%)

1282.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.94
/src/WhiskerToolbox/TableViewerWidget/TableViewerWidget.cpp
1
#include "TableViewerWidget.hpp"
2
#include "ui_TableViewerWidget.h"
3

4
#include "PaginatedTableModel.hpp"
5
#include "DataManager/utils/TableView/interfaces/IRowSelector.h"
6

7
#include <QScrollBar>
8
#include <QMessageBox>
9
#include <QHeaderView>
10

11
TableViewerWidget::TableViewerWidget(QWidget * parent)
21✔
12
    : QWidget(parent),
13
      ui(new Ui::TableViewerWidget),
42✔
14
      _model(new PaginatedTableModel(this)) {
21✔
15

16
    ui->setupUi(this);
21✔
17
    
18
    // Set up the table view
19
    ui->table_view->setModel(_model);
21✔
20
    ui->table_view->horizontalHeader()->setStretchLastSection(true);
21✔
21
    ui->table_view->horizontalHeader()->setSectionsMovable(true);
21✔
22
    ui->table_view->verticalHeader()->setDefaultSectionSize(25);
21✔
23
    
24
    _model->setPageSize(50);
21✔
25
    
26
    connectSignals();
21✔
27

28
    // Track column order when user reorders columns
29
    connect(ui->table_view->horizontalHeader(), &QHeaderView::sectionMoved, this,
63✔
30
            [this](int /*logicalIndex*/, int /*oldVisualIndex*/, int /*newVisualIndex*/) {
42✔
31
                // Reconstruct current order by visual indices
32
                QStringList order;
1✔
33
                int cols = _model ? _model->columnCount(QModelIndex()) : 0;
1✔
34
                for (int v = 0; v < cols; ++v) {
3✔
35
                    int logical = ui->table_view->horizontalHeader()->logicalIndex(v);
2✔
36
                    QVariant name = _model->headerData(logical, Qt::Horizontal, Qt::DisplayRole);
2✔
37
                    order.push_back(name.toString());
2✔
38
                }
2✔
39
                _currentColumnOrder = order;
1✔
40
                emit columnsReordered(order);
1✔
41
            });
2✔
42
}
21✔
43

44
TableViewerWidget::~TableViewerWidget() {
30✔
45
    delete ui;
21✔
46
}
30✔
47

48
void TableViewerWidget::setTableView(std::shared_ptr<TableView> table_view, QString const & table_name) {
6✔
49
    _table_name = table_name.isEmpty() ? "Unnamed Table" : table_name;
6✔
50
    
51
    if (table_view) {
6✔
52
        _total_rows = table_view->getRowCount();
6✔
53
        _model->setTableView(table_view);
6✔
54
        
55
        // Update UI
56
        ui->table_name_label->setText(QString("Table: %1").arg(_table_name));
6✔
57
        ui->row_count_label->setText(QString("Rows: %1").arg(_total_rows));
6✔
58
        ui->column_count_label->setText(QString("Columns: %1").arg(table_view->getColumnCount()));
6✔
59
        // Navigation hidden; skip controls
60
        // Initialize current column order from table view
61
        _currentColumnOrder.clear();
6✔
62
        for (auto const & name : table_view->getColumnNames()) {
27✔
63
            _currentColumnOrder.push_back(QString::fromStdString(name));
21✔
64
        }
6✔
65

66
    } else {
67
        clearTable();
×
68
    }
69
}
6✔
70

71
void TableViewerWidget::setTableConfiguration(std::unique_ptr<IRowSelector> row_selector,
14✔
72
                                             std::vector<ColumnInfo> column_infos,
73
                                             std::shared_ptr<DataManager> data_manager,
74
                                             QString const & table_name) {
75
    _table_name = table_name.isEmpty() ? "Unnamed Table" : table_name;
14✔
76
    
77
    if (row_selector && data_manager) {
14✔
78
        _total_rows = row_selector->getRowCount();
14✔
79
        QStringList desiredOrder = _currentColumnOrder;
14✔
80
        _model->setSourceTable(std::move(row_selector), std::move(column_infos), data_manager);
14✔
81
        
82
        // Update UI
83
        ui->table_name_label->setText(QString("Table: %1").arg(_table_name));
14✔
84
        ui->row_count_label->setText(QString("Rows: %1").arg(_total_rows));
14✔
85
        ui->column_count_label->setText(QString("Columns: %1").arg(column_infos.size()));
14✔
86
        // Navigation hidden; skip controls
87
        // Initialize or reapply column order
88
        if (!desiredOrder.isEmpty()) {
14✔
89
            // Reorder visual columns to match previous order
90
            int cols = _model->columnCount(QModelIndex());
6✔
91
            std::map<QString, int> nameToIndex;
6✔
92
            for (int c = 0; c < cols; ++c) {
21✔
93
                nameToIndex[_model->headerData(c, Qt::Horizontal, Qt::DisplayRole).toString()] = c;
15✔
94
            }
95
            int visualPos = 0;
6✔
96
            for (auto const & name : desiredOrder) {
12✔
97
                auto it = nameToIndex.find(name);
6✔
98
                if (it == nameToIndex.end()) continue;
6✔
99
                int logical = it->second;
6✔
100
                int currentVisual = ui->table_view->horizontalHeader()->visualIndex(logical);
6✔
101
                if (currentVisual != visualPos) {
6✔
102
                    ui->table_view->horizontalHeader()->moveSection(currentVisual, visualPos);
×
103
                }
104
                ++visualPos;
6✔
105
            }
106
            _currentColumnOrder = desiredOrder;
6✔
107
        } else {
6✔
108
            _currentColumnOrder.clear();
8✔
109
            int cols = _model->columnCount(QModelIndex());
8✔
110
            for (int c = 0; c < cols; ++c) {
33✔
111
                _currentColumnOrder.push_back(_model->headerData(c, Qt::Horizontal, Qt::DisplayRole).toString());
25✔
112
            }
113
        }
114

115
    } else {
14✔
116
        clearTable();
×
117
    }
118
}
14✔
119

120
void TableViewerWidget::clearTable() {
80✔
121
    _table_name.clear();
80✔
122
    _total_rows = 0;
80✔
123
    _model->clearTable();
80✔
124
    
125
    // Update UI
126
    ui->table_name_label->setText("Table: (None)");
80✔
127
    ui->row_count_label->setText("Rows: 0");
80✔
128
    ui->column_count_label->setText("Columns: 0");
80✔
129

130
}
80✔
131

132
void TableViewerWidget::setPageSize(size_t page_size) {
4✔
133
    _model->setPageSize(page_size);
4✔
134
    
135
}
4✔
136

137
QString TableViewerWidget::getTableName() const {
6✔
138
    return _table_name;
6✔
139
}
140

141
bool TableViewerWidget::hasTable() const {
11✔
142
    return _total_rows > 0;
11✔
143
}
144

145
void TableViewerWidget::onTableScrolled() {
1✔
146

147
    // Emit signal with current visible row
148
    QModelIndex top_left = ui->table_view->indexAt(ui->table_view->rect().topLeft());
1✔
149
    if (top_left.isValid()) {
1✔
150
        emit rowScrolled(static_cast<size_t>(top_left.row()));
1✔
151
    }
152
}
1✔
153

154
void TableViewerWidget::connectSignals() {
21✔
155
    
156
    // Table scroll events
157
    connect(ui->table_view->verticalScrollBar(), &QScrollBar::valueChanged,
63✔
158
            this, &TableViewerWidget::onTableScrolled);
42✔
159
    connect(ui->table_view->horizontalScrollBar(), &QScrollBar::valueChanged,
63✔
160
            this, &TableViewerWidget::onTableScrolled);
42✔
161
}
21✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc