UBGraphicsWidgetItem.cpp 37.1 KB
Newer Older
Claudio Valerio's avatar
Claudio Valerio committed
1
/*
2
 * Copyright (C) 2015-2018 Département de l'Instruction Publique (DIP-SEM)
Craig Watson's avatar
Craig Watson committed
3
 *
Claudio Valerio's avatar
Claudio Valerio committed
4
 * Copyright (C) 2013 Open Education Foundation
Claudio Valerio's avatar
Claudio Valerio committed
5
 *
Claudio Valerio's avatar
Claudio Valerio committed
6 7
 * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
 * l'Education Numérique en Afrique (GIP ENA)
8
 *
Claudio Valerio's avatar
Claudio Valerio committed
9 10 11
 * This file is part of OpenBoard.
 *
 * OpenBoard is free software: you can redistribute it and/or modify
Claudio Valerio's avatar
Claudio Valerio committed
12 13
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License,
14 15 16 17
 * with a specific linking exception for the OpenSSL project's
 * "OpenSSL" library (or with modified versions of it that use the
 * same license as the "OpenSSL" library).
 *
Claudio Valerio's avatar
Claudio Valerio committed
18
 * OpenBoard is distributed in the hope that it will be useful,
Claudio Valerio's avatar
Claudio Valerio committed
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Claudio Valerio's avatar
Claudio Valerio committed
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Claudio Valerio's avatar
Claudio Valerio committed
21
 * GNU General Public License for more details.
Claudio Valerio's avatar
Claudio Valerio committed
22
 *
Claudio Valerio's avatar
Claudio Valerio committed
23
 * You should have received a copy of the GNU General Public License
Claudio Valerio's avatar
Claudio Valerio committed
24
 * along with OpenBoard. If not, see <http://www.gnu.org/licenses/>.
Claudio Valerio's avatar
Claudio Valerio committed
25
 */
Claudio Valerio's avatar
Claudio Valerio committed
26

27

Claudio Valerio's avatar
Claudio Valerio committed
28

Claudio Valerio's avatar
Claudio Valerio committed
29

30 31
#include <QtNetwork>
#include <QtXml>
32
#include <QWebFrame>
Claudio Valerio's avatar
Claudio Valerio committed
33

34 35
#include "UBGraphicsWidgetItem.h"
#include "UBGraphicsScene.h"
Claudio Valerio's avatar
Claudio Valerio committed
36 37 38 39
#include "UBGraphicsItemDelegate.h"
#include "UBGraphicsWidgetItemDelegate.h"
#include "UBGraphicsDelegateFrame.h"

40 41 42 43
#include "api/UBWidgetUniboardAPI.h"
#include "api/UBW3CWidgetAPI.h"

 #include "board/UBBoardController.h"
Claudio Valerio's avatar
Claudio Valerio committed
44

45
#include "core/memcheck.h"
46 47 48
#include "core/UBApplicationController.h"
#include "core/UBApplication.h"
#include "core/UBSettings.h"
49

50
#include "frameworks/UBFileSystemUtils.h"
51 52
#include "frameworks/UBPlatformUtils.h"

53
#include "network/UBNetworkAccessManager.h"
54

55 56 57
#include "web/UBWebPage.h"
#include "web/UBWebKitUtils.h"
#include "web/UBWebController.h"
58

59 60
bool UBGraphicsWidgetItem::sInlineJavaScriptLoaded = false;
QStringList UBGraphicsWidgetItem::sInlineJavaScripts;
61

Yimgo's avatar
Yimgo committed
62
UBGraphicsWidgetItem::UBGraphicsWidgetItem(const QUrl &pWidgetUrl, QGraphicsItem *parent)
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
63
    : QGraphicsWebView(parent)
64 65
    , mInitialLoadDone(false)
    , mIsFreezable(true)
66
    , mIsResizable(false)
67
    , mLoadIsErronous(false)
68 69
    , mCanBeContent(0)
    , mCanBeTool(0)
Yimgo's avatar
Yimgo committed
70
    , mWidgetUrl(pWidgetUrl)
71 72
    , mIsFrozen(false)
    , mIsTakingSnapshot(false)
Claudio Valerio's avatar
Claudio Valerio committed
73
    , mShouldMoveWidget(false)
74
    , mUniboardAPI(0)
Claudio Valerio's avatar
Claudio Valerio committed
75
{
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
76
    setData(UBGraphicsItemData::ItemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly
Claudio Valerio's avatar
Claudio Valerio committed
77

78 79 80 81 82 83 84 85
    QGraphicsWebView::setPage(new UBWebPage(this));
    QGraphicsWebView::settings()->setAttribute(QWebSettings::JavaEnabled, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::PluginsEnabled, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
    QGraphicsWebView::settings()->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
86
    QGraphicsWebView::settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true);
Claudio Valerio's avatar
Claudio Valerio committed
87

88
    page()->setNetworkAccessManager(UBNetworkAccessManager::defaultAccessManager());
Claudio Valerio's avatar
Claudio Valerio committed
89

90
    setAcceptDrops(true);
91
    setAutoFillBackground(false);
Claudio Valerio's avatar
Claudio Valerio committed
92

93 94 95 96
    QPalette pagePalette = page()->palette();
    pagePalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
    pagePalette.setBrush(QPalette::Window, QBrush(Qt::transparent));
    page()->setPalette(pagePalette);
Claudio Valerio's avatar
Claudio Valerio committed
97

98 99 100 101
    QPalette viewPalette = palette();
    pagePalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
    viewPalette.setBrush(QPalette::Window, QBrush(Qt::transparent));
    setPalette(viewPalette);
Claudio Valerio's avatar
Claudio Valerio committed
102

103
    setDelegate(new UBGraphicsWidgetItemDelegate(this));
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
104 105 106

    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    QGraphicsWebView::setAcceptHoverEvents(true);
Claudio Valerio's avatar
Claudio Valerio committed
107 108 109 110
}


UBGraphicsWidgetItem::~UBGraphicsWidgetItem()
root's avatar
root committed
111
{
112
    /* NOOP */
root's avatar
root committed
113
}
Claudio Valerio's avatar
Claudio Valerio committed
114

115
void UBGraphicsWidgetItem::initialize()
Claudio Valerio's avatar
Claudio Valerio committed
116
{
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
117
    setMinimumSize(nominalSize());
118
    setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); // Necessary to set if we want z value to be assigned correctly
Claudio Valerio's avatar
Claudio Valerio committed
119

120 121
    if (Delegate() && Delegate()->frame() && resizable())
        Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::Resizing);
Claudio Valerio's avatar
Claudio Valerio committed
122

123 124
    QPalette palette = page()->palette();
    palette.setBrush(QPalette::Base, QBrush(Qt::transparent));
shibakaneki's avatar
shibakaneki committed
125 126
    page()->setPalette(palette);
    page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
Claudio Valerio's avatar
Claudio Valerio committed
127

