You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kplato/kptaccountspanel.cpp

453 lines
15 KiB

/* This file is part of the KDE project
Copyright (C) 2005 Dag Andersen <danders@get2net.dk>
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 <tqcombobox.h>
#include <tqheader.h>
#include <tqlistview.h>
#include <tqpushbutton.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tdelistview.h>
#include <tdelocale.h>
#include <kdebug.h>
namespace KPlato
{
class AccountItem : public TDEListViewItem {
public:
AccountItem(AccountsPanel &pan, TQListView *parent)
: TDEListViewItem(parent), account(0), panel(pan)
{ init(); }
AccountItem(AccountsPanel &pan, TQListViewItem *parent)
: TDEListViewItem(parent), account(0), panel(pan)
{ init(); }
AccountItem(AccountsPanel &pan, TQListView *parent, TQString label1, TQString label2 = TQString())
: TDEListViewItem(parent, label1, label2), account(0), panel(pan)
{ init(); }
AccountItem(AccountsPanel &pan, TQListViewItem *parent, TQString label1, TQString label2 = TQString())
: TDEListViewItem(parent, label1, label2), account(0), panel(pan)
{ init(); }
AccountItem(AccountsPanel &pan, TQListView *parent, TQListViewItem *after)
: TDEListViewItem(parent, after), account(0), panel(pan)
{ init(); }
AccountItem(AccountsPanel &pan, TQListViewItem *parent, TQListViewItem *after)
: TDEListViewItem(parent, after), account(0), panel(pan)
{ init(); }
Account *account;
bool isDefault;
TQString 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);
TQListViewItem::cancelRename(col);
setRenameEnabled(col, false);
}
private:
void init() {
setRenameEnabled(0, false);
setRenameEnabled(1, false);
setOpen(true);
isDefault = false;
}
};
AccountsPanel::AccountsPanel(Accounts &acc, TQWidget *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(TQListView::Accept);
addItems(accountList, acc);
slotSelectionChanged();
connect(accountList, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
connect(accountList, TQ_SIGNAL(itemRenamed(TQListViewItem*, int)), TQ_SLOT(slotItemRenamed(TQListViewItem*, int)));
connect(accountList, TQ_SIGNAL(doubleClicked(TQListViewItem*, const TQPoint &, int)), TQ_SLOT(slotListDoubleClicked(TQListViewItem*, const TQPoint &, int)));
connect(removeBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotRemoveBtn()));
connect(newBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotNewBtn()));
connect(subBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotSubBtn()));
connect(accountsComboBox, TQ_SIGNAL(activated(int)), TQ_SLOT(slotActivated(int)));
// Internal hacks, to get renaming to behave along with unique names
// Uses signals to not get in the way of TQListView
connect(this, TQ_SIGNAL(renameStarted(TQListViewItem*, int)), TQ_SLOT(slotRenameStarted(TQListViewItem*, int)));
connect(this, TQ_SIGNAL(startRename(TQListViewItem*, int)), TQ_SLOT(slotStartRename(TQListViewItem*, int)));
connect(this, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
}
void AccountsPanel::addItems(TQListView *lv, Accounts &acc) {
//kdDebug()<<k_funcinfo<<"No of accs: "<<acc.accountList().count()<<endl;
AccountListIterator it = acc.accountList();
for (; it.current(); ++it) {
TQString n = it.current()->name();
TQString 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(TQListViewItem *item, Account *acc) {
AccountListIterator it = acc->accountList();
for (; it.current(); ++it) {
TQString n = it.current()->name();
TQString 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 TQListViewItem *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(TQListViewItem *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"));
TQDictIterator<TQListViewItem> 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;
}
TQListViewItem *i = accountList->selectedItem();
removeBtn->setEnabled((bool)i);
newBtn->setEnabled(true);
subBtn->setEnabled((bool)i);
}
void AccountsPanel::slotItemRenamed(TQListViewItem *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(TQListViewItem *item) {
TQListViewItemIterator 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;
TQListViewItem *item = accountList->selectedItem();
if (item && item->text(0).isEmpty()) {
return;
}
TQListViewItem *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, TQPoint(), 0);
}
void AccountsPanel::slotSubBtn() {
//kdDebug()<<k_funcinfo<<endl;
TQListViewItem *item = accountList->selectedItem();
if (item && item->text(0).isEmpty()) {
return;
}
TQListViewItem *n;
if (item) {
n = new AccountItem(*this, item);
} else {
n = new AccountItem(*this, accountList);
}
slotListDoubleClicked(n, TQPoint(), 0);
}
KCommand *AccountsPanel::buildCommand(Part *part) {
KMacroCommand *cmd = 0;
// First remove
TQPtrListIterator<TQListViewItem> 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;
TQListViewItem *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, TQListViewItem *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)));
}
}
TQListViewItem *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(TQListViewItem* item, const TQPoint&, int col) {
//kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
if (m_renameItem)
return;
slotStartRename(item, col);
}
void AccountsPanel::slotRenameStarted(TQListViewItem */*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(TQListViewItem *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(TQListViewItem *i) {
AccountItem *item = static_cast<AccountItem*>(i);
if (item == 0)
return;
//kdDebug()<<k_funcinfo<<item->text(0)<<endl;
removeElement(item);
TQListViewItem *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(TQListViewItem */*item*/) {
//kdDebug()<<k_funcinfo<<endl;
m_renameItem = 0;
emit selectionChanged();
}
void AccountsPanel::slotOk() {
}
} //namespace KPlato
#include "kptaccountspanel.moc"