diff --git a/krita/ui/flake/kis_shape_controller.cpp b/krita/ui/flake/kis_shape_controller.cpp index e6e281e9a0..89d6dcd75b 100644 --- a/krita/ui/flake/kis_shape_controller.cpp +++ b/krita/ui/flake/kis_shape_controller.cpp @@ -1,225 +1,224 @@ /* * Copyright (c) 2007 Boudewijn Rempt * * This program 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; either version 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_shape_controller.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_node_manager.h" #include "kis_shape_selection.h" #include "kis_selection.h" #include "kis_selection_component.h" #include "kis_adjustment_layer.h" #include "kis_clone_layer.h" #include "canvas/kis_canvas2.h" #include "KisDocument.h" #include "kis_image.h" #include "kis_group_layer.h" #include "kis_node_shape.h" #include "kis_node_shapes_graph.h" #include "kis_name_server.h" #include "kis_mask.h" #include "kis_shape_layer.h" #include "KisViewManager.h" #include "kis_node.h" #include -#include #include #include #include #include struct KisShapeController::Private { public: KisDocument *doc; KisNameServer *nameServer; KisNodeShapesGraph shapesGraph; }; KisShapeController::KisShapeController(KisDocument *doc, KisNameServer *nameServer) : KisDummiesFacadeBase(doc) , m_d(new Private()) { m_d->doc = doc; m_d->nameServer = nameServer; resourceManager()->setUndoStack(doc->undoStack()); } KisShapeController::~KisShapeController() { KisNodeDummy *node = m_d->shapesGraph.rootDummy(); if (node) { m_d->shapesGraph.removeNode(node->node()); } delete m_d; } void KisShapeController::addNodeImpl(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis) { KisNodeShape *newShape = m_d->shapesGraph.addNode(node, parent, aboveThis); // XXX: what are we going to do with this shape? Q_UNUSED(newShape); KisShapeLayer *shapeLayer = dynamic_cast(node.data()); if (shapeLayer) { /** * Forward signals for global shape manager * \see comment in the constructor of KisCanvas2 */ connect(shapeLayer, SIGNAL(selectionChanged()), SIGNAL(selectionChanged())); connect(shapeLayer->shapeManager(), SIGNAL(selectionContentChanged()), SIGNAL(selectionContentChanged())); connect(shapeLayer, SIGNAL(currentLayerChanged(const KoShapeLayer*)), SIGNAL(currentLayerChanged(const KoShapeLayer*))); } } void KisShapeController::removeNodeImpl(KisNodeSP node) { KisShapeLayer *shapeLayer = dynamic_cast(node.data()); if (shapeLayer) { shapeLayer->disconnect(this); } m_d->shapesGraph.removeNode(node); } bool KisShapeController::hasDummyForNode(KisNodeSP node) const { return m_d->shapesGraph.containsNode(node); } KisNodeDummy* KisShapeController::dummyForNode(KisNodeSP node) const { return m_d->shapesGraph.nodeToDummy(node); } KisNodeDummy* KisShapeController::rootDummy() const { return m_d->shapesGraph.rootDummy(); } int KisShapeController::dummiesCount() const { return m_d->shapesGraph.shapesCount(); } static inline bool belongsToShapeSelection(KoShape* shape) { return dynamic_cast(shape->userData()); } void KisShapeController::addShape(KoShape* shape) { if (!image()) return; /** * Krita layers have their own creation path. * It goes through slotNodeAdded() */ Q_ASSERT(shape->shapeId() != KIS_NODE_SHAPE_ID && shape->shapeId() != KIS_SHAPE_LAYER_ID); KisCanvas2 *canvas = dynamic_cast(KoToolManager::instance()->activeCanvasController()->canvas()); Q_ASSERT(canvas); if (belongsToShapeSelection(shape)) { KisSelectionSP selection = canvas->viewManager()->selection(); if (selection) { if (!selection->shapeSelection()) { selection->setShapeSelection(new KisShapeSelection(image(), selection)); } KisShapeSelection * shapeSelection = static_cast(selection->shapeSelection()); shapeSelection->addShape(shape); } } else { KisShapeLayer *shapeLayer = dynamic_cast(shape->parent()); if (!shapeLayer) { shapeLayer = new KisShapeLayer(this, image(), i18n("Vector Layer %1", m_d->nameServer->number()), OPACITY_OPAQUE_U8); image()->undoAdapter()->addCommand(new KisImageLayerAddCommand(image(), shapeLayer, image()->rootLayer(), image()->rootLayer()->childCount())); } shapeLayer->addShape(shape); } m_d->doc->setModified(true); } void KisShapeController::removeShape(KoShape* shape) { /** * Krita layers have their own destruction path. * It goes through slotRemoveNode() */ Q_ASSERT(shape->shapeId() != KIS_NODE_SHAPE_ID && shape->shapeId() != KIS_SHAPE_LAYER_ID); shape->setParent(0); m_d->doc->setModified(true); } void KisShapeController::setInitialShapeForCanvas(KisCanvas2 *canvas) { if (!image()) return; KisNodeSP rootNode = image()->root(); if (m_d->shapesGraph.containsNode(rootNode)) { Q_ASSERT(canvas); Q_ASSERT(canvas->shapeManager()); KoSelection *selection = canvas->shapeManager()->selection(); if (selection) { selection->select(m_d->shapesGraph.nodeToShape(rootNode)); KoToolManager::instance()->switchToolRequested(KoToolManager::instance()->preferredToolForSelection(selection->selectedShapes())); } } } KoShapeLayer* KisShapeController::shapeForNode(KisNodeSP node) const { return m_d->shapesGraph.nodeToShape(node); } #include "kis_shape_controller.moc" diff --git a/libs/main/KoFindText_p.h b/libs/main/KoFindText_p.h index 97f6d08e05..6f313ae102 100644 --- a/libs/main/KoFindText_p.h +++ b/libs/main/KoFindText_p.h @@ -1,78 +1,77 @@ /* This file is part of the KDE project * * Copyright (c) 2010 Arjen Hiemstra * Copyright (C) 2011 Thorsten Zachmann * * 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 KoFindText_p_h #define KoFindText_p_h #include "KoFindText.h" #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include "KoFindOptionSet.h" #include "KoFindOption.h" #include "KoDocument.h" class KoFindText::Private { public: Private(KoFindText* qq) : q(qq), selectionStart(-1), selectionEnd(-1) { } void updateSelections(); void updateDocumentList(); void documentDestroyed(QObject *document); void updateCurrentMatch(int position); static void initializeFormats(); KoFindText *q; QList documents; QTextCursor currentCursor; QTextCursor selection; QHash > selections; int selectionStart; int selectionEnd; static QTextCharFormat highlightFormat; static QTextCharFormat currentMatchFormat; static QTextCharFormat currentSelectionFormat; static QTextCharFormat replacedFormat; static bool formatsInitialized; QPair currentMatch; }; #endif diff --git a/libs/rdf/KoDocumentRdf.cpp b/libs/rdf/KoDocumentRdf.cpp index a7a093a78a..875ceefed6 100644 --- a/libs/rdf/KoDocumentRdf.cpp +++ b/libs/rdf/KoDocumentRdf.cpp @@ -1,1074 +1,1067 @@ /* This file is part of the KDE project Copyright (C) 2010 KO GmbH Copyright (C) 2011,2012 Ben Martin hacking for fun! 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 "KoDocumentRdf.h" #include "KoRdfPrefixMapping.h" #include "RdfSemanticTreeWidgetSelectAction.h" #include "InsertSemanticObjectActionBase.h" #include "InsertSemanticObjectCreateAction.h" #include "InsertSemanticObjectReferenceAction.h" #include "KoRdfSemanticItemRegistry.h" -#include -#include #include #include -#include #include #include -#include -#include -#include #include #include #include #include #include #include #include -#include #include #include #include #include #define DEBUG_RDF #ifdef DEBUG_RDF #define RDEBUG kDebug(30015) #else #define RDEBUG if(0) kDebug(30015) #endif using namespace Soprano; class KoDocumentRdfPrivate { public: KoDocumentRdfPrivate() : model(Soprano::createModel()) , prefixMapping(0) { } ~KoDocumentRdfPrivate() { prefixMapping->deleteLater(); model->deleteLater(); } QSharedPointer model; ///< Main Model containing all Rdf for doc QMap > inlineRdfObjects; ///< Cache of weak pointers to inline Rdf KoRdfPrefixMapping *prefixMapping; ///< prefix -> URI mapping QMap > semanticItems; QMap > userStylesheets; }; KoDocumentRdf::KoDocumentRdf(QObject *parent) : KoDocumentRdfBase(parent) , d (new KoDocumentRdfPrivate()) { // if (!backendIsSane()) { // kWarning() << "Looks like the backend is not sane!"; // } d->prefixMapping = new KoRdfPrefixMapping(this); } KoDocumentRdf::~KoDocumentRdf() { RDEBUG; delete d; } QSharedPointer KoDocumentRdf::model() const { return d->model; } KoRdfPrefixMapping *KoDocumentRdf::prefixMapping() const { return d->prefixMapping; } /** * Graph context used for Rdf stored inline in content.xml * in an Rdfa like fashion. */ Soprano::Node KoDocumentRdf::inlineRdfContext() const { return Node(QUrl("http://www.calligra.org/Rdf/inline-rdf")); } QString KoDocumentRdf::rdfInternalMetadataWithoutSubjectURI() const { return "http://www.calligra.org/Rdf/internal/content.xml"; } QString KoDocumentRdf::rdfPathContextPrefix() const { return "http://www.calligra.org/Rdf/path/"; } Soprano::Node KoDocumentRdf::manifestRdfNode() const { return Node(QUrl(rdfPathContextPrefix() + "manifest.rdf")); } void KoDocumentRdf::freshenBNodes(QSharedPointer m) { Q_ASSERT(m); Q_ASSERT(d->model); QList removeList; QList addList; QMap bnodeMap; StatementIterator it = m->listStatements(); QList allStatements = it.allElements(); RDEBUG << "freshening model.sz:" << allStatements.size(); foreach (const Soprano::Statement &s, allStatements) { Soprano::Node subj = s.subject(); Soprano::Node obj = s.object(); Soprano::Statement news; if (subj.type() == Soprano::Node::BlankNode) { QString nodeStr = subj.toString(); Soprano::Node n = bnodeMap[ nodeStr ]; if (!n.isValid()) { n = d->model->createBlankNode(); bnodeMap[ nodeStr ] = n; } removeList << s; subj = n; news = Statement(subj, s.predicate(), obj, s.context()); } if (obj.type() == Soprano::Node::BlankNode) { QString nodeStr = obj.toString(); Soprano::Node n = bnodeMap[ nodeStr ]; if (!n.isValid()) { n = d->model->createBlankNode(); bnodeMap[ nodeStr ] = n; } removeList << s; obj = n; news = Statement(subj, s.predicate(), obj, s.context()); } if (news.isValid()) { addList << news; } } RDEBUG << "remove count:" << removeList.size(); RDEBUG << "add count:" << addList.size(); // Note that as of Jan 2010 you couldn't rely on // Soprano::Model::removeStatements() if every entry // in removeList did not exist exactly once in the model. KoTextRdfCore::removeStatementsIfTheyExist(m, removeList); RDEBUG << "after remove, model.sz:" << m->statementCount(); m->addStatements(addList); RDEBUG << "after add, model.sz:" << m->statementCount(); } bool KoDocumentRdf::loadRdf(KoStore *store, const Soprano::Parser *parser, const QString &fileName) { QSharedPointer tmpmodel(Soprano::createModel()); if (!d->model || !tmpmodel) { kWarning(30003) << "No soprano model"; return false; } bool ok = true; if (!store->open(fileName)) { RDEBUG << "Entry " << fileName << " not found!"; // not a warning as embedded stores don't have to have all files return false; } RDEBUG << "Loading external Rdf/XML from:" << fileName; Soprano::Node context(QUrl(rdfPathContextPrefix() + fileName)); QUrl BaseURI = QUrl(QString()); QString rdfxmlData(store->device()->readAll()); Soprano::StatementIterator it = parser->parseString(rdfxmlData, BaseURI, Soprano::SerializationRdfXml); QList allStatements = it.allElements(); RDEBUG << "Found " << allStatements.size() << " triples..." << endl; foreach (const Soprano::Statement &s, allStatements) { Soprano::Node subj = s.subject(); Soprano::Node pred = s.predicate(); Soprano::Node obj = s.object(); Error::ErrorCode err = tmpmodel->addStatement(subj, pred, obj, context); if (err != Error::ErrorNone) { RDEBUG << "Error adding triple! s:" << subj << " p:" << pred << " o:" << obj << endl; ok = false; break; } } RDEBUG << "calling freshenBNodes(), tmpmodel.sz:" << tmpmodel->statementCount(); #ifdef DEBUG_RDF dumpModel(fileName, tmpmodel); #endif freshenBNodes(tmpmodel); #ifdef DEBUG_RDF dumpModel(fileName, tmpmodel); #endif RDEBUG << "done with freshenBNodes(), tmpmodel.sz:" << tmpmodel->statementCount(); d->model->addStatements(tmpmodel->listStatements().allElements()); if (fileName == "manifest.rdf" && d->prefixMapping) { d->prefixMapping->load(d->model); foreach (const QString &semanticClass, KoRdfSemanticItemRegistry::instance()->classNames()) { hKoRdfSemanticItem si = KoRdfSemanticItemRegistry::instance()->createSemanticItem(semanticClass, this, this); si->loadUserStylesheets(d->model); } } store->close(); return ok; } bool KoDocumentRdf::loadOasis(KoStore *store) { if (!store) { kWarning(30003) << "No store backend"; return false; } if (!d->model) { kWarning(30003) << "No soprano model"; return false; } const Soprano::Parser *parser = Soprano::PluginManager::instance()->discoverParserForSerialization( Soprano::SerializationRdfXml); bool ok = loadRdf(store, parser, "manifest.rdf"); if (ok) { QString sparqlQuery = "prefix rdf: \n" "prefix odf: \n" "prefix odfcommon: \n" "select ?subj ?fileName \n" " where { \n" " ?subj rdf:type odf:MetaDataFile . \n" " ?subj odfcommon:path ?fileName \n" " } \n"; Soprano::QueryResultIterator it = d->model->executeQuery(sparqlQuery, Soprano::Query::QueryLanguageSparql); QList< QString > externalRdfFiles; // // This is a bit tricky, loadRdf() might block if the // sparql query is still being iterated, so we have to // store the fileNames and exhaust the binding result // iterator first. // while (it.next()) { QString fileName = it.binding("fileName").toString(); externalRdfFiles << fileName; } foreach (const QString &fileName, externalRdfFiles) { ok = loadRdf(store, parser, fileName); if (!ok) break; } } return ok; } bool KoDocumentRdf::saveRdf(KoStore *store, KoXmlWriter *manifestWriter, const Soprano::Node &context) const { bool ok = false; QString fileName("manifest.rdf"); if (context.toString() == inlineRdfContext().toString()) { RDEBUG << "found some internal Rdf, this is handled by augmenting the DOM"; return true; } if (!model()) { kWarning(30003) << "No soprano model"; return false; } // // The context contains the filename to save into // if (context.toString().startsWith(rdfPathContextPrefix())) { fileName = context.toString().mid(rdfPathContextPrefix().size()); } RDEBUG << "saving external file:" << fileName; if (!store->open(fileName)) { return false; } KoStoreDevice dev(store); QTextStream oss(&dev); if (fileName == "manifest.rdf" && d->prefixMapping) { d->prefixMapping->save(d->model, context); foreach (const QString &semanticClass, KoRdfSemanticItemRegistry::instance()->classNames()) { hKoRdfSemanticItem si = KoRdfSemanticItemRegistry::instance()->createSemanticItem(semanticClass, this, const_cast(this)); si->saveUserStylesheets(d->model, context); } } Soprano::StatementIterator triples = model()->listStatements(Soprano::Node(), Soprano::Node(), Soprano::Node(), context); const Soprano::Serializer *serializer = Soprano::PluginManager::instance()-> discoverSerializerForSerialization(Soprano::SerializationRdfXml); if (serializer) { QString data; QTextStream tss(&data); if (serializer->serialize(triples, tss, Soprano::SerializationRdfXml)) { tss.flush(); oss << data; RDEBUG << "fileName:" << fileName << " data.sz:" << data.size(); RDEBUG << "model.sz:" << model()->statementCount(); ok = true; } else { RDEBUG << "serialization of Rdf failed!"; } } oss.flush(); store->close(); manifestWriter->addManifestEntry(fileName, "application/rdf+xml"); return ok; } bool KoDocumentRdf::saveOasis(KoStore *store, KoXmlWriter *manifestWriter) { RDEBUG << "saveOasis() generic"; if (!d->model) { kWarning(30003) << "No soprano model"; return false; } bool ok = true; NodeIterator contextIter = model()->listContexts(); QList contexts = contextIter.allElements(); foreach (const Soprano::Node &node, contexts) { if (!saveRdf(store, manifestWriter, node)) { ok = false; } } return ok; } void KoDocumentRdf::updateXmlIdReferences(const QMap &m) { Q_ASSERT(d->model); QList removeList; QList addList; StatementIterator it = model()->listStatements( Node(), Node(QUrl("http://docs.oasis-open.org/opendocument/meta/package/common#idref")), Node(), Node()); if (!it.isValid()) return; // new xmlid->inlinerdfobject mapping QMap > inlineRdfObjects; QList allStatements = it.allElements(); foreach (const Soprano::Statement &s, allStatements) { RDEBUG << "seeking obj:" << s.object(); QMap::const_iterator mi = m.find(s.object().toString()); if (mi != m.end()) { const QString &oldID = mi.key(); const QString &newID = mi.value(); removeList << s; Statement n(s.subject(), s.predicate(), Node(LiteralValue::createPlainLiteral(newID)), s.context()); addList << n; RDEBUG << "looking for inlineRdf object for ID:" << oldID; if (KoTextInlineRdf *inlineRdf = findInlineRdfByID(oldID)) { RDEBUG << "updating the xmlid of the inline object"; RDEBUG << "old:" << oldID << " new:" << newID; inlineRdf->setXmlId(newID); inlineRdfObjects[newID] = inlineRdf; } } } // out with the old, in with the new // remove & add the triple lists. RDEBUG << "addStatements.size:" << addList.size(); RDEBUG << " remove.size:" << removeList.size(); KoTextRdfCore::removeStatementsIfTheyExist(d->model, removeList); d->model->addStatements(addList); d->inlineRdfObjects = inlineRdfObjects; } QList KoDocumentRdf::semanticItems(const QString &className, QSharedPointer m) { if (!m) { m = d->model; Q_ASSERT(m); } QList items; // TODO: improve double lookup if (KoRdfSemanticItemRegistry::instance()->classNames().contains(className)) { KoRdfSemanticItemRegistry::instance()->updateSemanticItems(d->semanticItems[className], this, className, m); items = d->semanticItems[className]; } return items; } hKoRdfSemanticItem KoDocumentRdf::createSemanticItem(const QString &semanticClass, QObject *parent) const { return KoRdfSemanticItemRegistry::instance()->createSemanticItem(semanticClass, this, parent); } void KoDocumentRdf::dumpModel(const QString &msg, QSharedPointer m) const { if (!m) { return; } QList allStatements = m->listStatements().allElements(); RDEBUG << "----- " << msg << " ----- model size:" << allStatements.size(); foreach (const Soprano::Statement &s, allStatements) { RDEBUG << s; } } Soprano::Statement KoDocumentRdf::toStatement(KoTextInlineRdf *inlineRdf) const { if (!inlineRdf) { return Soprano::Statement(); } if (inlineRdf->predicate().isEmpty()) { return Soprano::Statement(); } Soprano::Node subj = Soprano::Node::createResourceNode(QUrl(inlineRdf->subject())); Soprano::Node pred = Soprano::Node::createResourceNode(QUrl(inlineRdf->predicate())); Soprano::Node obj; switch (inlineRdf->sopranoObjectType()) { case Node::ResourceNode: obj = Soprano::Node::createResourceNode(inlineRdf->object()); break; case Node::LiteralNode: obj = Soprano::Node::createLiteralNode(inlineRdf->object()); break; case Node::BlankNode: obj = Soprano::Node::createBlankNode(inlineRdf->object()); break; } if (!inlineRdf->subject().size()) { subj = inlineRdfContext(); } RDEBUG << "subj:" << subj; RDEBUG << " pred:" << pred; RDEBUG << " obj:" << obj; Soprano::Statement ret(subj, pred, obj, inlineRdfContext()); return ret; } void KoDocumentRdf::addStatements(QSharedPointer model, const QString &xmlid) { Q_ASSERT(model); Q_ASSERT(d->model); QString sparqlQuery; QTextStream queryss(&sparqlQuery); RDEBUG << "addStatements model.sz:" << d->model->statementCount() << " xmlid:" << xmlid; queryss << "prefix pkg: \n" << "" << "select ?s ?p ?o ?g \n" << "where { \n" << " graph ?g { ?s ?p ?o } . ?s pkg:idref ?xmlid \n" << " filter( str(?xmlid) = \"" << xmlid << "\" ) \n" << "}\n"; queryss.flush(); RDEBUG << "sparql:" << sparqlQuery; Soprano::QueryResultIterator it = d->model->executeQuery(sparqlQuery, Soprano::Query::QueryLanguageSparql); while (it.next()) { Statement s(it.binding("s"), it.binding("p"), it.binding("o"), it.binding("g")); model->addStatement(s); RDEBUG << "result, s:" << it.binding("s"); RDEBUG << " p:" << it.binding("p"); RDEBUG << " o:" << it.binding("o"); } } void KoDocumentRdf::expandStatementsReferencingSubject(QSharedPointer _model) const { Q_ASSERT(_model); Q_ASSERT(d->model); QList addList; QList allStatements = _model->listStatements().allElements(); foreach (const Soprano::Statement &s, allStatements) { QList all = model()->listStatements(Node(), Node(), s.subject()).allElements(); addList.append(all); } _model->addStatements(addList); } void KoDocumentRdf::expandStatementsSubjectPointsTo(QSharedPointer _model) const { Q_ASSERT(_model); Q_ASSERT(d->model); QList addList; QList allStatements = _model->listStatements().allElements(); foreach (const Soprano::Statement &s, allStatements) { QList all = model()->listStatements(s.object(), Node(), Node()).allElements(); addList.append(all); } _model->addStatements(addList); } void KoDocumentRdf::expandStatementsSubjectPointsTo(QSharedPointer _model, const Soprano::Node &n) const { Q_ASSERT(_model); Q_ASSERT(d->model); QList addList = model()->listStatements(n, Node(), Node()).allElements(); _model->addStatements(addList); } void KoDocumentRdf::expandStatementsToIncludeRdfListsRecurse(QSharedPointer _model, QList &addList, const Soprano::Node &n) const { Q_ASSERT(_model); Q_ASSERT(d->model); Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); QList all; all = model()->listStatements(n, rdfFirst, Node()).allElements(); addList << all; all = model()->listStatements(n, rdfRest, Node()).allElements(); addList << all; foreach (const Soprano::Statement &s, all) { expandStatementsToIncludeRdfListsRecurse(_model, addList, s.object()); } } void KoDocumentRdf::expandStatementsToIncludeRdfLists(QSharedPointer model) const { Q_ASSERT(model); RDEBUG << "model.sz:" << model->statementCount(); QList addList; QList allStatements = model->listStatements().allElements(); foreach (const Soprano::Statement &s, allStatements) { expandStatementsToIncludeRdfListsRecurse(model, addList, s.subject()); } RDEBUG << "model.sz:" << model->statementCount(); RDEBUG << "addList.sz:" << addList.size(); model->addStatements(addList); } void KoDocumentRdf::expandStatementsToIncludeOtherPredicates(QSharedPointer _model) const { Q_ASSERT(_model); Q_ASSERT(d->model); QList addList; QList allStatements = _model->listStatements().allElements(); foreach (const Soprano::Statement &s, allStatements) { QList all = model()->listStatements(s.subject(), Node(), Node()).allElements(); addList.append(all); } _model->addStatements(addList); } void KoDocumentRdf::expandStatements(QSharedPointer model) const { Q_ASSERT(model); expandStatementsReferencingSubject(model); expandStatementsToIncludeOtherPredicates(model); } KAction *KoDocumentRdf::createInsertSemanticObjectReferenceAction(KoCanvasBase *host) { KAction *ret = new InsertSemanticObjectReferenceAction(host, this, i18n("Reference")); RDEBUG << "createInsertSemanticObjectReferenceAction"; return ret; } QList KoDocumentRdf::createInsertSemanticObjectNewActions(KoCanvasBase *host) { QList ret; foreach (const QString &semanticClass, KoRdfSemanticItemRegistry::instance()->classNames()) { ret.append(new InsertSemanticObjectCreateAction(host, this, semanticClass)); } return ret; } QPair KoDocumentRdf::findExtent(const QString &xmlid) const { KoTextInlineRdf *obj = findInlineRdfByID(xmlid); if (obj) { QPair ret = obj->findExtent(); RDEBUG << "(Semantic) have inline obj, extent:" << ret; return ret; } return QPair(-1, 0); } QPair KoDocumentRdf::findExtent(KoTextEditor *handler) const { Q_ASSERT(d->model); RDEBUG << "model.sz:" << d->model->statementCount(); const QTextDocument *document = handler->document(); // first check for bookmarks KoTextRangeManager *mgr = KoTextDocument(document).textRangeManager(); Q_ASSERT(mgr); QHash textRanges = mgr->textRangesChangingWithin(handler->document(), 0, handler->selectionEnd(), handler->selectionStart(), -1); foreach (const KoTextRange *range, textRanges) { return QPair(range->rangeStart(), range->rangeEnd()); } /* // find the text:meta inline objects int startPosition = handler->position(); KoInlineTextObjectManager *inlineObjectManager = KoTextDocument(handler->document()).inlineTextObjectManager(); Q_ASSERT(inlineObjectManager); QTextCursor cursor = document->find(QString(QChar::ObjectReplacementCharacter), startPosition, QTextDocument::FindBackward); while(!cursor.isNull()) { RDEBUG << "findXmlId" << cursor.position(); QTextCharFormat fmt = cursor.charFormat(); KoInlineObject *obj = inlineObjectManager->inlineTextObject(fmt); if (KoTextMeta *metamark = dynamic_cast(obj)) { if (metamark->type() == KoTextMeta::StartBookmark) { KoTextMeta *endmark = metamark->endBookmark(); Q_ASSERT(endmark); if (endmark->position() > startPosition) { return QPair(metamark->position(), endmark->position()); } } } cursor = document->find(QString(QChar::ObjectReplacementCharacter), cursor.position(), QTextDocument::FindBackward); } */ return QPair(-1, 0); } QString KoDocumentRdf::findXmlId(KoTextEditor *handler) const { int startPosition = handler->position(); Q_UNUSED(startPosition); KoTextInlineRdf *inlineRdf = 0; const QTextDocument *document = handler->document(); // first check for bookmarks KoTextRangeManager *mgr = KoTextDocument(document).textRangeManager(); Q_ASSERT(mgr); QHash textRanges = mgr->textRangesChangingWithin(document, 0, handler->selectionEnd(), handler->selectionStart(), -1); foreach (const KoTextRange *range, textRanges) { inlineRdf = range->inlineRdf(); if (inlineRdf) { return inlineRdf->xmlId(); } } /* // find the text:meta inline objects KoInlineTextObjectManager *inlineObjectManager = KoTextDocument(document).inlineTextObjectManager(); Q_ASSERT(inlineObjectManager); QTextCursor cursor = document->find(QString(QChar::ObjectReplacementCharacter), startPosition, QTextDocument::FindBackward); while(!cursor.isNull()) { RDEBUG << "Cursor position" << cursor.position(); QTextCharFormat fmt = cursor.charFormat(); KoInlineObject *obj = inlineObjectManager->inlineTextObject(fmt); RDEBUG << "obj" << obj; if (KoTextMeta *metamark = dynamic_cast(obj)) { if (metamark->type() == KoTextMeta::StartBookmark) { KoTextMeta *endmark = metamark->endBookmark(); // we used to assert on endmark, but we cannot keep people from // inserting a startbookmark and only then creating and inserting // the endmark if (endmark && endmark->position() > startPosition) { inlineRdf = metamark->inlineRdf(); } } } // if we've got inline rdf, we've found the nearest xmlid wrapping our current position if (inlineRdf) { break; } if( cursor.position() <= 0 ) break; // else continue with the next inline object cursor = document->find(QString(QChar::ObjectReplacementCharacter), cursor.position()-1, QTextDocument::FindBackward); } */ // we couldn't find inline rdf object... So try to see whether there's // inlineRdf in the charformat for the current cursor position. It's // unlikely, of course. Maybe this should be the first check, though? if (!inlineRdf) { inlineRdf = KoTextInlineRdf::tryToGetInlineRdf(handler); } if (inlineRdf) { return inlineRdf->xmlId(); } return QString(); } QSharedPointer KoDocumentRdf::findStatements(const QString &xmlid, int depth) { QSharedPointer ret(Soprano::createModel()); Q_ASSERT(ret); addStatements(ret, xmlid); for (int i = 1; i < depth; ++i) { expandStatements(ret); } return ret; } QSharedPointer KoDocumentRdf::findStatements(KoTextEditor *handler, int depth) { Q_ASSERT(d->model); QSharedPointer ret(Soprano::createModel()); Q_ASSERT(ret); QString xmlid = findXmlId(handler); KoTextInlineRdf *inlineRdf = findInlineRdfByID(xmlid); RDEBUG << "1 model.sz:" << d->model->statementCount() << " ret.sz:" << ret->statementCount(); if (inlineRdf) { RDEBUG << "have inlineRdf1...xmlid:" << inlineRdf->xmlId(); RDEBUG << " ret.sz:" << ret->statementCount(); ret->addStatement(toStatement(inlineRdf)); RDEBUG << "have inlineRdf2...xmlid:" << inlineRdf->xmlId(); RDEBUG << " ret.sz:" << ret->statementCount(); QString xmlid = inlineRdf->xmlId(); addStatements(ret, xmlid); } RDEBUG << "2 ret.sz:" << ret->statementCount(); RDEBUG << "checking for block inlineRdf..."; inlineRdf = KoTextInlineRdf::tryToGetInlineRdf(handler); if (inlineRdf) { RDEBUG << "inlineRdf:" << (void*)inlineRdf; ret->addStatement(toStatement(inlineRdf)); QString xmlid = inlineRdf->xmlId(); addStatements(ret, xmlid); RDEBUG << "have block inlineRdf...xmlid:" << inlineRdf->xmlId(); } RDEBUG << "3 ret.sz:" << ret->statementCount(); RDEBUG << "expanding statements..."; for (int i = 1; i < depth; ++i) { expandStatements(ret); } return ret; } KoTextInlineRdf *KoDocumentRdf::findInlineRdfByID(const QString &xmlid) const { if (d->inlineRdfObjects.contains(xmlid)) { QWeakPointer inlineRdf = d->inlineRdfObjects[xmlid]; if (!inlineRdf.isNull()) { return inlineRdf.data(); } else { d->inlineRdfObjects.remove(xmlid); } } return 0; } void KoDocumentRdf::rememberNewInlineRdfObject(KoTextInlineRdf *inlineRdf) { if (!inlineRdf) { return; } d->inlineRdfObjects[inlineRdf->xmlId()] = inlineRdf; } void KoDocumentRdf::updateInlineRdfStatements(const QTextDocument *qdoc) { RDEBUG << "top"; KoInlineTextObjectManager *textObjectManager = KoTextDocument(qdoc).inlineTextObjectManager(); KoTextRangeManager *textRangeManager = KoTextDocument(qdoc).textRangeManager(); d->inlineRdfObjects.clear(); if(!textObjectManager || !textRangeManager) { return; } // // Rdf from inline objects // QList kiocol = textObjectManager->inlineTextObjects(); foreach (KoInlineObject *kio, kiocol) { if (KoTextInlineRdf *inlineRdf = kio->inlineRdf()) { rememberNewInlineRdfObject(inlineRdf); } } // // Rdf from textranges // QList rangelist = textRangeManager->textRanges(); foreach (KoTextRange *range, rangelist) { if (KoTextInlineRdf *inlineRdf = range->inlineRdf()) { rememberNewInlineRdfObject(inlineRdf); } } // // Browse the blocks and see if any of them have Rdf attached // QVector formats = qdoc->allFormats(); foreach (const QTextFormat& tf, formats) { if (KoTextInlineRdf *inlineRdf = KoTextInlineRdf::tryToGetInlineRdf(tf)) { rememberNewInlineRdfObject(inlineRdf); } } if (!d->model) { return; } Soprano::Node context = inlineRdfContext(); RDEBUG << "removing"; // delete all inline Rdf statements from model d->model->removeAllStatements(Soprano::Node(), Soprano::Node(), Soprano::Node(), context); RDEBUG << "adding, count:" << d->inlineRdfObjects.size(); // add statements from inlineRdfObjects to model foreach (const QString &xmlid, d->inlineRdfObjects.keys()) { QWeakPointer sp = d->inlineRdfObjects[xmlid]; if (sp.isNull()) { d->inlineRdfObjects.remove(xmlid); } else { Soprano::Statement st = toStatement(sp.data()); if (st.isValid()) { d->model->addStatement(st); } } } RDEBUG << "done"; } void KoDocumentRdf::emitSemanticObjectAdded(hKoRdfSemanticItem item) const { emit semanticObjectAdded(item); } void KoDocumentRdf::emitSemanticObjectAddedConst(hKoRdfSemanticItem const item) const { emit semanticObjectAdded(item); } void KoDocumentRdf::emitSemanticObjectUpdated(hKoRdfSemanticItem item) { if (item) { // // reflow the formatting for each view of the semanticItem, in reverse document order // QMap col; RDEBUG << "xmlids:" << item->xmlIdList() << " reflow item:" << item->name(); insertReflow(col, item); applyReflow(col); } emit semanticObjectUpdated(item); } void KoDocumentRdf::emitSemanticObjectViewSiteUpdated(hKoRdfSemanticItem item, const QString &xmlid) { if (item) { RDEBUG << "xmlid:" << xmlid << " reflow item:" << item->name(); emit semanticObjectViewSiteUpdated(item, xmlid); } } bool KoDocumentRdf::completeLoading(KoStore *) { return true; } bool KoDocumentRdf::completeSaving(KoStore *, KoXmlWriter *, KoShapeSavingContext *) { return true; } KoDocumentRdf::reflowItem::reflowItem(hKoRdfSemanticItem si, const QString &xmlid, hKoSemanticStylesheet ss, const QPair< int, int > &extent) : m_si(si) , m_ss(ss) , m_xmlid(xmlid) , m_extent(extent) { } void KoDocumentRdf::insertReflow(QMap &col, hKoRdfSemanticItem obj, hKoSemanticStylesheet ss) { RDEBUG << "reflowing object:" << obj->name(); QStringList xmlidlist = obj->xmlIdList(); foreach (const QString &xmlid, xmlidlist) { QPair< int, int > extent = findExtent(xmlid); RDEBUG << "format(), adding reflow xmlid location:" << xmlid << " extent:" << extent; reflowItem item(obj, xmlid, ss, extent); col.insert(extent.first, item); } } void KoDocumentRdf::insertReflow(QMap &col, hKoRdfSemanticItem obj, const QString &sheetType, const QString &stylesheetName) { hKoSemanticStylesheet ss = obj->findStylesheetByName(sheetType, stylesheetName); insertReflow(col, obj, ss); } void KoDocumentRdf::insertReflow(QMap &col, hKoRdfSemanticItem obj) { RDEBUG << "reflowing object:" << obj->name(); foreach (const QString &xmlid, obj->xmlIdList()) { QPair extent = findExtent(xmlid); RDEBUG << "format(), adding reflow xmlid location:" << xmlid << " extent:" << extent; reflowItem item(obj, xmlid, hKoSemanticStylesheet(0), extent); col.insert(extent.first, item); } } void KoDocumentRdf::applyReflow(const QMap &col) { QMapIterator< int, reflowItem > i(col); i.toBack(); while (i.hasPrevious()) { const reflowItem &item = i.previous().value(); RDEBUG << "format(), extent:" << item.m_extent; RDEBUG << "xmlid:" << item.m_xmlid; RDEBUG << "format(), semitem:" << item.m_si.constData(); RDEBUG << "format(), semitem.name:" << item.m_si->name(); if (item.m_ss) { KoRdfSemanticItemViewSite vs(item.m_si, item.m_xmlid); vs.setStylesheetWithoutReflow(item.m_ss); } emitSemanticObjectViewSiteUpdated(item.m_si, item.m_xmlid); } } QList KoDocumentRdf::userStyleSheetList(const QString& className) const { return d->userStylesheets[className]; } void KoDocumentRdf::setUserStyleSheetList(const QString& className,const QList& l) { d->userStylesheets[className] = l; } bool KoDocumentRdf::backendIsSane() { const Soprano::Backend *backend = Soprano::discoverBackendByFeatures( Soprano::BackendFeatureContext | Soprano::BackendFeatureQuery | Soprano::BackendFeatureStorageMemory); if (!backend) { // without a backend with the desired features, this test fails kWarning() << "No suitable backend found."; return false; } kWarning() << "Found a backend: " << backend->pluginName(); Soprano::setUsedBackend(backend); Soprano::BackendSettings backendSettings; backendSettings << Soprano::BackendOptionStorageMemory; Soprano::StorageModel* model = backend->createModel(backendSettings); if (!model) { // if model creation failed, this test fails kWarning() << "No model could be created."; return false; } model->addStatement(Soprano::Statement( QUrl("subject"), QUrl("predicate"), QUrl("object"), QUrl("context"))); Soprano::QueryResultIterator it = model->executeQuery( "SELECT ?g ?s ?p ?o WHERE { GRAPH ?g { ?s ?p ?o } }", Soprano::Query::QueryLanguageSparql); if (!it.next()) { // there should be exactly one result statement kWarning() << "Query returned too few results."; delete model; return false; } if (it.next()) { // there should be exactly one result statement kWarning() << "Query returned too many results."; delete model; return false; } delete model; return true; } QStringList KoDocumentRdf::idrefList() const { Q_ASSERT(d->model); QStringList idrefs; StatementIterator it = model()->listStatements( Node(), Node(QUrl("http://docs.oasis-open.org/opendocument/meta/package/common#idref")), Node(), Node()); if (!it.isValid()) { return idrefs; } QList allStatements = it.allElements(); foreach (const Soprano::Statement &s, allStatements) { idrefs << s.object().toString(); } return idrefs; } diff --git a/plugins/variables/ChapterVariable.h b/plugins/variables/ChapterVariable.h index 7ff8b0ada3..2dd93a773f 100644 --- a/plugins/variables/ChapterVariable.h +++ b/plugins/variables/ChapterVariable.h @@ -1,64 +1,63 @@ /* This file is part of the KDE project * Copyright (C) 2011 Sebastian Sauer * * 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 CHAPTERVARIABLE_H #define CHAPTERVARIABLE_H #include #include -#include #include class KoShapeSavingContext; /** * This is a KoVariable for chapter variables. */ class ChapterVariable : public KoVariable { Q_OBJECT public: ChapterVariable(); // reimplmented QWidget* createOptionsWidget(); void readProperties(const KoProperties *props); void saveOdf(KoShapeSavingContext & context); bool loadOdf(const KoXmlElement & element, KoShapeLoadingContext & context); private Q_SLOTS: void formatChanged(int format); void levelChanged(int level); private: void resize(const QTextDocument *document, QTextInlineObject &object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd); enum FormatTypes { ChapterName, ChapterNumber, ChapterNumberName, ChapterPlainNumber, ChapterPlainNumberName }; FormatTypes m_format; int m_level; }; #endif diff --git a/plugins/variables/PageVariable.h b/plugins/variables/PageVariable.h index 30e33b0ade..919c3253cf 100644 --- a/plugins/variables/PageVariable.h +++ b/plugins/variables/PageVariable.h @@ -1,71 +1,70 @@ /* This file is part of the KDE project * Copyright (C) 2007 Pierre Ducroquet * Copyright (C) 2008 Thorsten Zachmann * Copyright (C) 2008 Sebastian Sauer * * 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 PAGEVARIABLE_H #define PAGEVARIABLE_H #include -#include #include #include class KoShapeSavingContext; /** * This is a KoVariable for page numbers. */ class PageVariable : public KoVariable { public: enum PageType { PageCount, PageNumber, PageContinuation }; /** * Constructor. */ PageVariable(); void readProperties(const KoProperties *props); void propertyChanged(Property property, const QVariant &value); /// reimplmented void saveOdf(KoShapeSavingContext & context); ///reimplemented bool loadOdf(const KoXmlElement & element, KoShapeLoadingContext & context); private: void resize(const QTextDocument *document, QTextInlineObject &object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd); PageType m_type; KoTextPage::PageSelection m_pageselect; int m_pageadjust; bool m_fixed; KoOdfNumberDefinition m_numberFormat; QString m_continuation; }; #endif