• 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
MarbleLegendBrowser.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Project.
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 2006-2007 Torsten Rahn <tackat@kde.org>
9 // Copyright 2007 Inge Wallin <ingwa@kde.org>
10 // Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
11 //
12 
13 
14 #include "MarbleLegendBrowser.h"
15 
16 #include <QTime>
17 #include <QUrl>
18 #include <QDesktopServices>
19 #include <QEvent>
20 #include <QFile>
21 #include <QFileInfo>
22 #include <QMouseEvent>
23 #include <QPainter>
24 #include <QTextFrame>
25 #include <QScrollBar>
26 #include <QStyle>
27 #include <QStyleOptionButton>
28 #include <QDesktopServices>
29 #include <QRegExp>
30 #include <QWebFrame>
31 #include <QWebElement>
32 #include <QTextDocument>
33 
34 #include "GeoSceneDocument.h"
35 #include "GeoSceneHead.h"
36 #include "GeoSceneLegend.h"
37 #include "GeoSceneSection.h"
38 #include "GeoSceneIcon.h"
39 #include "GeoSceneItem.h"
40 #include "GeoSceneProperty.h"
41 #include "GeoSceneSettings.h"
42 #include "MarbleModel.h"
43 #include "MarbleDebug.h"
44 #include "TemplateDocument.h"
45 
46 #include "MarbleDirs.h"
47 
48 namespace Marble
49 {
50 
51 class MarbleLegendBrowserPrivate
52 {
53  public:
54  MarbleModel *m_marbleModel;
55  QMap<QString, bool> m_checkBoxMap;
56  QMap<QString, QPixmap> m_symbolMap;
57  bool m_isLegendLoaded;
58 #ifdef Q_WS_MAEMO_5
59  bool m_suppressSelection;
60 #endif // Q_WS_MAEMO_5
61 };
62 
63 
64 // ================================================================
65 
66 
67 MarbleLegendBrowser::MarbleLegendBrowser( QWidget *parent )
68  : MarbleWebView( parent ),
69  d( new MarbleLegendBrowserPrivate )
70 {
71  d->m_isLegendLoaded = false;
72  d->m_marbleModel = 0;
73 #ifdef Q_WS_MAEMO_5
74  d->m_suppressSelection = false;
75 #endif // Q_WS_MAEMO_5
76 
77  QWebFrame *frame = page()->mainFrame();
78  connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
79  this, SLOT(injectCheckBoxChecker()));
80  page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
81  connect( this, SIGNAL(linkClicked(QUrl)), this, SLOT(openLinkExternally(QUrl)) );
82 }
83 
84 MarbleLegendBrowser::~MarbleLegendBrowser()
85 {
86  delete d;
87 }
88 
89 void MarbleLegendBrowser::setMarbleModel( MarbleModel *marbleModel )
90 {
91  // We need this to be able to get to the MapTheme.
92  d->m_marbleModel = marbleModel;
93 
94  if ( d->m_marbleModel ) {
95  connect ( d->m_marbleModel, SIGNAL(themeChanged(QString)),
96  this, SLOT(initTheme()) );
97  }
98 }
99 
100 QSize MarbleLegendBrowser::sizeHint() const
101 {
102  return QSize( 180, 320 );
103 }
104 
105 void MarbleLegendBrowser::initTheme()
106 {
107  // Check for a theme specific legend.html first
108  if ( d->m_marbleModel != 0 && d->m_marbleModel->mapTheme() != 0 )
109  {
110  const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
111 
112  d->m_checkBoxMap.clear();
113 
114  foreach ( const GeoSceneProperty *property, currentMapTheme->settings()->allProperties() ) {
115  if ( property->available() ) {
116  d->m_checkBoxMap[ property->name() ] = property->value();
117  }
118  }
119 
120  disconnect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)), 0, 0 );
121  connect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)),
122  this, SLOT(setCheckedProperty(QString,bool)) );
123  }
124 
125  if ( isVisible() ) {
126  loadLegend();
127  }
128  else {
129  d->m_isLegendLoaded = false;
130  }
131 }
132 
133 void MarbleLegendBrowser::loadLegend()
134 {
135 
136  // Read the html string.
137  QString legendPath;
138 
139  // Check for a theme specific legend.html first
140  if ( d->m_marbleModel != 0 && d->m_marbleModel->mapTheme() != 0 )
141  {
142  const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
143 
144  legendPath = MarbleDirs::path( "maps/" +
145  currentMapTheme->head()->target() + '/' +
146  currentMapTheme->head()->theme() + "/legend.html" );
147  }
148  if ( legendPath.isEmpty() ) {
149  legendPath = MarbleDirs::path( "legend.html" );
150  }
151 
152  QString finalHtml = readHtml( QUrl::fromLocalFile( legendPath ) );
153 
154  TemplateDocument doc(finalHtml);
155  finalHtml = doc.finalText();
156 
157  reverseSupportCheckboxes(finalHtml);
158 
159  // Generate some parts of the html from the MapTheme <Legend> tag.
160  const QString sectionsHtml = generateSectionsHtml();
161 
162  // And then create the final html from these two parts.
163  finalHtml.replace( QString( "<!-- ##customLegendEntries:all## -->" ), sectionsHtml );
164 
165  translateHtml( finalHtml );
166 
167  QUrl baseUrl = QUrl::fromLocalFile( legendPath );
168 
169  // Set the html string in the QTextBrowser.
170  setHtml(finalHtml, baseUrl);
171 
172  if ( d->m_marbleModel ) {
173  QTextDocument *document = new QTextDocument(page()->mainFrame()->toHtml());
174  d->m_marbleModel->setLegend( document );
175  }
176 }
177 
178 void MarbleLegendBrowser::injectCheckBoxChecker()
179 {
180  QWebFrame *frame = page()->mainFrame();
181  frame->addToJavaScriptWindowObject( "Marble", this );
182 }
183 
184 void MarbleLegendBrowser::openLinkExternally( const QUrl &url )
185 {
186  QDesktopServices::openUrl( url );
187 }
188 
189 bool MarbleLegendBrowser::event( QEvent * event )
190 {
191  // "Delayed initialization": legend gets created only
192  if ( event->type() == QEvent::Show ) {
193  if ( !d->m_isLegendLoaded ) {
194  loadLegend();
195  }
196  }
197 #ifdef Q_WS_MAEMO_5
198  else if ( event->type() == QEvent::MouseButtonPress ) {
199  if ( static_cast<QMouseEvent *>( event )->button() == Qt::LeftButton ) {
200  d->m_suppressSelection = true;
201  }
202  }
203  else if ( event->type() == QEvent::MouseButtonRelease ) {
204  if ( static_cast<QMouseEvent *>( event )->button() == Qt::LeftButton ) {
205  d->m_suppressSelection = false;
206  }
207  }
208  else if ( event->type() == QEvent::MouseMove ) {
209  if ( d->m_suppressSelection ) {
210  // eat event to suppress text selection under Maemo5
211  return true;
212  }
213  }
214 #endif // Q_WS_MAEMO_5
215 
216  return MarbleWebView::event( event );
217 }
218 
219 QString MarbleLegendBrowser::readHtml( const QUrl & name )
220 {
221  QString html;
222 
223  QFile data( name.toLocalFile() );
224  if ( data.open( QFile::ReadOnly ) ) {
225  QTextStream in( &data );
226  html = in.readAll();
227  data.close();
228  }
229 
230  return html;
231 }
232 
233 void MarbleLegendBrowser::translateHtml( QString & html )
234 {
235  // must match string extraction in Messages.sh
236  QString s = html.remove( 0, html.indexOf( "<body>" ) );
237  QRegExp rx( "</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*\"|'.*'|[^'\">\\s]+))?)+\\s*|\\s*)/?>" );
238  rx.setMinimal( true );
239  s.replace( rx, "\n" );
240  s.replace( QRegExp( "\\s*\n\\s*" ), "\n" );
241  QStringList words = s.split( '\n', QString::SkipEmptyParts );
242 
243  QStringList::const_iterator i = words.constBegin();
244  QStringList::const_iterator const end = words.constEnd();
245  for (; i != end; ++i )
246  html.replace( *i, tr( (*i).toUtf8() ) );
247 }
248 
249 void MarbleLegendBrowser::reverseSupportCheckboxes(QString &html)
250 {
251  const QString old = "<H4> <!--Locations checkbox--><a href=\"checkbox:cities\"><span style=\"text-decoration: none\"><img src=\"checkbox:cities\">&nbsp;</span></a> Populated Places</H4>";
252 
253  QString checked = "";
254  if (d->m_checkBoxMap["cities"])
255  checked = "checked";
256 
257  const QString repair = ""
258  "<div class=\"spec\"><h3><input type=\"checkbox\" "
259  "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" "
260  + checked + " name=\"cities\" />Populated Places</h3></div>\n";
261 
262  html.replace(old, repair);
263 }
264 
265 QString MarbleLegendBrowser::generateSectionsHtml()
266 {
267  // Generate HTML to include into legend.html here.
268 
269  QString customLegendString;
270 
271  if ( d->m_marbleModel == 0 || d->m_marbleModel->mapTheme() == 0 )
272  return QString();
273 
274  const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
275 
276  d->m_symbolMap.clear();
277 
278  /* This CSS code is required to style the following HTML code
279  * P.S. It use bootstrap also, so we don't need a lot of style here
280  */
281  QString bitStyle = "<style>"
282  ".well-legend {"
283  " background-color: #fcffdb;"
284  " padding-top: 10px;"
285  " padding-bottom: 5px;"
286  ""
287  "}"
288  ".legend-entry {"
289  " margin-bottom: -10px!important;"
290  "}"
291  ".well-legend .section-head {"
292  " color: #b3925d!important;"
293  "}"
294  ".legend-entry .image-pic {"
295  " float: left;"
296  " margin-right: 20px;"
297  " margin-top: 3px;"
298  "}"
299  ".legend-entry .notation {"
300  " line-height: 23px;"
301  "}"
302  "label span {"
303  " line-height: 30px;"
304  " font-weight: 600;"
305  "}"
306  "label input {"
307  " margin-right: 5px!important;"
308  "}"
309  "</style>";
310 
311  customLegendString += bitStyle;
312 
313  /* Okay, if you are reading it now, be ready for hell!
314  * We can't optimize this part of Legend Browser, but we will
315  * do it, anyway. It's complicated a lot, the most important
316  * thing is to understand everything.
317  */
318  foreach ( const GeoSceneSection *section, currentMapTheme->legend()->sections() ) {
319  // Each section is divided into the "well"
320  // Well is like a block of data with rounded corners
321  customLegendString += "<div class=\"well well-small well-legend\">";
322 
323  customLegendString += "<h4 class=\"section-head\">"+section->heading()+"</h4>";
324 
325  QString checkBoxString;
326  if (section->checkable()) {
327  // If it's needed to make a checkbox here, we will
328  QString checked = "";
329  if (d->m_checkBoxMap[section->connectTo()])
330  checked = "checked";
331  /* Important comment:
332  * We inject Marble object into JavaScript of each legend html file
333  * This is only one way to handle checkbox changes we see, so
334  * Marble.setCheckedProperty is a function that does it
335  */
336  checkBoxString = ""
337  "<label class=\"checkbox\">"
338  "<input type=\"checkbox\" "
339  "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" " +
340  checked + " name=\"" + section->connectTo() + "\" /><span>"
341  + section->heading() +
342  "</span></label>";
343  customLegendString += checkBoxString;
344  }
345 
346  foreach (const GeoSceneItem *item, section->items()) {
347  QString path = "";
348  int pixmapWidth = 24;
349  int pixmapHeight = 12;
350  // NOTICE. There are some pixmaps without image, so we should
351  // create just a plain rectangle with set color
352  if (!item->icon()->pixmap().isEmpty()) {
353  path = MarbleDirs::path( item->icon()->pixmap() );
354  const QPixmap oncePixmap(path);
355  pixmapWidth = oncePixmap.width();
356  pixmapHeight = oncePixmap.height();
357  }
358  QColor color = item->icon()->color();
359  QString styleDiv = "";
360  if (color != Qt::transparent) {
361  styleDiv = "width: " + QString::number(pixmapWidth) + "px; height: " +
362  QString::number(pixmapHeight) + "px; background-color: "
363  + color.name() + ";";
364  } else {
365  styleDiv = "width: " + QString::number(pixmapWidth) + "px; height: " +
366  QString::number(pixmapHeight) + "px;";
367  }
368  QString src = QUrl::fromLocalFile( path ).toString();
369  QString html = ""
370  "<div class=\"legend-entry\">"
371  " <img class=\"image-pic\""
372  " src=\"" + src + "\" style=\"" + styleDiv + "\" />"
373  " <p class=\"notation\">" + item->text() + "</p>"
374  "</div>";
375  customLegendString += html;
376  }
377  customLegendString += "</div>"; // <div class="well">
378  }
379 
380  return customLegendString;
381 }
382 
383 void MarbleLegendBrowser::setCheckedProperty( const QString& name, bool checked )
384 {
385  QWebElement box = page()->mainFrame()->findFirstElement("input[name="+name+"]");
386  if (!box.isNull()) {
387  if (checked != d->m_checkBoxMap[name]) {
388  d->m_checkBoxMap[name] = checked;
389  emit toggledShowProperty( name, checked );
390  }
391  }
392 
393  update();
394 }
395 
396 }
397 
398 #include "MarbleLegendBrowser.moc"
GeoSceneHead.h
Marble::GeoSceneItem
The section item in a legend of a GeoScene document.
Definition: GeoSceneItem.h:38
GeoSceneProperty.h
Marble::MarbleLegendBrowser::toggledShowProperty
void toggledShowProperty(QString, bool)
Marble::GeoSceneProperty
Settings property within a GeoScene document.
Definition: GeoSceneProperty.h:39
Marble::MarbleDirs::path
static QString path(const QString &relativePath)
Definition: MarbleDirs.cpp:53
Marble::GeoSceneItem::icon
const GeoSceneIcon * icon() const
Definition: GeoSceneItem.cpp:50
GeoSceneItem.h
Marble::MarbleLegendBrowser::sizeHint
QSize sizeHint() const
Definition: MarbleLegendBrowser.cpp:100
MarbleModel.h
This file contains the headers for MarbleModel.
QWidget
MarbleWebView
Definition: MarbleWebView.h:18
Marble::GeoSceneItem::text
QString text() const
Definition: GeoSceneItem.cpp:65
GeoSceneDocument.h
Marble::GeoSceneSection::checkable
bool checkable() const
Definition: GeoSceneSection.cpp:113
MarbleDebug.h
Marble::GeoSceneDocument::legend
const GeoSceneLegend * legend() const
Definition: GeoSceneDocument.cpp:116
Marble::MarbleLegendBrowser::translateHtml
void translateHtml(QString &html)
Definition: MarbleLegendBrowser.cpp:233
Marble::MarbleLegendBrowser::setCheckedProperty
void setCheckedProperty(const QString &name, bool checked)
Definition: MarbleLegendBrowser.cpp:383
TemplateDocument.h
Marble::GeoSceneSection::connectTo
QString connectTo() const
Definition: GeoSceneSection.cpp:123
MarbleDirs.h
Marble::MarbleLegendBrowser::MarbleLegendBrowser
MarbleLegendBrowser(QWidget *parent)
Definition: MarbleLegendBrowser.cpp:67
Marble::GeoSceneSection::heading
QString heading() const
Definition: GeoSceneSection.cpp:103
Marble::GeoSceneDocument
A container for features parsed from the DGML file.
Definition: GeoSceneDocument.h:44
Marble::MarbleLegendBrowser::~MarbleLegendBrowser
~MarbleLegendBrowser()
Definition: MarbleLegendBrowser.cpp:84
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:96
Marble::GeoSceneSection
Section of a GeoScene document.
Definition: GeoSceneSection.h:39
GeoSceneSettings.h
GeoSceneSection.h
Marble::MarbleLegendBrowser::readHtml
QString readHtml(const QUrl &name)
Definition: MarbleLegendBrowser.cpp:219
Marble::GeoSceneIcon::pixmap
QString pixmap() const
Definition: GeoSceneIcon.cpp:37
MarbleLegendBrowser.h
Marble::MarbleLegendBrowser::generateSectionsHtml
QString generateSectionsHtml()
Definition: MarbleLegendBrowser.cpp:265
Marble::GeoSceneLegend::sections
QVector< const GeoSceneSection * > sections() const
Definition: GeoSceneLegend.cpp:86
GeoSceneLegend.h
Marble::GeoSceneSection::items
QVector< GeoSceneItem * > items() const
Definition: GeoSceneSection.cpp:93
Marble::GeoSceneProperty::available
bool available() const
Definition: GeoSceneProperty.cpp:48
GeoSceneIcon.h
Marble::MarbleLegendBrowser::setMarbleModel
void setMarbleModel(MarbleModel *marbleModel)
Definition: MarbleLegendBrowser.cpp:89
Marble::GeoSceneSettings::allProperties
QVector< GeoSceneProperty * > allProperties()
Get the whole list of properties stored in the settings.
Definition: GeoSceneSettings.cpp:143
Marble::GeoSceneIcon::color
QColor color() const
Definition: GeoSceneIcon.cpp:47
Marble::GeoSceneDocument::settings
const GeoSceneSettings * settings() const
Definition: GeoSceneDocument.cpp:106
Marble::MarbleLegendBrowser::event
bool event(QEvent *event)
Definition: MarbleLegendBrowser.cpp:189
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