mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2024-11-30 07:46:51 +08:00
218 lines
7.8 KiB
C++
218 lines
7.8 KiB
C++
// Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
#include <QtWidgets/QtWidgets>
|
|
|
|
struct ManualTask {
|
|
const char *title;
|
|
const char *instructions;
|
|
unsigned sectionsMovable : 1;
|
|
unsigned selectionMode : 3;
|
|
};
|
|
|
|
ManualTask tasks[] = {
|
|
{ QT_TR_NOOP("0. Default"),
|
|
"Please provide instructions",
|
|
true, QAbstractItemView::SingleSelection
|
|
},
|
|
{ QT_TR_NOOP("1. Autoscroll"),
|
|
"<ol>"
|
|
"<li>Press and hold on section 9 of vertical header.<br/>"
|
|
"<em>(all cells in the row will be selected)</em>"
|
|
"</li>"
|
|
"<li>Extend the selection by moving the mouse down.<br/>"
|
|
"<em>(selection will extend to the next rows)</em>"
|
|
"</li>"
|
|
"<li>Continue to move the mouse down and outside the window geometry.<br/>"
|
|
"<em>(The view should scroll automatically and the selection should still extend)</em>"
|
|
"</li>"
|
|
"<li>While still holding the button, do the same in the opposite direction, i.e. move mouse up and outside the window geometry.<br/>"
|
|
"<em>(Verify that the view scrolls automatically and the selection changes)</em>"
|
|
"</li>"
|
|
"<li>Verify that it works in the other dimension, i.e Press and hold section 9 of the horizontal header.<br/>"
|
|
"<em>All cells in the column will be selected</em>"
|
|
"</li>"
|
|
"<li>Extend the selection by moving the mouse to the far right and outside the window geometry.<br/>"
|
|
"<em>(selection will extend to the next columns)</em>"
|
|
"</li>"
|
|
"<li>Verify that it works in the opposite direction (i.e. move mouse to the left of the window geometry).<br/>"
|
|
"<em>(Verify that the view scrolls automatically and the selection changes)</em>"
|
|
"</li>"
|
|
"</ol>",
|
|
false, QAbstractItemView::ExtendedSelection
|
|
}
|
|
|
|
};
|
|
|
|
|
|
class Window : public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
Window(QWidget *parent = nullptr): QWidget(parent), ckMovable(0), tableView(0), cbSelectionMode(0), m_taskInstructions(0)
|
|
{
|
|
m_taskInstructions = new QLabel();
|
|
if (sizeof(tasks) > 0)
|
|
m_taskInstructions->setText(tr(tasks[0].instructions));
|
|
|
|
QVBoxLayout *vbox = new QVBoxLayout(this);
|
|
vbox->addLayout(setupComboBox());
|
|
vbox->addWidget(setupGroupBox());
|
|
vbox->addWidget(setupTableView());
|
|
vbox->addWidget(m_taskInstructions);
|
|
}
|
|
|
|
void updateControls()
|
|
{
|
|
ckMovable->setChecked(tableView->verticalHeader()->sectionsMovable());
|
|
QAbstractItemView::SelectionMode sMode = tableView->selectionMode();
|
|
cbSelectionMode->setCurrentIndex((int)sMode);
|
|
}
|
|
|
|
private:
|
|
QFormLayout *setupComboBox()
|
|
{
|
|
QComboBox *combo = new QComboBox;
|
|
for (size_t i = 0; i < sizeof(tasks) / sizeof(tasks[0]); ++i) {
|
|
combo->addItem(tr(tasks[i].title));
|
|
}
|
|
|
|
connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_taskCombo_currentIndexChanged(int)));
|
|
QFormLayout *form = new QFormLayout;
|
|
form->addRow(tr("Choose task:"), combo);
|
|
return form;
|
|
}
|
|
|
|
QGroupBox *setupGroupBox()
|
|
{
|
|
QGroupBox *grp = new QGroupBox(tr("Properties"));
|
|
QFormLayout *form = new QFormLayout;
|
|
grp->setLayout(form);
|
|
ckMovable = new QCheckBox;
|
|
ckMovable->setObjectName(QLatin1String("ckMovable"));
|
|
connect(ckMovable, SIGNAL(toggled(bool)), this, SLOT(on_ckMovable_toggled(bool)));
|
|
form->addRow(tr("SectionsMovable"), ckMovable);
|
|
|
|
cbSelectionMode = new QComboBox;
|
|
cbSelectionMode->setObjectName(QLatin1String("cbSelectionMode"));
|
|
cbSelectionMode->addItems(QStringList() << QLatin1String("NoSelection")
|
|
<< QLatin1String("SingleSelection")
|
|
<< QLatin1String("MultiSelection")
|
|
<< QLatin1String("ExtendedSelection")
|
|
<< QLatin1String("ContiguousSelection")
|
|
);
|
|
|
|
connect(cbSelectionMode, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cbSelectionMode_currentIndexChanged(int)));
|
|
form->addRow(tr("SelectionMode"), cbSelectionMode);
|
|
return grp;
|
|
}
|
|
|
|
QTableView *setupTableView()
|
|
{
|
|
tableView = new QTableView;
|
|
const int rowCount = 200;
|
|
m.setRowCount(rowCount);
|
|
m.setColumnCount(250);
|
|
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
tableView->setModel(&m);
|
|
tableView->verticalHeader()->swapSections(rowCount - 1, 5);
|
|
return tableView;
|
|
}
|
|
|
|
private Q_SLOTS:
|
|
void on_ckMovable_toggled(bool arg)
|
|
{
|
|
tableView->verticalHeader()->setSectionsMovable(arg);
|
|
tableView->horizontalHeader()->setSectionsMovable(arg);
|
|
}
|
|
|
|
void on_cbSelectionMode_currentIndexChanged(int idx)
|
|
{
|
|
tableView->setSelectionMode((QAbstractItemView::SelectionMode)idx);
|
|
}
|
|
|
|
void on_taskCombo_currentIndexChanged(int idx)
|
|
{
|
|
ManualTask &task = tasks[idx];
|
|
m_taskInstructions->setText(tr(task.instructions));
|
|
ckMovable->setChecked(task.sectionsMovable);
|
|
cbSelectionMode->setCurrentIndex((QAbstractItemView::SelectionMode)task.selectionMode);
|
|
}
|
|
|
|
public:
|
|
QCheckBox *ckMovable;
|
|
QTableView *tableView;
|
|
QStandardItemModel m;
|
|
QComboBox *cbSelectionMode;
|
|
QLabel *m_taskInstructions;
|
|
};
|
|
|
|
class SomeHandler : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QHeaderView *m_hv;
|
|
QTableView *m_tv;
|
|
public:
|
|
SomeHandler(QHeaderView *hv, QTableView *tv);
|
|
public slots:
|
|
void slotSectionResized(int, int, int);
|
|
};
|
|
|
|
SomeHandler::SomeHandler(QHeaderView *hv, QTableView *tv)
|
|
{
|
|
m_hv = hv;
|
|
m_tv = tv;
|
|
m_tv->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
|
connect(hv, SIGNAL(sectionResized(int,int,int)), this, SLOT(slotSectionResized(int,int,int)));
|
|
}
|
|
void SomeHandler::slotSectionResized(int logsection, int oldsize, int newsize)
|
|
{
|
|
int offset = m_hv->offset();
|
|
m_tv->setUpdatesEnabled(false);
|
|
// Do some manual resizing - lets make every section having the new size.
|
|
m_hv->blockSignals(true);
|
|
m_hv->setDefaultSectionSize(newsize);
|
|
m_hv->blockSignals(false);
|
|
|
|
// Adjust offset and scrollbar. Maybe it isn't 100% perfect
|
|
// but proof of concept
|
|
// The test has sense without the define, too.
|
|
#define DO_CORRECT_OFFSET_AND_SB
|
|
#ifdef DO_CORRECT_OFFSET_AND_SB
|
|
int leftRemoved = (m_hv->visualIndex(logsection)) * (oldsize - newsize);
|
|
int newoffset = offset - leftRemoved;
|
|
if (newoffset < 0)
|
|
newoffset = 0;
|
|
|
|
if (newoffset > 0 && newoffset >= m_hv->count() * newsize - m_tv->viewport()->width())
|
|
m_hv->setOffsetToLastSection();
|
|
else
|
|
m_hv->setOffset(newoffset);
|
|
|
|
m_tv->horizontalScrollBar()->blockSignals(true);
|
|
m_tv->horizontalScrollBar()->setRange(0, m_hv->count() * newsize - m_tv->viewport()->width() );
|
|
m_tv->horizontalScrollBar()->setValue(newoffset);
|
|
m_tv->horizontalScrollBar()->blockSignals(false);
|
|
#endif
|
|
m_tv->setUpdatesEnabled(true);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
QApplication app(argc, argv);
|
|
Window window;
|
|
// Comment in the line below to test selection with keyboard (space)
|
|
// tv.setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
QHeaderView *hHeader = window.tableView->horizontalHeader();
|
|
QHeaderView *vHeader = window.tableView->verticalHeader();
|
|
SomeHandler handler(hHeader, window.tableView);
|
|
hHeader->setDefaultSectionSize(30);
|
|
window.resize(600, 600);
|
|
window.show();
|
|
hHeader->setSectionsMovable(true);
|
|
vHeader->setSectionsMovable(true);
|
|
window.updateControls();
|
|
app.exec();
|
|
}
|
|
#include "qheaderviewtest1.moc"
|