00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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
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
00401 QString cepPath = kabLocalDir() +
"contacteditorpages";
00402
if( !KGlobal::dirs()->exists(cepPath) ) {
00403 KIO::NetAccess::mkdir( cepPath,
this );
00404 }
00405
00406
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"