Dive list view: move column width logic back from DiveTripModel

Conceptually, the width of the columns should probably reside in
the view not the model. But much more severly, the old code didn't
work: Columns were set in a DiveTripModel, which was deleted
right away.

Therefore, move the logic back to the DiveListView. Introduce
a QVector<int> of the initial column widths, so that they can be
erased from the setting if unchanged.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2018-07-25 20:40:47 +02:00 committed by Dirk Hohndel
parent d3dc698bba
commit 079b99135a
4 changed files with 53 additions and 92 deletions

View file

@ -26,7 +26,8 @@
#include "core/metrics.h"
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0),
currentOrder(Qt::DescendingOrder), dontEmitDiveChangedSignal(false), selectionSaved(false)
currentOrder(Qt::DescendingOrder), dontEmitDiveChangedSignal(false), selectionSaved(false),
initialColumnWidths(DiveTripModel::COLUMNS, 50) // Set up with default length 50
{
setItemDelegate(new DiveListDelegate(this));
setUniformRowHeights(true);
@ -43,63 +44,15 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
setSelectionMode(ExtendedSelection);
header()->setContextMenuPolicy(Qt::ActionsContextMenu);
const QFontMetrics metrics(defaultModelFont());
int em = metrics.width('m');
int zw = metrics.width('0');
// Fixes for the layout needed for mac
#ifdef Q_OS_MAC
int ht = metrics.height();
header()->setMinimumHeight(ht + 4);
#endif
// TODO FIXME we need this to get the header names
// can we find a smarter way?
tripModel = new DiveTripModel(this);
// set the default width as a minimum between the hard-coded defaults,
// the header text width and the (assumed) content width, calculated
// based on type
for (int col = DiveTripModel::NR; col < DiveTripModel::COLUMNS; ++col) {
QString header_txt = tripModel->headerData(col, Qt::Horizontal, Qt::DisplayRole).toString();
int width = metrics.width(header_txt);
int sw = 0;
switch (col) {
case DiveTripModel::NR:
case DiveTripModel::DURATION:
sw = 8*zw;
break;
case DiveTripModel::DATE:
sw = 14*em;
break;
case DiveTripModel::RATING:
sw = static_cast<StarWidgetsDelegate*>(itemDelegateForColumn(col))->starSize().width();
break;
case DiveTripModel::SUIT:
case DiveTripModel::SAC:
sw = 7*em;
break;
case DiveTripModel::PHOTOS:
sw = 5*em;
break;
case DiveTripModel::LOCATION:
sw = 50*em;
break;
default:
sw = 5*em;
}
if (sw > width)
width = sw;
width += zw; // small padding
if (width > tripModel->columnWidth(col))
tripModel->setColumnWidth(col, width);
}
delete tripModel;
header()->setStretchLastSection(true);
installEventFilter(this);
// TODO: We use a dummy DiveTripModel to calculated column widths.
// Change this to a global object.
DiveTripModel tripModel;
for (int i = DiveTripModel::NR; i < DiveTripModel::COLUMNS; i++)
calculateInitialColumnWidth(tripModel, i);
}
DiveListView::~DiveListView()
@ -111,7 +64,7 @@ DiveListView::~DiveListView()
if (isColumnHidden(i))
continue;
// we used to hardcode them all to 100 - so that might still be in the settings
if (columnWidth(i) == 100 || columnWidth(i) == tripModel->columnWidth(i))
if (columnWidth(i) == 100 || columnWidth(i) == initialColumnWidths[i])
settings.remove(QString("colwidth%1").arg(i));
else
settings.setValue(QString("colwidth%1").arg(i), columnWidth(i));
@ -120,6 +73,45 @@ DiveListView::~DiveListView()
settings.endGroup();
}
void DiveListView::calculateInitialColumnWidth(const DiveTripModel &tripModel, int col)
{
const QFontMetrics metrics(defaultModelFont());
int em = metrics.width('m');
int zw = metrics.width('0');
QString header_txt = tripModel.headerData(col, Qt::Horizontal, Qt::DisplayRole).toString();
int width = metrics.width(header_txt);
int sw = 0;
switch (col) {
case DiveTripModel::NR:
case DiveTripModel::DURATION:
sw = 8*zw;
break;
case DiveTripModel::DATE:
sw = 14*em;
break;
case DiveTripModel::RATING:
sw = static_cast<StarWidgetsDelegate*>(itemDelegateForColumn(col))->starSize().width();
break;
case DiveTripModel::SUIT:
case DiveTripModel::SAC:
sw = 7*em;
break;
case DiveTripModel::PHOTOS:
sw = 5*em;
break;
case DiveTripModel::LOCATION:
sw = 50*em;
break;
default:
sw = 5*em;
}
if (sw > width)
width = sw;
width += zw; // small padding
initialColumnWidths[col] = std::max(initialColumnWidths[col], width);
}
void DiveListView::setupUi()
{
QSettings settings;
@ -137,7 +129,7 @@ void DiveListView::setupUi()
if (width.isValid())
setColumnWidth(i, width.toInt());
else
setColumnWidth(i, tripModel->columnWidth(i));
setColumnWidth(i, initialColumnWidths[i]);
}
settings.endGroup();
if (firstRun)
@ -424,7 +416,7 @@ void DiveListView::reload(DiveTripModel::Layout layout, bool forceSort)
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel *>(model());
QAbstractItemModel *oldModel = m->sourceModel();
tripModel = new DiveTripModel(this);
DiveTripModel *tripModel = new DiveTripModel(this);
tripModel->setLayout(layout);
m->setSourceModel(tripModel);

