summaryrefslogtreecommitdiffstats
path: root/libtdepim/kcmdesignerfields.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libtdepim/kcmdesignerfields.cpp')
-rw-r--r--libtdepim/kcmdesignerfields.cpp430
1 files changed, 430 insertions, 0 deletions
diff --git a/libtdepim/kcmdesignerfields.cpp b/libtdepim/kcmdesignerfields.cpp
new file mode 100644
index 000000000..870d89ce2
--- /dev/null
+++ b/libtdepim/kcmdesignerfields.cpp
@@ -0,0 +1,430 @@
+/*
+ This file is part of libtdepim.
+
+ Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
+ Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <unistd.h>
+
+#include <tqimage.h>
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqobjectlist.h>
+#include <tqpixmap.h>
+#include <tqpushbutton.h>
+#include <tqwhatsthis.h>
+#include <tqgroupbox.h>
+#include <tqwidgetfactory.h>
+#include <tqregexp.h>
+#include <tqtimer.h>
+
+#include <kaboutdata.h>
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kglobal.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <krun.h>
+#include <kstandarddirs.h>
+#include <kactivelabel.h>
+#include <kdirwatch.h>
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <kio/netaccess.h>
+
+#include "kcmdesignerfields.h"
+
+using namespace KPIM;
+
+class PageItem : public TQCheckListItem
+{
+ public:
+ PageItem( TQListView *parent, const TQString &path )
+ : TQCheckListItem( parent, "", TQCheckListItem::CheckBox ),
+ mPath( path ), mIsActive( false )
+ {
+ mName = path.mid( path.findRev( '/' ) + 1 );
+
+ TQWidget *wdg = TQWidgetFactory::create( mPath, 0, 0 );
+ if ( wdg ) {
+ setText( 0, wdg->caption() );
+
+ TQPixmap pm = TQPixmap::grabWidget( wdg );
+ TQImage img = pm.convertToImage().smoothScale( 300, 300, TQ_ScaleMin );
+ mPreview = img;
+
+ TQObjectList *list = wdg->queryList( TQWIDGET_OBJECT_NAME_STRING );
+ TQObjectListIt it( *list );
+
+ TQMap<TQString, TQString> allowedTypes;
+ allowedTypes.insert( TQLINEEDIT_OBJECT_NAME_STRING, i18n( "Text" ) );
+ allowedTypes.insert( TQTEXTEDIT_OBJECT_NAME_STRING, i18n( "Text" ) );
+ allowedTypes.insert( TQSPINBOX_OBJECT_NAME_STRING, i18n( "Numeric Value" ) );
+ allowedTypes.insert( TQCHECKBOX_OBJECT_NAME_STRING, i18n( "Boolean" ) );
+ allowedTypes.insert( TQCOMBOBOX_OBJECT_NAME_STRING, i18n( "Selection" ) );
+ allowedTypes.insert( TQDATETIMEEDIT_OBJECT_NAME_STRING, i18n( "Date & Time" ) );
+ allowedTypes.insert( "KLineEdit", i18n( "Text" ) );
+ allowedTypes.insert( "KDateTimeWidget", i18n( "Date & Time" ) );
+ allowedTypes.insert( "KDatePicker", i18n( "Date" ) );
+
+ while ( it.current() ) {
+ if ( allowedTypes.find( it.current()->className() ) != allowedTypes.end() ) {
+ TQString name = it.current()->name();
+ if ( name.startsWith( "X_" ) ) {
+ new TQListViewItem( this, name,
+ allowedTypes[ it.current()->className() ],
+ it.current()->className(),
+ TQWhatsThis::textFor( TQT_TQWIDGET( it.current() ) ) );
+ }
+ }
+
+ ++it;
+ }
+
+ delete list;
+ }
+ }
+
+ TQString name() const { return mName; }
+ TQString path() const { return mPath; }
+
+ TQPixmap preview()
+ {
+ return mPreview;
+ }
+
+ void setIsActive( bool isActive ) { mIsActive = isActive; }
+ bool isActive() const { return mIsActive; }
+
+ protected:
+ void paintBranches( TQPainter *p, const TQColorGroup & cg, int w, int y, int h )
+ {
+ TQListViewItem::paintBranches( p, cg, w, y, h );
+ }
+
+ private:
+ TQString mName;
+ TQString mPath;
+ TQPixmap mPreview;
+ bool mIsActive;
+};
+
+KCMDesignerFields::KCMDesignerFields( TQWidget *parent, const char *name )
+ : KCModule( parent, name )
+{
+ TQTimer::singleShot( 0, this, TQT_SLOT( delayedInit() ) );
+
+ KAboutData *about = new KAboutData( I18N_NOOP( "KCMDesignerfields" ),
+ I18N_NOOP( "TQt Designer Fields Dialog" ),
+ 0, 0, KAboutData::License_LGPL,
+ I18N_NOOP( "(c), 2004 Tobias Koenig" ) );
+
+ about->addAuthor( "Tobias Koenig", 0, "tokoe@kde.org" );
+ about->addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" );
+ setAboutData( about );
+}
+
+void KCMDesignerFields::delayedInit()
+{
+ kdDebug() << "KCMDesignerFields::delayedInit()" << endl;
+
+ initGUI();
+
+ connect( mPageView, TQT_SIGNAL( selectionChanged( TQListViewItem* ) ),
+ this, TQT_SLOT( updatePreview( TQListViewItem* ) ) );
+ connect( mPageView, TQT_SIGNAL( clicked( TQListViewItem* ) ),
+ this, TQT_SLOT( itemClicked( TQListViewItem* ) ) );
+
+ connect( mDeleteButton, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( deleteFile() ) );
+ connect( mImportButton, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( importFile() ) );
+ connect( mDesignerButton, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( startDesigner() ) );
+
+ load();
+
+ // Install a dirwatcher that will detect newly created or removed designer files
+ KDirWatch *dw = new KDirWatch( TQT_TQOBJECT(this) );
+ KStandardDirs::makeDir(localUiDir());
+ dw->addDir( localUiDir(), true );
+ connect( dw, TQT_SIGNAL( created(const TQString&) ), TQT_SLOT( rebuildList() ) );
+ connect( dw, TQT_SIGNAL( deleted(const TQString&) ), TQT_SLOT( rebuildList() ) );
+ connect( dw, TQT_SIGNAL( dirty(const TQString&) ), TQT_SLOT( rebuildList() ) );
+}
+
+void KCMDesignerFields::deleteFile()
+{
+ TQListViewItem *item = mPageView->selectedItem();
+ if ( item ) {
+ PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
+ if (KMessageBox::warningContinueCancel(this,
+ i18n( "<qt>Do you really want to delete '<b>%1</b>'?</qt>").tqarg( pageItem->text(0) ), "", KStdGuiItem::del() )
+ == KMessageBox::Continue)
+ KIO::NetAccess::del( pageItem->path(), 0 );
+ }
+ // The actual view refresh will be done automagically by the slots connected to kdirwatch
+}
+
+void KCMDesignerFields::importFile()
+{
+ KURL src = KFileDialog::getOpenFileName( TQDir::homeDirPath(), i18n("*.ui|Designer Files"),
+ this, i18n("Import Page") );
+ KURL dest = localUiDir();
+ dest.setFileName(src.fileName());
+ KIO::NetAccess::file_copy( src, dest, -1, true, false, this );
+ // The actual view refresh will be done automagically by the slots connected to kdirwatch
+}
+
+
+void KCMDesignerFields::loadUiFiles()
+{
+ TQStringList list = KGlobal::dirs()->findAllResources( "data", uiPath() + "/*.ui", true, true );
+ for ( TQStringList::iterator it = list.begin(); it != list.end(); ++it ) {
+ new PageItem( mPageView, *it );
+ }
+}
+
+void KCMDesignerFields::rebuildList()
+{
+ TQStringList ai = saveActivePages();
+ updatePreview( 0 );
+ mPageView->clear();
+ loadUiFiles();
+ loadActivePages(ai);
+}
+
+void KCMDesignerFields::loadActivePages(const TQStringList& ai)
+{
+ TQListViewItemIterator it( mPageView );
+ while ( it.current() ) {
+ if ( it.current()->parent() == 0 ) {
+ PageItem *item = static_cast<PageItem*>( it.current() );
+ if ( ai.find( item->name() ) != ai.end() ) {
+ item->setOn( true );
+ item->setIsActive( true );
+ }
+ }
+
+ ++it;
+ }
+}
+
+void KCMDesignerFields::load()
+{
+ loadActivePages( readActivePages() );
+}
+
+TQStringList KCMDesignerFields::saveActivePages()
+{
+ TQListViewItemIterator it( mPageView, TQListViewItemIterator::Checked |
+ TQListViewItemIterator::Selectable );
+
+ TQStringList activePages;
+ while ( it.current() ) {
+ if ( it.current()->parent() == 0 ) {
+ PageItem *item = static_cast<PageItem*>( it.current() );
+ activePages.append( item->name() );
+ }
+
+ ++it;
+ }
+
+ return activePages;
+}
+
+void KCMDesignerFields::save()
+{
+ writeActivePages( saveActivePages() );
+}
+
+void KCMDesignerFields::defaults()
+{
+}
+
+void KCMDesignerFields::initGUI()
+{
+ TQVBoxLayout *tqlayout = new TQVBoxLayout( this, KDialog::marginHint(),
+ KDialog::spacingHint() );
+
+ bool noDesigner = KStandardDirs::findExe("designer").isEmpty();
+
+ if ( noDesigner )
+ {
+ TQString txt =
+ i18n("<qt><b>Warning:</b> TQt Designer could not be found. It is probably not "
+ "installed. You will only be able to import existing designer files.</qt>");
+ TQLabel *lbl = new TQLabel( txt, this );
+ tqlayout->addWidget( lbl );
+ }
+
+ TQHBoxLayout *hbox = new TQHBoxLayout( tqlayout, KDialog::spacingHint() );
+
+ mPageView = new KListView( this );
+ mPageView->addColumn( i18n( "Available Pages" ) );
+ mPageView->setRootIsDecorated( true );
+ mPageView->setAllColumnsShowFocus( true );
+ mPageView->setFullWidth( true );
+ hbox->addWidget( mPageView );
+
+ TQGroupBox *box = new TQGroupBox(1, Qt::Horizontal, i18n("Preview of Selected Page"), this );
+
+ mPagePreview = new TQLabel( box );
+ mPagePreview->setMinimumWidth( 300 );
+
+ mPageDetails = new TQLabel( box );
+
+ hbox->addWidget( box );
+
+ loadUiFiles();
+
+ hbox = new TQHBoxLayout( tqlayout, KDialog::spacingHint() );
+
+ TQString cwHowto = i18n("<qt><p>This section allows you to add your own GUI"
+ " Elements ('<i>Widgets</i>') to store your own values"
+ " into %1. Proceed as described below:</p>"
+ "<ol>"
+ "<li>Click on '<i>Edit with TQt Designer</i>'"
+ "<li>In the dialog, select '<i>Widget</i>', then click <i>OK</i>"
+ "<li>Add your widgets to the form"
+ "<li>Save the file in the directory proposed by TQt Designer"
+ "<li>Close TQt Designer"
+ "</ol>"
+ "<p>In case you already have a designer file (*.ui) located"
+ " somewhere on your hard disk, simply choose '<i>Import Page</i>'</p>"
+ "<p><b>Important:</b> The name of each input widget you place within"
+ " the form must start with '<i>X_</i>'; so if you want the widget to"
+ " correspond to your custom entry '<i>X-Foo</i>', set the widget's"
+ " <i>name</i> property to '<i>X_Foo</i>'.</p>"
+ "<p><b>Important:</b> The widget will edit custom fields with an"
+ " application name of %2. To change the application name"
+ " to be edited, set the widget name in TQt Designer.</p></qt>" )
+ .tqarg( applicationName(), applicationName() );
+
+ KActiveLabel *activeLabel = new KActiveLabel(
+ i18n( "<a href=\"whatsthis:%1\">How does this work?</a>" ).tqarg(cwHowto), this );
+ hbox->addWidget( activeLabel );
+
+ // ### why is this needed? Looks like a KActiveLabel bug...
+ activeLabel->tqsetSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Maximum );
+
+ hbox->addStretch( 1 );
+
+ mDeleteButton = new TQPushButton( i18n( "Delete Page" ), this);
+ mDeleteButton->setEnabled( false );
+ hbox->addWidget( mDeleteButton );
+ mImportButton = new TQPushButton( i18n( "Import Page..." ), this);
+ hbox->addWidget( mImportButton );
+ mDesignerButton = new TQPushButton( i18n( "Edit with TQt Designer..." ), this );
+ hbox->addWidget( mDesignerButton );
+
+ if ( noDesigner )
+ mDesignerButton->setEnabled( false );
+
+ // FIXME: Why do I have to call show() for all widgets? A this->show() doesn't
+ // seem to work.
+ mPageView->show();
+ box->show();
+ activeLabel->show();
+ mDeleteButton->show();
+ mImportButton->show();
+ mDesignerButton->show();
+}
+
+void KCMDesignerFields::updatePreview( TQListViewItem *item )
+{
+ bool widgetItemSelected = false;
+
+ if ( item ) {
+ if ( item->parent() ) {
+ TQString details = TQString( "<qt><table>"
+ "<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>"
+ "<tr><td align=\"right\"><b>%3</b></td><td>%4</td></tr>"
+ "<tr><td align=\"right\"><b>%5</b></td><td>%6</td></tr>"
+ "<tr><td align=\"right\"><b>%7</b></td><td>%8</td></tr>"
+ "</table></qt>" )
+ .tqarg( i18n( "Key:" ) )
+ .tqarg( item->text( 0 ).replace("X_","X-") )
+ .tqarg( i18n( "Type:" ) )
+ .tqarg( item->text( 1 ) )
+ .tqarg( i18n( "Classname:" ) )
+ .tqarg( item->text( 2 ) )
+ .tqarg( i18n( "Description:" ) )
+ .tqarg( item->text( 3 ) );
+
+ mPageDetails->setText( details );
+
+ PageItem *pageItem = static_cast<PageItem*>( item->parent() );
+ mPagePreview->setPixmap( pageItem->preview() );
+ } else {
+ mPageDetails->setText( TQString() );
+
+ PageItem *pageItem = static_cast<PageItem*>( item );
+ mPagePreview->setPixmap( pageItem->preview() );
+
+ widgetItemSelected = true;
+ }
+
+ mPagePreview->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
+ } else {
+ mPagePreview->setPixmap( TQPixmap() );
+ mPagePreview->setFrameStyle( 0 );
+ mPageDetails->setText( TQString() );
+ }
+
+ mDeleteButton->setEnabled( widgetItemSelected );
+}
+
+void KCMDesignerFields::itemClicked( TQListViewItem *item )
+{
+ if ( !item || item->parent() != 0 )
+ return;
+
+ PageItem *pageItem = static_cast<PageItem*>( item );
+
+ if ( pageItem->isOn() != pageItem->isActive() ) {
+ emit changed( true );
+ pageItem->setIsActive( pageItem->isOn() );
+ }
+}
+
+void KCMDesignerFields::startDesigner()
+{
+ TQString cmdLine = "designer";
+
+ // check if path exists and create one if not.
+ TQString cepPath = localUiDir();
+ if( !KGlobal::dirs()->exists(cepPath) ) {
+ KIO::NetAccess::mkdir( cepPath, this );
+ }
+
+ // finally jump there
+ chdir(cepPath.local8Bit());
+
+ TQListViewItem *item = mPageView->selectedItem();
+ if ( item ) {
+ PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
+ cmdLine += " " + KProcess::quote( pageItem->path() );
+ }
+
+ KRun::runCommand( cmdLine );
+}
+
+#include "kcmdesignerfields.moc"