Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 123e2cc4 authored by Ben Martin's avatar Ben Martin

Some RDF goodness landing in trunk.

http://reviewboard.kde.org/r/2611/


svn path=/trunk/koffice/; revision=1089600
parent b50ea15c
......@@ -180,9 +180,25 @@ set(EXIV2_MIN_VERSION "0.16")
macro_optional_find_package(Exiv2)
macro_log_feature(EXIV2_FOUND "Exiv2" "Image metadata library and tools" "http://www.exiv2.org" FALSE "0.16" "Required by Krita")
##
## Test for soprano
##
macro_optional_find_package(Soprano)
macro_log_feature(Soprano_FOUND "Soprano" "KDE4 RDF handling library" "http://soprano.sourceforge.net/" FALSE "" "Required to handle RDF metadata in ODF")
if(NOT Soprano_FOUND)
set(SHOULD_BUILD_RDF FALSE)
set(SOPRANO_INCLUDE_DIR "")
else(NOT Soprano_FOUND)
set(SHOULD_BUILD_RDF TRUE)
endif(NOT Soprano_FOUND)
if( Soprano_FOUND )
add_definitions( -DSHOULD_BUILD_RDF )
endif( Soprano_FOUND )
##
## Test for lcms
##
##
macro_optional_find_package(LCMS)
set(REQUIRED_LCMS_VERSION 118)
if(LCMS_FOUND AND NOT LCMS_VERSION LESS ${REQUIRED_LCMS_VERSION})
......@@ -302,6 +318,7 @@ set(KOTEXT_INCLUDES ${CMAKE_SOURCE_DIR}/libs/kotext
# komain depends on kotext & flake
set(KOMAIN_INCLUDES ${KDE4_INCLUDES}
${SOPRANO_INCLUDE_DIR}
${KOTEXT_INCLUDES}
${CMAKE_SOURCE_DIR}/libs/widgets
${CMAKE_SOURCE_DIR}/libs/main
......
......@@ -51,6 +51,8 @@ set(kotext_LIB_SRCS
KoTextPage.cpp
KoPageProvider.cpp
KoTableColumnAndRowStyleManager.cpp
KoTextInlineRdf.cpp
KoTextMeta.cpp
styles/Styles_p.cpp
styles/KoCharacterStyle.cpp
......@@ -79,9 +81,18 @@ set(kotext_LIB_SRCS
KoTextDrag.cpp
)
if( Soprano_FOUND )
set(kotext_LIB_SRCS ${kotext_LIB_SRCS}
KoTextRdfCore.cpp
)
endif( Soprano_FOUND )
kde4_add_library(kotext SHARED ${kotext_LIB_SRCS})
target_link_libraries(kotext flake ${KDE4_KUTILS_LIBS})
if( Soprano_FOUND )
target_link_libraries(kotext ${SOPRANO_LIBRARIES})
endif( Soprano_FOUND )
target_link_libraries(kotext LINK_INTERFACE_LIBRARIES flake)
set_target_properties(kotext PROPERTIES
......@@ -118,6 +129,9 @@ install(
KoVariable.h
KoVariableManager.h
KoVariableRegistry.h
KoTextRdfCore.h
KoTextInlineRdf.h
KoTextMeta.h
DESTINATION
${INCLUDE_INSTALL_DIR} COMPONENT Devel
......
......@@ -21,6 +21,7 @@
#include <KoShapeSavingContext.h>
#include <KoXmlWriter.h>
#include <KoTextInlineRdf.h>
#include <QTextDocument>
#include <QTextInlineObject>
......@@ -33,7 +34,9 @@
class KoBookmark::Private
{
public:
Private(const QTextDocument *doc) : document(doc) { }
Private(const QTextDocument *doc)
: document(doc),
posInDocument(0) { }
const QTextDocument *document;
int posInDocument;
KoBookmark *endBookmark;
......@@ -68,6 +71,10 @@ void KoBookmark::saveOdf(KoShapeSavingContext &context)
nodeName = "text:bookmark-end";
writer->startElement(nodeName.toLatin1(), false);
writer->addAttribute("text:name", d->name.toLatin1());
if (d->type == StartBookmark && inlineRdf()) {
inlineRdf()->saveOdf(context, writer);
}
writer->endElement();
}
......
......@@ -22,7 +22,9 @@
#include "KoTextDocumentLayout.h"
#include "KoShapeSavingContext.h"
#include "KoInlineTextObjectManager.h"
#include "KoTextInlineRdf.h"
#include <kdebug.h>
#include <QDebug>
QDebug KoInlineObjectPrivate::printDebug(QDebug dbg) const
......@@ -50,6 +52,9 @@ KoInlineObject::~KoInlineObject()
if (d_ptr->manager) {
d_ptr->manager->removeInlineObject(this);
}
if (d_ptr->rdf) {
delete d_ptr->rdf;
}
delete d_ptr;
d_ptr = 0;
}
......@@ -109,3 +114,15 @@ QDebug operator<<(QDebug dbg, const KoInlineObject *o)
return o->d_func()->printDebug(dbg);
}
void KoInlineObject::setInlineRdf(KoTextInlineRdf* rdf)
{
Q_D(KoInlineObject);
d->rdf = rdf;
}
KoTextInlineRdf* KoInlineObject::inlineRdf() const
{
Q_D(const KoInlineObject);
return d->rdf;
}
......@@ -34,6 +34,7 @@ class KoShape;
class KoInlineTextObjectManager;
class KoInlineObjectPrivate;
class KoShapeSavingContext;
class KoTextInlineRdf;
/**
* Base class for all inline-text-objects.
......@@ -195,6 +196,19 @@ public:
*/
bool propertyChangeListener() const;
/**
* An inline object might have some Rdf metadata associated with it
* in content.xml
* Ownership of the rdf object is taken by this object, you should not
* delete it.
*/
void setInlineRdf(KoTextInlineRdf* rdf);
/**
* Get any Rdf which was stored in content.xml for this inline object
* This object continues to own the object, do not delete it.
*/
KoTextInlineRdf* inlineRdf() const;
protected:
explicit KoInlineObject(KoInlineObjectPrivate &, bool propertyChangeListener = false);
......
......@@ -18,21 +18,23 @@
*/
#include <QDebug>
class KoTextInlineRdf;
class KoInlineObjectPrivate
{
public:
KoInlineObjectPrivate()
: manager(0),
id(-1),
propertyChangeListener(0)
{
: manager(0),
id(-1),
propertyChangeListener(0),
rdf(0) {
}
virtual ~KoInlineObjectPrivate() { }
KoInlineTextObjectManager *manager;
int id;
bool propertyChangeListener;
KoTextInlineRdf* rdf; //< An inline object might have RDF, we own it.
virtual QDebug printDebug(QDebug dbg) const;
};
......@@ -54,7 +54,9 @@ enum Options {
CurrentTextAnchor = 341899485, ///< used by the text plugin whenever the anchor-position is changed
SelectedTextPosition = 21314576, ///< used by the text plugin whenever the alternative selection is changed
/// used by the text plugin whenever the alternative selection anchor-position is changed
SelectedTextAnchor = 3344189
SelectedTextAnchor = 3344189,
DocumentRdf ///< The KoDocumentRdf for the document,
/// this will be a KoDocumentRdfBase when Soprano support is not compiled in.
};
/// For paragraphs each tab definition is represented by this struct.
......
......@@ -33,6 +33,7 @@ class KoStyleManager;
class KoInlineTextObjectManager;
class KUndoStack;
class KoTextEditor;
class KoDocument;
/**
* KoTextDocument provides an easy mechanism to set and access the
......
......@@ -19,7 +19,6 @@
*/
#include "KoTextDrag.h"
#include <QApplication>
#include <QBuffer>
#include <QByteArray>
......@@ -41,6 +40,10 @@
#include "KoTextOdfSaveHelper.h"
#ifdef SHOULD_BUILD_RDF
#include "KoTextRdfCore.h"
#endif
KoTextDrag::KoTextDrag()
: m_mimeData(0)
{
......@@ -100,6 +103,8 @@ bool KoTextDrag::setOdf(const char * mimeType, KoTextOdfSaveHelper &helper)
Q_ASSERT(false);
}
}
kDebug(30015) << "helper.model:" << helper.rdfModel();
textSharedData->setRdfModel(helper.rdfModel());
if (!helper.writeBody()) {
return false;
......@@ -113,6 +118,15 @@ bool KoTextDrag::setOdf(const char * mimeType, KoTextOdfSaveHelper &helper)
//add manifest line for content.xml
manifestWriter->addManifestEntry("content.xml", "text/xml");
kDebug(30015) << "testing to see if we should add rdf to odf file?";
#ifdef SHOULD_BUILD_RDF
// RDF: Copy relevant RDF to output ODF
if (Soprano::Model* m = helper.rdfModel()) {
kDebug(30015) << "rdf model size:" << m->statementCount();
KoTextRdfCore::createAndSaveManifest(m, textSharedData->getRdfIdMapping(),
store, manifestWriter);
}
#endif
if (!mainStyles.saveOdfStylesDotXml(store, manifestWriter)) {
return false;
......
......@@ -1002,13 +1002,13 @@ int KoTextEditor::position() const
void KoTextEditor::removeSelectedText()
{
//TODO
d->caret.removeSelectedText();
}
void KoTextEditor::select(QTextCursor::SelectionType selection)
{
//TODO add selection of previous/next char, and option about hasSelection
d->caret.select (selection);
d->caret.select(selection);
}
QString KoTextEditor::selectedText() const
......
/* This file is part of the KDE project
Copyright (C) 2010 KO GmbH <ben.martin@kogmbh.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoTextInlineRdf.h"
#include <opendocument/KoTextSharedSavingData.h>
#include <KoShapeSavingContext.h>
#include <KoXmlReader.h>
#include <KoXmlWriter.h>
#include <KoXmlNS.h>
#include "KoBookmark.h"
#include "KoTextMeta.h"
#include "KoTextBlockData.h"
#include "KoCharacterStyle.h"
#include "KoTextEditor.h"
#include <kdebug.h>
#include <QTextCursor>
#include <QUuid>
#ifdef SHOULD_BUILD_RDF
#include <Soprano/Soprano>
enum Type {
EmptyNode = Soprano::Node::EmptyNode,
ResourceNode = Soprano::Node::ResourceNode,
LiteralNode = Soprano::Node::LiteralNode,
BlankNode = Soprano::Node::BlankNode
};
#else
enum Type {
EmptyNode,
ResourceNode,
LiteralNode,
BlankNode
};
#endif
class KoTextInlineRdf::Private
{
public:
Private(QTextDocument* doc, QTextBlock b)
: block(b),
document(doc),
bookmark(0),
kotextmeta(0) {
isObjectAttriuteUsed = false;
sopranoObjectType = LiteralNode;
}
Private(QTextDocument* doc, KoBookmark* b)
: document(doc),
bookmark(b),
kotextmeta(0) {
isObjectAttriuteUsed = false;
sopranoObjectType = LiteralNode;
}
Private(QTextDocument* doc, KoTextMeta* b)
:
document(doc),
bookmark(0),
kotextmeta(b) {
isObjectAttriuteUsed = false;
sopranoObjectType = LiteralNode;
}
Private(QTextDocument* doc, QTextTableCell c)
: document(doc),
bookmark(0),
kotextmeta(0),
cell(c) {
isObjectAttriuteUsed = false;
sopranoObjectType = LiteralNode;
}
QString id; // original xml:id
// where we might get the object value from
QTextBlock block;
// or document and one of bookmark, kotextmeta, ...
QTextDocument* document;
KoBookmark* bookmark;
KoTextMeta* kotextmeta;
QTextTableCell cell;
QString subject;
QString predicate;
int sopranoObjectType;
QString dt;
// if the content="" attribute was used,
// then isObjectAttriuteUsed=1 and object=content attribute value.
QString object;
bool isObjectAttriuteUsed;
};
KoTextInlineRdf::KoTextInlineRdf(QTextDocument* doc, QTextBlock b)
: d(new Private(doc, b))
{
}
KoTextInlineRdf::KoTextInlineRdf(QTextDocument* doc, KoBookmark* b)
: d(new Private(doc, b))
{
}
KoTextInlineRdf::KoTextInlineRdf(QTextDocument* doc, KoTextMeta* b)
: d(new Private(doc, b))
{
}
KoTextInlineRdf::KoTextInlineRdf(QTextDocument* doc, QTextTableCell b)
: d(new Private(doc, b))
{
}
KoTextInlineRdf::~KoTextInlineRdf()
{
kDebug(30015) << " this:" << (void*)this;
delete d;
}
bool KoTextInlineRdf::loadOdf(const KoXmlElement& e)
{
d->id = e.attribute("id", QString());
d->subject = e.attributeNS(KoXmlNS::xhtml, "about");
d->predicate = e.attributeNS(KoXmlNS::xhtml, "property");
d->dt = e.attributeNS(KoXmlNS::xhtml, "datatype");
QString content = e.attributeNS(KoXmlNS::xhtml, "content");
//
// Content / triple object explicitly set through an attribute
//
if (e.hasAttributeNS(KoXmlNS::xhtml, "content")) {
d->isObjectAttriuteUsed = true;
d->object = content;
}
return true;
}
bool KoTextInlineRdf::saveOdf(KoShapeSavingContext &context, KoXmlWriter* writer)
{
kDebug(30015) << " this:" << (void*)this << " xmlid:" << d->id;
QString oldID = d->id;
KoSharedSavingData *sharedData = context.sharedData(KOTEXT_SHARED_SAVING_ID);
KoTextSharedSavingData *textSharedData = 0;
if (sharedData) {
textSharedData = dynamic_cast<KoTextSharedSavingData *>(sharedData);
}
QString newID = createXmlId(writer);
if (KoTextSharedSavingData* sharedData =
dynamic_cast<KoTextSharedSavingData *>(
context.sharedData(KOTEXT_SHARED_SAVING_ID))) {
sharedData->addRdfIdMapping(oldID, newID);
}
kDebug(30015) << "oldID:" << oldID << " newID:" << newID;
writer->addAttribute("xml:id", newID);
if (!d->subject.isEmpty()) {
writer->addAttribute("xhtml:about", d->subject);
}
if (!d->predicate.isEmpty()) {
writer->addAttribute("xhtml:property", d->predicate);
}
if (!d->dt.isEmpty()) {
writer->addAttribute("xhtml:datatype", d->dt);
}
if (d->isObjectAttriuteUsed) {
writer->addAttribute("xhtml:content", d->object);
}
kDebug(30015) << "done..";
return true;
}
QString KoTextInlineRdf::createXmlId(KoXmlWriter* writer)
{
Q_UNUSED(writer);
QString uuid = QUuid::createUuid().toString();
uuid.replace("{", QString());
uuid.replace("}", QString());
QString ret = "rdfid-" + uuid;
kDebug(30015) << "createXmlId() ret:" << ret;
return ret;
}
QString KoTextInlineRdf::subject()
{
return d->subject;
}
QString KoTextInlineRdf::predicate()
{
return d->predicate;
}
QPair< int, int > KoTextInlineRdf::findExtent()
{
if (d->bookmark && d->document) {
KoBookmark* e = d->bookmark->endBookmark();
return QPair< int, int >(d->bookmark->position(), e->position());
}
if (d->kotextmeta && d->document) {
KoTextMeta* e = d->kotextmeta->endBookmark();
if (!e) {
return QPair< int, int >(0, 0);
}
return QPair< int, int >(d->kotextmeta->position(), e->position());
}
if (d->cell.isValid() && d->document) {
QTextCursor b = d->cell.firstCursorPosition();
QTextCursor e = d->cell.lastCursorPosition();
return QPair< int, int >(b.position(), e.position());
}
return QPair< int, int >(0, 0);
}
QString KoTextInlineRdf::object()
{
if (d->isObjectAttriuteUsed) {
return d->object;
}
if (d->bookmark && d->document) {
KoBookmark* e = d->bookmark->endBookmark();
QTextCursor cursor(d->document);
cursor.setPosition(d->bookmark->position(), QTextCursor::MoveAnchor);
cursor.setPosition(e->position(), QTextCursor::KeepAnchor);
QString ret = cursor.QTextCursor::selectedText();
return ret.replace(QChar::ObjectReplacementCharacter, QString());
}
if (d->kotextmeta && d->document) {
KoTextMeta* e = d->kotextmeta->endBookmark();
QTextCursor cursor(d->document);
if (!e) {
kDebug(30015) << "Broken KoTextMeta, no end tag found!";
return "";
} else {
cursor.setPosition(d->kotextmeta->position(), QTextCursor::MoveAnchor);
cursor.setPosition(e->position(), QTextCursor::KeepAnchor);
QString ret = cursor.selectedText();
return ret.replace(QChar::ObjectReplacementCharacter, QString());
}
}
if (d->cell.isValid() && d->document) {
QTextCursor b = d->cell.firstCursorPosition();
QTextCursor e = d->cell.lastCursorPosition();
QTextCursor cursor(d->document);
cursor.setPosition(b.position(), QTextCursor::MoveAnchor);
cursor.setPosition(e.position(), QTextCursor::KeepAnchor);
QString ret = cursor.selectedText();
return ret.replace(QChar::ObjectReplacementCharacter, QString());
}
return d->block.text();
}
int KoTextInlineRdf::sopranoObjectType()
{
return d->sopranoObjectType;
}
QString KoTextInlineRdf::xmlId()
{
return d->id;
}
void KoTextInlineRdf::setXmlId(const QString& id)
{
d->id = id;
}
KoTextInlineRdf* KoTextInlineRdf::tryToGetInlineRdf(QTextFormat& tf)
{
if (!tf.hasProperty(KoCharacterStyle::inlineRdf)) {
return 0;
}
QVariant v = tf.property(KoCharacterStyle::inlineRdf);
KoTextInlineRdf* inlineRdf = v.value< KoTextInlineRdf* >();
if (inlineRdf) {
return inlineRdf;
}
KoTextInlineRdf* ret(0);
return ret;
}
KoTextInlineRdf* KoTextInlineRdf::tryToGetInlineRdf(QTextCursor& cursor)
{
QTextCharFormat cf = cursor.charFormat();
QVariant v = cf.property(KoCharacterStyle::inlineRdf);
KoTextInlineRdf* inlineRdf = v.value< KoTextInlineRdf* >();
if (inlineRdf) {
return inlineRdf;
}
KoTextInlineRdf* ret(0);
return ret;
}
KoTextInlineRdf* KoTextInlineRdf::tryToGetInlineRdf(KoTextEditor* handler)
{
QTextCharFormat cf = handler->charFormat();
QVariant v = cf.property(KoCharacterStyle::inlineRdf);
KoTextInlineRdf* inlineRdf = v.value< KoTextInlineRdf* >();
if (inlineRdf) {
return inlineRdf;
}
KoTextInlineRdf* ret(0);
return ret;
}
void KoTextInlineRdf::attach(KoTextInlineRdf* inlineRdf, QTextCursor& cursor)
{
QTextCharFormat format = cursor.charFormat();
QVariant v = QVariant::fromValue(inlineRdf);
format.setProperty(KoCharacterStyle::inlineRdf, v);
cursor.mergeCharFormat(format);
}
/* This file is part of the KDE project
Copyright (C) 2010 KO GmbH <ben.martin@kogmbh.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KO_TEXT_INLINE_RDF_H
#define KO_TEXT_INLINE_RDF_H
#include "kotext_export.h"
#include "KoXmlReaderForward.h"
#include <QTextBlockUserData>
#include <QTextTableCell>
class KoXmlWriter;
class KoShapeSavingContext;
class KoBookmark;
class KoTextMeta;
class KoTextInlineRdf;
class RdfSemanticItem;
class RdfFoaF;
class KoTextEditor;
/**
* @short Store information from xhtml:property etc which are for inline Rdf
*
* @author Ben Martin <ben.martin@kogmbh.com>
* @see KoDocumentRdf
*