Commit 9e6df6e2 authored by Hans-Christian Ebke's avatar Hans-Christian Ebke

Added new meta data interface.


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20390 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 1016b6b3
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision: $ *
* $LastChangedBy: $ *
* $Date: $ *
* *
\*===========================================================================*/
#ifndef METADATAINTERFACE_HH
#define METADATAINTERFACE_HH
#include <OpenFlipper/common/Types.hh>
#include <QObject>
#include <QString>
#if QT_VERSION >= 0x050000
#include <QJsonDocument>
#endif
/** \file MetadataInterface.hh
*
* Interface implementing slots related to the deserialization of meta data
* (usually encountered in screenshots).
*/
/** \brief Enables implementers to react on deserialization of meta data.
*
* Using functions such as BaseObject::getCommentByKey() plugins can attach
* meta data to objects. This meta data is currently only serialized when
* taking viewer snapshots. "Plugin-DeserializeScreenshotMetadata" allows
* deserializing this metadata from a viewer snapshot. (In the future
* serialization and deserialization of meta data may occur in other contexts
* as well.)
*
* Whenever meta gets deserialized the slots in this interface will get
* triggered. Please refer to the documentation of the individual slots
* to find out which specific signal suits your needs.
*
* The slots are always triggered in the order
* slotGenericMetadataDeserialized(), slotObjectMetadataDeserialized(),
* slotObjectMetadataDeserializedJson().
*/
class MetadataInterface {
private slots:
/**
* This low-level signal is very inconvenient to use and chances are you
* want to use one of the other signals.
*
* Triggered for every top level meta data entry. Currently the only top
* level meta data entries created by OpenFlipper are "Mesh Comments",
* "Mesh Materials" and "View". "Mesh Comments" contains the raw
* concatenation of all object meta data and is very cumbersome to
* parse. In most cases it's a better idea to use
* objectMetadataDeserialized().
*/
virtual void slotGenericMetadataDeserialized(
QString key, QString value) {};
/**
* Triggered for every piece of object specific meta data encapsulated
* in "Mesh Comments".
*/
virtual void slotObjectMetadataDeserialized(
QString object_name, QString value) {};
#if QT_VERSION >= 0x050000
/**
* Triggered for every piece of object specific meta data encapsulated
* in "Mesh Comments" if it is valid JSON.
*/
virtual void slotObjectMetadataDeserializedJson(
QString object_name, QJsonDocument value) {};
#endif
signals:
/**
* Can be called by anyone who deserializes meta data, e.g. from a
* viewer snapshot PNG file. The appropriate slots within
* this interface will be triggered.
*/
virtual void metadataDeserialized(
const QVector<QPair<QString, QString> > &data) = 0;
public:
/// Destructor
virtual ~MetadataInterface() {};
};
#if QT_VERSION >= 0x050000
Q_DECLARE_INTERFACE(MetadataInterface,"OpenFlipper.MetadataInterface_qt5/1.0")
#else
Q_DECLARE_INTERFACE(MetadataInterface,"OpenFlipper.MetadataInterface_qt4/1.0")
#endif
#endif // METADATAINTERFACE_HH
......@@ -670,6 +670,6 @@ QString getSaveFileName(const QString &configProperty,
QString * selectedFilter = 0, QFileDialog::Options options = 0,
const QString & defaultSuffix = QString() );
}
} /* namespace PluginFunctions */
#endif //PLUGINFUNCTIONS_HH
......@@ -1251,6 +1251,23 @@ private slots:
void showReducedMenuBar(bool reduced);
//===========================================================================
/** @name Metadata support
* @{ */
//===========================================================================
signals:
void genericMetadataDeserialized(QString key, QString value);
void objectMetadataDeserialized(QString object_name, QString value);
#if QT_VERSION >= 0x050000
void objectMetadataDeserializedJson(
QString object_name, QJsonDocument value);
#endif
private slots:
void slotMetadataDeserialized(
const QVector<QPair<QString, QString> > &data);
private :
/// Core scripting engine
QScriptEngine scriptEngine_;
......
......@@ -64,6 +64,8 @@
#include <OpenFlipper/common/RendererInfo.hh>
#include <stdexcept>
//== IMPLEMENTATION ==========================================================
//========================================================================================
......@@ -446,6 +448,71 @@ void Core::slotGetCurrentRenderer(unsigned int _viewer, QString& _rendererName)
_rendererName = renderManager().active(_viewer)->name;
}
void Core::slotMetadataDeserialized(
const QVector<QPair<QString, QString> > &data) {
QString obj_metadata;
for (QVector<QPair<QString, QString> >::const_iterator
it = data.begin(); it != data.end(); ++it) {
if (it->first == "Mesh Comments")
obj_metadata = it->second;
emit genericMetadataDeserialized(it->first, it->second);
}
/*
* Now handle object metadata.
*/
QRegExp re_begin("BEGIN Comments for object \"([^\\n]*)\"");
QRegExp re_end("\\nEND Comments for object \"([^\\n]*)\"");
enum STATE {
STATE_SEARCH_BEGIN,
STATE_CONSUME_INNER,
STATE_EOS,
};
int cursor = 0;
QString current_object_name;
for (STATE state = STATE_SEARCH_BEGIN; state != STATE_EOS; ) {
switch (state) {
case STATE_SEARCH_BEGIN:
cursor = re_begin.indexIn(obj_metadata, cursor);
if (cursor == -1) {
state = STATE_EOS;
break;
}
current_object_name = re_begin.cap(1);
cursor += re_begin.matchedLength();
state = STATE_CONSUME_INNER;
break;
case STATE_CONSUME_INNER:
{
int next = re_end.indexIn(obj_metadata, cursor);
if (next == -1) {
state = STATE_EOS;
break;
}
const QStringRef value = obj_metadata.midRef(cursor, next - cursor);
emit objectMetadataDeserialized(current_object_name, value.toString());
#if QT_VERSION >= 0x050000
QJsonParseError json_error;
QJsonDocument json_doc =
QJsonDocument::fromJson(value.toUtf8(), &json_error);
if (json_error.error == QJsonParseError::NoError) {
emit objectMetadataDeserializedJson(
current_object_name, json_doc);
}
#endif
cursor = next + re_end.matchedLength();
state = STATE_SEARCH_BEGIN;
break;
}
default:
throw std::logic_error("metadataDeserialized(): Invalid state.");
}
}
}
//=============================================================================
......@@ -94,6 +94,7 @@
#include "OpenFlipper/BasePlugin/SelectionInterface.hh"
#include "OpenFlipper/BasePlugin/TypeInterface.hh"
#include "OpenFlipper/BasePlugin/PluginConnectionInterface.hh"
#include "OpenFlipper/BasePlugin/MetadataInterface.hh"
#include "OpenFlipper/common/RendererInfo.hh"
......@@ -2254,6 +2255,28 @@ void Core::loadPlugin(const QString& _filename,const bool _silent, QString& _lic
this , SLOT( slotEmptyObjectAdded ( int ) ),Qt::DirectConnection);
}
MetadataInterface* metadataPlugin = qobject_cast< MetadataInterface * >(plugin);
if ( metadataPlugin ) {
if (checkSlot(plugin, "slotGenericMetadataDeserialized(QString,QString)")) {
connect(this, SIGNAL(genericMetadataDeserialized(QString, QString)),
plugin, SLOT(slotGenericMetadataDeserialized(QString, QString)));
}
if (checkSlot(plugin, "slotObjectMetadataDeserialized(QString,QString)")) {
connect(this, SIGNAL(objectMetadataDeserialized(QString, QString)),
plugin, SLOT(slotObjectMetadataDeserialized(QString, QString)));
}
#if QT_VERSION >= 0x050000
if (checkSlot(plugin, "slotObjectMetadataDeserializedJson(QString,QJsonDocument)")) {
connect(this, SIGNAL(objectMetadataDeserializedJson(QString, QJsonDocument)),
plugin, SLOT(slotObjectMetadataDeserializedJson(QString, QJsonDocument)));
}
#endif
if (checkSignal(plugin, "metadataDeserialized(QVector<QPair<QString,QString> >)")) {
connect(plugin, SIGNAL(metadataDeserialized(QVector<QPair<QString, QString> >)),
this, SLOT(slotMetadataDeserialized(QVector<QPair<QString, QString> >)));
}
}
emit log(LOGOUT,"================================================================================");
}
......@@ -70,6 +70,10 @@
#include <vector>
#include <QMap>
#include "perObjectData.hh"
#if QT_VERSION >= 0x050000
#include <QJsonDocument>
#include <QJsonObject>
#endif
//== TYPEDEFS =================================================================
......@@ -575,10 +579,31 @@ class DLLEXPORTONLY BaseObject : public QObject {
result.append(QString("BEGIN Comments for object \"%1\"").arg(name()));
/*
* Compose JSON parsable object.
*/
#if QT_VERSION >= 0x050000
QJsonObject comment_obj;
for (QMap<QString, QString>::const_iterator it = commentsByKey_.begin(), it_end = commentsByKey_.end();
it != it_end; ++it) {
QJsonParseError json_error;
QString test_json_str = QString::fromUtf8("{\"test\": %1}").arg(it.value());
QByteArray test_json_ba = test_json_str.toUtf8();
QJsonDocument test_json = QJsonDocument::fromJson(test_json_ba, &json_error);
if (json_error.error != QJsonParseError::NoError) {
comment_obj[it.key()] = it.value();
} else {
comment_obj[it.key()] = test_json.object().value("test");
}
}
result.append(QString::fromUtf8(QJsonDocument(comment_obj).toJson(QJsonDocument::Indented)));
#else
for (QMap<QString, QString>::const_iterator it = commentsByKey_.begin(), it_end = commentsByKey_.end();
it != it_end; ++it) {
result.append(QString("%1: %2").arg(it.key(), it.value()));
}
#endif
result.append(QString("END Comments for object \"%1\"\n").arg(name()));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment