File indexing completed on 2024-05-05 16:27:22
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 "kgrapheditor.h" 0020 #include "KGraphEditorElementTreeWidget.h" 0021 #include "KGraphEditorNodesTreeWidget.h" 0022 #include "kgrapheditorConfigDialog.h" 0023 #include "kgrapheditor_debug.h" 0024 #include "kgrapheditorsettings.h" 0025 #include "part/kgraphviewer_part.h" 0026 #include "ui_preferencesOpenInExistingWindow.h" 0027 #include "ui_preferencesParsing.h" 0028 #include "ui_preferencesReload.h" 0029 #include "ui_preferencesReopenPreviouslyOpenedFiles.h" 0030 0031 #include <KActionCollection> 0032 #include <KService> 0033 #include <QDebug> 0034 #include <QDockWidget> 0035 #include <QFileDialog> 0036 #include <QMessageBox> 0037 #include <QStandardPaths> 0038 #include <QStatusBar> 0039 #include <QTabWidget> 0040 #include <QTreeWidget> 0041 #include <QUrl> 0042 #include <QtDBus/QtDBus> 0043 #include <kconfig.h> 0044 #include <kconfigdialog.h> 0045 #include <kedittoolbar.h> 0046 #include <klocalizedstring.h> 0047 #include <kparts/partmanager.h> 0048 #include <krecentfilesaction.h> 0049 #include <kstandardaction.h> 0050 #include <ktoggleaction.h> 0051 #include <ktoolbar.h> 0052 0053 #include <iostream> 0054 0055 using namespace KGraphViewer; 0056 0057 KGraphEditor::KGraphEditor() 0058 : KParts::MainWindow() 0059 , m_rfa(nullptr) 0060 , m_currentPart(nullptr) 0061 { 0062 // set the shell's ui resource file 0063 setXMLFile("kgrapheditorui.rc"); 0064 0065 m_widget = new QTabWidget(this); 0066 m_widget->setTabsClosable(true); 0067 connect(m_widget, SIGNAL(tabCloseRequested(int)), this, SLOT(close(int))); 0068 connect(m_widget, SIGNAL(currentChanged(int)), this, SLOT(newTabSelectedSlot(int))); 0069 0070 setCentralWidget(m_widget); 0071 0072 QDockWidget *topLeftDockWidget = new QDockWidget(this); 0073 topLeftDockWidget->setObjectName(QStringLiteral("TopLeftDockWidget")); 0074 m_treeWidget = new KGraphEditorNodesTreeWidget(topLeftDockWidget); 0075 connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotItemChanged(QTreeWidgetItem *, int))); 0076 connect(m_treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slotItemClicked(QTreeWidgetItem *, int))); 0077 connect(m_treeWidget, SIGNAL(removeNode(QString)), this, SLOT(slotRemoveNode(QString))); 0078 connect(m_treeWidget, SIGNAL(addAttribute(QString)), this, SLOT(slotAddAttribute(QString))); 0079 connect(m_treeWidget, SIGNAL(removeAttribute(QString, QString)), this, SLOT(slotRemoveAttribute(QString, QString))); 0080 0081 // m_treeWidget->setItemDelegate(new VariantDelegate(m_treeWidget)); 0082 m_treeWidget->setColumnCount(2); 0083 topLeftDockWidget->setWidget(m_treeWidget); 0084 addDockWidget(Qt::LeftDockWidgetArea, topLeftDockWidget); 0085 0086 QDockWidget *bottomLeftDockWidget = new QDockWidget(this); 0087 bottomLeftDockWidget->setObjectName(QStringLiteral("BottomLeftDockWidget")); 0088 m_newElementAttributesWidget = new KGraphEditorElementTreeWidget(bottomLeftDockWidget); 0089 connect(m_newElementAttributesWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotNewElementItemChanged(QTreeWidgetItem *, int))); 0090 connect(m_newElementAttributesWidget, SIGNAL(addAttribute(QString)), this, SLOT(slotAddNewElementAttribute(QString))); 0091 connect(m_newElementAttributesWidget, SIGNAL(removeAttribute(QString)), this, SLOT(slotRemoveNewElementAttribute(QString))); 0092 m_newElementAttributesWidget->setColumnCount(2); 0093 bottomLeftDockWidget->setWidget(m_newElementAttributesWidget); 0094 addDockWidget(Qt::LeftDockWidgetArea, bottomLeftDockWidget); 0095 0096 if (QDBusConnection::sessionBus().registerService("org.kde.kgrapheditor")) { 0097 qCDebug(KGRAPHEDITOR_LOG) << "Service Registered successfully"; 0098 QDBusConnection::sessionBus().registerObject("/", this, QDBusConnection::ExportAllSlots); 0099 0100 } else { 0101 qCDebug(KGRAPHEDITOR_LOG) << "Failed to register service..."; 0102 } 0103 0104 // Create a KParts part manager, to handle part activation/deactivation 0105 m_manager = new KParts::PartManager(this); 0106 0107 // When the manager says the active part changes, the window updates (recreates) the GUI 0108 connect(m_manager, SIGNAL(activePartChanged(KParts::Part *)), this, SLOT(createGUI(KParts::Part *))); 0109 0110 setupGUI(ToolBar | Keys | StatusBar | Save); 0111 0112 // then, setup our actions 0113 setupActions(); 0114 0115 // this routine will find and load our Part. it finds the Part by 0116 // name which is a bad idea usually.. but it's alright in this 0117 // case since our Part is made for this Shell 0118 0119 // Creates the GUI with a null part to make appear the main app menus and tools 0120 createGUI(0); 0121 } 0122 0123 KGraphEditor::~KGraphEditor() 0124 { 0125 } 0126 0127 void KGraphEditor::reloadPreviousFiles() 0128 { 0129 QStringList previouslyOpenedFiles = KGraphEditorSettings::previouslyOpenedFiles(); 0130 if ((previouslyOpenedFiles.empty() == false) && (QMessageBox::question(this, i18n("Session Restore"), i18n("Do you want to reload files from previous session?")) == QMessageBox::Yes)) { 0131 QStringList::const_iterator it, it_end; 0132 it = previouslyOpenedFiles.constBegin(); 0133 it_end = previouslyOpenedFiles.constEnd(); 0134 for (; it != it_end; it++) { 0135 openUrl(*it); 0136 } 0137 } 0138 } 0139 0140 KParts::ReadOnlyPart *KGraphEditor::slotNewGraph() 0141 { 0142 KPluginFactory *factory = KPluginFactory::loadFactory(KPluginMetaData("kgraphviewerpart")).plugin; 0143 if (!factory) { 0144 // if we couldn't find our Part, we exit since the Shell by 0145 // itself can't do anything useful 0146 QMessageBox::critical(this, i18n("Unable to start"), i18n("Could not find the KGraphViewer part.")); 0147 qApp->quit(); 0148 // we return here, cause kapp->quit() only means "exit the 0149 // next time we enter the event loop... 0150 return nullptr; 0151 } 0152 KParts::ReadOnlyPart *part = factory->create<KParts::ReadOnlyPart>(this); 0153 KGraphViewerInterface *view = qobject_cast<KGraphViewerInterface *>(part); 0154 if (!view) { 0155 // This should not happen 0156 qCWarning(KGRAPHEDITOR_LOG) << "Failed to get KPart" << Qt::endl; 0157 return nullptr; 0158 } 0159 view->setReadWrite(); 0160 0161 QWidget *w = part->widget(); 0162 0163 m_tabsPartsMap[w] = part; 0164 m_tabsFilesMap[w] = ""; 0165 connect(this, SIGNAL(hide(KParts::Part *)), part, SLOT(slotHide(KParts::Part *))); 0166 0167 m_manager->addPart(part, true); 0168 0169 m_widget->addTab(w, QIcon::fromTheme("kgraphviewer"), ""); 0170 m_widget->setCurrentWidget(w); 0171 m_closeAction->setEnabled(true); 0172 return part; 0173 } 0174 0175 void KGraphEditor::openUrl(const QUrl &url) 0176 { 0177 qCDebug(KGRAPHEDITOR_LOG) << url; 0178 KParts::ReadOnlyPart *part = slotNewGraph(); 0179 0180 // (KGraphEditorSettings::parsingMode() == "external") 0181 // ?kgv->setLayoutMethod(KGraphViewerInterface::ExternalProgram) 0182 // :kgv->setLayoutMethod(KGraphViewerInterface::InternalLibrary); 0183 0184 QString label = url.path().section('/', -1, -1); 0185 // @TODO set label 0186 m_widget->setTabText(m_widget->currentIndex(), label); 0187 m_tabsFilesMap[m_widget->currentWidget()] = url.path(); 0188 part->openUrl(url); 0189 0190 if (m_rfa) { 0191 m_rfa->addUrl(url); 0192 } 0193 0194 m_openedFiles.push_back(url.path()); 0195 } 0196 0197 void KGraphEditor::fileOpen() 0198 { 0199 // this slot is called whenever the File->Open menu is selected, 0200 // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar 0201 // button is clicked 0202 QFileDialog fileDialog(this); 0203 fileDialog.setMimeTypeFilters(QStringList(QStringLiteral("text/vnd.graphviz"))); 0204 fileDialog.setAcceptMode(QFileDialog::AcceptOpen); 0205 fileDialog.setFileMode(QFileDialog::ExistingFiles); 0206 if (fileDialog.exec() != QFileDialog::Accepted) { 0207 return; 0208 } 0209 0210 for (const QUrl &url : fileDialog.selectedUrls()) { 0211 openUrl(url); 0212 } 0213 } 0214 0215 void KGraphEditor::setupActions() 0216 { 0217 // create our actions 0218 0219 actionCollection()->addAction(KStandardAction::New, "file_new", this, SLOT(fileNew())); 0220 actionCollection()->addAction(KStandardAction::Open, "file_open", this, SLOT(fileOpen())); 0221 m_rfa = (KRecentFilesAction *)actionCollection()->addAction(KStandardAction::OpenRecent, "file_open_recent", this, SLOT(slotURLSelected(QUrl))); 0222 m_rfa->loadEntries(KConfigGroup(KSharedConfig::openConfig(), "kgrapheditor")); 0223 actionCollection()->addAction(KStandardAction::Save, "file_save", this, SLOT(fileSave())); 0224 actionCollection()->addAction(KStandardAction::SaveAs, "file_save_as", this, SLOT(fileSaveAs())); 0225 0226 m_closeAction = actionCollection()->addAction(KStandardAction::Close, "file_close", this, SLOT(close())); 0227 m_closeAction->setWhatsThis(i18n("Closes the current file")); 0228 m_closeAction->setEnabled(false); 0229 0230 actionCollection()->addAction(KStandardAction::Quit, "file_quit", qApp, SLOT(quit())); 0231 0232 m_statusbarAction = KStandardAction::showStatusbar(this, SLOT(optionsShowStatusbar()), this); 0233 0234 actionCollection()->addAction(KStandardAction::ConfigureToolbars, "options_configure_toolbars", this, SLOT(optionsConfigureToolbars())); 0235 actionCollection()->addAction(KStandardAction::Preferences, "options_configure", this, SLOT(optionsConfigure())); 0236 0237 QAction *edit_new_vertex = actionCollection()->addAction("edit_new_vertex"); 0238 edit_new_vertex->setText(i18n("Create a New Vertex")); 0239 edit_new_vertex->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kgraphviewerpart/pics/kgraphviewer-newnode.png"))); 0240 connect(edit_new_vertex, SIGNAL(triggered(bool)), this, SLOT(slotEditNewVertex())); 0241 0242 QAction *edit_new_edge = actionCollection()->addAction("edit_new_edge"); 0243 edit_new_edge->setText(i18n("Create a New Edge")); 0244 edit_new_edge->setIcon(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kgraphviewerpart/pics/kgraphviewer-newedge.png"))); 0245 connect(edit_new_edge, SIGNAL(triggered(bool)), this, SLOT(slotEditNewEdge())); 0246 } 0247 0248 void KGraphEditor::closeEvent(QCloseEvent *event) 0249 { 0250 KGraphEditorSettings::setPreviouslyOpenedFiles(m_openedFiles); 0251 m_rfa->saveEntries(KConfigGroup(KSharedConfig::openConfig(), "kgrapheditor")); 0252 0253 KGraphEditorSettings::self()->save(); 0254 KXmlGuiWindow::closeEvent(event); 0255 } 0256 0257 void KGraphEditor::fileNew() 0258 { 0259 // this slot is called whenever the File->New menu is selected, 0260 // the New shortcut is pressed (usually CTRL+N) or the New toolbar 0261 // button is clicked 0262 0263 slotNewGraph(); 0264 } 0265 0266 void KGraphEditor::optionsShowToolbar() 0267 { 0268 // this is all very cut and paste code for showing/hiding the 0269 // toolbar 0270 if (m_toolbarAction->isChecked()) 0271 toolBar()->show(); 0272 else 0273 toolBar()->hide(); 0274 } 0275 0276 void KGraphEditor::optionsShowStatusbar() 0277 { 0278 // this is all very cut and paste code for showing/hiding the 0279 // statusbar 0280 if (m_statusbarAction->isChecked()) 0281 statusBar()->show(); 0282 else 0283 statusBar()->hide(); 0284 } 0285 0286 void KGraphEditor::optionsConfigureToolbars() 0287 { 0288 KConfigGroup conf(KConfigGroup(KSharedConfig::openConfig(), "kgrapheditor")); 0289 saveMainWindowSettings(conf); 0290 0291 // use the standard toolbar editor 0292 KEditToolBar dlg(factory()); 0293 connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(applyNewToolbarConfig())); 0294 dlg.exec(); 0295 } 0296 0297 void KGraphEditor::optionsConfigure() 0298 { 0299 // An instance of your dialog could be already created and could be cached, 0300 // in which case you want to display the cached dialog instead of creating 0301 // another one 0302 if (KgeConfigurationDialog::showDialog("settings")) 0303 return; 0304 0305 // KConfigDialog didn't find an instance of this dialog, so lets create it : 0306 KgeConfigurationDialog *dialog = new KgeConfigurationDialog(this, "settings", KGraphEditorSettings::self()); 0307 0308 Ui::KGraphViewerPreferencesParsingWidget *parsingWidget = dialog->m_parsingWidget; 0309 qCDebug(KGRAPHEDITOR_LOG) << KGraphEditorSettings::parsingMode(); 0310 if (KGraphEditorSettings::parsingMode() == "external") { 0311 parsingWidget->external->setChecked(true); 0312 } else if (KGraphEditorSettings::parsingMode() == "internal") { 0313 parsingWidget->internal->setChecked(true); 0314 } 0315 connect((QObject *)parsingWidget->external, SIGNAL(toggled(bool)), this, SLOT(slotParsingModeExternalToggled(bool))); 0316 connect((QObject *)parsingWidget->internal, SIGNAL(toggled(bool)), this, SLOT(slotParsingModeInternalToggled(bool))); 0317 0318 /* KGraphViewerPreferencesReloadWidget* reloadWidget = 0319 new KGraphViewerPreferencesReloadWidget( 0, "KGraphViewer Settings" ); 0320 if (KGraphEditorSettings::reloadOnChangeMode() == "yes") 0321 { 0322 reloadWidget->reloadOnChangeMode->setButton(0); 0323 } 0324 else if (KGraphEditorSettings::reloadOnChangeMode() == "no") 0325 { 0326 reloadWidget->reloadOnChangeMode->setButton(1); 0327 } 0328 else if (KGraphEditorSettings::reloadOnChangeMode() == "ask") 0329 { 0330 reloadWidget->reloadOnChangeMode->setButton(2); 0331 } 0332 0333 connect((QObject*)reloadWidget->reloadOnChangeMode, SIGNAL(clicked(int)), this, SLOT(reloadOnChangeMode_pressed(int)) ); 0334 0335 dialog->addPage( reloadWidget, i18n("Reloading"), "kgraphreloadoptions", i18n("Reloading"), true); 0336 0337 KGraphViewerPreferencesOpenInExistingWindowWidget* openingWidget = 0338 new KGraphViewerPreferencesOpenInExistingWindowWidget( 0, "KGraphViewer Settings" ); 0339 if (KGraphEditorSettings::openInExistingWindowMode() == "yes") 0340 { 0341 openingWidget->openInExistingWindowMode->setButton(0); 0342 } 0343 else if (KGraphEditorSettings::openInExistingWindowMode() == "no") 0344 { 0345 openingWidget->openInExistingWindowMode->setButton(1); 0346 } 0347 else if (KGraphEditorSettings::openInExistingWindowMode() == "ask") 0348 { 0349 openingWidget->openInExistingWindowMode->setButton(2); 0350 } 0351 0352 connect((QObject*)openingWidget->openInExistingWindowMode, SIGNAL(clicked(int)), this, SLOT(openInExistingWindowMode_pressed(int)) ); 0353 0354 dialog->addPage( openingWidget, i18n("Opening"), "kgraphopeningoptions", i18n("Opening"), true); 0355 0356 KGraphViewerPreferencesReopenPreviouslyOpenedFilesWidget* reopeningWidget = 0357 new KGraphViewerPreferencesReopenPreviouslyOpenedFilesWidget( 0, "KGraphViewer Settings" ); 0358 if (KGraphEditorSettings::reopenPreviouslyOpenedFilesMode() == "yes") 0359 { 0360 reopeningWidget->reopenPreviouslyOpenedFilesMode->setButton(0); 0361 } 0362 else if (KGraphEditorSettings::reopenPreviouslyOpenedFilesMode() == "no") 0363 { 0364 reopeningWidget->reopenPreviouslyOpenedFilesMode->setButton(1); 0365 } 0366 else if (KGraphEditorSettings::reopenPreviouslyOpenedFilesMode() == "ask") 0367 { 0368 reopeningWidget->reopenPreviouslyOpenedFilesMode->setButton(2); 0369 } 0370 0371 connect((QObject*)reopeningWidget->reopenPreviouslyOpenedFilesMode, SIGNAL(clicked(int)), this, SLOT(reopenPreviouslyOpenedFilesMode_pressed(int)) ); 0372 0373 dialog->addPage( reopeningWidget, i18n("Session Management"), "kgraphreopeningoptions", i18n("Session Management"), true); 0374 */ 0375 // connect(dialog, SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); 0376 0377 dialog->show(); 0378 } 0379 0380 void KGraphEditor::applyNewToolbarConfig() 0381 { 0382 applyMainWindowSettings(KConfigGroup(KSharedConfig::openConfig(), "kgrapheditor")); 0383 } 0384 0385 // void KGraphViewer::reloadOnChangeMode_pressed(int value) 0386 // { 0387 // qCDebug(KGRAPHEDITOR_LOG) << "reloadOnChangeMode_pressed " << value; 0388 // switch (value) 0389 // { 0390 // case 0: 0391 // KGraphEditorSettings::setReloadOnChangeMode("yes"); 0392 // break; 0393 // case 1: 0394 // KGraphEditorSettings::setReloadOnChangeMode("no"); 0395 // break; 0396 // case 2: 0397 // KGraphEditorSettings::setReloadOnChangeMode("ask"); 0398 // break; 0399 // default: 0400 // qCWarning(KGRAPHEDITOR_LOG) << "Invalid reload on change mode value: " << value; 0401 // return; 0402 // } 0403 // qCDebug(KGRAPHEDITOR_LOG) << "emiting"; 0404 // emit(settingsChanged()); 0405 // KGraphEditorSettings::save(); 0406 // } 0407 // 0408 // void KGraphViewer::openInExistingWindowMode_pressed(int value) 0409 // { 0410 // std::cerr << "openInExistingWindowMode_pressed " << value << std::endl; 0411 // switch (value) 0412 // { 0413 // case 0: 0414 // KGraphEditorSettings::setOpenInExistingWindowMode("yes"); 0415 // break; 0416 // case 1: 0417 // KGraphEditorSettings::setOpenInExistingWindowMode("no"); 0418 // break; 0419 // case 2: 0420 // KGraphEditorSettings::setOpenInExistingWindowMode("ask"); 0421 // break; 0422 // default: 0423 // qCWarning(KGRAPHEDITOR_LOG) << "Invalid OpenInExistingWindow value: " << value << endl; 0424 // return; 0425 // } 0426 // 0427 // std::cerr << "emiting" << std::endl; 0428 // emit(settingsChanged()); 0429 // KGraphEditorSettings::save(); 0430 // } 0431 // 0432 // void KGraphViewer::reopenPreviouslyOpenedFilesMode_pressed(int value) 0433 // { 0434 // std::cerr << "reopenPreviouslyOpenedFilesMode_pressed " << value << std::endl; 0435 // switch (value) 0436 // { 0437 // case 0: 0438 // KGraphEditorSettings::setReopenPreviouslyOpenedFilesMode("yes"); 0439 // break; 0440 // case 1: 0441 // KGraphEditorSettings::setReopenPreviouslyOpenedFilesMode("no"); 0442 // break; 0443 // case 2: 0444 // KGraphEditorSettings::setReopenPreviouslyOpenedFilesMode("ask"); 0445 // break; 0446 // default: 0447 // qCWarning(KGRAPHEDITOR_LOG) << "Invalid ReopenPreviouslyOpenedFilesMode value: " << value << endl; 0448 // return; 0449 // } 0450 // 0451 // std::cerr << "emiting" << std::endl; 0452 // emit(settingsChanged()); 0453 // KGraphEditorSettings::save(); 0454 // } 0455 0456 void KGraphEditor::slotURLSelected(const QUrl &url) 0457 { 0458 openUrl(url); 0459 } 0460 0461 void KGraphEditor::close(int index) 0462 { 0463 QWidget *tab = m_widget->widget(index); 0464 m_openedFiles.removeAll(m_tabsFilesMap[tab]); 0465 m_widget->removeTab(index); 0466 tab->hide(); 0467 KParts::ReadOnlyPart *part = m_tabsPartsMap[tab]; 0468 m_manager->removePart(part); 0469 m_tabsPartsMap.remove(tab); 0470 m_tabsFilesMap.remove(tab); 0471 delete part; 0472 part = nullptr; 0473 /* delete tab; 0474 tab = nullptr;*/ 0475 m_closeAction->setEnabled(m_widget->count() > 0); 0476 } 0477 0478 void KGraphEditor::close() 0479 { 0480 int currentPage = m_widget->currentIndex(); 0481 if (currentPage != -1) { 0482 close(currentPage); 0483 } 0484 } 0485 0486 void KGraphEditor::fileSave() 0487 { 0488 QWidget *currentPage = m_widget->currentWidget(); 0489 if (currentPage) { 0490 emit(saveTo(QUrl(m_tabsFilesMap[currentPage]).path())); 0491 } 0492 } 0493 0494 void KGraphEditor::fileSaveAs() 0495 { 0496 QWidget *currentPage = m_widget->currentWidget(); 0497 if (currentPage) { 0498 QFileDialog fileDialog(currentPage, i18n("Save current graph")); 0499 fileDialog.setMimeTypeFilters(QStringList(QStringLiteral("text/vnd.graphviz"))); 0500 fileDialog.setAcceptMode(QFileDialog::AcceptSave); 0501 if (fileDialog.exec() != QFileDialog::Accepted) { 0502 return; 0503 } 0504 const QString fileName = fileDialog.selectedFiles().at(0); 0505 if (fileName.isEmpty()) { 0506 return; 0507 } 0508 0509 m_tabsFilesMap[currentPage] = fileName; 0510 emit(saveTo(fileName)); 0511 } 0512 } 0513 0514 void KGraphEditor::newTabSelectedSlot(int index) 0515 { 0516 // qCDebug(KGRAPHEDITOR_LOG) << tab; 0517 emit(hide((KParts::Part *)(m_manager->activePart()))); 0518 QWidget *tab = m_widget->widget(index); 0519 if (tab) { 0520 slotSetActiveGraph(m_tabsPartsMap[tab]); 0521 m_manager->setActivePart(m_tabsPartsMap[tab]); 0522 } 0523 } 0524 0525 void KGraphEditor::slotSetActiveGraph(KParts::ReadOnlyPart *part) 0526 { 0527 if (m_currentPart) { 0528 disconnect(this, SIGNAL(prepareAddNewElement(QMap<QString, QString>)), m_currentPart, SLOT(prepareAddNewElement(QMap<QString, QString>))); 0529 disconnect(this, SIGNAL(prepareAddNewEdge(QMap<QString, QString>)), m_currentPart, SLOT(prepareAddNewEdge(QMap<QString, QString>))); 0530 disconnect(this, SIGNAL(saveTo(QString)), m_currentPart, SLOT(saveTo(QString))); 0531 disconnect(this, SIGNAL(removeNode(QString)), m_currentPart, SLOT(slotRemoveNode(QString))); 0532 disconnect(this, SIGNAL(addAttribute(QString)), m_currentPart, SLOT(slotAddAttribute(QString))); 0533 disconnect(this, SIGNAL(removeAttribute(QString, QString)), m_currentPart, SLOT(slotRemoveAttribute(QString, QString))); 0534 disconnect(this, SIGNAL(update()), m_currentPart, SLOT(slotUpdate())); 0535 disconnect(this, SIGNAL(selectNode(QString)), m_currentPart, SLOT(slotSelectNode(QString))); 0536 disconnect(this, SIGNAL(saddNewEdge(QString, QString, QMap<QString, QString>)), m_currentPart, SLOT(slotAddNewEdge(QString, QString, QMap<QString, QString>))); 0537 disconnect(this, SIGNAL(renameNode(QString, QString)), m_currentPart, SLOT(slotRenameNode(QString, QString))); 0538 disconnect(this, SIGNAL(setAttribute(QString, QString, QString)), m_currentPart, SLOT(slotSetAttribute(QString, QString, QString))); 0539 } 0540 m_currentPart = part; 0541 m_treeWidget->clear(); 0542 if (m_currentPart == nullptr) { 0543 return; 0544 } 0545 connect(this, SIGNAL(prepareAddNewElement(QMap<QString, QString>)), part, SLOT(prepareAddNewElement(QMap<QString, QString>))); 0546 connect(this, SIGNAL(prepareAddNewEdge(QMap<QString, QString>)), part, SLOT(prepareAddNewEdge(QMap<QString, QString>))); 0547 connect(this, SIGNAL(saveTo(QString)), part, SLOT(saveTo(QString))); 0548 connect(this, SIGNAL(removeNode(QString)), part, SLOT(slotRemoveNode(QString))); 0549 connect(this, SIGNAL(addAttribute(QString)), part, SLOT(slotAddAttribute(QString))); 0550 connect(this, SIGNAL(removeAttribute(QString, QString)), part, SLOT(slotRemoveAttribute(QString, QString))); 0551 connect(this, SIGNAL(update()), part, SLOT(slotUpdate())); 0552 connect(this, SIGNAL(selectNode(QString)), part, SLOT(slotSelectNode(QString))); 0553 connect(this, SIGNAL(removeElement(QString)), m_currentPart, SLOT(slotRemoveElement(QString))); 0554 connect(this, SIGNAL(saddNewEdge(QString, QString, QMap<QString, QString>)), m_currentPart, SLOT(slotAddNewEdge(QString, QString, QMap<QString, QString>))); 0555 connect(this, SIGNAL(renameNode(QString, QString)), m_currentPart, SLOT(slotRenameNode(QString, QString))); 0556 connect(this, SIGNAL(setAttribute(QString, QString, QString)), m_currentPart, SLOT(slotSetAttribute(QString, QString, QString))); 0557 0558 QList<QString> nodesIds; // TODO = m_currentPart->nodesIds(); 0559 QList<QTreeWidgetItem *> items; 0560 for (const QString &nodeId : nodesIds) { 0561 qCDebug(KGRAPHEDITOR_LOG) << "new item " << nodeId; 0562 QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(nodeId)); 0563 item->setFlags(item->flags() | Qt::ItemIsEditable); 0564 QMap<QString, QString> attributes; // TODO = m_currentPart->nodeAtributes(nodeId); 0565 for (const QString &attrib : attributes.keys()) { 0566 if (attrib != "_draw_" && attrib != "_ldraw_") { 0567 QStringList list(attrib); 0568 list << attributes[attrib]; 0569 QTreeWidgetItem *child = new QTreeWidgetItem((QTreeWidget *)nullptr, list); 0570 child->setFlags(child->flags() | Qt::ItemIsEditable); 0571 item->addChild(child); 0572 } 0573 } 0574 items.append(item); 0575 } 0576 qCDebug(KGRAPHEDITOR_LOG) << "inserting"; 0577 m_treeWidget->insertTopLevelItems(0, items); 0578 0579 connect(m_currentPart, SIGNAL(graphLoaded()), this, SLOT(slotGraphLoaded())); 0580 0581 connect(m_currentPart, SIGNAL(newNodeAdded(QString)), this, SLOT(slotNewNodeAdded(QString))); 0582 0583 connect(m_currentPart, SIGNAL(newEdgeAdded(QString, QString)), this, SLOT(slotNewEdgeAdded(QString, QString))); 0584 0585 connect(m_currentPart, SIGNAL(removeElement(QString)), this, SLOT(slotRemoveElement(QString))); 0586 0587 connect(m_currentPart, SIGNAL(selectionIs(QList<QString>, QPoint)), this, SLOT(slotSelectionIs(QList<QString>, QPoint))); 0588 0589 connect(m_currentPart, SIGNAL(newEdgeFinished(QString, QString, QMap<QString, QString>)), this, SLOT(slotNewEdgeFinished(QString, QString, QMap<QString, QString>))); 0590 0591 connect(m_currentPart, SIGNAL(hoverEnter(QString)), this, SLOT(slotHoverEnter(QString))); 0592 0593 connect(m_currentPart, SIGNAL(hoverLeave(QString)), this, SLOT(slotHoverLeave(QString))); 0594 } 0595 0596 void KGraphEditor::slotNewNodeAdded(const QString &id) 0597 { 0598 qCDebug(KGRAPHEDITOR_LOG) << id; 0599 update(); 0600 } 0601 0602 void KGraphEditor::slotNewEdgeAdded(const QString &ids, const QString &idt) 0603 { 0604 qCDebug(KGRAPHEDITOR_LOG) << ids << idt; 0605 update(); 0606 } 0607 0608 void KGraphEditor::slotNewEdgeFinished(const QString &srcId, const QString &tgtId, const QMap<QString, QString> &attribs) 0609 { 0610 qCDebug(KGRAPHEDITOR_LOG) << srcId << tgtId << attribs; 0611 emit saddNewEdge(srcId, tgtId, attribs); 0612 update(); 0613 } 0614 0615 void KGraphEditor::slotGraphLoaded() 0616 { 0617 qCDebug(KGRAPHEDITOR_LOG); 0618 disconnect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotItemChanged(QTreeWidgetItem *, int))); 0619 disconnect(m_treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slotItemClicked(QTreeWidgetItem *, int))); 0620 0621 QList<QString> nodesIds; // TODO = m_currentPart->nodesIds(); 0622 QList<QTreeWidgetItem *> items; 0623 for (const QString &nodeId : nodesIds) { 0624 qCDebug(KGRAPHEDITOR_LOG) << "item " << nodeId; 0625 QTreeWidgetItem *item; 0626 QList<QTreeWidgetItem *> existingItems = m_treeWidget->findItems(nodeId, Qt::MatchRecursive | Qt::MatchExactly); 0627 if (existingItems.isEmpty()) { 0628 item = new QTreeWidgetItem((QTreeWidget *)nullptr, QStringList(nodeId)); 0629 items.append(item); 0630 } else { 0631 item = existingItems[0]; 0632 } 0633 item->setFlags(item->flags() | Qt::ItemIsEditable); 0634 QMap<QString, QString> attributes; // TODO = m_currentPart->nodeAtributes(nodeId); 0635 QList<QString> keys = attributes.keys(); 0636 for (int i = 0; i < item->childCount(); i++) { 0637 if (keys.contains(item->child(i)->text(0))) { 0638 item->child(i)->setText(1, attributes[item->child(i)->text(0)]); 0639 keys.removeAll(item->child(i)->text(0)); 0640 } 0641 } 0642 for (const QString &attrib : keys) { 0643 if (attrib != "_draw_" && attrib != "_ldraw_") { 0644 QStringList list(attrib); 0645 list << attributes[attrib]; 0646 QTreeWidgetItem *child = new QTreeWidgetItem((QTreeWidget *)nullptr, list); 0647 child->setFlags(child->flags() | Qt::ItemIsEditable); 0648 item->addChild(child); 0649 } 0650 } 0651 } 0652 qCDebug(KGRAPHEDITOR_LOG) << "inserting"; 0653 m_treeWidget->insertTopLevelItems(0, items); 0654 connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotItemChanged(QTreeWidgetItem *, int))); 0655 connect(m_treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slotItemClicked(QTreeWidgetItem *, int))); 0656 } 0657 0658 void KGraphEditor::slotItemChanged(QTreeWidgetItem *item, int column) 0659 { 0660 qCDebug(KGRAPHEDITOR_LOG); 0661 /* values column */ 0662 if (column == 0) { 0663 QString oldNodeName = m_currentTreeWidgetItemText; 0664 QString newNodeName = item->text(0); 0665 emit(renameNode(oldNodeName, newNodeName)); 0666 } else if (column == 1) { 0667 /* there is a parent ; it is an attribute line */ 0668 if (item->parent()) { 0669 QString nodeLabel = item->parent()->text(0); 0670 QString attributeName = item->text(0); 0671 QString attributeValue = item->text(1); 0672 emit(setAttribute(nodeLabel, attributeName, attributeValue)); 0673 } 0674 } 0675 emit update(); 0676 } 0677 0678 void KGraphEditor::slotItemClicked(QTreeWidgetItem *item, int column) 0679 { 0680 qCDebug(KGRAPHEDITOR_LOG) << column; 0681 m_currentTreeWidgetItemText = item->text(0); 0682 0683 QString nodeName = item->parent() ? item->parent()->text(0) : item->text(0); 0684 emit selectNode(nodeName); 0685 } 0686 0687 void KGraphEditor::slotEditNewVertex() 0688 { 0689 if (m_currentPart == nullptr) { 0690 qCDebug(KGRAPHEDITOR_LOG) << "new vertex: no part selected"; 0691 return; 0692 } 0693 qCDebug(KGRAPHEDITOR_LOG) << "new vertex"; 0694 emit(prepareAddNewElement(m_newElementAttributes)); 0695 } 0696 0697 void KGraphEditor::slotEditNewEdge() 0698 { 0699 if (m_currentPart == nullptr) { 0700 qCDebug(KGRAPHEDITOR_LOG) << "new edge: no part selected"; 0701 return; 0702 } 0703 qCDebug(KGRAPHEDITOR_LOG) << "new edge"; 0704 emit(prepareAddNewEdge(m_newElementAttributes)); 0705 } 0706 0707 void KGraphEditor::slotRemoveNode(const QString &nodeName) 0708 { 0709 emit removeNode(nodeName); 0710 emit update(); 0711 } 0712 0713 void KGraphEditor::slotAddAttribute(const QString &attribName) 0714 { 0715 emit addAttribute(attribName); 0716 emit update(); 0717 } 0718 0719 void KGraphEditor::slotRemoveAttribute(const QString &nodeName, const QString &attribName) 0720 { 0721 emit removeAttribute(nodeName, attribName); 0722 emit update(); 0723 } 0724 0725 void KGraphEditor::slotNewElementItemChanged(QTreeWidgetItem *item, int column) 0726 { 0727 qCDebug(KGRAPHEDITOR_LOG); 0728 if (column == 0) { 0729 qCWarning(KGRAPHEDITOR_LOG) << "Item id change not handled"; 0730 return; 0731 } else if (column == 1) { 0732 m_newElementAttributes[item->text(0)] = item->text(1); 0733 } else { 0734 qCWarning(KGRAPHEDITOR_LOG) << "Unknown column" << column; 0735 return; 0736 } 0737 } 0738 0739 void KGraphEditor::slotAddNewElementAttribute(const QString &attrib) 0740 { 0741 m_newElementAttributes[attrib] = QString(); 0742 } 0743 0744 void KGraphEditor::slotRemoveNewElementAttribute(const QString &attrib) 0745 { 0746 m_newElementAttributes.remove(attrib); 0747 } 0748 0749 void KGraphEditor::slotRemoveElement(const QString &id) 0750 { 0751 qCDebug(KGRAPHEDITOR_LOG) << id; 0752 m_treeWidget->slotRemoveElement(id); 0753 emit(removeElement(id)); 0754 } 0755 0756 void KGraphEditor::slotSelectionIs(const QList<QString> &elements, const QPoint &p) 0757 { 0758 qCDebug(KGRAPHEDITOR_LOG); 0759 Q_UNUSED(p); 0760 QList<QTreeWidgetItem *> items = m_treeWidget->selectedItems(); 0761 for (QTreeWidgetItem *item : items) { 0762 item->setSelected(false); 0763 } 0764 for (const QString &elementName : elements) { 0765 QList<QTreeWidgetItem *> items = m_treeWidget->findItems(elementName, Qt::MatchExactly, 0); 0766 for (QTreeWidgetItem *item : items) { 0767 item->setSelected(true); 0768 } 0769 } 0770 } 0771 0772 void KGraphEditor::slotParsingModeExternalToggled(bool value) 0773 { 0774 if (value) { 0775 KGraphEditorSettings::setParsingMode("external"); 0776 } 0777 // qCDebug(KGRAPHEDITOR_LOG) << "emiting"; 0778 // emit(settingsChanged()); 0779 KGraphEditorSettings::self()->save(); 0780 } 0781 0782 void KGraphEditor::slotParsingModeInternalToggled(bool value) 0783 { 0784 if (value) { 0785 KGraphEditorSettings::setParsingMode("internal"); 0786 } 0787 // qCDebug(KGRAPHEDITOR_LOG) << "emiting"; 0788 // emit(settingsChanged()); 0789 KGraphEditorSettings::self()->save(); 0790 } 0791 0792 void KGraphEditor::slotHoverEnter(const QString &id) 0793 { 0794 qCDebug(KGRAPHEDITOR_LOG) << id; 0795 statusBar()->showMessage(id); 0796 } 0797 0798 void KGraphEditor::slotHoverLeave(const QString &id) 0799 { 0800 qCDebug(KGRAPHEDITOR_LOG) << id; 0801 statusBar()->showMessage(""); 0802 } 0803 0804 #include "moc_kgrapheditor.cpp"