128 129
    connect(page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared,
            this, &UBGraphicsWidgetItem::javaScriptWindowObjectCleared);
130
    connect(page(), SIGNAL(geometryChangeRequested(const QRect&)), this, SLOT(geometryChangeRequested(const QRect&)));
131
    connect(this, SIGNAL(loadFinished(bool)), this, SLOT(mainFrameLoadFinished (bool)));
132
    connect(page()->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(initialLayoutCompleted()));
shibakaneki's avatar
shibakaneki committed
133 134 135
    connect(page(), SIGNAL(linkClicked(const QUrl&)), this, SLOT(onLinkClicked(const QUrl&)));
}

136 137
void UBGraphicsWidgetItem::onLinkClicked(const QUrl& url)
{
138
    load(url);
Claudio Valerio's avatar
Claudio Valerio committed
139 140
}

141 142 143 144 145
void UBGraphicsWidgetItem::initialLayoutCompleted()
{
    mInitialLoadDone = true;
}

146
QUrl UBGraphicsWidgetItem::mainHtml()
Claudio Valerio's avatar
Claudio Valerio committed
147
{
148
    return mMainHtmlUrl;
Claudio Valerio's avatar
Claudio Valerio committed
149 150
}

151
void UBGraphicsWidgetItem::loadMainHtml()
152
{
153
    mInitialLoadDone = false;
154
    load(mMainHtmlUrl);
155
}
156 157

QUrl UBGraphicsWidgetItem::widgetUrl()
158
{
159
    return mWidgetUrl;
160
}
161

162
QString UBGraphicsWidgetItem::mainHtmlFileName()
163
{
164
    return mMainHtmlFileName;
165 166
}

167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
bool UBGraphicsWidgetItem::canBeContent()
{
    // if we under MAC OS
    #if defined(Q_OS_MAC)
        return mCanBeContent & UBGraphicsWidgetItem::type_MAC;
    #endif

    // if we under UNIX OS
    #if defined(Q_OS_UNIX)
        return mCanBeContent & UBGraphicsWidgetItem::type_UNIX;
    #endif

    // if we under WINDOWS OS
    #if defined(Q_OS_WIN)
        return mCanBeContent & UBGraphicsWidgetItem::type_WIN;
    #endif
}
Claudio Valerio's avatar
Claudio Valerio committed
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
bool UBGraphicsWidgetItem::canBeTool()
{
    // if we under MAC OS
    #if defined(Q_OS_MAC)
        return mCanBeTool & UBGraphicsWidgetItem::type_MAC;
    #endif

        // if we under UNIX OS
    #if defined(Q_OS_UNIX)
        return mCanBeTool & UBGraphicsWidgetItem::type_UNIX;
    #endif

        // if we under WINDOWS OS
    #if defined(Q_OS_WIN)
        return mCanBeTool & UBGraphicsWidgetItem::type_WIN;
    #endif
}
Claudio Valerio's avatar
Claudio Valerio committed
202

203
QString UBGraphicsWidgetItem::preference(const QString& key) const
204
{
205
    return mPreferences.value(key);
206
}
Claudio Valerio's avatar
Claudio Valerio committed
207

208
void UBGraphicsWidgetItem::setPreference(const QString& key, QString value)
209
{
210 211
    if (key == "" || (mPreferences.contains(key) && mPreferences.value(key) == value))
        return;
Claudio Valerio's avatar
Claudio Valerio committed
212

213 214 215
    mPreferences.insert(key, value);
    if (scene())
        scene()->setModified(true);
Claudio Valerio's avatar
Claudio Valerio committed
216 217
}

218
QMap<QString, QString> UBGraphicsWidgetItem::preferences() const
Claudio Valerio's avatar
Claudio Valerio committed
219
{
220
    return mPreferences;
Claudio Valerio's avatar
Claudio Valerio committed
221 222 223
}


224
void UBGraphicsWidgetItem::removePreference(const QString& key)
Claudio Valerio's avatar
Claudio Valerio committed
225
{
226
    mPreferences.remove(key);
Claudio Valerio's avatar
Claudio Valerio committed
227 228 229
}


230
void UBGraphicsWidgetItem::removeAllPreferences()
Claudio Valerio's avatar
Claudio Valerio committed
231
{
232
    mPreferences.clear();
Claudio Valerio's avatar
Claudio Valerio committed
233 234
}

235
QString UBGraphicsWidgetItem::datastoreEntry(const QString& key) const
Claudio Valerio's avatar
Claudio Valerio committed
236
{
237 238
    if (mDatastore.contains(key))
        return mDatastore.value(key);
239
    else
240
        return QString();
241
}
Claudio Valerio's avatar
Claudio Valerio committed
242

243
void UBGraphicsWidgetItem::setDatastoreEntry(const QString& key, QString value)
244
{
245 246
    if (key == "" || (mDatastore.contains(key) && mDatastore.value(key) == value))
        return;
Claudio Valerio's avatar
Claudio Valerio committed
247

248 249 250 251
    mDatastore.insert(key, value);
    if (scene())
        scene()->setModified(true);
}
Claudio Valerio's avatar
Claudio Valerio committed
252

253 254 255 256
QMap<QString, QString> UBGraphicsWidgetItem::datastoreEntries() const
{
    return mDatastore;
}
Claudio Valerio's avatar
Claudio Valerio committed
257 258


259 260 261 262
void UBGraphicsWidgetItem::removeDatastoreEntry(const QString& key)
{
    mDatastore.remove(key);
}
Claudio Valerio's avatar
Claudio Valerio committed
263

264

265 266 267
void UBGraphicsWidgetItem::removeAllDatastoreEntries()
{
    mDatastore.clear();
Claudio Valerio's avatar
Claudio Valerio committed
268 269
}

270 271 272 273 274
void UBGraphicsWidgetItem::removeScript()
{
    if (page() && page()->mainFrame())
        page()->mainFrame()->evaluateJavaScript("if(widget && widget.onremove) { widget.onremove();}");
}
Claudio Valerio's avatar
Claudio Valerio committed
275

276
void UBGraphicsWidgetItem::processDropEvent(QGraphicsSceneDragDropEvent *event)
277
{
278
    mUniboardAPI->ProcessDropEvent(event);
279 280
}
bool UBGraphicsWidgetItem::isDropableData(const QMimeData *data) const
Claudio Valerio's avatar
Claudio Valerio committed
281
{
282
    return mUniboardAPI->isDropableData(data);
Claudio Valerio's avatar
Claudio Valerio committed
283 284
}

285 286
QUrl UBGraphicsWidgetItem::getOwnFolder() const
{
287 288
    return ownFolder;
}
Claudio Valerio's avatar
Claudio Valerio committed
289

290
void UBGraphicsWidgetItem::setOwnFolder(const QUrl &newFolder)
Claudio Valerio's avatar
Claudio Valerio committed
291
{
292
    ownFolder = newFolder;
Claudio Valerio's avatar
Claudio Valerio committed
293 294
}

