1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 1999-2012 Licq developers <licq-dev@googlegroups.com>
4  *
5  * Licq 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 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Licq 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 Licq; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "editgrpdlg.h"
21 
22 #include "config.h"
23 
24 #include <boost/foreach.hpp>
25 
26 #include <QDialogButtonBox>
27 #include <QGridLayout>
28 #include <QGroupBox>
29 #include <QLabel>
30 #include <QLineEdit>
31 #include <QListWidget>
32 #include <QPushButton>
33 #include <QVBoxLayout>
34 
35 #include <licq/contactlist/group.h>
36 #include <licq/contactlist/usermanager.h>
37 #include <licq/pluginsignal.h>
38 
39 #include "core/messagebox.h"
40 #include "core/signalmanager.h"
41 
42 #include "helpers/support.h"
43 
44 using namespace LicqQtGui;
45 /* TRANSLATOR LicqQtGui::EditGrpDlg */
46 
EditGrpDlg(QWidget * parent)47 EditGrpDlg::EditGrpDlg(QWidget* parent)
48   : QDialog(parent)
49 {
50   Support::setWidgetProps(this, "EditGroupDialog");
51   setWindowTitle(tr("Licq - Edit Groups"));
52 
53   QVBoxLayout* lay = new QVBoxLayout(this);
54   grpGroups = new QGroupBox(tr("Groups"));
55   lay->addWidget(grpGroups);
56 
57   QGridLayout* glay = new QGridLayout(grpGroups);
58   lstGroups = new QListWidget(grpGroups);
59   glay->addWidget(lstGroups, 0, 0);
60 
61   QVBoxLayout* vlay = new QVBoxLayout();
62 #define BUTTON(var, name, slot) \
63   var = new QPushButton(name, grpGroups); \
64   connect(var, SIGNAL(clicked()), SLOT(slot())); \
65   vlay->addWidget(var)
66 
67   BUTTON(btnAdd, tr("Add"), slot_add);
68   BUTTON(btnRemove, tr("Remove"), slot_remove);
69   BUTTON(btnUp, tr("Shift Up"), slot_up);
70   BUTTON(btnDown, tr("Shift Down"), slot_down);
71   BUTTON(btnEdit, tr("Edit Name"), slot_edit);
72 #undef BUTTON
73   vlay->addStretch(1);
74 
75   btnEdit->setToolTip(tr("Edit group name (hit enter to save)."));
76 
77   glay->addLayout(vlay, 0, 1);
78 
79   edtName = new QLineEdit(grpGroups);
80   edtName->setEnabled(false);
81   connect(edtName, SIGNAL(returnPressed()), SLOT(slot_editok()));
82   glay->addWidget(edtName, 1, 0);
83 
84   btnSave = new QPushButton(tr("&Save"));
85   btnSave->setEnabled(false);
86   btnSave->setToolTip(tr("Save the name of a group being modified."));
87   connect(btnSave, SIGNAL(clicked()), SLOT(slot_editok()));
88   glay->addWidget(btnSave, 1, 1);
89 
90   QDialogButtonBox* buttons = new QDialogButtonBox();
91   connect(buttons, SIGNAL(rejected()), SLOT(close()));
92   btnDone = buttons->addButton(QDialogButtonBox::Close);
93   lay->addWidget(buttons);
94 
95   RefreshList();
96   connect(gGuiSignalManager,
97       SIGNAL(updatedList(unsigned long, int, const Licq::UserId&)),
98       SLOT(listUpdated(unsigned long)));
99 
100   show();
101 }
102 
currentGroupId() const103 int EditGrpDlg::currentGroupId() const
104 {
105   if (lstGroups->currentItem() == NULL)
106     return 0;
107 
108   return lstGroups->currentItem()->data(Qt::UserRole).toInt();
109 }
110 
setCurrentGroupId(int groupId)111 void EditGrpDlg::setCurrentGroupId(int groupId)
112 {
113   for (int i = 0; i < lstGroups->count(); ++i)
114     if (lstGroups->item(i)->data(Qt::UserRole).toInt() == groupId)
115     {
116       lstGroups->setCurrentRow(i);
117       break;
118     }
119 }
120 
RefreshList()121 void EditGrpDlg::RefreshList()
122 {
123   int groupId = currentGroupId();
124   lstGroups->clear();
125 
126   Licq::GroupListGuard groupList;
127   BOOST_FOREACH(const Licq::Group* group, **groupList)
128   {
129     Licq::GroupReadGuard pGroup(group);
130 
131     QString name = QString::fromLocal8Bit(pGroup->name().c_str());
132     QListWidgetItem* item = new QListWidgetItem(name, lstGroups);
133     item->setData(Qt::UserRole, pGroup->id());
134   }
135 
136   setCurrentGroupId(groupId);
137 }
138 
listUpdated(unsigned long subSignal)139 void EditGrpDlg::listUpdated(unsigned long subSignal)
140 {
141   switch (subSignal)
142   {
143     case Licq::PluginSignal::ListGroupAdded:
144     case Licq::PluginSignal::ListGroupRemoved:
145     case Licq::PluginSignal::ListGroupChanged:
146     case Licq::PluginSignal::ListGroupsReordered:
147 
148     case Licq::PluginSignal::ListInvalidate:
149       if (btnSave->isEnabled()) // we are editing the group name
150         slot_editcancel();
151       RefreshList();
152       break;
153   }
154 }
155 
slot_add()156 void EditGrpDlg::slot_add()
157 {
158   // Don't add group until user has had a chance to set a name for it
159   myEditGroupId = 0;
160   lstGroups->setCurrentRow(-1);
161 
162   btnSave->setEnabled(true);
163   btnDone->setEnabled(false);
164   edtName->setEnabled(true);
165 
166   edtName->setText(tr("noname"));
167   edtName->setFocus();
168   edtName->selectAll();
169   btnEdit->setText(tr("Cancel"));
170   disconnect(btnEdit, SIGNAL(clicked()), this, SLOT(slot_edit()));
171   connect(btnEdit, SIGNAL(clicked()), SLOT(slot_editcancel()));
172   lstGroups->setEnabled(false);
173   btnSave->setDefault(true);
174 }
175 
slot_remove()176 void EditGrpDlg::slot_remove()
177 {
178   int groupId = currentGroupId();
179   if (groupId == 0)
180     return;
181 
182   QString warning(tr("Are you sure you want to remove\n"
183                      "the group '%1'?").arg(lstGroups->currentItem()->text()));
184 
185   if (QueryYesNo(this, warning))
186   {
187     Licq::gUserManager.RemoveGroup(groupId);
188     RefreshList();
189   }
190 }
191 
moveGroup(int delta)192 void EditGrpDlg::moveGroup(int delta)
193 {
194   int groupId = currentGroupId();
195   if (groupId == 0)
196     return;
197 
198   int oldSortIndex;
199 
200   {
201     Licq::GroupReadGuard group(groupId);
202     if (!group.isLocked())
203       return;
204     oldSortIndex = group->sortIndex();
205   }
206 
207   if (delta + oldSortIndex < 0)
208     return;
209 
210   Licq::gUserManager.ModifyGroupSorting(groupId, oldSortIndex + delta);
211   RefreshList();
212 }
213 
slot_up()214 void EditGrpDlg::slot_up()
215 {
216   moveGroup(-1);
217 }
218 
slot_down()219 void EditGrpDlg::slot_down()
220 {
221   moveGroup(1);
222 }
223 
slot_edit()224 void EditGrpDlg::slot_edit()
225 {
226   myEditGroupId = currentGroupId();
227   if (myEditGroupId == 0)
228     return;
229 
230   btnSave->setEnabled(true);
231   btnDone->setEnabled(false);
232   edtName->setEnabled(true);
233 
234   edtName->setText(lstGroups->currentItem()->text());
235   edtName->setFocus();
236   btnEdit->setText(tr("Cancel"));
237   disconnect(btnEdit, SIGNAL(clicked()), this, SLOT(slot_edit()));
238   connect(btnEdit, SIGNAL(clicked()), SLOT(slot_editcancel()));
239   lstGroups->setEnabled(false);
240   btnSave->setDefault(true);
241 }
242 
slot_editok()243 void EditGrpDlg::slot_editok()
244 {
245   if (myEditGroupId == 0)
246     myEditGroupId = Licq::gUserManager.AddGroup(edtName->text().toLocal8Bit().constData());
247   else
248     Licq::gUserManager.RenameGroup(myEditGroupId, edtName->text().toLocal8Bit().constData());
249   RefreshList();
250   setCurrentGroupId(myEditGroupId);
251 
252   btnSave->setDefault(false);
253   lstGroups->setEnabled(true);
254   btnEdit->setText(tr("Edit Name"));
255   edtName->clear();
256   edtName->setEnabled(false);
257   btnSave->setEnabled(false);
258   btnDone->setEnabled(true);
259   disconnect(btnEdit, SIGNAL(clicked()), this, SLOT(slot_editok()));
260   connect(btnEdit, SIGNAL(clicked()), SLOT(slot_edit()));
261 }
262 
slot_editcancel()263 void EditGrpDlg::slot_editcancel()
264 {
265   btnSave->setDefault(false);
266   lstGroups->setEnabled(true);
267   btnEdit->setText(tr("Edit Name"));
268   edtName->clear();
269   edtName->setEnabled(false);
270   btnSave->setEnabled(false);
271   btnDone->setEnabled(true);
272   disconnect(btnEdit, SIGNAL(clicked()), this, SLOT(slot_editcancel()));
273   connect(btnEdit, SIGNAL(clicked()), SLOT(slot_edit()));
274 }
275