1 /*
2 Copyright © 2011 Rohan Garg <rohan16garg@gmail.com>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of
7 the License or (at your option) version 3 or any later version
8 accepted by the membership of KDE e.V. (or its successor approved
9 by the membership of KDE e.V.), which shall act as a proxy
10 defined in Section 14 of version 3 of the license.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "custom-presence-dialog.h"
22 #include "global-presence-chooser.h"
23
24 #include <QListView>
25 #include <QHBoxLayout>
26 #include <QVBoxLayout>
27 #include <QPushButton>
28 #include <QSortFilterProxyModel>
29 #include <QModelIndex>
30 #include <QDialogButtonBox>
31 #include <QComboBox>
32
33 #include <KLocalizedString>
34 #include <KConfig>
35 #include <KSharedConfig>
36
37 #include <TelepathyQt/Presence>
38 #include <QLineEdit>
39 #include <QKeyEvent>
40
41 #include <KTp/Models/presence-model.h>
42
43 class FilteredModel : public QSortFilterProxyModel
44 {
45 Q_OBJECT
46 public:
47 FilteredModel(QObject *parent);
48 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
49 };
50
FilteredModel(QObject * parent)51 FilteredModel::FilteredModel(QObject *parent)
52 : QSortFilterProxyModel(parent)
53 {
54 }
55
filterAcceptsRow(int sourceRow,const QModelIndex & sourceParent) const56 bool FilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
57 {
58 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
59 KTp::Presence presence = index.data(KTp::PresenceModel::PresenceRole).value<KTp::Presence>();
60 return ! presence.statusMessage().isEmpty();
61 }
62
CustomPresenceDialog(KTp::PresenceModel * model,QWidget * parent)63 CustomPresenceDialog::CustomPresenceDialog(KTp::PresenceModel *model, QWidget *parent)
64 : QDialog(parent),
65 m_model(model)
66 {
67 setupDialog();
68 }
69
setupDialog()70 void CustomPresenceDialog::setupDialog()
71 {
72 setWindowTitle(i18n("Edit Custom Presences"));
73
74 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
75 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
76
77 FilteredModel *filteredModel = new FilteredModel(this);
78 filteredModel->setSourceModel(m_model);
79
80 m_listView = new QListView(this);
81 m_listView->setModel(filteredModel);
82
83 connect(m_listView, SIGNAL(clicked(QModelIndex)),
84 this, SLOT(presenceViewSelectionChanged(QModelIndex)));
85
86 connect(m_listView, SIGNAL(activated(QModelIndex)),
87 this, SLOT(presenceViewSelectionChanged(QModelIndex)));
88
89 m_statusMessage = new QComboBox(this);
90 m_statusMessage->setEditable(true);
91
92 m_statusMessage->addItem(QIcon::fromTheme("user-online"), i18n("Set custom available message..."), qVariantFromValue<KTp::Presence>(Tp::Presence::available()));
93 m_statusMessage->addItem(QIcon::fromTheme("user-busy"), i18n("Set custom busy message..."), qVariantFromValue<KTp::Presence>(Tp::Presence::busy()));
94 m_statusMessage->addItem(QIcon::fromTheme("user-away"), i18n("Set custom away message..."), qVariantFromValue<KTp::Presence>(Tp::Presence::away()));
95 m_statusMessage->addItem(QIcon::fromTheme("user-away-extended"), i18n("Set custom extended away message..."), qVariantFromValue<KTp::Presence>(Tp::Presence::xa()));
96
97 m_statusMessage->setAutoCompletion(false);
98 m_statusMessage->show();
99
100 m_statusMessage->lineEdit()->setPlaceholderText(m_statusMessage->currentText());
101 m_statusMessage->lineEdit()->setWhatsThis(KDED_STATUS_MESSAGE_PARSER_WHATSTHIS);
102
103 connect(m_statusMessage, SIGNAL(editTextChanged(QString)),
104 this, SLOT(presenceMessageTextChanged(QString)));
105
106 m_addStatus = new QPushButton(QIcon::fromTheme("list-add"), i18n("Add Presence"), this);
107 m_removeStatus = new QPushButton(QIcon::fromTheme("list-remove"), i18n("Remove Presence"), this);
108 m_removeStatus->setEnabled(false);
109
110 //this triggers the presenceMessageTextChanged() slot and disables the m_addStatus button
111 m_statusMessage->lineEdit()->setText(QString());
112
113 QVBoxLayout *vLayout = new QVBoxLayout();
114 vLayout->addWidget(m_statusMessage);
115
116 QHBoxLayout *hLayout = new QHBoxLayout();
117 hLayout->addWidget(m_listView);
118
119 QVBoxLayout *vLayout2 = new QVBoxLayout();
120 vLayout2->addWidget(m_addStatus);
121 vLayout2->addWidget(m_removeStatus);
122 vLayout2->addStretch(1);
123
124 hLayout->addLayout(vLayout2);
125 vLayout->addLayout(hLayout);
126
127 vLayout->addWidget(buttonBox);
128 setLayout(vLayout);
129
130 connect(m_addStatus, SIGNAL(clicked()), SLOT(addCustomPresence()));
131 connect(m_removeStatus, SIGNAL(clicked()), SLOT(removeCustomPresence()));
132 connect(m_statusMessage, SIGNAL(currentIndexChanged(QString)), SLOT(comboboxIndexChanged(QString)));
133
134 m_statusMessage->installEventFilter(this);
135 }
136
addCustomPresence()137 void CustomPresenceDialog::addCustomPresence()
138 {
139 int presenceIndex = m_statusMessage->currentIndex();
140 KTp::Presence presence = m_statusMessage->itemData(presenceIndex).value<KTp::Presence>();
141 presence.setStatus(presence.type(), QString(), m_statusMessage->currentText());
142
143 m_listView->setCurrentIndex(qobject_cast<FilteredModel*>(m_listView->model())->mapFromSource(m_model->addPresence(presence)));
144 m_statusMessage->lineEdit()->clear();
145 m_listView->setFocus();
146 m_removeStatus->setEnabled(true);
147
148 m_model->syncCustomPresencesToDisk();
149 }
150
removeCustomPresence()151 void CustomPresenceDialog::removeCustomPresence()
152 {
153 if (! m_listView->currentIndex().isValid()) {
154 return;
155 }
156
157 KTp::Presence presence = m_listView->currentIndex().data(KTp::PresenceModel::PresenceRole).value<KTp::Presence>();
158 m_model->removePresence(presence);
159
160 if (m_listView->model()->rowCount(QModelIndex()) == 0) {
161 m_removeStatus->setEnabled(false);
162 }
163
164 m_model->syncCustomPresencesToDisk();
165 }
166
comboboxIndexChanged(const QString & text)167 void CustomPresenceDialog::comboboxIndexChanged(const QString& text)
168 {
169 m_statusMessage->lineEdit()->setText(QString());
170 m_statusMessage->lineEdit()->setPlaceholderText(text);
171 }
172
eventFilter(QObject * obj,QEvent * event)173 bool CustomPresenceDialog::eventFilter(QObject* obj, QEvent* event)
174 {
175 if (obj == m_statusMessage && event->type() == QEvent::KeyPress) {
176 QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
177 if (keyEvent->modifiers() == Qt::NoModifier && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)) {
178 addCustomPresence();
179 m_statusMessage->lineEdit()->clear();
180 m_listView->setFocus();
181 return true;
182 } else {
183 return false;
184 }
185 } else {
186 // standard event processing
187 return QObject::eventFilter(obj, event);
188 }
189 }
190
presenceMessageTextChanged(const QString & text)191 void CustomPresenceDialog::presenceMessageTextChanged(const QString& text)
192 {
193 if (text.isEmpty()) {
194 m_addStatus->setEnabled(false);
195 } else {
196 m_addStatus->setEnabled(true);
197 }
198 }
199
presenceViewSelectionChanged(const QModelIndex & index)200 void CustomPresenceDialog::presenceViewSelectionChanged(const QModelIndex& index)
201 {
202 if (index.isValid()) {
203 m_removeStatus->setEnabled(true);
204 } else {
205 m_removeStatus->setEnabled(false);
206 }
207
208 KTp::Presence presence = index.data(KTp::PresenceModel::PresenceRole).value<KTp::Presence>();
209 m_statusMessage->lineEdit()->setText(presence.statusMessage());
210 }
211
212 #include "custom-presence-dialog.moc"
213 #include "moc_custom-presence-dialog.cpp" //hack because we have two QObejcts in teh same file
214