• 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
MapThemeDownloadDialog.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 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
9 // Copyright 2013 Dennis Nienhüser <earthwings@gentoo.org>
10 //
11 
12 #include "MapThemeDownloadDialog.h"
13 #include "ui_MapThemeDownloadDialog.h"
14 
15 #include "MarbleDirs.h"
16 #include "NewstuffModel.h"
17 #include "MarbleWidget.h"
18 
19 #include <QPainter>
20 #include <QTextDocument>
21 #include <QAbstractTextDocumentLayout>
22 #include <QStyledItemDelegate>
23 
24 namespace Marble
25 {
26 
27 class MapItemDelegate : public QStyledItemDelegate
28 {
29 public:
30  MapItemDelegate( QListView* view, NewstuffModel* newstuffModel, MarbleWidget* marbleWidget );
31  void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
32  QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
33 
34 protected:
35  bool editorEvent( QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index );
36 
37 private:
38  enum Element {
39  Icon,
40  Text,
41  InstallButton,
42  UpgradeButton,
43  OpenButton,
44  CancelButton,
45  RemoveButton,
46  ProgressReport
47  };
48 
49  int buttonWidth( const QStyleOptionViewItem &option ) const;
50  QStyleOptionButton button( Element element, const QStyleOptionViewItem &option ) const;
51  QRect position( Element element, const QStyleOptionViewItem &option ) const;
52  QString text( const QModelIndex &index ) const;
53  QListView* m_view;
54  NewstuffModel* m_newstuffModel;
55  mutable int m_buttonWidth;
56  int const m_margin;
57  int const m_iconSize;
58  MarbleWidget* m_marbleWidget;
59 };
60 
61 class MapThemeDownloadDialog::Private : public Ui::MapThemeDownloadDialog
62 {
63 public:
64  Private() :
65  m_model()
66  {}
67 
68  NewstuffModel m_model;
69 };
70 
71 MapThemeDownloadDialog::MapThemeDownloadDialog( MarbleWidget* marbleWidget ) :
72  QDialog( marbleWidget ),
73  d( new Private )
74 {
75  d->setupUi( this );
76 
77  d->m_model.setTargetDirectory( MarbleDirs::localPath() + "/maps" );
78  d->m_model.setProvider( "http://edu.kde.org/marble/newstuff/maps-4.5.xml" );
79  d->m_model.setRegistryFile( MarbleDirs::localPath() + "/newstuff/marble-map-themes.knsregistry", Marble::NewstuffModel::NameTag );
80 
81  d->listView->setIconSize( QSize( 130, 130 ) );
82  d->listView->setAlternatingRowColors( true );
83  d->listView->setUniformItemSizes( false );
84  d->listView->setResizeMode( QListView::Adjust );
85  d->listView->setItemDelegate( new MapItemDelegate( d->listView, &d->m_model, marbleWidget ) );
86  d->listView->setModel( &d->m_model );
87 }
88 
89 MapThemeDownloadDialog::~MapThemeDownloadDialog()
90 {
91  delete d;
92 }
93 
94 MapItemDelegate::MapItemDelegate( QListView *view , NewstuffModel *newstuffModel, MarbleWidget* marbleWidget ) :
95  m_view( view ),
96  m_newstuffModel( newstuffModel ),
97  m_buttonWidth( 0 ),
98  m_margin( 5 ),
99  m_iconSize( 16 ),
100  m_marbleWidget( marbleWidget )
101 {
102  // nothing to do
103 }
104 
105 void MapItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
106 {
107  QStyleOptionViewItemV4 styleOption = option;
108  styleOption.text = QString();
109  QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &styleOption, painter);
110 
111  QAbstractTextDocumentLayout::PaintContext paintContext;
112  if (styleOption.state & QStyle::State_Selected) {
113  paintContext.palette.setColor(QPalette::Text,
114  styleOption.palette.color(QPalette::Active, QPalette::HighlightedText));
115  }
116 
117  // Draw the map preview icon
118  QRect const iconRect = position( Icon, option );
119  QIcon const icon = index.data( Qt::DecorationRole ).value<QIcon>();
120  painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
121 
122  // Draw summary, author, and similar information
123  QTextDocument document;
124  QRect const textRect = position( Text, option );
125  document.setTextWidth( textRect.width() );
126  document.setDefaultFont( option.font );
127  document.setHtml( text( index ) );
128 
129  painter->save();
130  painter->translate( textRect.topLeft() );
131  painter->setClipRect( 0, 0, textRect.width(), textRect.height() );
132  document.documentLayout()->draw( painter, paintContext );
133  painter->restore();
134 
135  // Draw buttons and installation progress
136  if ( index.data( NewstuffModel::IsTransitioning ).toBool() ) {
137  qint64 total = qMax( qint64( 1 ), index.data( NewstuffModel::PayloadSize ).value<qint64>() );
138  qint64 progress = index.data( NewstuffModel::DownloadedSize ).value<qint64>();
139 
140  QStyleOptionProgressBar progressBarOption;
141  progressBarOption.rect = position( ProgressReport, option );
142  progressBarOption.minimum = 0;
143  progressBarOption.maximum = 100;
144  progressBarOption.progress = ( 100.0 * progress / total );
145  progressBarOption.text = QString::number( progressBarOption.progress ) + "%";
146  progressBarOption.textVisible = true;
147  QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
148 
149  QStyleOptionButton cancelButton = button( CancelButton, option );
150  QRect installRect = position( CancelButton, option );
151  cancelButton.rect = installRect;
152  QApplication::style()->drawControl( QStyle::CE_PushButton, &cancelButton, painter );
153  } else {
154  bool const installed = index.data( NewstuffModel::IsInstalled ).toBool();
155  bool const upgradable = index.data( NewstuffModel::IsUpgradable ).toBool();
156  Element element = InstallButton;
157  if ( installed ) {
158  element = upgradable ? UpgradeButton : OpenButton;
159  }
160  QStyleOptionButton actionButton = button( element, option );
161  QRect installRect = position( element, option );
162  actionButton.rect = installRect;
163  QApplication::style()->drawControl( QStyle::CE_PushButton, &actionButton, painter );
164 
165  if ( installed ) {
166  QStyleOptionButton removeButton = button( RemoveButton, option );
167  QRect removeRect = position( RemoveButton, option );
168  removeButton.rect = removeRect;
169  QApplication::style()->drawControl( QStyle::CE_PushButton, &removeButton, painter );
170  }
171  }
172 }
173 
174 QSize MapItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
175 {
176  if ( index.column() == 0 ) {
177  QSize const iconSize = option.decorationSize;
178  QTextDocument doc;
179  doc.setDefaultFont( option.font );
180  doc.setTextWidth( qMax( 200, m_view->contentsRect().width() - iconSize.width() - buttonWidth( option ) - 3 * m_margin ) );
181  doc.setHtml( text( index ) );
182  return QSize( iconSize.width() + doc.size().width() + buttonWidth( option ) + 3 * m_margin,
183  2 + qMax( iconSize.height(), qRound( doc.size().height() ) ) );
184  }
185 
186  return QSize();
187 }
188 
189 bool MapItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *, const QStyleOptionViewItem &option, const QModelIndex &index)
190 {
191  if ( ( event->type() == QEvent::MouseButtonRelease ) ) {
192  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
193  if ( index.data( NewstuffModel::IsTransitioning ).toBool() ) {
194  QRect cancelRect = position( CancelButton, option );
195  if ( cancelRect.contains( mouseEvent->pos() ) ) {
196  m_newstuffModel->cancel( index.row() );
197  return true;
198  }
199  } else {
200  bool const installed = index.data( NewstuffModel::IsInstalled ).toBool();
201  bool const upgradable = index.data( NewstuffModel::IsUpgradable ).toBool();
202 
203  if ( !installed || upgradable ) {
204  QRect installRect = position( InstallButton, option );
205  if ( installRect.contains( mouseEvent->pos() ) ) {
206  m_newstuffModel->install( index.row() );
207  return true;
208  }
209  }
210 
211  if ( installed && !upgradable && m_marbleWidget ) {
212  QRect openRect = position( OpenButton, option );
213  if ( openRect.contains( mouseEvent->pos() ) ) {
214  QStringList const files = index.data( NewstuffModel::InstalledFiles ).toStringList();
215  foreach( const QString &file, files ) {
216  if ( file.endsWith( ".dgml" ) ) {
217  QFileInfo dgmlFile( file );
218  QDir baseDir = dgmlFile.dir();
219  baseDir.cdUp();
220  baseDir.cdUp();
221  int const index = baseDir.absolutePath().size();
222  QString const mapTheme = dgmlFile.absoluteFilePath().mid( index+1 );
223  m_marbleWidget->setMapThemeId( mapTheme );
224  return true;
225  }
226  }
227  }
228  }
229 
230  if ( installed ) {
231  QRect removeRect = position( RemoveButton, option );
232  if ( removeRect.contains( mouseEvent->pos() ) ) {
233  m_newstuffModel->uninstall( index.row() );
234  return true;
235  }
236  }
237  }
238  }
239 
240  return false;
241 }
242 
243 int MapItemDelegate::buttonWidth(const QStyleOptionViewItem &option) const
244 {
245  if ( m_buttonWidth <= 0 ) {
246  int const installWidth = option.fontMetrics.size( 0, tr( "Install" ) ).width();
247  int const removeWidth = option.fontMetrics.size( 0, tr( "Remove" ) ).width();
248  int const cancelWidth = option.fontMetrics.size( 0, tr( "Cancel" ) ).width();
249  int const upgradeWidth = option.fontMetrics.size( 0, tr( "Upgrade" ) ).width();
250  m_buttonWidth = 2 * m_iconSize + qMax( qMax( installWidth, removeWidth ),
251  qMax( cancelWidth, upgradeWidth ) );
252  }
253 
254  return m_buttonWidth;
255 }
256 
257 QStyleOptionButton MapItemDelegate::button( Element element, const QStyleOptionViewItem &option ) const
258 {
259  QStyleOptionButton result;
260  result.state = option.state;
261  result.state &= ~QStyle::State_HasFocus;
262 
263  result.palette = option.palette;
264  result.features = QStyleOptionButton::None;
265 
266  switch (element) {
267  case InstallButton:
268  result.text = tr( "Install" );
269  result.icon = QIcon( ":/marble/dialog-ok.png" );
270  result.iconSize = QSize( m_iconSize, m_iconSize );
271  break;
272  case UpgradeButton:
273  result.text = tr( "Update" );
274  result.icon = QIcon( ":/marble/system-software-update.png" );
275  result.iconSize = QSize( m_iconSize, m_iconSize );
276  break;
277  case OpenButton:
278  result.text = tr( "Open" );
279  result.icon = QIcon( ":/marble/document-open.png" );
280  result.iconSize = QSize( m_iconSize, m_iconSize );
281  break;
282  case CancelButton:
283  result.text = tr( "Cancel" );
284  break;
285  case RemoveButton:
286  result.text = tr( "Remove" );
287  result.icon = QIcon( ":/marble/edit-delete.png" );
288  result.iconSize = QSize( m_iconSize, m_iconSize );
289  break;
290  default:
291  // ignored
292  break;
293  }
294 
295  return result;
296 }
297 
298 QRect MapItemDelegate::position(Element element, const QStyleOptionViewItem &option ) const
299 {
300  int const width = buttonWidth( option );
301  QPoint const topLeftCol1 = option.rect.topLeft() + QPoint( 0, 2 );
302  QPoint const topLeftCol2 = topLeftCol1 + QPoint( option.decorationSize.width(), 0 );
303  QPoint const topLeftCol3 = topLeftCol2 + QPoint( option.rect.width() - 3 * m_margin - width - option.decorationSize.width(), 0 );
304  switch (element) {
305  case Icon:
306  return QRect( topLeftCol1, option.decorationSize );
307  case Text:
308  return QRect( topLeftCol2, QSize( topLeftCol3.x()-topLeftCol2.x(), option.rect.height() ) );
309  case InstallButton:
310  case UpgradeButton:
311  case OpenButton:
312  {
313  QStyleOptionButton optionButton = button( element, option );
314  QSize size = option.fontMetrics.size( 0, optionButton.text ) + QSize( 4, 4 );
315  QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton, &optionButton, size );
316  buttonSize.setWidth( width );
317  return QRect( topLeftCol3, buttonSize );
318  }
319  case RemoveButton:
320  case CancelButton:
321  {
322  QStyleOptionButton optionButton = button( element, option );
323  QSize size = option.fontMetrics.size( 0, optionButton.text ) + QSize( 4, 4 );
324  QSize buttonSize = QApplication::style()->sizeFromContents( QStyle::CT_PushButton, &optionButton, size );
325  buttonSize.setWidth( width );
326  return QRect( topLeftCol3 + QPoint( 0, option.fontMetrics.height() + 8 + m_margin ), buttonSize );
327  }
328  case ProgressReport:
329  {
330  QSize const progressSize = QSize( width, option.fontMetrics.height() + 4 );
331  return QRect( topLeftCol3 + QPoint( 0, m_margin ), progressSize );
332  }
333  }
334 
335  Q_ASSERT(false);
336  return QRect();
337 }
338 
339 QString MapItemDelegate::text( const QModelIndex &index ) const
340 {
341  qreal const size = index.data( NewstuffModel::PayloadSize ).toLongLong() / 1024.0 / 1024.0;
342  // Fields are typically not longer than 200 characters. Prevent excessive long text here anyway
343  // due to bug 319542
344  int const maxEntrySize = 4096;
345  return QString("<p><b>%1</b><br />%2</p><p>Author: %3<br />License: %4<br />Version %5 (%6) %7</p>")
346  .arg( index.data().toString() )
347  .arg( index.data( NewstuffModel::Summary ).toString().left( maxEntrySize ) )
348  .arg( index.data( NewstuffModel::Author ).toString().left( maxEntrySize ) )
349  .arg( index.data( NewstuffModel::License ).toString().left( maxEntrySize ) )
350  .arg( index.data( NewstuffModel::Version ).toString().left( maxEntrySize ) )
351  .arg( index.data( NewstuffModel::ReleaseDate ).toString().left( maxEntrySize ) )
352  .arg( size > 0 ? QString( "%1 MB" ).arg( size, 0, 'f', 1 ) : QString() );
353 }
354 
355 }
356 
357 #include "MapThemeDownloadDialog.moc"
QPainter
Marble::NewstuffModel::IsTransitioning
Definition: NewstuffModel.h:51
QDialog
Marble::NewstuffModel::IsInstalled
Definition: NewstuffModel.h:48
Marble::NewstuffModel
Definition: NewstuffModel.h:26
Marble::MarbleDirs::localPath
static QString localPath()
Definition: MarbleDirs.cpp:217
NewstuffModel.h
MapThemeDownloadDialog.h
Marble::NewstuffModel::InstalledFiles
Definition: NewstuffModel.h:47
Marble::MarbleWidget
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:102
Marble::NewstuffModel::ReleaseDate
Definition: NewstuffModel.h:42
Marble::NewstuffModel::PayloadSize
Definition: NewstuffModel.h:52
Marble::MapThemeDownloadDialog::MapThemeDownloadDialog
MapThemeDownloadDialog(MarbleWidget *marbleWidget)
Definition: MapThemeDownloadDialog.cpp:71
Marble::None
Definition: tools/osm-addresses/OsmParser.h:40
Marble::NewstuffModel::License
Definition: NewstuffModel.h:39
MarbleDirs.h
Marble::NewstuffModel::Author
Definition: NewstuffModel.h:38
QAbstractItemModel
Marble::NewstuffModel::Summary
Definition: NewstuffModel.h:40
MarbleWidget.h
This file contains the headers for MarbleWidget.
Marble::NewstuffModel::Version
Definition: NewstuffModel.h:41
MarbleWidget
Wraps a Marble::MarbleWidget, providing access to important properties and methods.
Definition: MarbleDeclarativeWidget.h:50
iconSize
const QSize iconSize(16, 16)
Marble::MapThemeDownloadDialog::~MapThemeDownloadDialog
~MapThemeDownloadDialog()
Definition: MapThemeDownloadDialog.cpp:89
Marble::NewstuffModel::IsUpgradable
Definition: NewstuffModel.h:49
Marble::NewstuffModel::DownloadedSize
Definition: NewstuffModel.h:53
Marble::NewstuffModel::NameTag
Definition: NewstuffModel.h:58
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:38:51 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