16#include "qfiledialog.h"
17#include "qmessagebox.h"
19#include <QTemporaryFile>
30#define WIDGET(t, f) (findChild<t *>(QStringLiteral(#f)))
35 const std::string me_s = me ==
NULL ?
"" : me;
44 std::string gvedit_exe =
find_me();
52 if (slash == std::string::npos) {
53 errout <<
"no path separator in path to self, " << gvedit_exe.c_str()
58 std::string bin = gvedit_exe.substr(0, slash);
60 if (slash == std::string::npos) {
61 errout <<
"no path separator in directory containing self, " << bin.c_str()
66 std::string install_prefix = bin.substr(0, slash);
75 if (file.open(QIODevice::ReadOnly)) {
76 QTextStream stream(&file);
78 while (!stream.atEnd()) {
79 line = stream.readLine();
80 if (line.left(1) == QLatin1String(
":")) {
82 QStringList sl = line.split(u
':');
83 for (
int id = 0;
id < sl.count();
id++) {
87 if (sl[
id].contains(u
'G'))
88 cbNameG->addItem(attrName);
89 if (sl[
id].contains(u
'N'))
90 cbNameN->addItem(attrName);
91 if (sl[
id].contains(u
'E'))
92 cbNameE->addItem(attrName);
99 <<
"\" for reading\n";
117 tempDia.setupUi(
this);
119 activeWindow =
nullptr;
123 s = getenv(
"GVEDIT_PATH");
126 pathname = QString::fromUtf8(
s);
128 pathname = QString::fromStdString(
find_share());
130 connect(
WIDGET(QPushButton, pbAdd), &QPushButton::clicked,
this,
131 &CFrmSettings::addSlot);
132 connect(
WIDGET(QPushButton, pbNew), &QPushButton::clicked,
this,
133 &CFrmSettings::newSlot);
134 connect(
WIDGET(QPushButton, pbOpen), &QPushButton::clicked,
this,
135 &CFrmSettings::openSlot);
136 connect(
WIDGET(QPushButton, pbSave), &QPushButton::clicked,
this,
137 &CFrmSettings::saveSlot);
138 connect(
WIDGET(QPushButton, btnOK), &QPushButton::clicked,
this,
139 &CFrmSettings::okSlot);
140 connect(
WIDGET(QPushButton, btnCancel), &QPushButton::clicked,
this,
141 &CFrmSettings::cancelSlot);
142 connect(
WIDGET(QPushButton, pbOut), &QPushButton::clicked,
this,
143 &CFrmSettings::outputSlot);
144 connect(
WIDGET(QPushButton, pbHelp), &QPushButton::clicked,
this,
145 &CFrmSettings::helpSlot);
147 connect(
WIDGET(QComboBox, cbScope),
148 QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
149 &CFrmSettings::scopeChangedSlot);
152 if (!pathname.isEmpty()) {
153 loadAttrs(pathname + QLatin1String(
"/attrs.txt"),
155 WIDGET(QComboBox, cbNameE));
157 setWindowIcon(QIcon(QStringLiteral(
":/images/icon.png")));
160void CFrmSettings::outputSlot() {
161 QString _filter = QStringLiteral(
"Output File(*.%1)")
162 .arg(
WIDGET(QComboBox, cbExtension)->currentText());
163 QString
fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Graph As.."),
164 QStringLiteral(
"/"), _filter);
169void CFrmSettings::scopeChangedSlot(
int id) {
170 WIDGET(QComboBox, cbNameG)->setVisible(
id == 0);
171 WIDGET(QComboBox, cbNameN)->setVisible(
id == 1);
172 WIDGET(QComboBox, cbNameE)->setVisible(
id == 2);
175void CFrmSettings::addSlot() {
176 QString _scope =
WIDGET(QComboBox, cbScope)->currentText();
178 switch (
WIDGET(QComboBox, cbScope)->currentIndex()) {
180 _name =
WIDGET(QComboBox, cbNameG)->currentText();
183 _name =
WIDGET(QComboBox, cbNameN)->currentText();
186 _name =
WIDGET(QComboBox, cbNameE)->currentText();
189 QString _value =
WIDGET(QLineEdit, leValue)->text();
191 if (_value.trimmed().isEmpty())
192 QMessageBox::warning(
this, tr(
"GvEdit"),
193 tr(
"Please enter a value for selected attribute!"),
194 QMessageBox::Ok, QMessageBox::Ok);
196 QString
str = _scope + QLatin1Char(u
'[') + _name + QLatin1String(
"=\"");
197 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().contains(
str)) {
198 QMessageBox::warning(
this, tr(
"GvEdit"),
199 tr(
"Attribute is already defined!"), QMessageBox::Ok,
203 str =
str + _value + QLatin1String(
"\"]");
204 WIDGET(QTextEdit, teAttributes)
205 ->setPlainText(
WIDGET(QTextEdit, teAttributes)->toPlainText() +
str +
210void CFrmSettings::helpSlot() {
211 QDesktopServices::openUrl(
212 QUrl(QStringLiteral(
"http://www.graphviz.org/doc/info/attrs.html")));
215void CFrmSettings::cancelSlot() { this->reject(); }
217void CFrmSettings::okSlot() {
222void CFrmSettings::newSlot() {
223 WIDGET(QTextEdit, teAttributes)->setPlainText(tr(
""));
226void CFrmSettings::openSlot() {
227 QString
fileName = QFileDialog::getOpenFileName(
228 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text file (*.*)"));
231 if (!file.open(QFile::ReadOnly | QFile::Text)) {
232 QMessageBox::warning(
this, tr(
"MDI"),
233 tr(
"Cannot read file %1:\n%2.")
235 .arg(file.errorString()));
239 QTextStream
in(&file);
240 WIDGET(QTextEdit, teAttributes)->setPlainText(
in.readAll());
244void CFrmSettings::saveSlot() {
246 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().trimmed().isEmpty()) {
247 QMessageBox::warning(
this, tr(
"GvEdit"), tr(
"Nothing to save!"),
248 QMessageBox::Ok, QMessageBox::Ok);
252 QString
fileName = QFileDialog::getSaveFileName(
253 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text File(*.*)"));
257 if (!file.open(QFile::WriteOnly | QFile::Text)) {
258 QMessageBox::warning(
this, tr(
"MDI"),
259 tr(
"Cannot write file %1:\n%2.")
261 .arg(file.errorString()));
265 QTextStream
out(&file);
266 out <<
WIDGET(QTextEdit, teAttributes)->toPlainText();
270bool CFrmSettings::loadGraph(
MdiChild *m) {
281bool CFrmSettings::createLayout() {
287 WIDGET(QTextEdit, teAttributes)->toPlainText());
290 rdr.
data = bytes.constData();
311 QTemporaryFile tempFile;
312 tempFile.setAutoRemove(
false);
314 QString a = tempFile.fileName();
318void CFrmSettings::doPreview(
const QString &
fileName) {
333bool CFrmSettings::renderLayout() {
336 QString sfx =
WIDGET(QComboBox, cbExtension)->currentText();
339 if (
fileName.isEmpty() || sfx == QLatin1String(
"NONE"))
340 doPreview(QString());
354 if (!outf.open(QIODevice::WriteOnly)) {
355 QString pathName = QDir::homePath();
356 pathName.append(u
'/').append(
fileName);
357 fileName = QDir::toNativeSeparators(pathName);
359 QStringLiteral(
"Output written to %1\n").arg(
fileName);
373bool CFrmSettings::loadLayouts() {
return false; }
375bool CFrmSettings::loadRenderers() {
return false; }
377void CFrmSettings::refreshContent() {
380 WIDGET(QComboBox, cbExtension)->setCurrentIndex(activeWindow->
renderIdx);
384 WIDGET(QLineEdit, leOutput)
387 WIDGET(QComboBox, cbExtension)->currentText());
391 WIDGET(QLineEdit, leValue)->clear();
394void CFrmSettings::saveContent() {
396 activeWindow->
renderIdx =
WIDGET(QComboBox, cbExtension)->currentIndex();
402 if (createLayout() && renderLayout()) {
407 return QDialog::Accepted;
411 if (this->loadGraph(m))
415 if (this->loadGraph(m))
417 return QDialog::Rejected;
425 if (this->loadGraph(m)) {
429 return QDialog::Rejected;
432void 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)
static int in(Extype_t lhs, Exid_t *rhs, Exdisc_t *disc)
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
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)
File system path helpers.
#define PATH_SEPARATOR
character for separating directory components in a file system path