From 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- libkdepim/kcmdesignerfields.cpp | 429 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 429 insertions(+) create mode 100644 libkdepim/kcmdesignerfields.cpp (limited to 'libkdepim/kcmdesignerfields.cpp') diff --git a/libkdepim/kcmdesignerfields.cpp b/libkdepim/kcmdesignerfields.cpp new file mode 100644 index 000000000..8e18efc47 --- /dev/null +++ b/libkdepim/kcmdesignerfields.cpp @@ -0,0 +1,429 @@ +/* + This file is part of libkdepim. + + Copyright (c) 2004 Tobias Koenig + Copyright (c) 2004 Cornelius Schumacher + + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcmdesignerfields.h" + +using namespace KPIM; + +class PageItem : public QCheckListItem +{ + public: + PageItem( QListView *parent, const QString &path ) + : QCheckListItem( parent, "", QCheckListItem::CheckBox ), + mPath( path ), mIsActive( false ) + { + mName = path.mid( path.findRev( '/' ) + 1 ); + + QWidget *wdg = QWidgetFactory::create( mPath, 0, 0 ); + if ( wdg ) { + setText( 0, wdg->caption() ); + + QPixmap pm = QPixmap::grabWidget( wdg ); + QImage img = pm.convertToImage().smoothScale( 300, 300, QImage::ScaleMin ); + mPreview = img; + + QObjectList *list = wdg->queryList( "QWidget" ); + QObjectListIt it( *list ); + + QMap allowedTypes; + allowedTypes.insert( "QLineEdit", i18n( "Text" ) ); + allowedTypes.insert( "QTextEdit", i18n( "Text" ) ); + allowedTypes.insert( "QSpinBox", i18n( "Numeric Value" ) ); + allowedTypes.insert( "QCheckBox", i18n( "Boolean" ) ); + allowedTypes.insert( "QComboBox", i18n( "Selection" ) ); + allowedTypes.insert( "QDateTimeEdit", 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() ) { + QString name = it.current()->name(); + if ( name.startsWith( "X_" ) ) { + new QListViewItem( this, name, + allowedTypes[ it.current()->className() ], + it.current()->className(), + QWhatsThis::textFor( static_cast( it.current() ) ) ); + } + } + + ++it; + } + + delete list; + } + } + + QString name() const { return mName; } + QString path() const { return mPath; } + + QPixmap preview() + { + return mPreview; + } + + void setIsActive( bool isActive ) { mIsActive = isActive; } + bool isActive() const { return mIsActive; } + + protected: + void paintBranches( QPainter *p, const QColorGroup & cg, int w, int y, int h ) + { + QListViewItem::paintBranches( p, cg, w, y, h ); + } + + private: + QString mName; + QString mPath; + QPixmap mPreview; + bool mIsActive; +}; + +KCMDesignerFields::KCMDesignerFields( QWidget *parent, const char *name ) + : KCModule( parent, name ) +{ + QTimer::singleShot( 0, this, SLOT( delayedInit() ) ); + + KAboutData *about = new KAboutData( I18N_NOOP( "KCMDesignerfields" ), + I18N_NOOP( "Qt 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, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( updatePreview( QListViewItem* ) ) ); + connect( mPageView, SIGNAL( clicked( QListViewItem* ) ), + this, SLOT( itemClicked( QListViewItem* ) ) ); + + connect( mDeleteButton, SIGNAL( clicked() ), + this, SLOT( deleteFile() ) ); + connect( mImportButton, SIGNAL( clicked() ), + this, SLOT( importFile() ) ); + connect( mDesignerButton, SIGNAL( clicked() ), + this, SLOT( startDesigner() ) ); + + load(); + + // Install a dirwatcher that will detect newly created or removed designer files + KDirWatch *dw = new KDirWatch( this ); + dw->addDir( localUiDir(), true ); + connect( dw, SIGNAL( created(const QString&) ), SLOT( rebuildList() ) ); + connect( dw, SIGNAL( deleted(const QString&) ), SLOT( rebuildList() ) ); + connect( dw, SIGNAL( dirty(const QString&) ), SLOT( rebuildList() ) ); +} + +void KCMDesignerFields::deleteFile() +{ + QListViewItem *item = mPageView->selectedItem(); + if ( item ) { + PageItem *pageItem = static_cast( item->parent() ? item->parent() : item ); + if (KMessageBox::warningContinueCancel(this, + i18n( "Do you really want to delete '%1'?").arg( 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( QDir::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() +{ + QStringList list = KGlobal::dirs()->findAllResources( "data", uiPath() + "/*.ui", true, true ); + for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) { + new PageItem( mPageView, *it ); + } +} + +void KCMDesignerFields::rebuildList() +{ + QStringList ai = saveActivePages(); + updatePreview( 0 ); + mPageView->clear(); + loadUiFiles(); + loadActivePages(ai); +} + +void KCMDesignerFields::loadActivePages(const QStringList& ai) +{ + QListViewItemIterator it( mPageView ); + while ( it.current() ) { + if ( it.current()->parent() == 0 ) { + PageItem *item = static_cast( it.current() ); + if ( ai.find( item->name() ) != ai.end() ) { + item->setOn( true ); + item->setIsActive( true ); + } + } + + ++it; + } +} + +void KCMDesignerFields::load() +{ + loadActivePages( readActivePages() ); +} + +QStringList KCMDesignerFields::saveActivePages() +{ + QListViewItemIterator it( mPageView, QListViewItemIterator::Checked | + QListViewItemIterator::Selectable ); + + QStringList activePages; + while ( it.current() ) { + if ( it.current()->parent() == 0 ) { + PageItem *item = static_cast( it.current() ); + activePages.append( item->name() ); + } + + ++it; + } + + return activePages; +} + +void KCMDesignerFields::save() +{ + writeActivePages( saveActivePages() ); +} + +void KCMDesignerFields::defaults() +{ +} + +void KCMDesignerFields::initGUI() +{ + QVBoxLayout *layout = new QVBoxLayout( this, KDialog::marginHint(), + KDialog::spacingHint() ); + + bool noDesigner = KStandardDirs::findExe("designer").isEmpty(); + + if ( noDesigner ) + { + QString txt = + i18n("Warning: Qt Designer could not be found. It is probably not " + "installed. You will only be able to import existing designer files."); + QLabel *lbl = new QLabel( txt, this ); + layout->addWidget( lbl ); + } + + QHBoxLayout *hbox = new QHBoxLayout( layout, KDialog::spacingHint() ); + + mPageView = new KListView( this ); + mPageView->addColumn( i18n( "Available Pages" ) ); + mPageView->setRootIsDecorated( true ); + mPageView->setAllColumnsShowFocus( true ); + mPageView->setFullWidth( true ); + hbox->addWidget( mPageView ); + + QGroupBox *box = new QGroupBox(1, Qt::Horizontal, i18n("Preview of Selected Page"), this ); + + mPagePreview = new QLabel( box ); + mPagePreview->setMinimumWidth( 300 ); + + mPageDetails = new QLabel( box ); + + hbox->addWidget( box ); + + loadUiFiles(); + + hbox = new QHBoxLayout( layout, KDialog::spacingHint() ); + + QString cwHowto = i18n("

This section allows you to add your own GUI" + " Elements ('Widgets') to store your own values" + " into %1. Proceed as described below:

" + "
    " + "
  1. Click on 'Edit with Qt Designer'" + "
  2. In the dialog, select 'Widget', then click OK" + "
  3. Add your widgets to the form" + "
  4. Save the file in the directory proposed by Qt Designer" + "
  5. Close Qt Designer" + "
" + "

In case you already have a designer file (*.ui) located" + " somewhere on your hard disk, simply choose 'Import Page'

" + "

Important: The name of each input widget you place within" + " the form must start with 'X_'; so if you want the widget to" + " correspond to your custom entry 'X-Foo', set the widget's" + " name property to 'X_Foo'.

" + "

Important: 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 Qt Designer.

" ) + .arg( applicationName(), applicationName() ); + + KActiveLabel *activeLabel = new KActiveLabel( + i18n( "How does this work?" ).arg(cwHowto), this ); + hbox->addWidget( activeLabel ); + + // ### why is this needed? Looks like a KActiveLabel bug... + activeLabel->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ); + + hbox->addStretch( 1 ); + + mDeleteButton = new QPushButton( i18n( "Delete Page" ), this); + mDeleteButton->setEnabled( false ); + hbox->addWidget( mDeleteButton ); + mImportButton = new QPushButton( i18n( "Import Page..." ), this); + hbox->addWidget( mImportButton ); + mDesignerButton = new QPushButton( i18n( "Edit with Qt 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( QListViewItem *item ) +{ + bool widgetItemSelected = false; + + if ( item ) { + if ( item->parent() ) { + QString details = QString( "" + "" + "" + "" + "" + "
%1%2
%3%4
%5%6
%7%8
" ) + .arg( i18n( "Key:" ) ) + .arg( item->text( 0 ).replace("X_","X-") ) + .arg( i18n( "Type:" ) ) + .arg( item->text( 1 ) ) + .arg( i18n( "Classname:" ) ) + .arg( item->text( 2 ) ) + .arg( i18n( "Description:" ) ) + .arg( item->text( 3 ) ); + + mPageDetails->setText( details ); + + PageItem *pageItem = static_cast( item->parent() ); + mPagePreview->setPixmap( pageItem->preview() ); + } else { + mPageDetails->setText( QString::null ); + + PageItem *pageItem = static_cast( item ); + mPagePreview->setPixmap( pageItem->preview() ); + + widgetItemSelected = true; + } + + mPagePreview->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + } else { + mPagePreview->setPixmap( QPixmap() ); + mPagePreview->setFrameStyle( 0 ); + mPageDetails->setText( QString::null ); + } + + mDeleteButton->setEnabled( widgetItemSelected ); +} + +void KCMDesignerFields::itemClicked( QListViewItem *item ) +{ + if ( !item || item->parent() != 0 ) + return; + + PageItem *pageItem = static_cast( item ); + + if ( pageItem->isOn() != pageItem->isActive() ) { + emit changed( true ); + pageItem->setIsActive( pageItem->isOn() ); + } +} + +void KCMDesignerFields::startDesigner() +{ + QString cmdLine = "designer"; + + // check if path exists and create one if not. + QString cepPath = localUiDir(); + if( !KGlobal::dirs()->exists(cepPath) ) { + KIO::NetAccess::mkdir( cepPath, this ); + } + + // finally jump there + chdir(cepPath.local8Bit()); + + QListViewItem *item = mPageView->selectedItem(); + if ( item ) { + PageItem *pageItem = static_cast( item->parent() ? item->parent() : item ); + cmdLine += " " + KProcess::quote( pageItem->path() ); + } + + KRun::runCommand( cmdLine ); +} + +#include "kcmdesignerfields.moc" -- cgit v1.2.1