8 #include "MarbleLegendBrowser.h"
10 #include <QCoreApplication>
12 #include <QDesktopServices>
15 #include <QMouseEvent>
19 #ifndef MARBLE_NO_WEBKITWIDGETS
20 #include <QWebEnginePage>
21 #include <QWebChannel>
24 #include <QTextDocument>
26 #include "GeoSceneDocument.h"
27 #include "GeoSceneHead.h"
28 #include "GeoSceneLegend.h"
29 #include "GeoSceneSection.h"
30 #include "GeoSceneIcon.h"
31 #include "GeoSceneItem.h"
32 #include "GeoSceneProperty.h"
33 #include "GeoSceneSettings.h"
35 #include "MarbleDebug.h"
36 #include "TemplateDocument.h"
37 #include "MarbleDirs.h"
42 class MarbleLegendBrowserPrivate
45 MarbleModel *m_marbleModel;
49 MarbleJsWrapper *m_jsWrapper;
56 MarbleLegendBrowser::MarbleLegendBrowser(
QWidget *parent )
57 : MarbleWebView( parent ),
58 d( new MarbleLegendBrowserPrivate )
60 d->m_marbleModel =
nullptr;
61 d->m_jsWrapper =
new MarbleJsWrapper(
this);
64 MarbleLegendBrowser::~MarbleLegendBrowser()
69 void MarbleLegendBrowser::setMarbleModel( MarbleModel *marbleModel )
72 d->m_marbleModel = marbleModel;
74 if ( d->m_marbleModel ) {
75 connect ( d->m_marbleModel, SIGNAL(themeChanged(
QString)),
76 this, SLOT(initTheme()) );
80 QSize MarbleLegendBrowser::sizeHint()
const
82 return QSize( 320, 320 );
85 void MarbleLegendBrowser::initTheme()
88 if ( d->m_marbleModel !=
nullptr && d->m_marbleModel->mapTheme() !=
nullptr )
90 const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
92 d->m_checkBoxMap.clear();
94 for (
const GeoSceneProperty *property: currentMapTheme->settings()->allProperties() ) {
95 if ( property->available() ) {
96 d->m_checkBoxMap[
property->name() ] =
property->value();
100 disconnect ( currentMapTheme, SIGNAL(valueChanged(
QString,
bool)),
nullptr,
nullptr );
101 connect ( currentMapTheme, SIGNAL(valueChanged(
QString,
bool)),
102 this, SLOT(setCheckedProperty(
QString,
bool)) );
110 void MarbleLegendBrowser::loadLegend()
112 if (!d->m_marbleModel) {
116 #ifndef MARBLE_NO_WEBKITWIDGETS
117 if (d->m_currentThemeId != d->m_marbleModel->mapThemeId()) {
118 d->m_currentThemeId = d->m_marbleModel->mapThemeId();
127 if (d->m_marbleModel->mapTheme() !=
nullptr ) {
128 const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
131 currentMapTheme->head()->target() +
QLatin1Char(
'/') +
132 currentMapTheme->head()->theme() +
QLatin1String(
"/legend.html"));
135 legendPath = MarbleDirs::path(QStringLiteral(
"legend.html"));
140 TemplateDocument doc(finalHtml);
141 finalHtml = doc.finalText();
143 injectWebChannel(finalHtml);
144 reverseSupportCheckboxes(finalHtml);
147 const QString sectionsHtml = generateSectionsHtml();
150 finalHtml.
replace(
QString(
"<!-- ##customLegendEntries:all## -->" ), sectionsHtml );
152 translateHtml( finalHtml );
157 MarbleWebPage * page =
new MarbleWebPage(
this);
158 connect( page, SIGNAL(linkClicked(
QUrl)),
this, SLOT(openLinkExternally(
QUrl)) );
159 page->setHtml(finalHtml, baseUrl);
163 channel->
registerObject(QStringLiteral(
"Marble"), d->m_jsWrapper);
164 page->setWebChannel(channel);
166 if ( d->m_marbleModel ) {
167 page->toHtml([=](
QString document ) {
174 void MarbleLegendBrowser::openLinkExternally(
const QUrl &url )
183 bool MarbleLegendBrowser::event(
QEvent * event )
192 return MarbleWebView::event( event );
195 QString MarbleLegendBrowser::readHtml(
const QUrl & name )
209 void MarbleLegendBrowser::translateHtml(
QString & html )
213 QRegExp rx(
"</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*\"|'.*'|[^'\">\\s]+))?)+\\s*|\\s*)/?>" );
214 rx.setMinimal(
true );
221 for (; i !=
end; ++i )
225 void MarbleLegendBrowser::injectWebChannel(
QString &html)
227 QString webChannelCode =
"<script type=\"text/javascript\" src=\"qrc:///qtwebchannel/qwebchannel.js\"></script>";
228 webChannelCode +=
"<script> document.addEventListener(\"DOMContentLoaded\", function() {"
229 "new QWebChannel(qt.webChannelTransport, function (channel) {"
230 "Marble = channel.objects.Marble;"
234 html.
replace(
"</head>", webChannelCode);
237 void MarbleLegendBrowser::reverseSupportCheckboxes(
QString &html)
239 const QString old =
"<a href=\"checkbox:cities\"/>";
242 if (d->m_checkBoxMap[
"cities"])
246 "<input style=\"position: relative; top: -4px;\" type=\"checkbox\" "
247 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked +
QLatin1String(
" name=\"cities\"/>");
252 QString MarbleLegendBrowser::generateSectionsHtml()
258 if ( d->m_marbleModel ==
nullptr || d->m_marbleModel->mapTheme() ==
nullptr )
261 const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
263 d->m_symbolMap.clear();
270 for (
const GeoSceneSection *section: currentMapTheme->legend()->sections() ) {
273 customLegendString +=
QLatin1String(
"<div class=\"well well-small well-legend\">");
277 if (section->checkable()) {
279 QString const checked = d->m_checkBoxMap[section->connectTo()] ?
"checked" :
"";
285 if(!section->radio().isEmpty()) {
287 "<label class=\"section-head\">"
288 "<input style=\"position: relative; top: -4px;\" type=\"radio\" "
289 "onchange=\"Marble.setRadioCheckedProperty(this.value, this.name ,this.checked);\" ") +
296 "<label class=\"section-head\">"
297 "<input style=\"position: relative; top: -4px;\" type=\"checkbox\" "
298 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked +
QLatin1String(
" name=\"") + section->connectTo() +
QLatin1String(
"\" /><span>")
303 customLegendString += checkBoxString;
309 for (
const GeoSceneItem *item: section->items()) {
313 if (item->checkable()) {
314 QString const checked = d->m_checkBoxMap[item->connectTo()] ?
"checked" :
"";
316 "<input type=\"checkbox\" "
317 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ")
325 int pixmapWidth = 24;
326 int pixmapHeight = 12;
327 if (!item->icon()->pixmap().isEmpty()) {
328 QString path = MarbleDirs::path( item->icon()->pixmap() );
329 const QPixmap oncePixmap(path);
330 pixmapWidth = oncePixmap.width();
331 pixmapHeight = oncePixmap.height();
337 src =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
342 const QColor color = item->icon()->color();
346 styleDiv +=
" position: relative; top: -3px;";
349 "<div class=\"legend-entry\">"
352 " <span class=\"kotation\" >") + text +
QLatin1String(
"</span>"
355 customLegendString += html;
360 return customLegendString;
363 void MarbleLegendBrowser::setCheckedProperty(
const QString& name,
bool checked )
365 if (checked != d->m_checkBoxMap[name]) {
366 d->m_checkBoxMap[
name] = checked;
367 emit toggledShowProperty( name, checked );
371 void MarbleLegendBrowser::setRadioCheckedProperty(
const QString& value,
const QString& name ,
bool checked )
374 if (checked != d->m_checkBoxMap[name]) {
375 d->m_checkBoxMap[
name] = checked;
376 emit toggledShowProperty( name, checked );
382 #include "moc_MarbleLegendBrowser.cpp"