8#include "MarbleLegendBrowser.h"
10#include <QCoreApplication>
12#include <QDesktopServices>
19#ifndef MARBLE_NO_WEBKITWIDGETS
20#include <QWebEnginePage>
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"
42class MarbleLegendBrowserPrivate
45 MarbleModel *m_marbleModel;
49 MarbleJsWrapper *m_jsWrapper;
56MarbleLegendBrowser::MarbleLegendBrowser(
QWidget *parent )
57 : MarbleWebView( parent ),
58 d( new MarbleLegendBrowserPrivate )
60 d->m_marbleModel =
nullptr;
61 d->m_jsWrapper =
new MarbleJsWrapper(
this);
64MarbleLegendBrowser::~MarbleLegendBrowser()
69void MarbleLegendBrowser::setMarbleModel( MarbleModel *marbleModel )
72 d->m_marbleModel = marbleModel;
74 if ( d->m_marbleModel ) {
76 this, SLOT(initTheme()) );
80QSize MarbleLegendBrowser::sizeHint()
const
82 return QSize( 320, 320 );
85void 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 );
102 this, SLOT(setCheckedProperty(
QString,
bool)) );
110void 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 ) {
174void MarbleLegendBrowser::openLinkExternally(
const QUrl &url )
183bool MarbleLegendBrowser::event(
QEvent * event )
193QString MarbleLegendBrowser::readHtml(
const QUrl & name )
207void MarbleLegendBrowser::translateHtml(
QString & html )
211 QRegExp rx(
"</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*\"|'.*'|[^'\">\\s]+))?)+\\s*|\\s*)/?>" );
212 rx.setMinimal(
true );
214 s.
replace( QRegExp(
"\\s*\n\\s*" ),
"\n" );
219 for (; i !=
end; ++i )
223void MarbleLegendBrowser::injectWebChannel(
QString &html)
225 QString webChannelCode =
"<script type=\"text/javascript\" src=\"qrc:///qtwebchannel/qwebchannel.js\"></script>";
226 webChannelCode +=
"<script> document.addEventListener(\"DOMContentLoaded\", function() {"
227 "new QWebChannel(qt.webChannelTransport, function (channel) {"
228 "Marble = channel.objects.Marble;"
232 html.
replace(
"</head>", webChannelCode);
235void MarbleLegendBrowser::reverseSupportCheckboxes(
QString &html)
237 const QString old =
"<a href=\"checkbox:cities\"/>";
240 if (d->m_checkBoxMap[
"cities"])
244 "<input style=\"position: relative; top: -4px;\" type=\"checkbox\" "
245 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked +
QLatin1String(
" name=\"cities\"/>");
250QString MarbleLegendBrowser::generateSectionsHtml()
256 if ( d->m_marbleModel ==
nullptr || d->m_marbleModel->mapTheme() ==
nullptr )
259 const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
261 d->m_symbolMap.clear();
268 for (
const GeoSceneSection *section: currentMapTheme->legend()->sections() ) {
271 customLegendString +=
QLatin1String(
"<div class=\"well well-small well-legend\">");
275 if (section->checkable()) {
277 QString const checked = d->m_checkBoxMap[section->connectTo()] ?
"checked" :
"";
283 if(!section->radio().isEmpty()) {
285 "<label class=\"section-head\">"
286 "<input style=\"position: relative; top: -4px;\" type=\"radio\" "
287 "onchange=\"Marble.setRadioCheckedProperty(this.value, this.name ,this.checked);\" ") +
294 "<label class=\"section-head\">"
295 "<input style=\"position: relative; top: -4px;\" type=\"checkbox\" "
296 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked +
QLatin1String(
" name=\"") + section->connectTo() +
QLatin1String(
"\" /><span>")
301 customLegendString += checkBoxString;
307 for (
const GeoSceneItem *item: section->items()) {
311 if (item->checkable()) {
312 QString const checked = d->m_checkBoxMap[item->connectTo()] ?
"checked" :
"";
314 "<input type=\"checkbox\" "
315 "onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ")
323 int pixmapWidth = 24;
324 int pixmapHeight = 12;
325 if (!item->icon()->pixmap().isEmpty()) {
326 QString path = MarbleDirs::path( item->icon()->pixmap() );
327 const QPixmap oncePixmap(path);
328 pixmapWidth = oncePixmap.width();
329 pixmapHeight = oncePixmap.height();
335 src =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
340 const QColor color = item->icon()->color();
344 styleDiv +=
" position: relative; top: -3px;";
347 "<div class=\"legend-entry\">"
350 " <span class=\"kotation\" >") + text +
QLatin1String(
"</span>"
353 customLegendString += html;
358 return customLegendString;
361void MarbleLegendBrowser::setCheckedProperty(
const QString& name,
bool checked )
363 if (checked != d->m_checkBoxMap[name]) {
364 d->m_checkBoxMap[
name] = checked;
365 emit toggledShowProperty( name, checked );
369void MarbleLegendBrowser::setRadioCheckedProperty(
const QString& value,
const QString& name ,
bool checked )
372 if (checked != d->m_checkBoxMap[name]) {
373 d->m_checkBoxMap[
name] = checked;
374 emit toggledShowProperty( name, checked );
380#include "moc_MarbleLegendBrowser.cpp"
This file contains the headers for MarbleModel.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
QString name(GameStandardAction id)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
QString path(const QString &relativePath)
Binds a QML item to a specific geodetic location in screen coordinates.
bool isValid() const const
QString name(NameFormat format) const const
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
bool openUrl(const QUrl &url)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)
QString host(ComponentFormattingOptions options) const const
QString path(ComponentFormattingOptions options) const const
QString scheme() const const
QString toString(FormattingOptions options) const const
void registerObject(const QString &id, QObject *object)