summaryrefslogtreecommitdiffstats
path: root/kplato/kptaccountspanel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kplato/kptaccountspanel.cc')
-rw-r--r--kplato/kptaccountspanel.cc452
1 files changed, 452 insertions, 0 deletions
diff --git a/kplato/kptaccountspanel.cc b/kplato/kptaccountspanel.cc
new file mode 100644
index 00000000..70fba38e
--- /dev/null
+++ b/kplato/kptaccountspanel.cc
@@ -0,0 +1,452 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Dag Andersen <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ version 2 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "kptaccountspanel.h"
+#include "kptaccount.h"
+#include "kptcommand.h"
+#include "kptproject.h"
+
+#include <qcombobox.h>
+#include <qheader.h>
+#include <qlistview.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <klistview.h>
+#include <klocale.h>
+
+#include <kdebug.h>
+
+namespace KPlato
+{
+
+class AccountItem : public KListViewItem {
+public:
+ AccountItem(AccountsPanel &pan, QListView *parent)
+ : KListViewItem(parent), account(0), panel(pan)
+ { init(); }
+ AccountItem(AccountsPanel &pan, QListViewItem *parent)
+ : KListViewItem(parent), account(0), panel(pan)
+ { init(); }
+ AccountItem(AccountsPanel &pan, QListView *parent, QString label1, QString label2 = QString::null)
+ : KListViewItem(parent, label1, label2), account(0), panel(pan)
+ { init(); }
+ AccountItem(AccountsPanel &pan, QListViewItem *parent, QString label1, QString label2 = QString::null)
+ : KListViewItem(parent, label1, label2), account(0), panel(pan)
+ { init(); }
+ AccountItem(AccountsPanel &pan, QListView *parent, QListViewItem *after)
+ : KListViewItem(parent, after), account(0), panel(pan)
+ { init(); }
+ AccountItem(AccountsPanel &pan, QListViewItem *parent, QListViewItem *after)
+ : KListViewItem(parent, after), account(0), panel(pan)
+ { init(); }
+
+ Account *account;
+ bool isDefault;
+
+ QString oldText;
+ AccountsPanel &panel;
+protected:
+ virtual void cancelRename(int col) {
+ //kdDebug()<<k_funcinfo<<endl;
+ if ((col == 0 && oldText.isEmpty()) ||
+ (!panel.isUnique(this))) {
+ return;
+ }
+ panel.renameStopped(this);
+ QListViewItem::cancelRename(col);
+ setRenameEnabled(col, false);
+ }
+private:
+ void init() {
+ setRenameEnabled(0, false);
+ setRenameEnabled(1, false);
+ setOpen(true);
+ isDefault = false;
+
+ }
+};
+
+AccountsPanel::AccountsPanel(Accounts &acc, QWidget *p, const char *n)
+ : AccountsPanelBase(p, n),
+ m_accounts(acc),
+ m_currentIndex(0),
+ m_renameItem(0)
+{
+
+ accountList->setRootIsDecorated(true);
+ accountList->header()->setStretchEnabled(true, 1);
+ accountList->setItemMargin(2);
+ accountList->setDefaultRenameAction(QListView::Accept);
+ addItems(accountList, acc);
+
+ slotSelectionChanged();
+
+ connect(accountList, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(accountList, SIGNAL(itemRenamed(QListViewItem*, int)), SLOT(slotItemRenamed(QListViewItem*, int)));
+ connect(accountList, SIGNAL(doubleClicked(QListViewItem*, const QPoint &, int)), SLOT(slotListDoubleClicked(QListViewItem*, const QPoint &, int)));
+
+ connect(removeBtn, SIGNAL(clicked()), SLOT(slotRemoveBtn()));
+ connect(newBtn, SIGNAL(clicked()), SLOT(slotNewBtn()));
+ connect(subBtn, SIGNAL(clicked()), SLOT(slotSubBtn()));
+
+ connect(accountsComboBox, SIGNAL(activated(int)), SLOT(slotActivated(int)));
+
+ // Internal hacks, to get renaming to behave along with unique names
+ // Uses signals to not get in the way of QListView
+ connect(this, SIGNAL(renameStarted(QListViewItem*, int)), SLOT(slotRenameStarted(QListViewItem*, int)));
+ connect(this, SIGNAL(startRename(QListViewItem*, int)), SLOT(slotStartRename(QListViewItem*, int)));
+ connect(this, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+}
+
+void AccountsPanel::addItems(QListView *lv, Accounts &acc) {
+ //kdDebug()<<k_funcinfo<<"No of accs: "<<acc.accountList().count()<<endl;
+ AccountListIterator it = acc.accountList();
+ for (; it.current(); ++it) {
+ QString n = it.current()->name();
+ QString d = it.current()->description();
+ AccountItem *item = new AccountItem(*this, lv, n, d);
+ item->account = it.current();
+ item->isDefault = (it.current() == acc.defaultAccount());
+ if (it.current()->isElement()) {
+ addElement(item);
+ }
+ addItems(item, it.current());
+ }
+}
+
+void AccountsPanel::addItems(QListViewItem *item, Account *acc) {
+ AccountListIterator it = acc->accountList();
+ for (; it.current(); ++it) {
+ QString n = it.current()->name();
+ QString d = it.current()->description();
+ AccountItem *ai = new AccountItem(*this, item, n, d);
+ ai->account = it.current();
+ ai->isDefault = (it.current() == acc->list()->defaultAccount());
+ if (it.current()->isElement()) {
+ addElement(ai);
+ }
+ addItems(ai, it.current());
+ }
+}
+
+void AccountsPanel::addElement(const QListViewItem *item) {
+ if (item->parent()) {
+ removeElement(item->parent());
+ }
+ m_elements.replace(item->text(0), item);
+ //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
+ refreshDefaultAccount();
+}
+
+void AccountsPanel::removeElement(QListViewItem *item) {
+ static_cast<AccountItem*>(item)->isDefault = false;
+ m_elements.remove(item->text(0));
+ refreshDefaultAccount();
+}
+
+void AccountsPanel::refreshDefaultAccount() {
+ accountsComboBox->clear();
+ m_currentIndex = 0;
+ accountsComboBox->insertItem(i18n("None"));
+ QDictIterator<QListViewItem> it(m_elements);
+ for(int i=1; it.current(); ++it, ++i) {
+ accountsComboBox->insertItem(it.currentKey());
+ if (static_cast<AccountItem*>(it.current())->isDefault) {
+ m_currentIndex = i;
+ accountsComboBox->setCurrentItem(i);
+ //kdDebug()<<k_funcinfo<<"Default="<<it.current()->text(0)<<endl;
+ }
+ }
+ //kdDebug()<<k_funcinfo<<"size="<<accountsComboBox->count()<<endl;
+}
+void AccountsPanel::slotActivated(int index) {
+ //kdDebug()<<k_funcinfo<<index<<endl;
+ if (m_currentIndex >= (int)m_elements.count()) {
+ kdError()<<k_funcinfo<<"currentIndex ("<<m_currentIndex<<") out of range ("<<m_elements.count()<<")"<<endl;
+ } else if (m_currentIndex > 0) {
+ AccountItem *i = static_cast<AccountItem*>(m_elements[accountsComboBox->text(m_currentIndex)]);
+ if (i)
+ i->isDefault = false;
+ }
+ m_currentIndex = 0;
+ if (index < (int)m_elements.size()) {
+ AccountItem *i = static_cast<AccountItem*>(m_elements[accountsComboBox->currentText()]);
+ if (i) {
+ i->isDefault = true;
+ m_currentIndex = index;
+ //kdDebug()<<k_funcinfo<<"currentIndex="<<m_currentIndex<<", "<<m_elements[accountsComboBox->currentText()]->text(0)<<endl;
+ }
+ }
+ slotChanged();
+}
+
+void AccountsPanel::slotChanged() {
+ emit changed(true);
+}
+
+void AccountsPanel::slotSelectionChanged() {
+ //kdDebug()<<k_funcinfo<<endl;
+ if (m_renameItem) {
+ removeBtn->setEnabled(false);
+ newBtn->setEnabled(false);
+ subBtn->setEnabled(false);
+ accountList->setSelected(m_renameItem, true);
+ return;
+ }
+ if (accountList->childCount() == 0) {
+ removeBtn->setEnabled(false);
+ newBtn->setEnabled(true);
+ subBtn->setEnabled(false);
+ return;
+ }
+ QListViewItem *i = accountList->selectedItem();
+ removeBtn->setEnabled((bool)i);
+ newBtn->setEnabled(true);
+ subBtn->setEnabled((bool)i);
+}
+
+void AccountsPanel::slotItemRenamed(QListViewItem *item, int col) {
+ //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
+ item->setRenameEnabled(col, false);
+ m_renameItem = 0;
+ if (col != 0) {
+ renameStopped(item);
+ slotChanged();
+ return;
+ }
+ if (item->text(0).isEmpty()) {
+ item->setText(0, static_cast<AccountItem*>(item)->oldText); // keep the old name
+ }
+ if (item->text(0).isEmpty()) {
+ // Not allowed
+ //kdDebug()<<k_funcinfo<<"name empty"<<endl;
+ emit startRename(item, 0);
+ return;
+ }
+ if (!isUnique(item)) {
+ // name must be unique
+ emit startRename(item, 0);
+ return;
+ }
+ addElement(item);
+ removeBtn->setEnabled(accountList->selectedItem());
+ newBtn->setEnabled(accountList->selectedItem());
+ subBtn->setEnabled(accountList->selectedItem());
+ renameStopped(item);
+ slotChanged();
+}
+
+bool AccountsPanel::isUnique(QListViewItem *item) {
+ QListViewItemIterator it(accountList);
+ for (; it.current(); ++it) {
+ if (it.current() != item && it.current()->text(0) == item->text(0)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void AccountsPanel::slotRemoveBtn() {
+ slotRemoveItem(accountList->selectedItem());
+ slotChanged();
+}
+
+void AccountsPanel::slotNewBtn() {
+ //kdDebug()<<k_funcinfo<<endl;
+ QListViewItem *item = accountList->selectedItem();
+ if (item && item->text(0).isEmpty()) {
+ return;
+ }
+ QListViewItem *n;
+ if (item) {
+ if (item->parent()) {
+ n = new AccountItem(*this, item->parent(), item);
+ } else {
+ n = new AccountItem(*this, accountList, item);
+ }
+ } else {
+ n = new AccountItem(*this, accountList);
+ }
+ slotListDoubleClicked(n, QPoint(), 0);
+}
+
+void AccountsPanel::slotSubBtn() {
+ //kdDebug()<<k_funcinfo<<endl;
+ QListViewItem *item = accountList->selectedItem();
+ if (item && item->text(0).isEmpty()) {
+ return;
+ }
+ QListViewItem *n;
+ if (item) {
+ n = new AccountItem(*this, item);
+ } else {
+ n = new AccountItem(*this, accountList);
+ }
+ slotListDoubleClicked(n, QPoint(), 0);
+}
+
+KCommand *AccountsPanel::buildCommand(Part *part) {
+ KMacroCommand *cmd = 0;
+ // First remove
+ QPtrListIterator<QListViewItem> rit = m_removedItems;
+ for (;rit.current(); ++rit) {
+ AccountItem *item = static_cast<AccountItem*>(rit.current());
+ //kdDebug()<<k_funcinfo<<"Removed item"<<endl;
+ if (!cmd) cmd = new KMacroCommand(i18n("Modify Accounts"));
+ cmd->addCommand(new RemoveAccountCmd(part, part->getProject(), item->account));
+ }
+ m_removedItems.setAutoDelete(true);
+ // Then add/modify
+ KCommand *c = save(part, part->getProject());
+ if (c) {
+ if (!cmd) cmd = new KMacroCommand(i18n("Modify Accounts"));
+ cmd->addCommand(c);
+ }
+ return cmd;
+}
+
+KCommand *AccountsPanel::save(Part *part, Project &project) {
+ KMacroCommand *cmd=0;
+ QListViewItem *myChild = accountList->firstChild();
+ for (; myChild; myChild = myChild->nextSibling()) {
+ KCommand *c = save(part, project, myChild);
+ if (c) {
+ if (!cmd) cmd = new KMacroCommand("");
+ cmd->addCommand(c);
+ }
+ }
+ return cmd;
+}
+
+KCommand *AccountsPanel::save(Part *part, Project &project, QListViewItem *i) {
+ KMacroCommand *cmd=0;
+ AccountItem *item = static_cast<AccountItem*>(i);
+ if (item->account == 0) {
+ if (!item->text(0).isEmpty()) {
+ //kdDebug()<<k_funcinfo<<"New account: "<<item->text(0)<<endl;
+ if (!cmd) cmd = new KMacroCommand("");
+ item->account = new Account(item->text(0), item->text(1));
+ if (item->parent()) {
+ //kdDebug()<<k_funcinfo<<"New account: "<<item->text(0)<<endl;
+ cmd->addCommand(new AddAccountCmd(part, project, item->account, item->parent()->text(0)));
+ } else {
+ cmd->addCommand(new AddAccountCmd(part, project, item->account));
+ }
+ }
+ } else {
+ if (!item->text(0).isEmpty() && (item->text(0) != item->account->name())) {
+ if (!cmd) cmd = new KMacroCommand("");
+ //kdDebug()<<k_funcinfo<<"Renamed: "<<item->account->name()<<" to "<<item->text(0)<<endl;
+ cmd->addCommand(new RenameAccountCmd(part, item->account, item->text(0)));
+ }
+ if (item->text(1) != item->account->description()) {
+ if (!cmd) cmd = new KMacroCommand("");
+ //kdDebug()<<k_funcinfo<<"New description: "<<item->account->description()<<" to "<<item->text(1)<<endl;
+ cmd->addCommand(new ModifyAccountDescriptionCmd(part, item->account, item->text(1)));
+ }
+ }
+ QListViewItem *myChild = item->firstChild();
+ for (; myChild; myChild = myChild->nextSibling()) {
+ KCommand *c = save(part, project, myChild);
+ if (c) {
+ if (!cmd) cmd = new KMacroCommand("");
+ cmd->addCommand(c);
+ }
+ }
+ AccountItem *ai = static_cast<AccountItem*>(m_elements[accountsComboBox->currentText()]);
+ Account *newDefaultAccount = 0;
+ if (ai) {
+ newDefaultAccount = ai->account;
+ }
+ if (m_oldDefaultAccount != newDefaultAccount) {
+ if (!cmd) cmd = new KMacroCommand("");
+ cmd->addCommand(new ModifyDefaultAccountCmd(part, m_accounts, m_oldDefaultAccount, newDefaultAccount));
+ }
+ return cmd;
+}
+
+void AccountsPanel::slotListDoubleClicked(QListViewItem* item, const QPoint&, int col) {
+ //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
+ if (m_renameItem)
+ return;
+ slotStartRename(item, col);
+}
+
+void AccountsPanel::slotRenameStarted(QListViewItem */*item*/, int /*col*/) {
+ //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
+ if (accountList->isRenaming()) {
+ removeBtn->setEnabled(false);
+ newBtn->setEnabled(false);
+ subBtn->setEnabled(false);
+ }
+}
+
+void AccountsPanel::slotStartRename(QListViewItem *item, int col) {
+ //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
+ static_cast<AccountItem*>(item)->oldText = item->text(col);
+ item->setRenameEnabled(col, true);
+ item->startRename(col);
+ m_renameItem = item;
+
+ emit renameStarted(item, col);
+}
+
+void AccountsPanel::slotRemoveItem(QListViewItem *i) {
+ AccountItem *item = static_cast<AccountItem*>(i);
+ if (item == 0)
+ return;
+ //kdDebug()<<k_funcinfo<<item->text(0)<<endl;
+ removeElement(item);
+ QListViewItem *p = item->parent();
+ if (p) {
+ p->takeItem(item);
+ if (item->account) {
+ m_removedItems.append(item);
+ } else {
+ delete item;
+ }
+ if (p->childCount() == 0) {
+ addElement(p);
+ }
+ } else {
+ accountList->takeItem(item);
+ if (item->account) {
+ m_removedItems.append(item);
+ } else {
+ delete item;
+ }
+ }
+}
+
+// We don't get notified when rename is cancelled, this is called from the item
+void AccountsPanel::renameStopped(QListViewItem */*item*/) {
+ //kdDebug()<<k_funcinfo<<endl;
+ m_renameItem = 0;
+ emit selectionChanged();
+}
+
+void AccountsPanel::slotOk() {
+
+}
+
+} //namespace KPlato
+
+#include "kptaccountspanel.moc"