Warning, file /office/calligra/gemini/CloudAccountsModel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2014 Dan Leinir Turthra Jensen <admin@leinir.dk> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 * 0006 */ 0007 0008 #include "CloudAccountsModel.h" 0009 #include "PropertyContainer.h" 0010 0011 #include <QDebug> 0012 #include <QByteArray> 0013 #include <QDataStream> 0014 #include <QVariant> 0015 #include <QMetaObject> 0016 #include <QMetaProperty> 0017 #include <QFile> 0018 #include <QStandardPaths> 0019 0020 struct AccountEntry { 0021 public: 0022 AccountEntry(QObject* parent) 0023 : selected(false) 0024 , accountDetails(new PropertyContainer("", parent)) 0025 {} 0026 QString text; 0027 bool selected; 0028 QString accountType; 0029 QString stackComponent; 0030 QObject* accountDetails; 0031 0032 QByteArray serialize() { 0033 // selected is not serialised, because that would be silly 0034 QByteArray ba; 0035 QDataStream stream(&ba, QIODevice::WriteOnly); 0036 stream << text; 0037 stream << accountType; 0038 stream << stackComponent; 0039 Q_FOREACH(const QByteArray &name, accountDetails->dynamicPropertyNames()) { 0040 stream << name << accountDetails->property(name); 0041 } 0042 for(int i = accountDetails->metaObject()->propertyOffset(); i < accountDetails->metaObject()->propertyCount(); ++i) { 0043 stream << accountDetails->metaObject()->property(i).name() << accountDetails->metaObject()->property(i).read(accountDetails); 0044 } 0045 return ba; 0046 } 0047 0048 static AccountEntry* fromByteArray(QByteArray& ba, QObject* parent) { 0049 AccountEntry* entry = new AccountEntry(parent); 0050 QDataStream stream(&ba, QIODevice::ReadOnly); 0051 stream >> entry->text; 0052 stream >> entry->accountType; 0053 stream >> entry->stackComponent; 0054 entry->accountDetails->setProperty("text", entry->text); 0055 while(!stream.atEnd()) { 0056 QByteArray propertyName; 0057 QVariant data; 0058 stream >> propertyName; 0059 stream >> data; 0060 entry->accountDetails->setProperty(propertyName, data); 0061 } 0062 return entry; 0063 } 0064 }; 0065 0066 class CloudAccountsModel::Private { 0067 public: 0068 Private(CloudAccountsModel* qq) 0069 : q(qq) 0070 { 0071 dataFile = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/calligrageminicloudaccounts"); 0072 loadList(); 0073 } 0074 ~Private() 0075 { 0076 qDeleteAll(entries); 0077 } 0078 CloudAccountsModel* q; 0079 QList<AccountEntry*> entries; 0080 QString dataFile; 0081 0082 void saveList() 0083 { 0084 QByteArray ba; 0085 QDataStream stream(&ba, QIODevice::WriteOnly); 0086 Q_FOREACH(AccountEntry* entry, entries) { 0087 stream << entry->serialize(); 0088 } 0089 QFile data(dataFile); 0090 data.open(QIODevice::WriteOnly); 0091 data.write(ba); 0092 data.close(); 0093 } 0094 0095 void loadList() 0096 { 0097 QByteArray ba; 0098 QFile data(dataFile); 0099 data.open(QIODevice::ReadOnly); 0100 ba = data.readAll(); 0101 data.close(); 0102 0103 q->beginResetModel(); 0104 qDeleteAll(entries); 0105 entries.clear(); 0106 0107 QDataStream stream(&ba, QIODevice::ReadOnly); 0108 QByteArray entryBA; 0109 while(!stream.atEnd()) { 0110 stream >> entryBA; 0111 entries.append(AccountEntry::fromByteArray(entryBA, q)); 0112 } 0113 0114 q->endResetModel(); 0115 } 0116 }; 0117 0118 CloudAccountsModel::CloudAccountsModel(QObject* parent) 0119 : QAbstractListModel(parent) 0120 , d(new Private(this)) 0121 { 0122 } 0123 0124 CloudAccountsModel::~CloudAccountsModel() 0125 { 0126 delete d; 0127 } 0128 0129 QHash<int, QByteArray> CloudAccountsModel::roleNames() const 0130 { 0131 QHash<int, QByteArray> roles; 0132 roles[TextRole] = "text"; 0133 roles[SelectedRole] = "selected"; 0134 roles[AccountTypeRole] = "accountType"; 0135 roles[StackComponentRole] = "stackComponent"; 0136 roles[AccountDetailsRole] = "accountDetails"; 0137 return roles; 0138 } 0139 0140 QVariant CloudAccountsModel::data(const QModelIndex& index, int role) const 0141 { 0142 QVariant result; 0143 if(index.isValid() && index.row() > -1 && index.row() < d->entries.count()) 0144 { 0145 AccountEntry* entry = d->entries.at(index.row()); 0146 switch(role) 0147 { 0148 case TextRole: 0149 result = entry->text; 0150 break; 0151 case SelectedRole: 0152 result = entry->selected; 0153 break; 0154 case AccountTypeRole: 0155 result = entry->accountType; 0156 break; 0157 case StackComponentRole: 0158 result = entry->stackComponent; 0159 break; 0160 case AccountDetailsRole: 0161 result = QVariant::fromValue<QObject*>(entry->accountDetails); 0162 break; 0163 default: 0164 break; 0165 } 0166 } 0167 return result; 0168 } 0169 0170 int CloudAccountsModel::rowCount(const QModelIndex& parent) const 0171 { 0172 if(parent.isValid()) 0173 return 0; 0174 return d->entries.count(); 0175 } 0176 0177 void CloudAccountsModel::selectIndex(int newSelection) 0178 { 0179 Q_FOREACH(AccountEntry* entry, d->entries) { 0180 entry->selected = false; 0181 } 0182 if(newSelection >= 0 && newSelection < d->entries.count()) { 0183 d->entries.at(newSelection)->selected = true; 0184 } 0185 dataChanged(index(0), index(d->entries.count() - 1)); 0186 } 0187 0188 void CloudAccountsModel::addAccount(QString text, QString accountType, QString stackComponent, QObject* accountDetails, bool removeExisting) 0189 { 0190 if(removeExisting) { 0191 removeAccountByName(text); 0192 } 0193 AccountEntry* entry = new AccountEntry(this); 0194 entry->text = text; 0195 entry->accountType = accountType; 0196 entry->stackComponent = stackComponent; 0197 if(accountDetails) { 0198 Q_FOREACH(const QByteArray &name, accountDetails->dynamicPropertyNames()) { 0199 entry->accountDetails->setProperty(name, accountDetails->property(name)); 0200 } 0201 for(int i = accountDetails->metaObject()->propertyOffset(); i < accountDetails->metaObject()->propertyCount(); ++i) { 0202 entry->accountDetails->setProperty(accountDetails->metaObject()->property(i).name(), accountDetails->metaObject()->property(i).read(accountDetails)); 0203 } 0204 } 0205 int count = d->entries.count(); 0206 beginInsertRows(QModelIndex(), count, count); 0207 d->entries.append(entry); 0208 endInsertRows(); 0209 d->saveList(); 0210 } 0211 0212 void CloudAccountsModel::renameAccount(int index, QString newText) 0213 { 0214 if(index > -1 && index < d->entries.count() - 1) 0215 { 0216 d->entries.at(index)->text = newText; 0217 dataChanged(this->index(index), this->index(index)); 0218 d->saveList(); 0219 } 0220 } 0221 0222 void CloudAccountsModel::removeAccountByName(QString text) 0223 { 0224 beginResetModel(); 0225 for(int i = d->entries.count() - 1; i > -1; --i) { 0226 if(d->entries.at(i)->text == text) { 0227 d->entries.removeAt(i); 0228 } 0229 } 0230 endResetModel(); 0231 } 0232 0233 void CloudAccountsModel::removeAccount(int index) 0234 { 0235 if(index > -1 && index < d->entries.count()) 0236 { 0237 beginRemoveRows(QModelIndex(), index, index); 0238 delete(d->entries.takeAt(index)); 0239 endRemoveRows(); 0240 d->saveList(); 0241 } 0242 } 0243 0244 QObject* CloudAccountsModel::accountDetails(int index) 0245 { 0246 if(index > -1 && index < d->entries.count() - 1) 0247 { 0248 return d->entries.at(index)->accountDetails; 0249 } 0250 return 0; 0251 } 0252 0253 void CloudAccountsModel::setAccountDetails(int index, QObject* newDetails) 0254 { 0255 if(index > -1 && index < d->entries.count() - 1) 0256 { 0257 AccountEntry* entry = d->entries.at(index); 0258 if(newDetails) { 0259 Q_FOREACH(const QByteArray &name, newDetails->dynamicPropertyNames()) { 0260 entry->accountDetails->setProperty(name, newDetails->property(name)); 0261 } 0262 for(int i = newDetails->metaObject()->propertyOffset(); i < newDetails->metaObject()->propertyCount(); ++i) { 0263 entry->accountDetails->setProperty(newDetails->metaObject()->property(i).name(), newDetails->metaObject()->property(i).read(newDetails)); 0264 } 0265 } 0266 d->saveList(); 0267 } 0268 }