blob: 0eaa10ff8efab757c29ca6e4ebb50470adc92307 [file] [log] [blame]
Edric Milaret3e6aefe2015-06-05 16:07:26 -04001/***************************************************************************
Edric Milaretbab169d2016-01-07 15:13:33 -05002 * Copyright (C) 2015-2016 by Savoir-faire Linux *
Edric Milaret3e6aefe2015-06-05 16:07:26 -04003 * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 **************************************************************************/
18#include "accountserializationadapter.h"
19
20#include <QtWidgets/QWidget>
21#include <QtWidgets/QLayout>
22#include <QtWidgets/QLineEdit>
23#include <QtWidgets/QSpinBox>
Edric Milaret3ea594a2015-06-17 15:47:57 -040024#include <QtWidgets/QGroupBox>
25#include <QtWidgets/QFormLayout>
Edric Milaret3e6aefe2015-06-05 16:07:26 -040026#include <QtWidgets/QAbstractButton>
Edric Milaret3ea594a2015-06-17 15:47:57 -040027#include <QtWidgets/QLabel>
Edric Milaret3e6aefe2015-06-05 16:07:26 -040028
29#include <account.h>
30#include <accountmodel.h>
31
32constexpr static const char LRC_CFG[] = "lrcfg_";
33constexpr static const int LRC_CFG_LEN = 6 ;
34
35struct ConnHolder {
Edric Milarete0855a92015-06-12 11:38:24 -040036 QMetaObject::Connection c;
37 ~ConnHolder();
Edric Milaret3e6aefe2015-06-05 16:07:26 -040038};
39Q_DECLARE_METATYPE(ConnHolder*);
40
41ConnHolder::~ConnHolder()
42{
Edric Milarete0855a92015-06-12 11:38:24 -040043 QObject::disconnect(c);
Edric Milaret3e6aefe2015-06-05 16:07:26 -040044}
45
46static void avoidDuplicate(QWidget* w)
47{
Edric Milarete0855a92015-06-12 11:38:24 -040048 if (qvariant_cast<ConnHolder*>(w->property("lrcfgConn")))
49 delete qvariant_cast<ConnHolder*>(w->property("lrcfgConn"));
Edric Milaret3e6aefe2015-06-05 16:07:26 -040050}
51
52/**
53 * This check for some supported widgets and bind the widgets and property
54 */
Edric Milaret3ea594a2015-06-17 15:47:57 -040055static void setupWidget(QWidget* w, Account* a, const QHash<QByteArray, int>& roles)
Edric Milaret3e6aefe2015-06-05 16:07:26 -040056{
Edric Milarete0855a92015-06-12 11:38:24 -040057 if (w->objectName().left(LRC_CFG_LEN) == LRC_CFG) {
58 const QByteArray prop = w->objectName().mid(LRC_CFG_LEN, 999).toLatin1();
59 if (roles.contains(prop)) {
60 const int role = roles[prop];
Edric Milaret3ea594a2015-06-17 15:47:57 -040061 if (qobject_cast<QLineEdit*>(w)) {
62 QLineEdit* le = qobject_cast<QLineEdit*>(w);
63 avoidDuplicate(le);
64 le->setText(a->roleData(role).toString());
65 ConnHolder* c = new ConnHolder {
66 QObject::connect(le, &QLineEdit::textChanged, [a,role](const QString& text) {
67 if (a->roleData(role) != text)
68 a->setRoleData(role, text);
69 })
70 };
71 le->setProperty("lrcfgConn",QVariant::fromValue(c));
72 }
73 else if (qobject_cast<QSpinBox*>(w)) {
74 QSpinBox* sb = qobject_cast<QSpinBox*>(w);
75 avoidDuplicate(sb);
76 sb->setValue(a->roleData(role).toInt());
77 ConnHolder* c = new ConnHolder {
78 QObject::connect(sb, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [a,role](int value) {
79 if (a->roleData(role).toInt() != value)
80 a->setRoleData(role, value);
81 })
82 };
83 sb->setProperty("lrcfgConn",QVariant::fromValue(c));
84 }
85 else if (qobject_cast<QAbstractButton*>(w)) {
86 //QCheckBox, QRadioButton, QToolButton, QPushButton
87 QAbstractButton* b = qobject_cast<QAbstractButton*>(w);
88 avoidDuplicate(b);
89 b->setChecked(a->roleData(role).toBool());
90 ConnHolder* c = new ConnHolder {
91 QObject::connect(b, &QAbstractButton::toggled,[a,role](bool c) {
92 if (a->roleData(role).toBool() != c)
93 a->setRoleData(role, c);
94 })
95 };
96 b->setProperty("lrcfgConn",QVariant::fromValue(c));
97 }
98 else if (qobject_cast<QGroupBox*>(w)) {
99 QGroupBox* b = qobject_cast<QGroupBox*>(w);
100 avoidDuplicate(b);
101 b->setChecked(a->roleData(role).toBool());
102 ConnHolder* c = new ConnHolder {
103 QObject::connect(b, &QGroupBox::toggled,[a,role](bool c) {
104 if (a->roleData(role).toBool() != c)
105 a->setRoleData(role, c);
106 })
107 };
108 b->setProperty("lrcfgConn",QVariant::fromValue(c));
109 }
110 else {
111 qDebug() << "Unsupported widget type" << w;
112 }
113
114 //Check if the field is required for this account type
115 if (a->roleState((Account::Role)role) == Account::RoleState::UNAVAILABLE) {
Edric Milaret3ea594a2015-06-17 15:47:57 -0400116 w->setProperty("lrcfgVisible", w->isVisible() ? 2 : 1);
Edric Milarete0855a92015-06-12 11:38:24 -0400117 w->setVisible(false);
Edric Milaret3ea594a2015-06-17 15:47:57 -0400118
119 QFormLayout* fm = qobject_cast<QFormLayout*>(w->parentWidget()->layout());
120
121 //There is many of corner case here, this only handle the one that's
122 //created by Qt Designer
123 if (!fm) {
124 QLayoutItem* il = w->parentWidget()->layout()->itemAt(0);
125 if (il && il->layout())
126 fm = qobject_cast<QFormLayout*>(il->layout());
127 }
128
129 if (fm) {
130 QWidget* buddy = fm->labelForField(w);
Edric Milaret3ea594a2015-06-17 15:47:57 -0400131 if (buddy)
132 buddy->setVisible(false);
133
134 }
135 }
136 else {
137 //0 = unset, 1=invisible, 2=visible
Edric Milaret9d877ab2016-04-11 11:15:56 -0400138 w->setProperty("lrcfgVisible", 2);
139 w->setVisible(true);
Edric Milarete0855a92015-06-12 11:38:24 -0400140 }
141 }
142 else {
143 qWarning() << "Unknown config properties" << w->objectName();
144 }
145 }
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400146}
147
148static void clearConnections(QWidget* w)
149{
Edric Milarete0855a92015-06-12 11:38:24 -0400150 if (w->objectName().left(LRC_CFG_LEN) == LRC_CFG) {
151 avoidDuplicate(w);
152 }
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400153}
154
Edric Milaret3ea594a2015-06-17 15:47:57 -0400155static void drill(QWidget* w, Account* a, const QHash<QByteArray, int>& roles, bool clear = false)
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400156{
Edric Milarete0855a92015-06-12 11:38:24 -0400157 for (QObject *object : w->children()) {
158 if (!object->isWidgetType())
159 continue;
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400160
Edric Milarete0855a92015-06-12 11:38:24 -0400161 QWidget* w2 = static_cast<QWidget*>(object);
162 if (clear)
163 clearConnections(w2);
164 else
165 setupWidget(w2, a, roles);
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400166
Edric Milarete0855a92015-06-12 11:38:24 -0400167 drill(w2, a, roles);
168 }
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400169}
170
Edric Milaret3ea594a2015-06-17 15:47:57 -0400171static void hideLabel(QWidget* w) {
172 for (QObject *object : w->children()) {
173 if (!object->isWidgetType())
174 continue;
175 QWidget* w2 = qobject_cast<QWidget*>(object);
176 if (w2) {
177 QLabel* l = qobject_cast<QLabel*>(w2);
178 if (l && l->buddy()) {
179 l->setVisible(!l->buddy()->isHidden());
180 }
181 }
182 hideLabel(w2);
183 }
184}
185
186AccountSerializationAdapter::AccountSerializationAdapter(Account* a, QWidget* w) : QObject(w)
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400187{
Edric Milarete0855a92015-06-12 11:38:24 -0400188 static QHash<QByteArray, int> reverse;
189 if (reverse.isEmpty()) {
Edric Milareta3e47282015-10-23 15:20:30 -0400190 const QHash<int, QByteArray> a = AccountModel::instance().roleNames();
Edric Milarete0855a92015-06-12 11:38:24 -0400191 for (QHash<int, QByteArray>::const_iterator i = a.begin(); i != a.end(); ++i) {
192 reverse[i.value()] = i.key();
193 }
194 }
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400195
Edric Milarete0855a92015-06-12 11:38:24 -0400196 drill(w, a, reverse);
Edric Milaret3ea594a2015-06-17 15:47:57 -0400197 hideLabel(w);
Edric Milaret3e6aefe2015-06-05 16:07:26 -0400198}
199
200AccountSerializationAdapter::~AccountSerializationAdapter()
Edric Milaret3ea594a2015-06-17 15:47:57 -0400201{
202
203}