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

kig

  • sources
  • kde-4.12
  • kdeedu
  • kig
  • modes
typesdialog.cpp
Go to the documentation of this file.
1 
21 #include "typesdialog.h"
22 #include "typesdialog.moc"
23 
24 #include "edittype.h"
25 #include "ui_typeswidget.h"
26 #include "../kig/kig_part.h"
27 #include "../misc/guiaction.h"
28 #include "../misc/object_constructor.h"
29 
30 #include <kfiledialog.h>
31 #include <kiconloader.h>
32 #include <klocale.h>
33 #include <kmessagebox.h>
34 #include <kpushbutton.h>
35 #include <ktoolinvocation.h>
36 
37 #include <qbytearray.h>
38 #include <qevent.h>
39 #include <qfile.h>
40 #include <qlayout.h>
41 #include <qmenu.h>
42 #include <qstringlist.h>
43 
44 #include <algorithm>
45 #include <iterator>
46 
47 static QString wrapAt( const QString& str, int col = 50 )
48 {
49  QStringList ret;
50  int delta = 0;
51  while ( delta + col < str.length() )
52  {
53  int pos = delta + col;
54  while ( !str.at( pos ).isSpace() ) --pos;
55  ret << str.mid( delta, pos - delta );
56  delta = pos + 1;
57  }
58  ret << str.mid( delta );
59  return ret.join( "<br>" );
60 }
61 
62 class BaseListElement
63 {
64 protected:
65  BaseListElement();
66 
67 public:
68  virtual ~BaseListElement();
69 
70  virtual bool isMacro() const { return false; }
71  virtual QString name() const = 0;
72  virtual QString description() const = 0;
73  virtual QString icon( bool canNull = false ) const = 0;
74  virtual QString type() const = 0;
75 };
76 
77 BaseListElement::BaseListElement()
78 {
79 }
80 
81 BaseListElement::~BaseListElement()
82 {
83 }
84 
85 class MacroListElement
86  : public BaseListElement
87 {
88  Macro* mmacro;
89 public:
90  MacroListElement( Macro* m );
91  virtual ~MacroListElement();
92 
93  Macro* getMacro() const { return mmacro; }
94  virtual bool isMacro() const { return true; }
95  virtual QString name() const;
96  virtual QString description() const;
97  virtual QString icon( bool canNull = false ) const;
98  virtual QString type() const;
99 };
100 
101 MacroListElement::MacroListElement( Macro* m )
102  : BaseListElement(), mmacro( m )
103 {
104 }
105 
106 MacroListElement::~MacroListElement()
107 {
108  // do NOT delete the associated macro, but instead safely release the
109  // pointer, as it's kept elsewhere
110  mmacro = 0;
111 }
112 
113 QString MacroListElement::name() const
114 {
115  return mmacro->action->descriptiveName();
116 }
117 
118 QString MacroListElement::description() const
119 {
120  return mmacro->action->description();
121 }
122 
123 QString MacroListElement::icon( bool canNull ) const
124 {
125  return mmacro->ctor->iconFileName( canNull );
126 }
127 
128 QString MacroListElement::type() const
129 {
130  return i18n( "Macro" );
131 }
132 
133 
134 TypesModel::TypesModel( QObject* parent )
135  : QAbstractTableModel( parent )
136 {
137 }
138 
139 TypesModel::~TypesModel()
140 {
141 }
142 
143 void TypesModel::addMacros( const std::vector<Macro*>& macros )
144 {
145  if ( macros.size() < 1 )
146  return;
147 
148  beginInsertRows( QModelIndex(), melems.size(), melems.size() + macros.size() - 1 );
149 
150  for ( std::vector<Macro*>::const_iterator it = macros.begin();
151  it != macros.end(); ++it )
152  {
153  melems.push_back( new MacroListElement( *it ) );
154  }
155 
156  endInsertRows();
157 }
158 
159 void TypesModel::removeElements( const QModelIndexList& elems )
160 {
161  // this way of deleting needs some explanation: the std::vector.erase needs
162  // an iterator to the element to remove from the list, while the
163  // beginRemoveRows() of Qt needs the index(es). so, for each element to
164  // delete, we search it into melems (keeping a count of the id), and when we
165  // find it, we free the memory of the BaseListElement and remove the element
166  // from the list. in the meanwhile, we notify the model structure of Qt that
167  // we're removing a row.
168  for ( int i = elems.count(); i > 0; --i )
169  {
170  QModelIndex index = elems.at( i - 1 );
171  if ( !index.isValid() || index.row() < 0 || index.row() >= static_cast<int>( melems.size() )
172  || index.column() < 0 || index.column() > 3 )
173  continue;
174 
175  BaseListElement* element = melems[ index.row() ];
176 
177  bool found = false;
178  int id = 0;
179  for ( std::vector<BaseListElement*>::iterator mit = melems.begin();
180  mit != melems.end() && !found; )
181  {
182  if ( *mit == element )
183  {
184  found = true;
185  beginRemoveRows( QModelIndex(), id, id );
186 
187  delete (*mit);
188  mit = melems.erase( mit );
189  element = 0;
190 
191  endRemoveRows();
192  }
193  else
194  ++mit;
195  ++id;
196  }
197  }
198 }
199 
200 void TypesModel::clear()
201 {
202  for ( std::vector<BaseListElement*>::const_iterator it = melems.begin();
203  it != melems.end(); ++it )
204  delete *it;
205  melems.clear();
206 }
207 
208 void TypesModel::elementChanged( const QModelIndex& index )
209 {
210  if ( !index.isValid() || index.row() < 0 || index.row() >= static_cast<int>( melems.size() )
211  || index.column() < 0 || index.column() > 3 )
212  return;
213 
214  QModelIndex left = createIndex( index.row(), 1 );
215  QModelIndex right = createIndex( index.row(), 2 );
216  emit dataChanged( left, right );
217 }
218 
219 bool TypesModel::isMacro( const QModelIndex& index ) const
220 {
221  if ( !index.isValid() || index.row() < 0 || index.row() >= static_cast<int>( melems.size() ) )
222  return false;
223 
224  return melems[ index.row() ]->isMacro();
225 }
226 
227 Macro* TypesModel::macroFromIndex( const QModelIndex& index ) const
228 {
229  if ( !index.isValid() || index.row() < 0 || index.row() >= static_cast<int>( melems.size() ) )
230  return 0;
231 
232  BaseListElement* el = melems[ index.row() ];
233  if ( !el->isMacro() )
234  return 0;
235 
236  return static_cast<MacroListElement*>( el )->getMacro();
237 }
238 
239 int TypesModel::columnCount( const QModelIndex& parent ) const
240 {
241  return parent.isValid() ? 0 : 3;
242 }
243 
244 QVariant TypesModel::data( const QModelIndex& index, int role ) const
245 {
246  if ( !index.isValid() )
247  return QVariant();
248 
249  if ( ( index.row() < 0 ) || ( index.row() >= static_cast<int>( melems.size() ) ) )
250  return QVariant();
251 
252  switch ( role )
253  {
254  case Qt::DecorationRole:
255  {
256  if ( index.column() == 1 )
257  return KIcon( melems[ index.row() ]->icon() );
258  else
259  return QVariant();
260  break;
261  }
262  case Qt::DisplayRole:
263  {
264  switch ( index.column() )
265  {
266  case 0: return melems[ index.row() ]->type(); break;
267  case 1: return melems[ index.row() ]->name(); break;
268  case 2: return melems[ index.row() ]->description(); break;
269  default:
270  return QVariant();
271  }
272  break;
273  }
274  case Qt::ToolTipRole:
275  {
276  static QString macro_with_image(
277  "<qt><table cellspacing=\"5\"><tr><td><b>%1</b> (%4)</td>"
278  "<td rowspan=\"2\" align=\"right\"><img src=\"%3\"></td></tr>"
279  "<tr><td>%2</td></tr></table></qt>" );
280  static QString macro_no_image(
281  "<qt><b>%1</b> (%3)<br>%2</qt>" );
282 
283  if ( melems[ index.row() ]->icon( true ).isEmpty() )
284  return macro_no_image
285  .arg( melems[ index.row() ]->name() )
286  .arg( wrapAt( melems[ index.row() ]->description() ) )
287  .arg( melems[ index.row() ]->type() );
288  else
289  return macro_with_image
290  .arg( melems[ index.row() ]->name() )
291  .arg( wrapAt( melems[ index.row() ]->description() ) )
292  .arg( KIconLoader::global()->iconPath( melems[ index.row() ]->icon(), - KIconLoader::SizeMedium ) )
293  .arg( melems[ index.row() ]->type() );
294  }
295  default:
296  return QVariant();
297  }
298 }
299 
300 QVariant TypesModel::headerData( int section, Qt::Orientation orientation, int role ) const
301 {
302  if ( orientation != Qt::Horizontal )
303  return QVariant();
304 
305  if ( role == Qt::TextAlignmentRole )
306  return QVariant( Qt::AlignLeft );
307 
308  if ( role != Qt::DisplayRole )
309  return QVariant();
310 
311  switch ( section )
312  {
313  case 0: return i18n( "Type" ); break;
314  case 1: return i18n( "Name" ); break;
315  case 2: return i18n( "Description" ); break;
316  default:
317  return QVariant();
318  }
319 }
320 
321 QModelIndex TypesModel::index( int row, int column, const QModelIndex& parent ) const
322 {
323  if ( parent.isValid() || row < 0 || row >= static_cast<int>( melems.size() ) || column < 0 || column > 3 )
324  return QModelIndex();
325 
326  return createIndex( row, column, melems[row] );
327 }
328 
329 int TypesModel::rowCount( const QModelIndex& parent ) const
330 {
331  return parent.isValid() ? 0 : melems.size();
332 }
333 
334 
335 TypesDialog::TypesDialog( QWidget* parent, KigPart& part )
336  : KDialog( parent ),
337  mpart( part )
338 {
339  setCaption( i18n( "Manage Types" ) );
340  setButtons( Help | Ok | Cancel );
341 
342  QWidget* base = new QWidget( this );
343  setMainWidget( base );
344  mtypeswidget = new Ui_TypesWidget();
345  mtypeswidget->setupUi( base );
346  base->layout()->setMargin( 0 );
347 
348  // model creation and usage
349  mmodel = new TypesModel( mtypeswidget->typeList );
350  mtypeswidget->typeList->setModel( mmodel );
351 
352  mtypeswidget->typeList->setContextMenuPolicy( Qt::CustomContextMenu );
353 
354  // improving GUI look'n'feel...
355  mtypeswidget->buttonEdit->setIcon( KIcon( "document-properties" ) );
356  mtypeswidget->buttonRemove->setIcon( KIcon( "edit-delete" ) );
357  mtypeswidget->buttonExport->setIcon( KIcon( "document-export" ) );
358  mtypeswidget->buttonImport->setIcon( KIcon( "document-import" ) );
359 
360  // loading macros...
361  mmodel->addMacros( MacroList::instance()->macros() );
362 
363 // mtypeswidget->typeList->sortItems( 2, Qt::AscendingOrder );
364 
365  mtypeswidget->typeList->resizeColumnToContents( 0 );
366 
367  popup = new QMenu( this );
368  popup->addAction( KIcon( "document-properties" ), i18n( "&Edit..." ), this, SLOT( editType() ) );
369  popup->addAction( KIcon( "edit-delete" ), i18n( "&Delete" ), this, SLOT( deleteType() ) );
370  popup->addSeparator();
371  popup->addAction( KIcon( "document-export" ), i18n( "E&xport..." ), this, SLOT( exportType() ) );
372 
373  // saving types
374  mpart.saveTypes();
375 
376  connect( mtypeswidget->buttonExport, SIGNAL( clicked() ), this, SLOT( exportType() ) );
377  connect( mtypeswidget->buttonImport, SIGNAL( clicked() ), this, SLOT( importTypes() ) );
378  connect( mtypeswidget->buttonRemove, SIGNAL( clicked() ), this, SLOT( deleteType() ) );
379  connect( mtypeswidget->buttonEdit, SIGNAL( clicked() ), this, SLOT( editType() ) );
380  connect( mtypeswidget->typeList, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( typeListContextMenu( const QPoint& ) ) );
381  connect( this, SIGNAL( helpClicked() ), this, SLOT( slotHelp() ) );
382  connect( this, SIGNAL( okClicked() ), this, SLOT( slotOk() ) );
383  connect( this, SIGNAL( cancelClicked() ), this, SLOT( slotCancel() ) );
384 
385  resize( 460, 270 );
386 }
387 
388 TypesDialog::~TypesDialog()
389 {
390  delete mtypeswidget;
391 }
392 
393 void TypesDialog::slotHelp()
394 {
395  KToolInvocation::invokeHelp( "working-with-types", "kig" );
396 }
397 
398 void TypesDialog::slotOk()
399 {
400  mpart.saveTypes();
401  mpart.deleteTypes();
402  mpart.loadTypes();
403  accept();
404 }
405 
406 void TypesDialog::deleteType()
407 {
408  std::vector<Macro*> selectedTypes;
409  QModelIndexList indexes = selectedRows();
410  for ( QModelIndexList::const_iterator it = indexes.constBegin(); it != indexes.constEnd(); ++it )
411  {
412  Macro* macro = mmodel->macroFromIndex( *it );
413  if ( macro )
414  {
415  selectedTypes.push_back( macro );
416  }
417  }
418 
419  if (selectedTypes.empty()) return;
420  QStringList types;
421  for ( std::vector<Macro*>::iterator j = selectedTypes.begin();
422  j != selectedTypes.end(); ++j )
423  types << ( *j )->action->descriptiveName();
424  types.sort();
425  if ( KMessageBox::warningContinueCancelList( this,
426  i18np( "Are you sure you want to delete this type?",
427  "Are you sure you want to delete these %1 types?", selectedTypes.size() ),
428  types, i18n("Are You Sure?"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
429  "deleteTypeWarning") == KMessageBox::Cancel )
430  return;
431  bool updates = mtypeswidget->typeList->updatesEnabled();
432  mtypeswidget->typeList->setUpdatesEnabled( false );
433  mmodel->removeElements( indexes );
434  mtypeswidget->typeList->setUpdatesEnabled( updates );
435  for ( std::vector<Macro*>::iterator j = selectedTypes.begin();
436  j != selectedTypes.end(); ++j)
437  MacroList::instance()->remove( *j );
438 }
439 
440 void TypesDialog::exportType()
441 {
442  std::vector<Macro*> types;
443  QModelIndexList indexes = selectedRows();
444  for ( QModelIndexList::const_iterator it = indexes.constBegin(); it != indexes.constEnd(); ++it )
445  {
446  Macro* macro = mmodel->macroFromIndex( *it );
447  if ( macro )
448  types.push_back( macro );
449  }
450  if (types.empty()) return;
451  QString file_name = KFileDialog::getSaveFileName( KUrl( "kfiledialog:///macro" ), i18n("*.kigt|Kig Types Files\n*|All Files"), this, i18n( "Export Types" ) );
452  if ( file_name.isNull() )
453  return;
454  QFile fi( file_name );
455  if ( fi.exists() )
456  if ( KMessageBox::warningContinueCancel( this, i18n( "The file \"%1\" already exists. "
457  "Do you wish to overwrite it?", fi.fileName() ),
458  i18n( "Overwrite File?" ), KStandardGuiItem::overwrite() ) == KMessageBox::Cancel )
459  return;
460  MacroList::instance()->save( types, file_name );
461 }
462 
463 void TypesDialog::importTypes()
464 {
465  QStringList file_names =
466  KFileDialog::getOpenFileNames( KUrl( "kfiledialog:///importTypes" ), i18n("*.kigt|Kig Types Files\n*|All Files"), this, i18n( "Import Types" ));
467 
468  std::vector<Macro*> macros;
469 
470  for ( QStringList::const_iterator i = file_names.constBegin();
471  i != file_names.constEnd(); ++i)
472  {
473  std::vector<Macro*> nmacros;
474  bool ok = MacroList::instance()->load( *i, nmacros, mpart );
475  if ( ! ok )
476  continue;
477  std::copy( nmacros.begin(), nmacros.end(), std::back_inserter( macros ) );
478  };
479  MacroList::instance()->add( macros );
480 
481  mmodel->addMacros( macros );
482 
483  mtypeswidget->typeList->resizeColumnToContents( 0 );
484 }
485 
486 void TypesDialog::editType()
487 {
488  QModelIndexList indexes = selectedRows();
489  if ( indexes.isEmpty() )
490  return;
491  if ( indexes.count() > 1 )
492  {
493  KMessageBox::sorry( this,
494  i18n( "There is more than one type selected. You can "
495  "only edit one type at a time. Please select "
496  "only the type you want to edit and try again." ),
497  i18n( "More Than One Type Selected" ) );
498  return;
499  }
500  bool refresh = false;
501  QModelIndex index = indexes.first();
502  if ( mmodel->isMacro( index ) )
503  {
504  Macro* oldmacro = mmodel->macroFromIndex( index );
505  EditType editdialog( this, oldmacro->action->descriptiveName(), oldmacro->action->description(),
506  oldmacro->ctor->iconFileName( false ) );
507  if ( editdialog.exec() )
508  {
509  QString newname = editdialog.name();
510  QString newdesc = editdialog.description();
511  QString newicon = editdialog.icon();
512 
513 // mpart.unplugActionLists();
514  oldmacro->ctor->setName( newname );
515  oldmacro->ctor->setDescription( newdesc );
516  QByteArray ncicon( newicon.toUtf8() );
517  oldmacro->ctor->setIcon( ncicon );
518 // mpart.plugActionLists();
519  refresh = true;
520  }
521  }
522  if ( refresh )
523  {
524  mmodel->elementChanged( index );
525  }
526 }
527 
528 void TypesDialog::slotCancel()
529 {
530  mpart.deleteTypes();
531  mpart.loadTypes();
532  reject();
533 }
534 
535 QModelIndexList TypesDialog::selectedRows() const
536 {
537  QModelIndexList indexes = mtypeswidget->typeList->selectionModel()->selectedRows();
538  qSort( indexes );
539  return indexes;
540 }
541 
542 void TypesDialog::typeListContextMenu( const QPoint& pos )
543 {
544  QModelIndexList indexes = mtypeswidget->typeList->selectionModel()->selectedRows();
545  if ( indexes.isEmpty() )
546  return;
547 
548  popup->exec( mtypeswidget->typeList->viewport()->mapToGlobal( pos ) );
549 }
edittype.h
TypesModel
A model for representing the data.
Definition: typesdialog.h:40
TypesModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: typesdialog.cpp:321
TypesModel::headerData
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Definition: typesdialog.cpp:300
QWidget
TypesModel::data
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Definition: typesdialog.cpp:244
EditType
Simply dialog that allow the user the editing of a macro type...
Definition: edittype.h:30
KDialog
wrapAt
static QString wrapAt(const QString &str, int col=50)
This file is part of Kig, a KDE program for Interactive Geometry...
Definition: typesdialog.cpp:47
Macro::action
GUIAction * action
Definition: lists.h:94
TypesModel::columnCount
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Definition: typesdialog.cpp:239
KigPart::loadTypes
void loadTypes()
Definition: kig_part.cpp:1101
Macro::ctor
MacroConstructor * ctor
Definition: lists.h:95
KigPart::deleteTypes
void deleteTypes()
Definition: kig_part.cpp:1116
TypesModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: typesdialog.cpp:329
MacroConstructor::iconFileName
const QByteArray iconFileName(const bool canBeNull=false) const
Definition: object_constructor.cc:384
EditType::name
QString name() const
Definition: edittype.cc:113
TypesDialog::~TypesDialog
~TypesDialog()
Definition: typesdialog.cpp:388
MacroList::add
void add(Macro *m)
Add a Macro m .
Definition: lists.cc:213
TypesModel::macroFromIndex
Macro * macroFromIndex(const QModelIndex &index) const
Definition: typesdialog.cpp:227
TypesDialog::TypesDialog
TypesDialog(QWidget *parent, KigPart &)
Definition: typesdialog.cpp:335
TypesModel::removeElements
void removeElements(const QModelIndexList &elems)
Definition: typesdialog.cpp:159
TypesModel::elementChanged
void elementChanged(const QModelIndex &index)
Definition: typesdialog.cpp:208
TypesModel::~TypesModel
virtual ~TypesModel()
Definition: typesdialog.cpp:139
KigPart::saveTypes
void saveTypes()
Definition: kig_part.cpp:1086
MacroConstructor::setDescription
void setDescription(const QString &desc)
Definition: object_constructor.cc:602
typesdialog.h
MacroConstructor::setName
void setName(const QString &name)
Definition: object_constructor.cc:597
MacroList::save
bool save(Macro *m, const QString &f)
Save macro m to file f .
Definition: lists.cc:240
GUIAction::descriptiveName
virtual QString descriptiveName() const =0
TypesModel::addMacros
void addMacros(const std::vector< Macro * > &macros)
Definition: typesdialog.cpp:143
TypesModel::clear
void clear()
Definition: typesdialog.cpp:200
Macro
this is just a simple data struct.
Definition: lists.h:91
MacroList::load
bool load(const QString &f, vectype &ret, const KigPart &)
load macro's from file f .
Definition: lists.cc:298
MacroConstructor::setIcon
void setIcon(QByteArray &icon)
Definition: object_constructor.cc:607
KigPart
This is a "Part".
Definition: kig_part.h:68
MacroList::remove
void remove(Macro *m)
Remove macro m .
Definition: lists.cc:220
TypesModel::isMacro
bool isMacro(const QModelIndex &index) const
Definition: typesdialog.cpp:219
TypesModel::TypesModel
TypesModel(QObject *parent=0)
Definition: typesdialog.cpp:134
QAbstractTableModel
MacroList::instance
static MacroList * instance()
MacroList is a singleton.
Definition: lists.cc:195
GUIAction::description
virtual QString description() const =0
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:35:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kig

Skip menu "kig"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

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