View file

@ -71,12 +71,14 @@ private:
QModelIndex contextMenuIndex;
bool dontEmitDiveChangedSignal;
bool selectionSaved;
DiveTripModel *tripModel;
// Remember the initial column widths, to avoid writing unchanged widths to the settings
QVector<int> initialColumnWidths;
/* if dive_trip_t is null, there's no problem. */
QMultiHash<dive_trip_t *, int> selectedDives;
void merge_trip(const QModelIndex &a, const int offset);
void setupUi();
void calculateInitialColumnWidth(const DiveTripModel &tripModel, int col);
void backupExpandedRows();
void restoreExpandedRows();
int lastVisibleColumn();

View file

@ -442,18 +442,6 @@ DiveTripModel::DiveTripModel(QObject *parent) :
currentLayout(TREE)
{
columns = COLUMNS;
// setup the default width of columns (px)
columnWidthMap = QVector<int>(COLUMNS);
// pre-fill with 50px; the rest are explicit
for(int i = 0; i < COLUMNS; i++)
columnWidthMap[i] = 50;
columnWidthMap[NR] = 70;
columnWidthMap[DATE] = 140;
columnWidthMap[RATING] = 90;
columnWidthMap[SUIT] = 70;
columnWidthMap[SAC] = 70;
columnWidthMap[PHOTOS] = 5;
columnWidthMap[LOCATION] = 500;
}
Qt::ItemFlags DiveTripModel::flags(const QModelIndex &index) const
@ -658,21 +646,3 @@ bool DiveTripModel::setData(const QModelIndex &index, const QVariant &value, int
return false;
return diveItem->setData(index, value, role);
}
int DiveTripModel::columnWidth(int column)
{
if (column > COLUMNS - 1 || column < 0) {
qWarning() << "DiveTripModel::columnWidth(): not a valid column index -" << column;
return 50;
}
return columnWidthMap[column];
}
void DiveTripModel::setColumnWidth(int column, int width)
{
if (column > COLUMNS - 1 || column < 0) {
qWarning() << "DiveTripModel::setColumnWidth(): not a valid column index -" << column;
return;
}
columnWidthMap[column] = width;
}

View file

@ -99,13 +99,10 @@ public:
DiveTripModel(QObject *parent = 0);
Layout layout() const;
void setLayout(Layout layout);
int columnWidth(int column);
void setColumnWidth(int column, int width);
private:
void setupModelData();
QMap<dive_trip_t *, TripItem *> trips;
QVector<int> columnWidthMap;
Layout currentLayout;
};