295 296 297 298
void UBGraphicsWidgetItem::setSnapshotPath(const QUrl &newFilePath)
{
    SnapshotFile = newFilePath;
}
Claudio Valerio's avatar
Claudio Valerio committed
299

300
QUrl UBGraphicsWidgetItem::getSnapshotPath()
Claudio Valerio's avatar
Claudio Valerio committed
301
{
302
    return SnapshotFile;
Claudio Valerio's avatar
Claudio Valerio committed
303 304
}

305 306 307 308 309
void UBGraphicsWidgetItem::clearSource()
{
    UBFileSystemUtils::deleteDir(getOwnFolder().toLocalFile());
    UBFileSystemUtils::deleteFile(getSnapshotPath().toLocalFile());
}
Claudio Valerio's avatar
Claudio Valerio committed
310

311
void UBGraphicsWidgetItem::setUuid(const QUuid &pUuid)
Claudio Valerio's avatar
Claudio Valerio committed
312
{
313 314
    UBItem::setUuid(pUuid);
    setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene
Claudio Valerio's avatar
Claudio Valerio committed
315 316
}

317 318 319 320
QSize UBGraphicsWidgetItem::nominalSize() const
{
    return mNominalSize;
}
Claudio Valerio's avatar
Claudio Valerio committed
321

322
bool UBGraphicsWidgetItem::hasLoadedSuccessfully() const
Claudio Valerio's avatar
Claudio Valerio committed
323
{
324
    return (mInitialLoadDone && !mLoadIsErronous);
Claudio Valerio's avatar
Claudio Valerio committed
325 326
}

327 328
bool UBGraphicsWidgetItem::freezable()
{
329 330
    return mIsFreezable;
}
Claudio Valerio's avatar
Claudio Valerio committed
331

332
bool UBGraphicsWidgetItem::resizable()
333
{
334
    return mIsResizable;
335
}
336 337

bool UBGraphicsWidgetItem::isFrozen()
338
{
339
    return mIsFrozen;
Claudio Valerio's avatar
Claudio Valerio committed
340 341
}

342 343 344 345
QPixmap UBGraphicsWidgetItem::snapshot()
{
    return mSnapshot;
}
Claudio Valerio's avatar
Claudio Valerio committed
346

347
QPixmap UBGraphicsWidgetItem::takeSnapshot()
Claudio Valerio's avatar
Claudio Valerio committed
348
{
349
    mIsTakingSnapshot = true;
Claudio Valerio's avatar
Claudio Valerio committed
350

351 352 353
    QPixmap pixmap(size().toSize());
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
354

355 356
    QStyleOptionGraphicsItem options;
    paint(&painter, &options);
Claudio Valerio's avatar
Claudio Valerio committed
357

358
    mIsTakingSnapshot = false;
Claudio Valerio's avatar
Claudio Valerio committed
359

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
360 361
    mSnapshot = pixmap;

362 363 364 365
    return pixmap;
}

void UBGraphicsWidgetItem::setSnapshot(const QPixmap& pix)
Claudio Valerio's avatar
Claudio Valerio committed
366
{
367
    mSnapshot = pix;
Claudio Valerio's avatar
Claudio Valerio committed
368 369
}

370 371 372 373
UBGraphicsScene* UBGraphicsWidgetItem::scene()
{
    return qobject_cast<UBGraphicsScene*>(QGraphicsItem::scene());
}
Claudio Valerio's avatar
Claudio Valerio committed
374

375
int UBGraphicsWidgetItem::widgetType(const QUrl& pUrl)
Claudio Valerio's avatar
Claudio Valerio committed
376
{
377 378 379 380 381 382 383 384
    QString mime = UBFileSystemUtils::mimeTypeFromFileName(pUrl.toString());

    if (mime == "application/vnd.apple-widget")
        return UBWidgetType::Apple;
    else if (mime == "application/widget")
        return UBWidgetType::W3C;
    else
        return UBWidgetType::Other;
Claudio Valerio's avatar
Claudio Valerio committed
385 386
}

387 388 389 390 391 392 393
QString UBGraphicsWidgetItem::widgetName(const QUrl& widgetPath)
{
    QString name;
    QString version;
    QFile w3CConfigFile(widgetPath.toLocalFile() + "/config.xml");
    QFile appleConfigFile(widgetPath.toLocalFile() + "/Info.plist");

394
    if (w3CConfigFile.exists() && w3CConfigFile.open(QFile::ReadOnly)) {
395 396 397
        QDomDocument doc;
        doc.setContent(w3CConfigFile.readAll());
        QDomElement root = doc.firstChildElement("widget");
398
        if (!root.isNull()) {
399 400 401 402 403 404 405
            QDomElement nameElement = root.firstChildElement("name");
            if (!nameElement.isNull())
                name = nameElement.text();
            version = root.attribute("version", "");
        }
        w3CConfigFile.close();
    }
406
    else if (appleConfigFile.exists() && appleConfigFile.open(QFile::ReadOnly)) {
407 408 409
        QDomDocument doc;
        doc.setContent(appleConfigFile.readAll());
        QDomElement root = doc.firstChildElement("plist");
410
        if (!root.isNull()) {
411
            QDomElement dictElement = root.firstChildElement("dict");
412
            if (!dictElement.isNull()) {
413 414
                QDomNodeList childNodes  = dictElement.childNodes();

415 416 417 418 419 420
                /* looking for something like
                 * ..
                 * <key>CFBundleDisplayName</key>
                 * <string>brain scans</string>
                 * ..
                 */
421

422 423
                for(int i = 0; i < childNodes.count() - 1; i++) {
                    if (childNodes.at(i).isElement()) {
424
                        QDomElement elKey = childNodes.at(i).toElement();
425 426
                        if (elKey.text() == "CFBundleDisplayName") {
                            if (childNodes.at(i + 1).isElement()) {
427 428 429 430
                               QDomElement elValue = childNodes.at(i + 1).toElement();
                               name = elValue.text();
                            }
                        }
431 432
                        else if (elKey.text() == "CFBundleShortVersionString") {
                            if (childNodes.at(i + 1).isElement()) {
433 434 435 436 437 438 439 440 441 442 443
                               QDomElement elValue = childNodes.at(i + 1).toElement();
                               version = elValue.text();
                            }
                        }
                    }
                }
            }
        }
        appleConfigFile.close();
    }
    QString result;
Claudio Valerio's avatar
Claudio Valerio committed
444

445
    if (name.length() > 0) {
446
        result = name;
447
        if (version.length() > 0) {
448 449 450 451 452 453 454
            result += " ";
            result += version;
        }
    }
    return result;
}

