File indexing completed on 2024-05-19 15:27:50
0001 /* This file is part of KGraphViewer. 0002 Copyright (C) 2005-2007 Gael de Chalendar <kleag@free.fr> 0003 0004 KGraphViewer is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation, version 2. 0007 0008 This program is distributed in the hope that it will be useful, 0009 but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0011 General Public License for more details. 0012 0013 You should have received a copy of the GNU General Public License 0014 along with this program; if not, write to the Free Software 0015 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0016 02110-1301, USA 0017 */ 0018 0019 #include "kgraphviewer_part.h" 0020 #include "config-kgraphviewer.h" 0021 #include "dotgraph.h" 0022 #include "dotgraphview.h" 0023 #include "kgraphviewerlib_debug.h" 0024 0025 #include <KDirWatch> 0026 #include <KPluginFactory> 0027 #include <KSharedConfig> 0028 #include <QAction> 0029 #include <QDebug> 0030 #include <QIcon> 0031 #include <QStandardPaths> 0032 #include <iostream> 0033 #include <kactioncollection.h> 0034 #include <klocalizedstring.h> 0035 #include <kselectaction.h> 0036 #include <kstandardaction.h> 0037 #include <ktoggleaction.h> 0038 0039 #include <graphviz/gvc.h> 0040 0041 // #include "kgraphviewersettings.h" 0042 #include "kgraphviewer_partsettings.h" 0043 0044 namespace KGraphViewer 0045 { 0046 K_PLUGIN_FACTORY_WITH_JSON(KGraphViewerPartFactory, 0047 "kgraphviewer_part.json", 0048 registerPlugin<KGraphViewerPart>();) 0049 0050 class KGraphViewerPartPrivate 0051 { 0052 public: 0053 KGraphViewerPartPrivate() 0054 : m_watch(new KDirWatch()) 0055 , m_layoutMethod(KGraphViewerInterface::InternalLibrary) 0056 { 0057 } 0058 0059 ~KGraphViewerPartPrivate() 0060 { 0061 delete m_watch; 0062 } 0063 0064 DotGraphView *m_widget; 0065 KDirWatch *m_watch; 0066 KGraphViewerPart::LayoutMethod m_layoutMethod; 0067 }; 0068 0069 KGraphViewerPart::KGraphViewerPart(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList &) 0070 : KParts::ReadOnlyPart(parent) 0071 , d(new KGraphViewerPartPrivate()) 0072 { 0073 /* set the component name (1st argument) so that the XMLGUI .rc 0074 file is found also when this part is called from applications 0075 different then kgraphviewer (like kgrapheditor and konqueror). 0076 */ 0077 setMetaData(metaData); 0078 0079 // set our XML-UI resource file 0080 setXMLFile(QStringLiteral("kgraphviewer_part.rc"), true); 0081 0082 // this should be your custom internal widget 0083 d->m_widget = new DotGraphView(actionCollection(), parentWidget); 0084 d->m_widget->initEmpty(); 0085 d->m_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0086 connect(d->m_widget, &DotGraphView::graphLoaded, this, &KGraphViewerPart::graphLoaded); 0087 connect(d->m_widget, &DotGraphView::newEdgeAdded, this, &KGraphViewerPart::newEdgeAdded); 0088 connect(d->m_widget, &DotGraphView::newNodeAdded, this, &KGraphViewerPart::newNodeAdded); 0089 connect(d->m_widget, &DotGraphView::removeEdge, this, &KGraphViewerPart::removeEdge); 0090 connect(d->m_widget, &DotGraphView::removeElement, this, &KGraphViewerPart::removeElement); 0091 connect(d->m_widget, &DotGraphView::selectionIs, this, &KGraphViewerPart::selectionIs); 0092 connect(d->m_widget, static_cast<void (DotGraphView::*)(const QString &, const QPoint &)>(&DotGraphView::contextMenuEvent), this, &KGraphViewerPart::contextMenuEvent); 0093 connect(d->m_widget, &DotGraphView::newEdgeFinished, this, &KGraphViewerPart::newEdgeFinished); 0094 connect(d->m_widget, &DotGraphView::hoverEnter, this, &KGraphViewerPart::hoverEnter); 0095 connect(d->m_widget, &DotGraphView::hoverLeave, this, &KGraphViewerPart::hoverLeave); 0096 0097 // notify the part that this is our internal widget 0098 setWidget(d->m_widget); 0099 0100 QAction *printAct = actionCollection()->addAction(KStandardAction::Print, "file_print", d->m_widget, SLOT(print())); 0101 actionCollection()->setDefaultShortcut(printAct, Qt::ControlModifier + Qt::Key_P); 0102 printAct->setWhatsThis(i18n("Print the graph using current page setup settings")); 0103 0104 QAction *printPreviewAct = actionCollection()->addAction(KStandardAction::PrintPreview, "file_print_preview", d->m_widget, SLOT(printPreview())); 0105 actionCollection()->setDefaultShortcut(printPreviewAct, Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_P); 0106 printPreviewAct->setWhatsThis(i18n("Open the print preview window")); 0107 0108 // KAction* pagesetupAct = new KAction(i18n("&Page setup"), this); //actionCollection(), "file_page_setup"); 0109 QAction *pagesetupAct = actionCollection()->addAction("file_page_setup", d->m_widget, SLOT(pageSetup())); 0110 pagesetupAct->setText(i18n("Page setup")); 0111 pagesetupAct->setWhatsThis(i18n("Opens the Page Setup dialog to allow graph printing to be setup")); 0112 0113 QAction *redisplayAct = actionCollection()->addAction(KStandardAction::Redisplay, "view_redisplay", d->m_widget, SLOT(reload())); 0114 redisplayAct->setWhatsThis(i18n("Reload the current graph from file")); 0115 redisplayAct->setShortcut(Qt::Key_F5); 0116 0117 QAction *zoomInAct = actionCollection()->addAction(KStandardAction::ZoomIn, "view_zoom_in", d->m_widget, SLOT(zoomIn())); 0118 // xgettext: no-c-format 0119 zoomInAct->setWhatsThis(i18n("Zoom in by 10% on the currently viewed graph")); 0120 zoomInAct->setShortcut(Qt::Key_F7); 0121 0122 QAction *zoomOutAct = actionCollection()->addAction(KStandardAction::ZoomOut, "view_zoom_out", d->m_widget, SLOT(zoomOut())); 0123 // xgettext: no-c-format 0124 zoomOutAct->setWhatsThis(i18n("Zoom out by 10% from the currently viewed graph")); 0125 zoomOutAct->setShortcut(Qt::Key_F8); 0126 } 0127 0128 QString KGraphViewerPart::componentName() const 0129 { 0130 // also the part ui.rc file is in the program folder 0131 // TODO: change the component name to "kgraphviewerpart" by removing this method and 0132 // adapting the folder where the file is placed. 0133 // Needs a way to also move any potential custom user ui.rc files 0134 // from kgraphviewer/kgraphviewer_part.rc to kgraphviewerpart/kgraphviewer_part.rc 0135 return QStringLiteral("kgraphviewer"); 0136 } 0137 0138 /*DotGraph* KGraphViewerPart::graph() 0139 { 0140 return d->m_widget->graph(); 0141 } 0142 0143 const DotGraph* KGraphViewerPart::graph() const 0144 { 0145 return d->m_widget->graph(); 0146 } 0147 */ 0148 0149 void KGraphViewerPart::setBackgroundColor(const QColor &color) 0150 { 0151 d->m_widget->setBackgroundColor(color); 0152 } 0153 0154 bool KGraphViewerPart::closeUrl() 0155 { 0156 return d->m_widget->initEmpty(); 0157 } 0158 0159 bool KGraphViewerPart::slotLoadLibrary(graph_t *graph) 0160 { 0161 bool res = d->m_widget->slotLoadLibrary(graph); 0162 if (res) 0163 d->m_widget->show(); 0164 return res; 0165 } 0166 0167 KGraphViewerPart::~KGraphViewerPart() 0168 { 0169 delete d; 0170 } 0171 0172 bool KGraphViewerPart::openFile() 0173 { 0174 qCDebug(KGRAPHVIEWERLIB_LOG) << " " << localFilePath(); 0175 // d->m_widget->loadedDot( localFilePath() ); 0176 switch (d->m_layoutMethod) { 0177 case ExternalProgram: 0178 if (!d->m_widget->loadDot(localFilePath())) 0179 return false; 0180 break; 0181 case InternalLibrary: 0182 // kpart expects loading to be done sync in this method 0183 if (!d->m_widget->loadLibrarySync(localFilePath())) 0184 return false; 0185 break; 0186 default: 0187 qCWarning(KGRAPHVIEWERLIB_LOG) << "Unsupported layout method " << d->m_layoutMethod; 0188 } 0189 0190 // deletes the existing file watcher because we have no way know here the name of the 0191 // previously watched file and thus we cannot use removeFile... :-( 0192 delete d->m_watch; 0193 d->m_watch = new KDirWatch(); 0194 0195 // qCDebug(KGRAPHVIEWERLIB_LOG) << "Watching file " << localFilePath(); 0196 d->m_watch->addFile(localFilePath()); 0197 connect(d->m_watch, &KDirWatch::dirty, d->m_widget, &DotGraphView::dirty); 0198 QString label = localFilePath().section('/', -1, -1); 0199 0200 d->m_widget->show(); 0201 return true; 0202 } 0203 0204 void KGraphViewerPart::slotHide(KParts::Part *part) 0205 { 0206 if (part == this) { 0207 d->m_widget->hideToolsWindows(); 0208 } 0209 } 0210 0211 void KGraphViewerPart::slotUpdate() 0212 { 0213 d->m_widget->slotUpdate(); 0214 } 0215 0216 void KGraphViewerPart::prepareAddNewElement(const QMap<QString, QString> &attribs) 0217 { 0218 d->m_widget->prepareAddNewElement(attribs); 0219 } 0220 0221 void KGraphViewerPart::slotSetGraphAttributes(const QMap<QString, QString> &attribs) 0222 { 0223 d->m_widget->graph()->setGraphAttributes(attribs); 0224 } 0225 0226 void KGraphViewerPart::slotAddNewNode(const QMap<QString, QString> &attribs) 0227 { 0228 d->m_widget->graph()->addNewNode(attribs); 0229 } 0230 0231 void KGraphViewerPart::slotAddNewSubgraph(const QMap<QString, QString> &attribs) 0232 { 0233 d->m_widget->graph()->addNewSubgraph(attribs); 0234 } 0235 0236 void KGraphViewerPart::slotAddNewNodeToSubgraph(const QMap<QString, QString> &attribs, const QString &subgraph) 0237 { 0238 d->m_widget->graph()->addNewNodeToSubgraph(attribs, subgraph); 0239 } 0240 0241 void KGraphViewerPart::slotAddExistingNodeToSubgraph(const QMap<QString, QString> &attribs, const QString &subgraph) 0242 { 0243 d->m_widget->graph()->addExistingNodeToSubgraph(attribs, subgraph); 0244 } 0245 0246 void KGraphViewerPart::slotMoveExistingNodeToMainGraph(const QMap<QString, QString> &attribs) 0247 { 0248 d->m_widget->graph()->moveExistingNodeToMainGraph(attribs); 0249 } 0250 0251 void KGraphViewerPart::slotAddNewEdge(const QString &src, const QString &tgt, const QMap<QString, QString> &attribs) 0252 { 0253 d->m_widget->graph()->addNewEdge(src, tgt, attribs); 0254 } 0255 0256 void KGraphViewerPart::prepareAddNewEdge(const QMap<QString, QString> &attribs) 0257 { 0258 d->m_widget->prepareAddNewEdge(attribs); 0259 } 0260 0261 void KGraphViewerPart::setReadOnly() 0262 { 0263 d->m_widget->setReadOnly(); 0264 } 0265 0266 void KGraphViewerPart::setReadWrite() 0267 { 0268 d->m_widget->setReadWrite(); 0269 } 0270 0271 void KGraphViewerPart::saveTo(const QString &fileName) 0272 { 0273 d->m_widget->graph()->saveTo(fileName); 0274 } 0275 0276 void KGraphViewerPart::slotRemoveNode(const QString &nodeName) 0277 { 0278 d->m_widget->graph()->removeNodeNamed(nodeName); 0279 } 0280 0281 void KGraphViewerPart::slotRemoveNodeFromSubgraph(const QString &nodeName, const QString &subgraphName) 0282 { 0283 d->m_widget->graph()->removeNodeFromSubgraph(nodeName, subgraphName); 0284 } 0285 0286 void KGraphViewerPart::slotRemoveSubgraph(const QString &subgraphName) 0287 { 0288 d->m_widget->graph()->removeSubgraphNamed(subgraphName); 0289 } 0290 0291 void KGraphViewerPart::slotSelectNode(const QString &nodeName) 0292 { 0293 d->m_widget->slotSelectNode(nodeName); 0294 } 0295 0296 void KGraphViewerPart::slotAddAttribute(const QString &) 0297 { 0298 qCDebug(KGRAPHVIEWERLIB_LOG) << "NOT IMPLEMENTED"; 0299 } 0300 0301 void KGraphViewerPart::slotSetAttribute(const QString &elementId, const QString &attributeName, const QString &attributeValue) 0302 { 0303 d->m_widget->graph()->setAttribute(elementId, attributeName, attributeValue); 0304 } 0305 0306 void KGraphViewerPart::slotRemoveAttribute(const QString &nodeName, const QString &attribName) 0307 { 0308 d->m_widget->graph()->removeAttribute(nodeName, attribName); 0309 } 0310 0311 void KGraphViewerPart::slotRemoveEdge(const QString &id) 0312 { 0313 d->m_widget->graph()->removeEdge(id); 0314 } 0315 0316 void KGraphViewerPart::slotRemoveElement(const QString &id) 0317 { 0318 d->m_widget->graph()->removeElement(id); 0319 } 0320 0321 void KGraphViewerPart::slotSetHighlighting(bool highlightingValue) 0322 { 0323 d->m_widget->setHighlighting(highlightingValue); 0324 } 0325 0326 void KGraphViewerPart::slotPrepareToSelect() 0327 { 0328 d->m_widget->prepareSelectElements(); 0329 } 0330 0331 void KGraphViewerPart::slotSetCursor(const QCursor &cursor) 0332 { 0333 d->m_widget->setCursor(cursor); 0334 } 0335 0336 void KGraphViewerPart::slotUnsetCursor() 0337 { 0338 d->m_widget->unsetCursor(); 0339 } 0340 0341 void KGraphViewerPart::slotSetLayoutMethod(LayoutMethod method) 0342 { 0343 setLayoutMethod(method); 0344 } 0345 0346 void KGraphViewerPart::setLayoutMethod(LayoutMethod method) 0347 { 0348 d->m_layoutMethod = method; 0349 } 0350 0351 void KGraphViewerPart::centerOnNode(const QString &nodeId) 0352 { 0353 d->m_widget->centerOnNode(nodeId); 0354 } 0355 0356 void KGraphViewerPart::selectNode(const QString &nodeId) 0357 { 0358 slotSelectNode(nodeId); 0359 } 0360 0361 void KGraphViewerPart::setLayoutCommand(const QString &command) 0362 { 0363 d->m_widget->setLayoutCommand(command); 0364 } 0365 0366 void KGraphViewerPart::setPannerPosition(KGraphViewerInterface::PannerPosition position) 0367 { 0368 d->m_widget->viewBevActivated(position); 0369 } 0370 0371 void KGraphViewerPart::setPannerEnabled(bool enabled) 0372 { 0373 d->m_widget->setPannerEnabled(enabled); 0374 } 0375 0376 void KGraphViewerPart::setZoomFactor(double factor) 0377 { 0378 d->m_widget->setZoomFactor(factor); 0379 } 0380 0381 void KGraphViewerPart::zoomBy(double factor) 0382 { 0383 d->m_widget->applyZoom(factor); 0384 } 0385 0386 void KGraphViewerPart::zoomIn() 0387 { 0388 d->m_widget->zoomIn(); 0389 } 0390 0391 void KGraphViewerPart::zoomOut() 0392 { 0393 d->m_widget->zoomOut(); 0394 } 0395 0396 void KGraphViewerPart::slotRenameNode(const QString &oldNodeName, const QString &newNodeName) 0397 { 0398 d->m_widget->graph()->renameNode(oldNodeName, newNodeName); 0399 } 0400 0401 } 0402 0403 #include "kgraphviewer_part.moc" 0404 0405 #include "moc_kgraphviewer_part.cpp"