kaddressbook Library API Documentation

kcmkabcustomfields.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 <unistd.h> 00025 00026 #include <qimage.h> 00027 #include <qlabel.h> 00028 #include <qlayout.h> 00029 #include <qobjectlist.h> 00030 #include <qpixmap.h> 00031 #include <qpushbutton.h> 00032 #include <qwhatsthis.h> 00033 #include <qgroupbox.h> 00034 #include <qwidgetfactory.h> 00035 #include <qregexp.h> 00036 00037 #include <kaboutdata.h> 00038 #include <kdebug.h> 00039 #include <kdialog.h> 00040 #include <kglobal.h> 00041 #include <klistview.h> 00042 #include <klocale.h> 00043 #include <krun.h> 00044 #include <kstandarddirs.h> 00045 #include <kactivelabel.h> 00046 #include <kdirwatch.h> 00047 #include <kfiledialog.h> 00048 #include <kmessagebox.h> 00049 #include <kio/netaccess.h> 00050 00051 #include "kabprefs.h" 00052 00053 #include "kcmkabcustomfields.h" 00054 00055 extern "C" 00056 { 00057 KCModule *create_kabcustomfields( QWidget *parent, const char * ) { 00058 return new KCMKabCustomFields( parent, "kcmkabcustomfields" ); 00059 } 00060 } 00061 00062 class PageItem : public QCheckListItem 00063 { 00064 public: 00065 PageItem( QListView *parent, const QString &path ) 00066 : QCheckListItem( parent, "", QCheckListItem::CheckBox ), 00067 mPath( path ), mIsActive( false ) 00068 { 00069 mName = path.mid( path.findRev( '/' ) + 1 ); 00070 00071 QWidget *wdg = QWidgetFactory::create( mPath, 0, 0 ); 00072 if ( wdg ) { 00073 setText( 0, wdg->caption() ); 00074 00075 QPixmap pm = QPixmap::grabWidget( wdg ); 00076 QImage img = pm.convertToImage().smoothScale( 300, 300, QImage::ScaleMin ); 00077 mPreview = img; 00078 00079 QObjectList *list = wdg->queryList( "QWidget" ); 00080 QObjectListIt it( *list ); 00081 00082 QMap<QString, QString> allowedTypes; 00083 allowedTypes.insert( "QLineEdit", i18n( "Text" ) ); 00084 allowedTypes.insert( "QTextEdit", i18n( "Text" ) ); 00085 allowedTypes.insert( "QSpinBox", i18n( "Numeric Value" ) ); 00086 allowedTypes.insert( "QCheckBox", i18n( "Boolean" ) ); 00087 allowedTypes.insert( "QComboBox", i18n( "Selection" ) ); 00088 allowedTypes.insert( "QDateTimeEdit", i18n( "Date & Time" ) ); 00089 allowedTypes.insert( "KLineEdit", i18n( "Text" ) ); 00090 allowedTypes.insert( "KDateTimeWidget", i18n( "Date & Time" ) ); 00091 allowedTypes.insert( "KDatePicker", i18n( "Date" ) ); 00092 00093 while ( it.current() ) { 00094 if ( allowedTypes.find( it.current()->className() ) != allowedTypes.end() ) { 00095 QString name = it.current()->name(); 00096 if ( name.startsWith( "X_" ) ) { 00097 new QListViewItem( this, name, 00098 allowedTypes[ it.current()->className() ], 00099 it.current()->className(), 00100 QWhatsThis::textFor( static_cast<QWidget*>( it.current() ) ) ); 00101 } 00102 } 00103 00104 ++it; 00105 } 00106 00107 delete list; 00108 } else 00109 delete wdg; 00110 } 00111 00112 QString name() const { return mName; } 00113 QString path() const { return mPath; } 00114 00115 QPixmap preview() 00116 { 00117 return mPreview; 00118 } 00119 00120 void setIsActive( bool isActive ) { mIsActive = isActive; } 00121 bool isActive() const { return mIsActive; } 00122 00123 protected: 00124 void paintBranches( QPainter *p, const QColorGroup & cg, int w, int y, int h ) 00125 { 00126 QListViewItem::paintBranches( p, cg, w, y, h ); 00127 } 00128 00129 private: 00130 QString mName; 00131 QString mPath; 00132 QPixmap mPreview; 00133 bool mIsActive; 00134 }; 00135 00136 KCMKabCustomFields::KCMKabCustomFields( QWidget *parent, const char *name ) 00137 : KCModule( parent, name ) 00138 { 00139 initGUI(); 00140 00141 connect( mPageView, SIGNAL( selectionChanged( QListViewItem* ) ), 00142 this, SLOT( updatePreview( QListViewItem* ) ) ); 00143 connect( mPageView, SIGNAL( clicked( QListViewItem* ) ), 00144 this, SLOT( itemClicked( QListViewItem* ) ) ); 00145 00146 connect( mDeleteButton, SIGNAL( clicked() ), 00147 this, SLOT( deleteFile() ) ); 00148 connect( mImportButton, SIGNAL( clicked() ), 00149 this, SLOT( importFile() ) ); 00150 connect( mDesignerButton, SIGNAL( clicked() ), 00151 this, SLOT( startDesigner() ) ); 00152 00153 load(); 00154 00155 // Install a dirwatcher that will detect newly created or removed designer files 00156 KDirWatch *dw = new KDirWatch( this ); 00157 dw->addDir( kabLocalDir() + "contacteditorpages", true ); 00158 connect( dw, SIGNAL( created(const QString&) ), SLOT( rebuildList() ) ); 00159 connect( dw, SIGNAL( deleted(const QString&) ), SLOT( rebuildList() ) ); 00160 connect( dw, SIGNAL( dirty(const QString&) ), SLOT( rebuildList() ) ); 00161 00162 } 00163 00164 void KCMKabCustomFields::deleteFile() 00165 { 00166 QListViewItem *item = mPageView->selectedItem(); 00167 if ( item ) { 00168 PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item ); 00169 if (KMessageBox::warningContinueCancel(this, 00170 i18n( "<qt>Do you really want to delete '<b>%1</b>'?</qt>").arg( pageItem->text(0) ), "", KGuiItem( i18n("&Delete"), "editdelete") ) 00171 == KMessageBox::Continue) 00172 KIO::NetAccess::del( pageItem->path(), 0 ); 00173 } 00174 // The actual view refresh will be done automagically by the slots connected to kdirwatch 00175 } 00176 00177 void KCMKabCustomFields::importFile() 00178 { 00179 KURL src = KFileDialog::getOpenFileName( QDir::homeDirPath(), i18n("*.ui|Designer Files"), 00180 this, i18n("Import Page") ); 00181 KURL dest = kabLocalDir() + "contacteditorpages/"; 00182 dest.setFileName(src.fileName()); 00183 KIO::NetAccess::file_copy( src, dest, -1, true, false, this ); 00184 // The actual view refresh will be done automagically by the slots connected to kdirwatch 00185 } 00186 00187 00188 void KCMKabCustomFields::loadUiFiles() 00189 { 00190 QStringList list = KGlobal::dirs()->findAllResources( "data", "kaddressbook/contacteditorpages/*.ui", true, true ); 00191 for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) { 00192 new PageItem( mPageView, *it ); 00193 } 00194 } 00195 00196 void KCMKabCustomFields::rebuildList() 00197 { 00198 QStringList ai = saveActivePages(); 00199 updatePreview( 0 ); 00200 mPageView->clear(); 00201 loadUiFiles(); 00202 loadActivePages(ai); 00203 } 00204 00205 void KCMKabCustomFields::loadActivePages(const QStringList& ai) 00206 { 00207 QListViewItemIterator it( mPageView ); 00208 while ( it.current() ) { 00209 if ( it.current()->parent() == 0 ) { 00210 PageItem *item = static_cast<PageItem*>( it.current() ); 00211 if ( ai.find( item->name() ) != ai.end() ) { 00212 item->setOn( true ); 00213 item->setIsActive( true ); 00214 } 00215 } 00216 00217 ++it; 00218 } 00219 } 00220 00221 void KCMKabCustomFields::load() 00222 { 00223 loadActivePages(KABPrefs::instance()->mAdvancedCustomFields); 00224 } 00225 00226 QStringList KCMKabCustomFields::saveActivePages() 00227 { 00228 QListViewItemIterator it( mPageView, QListViewItemIterator::Checked | 00229 QListViewItemIterator::Selectable ); 00230 00231 QStringList activePages; 00232 while ( it.current() ) { 00233 if ( it.current()->parent() == 0 ) { 00234 PageItem *item = static_cast<PageItem*>( it.current() ); 00235 activePages.append( item->name() ); 00236 } 00237 00238 ++it; 00239 } 00240 00241 return activePages; 00242 } 00243 00244 void KCMKabCustomFields::save() 00245 { 00246 KABPrefs::instance()->mAdvancedCustomFields = saveActivePages(); 00247 KABPrefs::instance()->writeConfig(); 00248 } 00249 00250 void KCMKabCustomFields::defaults() 00251 { 00252 } 00253 00254 void KCMKabCustomFields::initGUI() 00255 { 00256 QVBoxLayout *layout = new QVBoxLayout( this, KDialog::marginHint(), 00257 KDialog::spacingHint() ); 00258 00259 bool noDesigner = KStandardDirs::findExe("designer").isEmpty(); 00260 00261 if ( noDesigner ) 00262 { 00263 QString txt = 00264 i18n("<qt><b>Warning:</b> Qt Designer could not be found. It is probably not " 00265 "installed. You will only be able to import existing designer files!</qt>"); 00266 QLabel *lbl = new QLabel( txt, this ); 00267 layout->addWidget( lbl ); 00268 } 00269 00270 QHBoxLayout *hbox = new QHBoxLayout( layout, KDialog::spacingHint() ); 00271 00272 mPageView = new KListView( this ); 00273 mPageView->addColumn( i18n( "Available Pages" ) ); 00274 mPageView->setRootIsDecorated( true ); 00275 mPageView->setAllColumnsShowFocus( true ); 00276 mPageView->setFullWidth( true ); 00277 hbox->addWidget( mPageView ); 00278 00279 QGroupBox *box = new QGroupBox(1, Qt::Horizontal, i18n("Preview of Selected Page"), this ); 00280 00281 mPagePreview = new QLabel( box ); 00282 mPagePreview->setMinimumWidth( 300 ); 00283 00284 mPageDetails = new QLabel( box ); 00285 00286 hbox->addWidget( box ); 00287 00288 loadUiFiles(); 00289 00290 hbox = new QHBoxLayout( layout, KDialog::spacingHint() ); 00291 00292 QString cwHowto = i18n("<qt><p>This section allows you to add your own GUI" 00293 " Elements ('<i>Widgets</i>') to store your own values" 00294 " into the address book. Proceed as described below:</p>" 00295 "<ol>" 00296 "<li>Click on '<i>Edit with Qt Designer</i>'" 00297 "<li>In the dialog, select '<i>Widget</i>', then click <i>OK</i>" 00298 "<li>Add your widgets to the form" 00299 "<li>Save the file in the directory proposed by Qt Designer" 00300 "<li>Close Qt Designer" 00301 "</ol>" 00302 "<p>In case you already have a designer file (*.ui) located" 00303 " somewhere on your hard disk, simply choose '<i>Import Page</i>'</p>" 00304 "<p><b>Important:</b> The name of each input widget you place within" 00305 " the form must start with '<i>X_</i>'; so if you want the widget to" 00306 " correspond to your custom entry '<i>X-Foo</i>', set the widget's" 00307 " <i>name</i> property to '<i>X_Foo</i>'.</p>" 00308 "<p><b>Important:</b> The widget will edit custom fields with an" 00309 " application name of KADDRESSBOOK. To change the application name" 00310 " to be edited, set the widget name in Qt Designer.</p></qt>" ); 00311 00312 KActiveLabel *activeLabel = new KActiveLabel( 00313 i18n( "<a href=\"whatsthis:%1\">How does this work?</a>" ).arg(cwHowto), this ); 00314 hbox->addWidget( activeLabel ); 00315 00316 // ### why is this needed? Looks like a KActiveLabel bug... 00317 activeLabel->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ); 00318 00319 hbox->addStretch( 1 ); 00320 00321 mDeleteButton = new QPushButton( i18n( "Delete Page" ), this); 00322 mDeleteButton->setEnabled( false ); 00323 hbox->addWidget( mDeleteButton ); 00324 mImportButton = new QPushButton( i18n( "Import Page..." ), this); 00325 hbox->addWidget( mImportButton ); 00326 mDesignerButton = new QPushButton( i18n( "Edit with Qt Designer..." ), this ); 00327 hbox->addWidget( mDesignerButton ); 00328 00329 if ( noDesigner ) 00330 mDesignerButton->setEnabled( false ); 00331 } 00332 00333 void KCMKabCustomFields::updatePreview( QListViewItem *item ) 00334 { 00335 bool widgetItemSelected = false; 00336 00337 if ( item ) { 00338 if ( item->parent() ) { 00339 QString details = QString( "<qt><table>" 00340 "<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>" 00341 "<tr><td align=\"right\"><b>%3</b></td><td>%4</td></tr>" 00342 "<tr><td align=\"right\"><b>%5</b></td><td>%6</td></tr>" 00343 "<tr><td align=\"right\"><b>%7</b></td><td>%8</td></tr>" 00344 "</table></qt>" ) 00345 .arg( i18n( "vCard key:" ) ) 00346 .arg( item->text( 0 ).replace("X_","X-") ) 00347 .arg( i18n( "Type:" ) ) 00348 .arg( item->text( 1 ) ) 00349 .arg( i18n( "Classname:" ) ) 00350 .arg( item->text( 2 ) ) 00351 .arg( i18n( "Description:" ) ) 00352 .arg( item->text( 3 ) ); 00353 00354 mPageDetails->setText( details ); 00355 00356 PageItem *pageItem = static_cast<PageItem*>( item->parent() ); 00357 mPagePreview->setPixmap( pageItem->preview() ); 00358 } else { 00359 mPageDetails->setText( QString::null ); 00360 00361 PageItem *pageItem = static_cast<PageItem*>( item ); 00362 mPagePreview->setPixmap( pageItem->preview() ); 00363 00364 widgetItemSelected = true; 00365 } 00366 00367 mPagePreview->setFrameStyle( QFrame::Panel | QFrame::Sunken ); 00368 } else { 00369 mPagePreview->setPixmap( QPixmap() ); 00370 mPagePreview->setFrameStyle( 0 ); 00371 mPageDetails->setText( QString::null ); 00372 } 00373 00374 mDeleteButton->setEnabled( widgetItemSelected ); 00375 } 00376 00377 void KCMKabCustomFields::itemClicked( QListViewItem *item ) 00378 { 00379 if ( !item || item->parent() != 0 ) 00380 return; 00381 00382 PageItem *pageItem = static_cast<PageItem*>( item ); 00383 00384 if ( pageItem->isOn() != pageItem->isActive() ) { 00385 emit changed( true ); 00386 pageItem->setIsActive( pageItem->isOn() ); 00387 } 00388 } 00389 00390 QString KCMKabCustomFields::kabLocalDir() 00391 { 00392 QStringList kabdirs = locateLocal("data", "kaddressbook/"); 00393 return kabdirs.grep( QRegExp( "^"+KGlobal::dirs()->localkdedir() ) ).first(); 00394 } 00395 00396 void KCMKabCustomFields::startDesigner() 00397 { 00398 QString cmdLine = "designer"; 00399 00400 // check if path exists and create one if not. 00401 QString cepPath = kabLocalDir() +"contacteditorpages"; 00402 if( !KGlobal::dirs()->exists(cepPath) ) { 00403 KIO::NetAccess::mkdir( cepPath, this ); 00404 } 00405 00406 // finnally jump there 00407 chdir(cepPath.local8Bit()); 00408 00409 QListViewItem *item = mPageView->selectedItem(); 00410 if ( item ) { 00411 PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item ); 00412 cmdLine += " " + pageItem->path(); 00413 } 00414 00415 KRun::runCommand( cmdLine ); 00416 } 00417 00418 const KAboutData* KCMKabCustomFields::aboutData() const 00419 { 00420 KAboutData *about = new KAboutData( I18N_NOOP( "kcmkabcustomfields" ), 00421 I18N_NOOP( "KAddressBook Custom Fields Dialog" ), 00422 0, 0, KAboutData::License_GPL, 00423 I18N_NOOP( "(c), 2004 Tobias Koenig" ) ); 00424 00425 about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" ); 00426 00427 return about; 00428 } 00429 00430 #include "kcmkabcustomfields.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:37 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003