455
QString UBGraphicsWidgetItem::iconFilePath(const QUrl& pUrl)
Claudio Valerio's avatar
Claudio Valerio committed
456
{
457
    /* TODO UB 4.x read config.xml widget.icon param first */
458

459
    QStringList files;
460

461 462 463 464 465
    files << "icon.svg";  /* W3C widget default 1 */
    files << "icon.ico";  /* W3C widget default 2 */
    files << "icon.png";  /* W3C widget default 3 */
    files << "icon.gif";  /* W3C widget default 4 */
    files << "Icon.png";  /* Apple widget default */
466

467 468 469
    QString file = UBFileSystemUtils::getFirstExistingFileFromList(pUrl.toLocalFile(), files);
    /* default */
    if (file.length() == 0)
470
    {
471
        file = QString(":/images/defaultWidgetIcon.png");
472
    }
473
    return file;
Claudio Valerio's avatar
Claudio Valerio committed
474 475
}

476 477 478 479 480 481
void UBGraphicsWidgetItem::freeze()
{
    QPixmap pix = takeSnapshot();
    mIsFrozen = true;
    setSnapshot(pix);
}
Claudio Valerio's avatar
Claudio Valerio committed
482

483
void UBGraphicsWidgetItem::unFreeze()
Claudio Valerio's avatar
Claudio Valerio committed
484
{
485
    mIsFrozen = false;
Claudio Valerio's avatar
Claudio Valerio committed
486 487
}

488 489 490 491 492 493 494 495 496 497 498 499
bool UBGraphicsWidgetItem::event(QEvent *event)
{
    if (mShouldMoveWidget && event->type() == QEvent::MouseMove) {
        QMouseEvent *mouseMoveEvent = static_cast<QMouseEvent*>(event);
        if (mouseMoveEvent->buttons() & Qt::LeftButton) {
            QPointF scenePos = mapToScene(mouseMoveEvent->pos());
            QPointF newPos = pos() + scenePos - mLastMousePos;
            setPos(newPos);
            mLastMousePos = scenePos;
            event->accept();
            return true;
        }
500
    }
501 502 503
    else if (event->type() == QEvent::ShortcutOverride)
        event->accept();

Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
504
    return QGraphicsWebView::event(event);
505 506 507 508 509 510 511 512
}

void UBGraphicsWidgetItem::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    processDropEvent(event);
    QGraphicsWebView::dropEvent(event);
}

Claudio Valerio's avatar
Claudio Valerio committed
513 514
void UBGraphicsWidgetItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
515
    if (!Delegate()->mousePressEvent(event))
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
516 517 518
        setSelected(true); /* forcing selection */

    QGraphicsWebView::mousePressEvent(event);
Claudio Valerio's avatar
Claudio Valerio committed
519 520 521 522 523 524 525 526 527 528

    // did webkit consume the mouse press ?
    mShouldMoveWidget = !event->isAccepted() && (event->buttons() & Qt::LeftButton);

    mLastMousePos = mapToScene(event->pos());

    event->accept();
}

void UBGraphicsWidgetItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
529
{
Claudio Valerio's avatar
Claudio Valerio committed
530
    mShouldMoveWidget = false;
531

532
    Delegate()->mouseReleaseEvent(event);
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
533
    QGraphicsWebView::mouseReleaseEvent(event);
534
}
535

536
void UBGraphicsWidgetItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Claudio Valerio's avatar
Claudio Valerio committed
537
{
538
    sendJSEnterEvent();
539
    Delegate()->hoverEnterEvent(event);
Claudio Valerio's avatar
Claudio Valerio committed
540
}
541
void UBGraphicsWidgetItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Claudio Valerio's avatar
Claudio Valerio committed
542
{
543
    sendJSLeaveEvent();
544
    Delegate()->hoverLeaveEvent(event);
545 546
}

547 548
void UBGraphicsWidgetItem::sendJSEnterEvent()
{
549 550
    if (page() && page()->mainFrame())
        page()->mainFrame()->evaluateJavaScript("if(widget && widget.onenter) { widget.onenter();}");
551
}
552

553 554
void UBGraphicsWidgetItem::sendJSLeaveEvent()
{
555 556
    if (page() && page()->mainFrame())
        page()->mainFrame()->evaluateJavaScript("if(widget && widget.onleave) { widget.onleave();}");
557 558 559 560 561 562 563
}

void UBGraphicsWidgetItem::injectInlineJavaScript()
{
    if (!sInlineJavaScriptLoaded) {
        sInlineJavaScripts = UBApplication::applicationController->widgetInlineJavaScripts();
        sInlineJavaScriptLoaded = true;
564
    }
565 566 567

    foreach(QString script, sInlineJavaScripts)
        page()->mainFrame()->evaluateJavaScript(script);
568
}
569

570
void UBGraphicsWidgetItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
571
{
Claudio Valerio's avatar
Claudio Valerio committed
572

-f's avatar
-f committed
573 574 575

    QGraphicsWebView::paint(painter, option, widget);

576

577 578
    if (!mInitialLoadDone) {
        QString message;
579

580
        message = tr("Loading ...");
581

582
        painter->setFont(QFont("Arial", 12));
583

584 585
        QFontMetrics fm = painter->fontMetrics();
        QRect txtBoundingRect = fm.boundingRect(message);
586

587 588
        txtBoundingRect.moveCenter(rect().center().toPoint());
        txtBoundingRect.adjust(-10, -5, 10, 5);
589

590 591 592
        painter->setPen(Qt::NoPen);
        painter->setBrush(UBSettings::paletteColor);
        painter->drawRoundedRect(txtBoundingRect, 3, 3);
Anatoly Mihalchenko's avatar
Anatoly Mihalchenko committed
593

594 595 596
        painter->setPen(Qt::white);
        painter->drawText(rect(), Qt::AlignCenter, message);
    }
597 598

    Delegate()->postpaint(painter, option, widget);
599 600
}

601
void UBGraphicsWidgetItem::geometryChangeRequested(const QRect& geom)
602
{
603
    resize(geom.width(), geom.height());
604
}
605

606
void UBGraphicsWidgetItem::javaScriptWindowObjectCleared()
Ivan Ilin's avatar
Ivan Ilin committed
607
{
608 609 610 611 612 613 614
    injectInlineJavaScript();

    if(!mUniboardAPI)
        mUniboardAPI = new UBWidgetUniboardAPI(scene(), this);

    page()->mainFrame()->addToJavaScriptWindowObject("sankore", mUniboardAPI);

Ivan Ilin's avatar
Ivan Ilin committed
615
}
Claudio Valerio's avatar
Claudio Valerio committed
616

617
void UBGraphicsWidgetItem::mainFrameLoadFinished (bool ok)
Claudio Valerio's avatar
Claudio Valerio committed
618
{
619 620
    mLoadIsErronous = !ok;
    update(boundingRect());
621 622 623

    if (mInitialLoadDone && scene() && scene()->renderingContext() == UBGraphicsScene::Screen)
        takeSnapshot();
Claudio Valerio's avatar
Claudio Valerio committed
624 625
}

