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.
tdepim/kaddressbook/customfieldswidget.cpp

564 lines
19 KiB

/*
This file is part of KAddressbook.
Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
As a special exception, permission is given to link this program
with any edition of TQt, and distribute the resulting executable,
without including the source code for TQt in the source distribution.
*/
#include <tqcheckbox.h>
#include <tqdatetimeedit.h>
#include <tqframe.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqvalidator.h>
#include <tqspinbox.h>
#include <tdeaccelmanager.h>
#include <kcombobox.h>
#include <kinputdialog.h>
#include <klineedit.h>
#include <kmessagebox.h>
#include "addresseeconfig.h"
#include "kabprefs.h"
#include "customfieldswidget.h"
AddFieldDialog::AddFieldDialog( TQWidget *parent, const char *name )
: KDialogBase( Plain, i18n( "Add Field" ), Ok | Cancel,
Ok, parent, name, true, true )
{
TQWidget *page = plainPage();
TQGridLayout *layout = new TQGridLayout( page, 3, 2, marginHint(), spacingHint() );
TQLabel *label = new TQLabel( i18n( "Title:" ), page );
layout->addWidget( label, 0, 0 );
mTitle = new KLineEdit( page );
mTitle->setValidator( new TQRegExpValidator( TQRegExp( "([a-zA-Z]|\\d|-)+" ), TQT_TQOBJECT(mTitle) ) );
label->setBuddy( mTitle );
layout->addWidget( mTitle, 0, 1 );
label = new TQLabel( i18n( "Type:" ), page );
layout->addWidget( label, 1, 0 );
mType = new KComboBox( page );
label->setBuddy( mType );
layout->addWidget( mType, 1, 1 );
mGlobal = new TQCheckBox( i18n( "Is available for all contacts" ), page );
mGlobal->setChecked( true );
layout->addMultiCellWidget( mGlobal, 2, 2, 0, 1 );
connect( mTitle, TQT_SIGNAL( textChanged( const TQString& ) ),
this, TQT_SLOT( nameChanged( const TQString& ) ) );
TDEAcceleratorManager::manage( this );
mTypeList.append( "text" );
mTypeName.append( i18n( "Text" ) );
mTypeList.append( "integer" );
mTypeName.append( i18n( "Numeric Value" ) );
mTypeList.append( "boolean" );
mTypeName.append( i18n( "Boolean" ) );
mTypeList.append( "date" );
mTypeName.append( i18n( "Date" ) );
mTypeList.append( "time" );
mTypeName.append( i18n( "Time" ) );
mTypeList.append( "datetime" );
mTypeName.append( i18n( "Date & Time" ) );
for ( uint i = 0; i < mTypeName.count(); ++i )
mType->insertItem( mTypeName[ i ] );
nameChanged( "" );
mTitle->setFocus();
}
TQString AddFieldDialog::title() const
{
return mTitle->text();
}
TQString AddFieldDialog::identifier() const
{
TQString id = mTitle->text().lower();
return id.replace( ",", "_" ).replace( " ", "_" );
}
TQString AddFieldDialog::type() const
{
return mTypeList[ mType->currentItem() ];
}
bool AddFieldDialog::isGlobal() const
{
return mGlobal->isChecked();
}
void AddFieldDialog::nameChanged( const TQString &name )
{
enableButton( Ok, !name.isEmpty() );
}
FieldWidget::FieldWidget( TQWidget *parent, const char *name )
: TQWidget( parent, name )
{
TQVBoxLayout *layout = new TQVBoxLayout( this, KDialog::marginHint(),
KDialog::spacingHint() );
mGlobalLayout = new TQVBoxLayout( layout, KDialog::spacingHint() );
mGlobalLayout->setAlignment( TQt::AlignTop );
mSeparator = new TQFrame( this );
mSeparator->setFrameStyle( TQFrame::HLine | TQFrame::Sunken );
mSeparator->hide();
layout->addWidget( mSeparator );
mLocalLayout = new TQVBoxLayout( layout, KDialog::spacingHint() );
mLocalLayout->setAlignment( TQt::AlignTop );
}
void FieldWidget::addField( const TQString &identifier, const TQString &title,
const TQString &type, bool isGlobal )
{
FieldRecord record;
record.mIdentifier = identifier;
record.mTitle = title;
record.mLabel = new TQLabel( title + ":", this );
record.mGlobal = isGlobal;
if ( type == "integer" ) {
TQSpinBox *wdg = new TQSpinBox( 0, 1000, 1, this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( valueChanged( int ) ),
this, TQT_SIGNAL( changed() ) );
} else if ( type == "boolean" ) {
TQCheckBox *wdg = new TQCheckBox( this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( toggled( bool ) ),
this, TQT_SIGNAL( changed() ) );
} else if ( type == "date" ) {
TQDateEdit *wdg = new TQDateEdit( this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( valueChanged( const TQDate& ) ),
this, TQT_SIGNAL( changed() ) );
} else if ( type == "time" ) {
TQTimeEdit *wdg = new TQTimeEdit( this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( valueChanged( const TQTime& ) ),
this, TQT_SIGNAL( changed() ) );
} else if ( type == "datetime" ) {
TQDateTimeEdit *wdg = new TQDateTimeEdit( this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( valueChanged( const TQDateTime& ) ),
this, TQT_SIGNAL( changed() ) );
} else if ( type == "text" ) {
TQLineEdit *wdg = new TQLineEdit( this );
record.mWidget = wdg;
connect( wdg, TQT_SIGNAL( textChanged( const TQString& ) ),
this, TQT_SIGNAL( changed() ) );
}
record.mLabel->show();
record.mWidget->show();
if ( isGlobal ) {
record.mLayout = new TQHBoxLayout( mGlobalLayout );
record.mLayout->addWidget( record.mLabel );
record.mLayout->addWidget( record.mWidget, TQt::AlignLeft );
} else {
record.mLayout = new TQHBoxLayout( mLocalLayout );
record.mLayout->addWidget( record.mLabel );
record.mLayout->addWidget( record.mWidget, TQt::AlignLeft );
mSeparator->show();
}
mFieldList.append( record );
recalculateLayout();
}
void FieldWidget::removeField( const TQString &identifier )
{
FieldRecordList::Iterator it;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
if ( (*it).mIdentifier == identifier ) {
delete (*it).mLabel;
delete (*it).mWidget;
delete (*it).mLayout;
mFieldList.remove( it );
recalculateLayout();
bool hasLocal = false;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
hasLocal = hasLocal || !(*it).mGlobal;
if ( !hasLocal )
mSeparator->hide();
return;
}
}
}
void FieldWidget::clearFields()
{
FieldRecordList::ConstIterator fieldIt;
for ( fieldIt = mFieldList.begin(); fieldIt != mFieldList.end(); ++fieldIt ) {
if ( (*fieldIt).mWidget->isA( TQLINEEDIT_OBJECT_NAME_STRING ) ) {
TQLineEdit *wdg = static_cast<TQLineEdit*>( (*fieldIt).mWidget );
wdg->setText( TQString() );
} else if ( (*fieldIt).mWidget->isA( TQSPINBOX_OBJECT_NAME_STRING ) ) {
TQSpinBox *wdg = static_cast<TQSpinBox*>( (*fieldIt).mWidget );
wdg->setValue( 0 );
} else if ( (*fieldIt).mWidget->isA( TQCHECKBOX_OBJECT_NAME_STRING ) ) {
TQCheckBox *wdg = static_cast<TQCheckBox*>( (*fieldIt).mWidget );
wdg->setChecked( true );
} else if ( (*fieldIt).mWidget->isA( TQDATEEDIT_OBJECT_NAME_STRING ) ) {
TQDateEdit *wdg = static_cast<TQDateEdit*>( (*fieldIt).mWidget );
wdg->setDate( TQDate::currentDate() );
} else if ( (*fieldIt).mWidget->isA( TQTIMEEDIT_OBJECT_NAME_STRING ) ) {
TQTimeEdit *wdg = static_cast<TQTimeEdit*>( (*fieldIt).mWidget );
wdg->setTime( TQTime::currentTime() );
} else if ( (*fieldIt).mWidget->isA( TQDATETIMEEDIT_OBJECT_NAME_STRING ) ) {
TQDateTimeEdit *wdg = static_cast<TQDateTimeEdit*>( (*fieldIt).mWidget );
wdg->setDateTime( TQDateTime::currentDateTime() );
}
}
}
void FieldWidget::loadContact( KABC::Addressee *addr )
{
const TQStringList customs = addr->customs();
clearFields();
TQStringList::ConstIterator it;
for ( it = customs.begin(); it != customs.end(); ++it ) {
TQString app, name, value;
splitField( *it, app, name, value );
if ( app != "KADDRESSBOOK" )
continue;
FieldRecordList::ConstIterator fieldIt;
for ( fieldIt = mFieldList.begin(); fieldIt != mFieldList.end(); ++fieldIt ) {
if ( (*fieldIt).mIdentifier == name ) {
if ( (*fieldIt).mWidget->isA( TQLINEEDIT_OBJECT_NAME_STRING ) ) {
TQLineEdit *wdg = static_cast<TQLineEdit*>( (*fieldIt).mWidget );
wdg->setText( value );
} else if ( (*fieldIt).mWidget->isA( TQSPINBOX_OBJECT_NAME_STRING ) ) {
TQSpinBox *wdg = static_cast<TQSpinBox*>( (*fieldIt).mWidget );
wdg->setValue( value.toInt() );
} else if ( (*fieldIt).mWidget->isA( TQCHECKBOX_OBJECT_NAME_STRING ) ) {
TQCheckBox *wdg = static_cast<TQCheckBox*>( (*fieldIt).mWidget );
wdg->setChecked( value == "true" || value == "1" );
} else if ( (*fieldIt).mWidget->isA( TQDATEEDIT_OBJECT_NAME_STRING ) ) {
TQDateEdit *wdg = static_cast<TQDateEdit*>( (*fieldIt).mWidget );
wdg->setDate( TQDate::fromString( value, Qt::ISODate ) );
} else if ( (*fieldIt).mWidget->isA( TQTIMEEDIT_OBJECT_NAME_STRING ) ) {
TQTimeEdit *wdg = static_cast<TQTimeEdit*>( (*fieldIt).mWidget );
wdg->setTime( TQTime::fromString( value, Qt::ISODate ) );
} else if ( (*fieldIt).mWidget->isA( TQDATETIMEEDIT_OBJECT_NAME_STRING ) ) {
TQDateTimeEdit *wdg = static_cast<TQDateTimeEdit*>( (*fieldIt).mWidget );
wdg->setDateTime( TQDateTime::fromString( value, Qt::ISODate ) );
}
}
}
}
}
void FieldWidget::setReadOnly( bool readOnly )
{
FieldRecordList::ConstIterator it;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
TQString value;
if ( (*it).mWidget->isA( TQLINEEDIT_OBJECT_NAME_STRING ) ) {
TQLineEdit *wdg = static_cast<TQLineEdit*>( (*it).mWidget );
wdg->setReadOnly(readOnly);
} else if ( (*it).mWidget->isA( TQSPINBOX_OBJECT_NAME_STRING ) ) {
TQSpinBox *wdg = static_cast<TQSpinBox*>( (*it).mWidget );
wdg->setEnabled( !readOnly );
} else if ( (*it).mWidget->isA( TQCHECKBOX_OBJECT_NAME_STRING ) ) {
TQCheckBox *wdg = static_cast<TQCheckBox*>( (*it).mWidget );
wdg->setEnabled( !readOnly );
} else if ( (*it).mWidget->isA( TQDATEEDIT_OBJECT_NAME_STRING ) ) {
TQDateEdit *wdg = static_cast<TQDateEdit*>( (*it).mWidget );
wdg->setEnabled( !readOnly );
} else if ( (*it).mWidget->isA( TQTIMEEDIT_OBJECT_NAME_STRING ) ) {
TQTimeEdit *wdg = static_cast<TQTimeEdit*>( (*it).mWidget );
wdg->setEnabled( !readOnly );
} else if ( (*it).mWidget->isA( TQDATETIMEEDIT_OBJECT_NAME_STRING ) ) {
TQDateTimeEdit *wdg = static_cast<TQDateTimeEdit*>( (*it).mWidget );
wdg->setEnabled( !readOnly );
}
}
}
void FieldWidget::storeContact( KABC::Addressee *addr )
{
FieldRecordList::ConstIterator it;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
TQString value;
if ( (*it).mWidget->isA( TQLINEEDIT_OBJECT_NAME_STRING ) ) {
TQLineEdit *wdg = static_cast<TQLineEdit*>( (*it).mWidget );
value = wdg->text();
} else if ( (*it).mWidget->isA( TQSPINBOX_OBJECT_NAME_STRING ) ) {
TQSpinBox *wdg = static_cast<TQSpinBox*>( (*it).mWidget );
value = TQString::number( wdg->value() );
} else if ( (*it).mWidget->isA( TQCHECKBOX_OBJECT_NAME_STRING ) ) {
TQCheckBox *wdg = static_cast<TQCheckBox*>( (*it).mWidget );
value = ( wdg->isChecked() ? "true" : "false" );
} else if ( (*it).mWidget->isA( TQDATEEDIT_OBJECT_NAME_STRING ) ) {
TQDateEdit *wdg = static_cast<TQDateEdit*>( (*it).mWidget );
value = wdg->date().toString( Qt::ISODate );
} else if ( (*it).mWidget->isA( TQTIMEEDIT_OBJECT_NAME_STRING ) ) {
TQTimeEdit *wdg = static_cast<TQTimeEdit*>( (*it).mWidget );
value = wdg->time().toString( Qt::ISODate );
} else if ( (*it).mWidget->isA( TQDATETIMEEDIT_OBJECT_NAME_STRING ) ) {
TQDateTimeEdit *wdg = static_cast<TQDateTimeEdit*>( (*it).mWidget );
value = wdg->dateTime().toString( Qt::ISODate );
}
if ( value.isEmpty() )
addr->removeCustom( "KADDRESSBOOK", (*it).mIdentifier );
else
addr->insertCustom( "KADDRESSBOOK", (*it).mIdentifier, value );
}
}
void FieldWidget::removeLocalFields()
{
FieldRecordList::Iterator it;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
if ( !(*it).mGlobal ) {
delete (*it).mLabel;
delete (*it).mWidget;
delete (*it).mLayout;
it = mFieldList.remove( it );
it--;
recalculateLayout();
}
}
}
void FieldWidget::recalculateLayout()
{
int maxWidth = 0;
FieldRecordList::ConstIterator it;
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
maxWidth = TQMAX( maxWidth, (*it).mLabel->minimumSizeHint().width() );
for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
(*it).mLabel->setMinimumWidth( maxWidth );
}
CustomFieldsWidget::CustomFieldsWidget( KABC::AddressBook *ab,
TQWidget *parent, const char *name )
: KAB::ContactEditorWidget( ab, parent, name )
{
initGUI();
connect( mAddButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( addField() ) );
connect( mRemoveButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( removeField() ) );
connect( mFieldWidget, TQT_SIGNAL( changed() ), this, TQT_SLOT( setModified() ) );
}
void CustomFieldsWidget::loadContact( KABC::Addressee *addr )
{
mAddressee = *addr;
mFieldWidget->removeLocalFields();
AddresseeConfig addrConfig( mAddressee );
TQStringList fields = addrConfig.customFields();
if ( !fields.isEmpty() ) {
for ( uint i = 0; i < fields.count(); i += 3 ) {
mFieldWidget->addField( fields[ i ], fields[ i + 1 ],
fields[ i + 2 ] , false );
mRemoveButton->setEnabled( true );
}
}
mFieldWidget->loadContact( addr );
}
void CustomFieldsWidget::storeContact( KABC::Addressee *addr )
{
mFieldWidget->storeContact( addr );
}
void CustomFieldsWidget::setReadOnly( bool readOnly )
{
mAddButton->setEnabled( !readOnly );
mRemoveButton->setEnabled( !readOnly && !mFieldWidget->fields().isEmpty() );
mFieldWidget->setReadOnly( readOnly );
}
void CustomFieldsWidget::addField()
{
AddFieldDialog dlg( this );
if ( dlg.exec() ) {
FieldRecordList list = mFieldWidget->fields();
FieldRecordList::ConstIterator it;
for ( it = list.begin(); it != list.end(); ++it )
if ( (*it).mIdentifier == dlg.identifier() ) {
KMessageBox::sorry( this, i18n( "A field with the same name already exists, please choose another one." ) );
return;
}
mFieldWidget->addField( dlg.identifier(), dlg.title(),
dlg.type(), dlg.isGlobal() );
if ( dlg.isGlobal() ) {
KABPrefs::instance()->setGlobalCustomFields( marshallFields( true ) );
} else {
AddresseeConfig addrConfig( mAddressee );
addrConfig.setCustomFields( marshallFields( false ) );
}
mRemoveButton->setEnabled( true );
}
}
void CustomFieldsWidget::removeField()
{
const FieldRecordList list = mFieldWidget->fields();
TQStringList fields;
FieldRecordList::ConstIterator it;
for ( it = list.begin(); it != list.end(); ++it )
fields.append( (*it).mTitle );
bool ok;
TQString title = KInputDialog::getItem( i18n( "Remove Field" ),
i18n( "Select the field you want to remove:" ),
fields, 0, false, &ok, this );
if ( ok ) {
for ( it = list.begin(); it != list.end(); ++it )
if ( (*it).mTitle == title ) {
mFieldWidget->removeField( (*it).mIdentifier );
if ( list.count() == 1 )
mRemoveButton->setEnabled( false );
if ( (*it).mGlobal ) {
KABPrefs::instance()->setGlobalCustomFields( marshallFields( true ) );
} else {
AddresseeConfig addrConfig( mAddressee );
addrConfig.setCustomFields( marshallFields( false ) );
}
return;
}
}
}
void CustomFieldsWidget::initGUI()
{
TQGridLayout *layout = new TQGridLayout( this, 2, 3, KDialog::marginHint(),
KDialog::spacingHint() );
mFieldWidget = new FieldWidget( this );
layout->addMultiCellWidget( mFieldWidget, 0, 0, 0, 2 );
mAddButton = new TQPushButton( i18n( "Add Field..." ), this );
layout->addWidget( mAddButton, 1, 1, TQt::AlignRight );
mRemoveButton = new TQPushButton( i18n( "Remove Field..." ), this );
mRemoveButton->setEnabled( false );
layout->addWidget( mRemoveButton, 1, 2, TQt::AlignRight );
// load global fields
TQStringList globalFields = KABPrefs::instance()->globalCustomFields();
if ( globalFields.isEmpty() )
return;
for ( uint i = 0; i < globalFields.count(); i += 3 ) {
mFieldWidget->addField( globalFields[ i ], globalFields[ i + 1 ],
globalFields[ i + 2 ] , true );
mRemoveButton->setEnabled( true );
}
}
TQStringList CustomFieldsWidget::marshallFields( bool global ) const
{
TQStringList retval;
const FieldRecordList list = mFieldWidget->fields();
FieldRecordList::ConstIterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
if ( (*it).mGlobal == global ) {
retval.append( (*it).mIdentifier );
retval.append( (*it).mTitle );
TQString type = "text";
if ( (*it).mWidget->isA( TQSPINBOX_OBJECT_NAME_STRING ) ) {
type = "integer";
} else if ( (*it).mWidget->isA( TQCHECKBOX_OBJECT_NAME_STRING ) ) {
type = "boolean";
} else if ( (*it).mWidget->isA( TQDATEEDIT_OBJECT_NAME_STRING ) ) {
type = "date";
} else if ( (*it).mWidget->isA( TQTIMEEDIT_OBJECT_NAME_STRING ) ) {
type = "time";
} else if ( (*it).mWidget->isA( TQDATETIMEEDIT_OBJECT_NAME_STRING ) ) {
type = "datetime";
} else if ( (*it).mWidget->isA( TQLINEEDIT_OBJECT_NAME_STRING ) ) {
type = "text";
}
retval.append( type );
}
}
return retval;
}
void splitField( const TQString &str, TQString &app, TQString &name, TQString &value )
{
int colon = str.find( ':' );
if ( colon != -1 ) {
TQString tmp = str.left( colon );
value = str.mid( colon + 1 );
int dash = tmp.find( '-' );
if ( dash != -1 ) {
app = tmp.left( dash );
name = tmp.mid( dash + 1 );
}
}
}
#include "customfieldswidget.moc"