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 CColumn(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 CColumn(headerName, toolTip, propertyIndex, new CValueObjectFormatter(alignment));
55  }
56 
57  CColumn CColumn::standardString(const QString &headerName, const CPropertyIndex &propertyIndex, int alignment)
58  {
59  return CColumn(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 CColumn(headerName, toolTip, propertyIndex, new CStringFormatter(alignment));
66  }
67 
68  CColumn CColumn::orderColumn(const CPropertyIndex &propertyIndex, int alignment)
69  {
70  return CColumn("#", "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 CColumn(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 CPropertyIndex(); }
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  for (const CColumn &c : m_columns)
205  {
206  if (c.hasWidthPercentage()) { return true; }
207  }
208  return false;
209  }
210 
211  void CColumns::setWidthPercentages(const QList<int> &percentages)
212  {
213  if (percentages.isEmpty())
214  {
215  for (CColumn &column : m_columns) { column.setWidthPercentage(-1); }
216  return;
217  }
218 
219  int c = 0;
220  for (CColumn &column : m_columns) { column.setWidthPercentage(percentages.at(c++)); }
221  }
222 
223  QList<int> CColumns::calculateWidths(int totalWidth) const
224  {
225  if (m_columns.isEmpty() || !this->hasAnyWidthPercentage()) { return {}; }
226 
227  int totalPercentage = 0;
228  const int averagePercentage = 100 / m_columns.size();
229 
230  for (const CColumn &c : m_columns)
231  {
232  totalPercentage += c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage;
233  }
234 
235  if (totalPercentage < 1) { return {}; }
236 
237  // ideally totalPercentage would be 100%, but there is no guarantee
238  const double part = static_cast<double>(totalWidth) / totalPercentage;
239  QList<int> widths;
240 
241  int usedWidth = 0;
242  for (const CColumn &c : m_columns)
243  {
244  const int percentage = c.hasWidthPercentage() ? c.getWidthPercentage() : averagePercentage;
245  const int restWidth = totalWidth - usedWidth;
246  const int width = qMin(restWidth, qRound(part * percentage));
247  widths.push_back(width);
248  usedWidth += width;
249  }
250 
251  return widths;
252  }
253 
255  {
256  if (this->endsWithEmptyColumn()) { return; }
258  }
259 
261  {
262  if (m_columns.isEmpty()) { return false; }
263  const CColumn c = m_columns.last();
264  return c.getPropertyIndex() == CPropertyIndexRef::GlobalIndexEmpty;
265  }
266 
267  const CDefaultFormatter *CColumns::getFormatter(const QModelIndex &index) const
268  {
269  if (!this->isValidColumn(index)) { return nullptr; }
270  const CColumn c = m_columns.at(index.column());
271  return c.getFormatter();
272  }
273 } // 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:260
void insertEmptyColumn()
Insert an empty column.
Definition: columns.cpp:254
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:223
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:211
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:267
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.