Claudio Valerio's avatar
Claudio Valerio committed
626 627
void UBGraphicsWidgetItem::wheelEvent(QGraphicsSceneWheelEvent *event)
{
Claudio Valerio's avatar
Claudio Valerio committed
628
    if (Delegate()->wheelEvent(event))
Claudio Valerio's avatar
Claudio Valerio committed
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
    {
        QGraphicsWebView::wheelEvent(event);
        event->accept();
    }
}

QVariant UBGraphicsWidgetItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if ((change == QGraphicsItem::ItemSelectedHasChanged) &&  scene()) {
        if (isSelected())
            scene()->setActiveWindow(this);
        else
            if(scene()->activeWindow() == this)
                scene()->setActiveWindow(0);
    }

    QVariant newValue = Delegate()->itemChange(change, value);
    return QGraphicsWebView::itemChange(change, newValue);
}

void UBGraphicsWidgetItem::resize(qreal w, qreal h)
{
    UBGraphicsWidgetItem::resize(QSizeF(w, h));
}


void UBGraphicsWidgetItem::resize(const QSizeF & pSize)
{
    if (pSize != size()) {
        QGraphicsWebView::setMaximumSize(pSize.width(), pSize.height());
        QGraphicsWebView::resize(pSize.width(), pSize.height());
        if (Delegate())
            Delegate()->positionHandles();
        if (scene())
            scene()->setModified(true);
    }
}

QSizeF UBGraphicsWidgetItem::size() const
{
    return QGraphicsWebView::size();
}

Claudio Valerio's avatar
Claudio Valerio committed
672 673 674


UBGraphicsAppleWidgetItem::UBGraphicsAppleWidgetItem(const QUrl& pWidgetUrl, QGraphicsItem *parent)
Yimgo's avatar
Yimgo committed
675
    : UBGraphicsWidgetItem(pWidgetUrl, parent)
Claudio Valerio's avatar
Claudio Valerio committed
676
{
677
    QString path = pWidgetUrl.toLocalFile();
Claudio Valerio's avatar
Claudio Valerio committed
678

679
    if (!path.endsWith(".wdgt") && !path.endsWith(".wdgt/")) {
680 681 682 683
        int lastSlashIndex = path.lastIndexOf("/");
        if (lastSlashIndex > 0)
            path = path.mid(0, lastSlashIndex + 1);
    }
Claudio Valerio's avatar
Claudio Valerio committed
684

685 686
    QFile plistFile(path + "/Info.plist");
    plistFile.open(QFile::ReadOnly);
Claudio Valerio's avatar
Claudio Valerio committed
687

688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
    QByteArray plistBin = plistFile.readAll();
    QString plist = QString::fromUtf8(plistBin);

    int mainHtmlIndex = plist.indexOf("MainHTML");
    int mainHtmlIndexStart = plist.indexOf("<string>", mainHtmlIndex);
    int mainHtmlIndexEnd = plist.indexOf("</string>", mainHtmlIndexStart);

    if (mainHtmlIndex > -1 && mainHtmlIndexStart > -1 && mainHtmlIndexEnd > -1)
        mMainHtmlFileName = plist.mid(mainHtmlIndexStart + 8, mainHtmlIndexEnd - mainHtmlIndexStart - 8);

    mMainHtmlUrl = pWidgetUrl;
    mMainHtmlUrl.setPath(pWidgetUrl.path() + "/" + mMainHtmlFileName);

    load(mMainHtmlUrl);

    QPixmap defaultPixmap(pWidgetUrl.toLocalFile() + "/Default.png");

    setMaximumSize(defaultPixmap.size());

    mNominalSize = defaultPixmap.size();
Claudio Valerio's avatar
Claudio Valerio committed
708 709 710 711 712 713 714

    initialize();
}


UBGraphicsAppleWidgetItem::~UBGraphicsAppleWidgetItem()
{
715 716 717 718 719 720 721 722
    /* NOOP */
}

void UBGraphicsAppleWidgetItem::setUuid(const QUuid &pUuid)
{
    UBItem::setUuid(pUuid);
    setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene
}
Claudio Valerio's avatar
Claudio Valerio committed
723 724 725

UBItem* UBGraphicsAppleWidgetItem::deepCopy() const
{
726
    UBGraphicsAppleWidgetItem *appleWidget = new UBGraphicsAppleWidgetItem(QGraphicsWebView::url(), parentItem());
Claudio Valerio's avatar
Claudio Valerio committed
727

728 729 730
    copyItemParameters(appleWidget);

    return appleWidget;
Claudio Valerio's avatar
Claudio Valerio committed
731

732 733 734 735 736 737
}

void UBGraphicsAppleWidgetItem::copyItemParameters(UBItem *copy) const
{
    UBGraphicsAppleWidgetItem *cp = dynamic_cast<UBGraphicsAppleWidgetItem*>(copy);
    if (cp)
Claudio Valerio's avatar
Claudio Valerio committed
738
    {
739 740 741 742
        foreach(QString key, mPreferences.keys())
        {
            cp->setPreference(key, mPreferences.value(key));
        }
Claudio Valerio's avatar
Claudio Valerio committed
743

744 745 746 747
        foreach(QString key, mDatastore.keys())
        {
            cp->setDatastoreEntry(key, mDatastore.value(key));
        }
Claudio Valerio's avatar
Claudio Valerio committed
748

749
        cp->setSourceUrl(this->sourceUrl());
750
        cp->setZValue(this->zValue());
751
    }
Claudio Valerio's avatar
Claudio Valerio committed
752 753 754

}

755 756 757 758 759 760



bool UBGraphicsW3CWidgetItem::sTemplateLoaded = false;
QString UBGraphicsW3CWidgetItem::sNPAPIWrappperConfigTemplate;
QMap<QString, QString> UBGraphicsW3CWidgetItem::sNPAPIWrapperTemplates;
Claudio Valerio's avatar
Claudio Valerio committed
761

762
UBGraphicsW3CWidgetItem::UBGraphicsW3CWidgetItem(const QUrl& pWidgetUrl, QGraphicsItem *parent)
Yimgo's avatar
Yimgo committed
763
    : UBGraphicsWidgetItem(pWidgetUrl, parent)
