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

marble

  • sources
  • kde-4.12
  • kdeedu
  • marble
  • src
  • lib
  • marble
PluginItemDelegate.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2009 Bastian Holst <bastianholst@gmx.de>
9 //
10 
11 // Self
12 #include "PluginItemDelegate.h"
13 
14 // Marble
15 #include "RenderPluginModel.h"
16 #include "MarbleDebug.h"
17 
18 // Qt
19 #include <QEvent>
20 #include <QSize>
21 #include <QVariant>
22 #include <QAbstractItemView>
23 #include <QMouseEvent>
24 #include <QStandardItemModel>
25 #include <QApplication>
26 #include <QPainter>
27 #include <QStandardItem>
28 
29 using namespace Marble;
30 /* TRANSLATOR Marble::PluginItemDelegate */
31 
32 const QSize iconSize( 16, 16 );
33 
34 PluginItemDelegate::PluginItemDelegate( QAbstractItemView *view, QObject * parent )
35  : QAbstractItemDelegate( parent )
36 {
37  // Enable mouse tracking of itemview makes it possible to find when the mouse if moved
38  // without pressed buttons.
39  view->setMouseTracking( true );
40 }
41 
42 PluginItemDelegate::~PluginItemDelegate()
43 {
44 }
45 
46 void PluginItemDelegate::paint( QPainter *painter,
47  const QStyleOptionViewItem& option,
48  const QModelIndex& index ) const
49 {
50  Q_ASSERT( index.isValid() );
51  QRect rect = option.rect;
52  QStyle *style = QApplication::style();
53 
54  painter->save();
55 
56  // Drawing the background
57  QStyleOption background = option;
58  style->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter );
59 
60  painter->translate( rect.topLeft() );
61 
62  // rect is now represented in item coordinates
63  rect.moveTopLeft( QPoint( 0, 0 ) );
64  // The point at the top left of the available drawing area.
65  QPoint topLeft( 0, 0 );
66  // The point at the top right of the available drawing area.
67  QPoint topRight( rect.topRight() );
68 
69  QRect nameRect = rect;
70 
71  // Painting the checkbox
72  QStyleOptionButton checkBox = checkboxOption( option, index, topLeft.x(), Qt::AlignLeft );
73  painter->save();
74  style->drawControl( QStyle::CE_CheckBox, &checkBox, painter );
75  painter->restore();
76 
77  nameRect.setLeft( checkBox.rect.right() + 1 );
78 
79  // Painting the About Button
80  QStyleOptionButton button = buttonOption( option, index, PluginItemDelegate::About,
81  topRight.x(), Qt::AlignRight );
82  style->drawControl( QStyle::CE_PushButton, &button, painter );
83  topRight -= QPoint( button.rect.width(), 0 );
84 
85  // Painting the Configure Button
86  if ( index.data( RenderPluginModel::ConfigurationDialogAvailable ).toBool() ) {
87  QStyleOptionButton button = buttonOption( option, index, PluginItemDelegate::Configure,
88  topRight.x(), Qt::AlignRight );
89  style->drawControl( QStyle::CE_PushButton, &button, painter );
90  topRight -= QPoint( button.rect.width(), 0 );
91 
92  nameRect.setRight( button.rect.left() -1 );
93  }
94 
95  // Painting the Icon
96  const QIcon icon = index.data( Qt::DecorationRole ).value<QIcon>();
97  const QPixmap iconPixmap = icon.pixmap(16, 16);
98 
99  nameRect.moveBottom( nameRect.bottom()+5 );
100  style->drawItemPixmap( painter,
101  nameRect,
102  Qt::AlignLeft,
103  iconPixmap );
104 
105  nameRect.setLeft( nameRect.left() + 16 + 5 );
106  nameRect.moveBottom( nameRect.bottom()-5 );
107 
108  // Painting the Name string
109  QString name = index.data( Qt::DisplayRole ).toString();
110 
111  style->drawItemText( painter,
112  nameRect,
113  Qt::AlignLeft | Qt::AlignVCenter,
114  option.palette,
115  true,
116  name );
117 
118  painter->restore();
119 }
120 
121 QSize PluginItemDelegate::sizeHint( const QStyleOptionViewItem& option,
122  const QModelIndex & index ) const
123 {
124  QSize size;
125 
126  QStyleOptionViewItem opt = option;
127  opt.rect = QRect( 0, 0, 0, 0 );
128  QList<QSize> elementSize;
129  QStyleOptionButton checkBox = checkboxOption( opt, index );
130  elementSize.append( checkBox.rect.size() );
131  QStyleOptionButton aboutButton = buttonOption( opt, index, PluginItemDelegate::About );
132  elementSize.append( aboutButton.rect.size() );
133  QStyleOptionButton configButton = buttonOption( opt, index, PluginItemDelegate::Configure );
134  elementSize.append( configButton.rect.size() );
135  elementSize.append( nameSize( index ) );
136 
137  foreach( const QSize& buttonSize, elementSize ) {
138  if( buttonSize.height() > size.height() )
139  size.setHeight( buttonSize.height() );
140  size.setWidth( size.width() + buttonSize.width() );
141  }
142 
143  return size;
144 }
145 
146 void PluginItemDelegate::setAboutIcon( const QIcon& icon )
147 {
148  m_aboutIcon = icon;
149 }
150 
151 void PluginItemDelegate::setConfigIcon( const QIcon& icon )
152 {
153  m_configIcon = icon;
154 }
155 
156 bool PluginItemDelegate::editorEvent( QEvent *event,
157  QAbstractItemModel *model,
158  const QStyleOptionViewItem &option,
159  const QModelIndex &index )
160 {
161  Q_ASSERT(event);
162  Q_ASSERT(model);
163 
164  if ( ( event->type() == QEvent::MouseButtonRelease )
165  || ( event->type() == QEvent::MouseButtonDblClick )
166  || ( event->type() == QEvent::MouseButtonPress )
167  || ( event->type() == QEvent::MouseMove ) )
168  {
169  QMouseEvent *me = static_cast<QMouseEvent*>(event);
170  QPoint mousePosition = me->pos() - option.rect.topLeft();
171 
172  if ( ( event->type() == QEvent::MouseMove )
173  && !( me->buttons() & Qt::LeftButton ) )
174  {
175  // If the mouse moves around and no left button is pressed, no pushbutton is pressed
176  // and no other event will be successful.
177  m_aboutPressedIndex = QModelIndex();
178  m_configPressedIndex = QModelIndex();
179  return true;
180  }
181 
182  // Handle checkbox
183  QRect checkRect = checkboxOption( option, index, 0, Qt::AlignLeft ).rect;
184  if ( checkRect.contains( mousePosition )
185  && ( ( event->type() == QEvent::MouseButtonDblClick )
186  || ( event->type() == QEvent::MouseButtonRelease ) ) )
187  {
188  // make sure that the item is checkable
189  Qt::ItemFlags flags = model->flags(index);
190  if ( !( flags & Qt::ItemIsUserCheckable ) || !( option.state & QStyle::State_Enabled )
191  || !( flags & Qt::ItemIsEnabled ) )
192  return false;
193 
194  // make sure that we have a check state
195  QVariant checkValue = index.data( Qt::CheckStateRole );
196  if ( !checkValue.isValid() )
197  return false;
198 
199  // eat the double click events inside the check rect
200  if ( event->type() == QEvent::MouseButtonDblClick )
201  return true;
202 
203  Qt::CheckState state = ( static_cast<Qt::CheckState>( checkValue.toInt() ) == Qt::Checked
204  ? Qt::Unchecked : Qt::Checked );
205  return model->setData(index, state, Qt::CheckStateRole);
206  }
207 
208  if ( ( event->type() == QEvent::MouseMove )
209  && !( me->buttons() & Qt::LeftButton ) )
210  {
211  m_aboutPressedIndex = QModelIndex();
212  m_configPressedIndex = QModelIndex();
213  return true;
214  }
215 
216  QPoint topRight = option.rect.topRight();
217 
218  // Handle aboutButton
219  {
220  QRect aboutRect = buttonOption( option,
221  index,
222  PluginItemDelegate::About,
223  topRight.x(),
224  Qt::AlignRight ).rect;
225  if ( aboutRect.contains( mousePosition ) ) {
226  if ( event->type() == QEvent::MouseButtonDblClick )
227  return true;
228  if ( event->type() == QEvent::MouseButtonPress ) {
229  m_aboutPressedIndex = index;
230  m_configPressedIndex = QModelIndex();
231  return true;
232  }
233  if ( event->type() == QEvent::MouseButtonRelease ) {
234  m_aboutPressedIndex = QModelIndex();
235  m_configPressedIndex = QModelIndex();
236  emit aboutPluginClicked( index );
237  return true;
238  }
239  if ( event->type() == QEvent::MouseMove ) {
240  if ( me->buttons() & Qt::LeftButton ) {
241  m_aboutPressedIndex = index;
242  m_configPressedIndex = QModelIndex();
243  return true;
244  }
245  else {
246  m_aboutPressedIndex = QModelIndex();
247  m_configPressedIndex = QModelIndex();
248  return true;
249  }
250  }
251  }
252  else {
253  // If the mouse is on the item and the mouse isn't above the button.
254  // no about button is pressed.
255  m_aboutPressedIndex = QModelIndex();
256  }
257  topRight -= QPoint( aboutRect.width(), 0 );
258  }
259 
260  // Handle configButton
261  // make sure we have config button
262  if ( index.data( RenderPluginModel::ConfigurationDialogAvailable ).toBool() ) {
263  QRect configRect = buttonOption( option,
264  index,
265  PluginItemDelegate::Configure,
266  topRight.x(),
267  Qt::AlignRight ).rect;
268  if( configRect.contains( mousePosition ) ) {
269  if ( event->type() == QEvent::MouseButtonDblClick )
270  return true;
271 
272  if ( event->type() == QEvent::MouseButtonPress ) {
273  m_aboutPressedIndex = QModelIndex();
274  m_configPressedIndex = index;
275  return true;
276  }
277  if ( event->type() == QEvent::MouseButtonRelease ) {
278  m_aboutPressedIndex = QModelIndex();
279  m_configPressedIndex = QModelIndex();
280  emit configPluginClicked( index );
281  return true;
282  }
283  if ( event->type() == QEvent::MouseMove ) {
284  if ( me->buttons() & Qt::LeftButton ) {
285  m_aboutPressedIndex = QModelIndex();
286  m_configPressedIndex = index;
287  return true;
288  }
289  else {
290  m_aboutPressedIndex = QModelIndex();
291  m_configPressedIndex = QModelIndex();
292  return true;
293  }
294  }
295  }
296  else {
297  // If the mouse is on the item and the mouse isn't above the button.
298  // no config button is pressed.
299  m_configPressedIndex = QModelIndex();
300  }
301 
302  topRight -= QPoint( configRect.width(), 0 );
303  }
304  else {
305  // If we don't have an config dialog shown and the mouse is over this item,
306  // no config button is pressed.
307  m_configPressedIndex = QModelIndex();
308  }
309  }
310 
311  return false;
312 }
313 
314 QStyleOptionButton PluginItemDelegate::checkboxOption( const QStyleOptionViewItem& option,
315  const QModelIndex& index,
316  int position,
317  Qt::AlignmentFlag alignment ) const
318 {
319  QStyleOptionButton checkboxOption;
320  if ( index.data( Qt::CheckStateRole ).toBool() )
321  checkboxOption.state = option.state | QStyle::State_On;
322  else
323  checkboxOption.state = option.state | QStyle::State_Off;
324  QSize size = QApplication::style()->sizeFromContents( QStyle::CT_CheckBox, &option, QSize() );
325  if ( size.isEmpty() ) {
326  // A checkbox has definitely a size != 0
327  checkboxOption.rect.setSize( QSize( 22, 22 ) );
328  }
329  else {
330  checkboxOption.rect.setSize( QSize( size.width(), size.height() ) );
331  }
332  checkboxOption.rect = alignRect( checkboxOption.rect, option.rect, position, alignment );
333  return checkboxOption;
334 }
335 
336 QStyleOptionButton PluginItemDelegate::buttonOption( const QStyleOptionViewItem& option,
337  const QModelIndex& index,
338  PluginItemDelegate::ButtonType type,
339  int position,
340  Qt::AlignmentFlag alignment ) const
341 {
342  QStyleOptionButton buttonOption;
343  buttonOption.state = option.state;
344  buttonOption.state &= ~QStyle::State_HasFocus;
345 
346  buttonOption.rect.setTopLeft( QPoint( 0, 0 ) );
347  buttonOption.palette = option.palette;
348  buttonOption.features = QStyleOptionButton::None;
349 
350  QSize contentSize;
351  if ( type == PluginItemDelegate::About ) {
352  if ( m_aboutIcon.isNull() ) {
353  buttonOption.text = tr( "About" );
354  contentSize = buttonOption.fontMetrics.size( 0, buttonOption.text ) + QSize( 4, 4 );
355  }
356  else {
357  buttonOption.icon = m_aboutIcon;
358  buttonOption.iconSize = iconSize;
359  contentSize = iconSize;
360  }
361 
362  if ( m_aboutPressedIndex == index ) {
363  buttonOption.state |= QStyle::State_Sunken;
364  }
365  }
366  else if ( type == PluginItemDelegate::Configure ) {
367  if ( m_configIcon.isNull() ) {
368  buttonOption.text = tr( "Configure" );
369  contentSize = buttonOption.fontMetrics.size( 0, buttonOption.text ) + QSize( 4, 4 );
370  }
371  else {
372  buttonOption.icon = m_configIcon;
373  buttonOption.iconSize = iconSize;
374  contentSize = iconSize;
375  }
376  if ( m_configPressedIndex == index ) {
377  buttonOption.state |= QStyle::State_Sunken;
378  }
379  }
380 
381  QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton,
382  &buttonOption,
383  contentSize );
384  buttonOption.rect.setSize( buttonSize );
385  buttonOption.rect = alignRect( buttonOption.rect, option.rect, position, alignment );
386  return buttonOption;
387 }
388 
389 QSize PluginItemDelegate::nameSize( const QModelIndex& index ) const
390 {
391  QString name = index.data( Qt::DisplayRole ).toString();
392  // FIXME: QApplication::fontMetrics() doesn't work for non-application fonts
393  QSize nameSize( QApplication::fontMetrics().size( 0, name ) );
394  return nameSize;
395 }
396 
397 QRect PluginItemDelegate::alignRect( QRect object,
398  QRect frame,
399  int position,
400  Qt::AlignmentFlag alignment ) const
401 {
402  QRect rect = object;
403 
404  rect.setTopLeft( QPoint( 0, 0 ) );
405  // Moves the object to the middle of the item.
406  if ( rect.height() < frame.height() ) {
407  rect.moveTop( ( frame.height() - rect.height() ) / 2 );
408  }
409 
410  if ( alignment & Qt::AlignLeft ) {
411  rect.moveLeft( position );
412  }
413  else if ( alignment & Qt::AlignRight ) {
414  rect.moveRight( position );
415  }
416 
417  return rect;
418 }
419 
420 
421 #include "PluginItemDelegate.moc"
QPainter
Marble::PluginItemDelegate::aboutPluginClicked
void aboutPluginClicked(const QModelIndex &index)
This signal is emitted if the user clicks on a "about"-button of an item in the view passed to the co...
Marble::PluginItemDelegate::sizeHint
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: PluginItemDelegate.cpp:121
RenderPluginModel.h
Marble::PluginItemDelegate::paint
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: PluginItemDelegate.cpp:46
Marble::PluginItemDelegate::PluginItemDelegate
PluginItemDelegate(QAbstractItemView *view, QObject *parent=0)
Definition: PluginItemDelegate.cpp:34
Marble::RenderPluginModel::ConfigurationDialogAvailable
Definition: RenderPluginModel.h:43
QObject
MarbleDebug.h
Marble::PluginItemDelegate::~PluginItemDelegate
~PluginItemDelegate()
Definition: PluginItemDelegate.cpp:42
Marble::None
Definition: tools/osm-addresses/OsmParser.h:40
PluginItemDelegate.h
QAbstractItemModel
Marble::PluginItemDelegate::configPluginClicked
void configPluginClicked(const QModelIndex &index)
This signal is emitted if the user clicks on a "configure"-button of an item in the view passed to th...
Marble::PluginItemDelegate::setAboutIcon
void setAboutIcon(const QIcon &icon)
Definition: PluginItemDelegate.cpp:146
Marble::PluginItemDelegate::setConfigIcon
void setConfigIcon(const QIcon &icon)
Definition: PluginItemDelegate.cpp:151
iconSize
const QSize iconSize(16, 16)
Marble::PluginItemDelegate::editorEvent
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
Definition: PluginItemDelegate.cpp:156
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

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

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