You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1239 lines
37 KiB
1239 lines
37 KiB
/* |
|
* Copyright (C) 2015-2016 Département de l'Instruction Publique (DIP-SEM) |
|
* |
|
* Copyright (C) 2013 Open Education Foundation |
|
* |
|
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour |
|
* l'Education Numérique en Afrique (GIP ENA) |
|
* |
|
* This file is part of OpenBoard. |
|
* |
|
* OpenBoard is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, version 3 of the License, |
|
* 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). |
|
* |
|
* OpenBoard is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with OpenBoard. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
|
|
|
|
|
|
|
|
#include <QtNetwork> |
|
#include <QtXml> |
|
#include <QWebFrame> |
|
|
|
#include "UBGraphicsWidgetItem.h" |
|
#include "UBGraphicsScene.h" |
|
#include "UBGraphicsItemDelegate.h" |
|
#include "UBGraphicsWidgetItemDelegate.h" |
|
#include "UBGraphicsDelegateFrame.h" |
|
|
|
#include "api/UBWidgetUniboardAPI.h" |
|
#include "api/UBW3CWidgetAPI.h" |
|
|
|
#include "board/UBBoardController.h" |
|
|
|
#include "core/memcheck.h" |
|
#include "core/UBApplicationController.h" |
|
#include "core/UBApplication.h" |
|
#include "core/UBSettings.h" |
|
|
|
#include "frameworks/UBFileSystemUtils.h" |
|
#include "frameworks/UBPlatformUtils.h" |
|
|
|
#include "network/UBNetworkAccessManager.h" |
|
|
|
#include "web/UBWebPage.h" |
|
#include "web/UBWebKitUtils.h" |
|
#include "web/UBWebController.h" |
|
|
|
bool UBGraphicsWidgetItem::sInlineJavaScriptLoaded = false; |
|
QStringList UBGraphicsWidgetItem::sInlineJavaScripts; |
|
|
|
UBGraphicsWidgetItem::UBGraphicsWidgetItem(const QUrl &pWidgetUrl, QGraphicsItem *parent) |
|
: QGraphicsWebView(parent) |
|
, mInitialLoadDone(false) |
|
, mIsFreezable(true) |
|
, mIsResizable(false) |
|
, mLoadIsErronous(false) |
|
, mCanBeContent(0) |
|
, mCanBeTool(0) |
|
, mWidgetUrl(pWidgetUrl) |
|
, mIsFrozen(false) |
|
, mIsTakingSnapshot(false) |
|
, mShouldMoveWidget(false) |
|
, mUniboardAPI(0) |
|
{ |
|
setData(UBGraphicsItemData::ItemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly |
|
|
|
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); |
|
QGraphicsWebView::settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true); |
|
|
|
page()->setNetworkAccessManager(UBNetworkAccessManager::defaultAccessManager()); |
|
|
|
setAcceptDrops(true); |
|
setAutoFillBackground(false); |
|
|
|
QPalette pagePalette = page()->palette(); |
|
pagePalette.setBrush(QPalette::Base, QBrush(Qt::transparent)); |
|
pagePalette.setBrush(QPalette::Window, QBrush(Qt::transparent)); |
|
page()->setPalette(pagePalette); |
|
|
|
QPalette viewPalette = palette(); |
|
pagePalette.setBrush(QPalette::Base, QBrush(Qt::transparent)); |
|
viewPalette.setBrush(QPalette::Window, QBrush(Qt::transparent)); |
|
setPalette(viewPalette); |
|
|
|
setDelegate(new UBGraphicsWidgetItemDelegate(this)); |
|
|
|
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); |
|
QGraphicsWebView::setAcceptHoverEvents(true); |
|
} |
|
|
|
|
|
UBGraphicsWidgetItem::~UBGraphicsWidgetItem() |
|
{ |
|
/* NOOP */ |
|
} |
|
|
|
void UBGraphicsWidgetItem::initialize() |
|
{ |
|
setMinimumSize(nominalSize()); |
|
setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); // Necessary to set if we want z value to be assigned correctly |
|
|
|
if (Delegate() && Delegate()->frame() && resizable()) |
|
Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::Resizing); |
|
|
|
QPalette palette = page()->palette(); |
|
palette.setBrush(QPalette::Base, QBrush(Qt::transparent)); |
|
page()->setPalette(palette); |
|
page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); |
|
|
|
connect(page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared, |
|
this, &UBGraphicsWidgetItem::javaScriptWindowObjectCleared); |
|
connect(page(), SIGNAL(geometryChangeRequested(const QRect&)), this, SLOT(geometryChangeRequested(const QRect&))); |
|
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(mainFrameLoadFinished (bool))); |
|
connect(page()->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(initialLayoutCompleted())); |
|
connect(page(), SIGNAL(linkClicked(const QUrl&)), this, SLOT(onLinkClicked(const QUrl&))); |
|
} |
|
|
|
void UBGraphicsWidgetItem::onLinkClicked(const QUrl& url) |
|
{ |
|
load(url); |
|
} |
|
|
|
void UBGraphicsWidgetItem::initialLayoutCompleted() |
|
{ |
|
mInitialLoadDone = true; |
|
} |
|
|
|
QUrl UBGraphicsWidgetItem::mainHtml() |
|
{ |
|
return mMainHtmlUrl; |
|
} |
|
|
|
void UBGraphicsWidgetItem::loadMainHtml() |
|
{ |
|
mInitialLoadDone = false; |
|
load(mMainHtmlUrl); |
|
} |
|
|
|
QUrl UBGraphicsWidgetItem::widgetUrl() |
|
{ |
|
return mWidgetUrl; |
|
} |
|
|
|
QString UBGraphicsWidgetItem::mainHtmlFileName() |
|
{ |
|
return mMainHtmlFileName; |
|
} |
|
|
|
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 |
|
} |
|
|
|
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 |
|
} |
|
|
|
QString UBGraphicsWidgetItem::preference(const QString& key) const |
|
{ |
|
return mPreferences.value(key); |
|
} |
|
|
|
void UBGraphicsWidgetItem::setPreference(const QString& key, QString value) |
|
{ |
|
if (key == "" || (mPreferences.contains(key) && mPreferences.value(key) == value)) |
|
return; |
|
|
|
mPreferences.insert(key, value); |
|
if (scene()) |
|
scene()->setModified(true); |
|
} |
|
|
|
QMap<QString, QString> UBGraphicsWidgetItem::preferences() const |
|
{ |
|
return mPreferences; |
|
} |
|
|
|
|
|
void UBGraphicsWidgetItem::removePreference(const QString& key) |
|
{ |
|
mPreferences.remove(key); |
|
} |
|
|
|
|
|
void UBGraphicsWidgetItem::removeAllPreferences() |
|
{ |
|
mPreferences.clear(); |
|
} |
|
|
|
QString UBGraphicsWidgetItem::datastoreEntry(const QString& key) const |
|
{ |
|
if (mDatastore.contains(key)) |
|
return mDatastore.value(key); |
|
else |
|
return QString(); |
|
} |
|
|
|
void UBGraphicsWidgetItem::setDatastoreEntry(const QString& key, QString value) |
|
{ |
|
if (key == "" || (mDatastore.contains(key) && mDatastore.value(key) == value)) |
|
return; |
|
|
|
mDatastore.insert(key, value); |
|
if (scene()) |
|
scene()->setModified(true); |
|
} |
|
|
|
QMap<QString, QString> UBGraphicsWidgetItem::datastoreEntries() const |
|
{ |
|
return mDatastore; |
|
} |
|
|
|
|
|
void UBGraphicsWidgetItem::removeDatastoreEntry(const QString& key) |
|
{ |
|
mDatastore.remove(key); |
|
} |
|
|
|
|
|
void UBGraphicsWidgetItem::removeAllDatastoreEntries() |
|
{ |
|
mDatastore.clear(); |
|
} |
|
|
|
void UBGraphicsWidgetItem::removeScript() |
|
{ |
|
if (page() && page()->mainFrame()) |
|
page()->mainFrame()->evaluateJavaScript("if(widget && widget.onremove) { widget.onremove();}"); |
|
} |
|
|
|
void UBGraphicsWidgetItem::processDropEvent(QGraphicsSceneDragDropEvent *event) |
|
{ |
|
mUniboardAPI->ProcessDropEvent(event); |
|
} |
|
bool UBGraphicsWidgetItem::isDropableData(const QMimeData *data) const |
|
{ |
|
return mUniboardAPI->isDropableData(data); |
|
} |
|
|
|
QUrl UBGraphicsWidgetItem::getOwnFolder() const |
|
{ |
|
return ownFolder; |
|
} |
|
|
|
void UBGraphicsWidgetItem::setOwnFolder(const QUrl &newFolder) |
|
{ |
|
ownFolder = newFolder; |
|
} |
|
|
|
void UBGraphicsWidgetItem::setSnapshotPath(const QUrl &newFilePath) |
|
{ |
|
SnapshotFile = newFilePath; |
|
} |
|
|
|
QUrl UBGraphicsWidgetItem::getSnapshotPath() |
|
{ |
|
return SnapshotFile; |
|
} |
|
|
|
void UBGraphicsWidgetItem::clearSource() |
|
{ |
|
UBFileSystemUtils::deleteDir(getOwnFolder().toLocalFile()); |
|
UBFileSystemUtils::deleteFile(getSnapshotPath().toLocalFile()); |
|
} |
|
|
|
void UBGraphicsWidgetItem::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 |
|
} |
|
|
|
QSize UBGraphicsWidgetItem::nominalSize() const |
|
{ |
|
return mNominalSize; |
|
} |
|
|
|
bool UBGraphicsWidgetItem::hasLoadedSuccessfully() const |
|
{ |
|
return (mInitialLoadDone && !mLoadIsErronous); |
|
} |
|
|
|
bool UBGraphicsWidgetItem::freezable() |
|
{ |
|
return mIsFreezable; |
|
} |
|
|
|
bool UBGraphicsWidgetItem::resizable() |
|
{ |
|
return mIsResizable; |
|
} |
|
|
|
bool UBGraphicsWidgetItem::isFrozen() |
|
{ |
|
return mIsFrozen; |
|
} |
|
|
|
QPixmap UBGraphicsWidgetItem::snapshot() |
|
{ |
|
return mSnapshot; |
|
} |
|
|
|
QPixmap UBGraphicsWidgetItem::takeSnapshot() |
|
{ |
|
mIsTakingSnapshot = true; |
|
|
|
QPixmap pixmap(size().toSize()); |
|
pixmap.fill(Qt::transparent); |
|
QPainter painter(&pixmap); |
|
|
|
QStyleOptionGraphicsItem options; |
|
paint(&painter, &options); |
|
|
|
mIsTakingSnapshot = false; |
|
|
|
mSnapshot = pixmap; |
|
|
|
return pixmap; |
|
} |
|
|
|
void UBGraphicsWidgetItem::setSnapshot(const QPixmap& pix) |
|
{ |
|
mSnapshot = pix; |
|
} |
|
|
|
UBGraphicsScene* UBGraphicsWidgetItem::scene() |
|
{ |
|
return qobject_cast<UBGraphicsScene*>(QGraphicsItem::scene()); |
|
} |
|
|
|
int UBGraphicsWidgetItem::widgetType(const QUrl& pUrl) |
|
{ |
|
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; |
|
} |
|
|
|
QString UBGraphicsWidgetItem::widgetName(const QUrl& widgetPath) |
|
{ |
|
QString name; |
|
QString version; |
|
QFile w3CConfigFile(widgetPath.toLocalFile() + "/config.xml"); |
|
QFile appleConfigFile(widgetPath.toLocalFile() + "/Info.plist"); |
|
|
|
if (w3CConfigFile.exists() && w3CConfigFile.open(QFile::ReadOnly)) { |
|
QDomDocument doc; |
|
doc.setContent(w3CConfigFile.readAll()); |
|
QDomElement root = doc.firstChildElement("widget"); |
|
if (!root.isNull()) { |
|
QDomElement nameElement = root.firstChildElement("name"); |
|
if (!nameElement.isNull()) |
|
name = nameElement.text(); |
|
version = root.attribute("version", ""); |
|
} |
|
w3CConfigFile.close(); |
|
} |
|
else if (appleConfigFile.exists() && appleConfigFile.open(QFile::ReadOnly)) { |
|
QDomDocument doc; |
|
doc.setContent(appleConfigFile.readAll()); |
|
QDomElement root = doc.firstChildElement("plist"); |
|
if (!root.isNull()) { |
|
QDomElement dictElement = root.firstChildElement("dict"); |
|
if (!dictElement.isNull()) { |
|
QDomNodeList childNodes = dictElement.childNodes(); |
|
|
|
/* looking for something like |
|
* .. |
|
* <key>CFBundleDisplayName</key> |
|
* <string>brain scans</string> |
|
* .. |
|
*/ |
|
|
|
for(int i = 0; i < childNodes.count() - 1; i++) { |
|
if (childNodes.at(i).isElement()) { |
|
QDomElement elKey = childNodes.at(i).toElement(); |
|
if (elKey.text() == "CFBundleDisplayName") { |
|
if (childNodes.at(i + 1).isElement()) { |
|
QDomElement elValue = childNodes.at(i + 1).toElement(); |
|
name = elValue.text(); |
|
} |
|
} |
|
else if (elKey.text() == "CFBundleShortVersionString") { |
|
if (childNodes.at(i + 1).isElement()) { |
|
QDomElement elValue = childNodes.at(i + 1).toElement(); |
|
version = elValue.text(); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
appleConfigFile.close(); |
|
} |
|
QString result; |
|
|
|
if (name.length() > 0) { |
|
result = name; |
|
if (version.length() > 0) { |
|
result += " "; |
|
result += version; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
QString UBGraphicsWidgetItem::iconFilePath(const QUrl& pUrl) |
|
{ |
|
/* TODO UB 4.x read config.xml widget.icon param first */ |
|
|
|
QStringList files; |
|
|
|
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 */ |
|
|
|
QString file = UBFileSystemUtils::getFirstExistingFileFromList(pUrl.toLocalFile(), files); |
|
/* default */ |
|
if (file.length() == 0) |
|
{ |
|
file = QString(":/images/defaultWidgetIcon.png"); |
|
} |
|
return file; |
|
} |
|
|
|
void UBGraphicsWidgetItem::freeze() |
|
{ |
|
QPixmap pix = takeSnapshot(); |
|
mIsFrozen = true; |
|
setSnapshot(pix); |
|
} |
|
|
|
void UBGraphicsWidgetItem::unFreeze() |
|
{ |
|
mIsFrozen = false; |
|
} |
|
|
|
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; |
|
} |
|
} |
|
else if (event->type() == QEvent::ShortcutOverride) |
|
event->accept(); |
|
|
|
return QGraphicsWebView::event(event); |
|
} |
|
|
|
void UBGraphicsWidgetItem::dropEvent(QGraphicsSceneDragDropEvent *event) |
|
{ |
|
processDropEvent(event); |
|
QGraphicsWebView::dropEvent(event); |
|
} |
|
|
|
void UBGraphicsWidgetItem::mousePressEvent(QGraphicsSceneMouseEvent *event) |
|
{ |
|
if (!Delegate()->mousePressEvent(event)) |
|
setSelected(true); /* forcing selection */ |
|
|
|
QGraphicsWebView::mousePressEvent(event); |
|
|
|
// did webkit consume the mouse press ? |
|
mShouldMoveWidget = !event->isAccepted() && (event->buttons() & Qt::LeftButton); |
|
|
|
mLastMousePos = mapToScene(event->pos()); |
|
|
|
event->accept(); |
|
} |
|
|
|
void UBGraphicsWidgetItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) |
|
{ |
|
mShouldMoveWidget = false; |
|
|
|
Delegate()->mouseReleaseEvent(event); |
|
QGraphicsWebView::mouseReleaseEvent(event); |
|
} |
|
|
|
void UBGraphicsWidgetItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) |
|
{ |
|
sendJSEnterEvent(); |
|
Delegate()->hoverEnterEvent(event); |
|
} |
|
void UBGraphicsWidgetItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) |
|
{ |
|
sendJSLeaveEvent(); |
|
Delegate()->hoverLeaveEvent(event); |
|
} |
|
|
|
void UBGraphicsWidgetItem::sendJSEnterEvent() |
|
{ |
|
if (page() && page()->mainFrame()) |
|
page()->mainFrame()->evaluateJavaScript("if(widget && widget.onenter) { widget.onenter();}"); |
|
} |
|
|
|
void UBGraphicsWidgetItem::sendJSLeaveEvent() |
|
{ |
|
if (page() && page()->mainFrame()) |
|
page()->mainFrame()->evaluateJavaScript("if(widget && widget.onleave) { widget.onleave();}"); |
|
} |
|
|
|
void UBGraphicsWidgetItem::injectInlineJavaScript() |
|
{ |
|
if (!sInlineJavaScriptLoaded) { |
|
sInlineJavaScripts = UBApplication::applicationController->widgetInlineJavaScripts(); |
|
sInlineJavaScriptLoaded = true; |
|
} |
|
|
|
foreach(QString script, sInlineJavaScripts) |
|
page()->mainFrame()->evaluateJavaScript(script); |
|
} |
|
|
|
void UBGraphicsWidgetItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
{ |
|
|
|
|
|
QGraphicsWebView::paint(painter, option, widget); |
|
|
|
|
|
if (!mInitialLoadDone) { |
|
QString message; |
|
|
|
message = tr("Loading ..."); |
|
|
|
painter->setFont(QFont("Arial", 12)); |
|
|
|
QFontMetrics fm = painter->fontMetrics(); |
|
QRect txtBoundingRect = fm.boundingRect(message); |
|
|
|
txtBoundingRect.moveCenter(rect().center().toPoint()); |
|
txtBoundingRect.adjust(-10, -5, 10, 5); |
|
|
|
painter->setPen(Qt::NoPen); |
|
painter->setBrush(UBSettings::paletteColor); |
|
painter->drawRoundedRect(txtBoundingRect, 3, 3); |
|
|
|
painter->setPen(Qt::white); |
|
painter->drawText(rect(), Qt::AlignCenter, message); |
|
} |
|
|
|
Delegate()->postpaint(painter, option, widget); |
|
} |
|
|
|
void UBGraphicsWidgetItem::geometryChangeRequested(const QRect& geom) |
|
{ |
|
resize(geom.width(), geom.height()); |
|
} |
|
|
|
void UBGraphicsWidgetItem::javaScriptWindowObjectCleared() |
|
{ |
|
injectInlineJavaScript(); |
|
|
|
if(!mUniboardAPI) |
|
mUniboardAPI = new UBWidgetUniboardAPI(scene(), this); |
|
|
|
page()->mainFrame()->addToJavaScriptWindowObject("sankore", mUniboardAPI); |
|
|
|
} |
|
|
|
void UBGraphicsWidgetItem::mainFrameLoadFinished (bool ok) |
|
{ |
|
mLoadIsErronous = !ok; |
|
update(boundingRect()); |
|
|
|
if (mInitialLoadDone && scene() && scene()->renderingContext() == UBGraphicsScene::Screen) |
|
takeSnapshot(); |
|
} |
|
|
|
void UBGraphicsWidgetItem::wheelEvent(QGraphicsSceneWheelEvent *event) |
|
{ |
|
if (Delegate()->wheelEvent(event)) |
|
{ |
|
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(); |
|
} |
|
|
|
|
|
|
|
UBGraphicsAppleWidgetItem::UBGraphicsAppleWidgetItem(const QUrl& pWidgetUrl, QGraphicsItem *parent) |
|
: UBGraphicsWidgetItem(pWidgetUrl, parent) |
|
{ |
|
QString path = pWidgetUrl.toLocalFile(); |
|
|
|
if (!path.endsWith(".wdgt") && !path.endsWith(".wdgt/")) { |
|
int lastSlashIndex = path.lastIndexOf("/"); |
|
if (lastSlashIndex > 0) |
|
path = path.mid(0, lastSlashIndex + 1); |
|
} |
|
|
|
QFile plistFile(path + "/Info.plist"); |
|
plistFile.open(QFile::ReadOnly); |
|
|
|
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(); |
|
|
|
initialize(); |
|
} |
|
|
|
|
|
UBGraphicsAppleWidgetItem::~UBGraphicsAppleWidgetItem() |
|
{ |
|
/* 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 |
|
} |
|
|
|
UBItem* UBGraphicsAppleWidgetItem::deepCopy() const |
|
{ |
|
UBGraphicsAppleWidgetItem *appleWidget = new UBGraphicsAppleWidgetItem(QGraphicsWebView::url(), parentItem()); |
|
|
|
copyItemParameters(appleWidget); |
|
|
|
return appleWidget; |
|
|
|
} |
|
|
|
void UBGraphicsAppleWidgetItem::copyItemParameters(UBItem *copy) const |
|
{ |
|
UBGraphicsAppleWidgetItem *cp = dynamic_cast<UBGraphicsAppleWidgetItem*>(copy); |
|
if (cp) |
|
{ |
|
foreach(QString key, mPreferences.keys()) |
|
{ |
|
cp->setPreference(key, mPreferences.value(key)); |
|
} |
|
|
|
foreach(QString key, mDatastore.keys()) |
|
{ |
|
cp->setDatastoreEntry(key, mDatastore.value(key)); |
|
} |
|
|
|
cp->setSourceUrl(this->sourceUrl()); |
|
cp->setZValue(this->zValue()); |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool UBGraphicsW3CWidgetItem::sTemplateLoaded = false; |
|
QString UBGraphicsW3CWidgetItem::sNPAPIWrappperConfigTemplate; |
|
QMap<QString, QString> UBGraphicsW3CWidgetItem::sNPAPIWrapperTemplates; |
|
|
|
UBGraphicsW3CWidgetItem::UBGraphicsW3CWidgetItem(const QUrl& pWidgetUrl, QGraphicsItem *parent) |
|
: UBGraphicsWidgetItem(pWidgetUrl, parent) |
|
, mW3CWidgetAPI(0) |
|
{ |
|
QString path = pWidgetUrl.toLocalFile(); |
|
QDir potentialDir(path); |
|
|
|
if (!path.endsWith(".wgt") && !path.endsWith(".wgt/") && !potentialDir.exists()) { |
|
int lastSlashIndex = path.lastIndexOf("/"); |
|
if (lastSlashIndex > 0) |
|
path = path.mid(0, lastSlashIndex + 1); |
|
} |
|
|
|
if (!path.endsWith("/")) |
|
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"); |
|
|
|
if (widgetDomList.count() > 0) { |
|
QDomElement widgetElement = widgetDomList.item(0).toElement(); |
|
|
|
width = widgetElement.attribute("width", "300").toInt(); |
|
height = widgetElement.attribute("height", "150").toInt(); |
|
|
|
mMetadatas.id = widgetElement.attribute("id", ""); |
|
|
|
/* some early widget (<= 4.3.4) where using identifier instead of id */ |
|
if (mMetadatas.id.length() == 0) |
|
mMetadatas.id = widgetElement.attribute("identifier", ""); |
|
|
|
mMetadatas.version = widgetElement.attribute("version", ""); |
|
|
|
/* TODO UB 4.x map properly ub namespace */ |
|
mIsResizable = widgetElement.attribute("ub:resizable", "false") == "true"; |
|
mIsFreezable = widgetElement.attribute("ub:freezable", "true") == "true"; |
|
|
|
QString roles = widgetElement.attribute("ub:roles", "content tool").trimmed().toLower(); |
|
|
|
/* ------------------------------ */ |
|
|
|
if (roles == "" || roles.contains("tool")) |
|
mCanBeTool = UBGraphicsWidgetItem::type_ALL; |
|
|
|
if (roles.contains("twin")) |
|
mCanBeTool |= UBGraphicsWidgetItem::type_WIN; |
|
|
|
if (roles.contains("tmac")) |
|
mCanBeTool |= UBGraphicsWidgetItem::type_MAC; |
|
|
|
if (roles.contains("tunix")) |
|
mCanBeTool |= UBGraphicsWidgetItem::type_UNIX; |
|
|
|
/* --------- */ |
|
|
|
if (roles == "" || roles.contains("content")) |
|
mCanBeContent = UBGraphicsWidgetItem::type_ALL; |
|
|
|
if (roles.contains("cwin")) |
|
mCanBeContent |= UBGraphicsWidgetItem::type_WIN; |
|
|
|
if (roles.contains("cmac")) |
|
mCanBeContent |= UBGraphicsWidgetItem::type_MAC; |
|
|
|
if (roles.contains("cunix")) |
|
mCanBeContent |= UBGraphicsWidgetItem::type_UNIX; |
|
|
|
//------------------------------// |
|
|
|
QDomNodeList contentDomList = widgetElement.elementsByTagName("content"); |
|
|
|
if (contentDomList.count() > 0) { |
|
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"); |
|
|
|
if (authorDomList.count() > 0) { |
|
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"); |
|
|
|
for (int i = 0; i < propertiesDomList.length(); i++) { |
|
QDomElement preferenceElement = propertiesDomList.at(i).toElement(); |
|
QString prefName = preferenceElement.attribute("name", ""); |
|
|
|
if (prefName.length() > 0) { |
|
QString prefValue = preferenceElement.attribute("value", ""); |
|
bool readOnly = (preferenceElement.attribute("readonly", "false") == "true"); |
|
|
|
mPreferences.insert(prefName, PreferenceValue(prefValue, readOnly)); |
|
} |
|
} |
|
} |
|
|
|
if (mMainHtmlFileName.length() == 0) { |
|
QFile defaultStartFile(path + "index.htm"); |
|
|
|
if (defaultStartFile.exists()) |
|
mMainHtmlFileName = "index.htm"; |
|
else { |
|
QFile secondDefaultStartFile(path + "index.html"); |
|
|
|
if (secondDefaultStartFile.exists()) |
|
mMainHtmlFileName = "index.html"; |
|
} |
|
} |
|
|
|
mMainHtmlUrl = pWidgetUrl; |
|
mMainHtmlUrl.setPath(pWidgetUrl.path() + "/" + mMainHtmlFileName); |
|
/* is it a valid local file ? */ |
|
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); |
|
|
|
initialize(); |
|
setOwnFolder(pWidgetUrl); |
|
} |
|
|
|
UBGraphicsW3CWidgetItem::~UBGraphicsW3CWidgetItem() |
|
{ |
|
/* NOOP */ |
|
} |
|
|
|
void UBGraphicsW3CWidgetItem::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 |
|
} |
|
|
|
UBItem* UBGraphicsW3CWidgetItem::deepCopy() const |
|
{ |
|
UBGraphicsW3CWidgetItem *copy = new UBGraphicsW3CWidgetItem(mWidgetUrl, parentItem()); |
|
copy->setUuid(this->uuid()); // this is OK for now as long as Widgets are imutable |
|
copyItemParameters(copy); |
|
|
|
return copy; |
|
} |
|
|
|
QMap<QString, UBGraphicsW3CWidgetItem::PreferenceValue> UBGraphicsW3CWidgetItem::preferences() |
|
{ |
|
return mPreferences; |
|
} |
|
|
|
UBGraphicsW3CWidgetItem::Metadata UBGraphicsW3CWidgetItem::metadatas() const |
|
{ |
|
return mMetadatas; |
|
} |
|
|
|
QString UBGraphicsW3CWidgetItem::createNPAPIWrapper(const QString& url, const QString& pMimeType, const QSize& sizeHint, const QString& pName) |
|
{ |
|
const QString userWidgetPath = UBSettings::settings()->userInteractiveDirectory() + "/" + tr("Web"); |
|
QDir userWidgetDir(userWidgetPath); |
|
|
|
return createNPAPIWrapperInDir(url, userWidgetDir, pMimeType, sizeHint, pName); |
|
} |
|
|
|
QString UBGraphicsW3CWidgetItem::createNPAPIWrapperInDir(const QString& pUrl, const QDir& pDir, const QString& pMimeType, const QSize& sizeHint, const QString& pName) |
|
{ |
|
QString url = pUrl; |
|
url = UBFileSystemUtils::removeLocalFilePrefix(url); |
|
QString name = pName; |
|
|
|
QFileInfo fi(url); |
|
|
|
if (name.length() == 0) |
|
name = fi.baseName(); |
|
|
|
if (fi.exists()) |
|
url = fi.fileName(); |
|
|
|
loadNPAPIWrappersTemplates(); |
|
|
|
QString htmlTemplate; |
|
|
|
if (pMimeType.length() > 0 && sNPAPIWrapperTemplates.contains(pMimeType)) |
|
htmlTemplate = sNPAPIWrapperTemplates.value(pMimeType); |
|
else { |
|
QString extension = UBFileSystemUtils::extension(url); |
|
if (sNPAPIWrapperTemplates.contains(extension)) |
|
htmlTemplate = sNPAPIWrapperTemplates.value(extension); |
|
} |
|
|
|
if (htmlTemplate.length() > 0) { |
|
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); |
|
if (fi.exists()) { |
|
QString target = widgetLibraryPath + "/" + fi.fileName(); |
|
QString source = pUrl; |
|
source = UBFileSystemUtils::removeLocalFilePrefix(source); |
|
QFile::copy(source, target); |
|
} |
|
|
|
QFile configFile(widgetLibraryPath + "/config.xml"); |
|
|
|
if (!configFile.open(QIODevice::WriteOnly)) { |
|
qWarning() << "Cannot open file " << configFile.fileName(); |
|
return QString(); |
|
} |
|
|
|
QTextStream outConfig(&configFile); |
|
outConfig.setCodec("UTF-8"); |
|
|
|
outConfig << configTemplate; |
|
configFile.close(); |
|
|
|
QFile indexFile(widgetLibraryPath + "/index.htm"); |
|
|
|
if (!indexFile.open(QIODevice::WriteOnly)) { |
|
qWarning() << "Cannot open file " << indexFile.fileName(); |
|
return QString(); |
|
} |
|
|
|
QTextStream outIndex(&indexFile); |
|
outIndex.setCodec("UTF-8"); |
|
|
|
outIndex << htmlTemplate; |
|
indexFile.close(); |
|
|
|
return widgetLibraryPath; |
|
} |
|
else |
|
return QString(); |
|
} |
|
|
|
QString UBGraphicsW3CWidgetItem::createHtmlWrapperInDir(const QString& html, const QDir& pDir, const QSize& sizeHint, const QString& pName) |
|
{ |
|
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()); |
|
|
|
if (!configFile.open(QIODevice::WriteOnly)) { |
|
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()); |
|
if (!widgetHtmlFile.open(QIODevice::WriteOnly)) { |
|
qWarning() << "cannot open file " << widgetHtmlFile.fileName(); |
|
return QString(); |
|
} |
|
|
|
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; |
|
} |
|
|
|
QString UBGraphicsW3CWidgetItem::freezedWidgetPage() |
|
{ |
|
static QString defaultcontent; |
|
|
|
if (defaultcontent.isNull()) { |
|
QString freezedWidgetDefaultContentFilePath = freezedWidgetFilePath(); |
|
QFile wrapperFile(freezedWidgetDefaultContentFilePath); |
|
if (!wrapperFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
|
qDebug() << "can't open wrapper file " + freezedWidgetDefaultContentFilePath; |
|
defaultcontent = ""; |
|
} |
|
else { |
|
QByteArray arr = wrapperFile.readAll(); |
|
if (!arr.isEmpty()) |
|
defaultcontent = QString(arr); |
|
else { |
|
qDebug() << "content of " + freezedWidgetDefaultContentFilePath + "is empty"; |
|
defaultcontent = QString(); |
|
} |
|
} |
|
} |
|
|
|
return defaultcontent; |
|
} |
|
|
|
QString UBGraphicsW3CWidgetItem::freezedWidgetFilePath() |
|
{ |
|
return UBPlatformUtils::applicationResourcesDirectory() + "/etc/" + "freezedWidgetWrapper.html"; |
|
} |
|
|
|
bool UBGraphicsW3CWidgetItem::hasNPAPIWrapper(const QString& pMimeType) |
|
{ |
|
loadNPAPIWrappersTemplates(); |
|
|
|
return sNPAPIWrapperTemplates.contains(pMimeType); |
|
} |
|
|
|
void UBGraphicsW3CWidgetItem::javaScriptWindowObjectCleared() |
|
{ |
|
UBGraphicsWidgetItem::javaScriptWindowObjectCleared(); |
|
|
|
if(!mW3CWidgetAPI) |
|
mW3CWidgetAPI = new UBW3CWidgetAPI(this); |
|
|
|
page()->mainFrame()->addToJavaScriptWindowObject("widget", mW3CWidgetAPI); |
|
|
|
} |
|
|
|
void UBGraphicsW3CWidgetItem::loadNPAPIWrappersTemplates() |
|
{ |
|
if (!sTemplateLoaded) { |
|
sNPAPIWrapperTemplates.clear(); |
|
|
|
QString etcPath = UBPlatformUtils::applicationResourcesDirectory() + "/etc/"; |
|
|
|
QDir etcDir(etcPath); |
|
|
|
foreach(QString fileName, etcDir.entryList()) { |
|
if (fileName.startsWith("npapi-wrapper") && (fileName.endsWith(".htm") || fileName.endsWith(".html"))) { |
|
|
|
QString htmlContent = UBFileSystemUtils::readTextFile(etcPath + fileName); |
|
|
|
if (htmlContent.length() > 0) { |
|
QStringList tokens = fileName.split("."); |
|
|
|
if (tokens.length() >= 4) { |
|
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) |
|
{ |
|
QDomNodeList subList = rootElement.elementsByTagName(subTagName); |
|
|
|
QString lang = locale.name(); |
|
|
|
if (lang.length() > 2) |
|
lang[2] = QLatin1Char('-'); |
|
|
|
if (subList.count() > 1) { |
|
for(int i = 0; i < subList.count(); i++) { |
|
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(); |
|
} |
|
} |
|
|
|
if (subList.count() >= 1) { |
|
QDomElement element = subList.item(0).toElement(); |
|
return element.text(); |
|
} |
|
|
|
return QString(); |
|
} |
|
|
|
void UBGraphicsW3CWidgetItem::copyItemParameters(UBItem *copy) const |
|
{ |
|
UBGraphicsW3CWidgetItem *cp = dynamic_cast<UBGraphicsW3CWidgetItem*>(copy); |
|
if (cp) |
|
{ |
|
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()); |
|
|
|
cp->resize(this->size()); |
|
|
|
foreach(QString key, this->UBGraphicsWidgetItem::preferences().keys()) |
|
{ |
|
cp->setPreference(key, UBGraphicsWidgetItem::preferences().value(key)); |
|
} |
|
|
|
foreach(QString key, mDatastore.keys()) |
|
{ |
|
cp->setDatastoreEntry(key, mDatastore.value(key)); |
|
} |
|
|
|
cp->setZValue(this->zValue()); |
|
} |
|
} |
|
|
|
|