Claudio Valerio's avatar
Claudio Valerio committed
764 765
    , mW3CWidgetAPI(0)
{
766 767 768
    QString path = pWidgetUrl.toLocalFile();
    QDir potentialDir(path);

769
    if (!path.endsWith(".wgt") && !path.endsWith(".wgt/") && !potentialDir.exists()) {
770 771 772 773 774
        int lastSlashIndex = path.lastIndexOf("/");
        if (lastSlashIndex > 0)
            path = path.mid(0, lastSlashIndex + 1);
    }

775
    if (!path.endsWith("/"))
776 777 778 779 780 781 782 783 784 785 786 787
        path += "/";

    int width = 300;
    int height = 150;

    QFile configFile(path + "config.xml");
    configFile.open(QFile::ReadOnly);

    QDomDocument doc;
    doc.setContent(configFile.readAll());
    QDomNodeList widgetDomList = doc.elementsByTagName("widget");

788
    if (widgetDomList.count() > 0) {
789 790 791 792 793 794 795
        QDomElement widgetElement = widgetDomList.item(0).toElement();

        width = widgetElement.attribute("width", "300").toInt();
        height = widgetElement.attribute("height", "150").toInt();

        mMetadatas.id = widgetElement.attribute("id", "");

796
        /* some early widget (<= 4.3.4) where using identifier instead of id */
797 798 799 800 801
        if (mMetadatas.id.length() == 0)
             mMetadatas.id = widgetElement.attribute("identifier", "");

        mMetadatas.version = widgetElement.attribute("version", "");

802
        /* TODO UB 4.x map properly ub namespace */
803 804 805 806 807
        mIsResizable = widgetElement.attribute("ub:resizable", "false") == "true";
        mIsFreezable = widgetElement.attribute("ub:freezable", "true") == "true";

        QString roles = widgetElement.attribute("ub:roles", "content tool").trimmed().toLower();

808
        /* ------------------------------ */
809

810
        if (roles == "" || roles.contains("tool"))
811 812
            mCanBeTool = UBGraphicsWidgetItem::type_ALL;

813
        if (roles.contains("twin"))
814 815
            mCanBeTool |= UBGraphicsWidgetItem::type_WIN;

816
        if (roles.contains("tmac"))
817
            mCanBeTool |= UBGraphicsWidgetItem::type_MAC;
818

819
        if (roles.contains("tunix"))
820 821
            mCanBeTool |= UBGraphicsWidgetItem::type_UNIX;

822
        /* --------- */
823

824
        if (roles == "" || roles.contains("content"))
825 826
            mCanBeContent = UBGraphicsWidgetItem::type_ALL;

827
        if (roles.contains("cwin"))
828 829
            mCanBeContent |= UBGraphicsWidgetItem::type_WIN;

830
        if (roles.contains("cmac"))
831 832
            mCanBeContent |= UBGraphicsWidgetItem::type_MAC;

833
        if (roles.contains("cunix"))
834 835 836 837 838 839
            mCanBeContent |= UBGraphicsWidgetItem::type_UNIX;

        //------------------------------//

        QDomNodeList contentDomList = widgetElement.elementsByTagName("content");

840
        if (contentDomList.count() > 0) {
841 842 843 844 845 846 847 848 849
            QDomElement contentElement = contentDomList.item(0).toElement();
            mMainHtmlFileName = contentElement.attribute("src", "");
        }

        mMetadatas.name = textForSubElementByLocale(widgetElement, "name", QLocale::system());
        mMetadatas.description = textForSubElementByLocale(widgetElement, "description ", QLocale::system());

        QDomNodeList authorDomList = widgetElement.elementsByTagName("author");

850
        if (authorDomList.count() > 0) {
851 852 853 854 855 856 857 858 859
            QDomElement authorElement = authorDomList.item(0).toElement();

            mMetadatas.author = authorElement.text();
            mMetadatas.authorHref = authorElement.attribute("href", "");
            mMetadatas.authorEmail = authorElement.attribute("email ", "");
        }

        QDomNodeList propertiesDomList = widgetElement.elementsByTagName("preference");

Craig Watson's avatar
Craig Watson committed
860
        for (int i = 0; i < propertiesDomList.length(); i++) {
861 862 863
            QDomElement preferenceElement = propertiesDomList.at(i).toElement();
            QString prefName = preferenceElement.attribute("name", "");

864
            if (prefName.length() > 0) {
865 866 867 868 869
                QString prefValue = preferenceElement.attribute("value", "");
                bool readOnly = (preferenceElement.attribute("readonly", "false") == "true");

                mPreferences.insert(prefName, PreferenceValue(prefValue, readOnly));
            }
870
        }
871 872
    }

873
    if (mMainHtmlFileName.length() == 0) {
874 875 876 877
        QFile defaultStartFile(path + "index.htm");

        if (defaultStartFile.exists())
            mMainHtmlFileName = "index.htm";
878
        else {
879 880 881 882 883 884 885 886 887
            QFile secondDefaultStartFile(path + "index.html");

            if (secondDefaultStartFile.exists())
                mMainHtmlFileName = "index.html";
        }
    }

    mMainHtmlUrl = pWidgetUrl;
    mMainHtmlUrl.setPath(pWidgetUrl.path() + "/" + mMainHtmlFileName);
888
    /* is it a valid local file ? */
889 890 891 892 893 894 895 896 897 898 899 900 901 902
    QFile f(mMainHtmlUrl.toLocalFile());

    if(!f.exists())
        mMainHtmlUrl = QUrl(mMainHtmlFileName);

    connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(javaScriptWindowObjectCleared()));
    connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), this, SLOT(javaScriptWindowObjectCleared()));

    load(mMainHtmlUrl);

    setMaximumSize(QSize(width, height));

    mNominalSize = QSize(width, height);

Claudio Valerio's avatar
Claudio Valerio committed
903
    initialize();
904
    setOwnFolder(pWidgetUrl);
Claudio Valerio's avatar
Claudio Valerio committed
905 906 907 908
}

UBGraphicsW3CWidgetItem::~UBGraphicsW3CWidgetItem()
{
909
    /* NOOP */
Claudio Valerio's avatar
Claudio Valerio committed
910 911
}

root's avatar
root committed
912
void UBGraphicsW3CWidgetItem::setUuid(const QUuid &pUuid)
Claudio Valerio's avatar
Claudio Valerio committed
913
{
root's avatar
root committed
914 915
    UBItem::setUuid(pUuid);
    setData(UBGraphicsItemData::ItemUuid, QVariant(pUuid)); //store item uuid inside the QGraphicsItem to fast operations with Items on the scene
Claudio Valerio's avatar
Claudio Valerio committed
916 917 918 919
}

UBItem* UBGraphicsW3CWidgetItem::deepCopy() const
{
Yimgo's avatar
Yimgo committed
920
    UBGraphicsW3CWidgetItem *copy = new UBGraphicsW3CWidgetItem(mWidgetUrl, parentItem());
Claudio Valerio's avatar
Claudio Valerio committed
921
    copy->setUuid(this->uuid()); // this is OK for now as long as Widgets are imutable
Yimgo's avatar
Yimgo committed
922
    copyItemParameters(copy);
Claudio Valerio's avatar
Claudio Valerio committed
923 924 925 926

    return copy;
}

927 928 929
QMap<QString, UBGraphicsW3CWidgetItem::PreferenceValue> UBGraphicsW3CWidgetItem::preferences()
{
    return mPreferences;
930 931
}

