Marble

TourItemDelegate.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2013 Mihail Ivchenko <[email protected]>
4 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <[email protected]>
5 // SPDX-FileCopyrightText: 2014 Illya Kovalevskyy <[email protected]>
6 //
7 
8 #include "TourItemDelegate.h"
9 
10 #include <QAbstractTextDocumentLayout>
11 #include <QStyleOptionButton>
12 #include <QPainter>
13 #include <QApplication>
14 #include <QListView>
15 #include <QPointer>
16 
17 #include "MarblePlacemarkModel.h"
18 #include "geodata/data/GeoDataContainer.h"
19 #include "geodata/data/GeoDataFlyTo.h"
20 #include "geodata/data/GeoDataObject.h"
21 #include "geodata/data/GeoDataTourControl.h"
22 #include "geodata/data/GeoDataWait.h"
23 #include "geodata/data/GeoDataCoordinates.h"
24 #include "geodata/data/GeoDataSoundCue.h"
25 #include "geodata/data/GeoDataAnimatedUpdate.h"
26 #include "FlyToEditWidget.h"
27 #include "TourControlEditWidget.h"
28 #include "SoundCueEditWidget.h"
29 #include "WaitEditWidget.h"
30 #include "RemoveItemEditWidget.h"
31 #include "GeoDataPlacemark.h"
32 #include "GeoDataCreate.h"
33 #include "GeoDataUpdate.h"
34 #include "GeoDataDelete.h"
35 #include "GeoDataChange.h"
36 #include "EditPlacemarkDialog.h"
37 #include "MarbleWidget.h"
38 #include "GeoDataPlaylist.h"
39 #include "TourWidget.h"
40 
41 namespace Marble
42 {
43 
44 TourItemDelegate::TourItemDelegate( QListView* view, MarbleWidget* widget, TourWidget* tour ):
45  m_listView( view ), m_widget( widget ), m_editable( true ), m_tourWidget( tour )
46 {
47  QObject::connect( this, SIGNAL(editingChanged(QModelIndex)), m_listView, SLOT(update(QModelIndex)) );
48  m_listView->setEditTriggers( QAbstractItemView::NoEditTriggers );
49 }
50 
51 void TourItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
52 {
53  QStyleOptionViewItem styleOption = option;
54  styleOption.text = QString();
55  QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &styleOption, painter);
56 
58  if (styleOption.state & QStyle::State_Selected) {
59  paintContext.palette.setColor(QPalette::Text,
60  styleOption.palette.color(QPalette::Active, QPalette::HighlightedText));
61  }
62 
63  if ( m_listView->currentIndex() == index && m_tourWidget->isPlaying() ) {
64  painter->fillRect( option.rect, paintContext.palette.color( QPalette::Midlight ) );
65  QStyledItemDelegate::paint( painter, option, index );
66  }
67 
69  QRect const labelRect = position(Label, option);
70  label.setTextWidth( labelRect.width() );
71  label.setDefaultFont( option.font );
72 
73  QStyleOptionButton button;
74  button.state = option.state;
75  button.palette = option.palette;
76  button.features = QStyleOptionButton::None;
77  button.iconSize = QSize( 16, 16 );
78  button.state &= ~QStyle::State_HasFocus;
79  if( !editable() ) {
80  button.state &= ~QStyle::State_Enabled;
81  }
82 
83  QRect const iconRect = position( GeoDataElementIcon, option );
84 
85  const GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data(MarblePlacemarkModel::ObjectPointerRole));
86  if (!m_editingIndices.contains(index)) {
87  if (const GeoDataTourControl *tourControl = geodata_cast<GeoDataTourControl>(object)) {
88  GeoDataTourControl::PlayMode const playMode = tourControl->playMode();
89 
90  if ( playMode == GeoDataTourControl::Play ) {
91  label.setHtml( tr("Play the tour") );
92  } else if ( playMode == GeoDataTourControl::Pause ) {
93  label.setHtml( tr("Pause the tour") );
94  }
95  painter->save();
96  painter->translate( labelRect.topLeft() );
97  painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
98  label.documentLayout()->draw( painter, paintContext );
99  painter->restore();
100  button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
101 
102  QRect const buttonRect = position( EditButton, option );
103  button.rect = buttonRect;
104 
105  QIcon const icon = QIcon(QStringLiteral(":/marble/media-playback-pause.png"));
106  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
107 
108  } else if (geodata_cast<GeoDataFlyTo>(object)) {
109  GeoDataCoordinates const flyToCoords = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
110  label.setHtml( flyToCoords.toString() );
111  button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
112 
113  painter->save();
114  painter->translate( labelRect.topLeft() );
115  painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
116  label.documentLayout()->draw( painter, paintContext );
117  painter->restore();
118 
119  QRect const buttonRect = position( EditButton, option );
120  button.rect = buttonRect;
121 
122  QIcon const icon = QIcon(QStringLiteral(":/marble/flag.png"));
123  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
124  } else if (const GeoDataWait *wait = geodata_cast<GeoDataWait>(object)) {
125  label.setHtml( tr("Wait for %1 seconds").arg( QString::number( wait->duration() ) ) );
126 
127  painter->save();
128  painter->translate( labelRect.topLeft() );
129  painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
130  label.documentLayout()->draw( painter, paintContext );
131  painter->restore();
132 
133  button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
134 
135  QRect const buttonRect = position( EditButton, option );
136  button.rect = buttonRect;
137 
138  QIcon const icon = QIcon(QStringLiteral(":/marble/player-time.png"));
139  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
140  } else if (const GeoDataSoundCue *soundCue = geodata_cast<GeoDataSoundCue>(object)) {
141  label.setHtml(soundCue->href().section(QLatin1Char('/'), -1));
142 
143  painter->save();
144  painter->translate( labelRect.topLeft() );
145  painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
146  label.documentLayout()->draw( painter, paintContext );
147  painter->restore();
148 
149  QStyleOptionButton playButton = button;
150 
151  button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
152  QRect const buttonRect = position( EditButton, option );
153  button.rect = buttonRect;
154 
155  playButton.icon = QIcon(QStringLiteral(":/marble/playback-play.png"));
156  QRect const playButtonRect = position( ActionButton, option );
157  playButton.rect = playButtonRect;
158  QApplication::style()->drawControl( QStyle::CE_PushButton, &playButton, painter );
159 
160  QIcon const icon = QIcon(QStringLiteral(":/marble/audio-x-generic.png"));
161  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
162  } else if (const GeoDataAnimatedUpdate *animUpdate = geodata_cast<GeoDataAnimatedUpdate>(object)) {
163  const GeoDataUpdate *update = animUpdate->update();
164  bool ok = false;
165  QString iconString;
166  if( update && update->create() && update->create()->size() != 0
167  && (dynamic_cast<const GeoDataContainer *>(&update->create()->first()))) {
168  const GeoDataContainer *container = static_cast<const GeoDataContainer*>(update->create()->child(0));
169  if( container->size() > 0 ) {
170  label.setHtml( tr( "Create item %1" ).arg( container->first().id() ) );
171  ok = true;
172  iconString = QStringLiteral(":/icons/add-placemark.png");
173  }
174  } else if( update && update->getDelete() && update->getDelete()->size() != 0 ){
175  label.setHtml( tr( "Remove item %1" ).arg( update->getDelete()->first().targetId() ) );
176  ok = true;
177  iconString = QStringLiteral(":/icons/remove.png");
178  } else if( update && update->change() && update->change()->size() != 0 ){
179  label.setHtml( tr( "Change item %1" ).arg( update->change()->first().targetId() ) );
180  ok = true;
181  iconString = QStringLiteral(":/marble/document-edit.png");
182  }
183  if( update && !ok ) {
184  label.setHtml( tr( "Update items" ) );
185  button.state &= ~QStyle::State_Enabled & ~QStyle::State_Sunken;
186  }
187 
188  painter->save();
189  painter->translate( labelRect.topLeft() );
190  painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
191  label.documentLayout()->draw( painter, paintContext );
192  painter->restore();
193 
194  button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
195  QRect const buttonRect = position( EditButton, option );
196  button.rect = buttonRect;
197 
198  QIcon const icon = QIcon( iconString );
199  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
200  }
201  }
202 
203  QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter );
204 }
205 
206 QRect TourItemDelegate::position( Element element, const QStyleOptionViewItem &option )
207 {
208  QPoint const topCol1 = option.rect.topLeft() + QPoint(10, 10);
209  QPoint const topCol2 = topCol1 + QPoint(30, 0);
210  QPoint const topCol3 = topCol2 + QPoint(210, 0);
211  QPoint const topCol4 = topCol3 + QPoint(30, 0);
212  QSize const labelSize = QSize(220, 30);
213  QSize const iconsSize = QSize(22, 22);
214 
215  switch(element)
216  {
217  case GeoDataElementIcon:
218  return QRect( topCol1, iconsSize );
219  case Label:
220  return QRect( topCol2, labelSize );
221  case EditButton:
222  return QRect( topCol3, iconsSize );
223  case ActionButton:
224  return QRect( topCol4, iconsSize );
225  }
226  return QRect();
227 }
228 
229 QStringList TourItemDelegate::findIds(const GeoDataPlaylist &playlist, bool onlyFeatures)
230 {
231  QStringList result;
232  for (int i = 0; i < playlist.size(); ++i) {
233  const GeoDataTourPrimitive *primitive = playlist.primitive(i);
234  if( !primitive->id().isEmpty() && !onlyFeatures ) {
235  result << primitive->id();
236  }
237  if (const GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
238  if( animatedUpdate->update() != nullptr ) {
239  const GeoDataUpdate *update = animatedUpdate->update();
240  if( !update->id().isEmpty() && !onlyFeatures ) {
241  result << update->id();
242  }
243  if( update->create() != nullptr ) {
244  if( !update->create()->id().isEmpty() && !onlyFeatures ) {
245  result << update->create()->id();
246  }
247  for( int j = 0; j < update->create()->size(); ++j ) {
248  if( !update->create()->at( j ).id().isEmpty() ) {
249  result << update->create()->at( j ).id();
250  }
251  }
252  }
253  if( update->change() != nullptr ) {
254  if( !update->change()->id().isEmpty() && !onlyFeatures ) {
255  result << update->change()->id();
256  }
257  for( int j = 0; j < update->change()->size(); ++j ) {
258  if( !update->change()->at( j ).id().isEmpty() ) {
259  result << update->change()->at( j ).id();
260  }
261  }
262  }
263  if( update->getDelete() != nullptr ) {
264  if( !update->getDelete()->id().isEmpty() && !onlyFeatures ) {
265  result << update->getDelete()->id();
266  }
267  for( int j = 0; j < update->getDelete()->size(); ++j ) {
268  if( !update->getDelete()->at( j ).id().isEmpty() ) {
269  result << update->getDelete()->at( j ).id();
270  }
271  }
272  }
273  }
274  }
275  }
276  return result;
277 }
278 
279 GeoDataPlaylist *TourItemDelegate::playlist() const
280 {
281  QModelIndex const rootIndex = m_listView->rootIndex();
282  if( rootIndex.isValid() ) {
283  GeoDataObject *rootObject = static_cast<GeoDataObject*>( rootIndex.internalPointer() );
284  if (GeoDataPlaylist *playlist = geodata_cast<GeoDataPlaylist>(rootObject)) {
285  return playlist;
286  }
287  }
288  return nullptr;
289 }
290 
291 
292 QSize TourItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
293 {
294  Q_UNUSED( option );
295  Q_UNUSED( index );
296  return QSize(290,50);
297 }
298 
299 QWidget* TourItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
300 {
301  Q_UNUSED( option );
302  GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data( MarblePlacemarkModel::ObjectPointerRole ) );
303  if (geodata_cast<GeoDataFlyTo>(object)) {
304  FlyToEditWidget* widget = new FlyToEditWidget(index, m_widget, parent);
305  widget->setFirstFlyTo( m_firstFlyTo );
306  connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
307  connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
308  connect( this, SIGNAL(firstFlyToChanged(QPersistentModelIndex)), widget, SLOT(setFirstFlyTo(QPersistentModelIndex)) );
309  return widget;
310 
311  } else if (geodata_cast<GeoDataTourControl>(object)) {
312  TourControlEditWidget* widget = new TourControlEditWidget(index, parent);
313  connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
314  connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
315  return widget;
316 
317  } else if (geodata_cast<GeoDataWait>(object)) {
318  WaitEditWidget* widget = new WaitEditWidget(index, parent);
319  connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
320  connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
321  return widget;
322 
323  } else if (geodata_cast<GeoDataSoundCue>(object)) {
324  SoundCueEditWidget* widget = new SoundCueEditWidget(index, parent);
325  connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
326  connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
327  return widget;
328 
329  } else if (geodata_cast<GeoDataAnimatedUpdate>(object)) {
330  RemoveItemEditWidget* widget = new RemoveItemEditWidget(index, parent);
331  GeoDataPlaylist *playlistObject = playlist();
332  if( playlistObject != nullptr ) {
333  widget->setFeatureIds(findIds(*playlistObject));
334  }
335  widget->setDefaultFeatureId( m_defaultFeatureId );
336  connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
337  connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
338  connect( this, SIGNAL(featureIdsChanged(QStringList)), widget, SLOT(setFeatureIds(QStringList)) );
339  connect( this, SIGNAL(defaultFeatureIdChanged(QString)), widget, SLOT(setDefaultFeatureId(QString)) );
340  return widget;
341 
342  }
343  return nullptr;
344 }
345 
346 bool TourItemDelegate::editable() const
347 {
348  return m_editable;
349 }
350 
351 void TourItemDelegate::setEditable( bool editable )
352 {
353  if( m_editable != editable ) {
354  m_editable = editable;
355  emit editableChanged( m_editable );
356  }
357 }
358 
359 QModelIndex TourItemDelegate::firstFlyTo() const
360 {
361  return m_firstFlyTo;
362 }
363 
364 bool TourItemDelegate::editAnimatedUpdate(GeoDataAnimatedUpdate *animatedUpdate, bool create)
365 {
366  if( animatedUpdate->update() == nullptr ) {
367  return false;
368  }
369  GeoDataFeature *feature = nullptr;
370  if( create && !( animatedUpdate->update()->create() == nullptr || animatedUpdate->update()->create()->size() == 0 ) ) {
371  GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( animatedUpdate->update()->create()->child( 0 ) );
372  if( container != nullptr && container->size() ) {
373  feature = container->child( 0 );
374  }
375  } else if ( !create && !( animatedUpdate->update()->change() == nullptr || animatedUpdate->update()->change()->size() == 0 ) ) {
376  GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( animatedUpdate->update()->change()->child( 0 ) );
377  if( container != nullptr && container->size() ) {
378  feature = container->child( 0 );
379  }
380  }
381  if( feature == nullptr ) {
382  return false;
383  }
384 
385  QStringList ids;
386 
387  GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>( feature );
388 
389  if( !create ) {
390  if( placemark->targetId().isEmpty() && !defaultFeatureId().isEmpty() ) {
391  GeoDataFeature *feature = findFeature( defaultFeatureId() );
392  if (GeoDataPlacemark *targetPlacemark = (feature != nullptr ? geodata_cast<GeoDataPlacemark>(feature) : nullptr)) {
393  animatedUpdate->update()->change()->placemarkList().remove( 0 );
394  delete placemark;
395  placemark = new GeoDataPlacemark( *targetPlacemark );
396  animatedUpdate->update()->change()->placemarkList().insert( 0, placemark );
397  placemark->setTargetId( defaultFeatureId() );
398  placemark->setId(QString());
399  }
400  }
401  }
402 
403  QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog( placemark, nullptr, m_widget );
404  if( create ) {
405  dialog->setWindowTitle( QObject::tr( "Add Placemark to Tour" ) );
406  } else {
407  dialog->setWindowTitle( QObject::tr( "Change Placemark in Tour" ) );
408  dialog->setTargetIdFieldVisible( true );
409  dialog->setIdFieldVisible( false );
410  }
411  GeoDataPlaylist* playlistObject = playlist();
412  if( playlistObject != nullptr ) {
413  ids.append(findIds(*playlistObject, true));
414  }
415  ids.removeOne( placemark->id() );
416  if( create ) {
417  dialog->setIdFilter( ids );
418  } else {
419  dialog->setTargetIds( ids );
420  }
421  bool status = dialog->exec();
422  if( !create ) {
423  placemark->setId(QString());
424  }
425  return status;
426 }
427 
428 QString TourItemDelegate::defaultFeatureId() const
429 {
430  return m_defaultFeatureId;
431 }
432 
433 
434 
435 GeoDataFeature *TourItemDelegate::findFeature(const QString &id) const
436 {
437  GeoDataPlaylist *playlistObject = playlist();
438  if( playlistObject == nullptr ) {
439  return nullptr;
440  }
441  GeoDataFeature *result = nullptr;
442  for( int i = 0; i < playlistObject->size(); ++i ) {
443  GeoDataTourPrimitive *primitive = playlistObject->primitive( i );
444  if (GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
445  if( animatedUpdate->update() != nullptr ) {
446  GeoDataUpdate *update = animatedUpdate->update();
447  if( update->create() != nullptr ) {
448  for( int j = 0; j < update->create()->featureList().size(); ++j ) {
449  if( update->create()->at( j ).id() == id ) {
450  result = update->create()->featureList().at( j );
451  }
452  }
453  }
454  if( update->change() != nullptr ) {
455  for( int j = 0; j < update->change()->featureList().size(); ++j ) {
456  if( update->change()->at( j ).id() == id ) {
457  result = update->change()->featureList().at( j );
458  }
459  }
460  }
461  if( update->getDelete() != nullptr ) {
462  for( int j = 0; j < update->getDelete()->featureList().size(); ++j ) {
463  if( update->getDelete()->at( j ).id() == id ) {
464  result = update->getDelete()->featureList().at( j );
465  }
466  }
467  }
468  }
469  }
470  }
471  return result;
472 }
473 
474 void TourItemDelegate::setFirstFlyTo(const QPersistentModelIndex &index )
475 {
476  m_firstFlyTo = index;
477  emit firstFlyToChanged( m_firstFlyTo );
478 }
479 
480 void TourItemDelegate::setDefaultFeatureId(const QString &id)
481 {
482  m_defaultFeatureId = id;
483  const QStringList ids = playlist() ? findIds(*playlist()) : QStringList();
484  emit featureIdsChanged( ids );
485  emit defaultFeatureIdChanged( id );
486 }
487 
488 bool TourItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
489 {
490  Q_UNUSED( model );
491  if ( ( event->type() == QEvent::MouseButtonRelease ) && editable() ) {
492  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
493  QRect editRect = position( EditButton, option );
494  if ( editRect.contains( mouseEvent->pos() ) ) {
495  if( m_editingIndices.contains( index ) ) {
496  m_editingIndices.removeOne( index );
497  emit editingChanged( index );
498  return true;
499  }else{
500  GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data( MarblePlacemarkModel::ObjectPointerRole ) );
501  if (GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(object)) {
502  if( animatedUpdate->update() && animatedUpdate->update()->create() ) {
503  if( editAnimatedUpdate( animatedUpdate ) ) {
504  setDefaultFeatureId( m_defaultFeatureId );
505  }
506  } else if( animatedUpdate->update() && animatedUpdate->update()->change() ) {
507  editAnimatedUpdate( animatedUpdate, false );
508  } else if ( animatedUpdate->update() && animatedUpdate->update()->getDelete() ) {
509  m_editingIndices.append( index );
510  m_listView->openPersistentEditor( index );
511  }
512  } else {
513  m_editingIndices.append( index );
514  m_listView->openPersistentEditor( index );
515  }
516  }
517  emit editingChanged( index );
518  return true;
519  }
520  }
521  return false;
522 }
523 
524 void TourItemDelegate::closeEditor( const QModelIndex &index )
525 {
526  emit edited( index );
527  m_listView->closePersistentEditor( index );
528  m_editingIndices.removeOne( index );
529 }
530 
531 }
532 
533 #include "moc_TourItemDelegate.cpp"
void append(const T &value)
QPoint pos() const const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
MouseButtonRelease
QPoint topLeft() const const
QString number(int n, int base)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
QSize size() const const
void * internalPointer() const const
T value() const const
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
int width() const const
bool contains(const QRect &rectangle, bool proper) const const
void fillRect(const QRectF &rectangle, const QBrush &brush)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
@ ObjectPointerRole
The pointer to a specific object.
QVariant data(int role) const const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const override
bool removeOne(const T &value)
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
virtual QVariant rootObject()
@ CoordinateRole
The GeoDataCoordinates coordinate.
Binds a QML item to a specific geodetic location in screen coordinates.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
bool isValid() const const
QString label(StandardShortcut id)
int height() const const
QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) const const
void update(Part *part, const QByteArray &data, qint64 dataSize)
QModelIndex child(int row, int column) const const
void translate(const QPointF &offset)
void restore()
void save()
QString tr(const char *sourceText, const char *disambiguation, int n)
QStyle * style()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 04:07:51 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.