16#include "qfiledialog.h"
17#include "qmessagebox.h"
19#include <QTemporaryFile>
29#define WIDGET(t, f) (findChild<t *>(QStringLiteral(#f)))
34 const std::string me_s = me ==
NULL ?
"" : me;
43 const char PATH_SEPARATOR =
'\\';
45 const char PATH_SEPARATOR =
'/';
49 std::string gvedit_exe =
find_me();
56 size_t slash = gvedit_exe.rfind(PATH_SEPARATOR);
57 if (slash == std::string::npos) {
58 errout <<
"no path separator in path to self, " << gvedit_exe.c_str()
63 std::string bin = gvedit_exe.substr(0, slash);
64 slash = bin.rfind(PATH_SEPARATOR);
65 if (slash == std::string::npos) {
66 errout <<
"no path separator in directory containing self, " << bin.c_str()
71 std::string install_prefix = bin.substr(0, slash);
73 return install_prefix + PATH_SEPARATOR +
"share" + PATH_SEPARATOR +
74 "graphviz" + PATH_SEPARATOR +
"gvedit";
80 if (file.open(QIODevice::ReadOnly)) {
81 QTextStream stream(&file);
83 while (!stream.atEnd()) {
84 line = stream.readLine();
85 if (line.left(1) == QLatin1String(
":")) {
87 QStringList sl = line.split(u
':');
88 for (
int id = 0;
id < sl.count();
id++) {
92 if (sl[
id].contains(u
'G'))
93 cbNameG->addItem(attrName);
94 if (sl[
id].contains(u
'N'))
95 cbNameN->addItem(attrName);
96 if (sl[
id].contains(u
'E'))
97 cbNameE->addItem(attrName);
104 <<
"\" for reading\n";
124 activeWindow =
nullptr;
128 s = getenv(
"GVEDIT_PATH");
131 pathname = QString::fromUtf8(
s);
133 pathname = QString::fromStdString(
find_share());
135 connect(
WIDGET(QPushButton, pbAdd), &QPushButton::clicked,
this,
136 &CFrmSettings::addSlot);
137 connect(
WIDGET(QPushButton, pbNew), &QPushButton::clicked,
this,
138 &CFrmSettings::newSlot);
139 connect(
WIDGET(QPushButton, pbOpen), &QPushButton::clicked,
this,
140 &CFrmSettings::openSlot);
141 connect(
WIDGET(QPushButton, pbSave), &QPushButton::clicked,
this,
142 &CFrmSettings::saveSlot);
143 connect(
WIDGET(QPushButton, btnOK), &QPushButton::clicked,
this,
144 &CFrmSettings::okSlot);
145 connect(
WIDGET(QPushButton, btnCancel), &QPushButton::clicked,
this,
146 &CFrmSettings::cancelSlot);
147 connect(
WIDGET(QPushButton, pbOut), &QPushButton::clicked,
this,
148 &CFrmSettings::outputSlot);
149 connect(
WIDGET(QPushButton, pbHelp), &QPushButton::clicked,
this,
150 &CFrmSettings::helpSlot);
152 connect(
WIDGET(QComboBox, cbScope),
153 QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
154 &CFrmSettings::scopeChangedSlot);
157 if (!pathname.isEmpty()) {
158 loadAttrs(pathname + QLatin1String(
"/attrs.txt"),
160 WIDGET(QComboBox, cbNameE));
162 setWindowIcon(QIcon(QStringLiteral(
":/images/icon.png")));
165void CFrmSettings::outputSlot() {
166 QString _filter = QStringLiteral(
"Output File(*.%1)")
167 .arg(
WIDGET(QComboBox, cbExtension)->currentText());
168 QString
fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Graph As.."),
169 QStringLiteral(
"/"), _filter);
174void CFrmSettings::scopeChangedSlot(
int id) {
175 WIDGET(QComboBox, cbNameG)->setVisible(
id == 0);
176 WIDGET(QComboBox, cbNameN)->setVisible(
id == 1);
177 WIDGET(QComboBox, cbNameE)->setVisible(
id == 2);
180void CFrmSettings::addSlot() {
181 QString _scope =
WIDGET(QComboBox, cbScope)->currentText();
183 switch (
WIDGET(QComboBox, cbScope)->currentIndex()) {
185 _name =
WIDGET(QComboBox, cbNameG)->currentText();
188 _name =
WIDGET(QComboBox, cbNameN)->currentText();
191 _name =
WIDGET(QComboBox, cbNameE)->currentText();
194 QString _value =
WIDGET(QLineEdit, leValue)->text();
196 if (_value.trimmed().isEmpty())
197 QMessageBox::warning(
this, tr(
"GvEdit"),
198 tr(
"Please enter a value for selected attribute!"),
199 QMessageBox::Ok, QMessageBox::Ok);
201 QString
str = _scope + QLatin1Char(u
'[') + _name + QLatin1String(
"=\"");
202 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().contains(
str)) {
203 QMessageBox::warning(
this, tr(
"GvEdit"),
204 tr(
"Attribute is already defined!"), QMessageBox::Ok,
208 str =
str + _value + QLatin1String(
"\"]");
209 WIDGET(QTextEdit, teAttributes)
210 ->setPlainText(
WIDGET(QTextEdit, teAttributes)->toPlainText() +
str +
215void CFrmSettings::helpSlot() {
216 QDesktopServices::openUrl(
217 QUrl(QStringLiteral(
"http://www.graphviz.org/doc/info/attrs.html")));
220void CFrmSettings::cancelSlot() { this->reject(); }
222void CFrmSettings::okSlot() {
227void CFrmSettings::newSlot() {
228 WIDGET(QTextEdit, teAttributes)->setPlainText(tr(
""));
231void CFrmSettings::openSlot() {
232 QString
fileName = QFileDialog::getOpenFileName(
233 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text file (*.*)"));
236 if (!file.open(QFile::ReadOnly | QFile::Text)) {
237 QMessageBox::warning(
this, tr(
"MDI"),
238 tr(
"Cannot read file %1:\n%2.")
240 .arg(file.errorString()));
244 QTextStream in(&file);
245 WIDGET(QTextEdit, teAttributes)->setPlainText(in.readAll());
249void CFrmSettings::saveSlot() {
251 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().trimmed().isEmpty()) {
252 QMessageBox::warning(
this, tr(
"GvEdit"), tr(
"Nothing to save!"),
253 QMessageBox::Ok, QMessageBox::Ok);
257 QString
fileName = QFileDialog::getSaveFileName(
258 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text File(*.*)"));
262 if (!file.open(QFile::WriteOnly | QFile::Text)) {
263 QMessageBox::warning(
this, tr(
"MDI"),
264 tr(
"Cannot write file %1:\n%2.")
266 .arg(file.errorString()));
270 QTextStream
out(&file);
271 out <<
WIDGET(QTextEdit, teAttributes)->toPlainText();
275bool CFrmSettings::loadGraph(
MdiChild *m) {
286bool CFrmSettings::createLayout() {
292 WIDGET(QTextEdit, teAttributes)->toPlainText());
299 rdr.
data = bytes.constData();
320 QTemporaryFile tempFile;
321 tempFile.setAutoRemove(
false);
323 QString a = tempFile.fileName();
327void CFrmSettings::doPreview(
const QString &
fileName) {
342bool CFrmSettings::renderLayout() {
345 QString sfx =
WIDGET(QComboBox, cbExtension)->currentText();
348 if (
fileName.isEmpty() || sfx == QLatin1String(
"NONE"))
349 doPreview(QString());
363 if (!outf.open(QIODevice::WriteOnly)) {
364 QString pathName = QDir::homePath();
365 pathName.append(u
'/').append(
fileName);
366 fileName = QDir::toNativeSeparators(pathName);
368 QStringLiteral(
"Output written to %1\n").arg(
fileName);
382bool CFrmSettings::loadLayouts() {
return false; }
384bool CFrmSettings::loadRenderers() {
return false; }
386void CFrmSettings::refreshContent() {
389 WIDGET(QComboBox, cbExtension)->setCurrentIndex(activeWindow->
renderIdx);
393 WIDGET(QLineEdit, leOutput)
396 WIDGET(QComboBox, cbExtension)->currentText());
400 WIDGET(QLineEdit, leValue)->clear();
403void CFrmSettings::saveContent() {
405 activeWindow->
renderIdx =
WIDGET(QComboBox, cbExtension)->currentIndex();
411 if (createLayout() && renderLayout()) {
416 return QDialog::Accepted;
420 if (this->loadGraph(m))
424 if (this->loadGraph(m))
426 return QDialog::Rejected;
434 if (this->loadGraph(m)) {
438 return QDialog::Rejected;
441void CFrmSettings::setActiveWindow(
MdiChild *m) { this->activeWindow = m; }
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)
MdiChild * getActiveWindow()
std::unique_ptr< ImageViewer > previewFrm
bool loadPreview(const QString &fileName)
void setupUi(QDialog *Dialog)
bool loadAttrs(const QString &fileName, QComboBox *cbNameG, QComboBox *cbNameN, QComboBox *cbNameE)
QString stripFileExtension(const QString &fileName)
int errorPipe(char *errMsg)
static std::string find_me()
wrapper around gv_find_me to convert to a C++ type
static std::string find_share(void)
find an absolute path to where Gvedit auxiliary files are stored
static QString buildTempFile()
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Agraph_t * agmemread(const char *cp)
reads a graph from the input string
void agsetfile(const char *)
sets the current file name for subsequent error reporting
int gvLayout(GVC_t *gvc, graph_t *g, const char *engine)
int gvRenderFilename(GVC_t *gvc, graph_t *g, const char *format, const char *filename)
platform abstraction for finding the path to yourself
textitem scanner parser str
char * fileName(ingraph_state *sp)
Return name of current file being processed.
static int layout(graph_t *g, layout_info *infop)