kaddressbook Library API Documentation

customfieldswidget.cpp

00001 /*
00002     This file is part of KAddressbook.
00003     Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qcheckbox.h>
00025 #include <qdatetimeedit.h>
00026 #include <qframe.h>
00027 #include <qlabel.h>
00028 #include <qlayout.h>
00029 #include <qpushbutton.h>
00030 #include <qspinbox.h>
00031 
00032 #include <kaccelmanager.h>
00033 #include <kcombobox.h>
00034 #include <kinputdialog.h>
00035 #include <klineedit.h>
00036 #include <kmessagebox.h>
00037 
00038 #include "addresseeconfig.h"
00039 #include "kabprefs.h"
00040 
00041 #include "customfieldswidget.h"
00042 
00043 
00044 AddFieldDialog::AddFieldDialog( QWidget *parent, const char *name )
00045   : KDialogBase( Plain, i18n( "Add Field" ), Ok | Cancel,
00046                  Ok, parent, name, true, true )
00047 {
00048   QWidget *page = plainPage();
00049 
00050   QGridLayout *layout = new QGridLayout( page, 3, 2, marginHint(), spacingHint() );
00051 
00052   QLabel *label = new QLabel( i18n( "Title:" ), page );
00053   layout->addWidget( label, 0, 0 );
00054 
00055   mTitle = new KLineEdit( page );
00056   label->setBuddy( mTitle );
00057   layout->addWidget( mTitle, 0, 1 );
00058 
00059   label = new QLabel( i18n( "Type:" ), page );
00060   layout->addWidget( label, 1, 0 );
00061 
00062   mType = new KComboBox( page );
00063   label->setBuddy( mType );
00064   layout->addWidget( mType, 1, 1 );
00065 
00066   mGlobal = new QCheckBox( i18n( "Is available for all contacts" ), page );
00067   mGlobal->setChecked( true );
00068   layout->addMultiCellWidget( mGlobal, 2, 2, 0, 1 );
00069 
00070   connect( mTitle, SIGNAL( textChanged( const QString& ) ),
00071            this, SLOT( nameChanged( const QString& ) ) );
00072 
00073   KAcceleratorManager::manage( this );
00074 
00075   mTypeList.append( "text" );
00076   mTypeName.append( i18n( "Text" ) );
00077   mTypeList.append( "integer" );
00078   mTypeName.append( i18n( "Numeric Value" ) );
00079   mTypeList.append( "boolean" );
00080   mTypeName.append( i18n( "Boolean" ) );
00081   mTypeList.append( "date" );
00082   mTypeName.append( i18n( "Date" ) );
00083   mTypeList.append( "time" );
00084   mTypeName.append( i18n( "Time" ) );
00085   mTypeList.append( "datetime" );
00086   mTypeName.append( i18n( "Date & Time" ) );
00087 
00088   for ( uint i = 0; i < mTypeName.count(); ++i )
00089     mType->insertItem( mTypeName[ i ] );
00090 
00091   nameChanged( "" );
00092 
00093   mTitle->setFocus();
00094 }
00095 
00096 QString AddFieldDialog::title() const
00097 {
00098   return mTitle->text();
00099 }
00100 
00101 QString AddFieldDialog::identifier() const
00102 {
00103   QString id = mTitle->text().lower();
00104   return id.replace( ",", "_" ).replace( " ", "_" );
00105 }
00106 
00107 QString AddFieldDialog::type() const
00108 {
00109   return mTypeList[ mType->currentItem() ];
00110 }
00111 
00112 bool AddFieldDialog::isGlobal() const
00113 {
00114   return mGlobal->isChecked();
00115 }
00116 
00117 void AddFieldDialog::nameChanged( const QString &name )
00118 {
00119   enableButton( Ok, !name.isEmpty() );
00120 }
00121 
00122 FieldWidget::FieldWidget( QWidget *parent, const char *name )
00123   : QWidget( parent, name )
00124 {
00125   QVBoxLayout *layout = new QVBoxLayout( this, KDialog::marginHint(),
00126                                          KDialog::spacingHint() );
00127 
00128   mGlobalLayout = new QVBoxLayout( layout, KDialog::spacingHint() );
00129   mGlobalLayout->setAlignment( Qt::AlignTop );
00130 
00131   mSeparator = new QFrame( this );
00132   mSeparator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
00133   mSeparator->hide();
00134   layout->addWidget( mSeparator );
00135 
00136   mLocalLayout = new QVBoxLayout( layout, KDialog::spacingHint() );
00137   mLocalLayout->setAlignment( Qt::AlignTop );
00138 }
00139 
00140 void FieldWidget::addField( const QString &identifier, const QString &title,
00141                             const QString &type, bool isGlobal )
00142 {
00143   FieldRecord record;
00144 
00145   record.mIdentifier = identifier;
00146   record.mTitle = title;
00147   record.mLabel = new QLabel( title + ":", this );
00148   record.mGlobal = isGlobal;
00149   if ( type == "integer" ) {
00150     QSpinBox *wdg = new QSpinBox( 0, 1000, 1, this );
00151     record.mWidget = wdg;
00152     connect( wdg, SIGNAL( valueChanged( int ) ),
00153              this, SIGNAL( changed() ) );
00154   } else if ( type == "boolean" ) {
00155     QCheckBox *wdg = new QCheckBox( this );
00156     record.mWidget = wdg;
00157     connect( wdg, SIGNAL( toggled( bool ) ),
00158              this, SIGNAL( changed() ) );
00159   } else if ( type == "date" ) {
00160     QDateEdit *wdg = new QDateEdit( this );
00161     record.mWidget = wdg;
00162     connect( wdg, SIGNAL( valueChanged( const QDate& ) ),
00163              this, SIGNAL( changed() ) );
00164   } else if ( type == "time" ) {
00165     QTimeEdit *wdg = new QTimeEdit( this );
00166     record.mWidget = wdg;
00167     connect( wdg, SIGNAL( valueChanged( const QTime& ) ),
00168              this, SIGNAL( changed() ) );
00169   } else if ( type == "datetime" ) {
00170     QDateTimeEdit *wdg = new QDateTimeEdit( this );
00171     record.mWidget = wdg;
00172     connect( wdg, SIGNAL( valueChanged( const QDateTime& ) ),
00173              this, SIGNAL( changed() ) );
00174   } else  if ( type == "text" ) {
00175     QLineEdit *wdg = new QLineEdit( this );
00176     record.mWidget = wdg;
00177     connect( wdg, SIGNAL( textChanged( const QString& ) ),
00178              this, SIGNAL( changed() ) );
00179   }
00180 
00181   record.mLabel->show();
00182   record.mWidget->show();
00183 
00184   if ( isGlobal ) {
00185     record.mLayout = new QHBoxLayout( mGlobalLayout );
00186     record.mLayout->addWidget( record.mLabel );
00187     record.mLayout->addWidget( record.mWidget, Qt::AlignLeft );
00188   } else {
00189     record.mLayout = new QHBoxLayout( mLocalLayout );
00190     record.mLayout->addWidget( record.mLabel );
00191     record.mLayout->addWidget( record.mWidget, Qt::AlignLeft );
00192     mSeparator->show();
00193   }
00194 
00195   mFieldList.append( record );
00196 
00197   recalculateLayout();
00198 }
00199 
00200 void FieldWidget::removeField( const QString &identifier )
00201 {
00202   FieldRecordList::Iterator it;
00203   for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
00204     if ( (*it).mIdentifier == identifier ) {
00205       delete (*it).mLabel;
00206       delete (*it).mWidget;
00207       delete (*it).mLayout;
00208 
00209       mFieldList.remove( it );
00210       recalculateLayout();
00211 
00212       bool hasLocal = false;
00213       for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
00214         hasLocal = hasLocal || !(*it).mGlobal;
00215 
00216       if ( !hasLocal )
00217         mSeparator->hide();
00218 
00219       return;
00220     }
00221   }
00222 }
00223 
00224 void FieldWidget::loadContact( KABC::Addressee *addr )
00225 {
00226   QStringList customs = addr->customs();
00227 
00228   QStringList::Iterator it;
00229   for ( it = customs.begin(); it != customs.end(); ++it ) {
00230     QString app, name, value;
00231     splitField( *it, app, name, value );
00232     if ( app != "KADDRESSBOOK" )
00233       continue;
00234 
00235     FieldRecordList::Iterator fieldIt;
00236     for ( fieldIt = mFieldList.begin(); fieldIt != mFieldList.end(); ++fieldIt ) {
00237       if ( (*fieldIt).mIdentifier == name ) {
00238         if ( (*fieldIt).mWidget->isA( "QLineEdit" ) ) {
00239           QLineEdit *wdg = static_cast<QLineEdit*>( (*fieldIt).mWidget );
00240           wdg->setText( value );
00241         } else if ( (*fieldIt).mWidget->isA( "QSpinBox" ) ) {
00242           QSpinBox *wdg = static_cast<QSpinBox*>( (*fieldIt).mWidget );
00243           wdg->setValue( value.toInt() );
00244         } else if ( (*fieldIt).mWidget->isA( "QCheckBox" ) ) {
00245           QCheckBox *wdg = static_cast<QCheckBox*>( (*fieldIt).mWidget );
00246           wdg->setChecked( value == "true" || value == "1" );
00247         } else if ( (*fieldIt).mWidget->isA( "QDateEdit" ) ) {
00248           QDateEdit *wdg = static_cast<QDateEdit*>( (*fieldIt).mWidget );
00249           wdg->setDate( QDate::fromString( value, Qt::ISODate ) );
00250         } else if ( (*fieldIt).mWidget->isA( "QTimeEdit" ) ) {
00251           QTimeEdit *wdg = static_cast<QTimeEdit*>( (*fieldIt).mWidget );
00252           wdg->setTime( QTime::fromString( value, Qt::ISODate ) );
00253         } else if ( (*fieldIt).mWidget->isA( "QDateTimeEdit" ) ) {
00254           QDateTimeEdit *wdg = static_cast<QDateTimeEdit*>( (*fieldIt).mWidget );
00255           wdg->setDateTime( QDateTime::fromString( value, Qt::ISODate ) );
00256         }
00257       }
00258     }
00259   }
00260 }
00261 
00262 void FieldWidget::storeContact( KABC::Addressee *addr )
00263 {
00264   FieldRecordList::Iterator it;
00265   for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
00266     QString value;
00267     if ( (*it).mWidget->isA( "QLineEdit" ) ) {
00268       QLineEdit *wdg = static_cast<QLineEdit*>( (*it).mWidget );
00269       value = wdg->text();
00270     } else if ( (*it).mWidget->isA( "QSpinBox" ) ) {
00271       QSpinBox *wdg = static_cast<QSpinBox*>( (*it).mWidget );
00272       value = QString::number( wdg->value() );
00273     } else if ( (*it).mWidget->isA( "QCheckBox" ) ) {
00274       QCheckBox *wdg = static_cast<QCheckBox*>( (*it).mWidget );
00275       value = ( wdg->isChecked() ? "true" : "false" );
00276     } else if ( (*it).mWidget->isA( "QDateEdit" ) ) {
00277       QDateEdit *wdg = static_cast<QDateEdit*>( (*it).mWidget );
00278       value = wdg->date().toString( Qt::ISODate );
00279     } else if ( (*it).mWidget->isA( "QTimeEdit" ) ) {
00280       QTimeEdit *wdg = static_cast<QTimeEdit*>( (*it).mWidget );
00281       value = wdg->time().toString( Qt::ISODate );
00282     } else if ( (*it).mWidget->isA( "QDateTimeEdit" ) ) {
00283       QDateTimeEdit *wdg = static_cast<QDateTimeEdit*>( (*it).mWidget );
00284       value = wdg->dateTime().toString( Qt::ISODate );
00285     }
00286 
00287     if ( value.isEmpty() )
00288       addr->removeCustom( "KADDRESSBOOK", (*it).mIdentifier );
00289     else
00290       addr->insertCustom( "KADDRESSBOOK", (*it).mIdentifier, value );
00291   }
00292 }
00293 
00294 void FieldWidget::removeLocalFields()
00295 {
00296   FieldRecordList::Iterator it;
00297   for ( it = mFieldList.begin(); it != mFieldList.end(); ++it ) {
00298     if ( !(*it).mGlobal ) {
00299       delete (*it).mLabel;
00300       delete (*it).mWidget;
00301       delete (*it).mLayout;
00302 
00303       it = mFieldList.remove( it );
00304       it--;
00305       recalculateLayout();
00306     }
00307   }
00308 }
00309 
00310 void FieldWidget::recalculateLayout()
00311 {
00312   int maxWidth = 0;
00313 
00314   FieldRecordList::Iterator it;
00315   for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
00316     maxWidth = QMAX( maxWidth, (*it).mLabel->minimumSizeHint().width() );
00317 
00318   for ( it = mFieldList.begin(); it != mFieldList.end(); ++it )
00319     (*it).mLabel->setMinimumWidth( maxWidth );
00320 }
00321 
00322 CustomFieldsWidget::CustomFieldsWidget( KABC::AddressBook *ab,
00323                                         QWidget *parent, const char *name )
00324   : KAB::ContactEditorWidget( ab, parent, name )
00325 {
00326   initGUI();
00327 
00328   connect( mAddButton, SIGNAL( clicked() ), this, SLOT( addField() ) );
00329   connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( removeField() ) );
00330 
00331   connect( mFieldWidget, SIGNAL( changed() ), this, SLOT( setModified() ) );
00332 }
00333 
00334 void CustomFieldsWidget::loadContact( KABC::Addressee *addr )
00335 {
00336   mAddressee = *addr;
00337 
00338   mFieldWidget->removeLocalFields();
00339 
00340   AddresseeConfig addrConfig( mAddressee );
00341   QStringList fields = addrConfig.customFields();
00342 
00343   if ( !fields.isEmpty() ) {
00344     for ( uint i = 0; i < fields.count(); i += 3 ) {
00345       mFieldWidget->addField( fields[ i ], fields[ i + 1 ],
00346                               fields[ i + 2 ] , false );
00347       mRemoveButton->setEnabled( true );
00348     }
00349   }
00350 
00351   mFieldWidget->loadContact( addr );
00352 }
00353 
00354 void CustomFieldsWidget::storeContact( KABC::Addressee *addr )
00355 {
00356   mFieldWidget->storeContact( addr );
00357 }
00358 
00359 void CustomFieldsWidget::setReadOnly( bool readOnly )
00360 {
00361   mAddButton->setEnabled( !readOnly );
00362   mRemoveButton->setEnabled( !readOnly && !mFieldWidget->fields().isEmpty() );
00363 }
00364 
00365 void CustomFieldsWidget::addField()
00366 {
00367   AddFieldDialog dlg( this );
00368 
00369   if ( dlg.exec() ) {
00370     FieldRecordList list = mFieldWidget->fields();
00371 
00372     FieldRecordList::Iterator it;
00373     for ( it = list.begin(); it != list.end(); ++it )
00374       if ( (*it).mIdentifier == dlg.identifier() ) {
00375         KMessageBox::sorry( this, i18n( "A field with the same name already exists, please choose another one." ) );
00376         return;
00377       }
00378 
00379     mFieldWidget->addField( dlg.identifier(), dlg.title(),
00380                             dlg.type(), dlg.isGlobal() );
00381 
00382     if ( dlg.isGlobal() ) {
00383       KABPrefs::instance()->mGlobalCustomFields = marshallFields( true );
00384     } else {
00385       AddresseeConfig addrConfig( mAddressee );
00386       addrConfig.setCustomFields( marshallFields( false ) );
00387     }
00388 
00389     mRemoveButton->setEnabled( true );
00390   }
00391 }
00392 
00393 void CustomFieldsWidget::removeField()
00394 {
00395   FieldRecordList list = mFieldWidget->fields();
00396 
00397   QStringList fields;
00398 
00399   FieldRecordList::Iterator it;
00400   for ( it = list.begin(); it != list.end(); ++it )
00401     fields.append( (*it).mTitle );
00402 
00403   bool ok;
00404   QString title = KInputDialog::getItem( i18n( "Remove Field" ),
00405                                          i18n( "Select the field you want to remove:" ),
00406                                          fields, 0, false, &ok, this );
00407 
00408   if ( ok ) {
00409     for ( it = list.begin(); it != list.end(); ++it )
00410       if ( (*it).mTitle == title ) {
00411         mFieldWidget->removeField( (*it).mIdentifier );
00412 
00413         if ( list.count() == 1 )
00414           mRemoveButton->setEnabled( false );
00415 
00416         if ( (*it).mGlobal ) {
00417           KABPrefs::instance()->mGlobalCustomFields = marshallFields( true );
00418         } else {
00419           AddresseeConfig addrConfig( mAddressee );
00420           addrConfig.setCustomFields( marshallFields( false ) );
00421         }
00422 
00423         return;
00424       }
00425   }
00426 }
00427 
00428 void CustomFieldsWidget::initGUI()
00429 {
00430   QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
00431                                          KDialog::spacingHint() );
00432 
00433   mFieldWidget = new FieldWidget( this );
00434   layout->addMultiCellWidget( mFieldWidget, 0, 0, 0, 2 );
00435 
00436   mAddButton = new QPushButton( i18n( "Add Field..." ), this );
00437   layout->addWidget( mAddButton, 1, 1, Qt::AlignRight );
00438 
00439   mRemoveButton = new QPushButton( i18n( "Remove Field..." ), this );
00440   mRemoveButton->setEnabled( false );
00441   layout->addWidget( mRemoveButton, 1, 2, Qt::AlignRight );
00442 
00443   // load global fields
00444   QStringList globalFields = KABPrefs::instance()->mGlobalCustomFields;
00445 
00446   if ( globalFields.isEmpty() )
00447     return;
00448 
00449   for ( uint i = 0; i < globalFields.count(); i += 3 ) {
00450     mFieldWidget->addField( globalFields[ i ], globalFields[ i + 1 ],
00451                             globalFields[ i + 2 ] , true );
00452     mRemoveButton->setEnabled( true );
00453   }
00454 }
00455 
00456 QStringList CustomFieldsWidget::marshallFields( bool global ) const
00457 {
00458   QStringList retval;
00459 
00460   FieldRecordList list = mFieldWidget->fields();
00461   FieldRecordList::Iterator it;
00462   for ( it = list.begin(); it != list.end(); ++it ) {
00463     if ( (*it).mGlobal == global ) {
00464       retval.append( (*it).mIdentifier );
00465       retval.append( (*it).mTitle );
00466 
00467       QString type = "text";
00468       if ( (*it).mWidget->isA( "QSpinBox" ) ) {
00469         type = "integer";
00470       } else if ( (*it).mWidget->isA( "QCheckBox" ) ) {
00471         type = "boolean";
00472       } else if ( (*it).mWidget->isA( "QDateEdit" ) ) {
00473         type = "date";
00474       } else if ( (*it).mWidget->isA( "QTimeEdit" ) ) {
00475         type = "time";
00476       } else if ( (*it).mWidget->isA( "QDateTimeEdit" ) ) {
00477         type = "datetime";
00478       } else if ( (*it).mWidget->isA( "QLineEdit" ) ) {
00479         type = "text";
00480       }
00481 
00482       retval.append( type );
00483     }
00484   }
00485 
00486   return retval;
00487 }
00488 
00489 
00490 void splitField( const QString &str, QString &app, QString &name, QString &value )
00491 {
00492   int colon = str.find( ':' );
00493   if ( colon != -1 ) {
00494     QString tmp = str.left( colon );
00495     value = str.mid( colon + 1 );
00496 
00497     int dash = tmp.find( '-' );
00498     if ( dash != -1 ) {
00499       app = tmp.left( dash );
00500       name = tmp.mid( dash + 1 );
00501     }
00502   }
00503 }
00504 
00505 #include "customfieldswidget.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu May 3 20:21:49 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003