Warning, file /office/calligra/libs/rdf/KoRdfSemanticItem.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2010 KO GmbH <ben.martin@kogmbh.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "KoRdfSemanticItem.h" 0021 0022 //Calligra 0023 #include <KoCanvasBase.h> 0024 #include <KoCanvasResourceManager.h> 0025 #include <KoChangeTrackerDisabledRAII.h> 0026 #include <KoDocumentRdf.h> 0027 #include <KoTextDocument.h> 0028 #include <KoTextEditor.h> 0029 #include <KoText.h> 0030 #include <KoTextInlineRdf.h> 0031 #include <KoTextMeta.h> 0032 #include <KoTextRdfCore.h> 0033 0034 // KF5 0035 #include <KDebug> 0036 0037 //QT 0038 #include <QUuid> 0039 #include <QWidget> 0040 0041 using namespace Soprano; 0042 0043 KoRdfSemanticItem::KoRdfSemanticItem(QObject *parent) 0044 : KoRdfBasicSemanticItem(parent) 0045 { 0046 } 0047 0048 KoRdfSemanticItem::KoRdfSemanticItem(QObject *parent, const KoDocumentRdf *rdf) 0049 : KoRdfBasicSemanticItem(parent, rdf) 0050 { 0051 } 0052 0053 KoRdfSemanticItem::KoRdfSemanticItem(QObject *parent, const KoDocumentRdf *rdf, Soprano::QueryResultIterator &it) 0054 : KoRdfBasicSemanticItem(parent, rdf, it) 0055 { 0056 } 0057 0058 KoRdfSemanticItem::~KoRdfSemanticItem() 0059 { 0060 } 0061 0062 KoRdfSemanticTreeWidgetItem *KoRdfSemanticItem::createQTreeWidgetItem(QTreeWidgetItem *parent) 0063 { 0064 Q_UNUSED(parent); 0065 return 0; 0066 } 0067 0068 void KoRdfSemanticItem::importFromDataComplete(const QByteArray &ba, const KoDocumentRdf *rdf, KoCanvasBase *host) 0069 { 0070 Q_UNUSED(ba); 0071 0072 // Create and populate and editor with the current data, 0073 // then update the Rdf from that editor. 0074 QWidget *parent = 0; 0075 QWidget *objectEditor = createEditor(parent); 0076 updateFromEditorData(); 0077 0078 if (host) { 0079 insert(host); 0080 } 0081 delete objectEditor; 0082 0083 if (rdf) { 0084 rdf->emitSemanticObjectAdded(hKoRdfSemanticItem(this)); 0085 } 0086 } 0087 0088 void KoRdfSemanticItem::setupStylesheetReplacementMapping(QMap<QString, QString> &m) 0089 { 0090 Q_UNUSED(m); 0091 } 0092 0093 void KoRdfSemanticItem::exportToMime(QMimeData *md) const 0094 { 0095 Q_UNUSED(md); 0096 } 0097 0098 void KoRdfSemanticItem::insert(KoCanvasBase *host) 0099 { 0100 Q_UNUSED(host); 0101 kDebug(30015) << "insert..."; 0102 KoTextEditor *editor = KoTextEditor::getTextEditorFromCanvas(host); 0103 0104 Q_ASSERT(editor); 0105 Q_ASSERT(editor->document()); 0106 0107 KoTextDocument ktd(editor->document()); 0108 KoChangeTrackerDisabledRAII disableChangeTracker(ktd.changeTracker()); 0109 Q_UNUSED(disableChangeTracker); 0110 0111 // int originalpos = editor->position(); 0112 KoTextMeta *startmark = new KoTextMeta(editor->document()); 0113 editor->insertInlineObject(startmark); 0114 KoTextInlineRdf *inlineRdf(new KoTextInlineRdf((QTextDocument*)editor->document(), startmark)); 0115 0116 // generate an xml:id for inlineRdf 0117 // set it and also insert some Rdf into manifest.rdf to link 0118 // the new xml:id to the foaf Rdf data. 0119 QString newID = inlineRdf->createXmlId(); 0120 inlineRdf->setXmlId(newID); 0121 startmark->setInlineRdf(inlineRdf); 0122 0123 // we could do a paragraph relayout to update the position() values 0124 // of the start and end, but this is more efficient. 0125 startmark->updatePosition( (QTextDocument*)editor->document(), 0126 startmark->position()-1, 0127 QTextCharFormat() ); 0128 if (documentRdf()) { 0129 Soprano::Statement st( 0130 linkingSubject(), 0131 Node::createResourceNode(QUrl("http://docs.oasis-open.org/ns/office/1.2/meta/pkg#idref")), 0132 Node::createLiteralNode(newID), 0133 documentRdf()->manifestRdfNode()); 0134 documentRdf()->model()->addStatement(st); 0135 kDebug(30015) << "KoRdfSemanticItem::insert() HAVE documentRdf(), linking statement:" << st; 0136 0137 QSharedPointer<Soprano::Model> model(Soprano::createModel()); 0138 const_cast<KoDocumentRdf*>(documentRdf())->addStatements(model, newID); 0139 kDebug(30015) << "KoRdfSemanticItem::insert() returned model size:" << model->statementCount(); 0140 const_cast<KoDocumentRdf*>(documentRdf())->rememberNewInlineRdfObject(inlineRdf); 0141 } else { 0142 kDebug(30015) << "KoRdfSemanticItem::insert() documentRdf() is not set!"; 0143 } 0144 0145 // 0146 // Use stylesheets to format the display of the newly inserted 0147 // semitem. To do this, there needs to be a start and end KoTextMeta 0148 // and they have to be properly linked. So first the name() is inserted 0149 // and the endmark inserted so that the stylesheet system has a valid 0150 // begin <-> end range. To make the docker happy, we move the cursor back 0151 // over the end marker so that the cursor is within the newly inserted 0152 // semitem. 0153 // 0154 editor->insertText(name()); 0155 0156 KoTextMeta *endmark = new KoTextMeta(editor->document()); 0157 editor->insertInlineObject(endmark); 0158 startmark->setEndBookmark(endmark); 0159 0160 editor->setPosition(editor->position() - 1, QTextCursor::MoveAnchor); 0161 // let the RDF docker know about this new object too. 0162 KoCanvasResourceManager *provider = host->resourceManager(); 0163 provider->setResource(KoText::CurrentTextPosition, editor->position() - 1); 0164 0165 hKoSemanticStylesheet ss = defaultStylesheet(); 0166 KoRdfSemanticItemViewSite vs(hKoRdfSemanticItem(this), newID); 0167 vs.applyStylesheet(editor, ss); 0168 0169 } 0170 0171 QList<hKoSemanticStylesheet> KoRdfSemanticItem::userStylesheets() const 0172 { 0173 return documentRdf()->userStyleSheetList(className()); 0174 } 0175 0176 hKoSemanticStylesheet KoRdfSemanticItem::findStylesheetByUuid(const QString &id) const 0177 { 0178 hKoSemanticStylesheet ret = hKoSemanticStylesheet(0); 0179 if (id.isEmpty()) { 0180 return ret; 0181 } 0182 foreach (hKoSemanticStylesheet ss, stylesheets()) { 0183 if (ss->uuid() == id) { 0184 return ss; 0185 } 0186 } 0187 foreach (hKoSemanticStylesheet ss, userStylesheets()) { 0188 if (ss->uuid() == id) { 0189 return ss; 0190 } 0191 } 0192 return ret; 0193 } 0194 0195 hKoSemanticStylesheet KoRdfSemanticItem::findStylesheetByName(const QList<hKoSemanticStylesheet> &ssheets, 0196 const QString &n) const 0197 { 0198 hKoSemanticStylesheet ret = hKoSemanticStylesheet(0); 0199 foreach (hKoSemanticStylesheet ss, ssheets) { 0200 if (ss->name() == n) { 0201 return ss; 0202 } 0203 } 0204 return ret; 0205 } 0206 0207 hKoSemanticStylesheet KoRdfSemanticItem::findStylesheetByName(const QString &sheetType, const QString &n) const 0208 { 0209 if (sheetType == "System") { 0210 return findStylesheetByName(stylesheets(), n); 0211 } 0212 return findStylesheetByName(userStylesheets(), n); 0213 } 0214 0215 hKoSemanticStylesheet KoRdfSemanticItem::defaultStylesheet() const 0216 { 0217 QString semanticClass = metaObject()->className(); 0218 QSharedPointer<Soprano::Model> m = documentRdf()->model(); 0219 QString name = KoTextRdfCore::getProperty(m, 0220 Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0221 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet")), 0222 "name"); 0223 QString type = KoTextRdfCore::getProperty(m, 0224 Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0225 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-type")), 0226 KoSemanticStylesheet::stylesheetTypeSystem()); 0227 QString uuid = KoTextRdfCore::getProperty(m, 0228 Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0229 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-uuid")), 0230 QString()); 0231 kDebug(30015) << "name:" << name << " type:" << type << "\n uuid:" << uuid; 0232 hKoSemanticStylesheet ret = findStylesheetByUuid(uuid); 0233 if (!ret) { 0234 ret = findStylesheetByName(type, name); 0235 } 0236 if (!ret) { 0237 // The "name" stylesheet should always exist 0238 ret = findStylesheetByName(KoSemanticStylesheet::stylesheetTypeSystem(), "name"); 0239 } 0240 Q_ASSERT(ret); 0241 return ret; 0242 } 0243 0244 void KoRdfSemanticItem::defaultStylesheet(hKoSemanticStylesheet ss) 0245 { 0246 const KoDocumentRdf *rdf = documentRdf(); 0247 QSharedPointer<Soprano::Model> m = documentRdf()->model(); 0248 QString uuid = ss->uuid(); 0249 QString name = ss->name(); 0250 QString semanticClass = metaObject()->className(); 0251 0252 m->removeAllStatements( 0253 Statement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0254 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet")), 0255 Node())); 0256 m->addStatement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0257 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet")), 0258 Node::createLiteralNode(name), 0259 rdf->manifestRdfNode()); 0260 m->removeAllStatements( 0261 Statement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0262 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-type")), 0263 Node())); 0264 m->addStatement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0265 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-type")), 0266 Node::createLiteralNode(name), 0267 rdf->manifestRdfNode()); 0268 m->removeAllStatements( 0269 Statement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0270 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-uuid")), 0271 Node())); 0272 m->addStatement(Node::createResourceNode(QUrl("http://calligra.org/rdf/document/" + semanticClass)), 0273 Node::createResourceNode(QUrl("http://calligra.org/rdf/stylesheet-uuid")), 0274 Node::createLiteralNode(uuid), 0275 rdf->manifestRdfNode()); 0276 } 0277 0278 hKoSemanticStylesheet KoRdfSemanticItem::createUserStylesheet(const QString &name, const QString &templateString) 0279 { 0280 bool isMutable = true; 0281 hKoSemanticStylesheet ss = 0282 hKoSemanticStylesheet( 0283 new KoSemanticStylesheet(QUuid::createUuid().toString(), 0284 name, templateString, 0285 KoSemanticStylesheet::stylesheetTypeUser(), 0286 isMutable)); 0287 QList<hKoSemanticStylesheet> userSheets = userStylesheets(); 0288 userSheets << ss; 0289 const_cast<KoDocumentRdf*>(documentRdf())->setUserStyleSheetList(className(),userSheets); 0290 connect(ss.data(), SIGNAL(nameChanging(hKoSemanticStylesheet,QString,QString)), 0291 this, SLOT(onUserStylesheetRenamed(hKoSemanticStylesheet,QString,QString))); 0292 return ss; 0293 } 0294 0295 hKoSemanticStylesheet KoRdfSemanticItem::createSystemStylesheet(const QString &uuid, const QString &name, const QString &templateString) const 0296 { 0297 const bool isNotMutable = false; 0298 hKoSemanticStylesheet ss = 0299 hKoSemanticStylesheet(new KoSemanticStylesheet(uuid, name, templateString, KoSemanticStylesheet::stylesheetTypeSystem(), isNotMutable)); 0300 return ss; 0301 } 0302 0303 void KoRdfSemanticItem::onUserStylesheetRenamed(hKoSemanticStylesheet ss, const QString &oldName, const QString &newName) 0304 { 0305 Q_UNUSED(ss); 0306 Q_UNUSED(oldName); 0307 Q_UNUSED(newName); 0308 } 0309 0310 void KoRdfSemanticItem::destroyUserStylesheet(hKoSemanticStylesheet ss) 0311 { 0312 QList<hKoSemanticStylesheet> userSheets = userStylesheets(); 0313 userSheets.removeAll(ss); 0314 const_cast<KoDocumentRdf*>(documentRdf())->setUserStyleSheetList(className(),userSheets); 0315 } 0316 0317 void KoRdfSemanticItem::loadUserStylesheets(QSharedPointer<Soprano::Model> model) 0318 { 0319 QString semanticClass = metaObject()->className(); 0320 QString nodePrefix = "http://calligra.org/rdf/user-stylesheets/" + semanticClass + "/"; 0321 Node rdfNil = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); 0322 Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); 0323 Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); 0324 0325 Soprano::Node ListHeadSubject = Node::createResourceNode(QUrl(nodePrefix + "list")); 0326 QList<Statement> listNodes = KoTextRdfCore::loadList(model, ListHeadSubject); 0327 kDebug(30015) << "semanticClass:" << semanticClass << " listNodes.sz:" << listNodes.size(); 0328 foreach (const Soprano::Statement &s, listNodes) { 0329 Soprano::Node dataBNode = s.object(); 0330 0331 QString uuid = KoTextRdfCore::getObject(model, dataBNode, 0332 Node::createResourceNode(QUrl(nodePrefix + "uuid"))).toString(); 0333 QString name = KoTextRdfCore::getObject(model, dataBNode, 0334 Node::createResourceNode(QUrl(nodePrefix + "name"))).toString(); 0335 QString templateString = KoTextRdfCore::getObject(model, dataBNode, 0336 Node::createResourceNode(QUrl(nodePrefix + "template"))).toString(); 0337 kDebug(30015) << "dataBNode:" << dataBNode; 0338 kDebug(30015) << "loading name:" << name << " template:" << templateString; 0339 0340 if (findStylesheetByName(userStylesheets(), name)) { 0341 continue; 0342 } 0343 0344 bool isMutable = true; 0345 hKoSemanticStylesheet ss = 0346 hKoSemanticStylesheet( 0347 new KoSemanticStylesheet(uuid, name, templateString, 0348 KoSemanticStylesheet::stylesheetTypeUser(), 0349 isMutable)); 0350 QList<hKoSemanticStylesheet> userSheets = userStylesheets(); 0351 userSheets << ss; 0352 const_cast<KoDocumentRdf*>(documentRdf())->setUserStyleSheetList(className(),userSheets); 0353 connect(ss.data(), SIGNAL(nameChanging(hKoSemanticStylesheet,QString,QString)), 0354 this, SLOT(onUserStylesheetRenamed(KoSemanticStylesheetPtr,QString,QString))); 0355 } 0356 } 0357 0358 void KoRdfSemanticItem::saveUserStylesheets(QSharedPointer<Soprano::Model> model, const Soprano::Node &context) const 0359 { 0360 QString semanticClass = metaObject()->className(); 0361 QString nodePrefix = "http://calligra.org/rdf/user-stylesheets/" + semanticClass + "/"; 0362 Node rdfNil = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil")); 0363 Node rdfFirst = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#first")); 0364 Node rdfRest = Node::createResourceNode(QUrl("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest")); 0365 0366 Soprano::Node dataBNode = model->createBlankNode(); 0367 QList< Soprano::Node > dataBNodeList; 0368 0369 QList<hKoSemanticStylesheet> ssl = userStylesheets(); 0370 foreach (hKoSemanticStylesheet ss, ssl) { 0371 kDebug(30015) << "saving sheet:" << ss->name(); 0372 0373 dataBNode = model->createBlankNode(); 0374 model->addStatement(dataBNode, Node::createResourceNode(QUrl(nodePrefix + "uuid")), 0375 Node::createLiteralNode(ss->uuid()), context); 0376 model->addStatement(dataBNode, Node::createResourceNode(QUrl(nodePrefix + "name")), 0377 Node::createLiteralNode(ss->name()), context); 0378 model->addStatement(dataBNode, Node::createResourceNode(QUrl(nodePrefix + "template")), 0379 Node::createLiteralNode(ss->templateString()), context); 0380 dataBNodeList << dataBNode; 0381 } 0382 0383 kDebug(30015) << "saving list, size:" << dataBNodeList.size(); 0384 Soprano::Node ListHeadSubject = Node::createResourceNode(QUrl(nodePrefix + "list")); 0385 KoTextRdfCore::saveList(model, ListHeadSubject, dataBNodeList, context); 0386 } 0387 0388 QList<hKoRdfSemanticItem> KoRdfSemanticItem::fromList(const QList< hKoRdfBasicSemanticItem > &lst) 0389 { 0390 QList<hKoRdfSemanticItem> res; 0391 foreach (const hKoRdfBasicSemanticItem &l, lst) { 0392 KoRdfSemanticItem *newl = dynamic_cast<KoRdfSemanticItem *>(l.data()); 0393 if (newl) { 0394 res << hKoRdfSemanticItem(newl); 0395 } 0396 } 0397 return res; 0398 }