swift
columns.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "gui/models/columns.h"
5 
6 #include <QByteArray>
7 #include <QCoreApplication>
8 #include <QModelIndex>
9 
10 #include "gui/guiapplication.h"
12 
13 using namespace swift::misc;
14 
15 namespace swift::gui::models
16 {
17  CColumn::CColumn(const QString &headerName, const QString &toolTip, const CPropertyIndex &propertyIndex,
18  CDefaultFormatter *formatter, bool editable)
19  : m_columnName(headerName), m_columnToolTip(toolTip),
20  m_formatter(formatter ? formatter : new CDefaultFormatter()), m_propertyIndex(propertyIndex),
21  m_editable(editable)
22  {}
23 
24  CColumn::CColumn(const CPropertyIndex &propertyIndex)
25  : m_formatter(new CPixmapFormatter()), m_propertyIndex(propertyIndex)
26  {}
27 
28  bool CColumn::hasSortPropertyIndex() const { return !m_sortPropertyIndex.isEmpty(); }
29 
30  void CColumn::setSortPropertyIndex(const CPropertyIndex &propertyIndex)
31  {
32  Q_ASSERT(!propertyIndex.isEmpty());
33  m_sortPropertyIndex = propertyIndex;
34  }
35 
37  {
38  const bool incogntio = this->isIncognito() && sGui && sGui->isIncognito();
39  return incogntio ? CColumn::incongitoFormatter() : m_formatter.data();
40  }
41 
42  CColumn::CColumn(const QString &toolTip, const CPropertyIndex &propertyIndex)
43  : m_columnToolTip(toolTip), m_formatter(new CPixmapFormatter()), m_propertyIndex(propertyIndex)
44  {}
45 
46  CColumn CColumn::standardValueObject(const QString &headerName, const CPropertyIndex &propertyIndex, int alignment)
47  {
48  return { headerName, propertyIndex, new CValueObjectFormatter(alignment) };
49  }
50 
51  CColumn CColumn::standardValueObject(const QString &headerName, const QString &toolTip,
52  const CPropertyIndex &propertyIndex, int alignment)
53  {
54  return { headerName, toolTip, propertyIndex, new CValueObjectFormatter(alignment) };
55  }
56 
57  CColumn CColumn::standardString(const QString &headerName, const CPropertyIndex &propertyIndex, int alignment)
58  {
59  return { headerName, propertyIndex, new CStringFormatter(alignment) };
60  }
61 
62  CColumn CColumn::standardString(const QString &headerName, const QString &toolTip,
63  const CPropertyIndex &propertyIndex, int alignment)
64  {
65  return { headerName, toolTip, propertyIndex, new CStringFormatter(alignment) };
66  }
67 
68  CColumn CColumn::orderColumn(const CPropertyIndex &propertyIndex, int alignment)
69  {
70  return { "#", "order", propertyIndex, new CStringFormatter(alignment) };
71  }
72 
73  CColumn CColumn::standardInteger(const QString &headerName, const QString &toolTip,
74  const CPropertyIndex &propertyIndex, int alignment)
75  {
76  return { headerName, toolTip, propertyIndex, new CIntegerFormatter(alignment) };
77  }
78 
80  {
81  CColumn col = CColumn("", "", CPropertyIndexRef::GlobalIndexEmpty, new CEmptyFormatter());
82  col.setWidthPercentage(1);
83  return col;
84  }
85 
86  const CIncognitoFormatter *CColumn::incongitoFormatter()
87  {
88  static const CIncognitoFormatter incognito;
89  return &incognito;
90  }
91 
92  // --------------- columns ----------------------------------------------
93 
94  CColumns::CColumns(const QString &translationContext, QObject *parent)
95  : QObject(parent), m_translationContext(translationContext)
96  {
97  // void
98  }
99 
100  void CColumns::addColumn(const CColumn &column)
101  {
102  Q_ASSERT(!m_translationContext.isEmpty());
103  CColumn copy(column);
104  copy.setTranslationContext(m_translationContext);
105  m_columns.push_back(copy);
106  }
107 
109  {
110  CColumn copy(column);
111  copy.setIncognito(true);
112  this->addColumn(copy);
113  }
114 
115  QString CColumns::propertyIndexToColumnName(const CPropertyIndex &propertyIndex, bool i18n) const
116  {
117  const int column = this->propertyIndexToColumn(propertyIndex);
118  Q_UNUSED(i18n) // not implemented
119  return m_columns.at(column).getColumnName();
120  }
121 
122  QString CColumns::columnToName(int column, bool i18n) const
123  {
124  Q_ASSERT(isValidColumn(column));
125  Q_UNUSED(i18n) // not implemented
126  return m_columns.at(column).getColumnName();
127  }
128 
130  {
131  Q_ASSERT(isValidColumn(column));
132  return m_columns.at(column).getPropertyIndex();
133  }
134 
136  {
137  Q_ASSERT(isValidColumn(column));
138  const CColumn col = m_columns[column];
139  Q_ASSERT(col.isSortable());
140  if (!col.isSortable()) { return {}; }
141  if (col.hasSortPropertyIndex()) { return col.getSortPropertyIndex(); }
142  return col.getPropertyIndex();
143  }
144 
145  int CColumns::propertyIndexToColumn(const CPropertyIndex &propertyIndex) const
146  {
147  for (int i = 0; i < m_columns.size(); i++)
148  {
149  if (m_columns.at(i).getPropertyIndex() == propertyIndex) { return i; }
150  }
151  return -1;
152  }
153 
154  int CColumns::nameToPropertyIndex(const QString &name) const
155  {
156  for (int i = 0; i < m_columns.size(); i++)
157  {
158  if (m_columns.at(i).getColumnName() == name) { return i; }
159  }
160  return -1;
161  }
162 
163  int CColumns::size() const { return m_columns.size(); }
164 
165  bool CColumns::hasAlignment(const QModelIndex &index) const
166  {
167  if (!isValidColumn(index)) return false;
168  return m_columns.at(index.column()).hasAlignment();
169  }
170 
171  bool CColumns::isEditable(const QModelIndex &index) const
172  {
173  if (!isValidColumn(index)) return false;
174  return m_columns.at(index.column()).isEditable();
175  }
176 
177  bool CColumns::isEditable(int column) const
178  {
179  if (!isValidColumn(column)) return false;
180  return m_columns.at(column).isEditable();
181  }
182 
183  bool CColumns::isSortable(const QModelIndex &index) const
184  {
185  if (!isValidColumn(index)) return false;
186  return m_columns.at(index.column()).isSortable();
187  }
188 
189  bool CColumns::isSortable(int column) const
190  {
191  if (!isValidColumn(column)) { return false; }
192  return m_columns.at(column).isSortable();
193  }
194 
195  bool CColumns::isValidColumn(const QModelIndex &index) const
196  {
197  return (index.column() >= 0 && index.column() < m_columns.size());
198  }
199 
200  bool CColumns::isValidColumn(int column) const { return column >= 0 && column < m_columns.size(); }
201 
203  {
204  return std::any_of(m_columns.cbegin(), m_columns.cend(),
205  [](const CColumn &c) { return c.hasWidthPercentage(); });
206  }
207 
208  void CColumns::setWidthPercentages(const QList<int> &percentages)
209  {
210  if (percentages.isEmpty())
211  {
212  for (CColumn &column : m_columns) { column.setWidthPercentage(-1); }
213  return;
214  }
215 
216  int c = 0;
217  for (CColumn &column : m_columns) { column.setWidthPercentage(percentages.at(c++)); }
218  }
219 
220  QList<int> CColumns::calculateWidths(int totalWidth) const
221  {
222  if (m_columns.isEmpty() || !this->hasAnyWidthPercentage()) { return {}; }
223 
224  int totalPercentage = 0;
225  const int averagePercentage = 100 / m_columns.size();
226 
227  for (const CColumn &c : m_columns)
228  {
229  totalPercentage += c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage;
230  }
231 
232  if (totalPercentage < 1) { return {}; }
233 
234  // ideally totalPercentage would be 100%, but there is no guarantee
235  const double part = static_cast<double>(totalWidth) / totalPercentage;
236  QList<int> widths;
237 
238  int usedWidth = 0;
239  for (const CColumn &c : m_columns)
240  {
241  const int percentage = c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage;
242  const int restWidth = totalWidth - usedWidth;
243  const int width = qMin(restWidth, qRound(part * percentage));
244  widths.push_back(width);
245  usedWidth += width;
246  }
247 
248  return widths;
249  }
250 
252  {
253  if (this->endsWithEmptyColumn()) { return; }
255  }
256 
258  {
259  if (m_columns.isEmpty()) { return false; }
260  const CColumn c = m_columns.last();
261  return c.getPropertyIndex() == CPropertyIndexRef::GlobalIndexEmpty;
262  }
263 
265  {
266  if (!this->isValidColumn(index)) { return nullptr; }
267  const CColumn c = m_columns.at(index.column());
268  return c.getFormatter();
269  }
270 } // namespace swift::gui::models
bool isIncognito() const
Is incognito mode?
Single column.
Definition: columns.h:26
const CDefaultFormatter * getFormatter() const
Formatter.
Definition: columns.cpp:36
bool isIncognito() const
If incognito mode, do NOT display daza.
Definition: columns.h:103
bool isSortable() const
Sortable?
Definition: columns.h:54
static CColumn standardValueObject(const QString &headerName, const swift::misc::CPropertyIndex &propertyIndex, int alignment=CDefaultFormatter::alignDefault())
Get a standard value object formatted column.
Definition: columns.cpp:46
static CColumn standardString(const QString &headerName, const swift::misc::CPropertyIndex &propertyIndex, int alignment=CDefaultFormatter::alignDefault())
Get a standard string object formatted column.
Definition: columns.cpp:57
const swift::misc::CPropertyIndex & getPropertyIndex() const
Property index.
Definition: columns.h:88
void setSortPropertyIndex(const swift::misc::CPropertyIndex &propertyIndex)
Property index used when sorting, option alternative.
Definition: columns.cpp:30
void setWidthPercentage(int width)
Width percentage.
Definition: columns.h:100
void setTranslationContext(const QString &translationContext)
Translation context.
Definition: columns.h:91
static CColumn orderColumn(const swift::misc::CPropertyIndex &propertyIndex=swift::misc::CPropertyIndexRef::GlobalIndexIOrderable, int alignment=CDefaultFormatter::alignRightVCenter())
Get a standard string object formatted column.
Definition: columns.cpp:68
CColumn(const QString &headerName, const swift::misc::CPropertyIndex &propertyIndex, CDefaultFormatter *formatter, bool editable=false)
Constructor.
Definition: columns.h:29
static CColumn emptyColumn()
An empty column.
Definition: columns.cpp:79
static CColumn standardInteger(const QString &headerName, const QString &toolTip, const swift::misc::CPropertyIndex &propertyIndex, int alignment=CDefaultFormatter::alignRightVCenter())
Get a standard integer value formatted column.
Definition: columns.cpp:73
bool hasSortPropertyIndex() const
Sort index available.
Definition: columns.cpp:28
swift::misc::CPropertyIndex getSortPropertyIndex() const
Property index used when sorting, option alternative.
Definition: columns.h:60
void setIncognito(bool incognito)
Mark as incognito enabled.
Definition: columns.h:106
bool endsWithEmptyColumn() const
Ending with an empty column.
Definition: columns.cpp:257
void insertEmptyColumn()
Insert an empty column.
Definition: columns.cpp:251
int size() const
Size (number of columns)
Definition: columns.cpp:163
QString propertyIndexToColumnName(const swift::misc::CPropertyIndex &propertyIndex, bool i18n=false) const
Property index to name.
Definition: columns.cpp:115
bool isValidColumn(const QModelIndex &index) const
Valid column?
Definition: columns.cpp:195
bool isSortable(const QModelIndex &index) const
Sortable column?
Definition: columns.cpp:183
QList< int > calculateWidths(int totalWidth) const
Calculate the absolute width.
Definition: columns.cpp:220
bool hasAnyWidthPercentage() const
Any column with width percentage?
Definition: columns.cpp:202
QString columnToName(int column, bool i18n=false) const
Column index to name.
Definition: columns.cpp:122
void setWidthPercentages(const QList< int > &percentages)
Set the width percentages.
Definition: columns.cpp:208
int propertyIndexToColumn(const swift::misc::CPropertyIndex &propertyIndex) const
Property index to column.
Definition: columns.cpp:145
int nameToPropertyIndex(const QString &name) const
Column index to name.
Definition: columns.cpp:154
bool isEditable(const QModelIndex &index) const
Is this column editable?
Definition: columns.cpp:171
bool hasAlignment(const QModelIndex &index) const
Alignment for this column?
Definition: columns.cpp:165
void addColumnIncognito(const CColumn &column)
Add a column as incognito enabled.
Definition: columns.cpp:108
CColumns(const QString &translationContext, QObject *parent=nullptr)
Columns constructors.
Definition: columns.cpp:94
swift::misc::CPropertyIndex columnToSortPropertyIndex(int column) const
Column to property index for sort, considers.
Definition: columns.cpp:135
swift::misc::CPropertyIndex columnToPropertyIndex(int column) const
Column to property index.
Definition: columns.cpp:129
void addColumn(const CColumn &column)
Add a column.
Definition: columns.cpp:100
const CDefaultFormatter * getFormatter(const QModelIndex &index) const
Formatter.
Definition: columns.cpp:264
Column formatter default implementation, also serving as interface.
Just returns a empty "" value.
Just returns a empty "" value.
Formatter when column contains an integer.
String formatter, if known the variant already contains the appropriate string.
Default formatter when column contains CValueObject.
bool isEmpty() const
Empty?
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Models to be used with views, mainly QTableView.
Free functions in swift::misc.
QList< T >::const_reference at(qsizetype i) const const
bool isEmpty() const const
void push_back(QList< T >::parameter_type value)
int column() const const
bool isEmpty() const const