932 933 934 935
UBGraphicsW3CWidgetItem::Metadata UBGraphicsW3CWidgetItem::metadatas() const
{
    return mMetadatas;
}
936

937
QString UBGraphicsW3CWidgetItem::createNPAPIWrapper(const QString& url, const QString& pMimeType, const QSize& sizeHint, const QString& pName)
938 939 940 941 942 943 944
{
    const QString userWidgetPath = UBSettings::settings()->userInteractiveDirectory() + "/" + tr("Web");
    QDir userWidgetDir(userWidgetPath);

    return createNPAPIWrapperInDir(url, userWidgetDir, pMimeType, sizeHint, pName);
}

945
QString UBGraphicsW3CWidgetItem::createNPAPIWrapperInDir(const QString& pUrl, const QDir& pDir, const QString& pMimeType, const QSize& sizeHint, const QString& pName)
946 947 948 949 950 951 952 953 954 955
{
    QString url = pUrl;
    url = UBFileSystemUtils::removeLocalFilePrefix(url);
    QString name = pName;

    QFileInfo fi(url);

    if (name.length() == 0)
        name = fi.baseName();

956
    if (fi.exists())
957 958 959 960 961 962
        url = fi.fileName();

    loadNPAPIWrappersTemplates();

    QString htmlTemplate;

963
    if (pMimeType.length() > 0 && sNPAPIWrapperTemplates.contains(pMimeType))
964 965 966 967 968 969 970
        htmlTemplate = sNPAPIWrapperTemplates.value(pMimeType);
    else {
        QString extension = UBFileSystemUtils::extension(url);
        if (sNPAPIWrapperTemplates.contains(extension))
            htmlTemplate = sNPAPIWrapperTemplates.value(extension);
    }

971
    if (htmlTemplate.length() > 0) {
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994
        htmlTemplate = htmlTemplate.replace(QString("{in.url}"), url)
            .replace(QString("{in.width}"), QString("%1").arg(sizeHint.width()))
            .replace(QString("{in.height}"), QString("%1").arg(sizeHint.height()));

        QString configTemplate = sNPAPIWrappperConfigTemplate
            .replace(QString("{in.id}"), url)
            .replace(QString("{in.width}"), QString("%1").arg(sizeHint.width()))
            .replace(QString("{in.height}"), QString("%1").arg(sizeHint.height()))
            .replace(QString("{in.name}"), name)
            .replace(QString("{in.startFile}"), QString("index.htm"));

        QString dirPath = pDir.path();
        if (!pDir.exists())
            pDir.mkpath(dirPath);

        QString widgetLibraryPath = dirPath + "/" + name + ".wgt";
        QDir widgetLibraryDir(widgetLibraryPath);

        if (widgetLibraryDir.exists())
            if (!UBFileSystemUtils::deleteDir(widgetLibraryDir.path()))
                qWarning() << "Cannot delete old widget " << widgetLibraryDir.path();

        widgetLibraryDir.mkpath(widgetLibraryPath);
995
        if (fi.exists()) {
996 997 998 999 1000 1001 1002 1003
            QString target = widgetLibraryPath + "/" + fi.fileName();
            QString source = pUrl;
            source = UBFileSystemUtils::removeLocalFilePrefix(source);
            QFile::copy(source, target);
        }

        QFile configFile(widgetLibraryPath + "/config.xml");

1004
        if (!configFile.open(QIODevice::WriteOnly)) {
1005
            qWarning() << "Cannot open file " << configFile.fileName();
1006
            return QString();
Claudio Valerio's avatar
Claudio Valerio committed
1007
        }
1008 1009 1010 1011 1012 1013 1014 1015 1016

        QTextStream outConfig(&configFile);
        outConfig.setCodec("UTF-8");

        outConfig << configTemplate;
        configFile.close();

        QFile indexFile(widgetLibraryPath + "/index.htm");

1017
        if (!indexFile.open(QIODevice::WriteOnly)) {
1018
            qWarning() << "Cannot open file " << indexFile.fileName();
1019
            return QString();
1020 1021 1022 1023 1024 1025 1026 1027 1028
        }

        QTextStream outIndex(&indexFile);
        outIndex.setCodec("UTF-8");

        outIndex << htmlTemplate;
        indexFile.close();

        return widgetLibraryPath;
Claudio Valerio's avatar
Claudio Valerio committed
1029 1030
    }
    else
1031
        return QString();
1032 1033
}

1034
QString UBGraphicsW3CWidgetItem::createHtmlWrapperInDir(const QString& html, const QDir& pDir, const QSize& sizeHint, const QString& pName)
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
{
    QString widgetPath = pDir.path() + "/" + pName + ".wgt";
    widgetPath = UBFileSystemUtils::nextAvailableFileName(widgetPath);
    QDir widgetDir(widgetPath);

    if (!widgetDir.exists())
        widgetDir.mkpath(widgetDir.path());

    QFile configFile(widgetPath + "/" + "config.xml");

    if (configFile.exists())
        configFile.remove(configFile.fileName());

1048
    if (!configFile.open(QIODevice::WriteOnly)) {
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
        qWarning() << "Cannot open file " << configFile.fileName();
        return "";
    }

    QTextStream outConfig(&configFile);
    outConfig.setCodec("UTF-8");
    outConfig << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
    outConfig << "<widget xmlns=\"http://www.w3.org/ns/widgets\"" << endl;
    outConfig << "    xmlns:ub=\"http://uniboard.mnemis.com/widgets\"" << endl;
    outConfig << "    id=\"http://uniboard.mnemis.com/" << pName << "\"" <<endl;

    outConfig << "    version=\"1.0\"" << endl;
    outConfig << "    width=\"" << sizeHint.width() << "\"" << endl;
    outConfig << "    height=\"" << sizeHint.height() << "\"" << endl;
    outConfig << "    ub:resizable=\"true\">" << endl;

    outConfig << "  <name>" << pName << "</name>" << endl;
    outConfig << "  <content src=\"" << pName << ".html\"/>" << endl;

    outConfig << "</widget>" << endl;

    configFile.close();

    const QString fullHtmlFileName = widgetPath + "/" + pName + ".html";

    QFile widgetHtmlFile(fullHtmlFileName);
    if (widgetHtmlFile.exists())
        widgetHtmlFile.remove(widgetHtmlFile.fileName());
1077
    if (!widgetHtmlFile.open(QIODevice::WriteOnly)) {
1078
        qWarning() << "cannot open file " << widgetHtmlFile.fileName();
1079
        return QString();
Claudio Valerio's avatar
Claudio Valerio committed
1080
    }
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097

    QTextStream outStartFile(&widgetHtmlFile);
    outStartFile.setCodec("UTF-8");

    outStartFile << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" << endl;
    outStartFile << "<html>" << endl;
    outStartFile << "<head>" << endl;
    outStartFile << "    <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">" << endl;
    outStartFile << "</head>" << endl;
    outStartFile << "  <body>" << endl;
    outStartFile << html << endl;
    outStartFile << "  </body>" << endl;
    outStartFile << "</html>" << endl;

    widgetHtmlFile.close();

    return widgetPath;
Claudio Valerio's avatar
Claudio Valerio committed
1098 1099
}

