25 QString::fromUtf8(errMsg));
30 for (
int i = 0; i < count; i++)
36 const QStringList &more, std::string_view prefer) {
39 std::optional<int> idx;
42 for (
int id = 0;
id < count;
id++) {
43 cb.addItem(QString::fromUtf8(lp[
id]));
44 if (!idx.has_value() && prefer == lp[
id])
53 cb.setCurrentIndex(*idx);
55 return idx.value_or(0);
58void CMainWindow::createConsole() {
59 QDockWidget *dock =
new QDockWidget(tr(
"Output Console"),
nullptr);
60 QTextEdit *textEdit =
new QTextEdit(dock);
62 dock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
63 addDockWidget(Qt::BottomDockWidgetArea, dock);
64 QVBoxLayout *vL =
new QVBoxLayout();
66 textEdit->setObjectName(QStringLiteral(
"textEdit"));
70 vL->addWidget(textEdit);
71 vL->setContentsMargins(1, 1, 1, 1);
73 QFrame *fr =
new QFrame(dock);
76 QPushButton *logNewBtn =
77 new QPushButton(QIcon(QStringLiteral(
":/images/new.png")), {}, fr);
78 QPushButton *logSaveBtn =
79 new QPushButton(QIcon(QStringLiteral(
":/images/save.png")), {}, fr);
80 QHBoxLayout *consoleLayout =
new QHBoxLayout();
81 consoleLayout->addWidget(logNewBtn);
82 connect(logNewBtn, &QPushButton::clicked,
this, &CMainWindow::slotNewLog);
83 connect(logSaveBtn, &QPushButton::clicked,
this, &CMainWindow::slotSaveLog);
84 consoleLayout->addWidget(logSaveBtn);
85 consoleLayout->addStretch();
87 consoleLayout->setContentsMargins(1, 1, 1, 1);
89 fr->setLayout(consoleLayout);
91 QFrame *mainFrame =
new QFrame(dock);
92 mainFrame->setLayout(vL);
94 dock->setWidget(mainFrame);
97static const QStringList
xtra = {QStringLiteral(
"NONE")};
101 QWidget *centralwidget =
new QWidget(
this);
102 centralwidget->setObjectName(QStringLiteral(
"centralwidget"));
103 QVBoxLayout *verticalLayout_2 =
new QVBoxLayout(centralwidget);
104 verticalLayout_2->setObjectName(QStringLiteral(
"verticalLayout_2"));
105 QVBoxLayout *verticalLayout =
new QVBoxLayout();
106 verticalLayout->setObjectName(QStringLiteral(
"verticalLayout"));
107 mdiArea =
new QMdiArea(centralwidget);
108 mdiArea->setObjectName(QStringLiteral(
"mdiArea"));
110 verticalLayout->addWidget(
mdiArea);
111 verticalLayout_2->setContentsMargins(1, 1, 1, 1);
112 verticalLayout_2->addLayout(verticalLayout);
113 setCentralWidget(centralwidget);
114 centralwidget->layout()->setContentsMargins(1, 1, 1, 1);
119 connect(
mdiArea, &QMdiArea::subWindowActivated,
this,
120 &CMainWindow::slotRefreshMenus);
132 setWindowTitle(tr(
"GVEdit"));
133 this->resize(1024, 900);
135 setUnifiedTitleAndToolBarOnMac(
true);
136 QComboBox *cb = (QComboBox *)frmSettings->findChild<QComboBox *>(
137 QStringLiteral(
"cbLayout"));
138 dfltLayoutIdx =
LoadPlugins(*cb, frmSettings->
gvc,
"layout", {},
"dot");
139 cb = (QComboBox *)frmSettings->findChild<QComboBox *>(
140 QStringLiteral(
"cbExtension"));
142 statusBar()->showMessage(tr(
"Ready"));
143 setWindowIcon(QIcon(QStringLiteral(
":/images/icon.png")));
145 for (
const QString &file : files) {
152 if (
mdiArea->currentSubWindow()) {
160void CMainWindow::slotNew() {
168 QMdiSubWindow *existing = findMdiChild(
fileName);
170 mdiArea->setActiveSubWindow(existing);
176 statusBar()->showMessage(tr(
"File loaded"), 2000);
185void CMainWindow::slotOpen() {
187 QStringLiteral(
"*.cpp"),
188 QStringLiteral(
"*.cxx"),
189 QStringLiteral(
"*.cc"),
193 fd.setNameFilter(QStringLiteral(
"XML (*.xml)"));
194 QString
fileName = fd.getOpenFileName(
this);
199void CMainWindow::slotSave() {
200 if (activeMdiChild() && activeMdiChild()->save())
201 statusBar()->showMessage(tr(
"File saved"), 2000);
204void CMainWindow::slotSaveAs() {
205 if (activeMdiChild() && activeMdiChild()->saveAs())
206 statusBar()->showMessage(tr(
"File saved"), 2000);
209void CMainWindow::slotCut() {
210 if (activeMdiChild())
211 activeMdiChild()->cut();
214void CMainWindow::slotCopy() {
215 if (activeMdiChild())
216 activeMdiChild()->copy();
219void CMainWindow::slotPaste() {
220 if (activeMdiChild())
221 activeMdiChild()->paste();
224void CMainWindow::slotAbout() {
225 QString abs(tr(
"<b>GVEdit</b> Graph File Editor For Graphviz"
227 "Graphviz version: "));
230 QMessageBox::about(
this, tr(
"About GVEdit"), abs);
233void CMainWindow::setChild() {
234 if (prevChild != activeMdiChild()) {
236 QStringLiteral(
"working on %1\n").arg(activeMdiChild()->currentFile());
238 prevChild = activeMdiChild();
242void CMainWindow::slotSettings() {
247void CMainWindow::slotRun(
MdiChild *m) {
256void CMainWindow::slotNewLog() {
globTextEdit->clear(); }
258void CMainWindow::slotSaveLog() {
261 QMessageBox::warning(
this, tr(
"GvEdit"), tr(
"Nothing to save!"),
262 QMessageBox::Ok, QMessageBox::Ok);
266 QString
fileName = QFileDialog::getSaveFileName(
267 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text File(*.*)"));
271 if (!file.open(QFile::WriteOnly | QFile::Text)) {
272 QMessageBox::warning(
this, tr(
"MDI"),
273 tr(
"Cannot write file %1:\n%2.")
275 .arg(file.errorString()));
279 QTextStream
out(&file);
285void CMainWindow::updateFileMenu() {
286 if (!activeMdiChild()) {
287 saveAct->setEnabled(
false);
288 saveAsAct->setEnabled(
false);
289 pasteAct->setEnabled(
false);
290 closeAct->setEnabled(
false);
291 closeAllAct->setEnabled(
false);
292 tileAct->setEnabled(
false);
293 cascadeAct->setEnabled(
false);
294 nextAct->setEnabled(
false);
295 previousAct->setEnabled(
false);
296 separatorAct->setVisible(
false);
297 settingsAct->setEnabled(
false);
298 layoutAct->setEnabled(
false);
300 saveAct->setEnabled(
true);
301 saveAsAct->setEnabled(
true);
302 pasteAct->setEnabled(
true);
303 closeAct->setEnabled(
true);
304 closeAllAct->setEnabled(
true);
305 tileAct->setEnabled(
true);
306 cascadeAct->setEnabled(
true);
307 nextAct->setEnabled(
true);
308 previousAct->setEnabled(
true);
309 separatorAct->setVisible(
true);
310 settingsAct->setEnabled(
true);
311 layoutAct->setEnabled(
true);
313 if (activeMdiChild()->textCursor().hasSelection()) {
314 cutAct->setEnabled(
true);
315 copyAct->setEnabled(
true);
318 cutAct->setEnabled(
false);
319 copyAct->setEnabled(
false);
324void CMainWindow::slotRefreshMenus() { updateMenus(); }
326void CMainWindow::updateMenus() {
327 this->updateFileMenu();
328 this->updateWindowMenu();
331void CMainWindow::updateWindowMenu() {
333 mWindow->addAction(closeAct);
334 mWindow->addAction(closeAllAct);
335 mWindow->addSeparator();
336 mWindow->addAction(tileAct);
337 mWindow->addAction(cascadeAct);
338 mWindow->addSeparator();
339 mWindow->addAction(nextAct);
340 mWindow->addAction(previousAct);
341 mWindow->addAction(separatorAct);
343 QList<QMdiSubWindow *> windows =
mdiArea->subWindowList();
344 separatorAct->setVisible(!windows.isEmpty());
346 for (
int i = 0; i < windows.size(); ++i) {
347 QMdiSubWindow *window = windows.at(i);
348 if (window->widget()->inherits(
"MdiChild")) {
349 MdiChild *child = qobject_cast<MdiChild *>(window->widget());
356 QAction *action = mWindow->addAction(text);
357 action->setCheckable(
true);
358 action->setChecked(child == activeMdiChild());
359 connect(action, &QAction::triggered,
this,
360 [
this, window] { activateChild(window); });
365MdiChild *CMainWindow::createMdiChild() {
368 QMdiSubWindow *
s =
mdiArea->addSubWindow(child);
370 s->move(
mdiArea->subWindowList().count() * 5,
371 mdiArea->subWindowList().count() * 5);
372 connect(child, &MdiChild::copyAvailable, cutAct, &QAction::setEnabled);
373 connect(child, &MdiChild::copyAvailable, copyAct, &QAction::setEnabled);
380void CMainWindow::actions() {
382 new QAction(QIcon(QStringLiteral(
":/images/new.png")), tr(
"&New"),
this);
383 newAct->setShortcuts(QKeySequence::New);
384 newAct->setStatusTip(tr(
"Create a new file"));
385 connect(newAct, &QAction::triggered,
this, &CMainWindow::slotNew);
387 openAct =
new QAction(QIcon(QStringLiteral(
":/images/open.png")),
388 tr(
"&Open..."),
this);
389 openAct->setShortcuts(QKeySequence::Open);
390 openAct->setStatusTip(tr(
"Open an existing file"));
391 connect(openAct, &QAction::triggered,
this, &CMainWindow::slotOpen);
393 saveAct =
new QAction(QIcon(QStringLiteral(
":/images/save.png")), tr(
"&Save"),
395 saveAct->setShortcuts(QKeySequence::Save);
396 saveAct->setStatusTip(tr(
"Save the document to disk"));
397 connect(saveAct, &QAction::triggered,
this, &CMainWindow::slotSave);
399 saveAsAct =
new QAction(tr(
"Save &As..."),
this);
400 saveAsAct->setShortcuts(QKeySequence::SaveAs);
401 saveAsAct->setStatusTip(tr(
"Save the document under a new name"));
402 connect(saveAsAct, &QAction::triggered,
this, &CMainWindow::slotSaveAs);
404 exitAct =
new QAction(tr(
"E&xit"),
this);
405 exitAct->setShortcuts(QKeySequence::Quit);
406 exitAct->setStatusTip(tr(
"Exit the application"));
407 connect(exitAct, &QAction::triggered, qApp, &QApplication::closeAllWindows);
410 new QAction(QIcon(QStringLiteral(
":/images/cut.png")), tr(
"Cu&t"),
this);
411 cutAct->setShortcuts(QKeySequence::Cut);
412 cutAct->setStatusTip(tr(
"Cut the current selection's contents to the "
414 connect(cutAct, &QAction::triggered,
this, &CMainWindow::slotCut);
416 copyAct =
new QAction(QIcon(QStringLiteral(
":/images/copy.png")), tr(
"&Copy"),
418 copyAct->setShortcuts(QKeySequence::Copy);
419 copyAct->setStatusTip(tr(
"Copy the current selection's contents to the "
421 connect(copyAct, &QAction::triggered,
this, &CMainWindow::slotCopy);
423 pasteAct =
new QAction(QIcon(QStringLiteral(
":/images/paste.png")),
425 pasteAct->setShortcuts(QKeySequence::Paste);
426 pasteAct->setStatusTip(tr(
"Paste the clipboard's contents into the current "
428 connect(pasteAct, &QAction::triggered,
this, &CMainWindow::slotPaste);
430 closeAct =
new QAction(tr(
"Cl&ose"),
this);
431 closeAct->setStatusTip(tr(
"Close the active window"));
432 connect(closeAct, &QAction::triggered,
mdiArea,
433 &QMdiArea::closeActiveSubWindow);
435 closeAllAct =
new QAction(tr(
"Close &All"),
this);
436 closeAllAct->setStatusTip(tr(
"Close all the windows"));
437 connect(closeAllAct, &QAction::triggered,
mdiArea,
438 &QMdiArea::closeAllSubWindows);
440 tileAct =
new QAction(tr(
"&Tile"),
this);
441 tileAct->setStatusTip(tr(
"Tile the windows"));
442 connect(tileAct, &QAction::triggered,
mdiArea, &QMdiArea::tileSubWindows);
444 cascadeAct =
new QAction(tr(
"&Cascade"),
this);
445 cascadeAct->setStatusTip(tr(
"Cascade the windows"));
446 connect(cascadeAct, &QAction::triggered,
mdiArea,
447 &QMdiArea::cascadeSubWindows);
449 nextAct =
new QAction(tr(
"Ne&xt"),
this);
450 nextAct->setShortcuts(QKeySequence::NextChild);
451 nextAct->setStatusTip(tr(
"Move the focus to the next window"));
452 connect(nextAct, &QAction::triggered,
mdiArea,
453 &QMdiArea::activateNextSubWindow);
455 previousAct =
new QAction(tr(
"Pre&vious"),
this);
456 previousAct->setShortcuts(QKeySequence::PreviousChild);
457 previousAct->setStatusTip(tr(
"Move the focus to the previous window"));
458 connect(previousAct, &QAction::triggered,
mdiArea,
459 &QMdiArea::activatePreviousSubWindow);
461 separatorAct =
new QAction(
this);
462 separatorAct->setSeparator(
true);
464 aboutAct =
new QAction(tr(
"&About"),
this);
465 aboutAct->setStatusTip(tr(
"Show the application's About box"));
466 connect(aboutAct, &QAction::triggered,
this, &CMainWindow::slotAbout);
468 settingsAct =
new QAction(QIcon(QStringLiteral(
":/images/settings.png")),
469 tr(
"Settings"),
this);
470 settingsAct->setStatusTip(tr(
"Show Graphviz Settings"));
471 connect(settingsAct, &QAction::triggered,
this, &CMainWindow::slotSettings);
472 settingsAct->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_F5));
474 layoutAct =
new QAction(QIcon(QStringLiteral(
":/images/run.png")),
476 layoutAct->setStatusTip(tr(
"Layout the active graph"));
477 connect(layoutAct, &QAction::triggered,
this, [
this] { slotRun(); });
478 layoutAct->setShortcut(QKeySequence(Qt::Key_F5));
481void CMainWindow::menus() {
482 mFile = menuBar()->addMenu(tr(
"&File"));
483 mEdit = menuBar()->addMenu(tr(
"&Edit"));
484 mWindow = menuBar()->addMenu(tr(
"&Window"));
485 mGraph = menuBar()->addMenu(tr(
"&Graph"));
486 mHelp = menuBar()->addMenu(tr(
"&Help"));
488 mFile->addAction(newAct);
489 mFile->addAction(openAct);
490 mFile->addAction(saveAct);
491 mFile->addAction(saveAsAct);
492 mFile->addSeparator();
494 mFile->addAction(exitAct);
496 mEdit->addAction(cutAct);
497 mEdit->addAction(copyAct);
498 mEdit->addAction(pasteAct);
500 mGraph->addAction(settingsAct);
501 mGraph->addAction(layoutAct);
502 mGraph->addSeparator();
505 connect(mWindow, &QMenu::aboutToShow,
this, &CMainWindow::slotRefreshMenus);
506 mHelp->addAction(aboutAct);
509void CMainWindow::toolBars() {
510 tbFile = addToolBar(tr(
"File"));
511 tbFile->addAction(newAct);
512 tbFile->addAction(openAct);
513 tbFile->addAction(saveAct);
515 tbEdit = addToolBar(tr(
"Edit"));
516 tbEdit->addAction(cutAct);
517 tbEdit->addAction(copyAct);
518 tbEdit->addAction(pasteAct);
520 tbGraph = addToolBar(tr(
"Graph"));
521 tbGraph->addAction(settingsAct);
522 tbGraph->addAction(layoutAct);
525void CMainWindow::readSettings() {
528 QSettings settings(QStringLiteral(
"Graphviz"), QStringLiteral(
"gvedit"));
529 if (settings.contains(QStringLiteral(
"pos")) &&
530 settings.contains(QStringLiteral(
"size"))) {
532 settings.value(QStringLiteral(
"pos"), QPoint(200, 200)).toPoint();
534 settings.value(QStringLiteral(
"size"), QSize(400, 400)).toSize();
542 QSettings settings(QStringLiteral(
"Trolltech"),
543 QStringLiteral(
"MDI Example"));
545 settings.value(QStringLiteral(
"pos"), QPoint(200, 200)).toPoint();
546 QSize size = settings.value(QStringLiteral(
"size"), QSize(400, 400)).toSize();
551void CMainWindow::writeSettings() {
552 QSettings settings(QStringLiteral(
"Graphviz"), QStringLiteral(
"gvedit"));
553 settings.setValue(QStringLiteral(
"pos"), pos());
554 settings.setValue(QStringLiteral(
"size"), size());
557MdiChild *CMainWindow::activeMdiChild() {
558 if (QMdiSubWindow *activeSubWindow =
mdiArea->activeSubWindow()) {
559 if (activeSubWindow->widget()->inherits(
"MdiChild"))
560 return qobject_cast<MdiChild *>(activeSubWindow->widget());
562 return qobject_cast<ImageViewer *>(activeSubWindow->widget())
568QMdiSubWindow *CMainWindow::findMdiChild(
const QString &
fileName) {
569 QString canonicalFilePath = QFileInfo(
fileName).canonicalFilePath();
571 foreach (QMdiSubWindow *window,
mdiArea->subWindowList()) {
572 if (window->widget()->inherits(
"MdiChild")) {
574 MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget());
580 qobject_cast<ImageViewer *>(window->widget())->graphWindow;
588void CMainWindow::activateChild(QWidget *window) {
591 mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
static void out(agerrlevel_t level, const char *fmt, va_list args)
Report messages using a user-supplied or default write function.
int runSettings(MdiChild *m)
int showSettings(MdiChild *m)
void closeEvent(QCloseEvent *event)
void addFile(const QString &fileName)
CMainWindow(const QStringList &files)
QString userFriendlyCurrentFile()
bool loadFile(const QString &fileName)
int errorPipe(char *errMsg)
agusererrf agseterrf(agusererrf newf)
char ** gvPluginList(GVC_t *gvc, const char *kind, int *sz)
char * gvcVersion(GVC_t *gvc)
char * fileName(ingraph_state *sp)
Return name of current file being processed.
int errorPipe(char *errMsg)
static int LoadPlugins(QComboBox &cb, GVC_t *gvc, const char *kind, const QStringList &more, std::string_view prefer)
static const QStringList xtra
static void freeList(char **lp, int count)