19#include "qfiledialog.h"
20#include "qmessagebox.h"
22#include <QTemporaryFile>
33#define WIDGET(t, f) (findChild<t *>(QStringLiteral(#f)))
38 const std::string me_s = me ==
NULL ?
"" : me;
47 std::string gvedit_exe =
find_me();
55 if (slash == std::string::npos) {
56 errout <<
"no path separator in path to self, " << gvedit_exe.c_str()
61 std::string bin = gvedit_exe.substr(0, slash);
63 if (slash == std::string::npos) {
64 errout <<
"no path separator in directory containing self, " << bin.c_str()
69 std::string install_prefix = bin.substr(0, slash);
78 if (file.open(QIODevice::ReadOnly)) {
79 QTextStream stream(&file);
81 while (!stream.atEnd()) {
82 line = stream.readLine();
83 if (line.left(1) == QLatin1String(
":")) {
85 QStringList sl = line.split(u
':');
86 for (
int id = 0;
id < sl.count();
id++) {
90 if (sl[
id].contains(u
'G'))
91 cbNameG->addItem(attrName);
92 if (sl[
id].contains(u
'N'))
93 cbNameN->addItem(attrName);
94 if (sl[
id].contains(u
'E'))
95 cbNameE->addItem(attrName);
102 <<
"\" for reading\n";
120 tempDia.setupUi(
this);
122 activeWindow =
nullptr;
126 s = getenv(
"GVEDIT_PATH");
129 pathname = QString::fromUtf8(
s);
131 pathname = QString::fromStdString(
find_share());
133 connect(
WIDGET(QPushButton, pbAdd), &QPushButton::clicked,
this,
134 &CFrmSettings::addSlot);
135 connect(
WIDGET(QPushButton, pbNew), &QPushButton::clicked,
this,
136 &CFrmSettings::newSlot);
137 connect(
WIDGET(QPushButton, pbOpen), &QPushButton::clicked,
this,
138 &CFrmSettings::openSlot);
139 connect(
WIDGET(QPushButton, pbSave), &QPushButton::clicked,
this,
140 &CFrmSettings::saveSlot);
141 connect(
WIDGET(QPushButton, btnOK), &QPushButton::clicked,
this,
142 &CFrmSettings::okSlot);
143 connect(
WIDGET(QPushButton, btnCancel), &QPushButton::clicked,
this,
144 &CFrmSettings::cancelSlot);
145 connect(
WIDGET(QPushButton, pbOut), &QPushButton::clicked,
this,
146 &CFrmSettings::outputSlot);
147 connect(
WIDGET(QPushButton, pbHelp), &QPushButton::clicked,
this,
148 &CFrmSettings::helpSlot);
150 connect(
WIDGET(QComboBox, cbScope),
151 QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
152 &CFrmSettings::scopeChangedSlot);
155 if (!pathname.isEmpty()) {
156 loadAttrs(pathname + QLatin1String(
"/attrs.txt"),
158 WIDGET(QComboBox, cbNameE));
160 setWindowIcon(QIcon(QStringLiteral(
":/images/icon.png")));
163void CFrmSettings::outputSlot() {
164 QString _filter = QStringLiteral(
"Output File(*.%1)")
165 .arg(
WIDGET(QComboBox, cbExtension)->currentText());
166 QString
fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Graph As.."),
167 QStringLiteral(
"/"), _filter);
172void CFrmSettings::scopeChangedSlot(
int id) {
173 WIDGET(QComboBox, cbNameG)->setVisible(
id == 0);
174 WIDGET(QComboBox, cbNameN)->setVisible(
id == 1);
175 WIDGET(QComboBox, cbNameE)->setVisible(
id == 2);
178void CFrmSettings::addSlot() {
179 QString _scope =
WIDGET(QComboBox, cbScope)->currentText();
181 switch (
WIDGET(QComboBox, cbScope)->currentIndex()) {
183 _name =
WIDGET(QComboBox, cbNameG)->currentText();
186 _name =
WIDGET(QComboBox, cbNameN)->currentText();
189 _name =
WIDGET(QComboBox, cbNameE)->currentText();
192 QString _value =
WIDGET(QLineEdit, leValue)->text();
194 if (_value.trimmed().isEmpty())
195 QMessageBox::warning(
this, tr(
"GvEdit"),
196 tr(
"Please enter a value for selected attribute!"),
197 QMessageBox::Ok, QMessageBox::Ok);
199 QString
str = _scope + QLatin1Char(u
'[') + _name + QLatin1String(
"=\"");
200 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().contains(
str)) {
201 QMessageBox::warning(
this, tr(
"GvEdit"),
202 tr(
"Attribute is already defined!"), QMessageBox::Ok,
206 str =
str + _value + QLatin1String(
"\"]");
207 WIDGET(QTextEdit, teAttributes)
208 ->setPlainText(
WIDGET(QTextEdit, teAttributes)->toPlainText() +
str +
213void CFrmSettings::helpSlot() {
214 QDesktopServices::openUrl(
215 QUrl(QStringLiteral(
"http://www.graphviz.org/doc/info/attrs.html")));
218void CFrmSettings::cancelSlot() { this->reject(); }
220void CFrmSettings::okSlot() {
225void CFrmSettings::newSlot() {
226 WIDGET(QTextEdit, teAttributes)->setPlainText(tr(
""));
229void CFrmSettings::openSlot() {
230 QString
fileName = QFileDialog::getOpenFileName(
231 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text file (*.*)"));
234 if (!file.open(QFile::ReadOnly | QFile::Text)) {
235 QMessageBox::warning(
this, tr(
"MDI"),
236 tr(
"Cannot read file %1:\n%2.")
238 .arg(file.errorString()));
242 QTextStream
in(&file);
243 WIDGET(QTextEdit, teAttributes)->setPlainText(
in.readAll());
247void CFrmSettings::saveSlot() {
249 if (
WIDGET(QTextEdit, teAttributes)->toPlainText().trimmed().isEmpty()) {
250 QMessageBox::warning(
this, tr(
"GvEdit"), tr(
"Nothing to save!"),
251 QMessageBox::Ok, QMessageBox::Ok);
255 QString
fileName = QFileDialog::getSaveFileName(
256 this, tr(
"Open File"), QStringLiteral(
"/"), tr(
"Text File(*.*)"));
260 if (!file.open(QFile::WriteOnly | QFile::Text)) {
261 QMessageBox::warning(
this, tr(
"MDI"),
262 tr(
"Cannot write file %1:\n%2.")
264 .arg(file.errorString()));
268 QTextStream
out(&file);
269 out <<
WIDGET(QTextEdit, teAttributes)->toPlainText();
273bool CFrmSettings::loadGraph(
MdiChild *m) {
284bool CFrmSettings::createLayout() {
290 WIDGET(QTextEdit, teAttributes)->toPlainText());
293 rdr.
data = bytes.constData();
314 QTemporaryFile tempFile;
315 tempFile.setAutoRemove(
false);
317 QString a = tempFile.fileName();
321void CFrmSettings::doPreview(
const QString &
fileName) {
336bool CFrmSettings::renderLayout() {
339 QString sfx =
WIDGET(QComboBox, cbExtension)->currentText();
342 if (
fileName.isEmpty() || sfx == QLatin1String(
"NONE"))
343 doPreview(QString());
357 if (!outf.open(QIODevice::WriteOnly)) {
358 QString pathName = QDir::homePath();
359 pathName.append(u
'/').append(
fileName);
360 fileName = QDir::toNativeSeparators(pathName);
362 QStringLiteral(
"Output written to %1\n").arg(
fileName);
376bool CFrmSettings::loadLayouts() {
return false; }
378bool CFrmSettings::loadRenderers() {
return false; }
380void CFrmSettings::refreshContent() {
383 WIDGET(QComboBox, cbExtension)->setCurrentIndex(activeWindow->
renderIdx);
387 WIDGET(QLineEdit, leOutput)
390 WIDGET(QComboBox, cbExtension)->currentText());
394 WIDGET(QLineEdit, leValue)->clear();
397void CFrmSettings::saveContent() {
399 activeWindow->
renderIdx =
WIDGET(QComboBox, cbExtension)->currentIndex();
405 if (createLayout() && renderLayout()) {
410 return QDialog::Accepted;
414 if (this->loadGraph(m))
418 if (this->loadGraph(m))
420 return QDialog::Rejected;
428 if (this->loadGraph(m)) {
432 return QDialog::Rejected;
435void 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