1100
QString UBGraphicsW3CWidgetItem::freezedWidgetPage()
root's avatar
root committed
1101
{
1102 1103 1104
    static QString defaultcontent;

    if (defaultcontent.isNull()) {
1105
        QString freezedWidgetDefaultContentFilePath = freezedWidgetFilePath();
1106 1107 1108 1109
        QFile wrapperFile(freezedWidgetDefaultContentFilePath);
        if (!wrapperFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug() << "can't open wrapper file " + freezedWidgetDefaultContentFilePath;
            defaultcontent = "";
1110
        }
1111
        else {
1112
            QByteArray arr = wrapperFile.readAll();
1113
            if (!arr.isEmpty())
1114
                defaultcontent = QString(arr);
1115
            else {
1116
                qDebug() << "content of " + freezedWidgetDefaultContentFilePath + "is empty";
1117
                defaultcontent = QString();
1118 1119 1120 1121 1122 1123 1124
            }
        }
    }

    return defaultcontent;
}

1125 1126 1127 1128 1129
QString UBGraphicsW3CWidgetItem::freezedWidgetFilePath()
{
    return UBPlatformUtils::applicationResourcesDirectory() + "/etc/" + "freezedWidgetWrapper.html";
}

1130 1131 1132 1133 1134
bool UBGraphicsW3CWidgetItem::hasNPAPIWrapper(const QString& pMimeType)
{
    loadNPAPIWrappersTemplates();

    return sNPAPIWrapperTemplates.contains(pMimeType);
root's avatar
root committed
1135 1136
}

Claudio Valerio's avatar
Claudio Valerio committed
1137 1138 1139 1140 1141 1142 1143
void UBGraphicsW3CWidgetItem::javaScriptWindowObjectCleared()
{
    UBGraphicsWidgetItem::javaScriptWindowObjectCleared();

    if(!mW3CWidgetAPI)
        mW3CWidgetAPI = new UBW3CWidgetAPI(this);

1144
    page()->mainFrame()->addToJavaScriptWindowObject("widget", mW3CWidgetAPI);
Claudio Valerio's avatar
Claudio Valerio committed
1145 1146 1147

}

1148
void UBGraphicsW3CWidgetItem::loadNPAPIWrappersTemplates()
Claudio Valerio's avatar
Claudio Valerio committed
1149
{
1150
    if (!sTemplateLoaded) {
1151
        sNPAPIWrapperTemplates.clear();
Claudio Valerio's avatar
Claudio Valerio committed
1152

1153
        QString etcPath = UBPlatformUtils::applicationResourcesDirectory() + "/etc/";
Claudio Valerio's avatar
Claudio Valerio committed
1154

1155
        QDir etcDir(etcPath);
Claudio Valerio's avatar
Claudio Valerio committed
1156

1157 1158
        foreach(QString fileName, etcDir.entryList()) {
            if (fileName.startsWith("npapi-wrapper") && (fileName.endsWith(".htm") || fileName.endsWith(".html"))) {
Claudio Valerio's avatar
Claudio Valerio committed
1159

1160 1161
                QString htmlContent = UBFileSystemUtils::readTextFile(etcPath + fileName);

1162
                if (htmlContent.length() > 0) {
1163 1164
                    QStringList tokens = fileName.split(".");

1165
                    if (tokens.length() >= 4) {
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
                        QString mime = tokens.at(tokens.length() - 4 );
                        mime += "/" + tokens.at(tokens.length() - 3);

                        QString fileExtension = tokens.at(tokens.length() - 2);

                        sNPAPIWrapperTemplates.insert(mime, htmlContent);
                        sNPAPIWrapperTemplates.insert(fileExtension, htmlContent);
                    }
                }
            }
        }
        sNPAPIWrappperConfigTemplate = UBFileSystemUtils::readTextFile(etcPath + "npapi-wrapper.config.xml");
        sTemplateLoaded = true;
    }
}

QString UBGraphicsW3CWidgetItem::textForSubElementByLocale(QDomElement rootElement, QString subTagName, QLocale locale)
Claudio Valerio's avatar
Claudio Valerio committed
1183
{
1184
    QDomNodeList subList = rootElement.elementsByTagName(subTagName);
Claudio Valerio's avatar
Claudio Valerio committed
1185

1186 1187 1188 1189 1190
    QString lang = locale.name();

    if (lang.length() > 2)
        lang[2] = QLatin1Char('-');

1191 1192
    if (subList.count() > 1) {
        for(int i = 0; i < subList.count(); i++) {
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
            QDomNode node = subList.at(i);
            QDomElement element = node.toElement();

            QString configLang = element.attribute("xml:lang", "");

            if(lang == configLang || (configLang.length() == 2 && configLang == lang.left(2)))
                 return element.text();
        }
    }

1203
    if (subList.count() >= 1) {
1204 1205 1206 1207
        QDomElement element = subList.item(0).toElement();
        return element.text();
    }

1208
    return QString();
1209
}
Claudio Valerio's avatar
Claudio Valerio committed
1210

1211 1212 1213 1214
void UBGraphicsW3CWidgetItem::copyItemParameters(UBItem *copy) const
{
    UBGraphicsW3CWidgetItem *cp = dynamic_cast<UBGraphicsW3CWidgetItem*>(copy);
    if (cp)
Claudio Valerio's avatar
Claudio Valerio committed
1215
    {
1216 1217 1218 1219 1220 1221 1222
        cp->setPos(this->pos());
        cp->setTransform(this->transform());
        cp->setFlag(QGraphicsItem::ItemIsMovable, true);
        cp->setFlag(QGraphicsItem::ItemIsSelectable, true);
        cp->setData(UBGraphicsItemData::ItemLayerType, this->data(UBGraphicsItemData::ItemLayerType));
        cp->setData(UBGraphicsItemData::ItemLocked, this->data(UBGraphicsItemData::ItemLocked));
        cp->setSourceUrl(this->sourceUrl());
Claudio Valerio's avatar
Claudio Valerio committed
1223

1224
        cp->resize(this->size());
Claudio Valerio's avatar
Claudio Valerio committed
1225

1226
        foreach(QString key, this->UBGraphicsWidgetItem::preferences().keys())
1227
        {
Yimgo's avatar
Yimgo committed
1228
            cp->setPreference(key, UBGraphicsWidgetItem::preferences().value(key));
1229 1230 1231 1232 1233 1234
        }

        foreach(QString key, mDatastore.keys())
        {
            cp->setDatastoreEntry(key, mDatastore.value(key));
        }
1235 1236

        cp->setZValue(this->zValue());
1237
    }
Yimgo's avatar
Yimgo committed
1238 1239
}