00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <unistd.h>
00024
00025 #include <tqimage.h>
00026 #include <tqlabel.h>
00027 #include <tqlayout.h>
00028 #include <tqobjectlist.h>
00029 #include <tqpixmap.h>
00030 #include <tqpushbutton.h>
00031 #include <tqwhatsthis.h>
00032 #include <tqgroupbox.h>
00033 #include <tqwidgetfactory.h>
00034 #include <tqregexp.h>
00035 #include <tqtimer.h>
00036
00037 #include <tdeaboutdata.h>
00038 #include <kdebug.h>
00039 #include <kdialog.h>
00040 #include <tdeglobal.h>
00041 #include <tdelistview.h>
00042 #include <tdelocale.h>
00043 #include <krun.h>
00044 #include <kstandarddirs.h>
00045 #include <kactivelabel.h>
00046 #include <kdirwatch.h>
00047 #include <tdefiledialog.h>
00048 #include <tdemessagebox.h>
00049 #include <kprocess.h>
00050 #include <tdeio/netaccess.h>
00051
00052 #include "kcmdesignerfields.h"
00053
00054 using namespace KPIM;
00055
00056 class PageItem : public TQCheckListItem
00057 {
00058 public:
00059 PageItem( TQListView *parent, const TQString &path )
00060 : TQCheckListItem( parent, "", TQCheckListItem::CheckBox ),
00061 mPath( path ), mIsActive( false )
00062 {
00063 mName = path.mid( path.findRev( '/' ) + 1 );
00064
00065 TQWidget *wdg = TQWidgetFactory::create( mPath, 0, 0 );
00066 if ( wdg ) {
00067 setText( 0, wdg->caption() );
00068
00069 TQPixmap pm = TQPixmap::grabWidget( wdg );
00070 TQImage img = pm.convertToImage().smoothScale( 300, 300, TQ_ScaleMin );
00071 mPreview = img;
00072
00073 TQObjectList *list = wdg->queryList( TQWIDGET_OBJECT_NAME_STRING );
00074 TQObjectListIt it( *list );
00075
00076 TQMap<TQString, TQString> allowedTypes;
00077 allowedTypes.insert( TQLINEEDIT_OBJECT_NAME_STRING, i18n( "Text" ) );
00078 allowedTypes.insert( TQTEXTEDIT_OBJECT_NAME_STRING, i18n( "Text" ) );
00079 allowedTypes.insert( TQSPINBOX_OBJECT_NAME_STRING, i18n( "Numeric Value" ) );
00080 allowedTypes.insert( TQCHECKBOX_OBJECT_NAME_STRING, i18n( "Boolean" ) );
00081 allowedTypes.insert( TQCOMBOBOX_OBJECT_NAME_STRING, i18n( "Selection" ) );
00082 allowedTypes.insert( TQDATETIMEEDIT_OBJECT_NAME_STRING, i18n( "Date & Time" ) );
00083 allowedTypes.insert( "KLineEdit", i18n( "Text" ) );
00084 allowedTypes.insert( "KDateTimeWidget", i18n( "Date & Time" ) );
00085 allowedTypes.insert( "KDatePicker", i18n( "Date" ) );
00086
00087 while ( it.current() ) {
00088 if ( allowedTypes.find( it.current()->className() ) != allowedTypes.end() ) {
00089 TQString name = it.current()->name();
00090 if ( name.startsWith( "X_" ) ) {
00091 new TQListViewItem( this, name,
00092 allowedTypes[ it.current()->className() ],
00093 it.current()->className(),
00094 TQWhatsThis::textFor( TQT_TQWIDGET( it.current() ) ) );
00095 }
00096 }
00097
00098 ++it;
00099 }
00100
00101 delete list;
00102 }
00103 }
00104
00105 TQString name() const { return mName; }
00106 TQString path() const { return mPath; }
00107
00108 TQPixmap preview()
00109 {
00110 return mPreview;
00111 }
00112
00113 void setIsActive( bool isActive ) { mIsActive = isActive; }
00114 bool isActive() const { return mIsActive; }
00115
00116 protected:
00117 void paintBranches( TQPainter *p, const TQColorGroup & cg, int w, int y, int h )
00118 {
00119 TQListViewItem::paintBranches( p, cg, w, y, h );
00120 }
00121
00122 private:
00123 TQString mName;
00124 TQString mPath;
00125 TQPixmap mPreview;
00126 bool mIsActive;
00127 };
00128
00129 KCMDesignerFields::KCMDesignerFields( TQWidget *parent, const char *name )
00130 : TDECModule( parent, name )
00131 {
00132 TQTimer::singleShot( 0, this, TQT_SLOT( delayedInit() ) );
00133
00134 TDEAboutData *about = new TDEAboutData( I18N_NOOP( "KCMDesignerfields" ),
00135 I18N_NOOP( "TQt Designer Fields Dialog" ),
00136 0, 0, TDEAboutData::License_LGPL,
00137 I18N_NOOP( "(c), 2004 Tobias Koenig" ) );
00138
00139 about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );
00140 about->addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
00141 setAboutData( about );
00142 }
00143
00144 void KCMDesignerFields::delayedInit()
00145 {
00146 kdDebug() << "KCMDesignerFields::delayedInit()" << endl;
00147
00148 initGUI();
00149
00150 connect( mPageView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ),
00151 this, TQT_SLOT( updatePreview( TQListViewItem* ) ) );
00152 connect( mPageView, TQT_SIGNAL( clicked( TQListViewItem* ) ),
00153 this, TQT_SLOT( itemClicked( TQListViewItem* ) ) );
00154
00155 connect( mDeleteButton, TQT_SIGNAL( clicked() ),
00156 this, TQT_SLOT( deleteFile() ) );
00157 connect( mImportButton, TQT_SIGNAL( clicked() ),
00158 this, TQT_SLOT( importFile() ) );
00159 connect( mDesignerButton, TQT_SIGNAL( clicked() ),
00160 this, TQT_SLOT( startDesigner() ) );
00161
00162 load();
00163
00164
00165 KDirWatch *dw = new KDirWatch( TQT_TQOBJECT(this) );
00166 TDEStandardDirs::makeDir(localUiDir());
00167 dw->addDir( localUiDir(), true );
00168 connect( dw, TQT_SIGNAL( created(const TQString&) ), TQT_SLOT( rebuildList() ) );
00169 connect( dw, TQT_SIGNAL( deleted(const TQString&) ), TQT_SLOT( rebuildList() ) );
00170 connect( dw, TQT_SIGNAL( dirty(const TQString&) ), TQT_SLOT( rebuildList() ) );
00171 }
00172
00173 void KCMDesignerFields::deleteFile()
00174 {
00175 TQListViewItem *item = mPageView->selectedItem();
00176 if ( item ) {
00177 PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
00178 if (KMessageBox::warningContinueCancel(this,
00179 i18n( "<qt>Do you really want to delete '<b>%1</b>'?</qt>").arg( pageItem->text(0) ), "", KStdGuiItem::del() )
00180 == KMessageBox::Continue)
00181 TDEIO::NetAccess::del( pageItem->path(), 0 );
00182 }
00183
00184 }
00185
00186 void KCMDesignerFields::importFile()
00187 {
00188 KURL src = KFileDialog::getOpenFileName( TQDir::homeDirPath(), i18n("*.ui|Designer Files"),
00189 this, i18n("Import Page") );
00190 KURL dest = localUiDir();
00191 dest.setFileName(src.fileName());
00192 TDEIO::NetAccess::file_copy( src, dest, -1, true, false, this );
00193
00194 }
00195
00196
00197 void KCMDesignerFields::loadUiFiles()
00198 {
00199 TQStringList list = TDEGlobal::dirs()->findAllResources( "data", uiPath() + "/*.ui", true, true );
00200 for ( TQStringList::iterator it = list.begin(); it != list.end(); ++it ) {
00201 new PageItem( mPageView, *it );
00202 }
00203 }
00204
00205 void KCMDesignerFields::rebuildList()
00206 {
00207 TQStringList ai = saveActivePages();
00208 updatePreview( 0 );
00209 mPageView->clear();
00210 loadUiFiles();
00211 loadActivePages(ai);
00212 }
00213
00214 void KCMDesignerFields::loadActivePages(const TQStringList& ai)
00215 {
00216 TQListViewItemIterator it( mPageView );
00217 while ( it.current() ) {
00218 if ( it.current()->parent() == 0 ) {
00219 PageItem *item = static_cast<PageItem*>( it.current() );
00220 if ( ai.find( item->name() ) != ai.end() ) {
00221 item->setOn( true );
00222 item->setIsActive( true );
00223 }
00224 }
00225
00226 ++it;
00227 }
00228 }
00229
00230 void KCMDesignerFields::load()
00231 {
00232 loadActivePages( readActivePages() );
00233 }
00234
00235 TQStringList KCMDesignerFields::saveActivePages()
00236 {
00237 TQListViewItemIterator it( mPageView, TQListViewItemIterator::Checked |
00238 TQListViewItemIterator::Selectable );
00239
00240 TQStringList activePages;
00241 while ( it.current() ) {
00242 if ( it.current()->parent() == 0 ) {
00243 PageItem *item = static_cast<PageItem*>( it.current() );
00244 activePages.append( item->name() );
00245 }
00246
00247 ++it;
00248 }
00249
00250 return activePages;
00251 }
00252
00253 void KCMDesignerFields::save()
00254 {
00255 writeActivePages( saveActivePages() );
00256 }
00257
00258 void KCMDesignerFields::defaults()
00259 {
00260 }
00261
00262 void KCMDesignerFields::initGUI()
00263 {
00264 TQVBoxLayout *layout = new TQVBoxLayout( this, KDialog::marginHint(),
00265 KDialog::spacingHint() );
00266
00267 bool noDesigner = TDEStandardDirs::findExe("designer").isEmpty();
00268
00269 if ( noDesigner )
00270 {
00271 TQString txt =
00272 i18n("<qt><b>Warning:</b> TQt Designer could not be found. It is probably not "
00273 "installed. You will only be able to import existing designer files.</qt>");
00274 TQLabel *lbl = new TQLabel( txt, this );
00275 layout->addWidget( lbl );
00276 }
00277
00278 TQHBoxLayout *hbox = new TQHBoxLayout( layout, KDialog::spacingHint() );
00279
00280 mPageView = new TDEListView( this );
00281 mPageView->addColumn( i18n( "Available Pages" ) );
00282 mPageView->setRootIsDecorated( true );
00283 mPageView->setAllColumnsShowFocus( true );
00284 mPageView->setFullWidth( true );
00285 hbox->addWidget( mPageView );
00286
00287 TQGroupBox *box = new TQGroupBox(1, Qt::Horizontal, i18n("Preview of Selected Page"), this );
00288
00289 mPagePreview = new TQLabel( box );
00290 mPagePreview->setMinimumWidth( 300 );
00291
00292 mPageDetails = new TQLabel( box );
00293
00294 hbox->addWidget( box );
00295
00296 loadUiFiles();
00297
00298 hbox = new TQHBoxLayout( layout, KDialog::spacingHint() );
00299
00300 TQString cwHowto = i18n("<qt><p>This section allows you to add your own GUI"
00301 " Elements ('<i>Widgets</i>') to store your own values"
00302 " into %1. Proceed as described below:</p>"
00303 "<ol>"
00304 "<li>Click on '<i>Edit with TQt Designer</i>'"
00305 "<li>In the dialog, select '<i>Widget</i>', then click <i>OK</i>"
00306 "<li>Add your widgets to the form"
00307 "<li>Save the file in the directory proposed by TQt Designer"
00308 "<li>Close TQt Designer"
00309 "</ol>"
00310 "<p>In case you already have a designer file (*.ui) located"
00311 " somewhere on your hard disk, simply choose '<i>Import Page</i>'</p>"
00312 "<p><b>Important:</b> The name of each input widget you place within"
00313 " the form must start with '<i>X_</i>'; so if you want the widget to"
00314 " correspond to your custom entry '<i>X-Foo</i>', set the widget's"
00315 " <i>name</i> property to '<i>X_Foo</i>'.</p>"
00316 "<p><b>Important:</b> The widget will edit custom fields with an"
00317 " application name of %2. To change the application name"
00318 " to be edited, set the widget name in TQt Designer.</p></qt>" )
00319 .arg( applicationName(), applicationName() );
00320
00321 KActiveLabel *activeLabel = new KActiveLabel(
00322 i18n( "<a href=\"whatsthis:%1\">How does this work?</a>" ).arg(cwHowto), this );
00323 hbox->addWidget( activeLabel );
00324
00325
00326 activeLabel->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Maximum );
00327
00328 hbox->addStretch( 1 );
00329
00330 mDeleteButton = new TQPushButton( i18n( "Delete Page" ), this);
00331 mDeleteButton->setEnabled( false );
00332 hbox->addWidget( mDeleteButton );
00333 mImportButton = new TQPushButton( i18n( "Import Page..." ), this);
00334 hbox->addWidget( mImportButton );
00335 mDesignerButton = new TQPushButton( i18n( "Edit with TQt Designer..." ), this );
00336 hbox->addWidget( mDesignerButton );
00337
00338 if ( noDesigner )
00339 mDesignerButton->setEnabled( false );
00340
00341
00342
00343 mPageView->show();
00344 box->show();
00345 activeLabel->show();
00346 mDeleteButton->show();
00347 mImportButton->show();
00348 mDesignerButton->show();
00349 }
00350
00351 void KCMDesignerFields::updatePreview( TQListViewItem *item )
00352 {
00353 bool widgetItemSelected = false;
00354
00355 if ( item ) {
00356 if ( item->parent() ) {
00357 TQString details = TQString( "<qt><table>"
00358 "<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>"
00359 "<tr><td align=\"right\"><b>%3</b></td><td>%4</td></tr>"
00360 "<tr><td align=\"right\"><b>%5</b></td><td>%6</td></tr>"
00361 "<tr><td align=\"right\"><b>%7</b></td><td>%8</td></tr>"
00362 "</table></qt>" )
00363 .arg( i18n( "Key:" ) )
00364 .arg( item->text( 0 ).replace("X_","X-") )
00365 .arg( i18n( "Type:" ) )
00366 .arg( item->text( 1 ) )
00367 .arg( i18n( "Classname:" ) )
00368 .arg( item->text( 2 ) )
00369 .arg( i18n( "Description:" ) )
00370 .arg( item->text( 3 ) );
00371
00372 mPageDetails->setText( details );
00373
00374 PageItem *pageItem = static_cast<PageItem*>( item->parent() );
00375 mPagePreview->setPixmap( pageItem->preview() );
00376 } else {
00377 mPageDetails->setText( TQString() );
00378
00379 PageItem *pageItem = static_cast<PageItem*>( item );
00380 mPagePreview->setPixmap( pageItem->preview() );
00381
00382 widgetItemSelected = true;
00383 }
00384
00385 mPagePreview->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
00386 } else {
00387 mPagePreview->setPixmap( TQPixmap() );
00388 mPagePreview->setFrameStyle( 0 );
00389 mPageDetails->setText( TQString() );
00390 }
00391
00392 mDeleteButton->setEnabled( widgetItemSelected );
00393 }
00394
00395 void KCMDesignerFields::itemClicked( TQListViewItem *item )
00396 {
00397 if ( !item || item->parent() != 0 )
00398 return;
00399
00400 PageItem *pageItem = static_cast<PageItem*>( item );
00401
00402 if ( pageItem->isOn() != pageItem->isActive() ) {
00403 emit changed( true );
00404 pageItem->setIsActive( pageItem->isOn() );
00405 }
00406 }
00407
00408 void KCMDesignerFields::startDesigner()
00409 {
00410 TQString cmdLine = "designer";
00411
00412
00413 TQString cepPath = localUiDir();
00414 if( !TDEGlobal::dirs()->exists(cepPath) ) {
00415 TDEIO::NetAccess::mkdir( cepPath, this );
00416 }
00417
00418
00419 chdir(cepPath.local8Bit());
00420
00421 TQListViewItem *item = mPageView->selectedItem();
00422 if ( item ) {
00423 PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
00424 cmdLine += " " + TDEProcess::quote( pageItem->path() );
00425 }
00426
00427 KRun::runCommand( cmdLine );
00428 }
00429
00430 #include "kcmdesignerfields.moc"