• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

korganizer

  • sources
  • kde-4.12
  • kdepim
  • korganizer
kcmdesignerfields.cpp
Go to the documentation of this file.
1 /*
2  This file is part of KOrganizer.
3 
4  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
5  Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "kcmdesignerfields.h"
24 
25 #include <KAboutData>
26 #include <KDebug>
27 #include <KDirWatch>
28 #include <KFileDialog>
29 #include <KMessageBox>
30 #include <KRun>
31 #include <KShell>
32 #include <KStandardDirs>
33 #include <KIO/Job>
34 #include <KIO/NetAccess>
35 
36 #include <QGroupBox>
37 #include <QHBoxLayout>
38 #include <QHeaderView>
39 #include <QLabel>
40 #include <QPushButton>
41 #include <QTreeWidget>
42 #include <QUiLoader>
43 #include <QWhatsThis>
44 
45 class PageItem : public QTreeWidgetItem
46 {
47  public:
48  PageItem( QTreeWidget *parent, const QString &path )
49  : QTreeWidgetItem( parent ),
50  mPath( path ), mIsActive( false )
51  {
52  setFlags( flags() | Qt::ItemIsUserCheckable );
53  setCheckState( 0, Qt::Unchecked );
54  mName = path.mid( path.lastIndexOf( QLatin1Char('/') ) + 1 );
55 
56  QFile f( mPath );
57  if (!f.open( QFile::ReadOnly ) )
58  return;
59  QUiLoader builder;
60  QWidget *wdg = builder.load( &f, 0 );
61  f.close();
62  if ( wdg ) {
63  setText( 0, wdg->windowTitle() );
64 
65  QPixmap pm = QPixmap::grabWidget( wdg );
66  QImage img = pm.toImage().scaled( 300, 300, Qt::KeepAspectRatio, Qt::SmoothTransformation );
67  mPreview = QPixmap::fromImage(img);
68 
69  QMap<QString, QString> allowedTypes;
70  allowedTypes.insert( QLatin1String("QLineEdit"), i18n( "Text" ) );
71  allowedTypes.insert( QLatin1String("QTextEdit"), i18n( "Text" ) );
72  allowedTypes.insert( QLatin1String("QSpinBox"), i18n( "Numeric Value" ) );
73  allowedTypes.insert( QLatin1String("QCheckBox"), i18n( "Boolean" ) );
74  allowedTypes.insert( QLatin1String("QComboBox"), i18n( "Selection" ) );
75  allowedTypes.insert( QLatin1String("QDateTimeEdit"), i18n( "Date & Time" ) );
76  allowedTypes.insert( QLatin1String("KLineEdit"), i18n( "Text" ) );
77  allowedTypes.insert( QLatin1String("KTextEdit"), i18n( "Text" ) );
78  allowedTypes.insert( QLatin1String("KDateTimeWidget"), i18n( "Date & Time" ) );
79  allowedTypes.insert( QLatin1String("KDatePicker"), i18n( "Date" ) );
80 
81  QList<QWidget*> list = wdg->findChildren<QWidget*>();
82  QWidget *it;
83  Q_FOREACH ( it, list ) {
84  if ( allowedTypes.contains( QLatin1String(it->metaObject()->className()) ) ) {
85  QString name = it->objectName();
86  if ( name.startsWith( QLatin1String( "X_" ) ) ) {
87  new QTreeWidgetItem( this, QStringList()
88  << name
89  << allowedTypes[ QLatin1String(it->metaObject()->className()) ]
90  << QLatin1String(it->metaObject()->className())
91  << it->whatsThis() );
92  }
93  }
94  }
95 
96  }
97  }
98 
99  QString name() const
100  {
101  return mName;
102  }
103 
104  QString path() const
105  {
106  return mPath;
107  }
108 
109  QPixmap preview()
110  {
111  return mPreview;
112  }
113 
114  void setIsActive( bool isActive )
115  {
116  mIsActive = isActive;
117  }
118 
119  bool isActive() const
120  {
121  return mIsActive;
122  }
123 
124  bool isOn() const
125  {
126  return checkState( 0 ) == Qt::Checked;
127  }
128 
129  private:
130  QString mName;
131  QString mPath;
132  QPixmap mPreview;
133  bool mIsActive;
134 };
135 
136 KCMDesignerFields::KCMDesignerFields( const KComponentData &instance, QWidget *parent,
137  const QVariantList &args )
138  : KCModule( instance, parent, args ),
139  mPageView( 0 ),
140  mPagePreview( 0 ),
141  mPageDetails( 0 ),
142  mDeleteButton( 0 ),
143  mImportButton( 0 ),
144  mDesignerButton( 0 )
145 {
146  KAboutData *about = new KAboutData( I18N_NOOP( "KCMDesignerfields" ), 0,
147  ki18n( "Qt Designer Fields Dialog" ),
148  0, KLocalizedString(), KAboutData::License_LGPL,
149  ki18n( "(c), 2004 Tobias Koenig" ) );
150 
151  about->addAuthor( ki18n( "Tobias Koenig" ), KLocalizedString(), "tokoe@kde.org" );
152  about->addAuthor( ki18n( "Cornelius Schumacher" ), KLocalizedString(), "schumacher@kde.org" );
153  setAboutData( about );
154 }
155 
156 void KCMDesignerFields::delayedInit()
157 {
158  kDebug() << "KCMDesignerFields::delayedInit()";
159 
160  initGUI();
161 
162  connect( mPageView, SIGNAL(itemSelectionChanged()),
163  this, SLOT(updatePreview()) );
164  connect( mPageView, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
165  this, SLOT(itemClicked(QTreeWidgetItem*)) );
166 
167  connect( mDeleteButton, SIGNAL(clicked()),
168  this, SLOT(deleteFile()) );
169  connect( mImportButton, SIGNAL(clicked()),
170  this, SLOT(importFile()) );
171  connect( mDesignerButton, SIGNAL(clicked()),
172  this, SLOT(startDesigner()) );
173 
174  load();
175 
176  // Install a dirwatcher that will detect newly created or removed designer files
177  KDirWatch *dw = new KDirWatch( this );
178  KStandardDirs::makeDir( localUiDir() );
179  dw->addDir( localUiDir(), KDirWatch::WatchFiles );
180  connect( dw, SIGNAL(created(QString)), SLOT(rebuildList()) );
181  connect( dw, SIGNAL(deleted(QString)), SLOT(rebuildList()) );
182  connect( dw, SIGNAL(dirty(QString)), SLOT(rebuildList()) );
183 }
184 
185 void KCMDesignerFields::deleteFile()
186 {
187  foreach ( QTreeWidgetItem *item, mPageView->selectedItems() ) {
188  PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
189  if ( KMessageBox::warningContinueCancel(
190  this,
191  i18n( "<qt>Do you really want to delete '<b>%1</b>'?</qt>",
192  pageItem->text(0) ), QString(), KStandardGuiItem::del() ) == KMessageBox::Continue ) {
193  KIO::NetAccess::del( pageItem->path(), 0 );
194  }
195  }
196  // The actual view refresh will be done automagically by the slots connected to kdirwatch
197 }
198 
199 void KCMDesignerFields::importFile()
200 {
201  KUrl src = KFileDialog::getOpenFileName( QDir::homePath(),
202  i18n( "*.ui|Designer Files" ),
203  this, i18n( "Import Page" ) );
204  KUrl dest = localUiDir();
205  QDir().mkpath( localUiDir() );
206  dest.setFileName( src.fileName() );
207  KIO::Job *job = KIO::file_copy( src, dest, -1, KIO::Overwrite );
208  KIO::NetAccess::synchronousRun( job, this );
209 
210  // The actual view refresh will be done automagically by the slots connected to kdirwatch
211 }
212 
213 void KCMDesignerFields::loadUiFiles()
214 {
215  const QStringList list = KGlobal::dirs()->findAllResources( "data", uiPath() + QLatin1String("/*.ui"),
216  KStandardDirs::Recursive |
217  KStandardDirs::NoDuplicates );
218  for ( QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) {
219  new PageItem( mPageView, *it );
220  }
221 }
222 
223 void KCMDesignerFields::rebuildList()
224 {
225  // If nothing is initialized there is no need to do something
226  if ( mPageView ) {
227  QStringList ai = saveActivePages();
228  updatePreview();
229  mPageView->clear();
230  loadUiFiles();
231  loadActivePages(ai);
232  }
233 }
234 
235 void KCMDesignerFields::loadActivePages( const QStringList &ai )
236 {
237  QTreeWidgetItemIterator it( mPageView );
238  while ( *it ) {
239  if ( (*it)->parent() == 0 ) {
240  PageItem *item = static_cast<PageItem*>( *it );
241  if ( ai.contains( item->name() ) ) {
242  item->setCheckState( 0, Qt::Checked );
243  item->setIsActive( true );
244  }
245  }
246 
247  ++it;
248  }
249 }
250 
251 void KCMDesignerFields::load()
252 {
253  // see KCModule::showEvent()
254  if ( !mPageView ) {
255  delayedInit();
256  }
257  loadActivePages( readActivePages() );
258 }
259 
260 QStringList KCMDesignerFields::saveActivePages()
261 {
262  QTreeWidgetItemIterator it( mPageView, QTreeWidgetItemIterator::Checked |
263  QTreeWidgetItemIterator::Selectable );
264 
265  QStringList activePages;
266  while ( *it ) {
267  if ( (*it)->parent() == 0 ) {
268  PageItem *item = static_cast<PageItem*>( *it );
269  activePages.append( item->name() );
270  }
271 
272  ++it;
273  }
274 
275  return activePages;
276 }
277 
278 void KCMDesignerFields::save()
279 {
280  writeActivePages( saveActivePages() );
281 }
282 
283 void KCMDesignerFields::defaults()
284 {
285 }
286 
287 void KCMDesignerFields::initGUI()
288 {
289  QVBoxLayout *layout = new QVBoxLayout( this );
290  layout->setSpacing( KDialog::spacingHint() );
291  layout->setMargin( KDialog::marginHint() );
292 
293  bool noDesigner = KStandardDirs::findExe( QLatin1String("designer") ).isEmpty();
294 
295  if ( noDesigner ) {
296  QString txt =
297  i18n( "<qt><b>Warning:</b> Qt Designer could not be found. It is probably not "
298  "installed. You will only be able to import existing designer files.</qt>" );
299  QLabel *lbl = new QLabel( txt, this );
300  layout->addWidget( lbl );
301  }
302 
303  QHBoxLayout *hbox = new QHBoxLayout();
304  layout->addLayout( hbox );
305  hbox->setSpacing( KDialog::spacingHint() );
306 
307  mPageView = new QTreeWidget( this );
308  mPageView->setHeaderLabel( i18n( "Available Pages" ) );
309  mPageView->setRootIsDecorated( true );
310  mPageView->setAllColumnsShowFocus( true );
311  mPageView->header()->setResizeMode( QHeaderView::Stretch );
312  hbox->addWidget( mPageView );
313 
314  QGroupBox *box = new QGroupBox( i18n( "Preview of Selected Page" ), this );
315  QVBoxLayout *boxLayout = new QVBoxLayout( box );
316 
317  mPagePreview = new QLabel( box );
318  mPagePreview->setMinimumWidth( 300 );
319  boxLayout->addWidget( mPagePreview );
320 
321  mPageDetails = new QLabel( box );
322  boxLayout->addWidget( mPageDetails );
323  boxLayout->addStretch( 1 );
324 
325  hbox->addWidget( box );
326 
327  loadUiFiles();
328 
329  hbox = new QHBoxLayout();
330  layout->addLayout( hbox );
331  hbox->setSpacing( KDialog::spacingHint() );
332 
333  QString cwHowto =
334  i18n( "<qt><p>This section allows you to add your own GUI"
335  " Elements ('<i>Widgets</i>') to store your own values"
336  " into %1. Proceed as described below:</p>"
337  "<ol>"
338  "<li>Click on '<i>Edit with Qt Designer</i>'</li>"
339  "<li>In the dialog, select '<i>Widget</i>', then click <i>OK</i></li>"
340  "<li>Add your widgets to the form</li>"
341  "<li>Save the file in the directory proposed by Qt Designer</li>"
342  "<li>Close Qt Designer</li>"
343  "</ol>"
344  "<p>In case you already have a designer file (*.ui) located"
345  " somewhere on your hard disk, simply choose '<i>Import Page</i>'</p>"
346  "<p><b>Important:</b> The name of each input widget you place within"
347  " the form must start with '<i>X_</i>'; so if you want the widget to"
348  " correspond to your custom entry '<i>X-Foo</i>', set the widget's"
349  " <i>name</i> property to '<i>X_Foo</i>'.</p>"
350  "<p><b>Important:</b> The widget will edit custom fields with an"
351  " application name of %2. To change the application name"
352  " to be edited, set the widget name in Qt Designer.</p></qt>",
353  applicationName(), applicationName() );
354 
355  QLabel *activeLabel = new QLabel(
356  i18n( "<a href=\"whatsthis:%1\">How does this work?</a>", cwHowto ), this );
357  activeLabel->setTextInteractionFlags( Qt::LinksAccessibleByMouse|
358  Qt::LinksAccessibleByKeyboard );
359  connect( activeLabel, SIGNAL(linkActivated(QString)),
360  this, SLOT(showWhatsThis(QString)) );
361  hbox->addWidget( activeLabel );
362 
363  // ### why is this needed? Looks like a KActiveLabel bug...
364  activeLabel->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
365 
366  hbox->addStretch( 1 );
367 
368  mDeleteButton = new QPushButton( i18n( "Delete Page" ), this );
369  mDeleteButton->setEnabled( false );
370  hbox->addWidget( mDeleteButton );
371  mImportButton = new QPushButton( i18n( "Import Page..." ), this );
372  hbox->addWidget( mImportButton );
373  mDesignerButton = new QPushButton( i18n( "Edit with Qt Designer..." ), this );
374  hbox->addWidget( mDesignerButton );
375 
376  if ( noDesigner ) {
377  mDesignerButton->setEnabled( false );
378  }
379 }
380 
381 void KCMDesignerFields::updatePreview()
382 {
383  QTreeWidgetItem *item = 0;
384  if ( mPageView->selectedItems().size() == 1 ) {
385  item = mPageView->selectedItems().first();
386  }
387  bool widgetItemSelected = false;
388 
389  if ( item ) {
390  if ( item->parent() ) {
391  QString details = QString::fromLatin1( "<qt><table>"
392  "<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>"
393  "<tr><td align=\"right\"><b>%3</b></td><td>%4</td></tr>"
394  "<tr><td align=\"right\"><b>%5</b></td><td>%6</td></tr>"
395  "<tr><td align=\"right\"><b>%7</b></td><td>%8</td></tr>"
396  "</table></qt>" )
397  .arg( i18n( "Key:" ) )
398  .arg( item->text( 0 ).replace( QLatin1String("X_"),QLatin1String("X-") ) )
399  .arg( i18n( "Type:" ) )
400  .arg( item->text( 1 ) )
401  .arg( i18n( "Classname:" ) )
402  .arg( item->text( 2 ) )
403  .arg( i18n( "Description:" ) )
404  .arg( item->text( 3 ) );
405 
406  mPageDetails->setText( details );
407 
408  PageItem *pageItem = static_cast<PageItem*>( item->parent() );
409  mPagePreview->setWindowIcon( pageItem->preview() );
410  } else {
411  mPageDetails->setText( QString() );
412 
413  PageItem *pageItem = static_cast<PageItem*>( item );
414  mPagePreview->setWindowIcon( pageItem->preview() );
415 
416  widgetItemSelected = true;
417  }
418 
419  mPagePreview->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
420  } else {
421  mPagePreview->setWindowIcon( QPixmap() );
422  mPagePreview->setFrameStyle( 0 );
423  mPageDetails->setText( QString() );
424  }
425 
426  mDeleteButton->setEnabled( widgetItemSelected );
427 }
428 
429 void KCMDesignerFields::itemClicked( QTreeWidgetItem *item )
430 {
431  if ( !item || item->parent() != 0 ) {
432  return;
433  }
434 
435  PageItem *pageItem = static_cast<PageItem*>( item );
436 
437  if ( pageItem->isOn() != pageItem->isActive() ) {
438  emit changed( true );
439  pageItem->setIsActive( pageItem->isOn() );
440  }
441 }
442 
443 void KCMDesignerFields::startDesigner()
444 {
445  QString cmdLine = QLatin1String("designer");
446 
447  // check if path exists and create one if not.
448  QString cepPath = localUiDir();
449  if( !KGlobal::dirs()->exists(cepPath) ) {
450  KIO::NetAccess::mkdir( cepPath, this );
451  }
452 
453  // finally jump there
454  QDir::setCurrent( QLatin1String(cepPath.toLocal8Bit()) );
455 
456  QTreeWidgetItem *item = 0;
457  if ( mPageView->selectedItems().size() == 1 ) {
458  item = mPageView->selectedItems().first();
459  }
460  if ( item ) {
461  PageItem *pageItem = static_cast<PageItem*>( item->parent() ? item->parent() : item );
462  cmdLine += QLatin1Char(' ') + KShell::quoteArg( pageItem->path() );
463  }
464 
465  KRun::runCommand( cmdLine, topLevelWidget() );
466 }
467 
468 void KCMDesignerFields::showWhatsThis( const QString &href )
469 {
470  if ( href.startsWith( QLatin1String( "whatsthis:" ) ) ) {
471  QPoint pos = QCursor::pos();
472  QWhatsThis::showText( pos, href.mid( 10 ), this );
473  }
474 }
475 
476 #include "kcmdesignerfields.moc"
KCMDesignerFields::KCMDesignerFields
KCMDesignerFields(const KComponentData &instance, QWidget *parent=0, const QVariantList &args=QVariantList())
Definition: kcmdesignerfields.cpp:136
KCMDesignerFields::writeActivePages
virtual void writeActivePages(const QStringList &)=0
KCMDesignerFields::loadActivePages
void loadActivePages(const QStringList &)
Definition: kcmdesignerfields.cpp:235
kcmdesignerfields.h
QWidget
KCMDesignerFields::loadUiFiles
void loadUiFiles()
Definition: kcmdesignerfields.cpp:213
KCMDesignerFields::defaults
virtual void defaults()
Definition: kcmdesignerfields.cpp:283
KCMDesignerFields::uiPath
virtual QString uiPath()=0
KAboutData
KCMDesignerFields::save
virtual void save()
Definition: kcmdesignerfields.cpp:278
KCMDesignerFields::saveActivePages
QStringList saveActivePages()
Definition: kcmdesignerfields.cpp:260
KCMDesignerFields::applicationName
virtual QString applicationName()=0
KCMDesignerFields::localUiDir
virtual QString localUiDir()=0
KCMDesignerFields::load
virtual void load()
Definition: kcmdesignerfields.cpp:251
KCModule
KCMDesignerFields::readActivePages
virtual QStringList readActivePages()=0
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:19 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

korganizer

Skip menu "korganizer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal