Lomiri
modelprinter.cpp
1 /*
2  * Copyright 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors:
17  * Nick Dedekind <nick.dedekind@canonical.com>
18  */
19 
20 // self
21 #include "modelprinter.h"
22 
23 #include <ayatanamenumodel.h>
24 
25 // Qt
26 #include <QTextStream>
27 
28 ModelPrinter::ModelPrinter(QObject *parent)
29  : QObject(parent)
30  , m_model(nullptr)
31 {
32 }
33 
34 void ModelPrinter::setSourceModel(AyatanaMenuModel * sourceModel)
35 {
36  if (m_model != nullptr) {
37  disconnect(m_model);
38  }
39  if (m_model != sourceModel) {
40  m_model = sourceModel;
41  Q_EMIT modelChanged();
42  Q_EMIT textChanged();
43  }
44  if (m_model != nullptr) {
45  connect(m_model, &AyatanaMenuModel::rowsInserted, this, &ModelPrinter::textChanged);
46  connect(m_model, &AyatanaMenuModel::rowsRemoved, this, &ModelPrinter::textChanged);
47  connect(m_model, &AyatanaMenuModel::dataChanged, this, &ModelPrinter::textChanged);
48  }
49 }
50 
51 AyatanaMenuModel* ModelPrinter::sourceModel() const
52 {
53  return m_model;
54 }
55 
56 QString ModelPrinter::text()
57 {
58  return getModelDataString(m_model, 0);
59 }
60 
61 QString tabify(int level) { QString str;
62  for (int i = 0; i < level; i++) {
63  str += QLatin1String(" ");
64  }
65  return str;
66 }
67 
68 QString ModelPrinter::getModelDataString(AyatanaMenuModel* sourceModel, int level)
69 {
70  if (!sourceModel)
71  return QLatin1String("");
72 
73  QString str;
74  QTextStream stream(&str);
75 
76  int rowCount = sourceModel->rowCount();
77  for (int row = 0; row < rowCount; row++) {
78 
79 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
80  stream << getRowSring(sourceModel, row, level) << Qt::endl;
81 #else
82  stream << getRowSring(sourceModel, row, level) << endl;
83 #endif
84 
85  AyatanaMenuModel* childMenuModel = qobject_cast<AyatanaMenuModel*>(sourceModel->submenu(row));
86  if (childMenuModel) {
87 
88  if (!m_children.contains(childMenuModel)) {
89  m_children << childMenuModel;
90  connect(childMenuModel, &AyatanaMenuModel::rowsInserted, this, &ModelPrinter::textChanged);
91  connect(childMenuModel, &AyatanaMenuModel::rowsRemoved, this, &ModelPrinter::textChanged);
92  connect(childMenuModel, &AyatanaMenuModel::dataChanged, this, &ModelPrinter::textChanged);
93  }
94  stream << getModelDataString(childMenuModel, level+1);
95  }
96  }
97  return str;
98 }
99 
100 QString ModelPrinter::getRowSring(AyatanaMenuModel* sourceModel, int row, int depth) const
101 {
102  QString str;
103  QTextStream stream(&str);
104 
105  // Print out this row
106  QHash<int, QByteArray> roleNames = sourceModel->roleNames();
107  QList<int> roles = roleNames.keys();
108  std::sort(roles.begin(), roles.end());
109 
110  Q_FOREACH(int role, roles) {
111  const QByteArray& roleName = roleNames[role];
112  stream << getVariantString(roleName, sourceModel->get(row, roleName), depth);
113  }
114  return str;
115 }
116 
117 QString ModelPrinter::getVariantString(const QVariant& vData) const
118 {
119  if (vData.type() == QVariant::List) {
120  QStringList strList;
121  for (const auto& v : vData.toList())
122  strList.append(getVariantString(v));
123 
124  return '[' + strList.join(", ") + ']';
125  }
126 
127  return vData.toString();
128 }
129 
130 QString ModelPrinter::getVariantString(const QString& roleName, const QVariant &vData, int depth) const
131 {
132  QString str;
133  QTextStream stream(&str);
134 
135  if (vData.canConvert(QMetaType::QVariantMap)) {
136  QMapIterator<QString, QVariant> iter(vData.toMap());
137  while (iter.hasNext()) {
138  iter.next();
139  stream << tabify(depth);
140  stream << roleName
141  << "."
142  << iter.key()
143  << ": "
144  << getVariantString(iter.value())
145 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
146  << Qt::endl;
147 #else
148  << endl;
149 #endif
150  }
151  }
152  else {
153  stream << tabify(depth);
154  stream << roleName
155  << ": "
156  << getVariantString(vData)
157 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
158  << Qt::endl;
159 #else
160  << endl;
161 #endif
162  }
163  return str;
164 }