kplato

kptaccountspanel.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Dag Andersen <danders@get2net.dk>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation;
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "kptaccountspanel.h"
21#include "kptaccount.h"
22#include "kptcommand.h"
23#include "kptproject.h"
24
25#include <tqcombobox.h>
26#include <tqheader.h>
27#include <tqlistview.h>
28#include <tqpushbutton.h>
29#include <tqstring.h>
30#include <tqstringlist.h>
31
32#include <tdelistview.h>
33#include <tdelocale.h>
34
35#include <kdebug.h>
36
37namespace KPlato
38{
39
40class AccountItem : public TDEListViewItem {
41public:
42 AccountItem(AccountsPanel &pan, TQListView *parent)
43 : TDEListViewItem(parent), account(0), panel(pan)
44 { init(); }
45 AccountItem(AccountsPanel &pan, TQListViewItem *parent)
46 : TDEListViewItem(parent), account(0), panel(pan)
47 { init(); }
48 AccountItem(AccountsPanel &pan, TQListView *parent, TQString label1, TQString label2 = TQString())
49 : TDEListViewItem(parent, label1, label2), account(0), panel(pan)
50 { init(); }
51 AccountItem(AccountsPanel &pan, TQListViewItem *parent, TQString label1, TQString label2 = TQString())
52 : TDEListViewItem(parent, label1, label2), account(0), panel(pan)
53 { init(); }
54 AccountItem(AccountsPanel &pan, TQListView *parent, TQListViewItem *after)
55 : TDEListViewItem(parent, after), account(0), panel(pan)
56 { init(); }
57 AccountItem(AccountsPanel &pan, TQListViewItem *parent, TQListViewItem *after)
58 : TDEListViewItem(parent, after), account(0), panel(pan)
59 { init(); }
60
61 Account *account;
62 bool isDefault;
63
64 TQString oldText;
65 AccountsPanel &panel;
66protected:
67 virtual void cancelRename(int col) {
68 //kdDebug()<<k_funcinfo<<endl;
69 if ((col == 0 && oldText.isEmpty()) ||
70 (!panel.isUnique(this))) {
71 return;
72 }
73 panel.renameStopped(this);
74 TQListViewItem::cancelRename(col);
75 setRenameEnabled(col, false);
76 }
77private:
78 void init() {
79 setRenameEnabled(0, false);
80 setRenameEnabled(1, false);
81 setOpen(true);
82 isDefault = false;
83
84 }
85};
86
87AccountsPanel::AccountsPanel(Accounts &acc, TQWidget *p, const char *n)
88 : AccountsPanelBase(p, n),
89 m_accounts(acc),
90 m_currentIndex(0),
91 m_renameItem(0)
92{
93
94 accountList->setRootIsDecorated(true);
95 accountList->header()->setStretchEnabled(true, 1);
96 accountList->setItemMargin(2);
97 accountList->setDefaultRenameAction(TQListView::Accept);
98 addItems(accountList, acc);
99
100 slotSelectionChanged();
101
102 connect(accountList, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
103 connect(accountList, TQ_SIGNAL(itemRenamed(TQListViewItem*, int)), TQ_SLOT(slotItemRenamed(TQListViewItem*, int)));
104 connect(accountList, TQ_SIGNAL(doubleClicked(TQListViewItem*, const TQPoint &, int)), TQ_SLOT(slotListDoubleClicked(TQListViewItem*, const TQPoint &, int)));
105
106 connect(removeBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotRemoveBtn()));
107 connect(newBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotNewBtn()));
108 connect(subBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotSubBtn()));
109
110 connect(accountsComboBox, TQ_SIGNAL(activated(int)), TQ_SLOT(slotActivated(int)));
111
112 // Internal hacks, to get renaming to behave along with unique names
113 // Uses signals to not get in the way of TQListView
114 connect(this, TQ_SIGNAL(renameStarted(TQListViewItem*, int)), TQ_SLOT(slotRenameStarted(TQListViewItem*, int)));
115 connect(this, TQ_SIGNAL(startRename(TQListViewItem*, int)), TQ_SLOT(slotStartRename(TQListViewItem*, int)));
116 connect(this, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
117}
118
119void AccountsPanel::addItems(TQListView *lv, Accounts &acc) {
120 //kdDebug()<<k_funcinfo<<"No of accs: "<<acc.accountList().count()<<endl;
121 AccountListIterator it = acc.accountList();
122 for (; it.current(); ++it) {
123 TQString n = it.current()->name();
124 TQString d = it.current()->description();
125 AccountItem *item = new AccountItem(*this, lv, n, d);
126 item->account = it.current();
127 item->isDefault = (it.current() == acc.defaultAccount());
128 if (it.current()->isElement()) {
129 addElement(item);
130 }
131 addItems(item, it.current());
132 }
133}
134
135void AccountsPanel::addItems(TQListViewItem *item, Account *acc) {
136 AccountListIterator it = acc->accountList();
137 for (; it.current(); ++it) {
138 TQString n = it.current()->name();
139 TQString d = it.current()->description();
140 AccountItem *ai = new AccountItem(*this, item, n, d);
141 ai->account = it.current();
142 ai->isDefault = (it.current() == acc->list()->defaultAccount());
143 if (it.current()->isElement()) {
144 addElement(ai);
145 }
146 addItems(ai, it.current());
147 }
148}
149
150void AccountsPanel::addElement(const TQListViewItem *item) {
151 if (item->parent()) {
152 removeElement(item->parent());
153 }
154 m_elements.replace(item->text(0), item);
155 //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
156 refreshDefaultAccount();
157}
158
159void AccountsPanel::removeElement(TQListViewItem *item) {
160 static_cast<AccountItem*>(item)->isDefault = false;
161 m_elements.remove(item->text(0));
162 refreshDefaultAccount();
163}
164
165void AccountsPanel::refreshDefaultAccount() {
166 accountsComboBox->clear();
167 m_currentIndex = 0;
168 accountsComboBox->insertItem(i18n("None"));
169 TQDictIterator<TQListViewItem> it(m_elements);
170 for(int i=1; it.current(); ++it, ++i) {
171 accountsComboBox->insertItem(it.currentKey());
172 if (static_cast<AccountItem*>(it.current())->isDefault) {
173 m_currentIndex = i;
174 accountsComboBox->setCurrentItem(i);
175 //kdDebug()<<k_funcinfo<<"Default="<<it.current()->text(0)<<endl;
176 }
177 }
178 //kdDebug()<<k_funcinfo<<"size="<<accountsComboBox->count()<<endl;
179}
180void AccountsPanel::slotActivated(int index) {
181 //kdDebug()<<k_funcinfo<<index<<endl;
182 if (m_currentIndex >= (int)m_elements.count()) {
183 kdError()<<k_funcinfo<<"currentIndex ("<<m_currentIndex<<") out of range ("<<m_elements.count()<<")"<<endl;
184 } else if (m_currentIndex > 0) {
185 AccountItem *i = static_cast<AccountItem*>(m_elements[accountsComboBox->text(m_currentIndex)]);
186 if (i)
187 i->isDefault = false;
188 }
189 m_currentIndex = 0;
190 if (index < (int)m_elements.size()) {
191 AccountItem *i = static_cast<AccountItem*>(m_elements[accountsComboBox->currentText()]);
192 if (i) {
193 i->isDefault = true;
194 m_currentIndex = index;
195 //kdDebug()<<k_funcinfo<<"currentIndex="<<m_currentIndex<<", "<<m_elements[accountsComboBox->currentText()]->text(0)<<endl;
196 }
197 }
198 slotChanged();
199}
200
201void AccountsPanel::slotChanged() {
202 emit changed(true);
203}
204
205void AccountsPanel::slotSelectionChanged() {
206 //kdDebug()<<k_funcinfo<<endl;
207 if (m_renameItem) {
208 removeBtn->setEnabled(false);
209 newBtn->setEnabled(false);
210 subBtn->setEnabled(false);
211 accountList->setSelected(m_renameItem, true);
212 return;
213 }
214 if (accountList->childCount() == 0) {
215 removeBtn->setEnabled(false);
216 newBtn->setEnabled(true);
217 subBtn->setEnabled(false);
218 return;
219 }
220 TQListViewItem *i = accountList->selectedItem();
221 removeBtn->setEnabled((bool)i);
222 newBtn->setEnabled(true);
223 subBtn->setEnabled((bool)i);
224}
225
226void AccountsPanel::slotItemRenamed(TQListViewItem *item, int col) {
227 //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
228 item->setRenameEnabled(col, false);
229 m_renameItem = 0;
230 if (col != 0) {
231 renameStopped(item);
232 slotChanged();
233 return;
234 }
235 if (item->text(0).isEmpty()) {
236 item->setText(0, static_cast<AccountItem*>(item)->oldText); // keep the old name
237 }
238 if (item->text(0).isEmpty()) {
239 // Not allowed
240 //kdDebug()<<k_funcinfo<<"name empty"<<endl;
241 emit startRename(item, 0);
242 return;
243 }
244 if (!isUnique(item)) {
245 // name must be unique
246 emit startRename(item, 0);
247 return;
248 }
249 addElement(item);
250 removeBtn->setEnabled(accountList->selectedItem());
251 newBtn->setEnabled(accountList->selectedItem());
252 subBtn->setEnabled(accountList->selectedItem());
253 renameStopped(item);
254 slotChanged();
255}
256
257bool AccountsPanel::isUnique(TQListViewItem *item) {
258 TQListViewItemIterator it(accountList);
259 for (; it.current(); ++it) {
260 if (it.current() != item && it.current()->text(0) == item->text(0)) {
261 return false;
262 }
263 }
264 return true;
265}
266
267void AccountsPanel::slotRemoveBtn() {
268 slotRemoveItem(accountList->selectedItem());
269 slotChanged();
270}
271
272void AccountsPanel::slotNewBtn() {
273 //kdDebug()<<k_funcinfo<<endl;
274 TQListViewItem *item = accountList->selectedItem();
275 if (item && item->text(0).isEmpty()) {
276 return;
277 }
278 TQListViewItem *n;
279 if (item) {
280 if (item->parent()) {
281 n = new AccountItem(*this, item->parent(), item);
282 } else {
283 n = new AccountItem(*this, accountList, item);
284 }
285 } else {
286 n = new AccountItem(*this, accountList);
287 }
288 slotListDoubleClicked(n, TQPoint(), 0);
289}
290
291void AccountsPanel::slotSubBtn() {
292 //kdDebug()<<k_funcinfo<<endl;
293 TQListViewItem *item = accountList->selectedItem();
294 if (item && item->text(0).isEmpty()) {
295 return;
296 }
297 TQListViewItem *n;
298 if (item) {
299 n = new AccountItem(*this, item);
300 } else {
301 n = new AccountItem(*this, accountList);
302 }
303 slotListDoubleClicked(n, TQPoint(), 0);
304}
305
306KCommand *AccountsPanel::buildCommand(Part *part) {
307 KMacroCommand *cmd = 0;
308 // First remove
309 TQPtrListIterator<TQListViewItem> rit = m_removedItems;
310 for (;rit.current(); ++rit) {
311 AccountItem *item = static_cast<AccountItem*>(rit.current());
312 //kdDebug()<<k_funcinfo<<"Removed item"<<endl;
313 if (!cmd) cmd = new KMacroCommand(i18n("Modify Accounts"));
314 cmd->addCommand(new RemoveAccountCmd(part, part->getProject(), item->account));
315 }
316 m_removedItems.setAutoDelete(true);
317 // Then add/modify
318 KCommand *c = save(part, part->getProject());
319 if (c) {
320 if (!cmd) cmd = new KMacroCommand(i18n("Modify Accounts"));
321 cmd->addCommand(c);
322 }
323 return cmd;
324}
325
326KCommand *AccountsPanel::save(Part *part, Project &project) {
327 KMacroCommand *cmd=0;
328 TQListViewItem *myChild = accountList->firstChild();
329 for (; myChild; myChild = myChild->nextSibling()) {
330 KCommand *c = save(part, project, myChild);
331 if (c) {
332 if (!cmd) cmd = new KMacroCommand("");
333 cmd->addCommand(c);
334 }
335 }
336 return cmd;
337}
338
339KCommand *AccountsPanel::save(Part *part, Project &project, TQListViewItem *i) {
340 KMacroCommand *cmd=0;
341 AccountItem *item = static_cast<AccountItem*>(i);
342 if (item->account == 0) {
343 if (!item->text(0).isEmpty()) {
344 //kdDebug()<<k_funcinfo<<"New account: "<<item->text(0)<<endl;
345 if (!cmd) cmd = new KMacroCommand("");
346 item->account = new Account(item->text(0), item->text(1));
347 if (item->parent()) {
348 //kdDebug()<<k_funcinfo<<"New account: "<<item->text(0)<<endl;
349 cmd->addCommand(new AddAccountCmd(part, project, item->account, item->parent()->text(0)));
350 } else {
351 cmd->addCommand(new AddAccountCmd(part, project, item->account));
352 }
353 }
354 } else {
355 if (!item->text(0).isEmpty() && (item->text(0) != item->account->name())) {
356 if (!cmd) cmd = new KMacroCommand("");
357 //kdDebug()<<k_funcinfo<<"Renamed: "<<item->account->name()<<" to "<<item->text(0)<<endl;
358 cmd->addCommand(new RenameAccountCmd(part, item->account, item->text(0)));
359 }
360 if (item->text(1) != item->account->description()) {
361 if (!cmd) cmd = new KMacroCommand("");
362 //kdDebug()<<k_funcinfo<<"New description: "<<item->account->description()<<" to "<<item->text(1)<<endl;
363 cmd->addCommand(new ModifyAccountDescriptionCmd(part, item->account, item->text(1)));
364 }
365 }
366 TQListViewItem *myChild = item->firstChild();
367 for (; myChild; myChild = myChild->nextSibling()) {
368 KCommand *c = save(part, project, myChild);
369 if (c) {
370 if (!cmd) cmd = new KMacroCommand("");
371 cmd->addCommand(c);
372 }
373 }
374 AccountItem *ai = static_cast<AccountItem*>(m_elements[accountsComboBox->currentText()]);
375 Account *newDefaultAccount = 0;
376 if (ai) {
377 newDefaultAccount = ai->account;
378 }
379 if (m_oldDefaultAccount != newDefaultAccount) {
380 if (!cmd) cmd = new KMacroCommand("");
381 cmd->addCommand(new ModifyDefaultAccountCmd(part, m_accounts, m_oldDefaultAccount, newDefaultAccount));
382 }
383 return cmd;
384}
385
386void AccountsPanel::slotListDoubleClicked(TQListViewItem* item, const TQPoint&, int col) {
387 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
388 if (m_renameItem)
389 return;
390 slotStartRename(item, col);
391}
392
393void AccountsPanel::slotRenameStarted(TQListViewItem */*item*/, int /*col*/) {
394 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
395 if (accountList->isRenaming()) {
396 removeBtn->setEnabled(false);
397 newBtn->setEnabled(false);
398 subBtn->setEnabled(false);
399 }
400}
401
402void AccountsPanel::slotStartRename(TQListViewItem *item, int col) {
403 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
404 static_cast<AccountItem*>(item)->oldText = item->text(col);
405 item->setRenameEnabled(col, true);
406 item->startRename(col);
407 m_renameItem = item;
408
409 emit renameStarted(item, col);
410}
411
412void AccountsPanel::slotRemoveItem(TQListViewItem *i) {
413 AccountItem *item = static_cast<AccountItem*>(i);
414 if (item == 0)
415 return;
416 //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
417 removeElement(item);
418 TQListViewItem *p = item->parent();
419 if (p) {
420 p->takeItem(item);
421 if (item->account) {
422 m_removedItems.append(item);
423 } else {
424 delete item;
425 }
426 if (p->childCount() == 0) {
427 addElement(p);
428 }
429 } else {
430 accountList->takeItem(item);
431 if (item->account) {
432 m_removedItems.append(item);
433 } else {
434 delete item;
435 }
436 }
437}
438
439// We don't get notified when rename is cancelled, this is called from the item
440void AccountsPanel::renameStopped(TQListViewItem */*item*/) {
441 //kdDebug()<<k_funcinfo<<endl;
442 m_renameItem = 0;
443 emit selectionChanged();
444}
445
446void AccountsPanel::slotOk() {
447
448}
449
450} //namespace KPlato
451
452#include "kptaccountspanel.moc"
Accounts administrates all accounts.
Definition kptaccount.h:180