diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/delimitedstringitemdelegate.cpp | 44 | ||||
-rw-r--r-- | src/gui/delimitedstringitemdelegate.h | 42 | ||||
-rw-r--r-- | src/gui/exportdialog.cpp | 194 | ||||
-rw-r--r-- | src/gui/exportdialog.h | 61 | ||||
-rw-r--r-- | src/gui/exportdialog.ui | 162 | ||||
-rw-r--r-- | src/gui/latexprocess.cpp | 169 | ||||
-rw-r--r-- | src/gui/latexprocess.h | 56 | ||||
-rw-r--r-- | src/gui/mainmenu.cpp | 51 | ||||
-rw-r--r-- | src/gui/mainmenu.h | 7 | ||||
-rw-r--r-- | src/gui/mainmenu.ui | 36 | ||||
-rw-r--r-- | src/gui/preferencedialog.cpp | 111 | ||||
-rw-r--r-- | src/gui/preferencedialog.h | 31 | ||||
-rw-r--r-- | src/gui/preferencedialog.ui | 272 | ||||
-rw-r--r-- | src/gui/previewwindow.cpp | 208 | ||||
-rw-r--r-- | src/gui/previewwindow.h | 72 | ||||
-rw-r--r-- | src/gui/previewwindow.ui | 107 | ||||
-rw-r--r-- | src/gui/styleeditor.cpp | 62 | ||||
-rw-r--r-- | src/gui/styleeditor.h | 26 | ||||
-rw-r--r-- | src/gui/tikzscene.cpp | 101 | ||||
-rw-r--r-- | src/gui/tikzscene.h | 4 | ||||
-rw-r--r-- | src/gui/tikzview.cpp | 8 | ||||
-rw-r--r-- | src/gui/undocommands.cpp | 6 | ||||
-rw-r--r-- | src/gui/undocommands.h | 36 |
23 files changed, 1752 insertions, 114 deletions
diff --git a/src/gui/delimitedstringitemdelegate.cpp b/src/gui/delimitedstringitemdelegate.cpp new file mode 100644 index 0000000..7b6c58e --- /dev/null +++ b/src/gui/delimitedstringitemdelegate.cpp @@ -0,0 +1,44 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include "delimitedstringitemdelegate.h" + +#include <QLineEdit> + +DelimitedStringItemDelegate::DelimitedStringItemDelegate(QObject *parent) : QItemDelegate (parent) +{ + _validator = new DelimitedStringValidator(this); +} + +DelimitedStringItemDelegate::~DelimitedStringItemDelegate() +{ +} + +QWidget *DelimitedStringItemDelegate::createEditor( + QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QWidget *editor = QItemDelegate::createEditor(parent, option, index); + + if (QLineEdit *lineEdit = dynamic_cast<QLineEdit*>(editor)) { + lineEdit->setValidator(_validator); + } + + return editor; +} diff --git a/src/gui/delimitedstringitemdelegate.h b/src/gui/delimitedstringitemdelegate.h new file mode 100644 index 0000000..bd1a856 --- /dev/null +++ b/src/gui/delimitedstringitemdelegate.h @@ -0,0 +1,42 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +/*! + * A QItemDelete that attaches a DelimitedStringValidator to any QLineEdit + */ + +#ifndef DELIMITEDSTRINGITEMDELEGATE_H +#define DELIMITEDSTRINGITEMDELEGATE_H + +#include "delimitedstringvalidator.h" + +#include <QWidget> +#include <QItemDelegate> + +class DelimitedStringItemDelegate : public QItemDelegate +{ + Q_OBJECT +public: + DelimitedStringItemDelegate(QObject *parent=nullptr); + virtual ~DelimitedStringItemDelegate() override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; +private: + DelimitedStringValidator *_validator; +}; + +#endif // DELIMITEDSTRINGITEMDELEGATE_H diff --git a/src/gui/exportdialog.cpp b/src/gui/exportdialog.cpp new file mode 100644 index 0000000..bd1ef53 --- /dev/null +++ b/src/gui/exportdialog.cpp @@ -0,0 +1,194 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include "exportdialog.h" +#include "ui_exportdialog.h" + +#include "tikzit.h" + +#include <QFileDialog> +#include <QSettings> +#include <QStandardPaths> + +ExportDialog::ExportDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ExportDialog) +{ + QSettings settings("tikzit", "tikzit"); + ui->setupUi(this); + + QIntValidator *v = new QIntValidator(this); + v->setBottom(1); + ui->width->setValidator(v); + ui->height->setValidator(v); + connect(ui->width, SIGNAL(editingFinished()), + this, SLOT(setHeightFromWidth())); + connect(ui->height, SIGNAL(editingFinished()), + this, SLOT(setWidthFromHeight())); + + PdfDocument *doc = tikzit->previewWindow()->doc(); + if (doc) { + QSize size = doc->size() * 4; + ui->width->blockSignals(true); + ui->height->blockSignals(true); + ui->width->setText(QString::number(size.width())); + ui->height->setText(QString::number(size.height())); + ui->width->blockSignals(false); + ui->height->blockSignals(false); + } + + if (!settings.value("previous-export-file-format").isNull()) { + ui->fileFormat->setCurrentIndex(settings.value("previous-export-file-format").toInt()); + } + + // set a default export file + QString path = (!settings.value("previous-export-file-path").isNull()) ? + settings.value("previous-export-file-path").toString() : + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + + QString suffix; + switch (ui->fileFormat->currentIndex()) { + case PNG: suffix = ".png"; break; + case JPG: suffix = ".jpg"; break; + case PDF: suffix = ".pdf"; break; + } + + QString fileName; + int i = 0; + bool exists = true; + while (exists) { + fileName = path + "/tikzit_image" + QString::number(i) + suffix; + exists = QFileInfo::exists(fileName); + ++i; + } + ui->filePath->setText(QDir::toNativeSeparators(fileName)); +} + +ExportDialog::~ExportDialog() +{ + delete ui; +} + +QString ExportDialog::filePath() +{ + return ui->filePath->text(); +} + +QSize ExportDialog::size() +{ + return QSize(ui->width->text().toInt(), + ui->height->text().toInt()); +} + +ExportDialog::Format ExportDialog::fileFormat() +{ + return static_cast<Format>(ui->fileFormat->currentIndex()); +} + +void ExportDialog::accept() +{ + QSettings settings("tikzit", "tikzit"); + QFileInfo fi(filePath()); + settings.setValue("previous-export-file-path", fi.absolutePath()); + settings.setValue("previous-export-file-format", fileFormat()); + QDialog::accept(); +} + +void ExportDialog::setHeightFromWidth() +{ + if (ui->keepAspect->isChecked()) { + PdfDocument *doc = tikzit->previewWindow()->doc(); + if (doc == nullptr || doc->size().width() == 0 || doc->size().height() == 0) return; + int w = ui->width->text().toInt(); + int h = (w * doc->size().height()) / doc->size().width(); + + ui->height->blockSignals(true); + ui->height->setText(QString::number(h)); + ui->height->blockSignals(false); + } +} + +void ExportDialog::setWidthFromHeight() +{ + if (ui->keepAspect->isChecked()) { + PdfDocument *doc = tikzit->previewWindow()->doc(); + if (doc == nullptr || doc->size().width() == 0 || doc->size().height() == 0) return; + int h = ui->height->text().toInt(); + int w = (h * doc->size().width()) / doc->size().height(); + + ui->width->blockSignals(true); + ui->width->setText(QString::number(w)); + ui->width->blockSignals(false); + } +} + +void ExportDialog::on_keepAspect_stateChanged(int state) +{ + if (state == Qt::Checked) setHeightFromWidth(); +} + +void ExportDialog::on_browseButton_clicked() +{ + QSettings settings("tikzit", "tikzit"); + + QString suffix; + switch (ui->fileFormat->currentIndex()) { + case PNG: suffix = "png"; break; + case JPG: suffix = "jpg"; break; + case PDF: suffix = "pdf"; break; + } + + QFileDialog dialog; + dialog.setDefaultSuffix(suffix); + dialog.setWindowTitle(tr("Export File Path")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setNameFilter(ui->fileFormat->currentText()); + dialog.setFileMode(QFileDialog::AnyFile); + dialog.setLabelText(QFileDialog::Accept, "Select"); + + QFileInfo fi(ui->filePath->text()); + if (!fi.absolutePath().isEmpty()) { + dialog.setDirectory(fi.absolutePath()); + dialog.selectFile(fi.baseName()); + } + + dialog.setOption(QFileDialog::DontUseNativeDialog); + + if (dialog.exec()) { + ui->filePath->setText(QDir::toNativeSeparators(dialog.selectedFiles()[0])); + } +} + +void ExportDialog::on_fileFormat_currentIndexChanged(int f) +{ + ui->width->setEnabled(f != PDF); + ui->height->setEnabled(f != PDF); + ui->keepAspect->setEnabled(f != PDF); + + QString path = ui->filePath->text(); + if (!path.isEmpty()) { + QRegularExpression re("\\.[^.]*$"); + switch (f) { + case PNG: path.replace(re, ".png"); break; + case JPG: path.replace(re, ".jpg"); break; + case PDF: path.replace(re, ".pdf"); break; + } + + ui->filePath->setText(path); + } +} diff --git a/src/gui/exportdialog.h b/src/gui/exportdialog.h new file mode 100644 index 0000000..bcb6879 --- /dev/null +++ b/src/gui/exportdialog.h @@ -0,0 +1,61 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +/*! + * A dialog for exporting a LaTeX-generated preview to PNG, JPG, or PDF. + */ + +#ifndef EXPORTDIALOG_H +#define EXPORTDIALOG_H + +#include <QDialog> + +namespace Ui { +class ExportDialog; +} + +class ExportDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ExportDialog(QWidget *parent = nullptr); + ~ExportDialog() override; + enum Format { + PNG = 0, + JPG = 1, + PDF = 2 + }; + QString filePath(); + QSize size(); + Format fileFormat(); +public slots: + void accept() override; + +protected slots: + void setHeightFromWidth(); + void setWidthFromHeight(); + void on_keepAspect_stateChanged(int state); + void on_browseButton_clicked(); + void on_fileFormat_currentIndexChanged(int f); + +private: + Ui::ExportDialog *ui; +}; + +#endif // EXPORTDIALOG_H diff --git a/src/gui/exportdialog.ui b/src/gui/exportdialog.ui new file mode 100644 index 0000000..82cefdc --- /dev/null +++ b/src/gui/exportdialog.ui @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ExportDialog</class> + <widget class="QDialog" name="ExportDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>394</width> + <height>119</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>Export Image</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>File</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Format</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLineEdit" name="filePath"/> + </item> + <item> + <widget class="QToolButton" name="browseButton"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="fileFormat"> + <item> + <property name="text"> + <string>Portable Network Graphics (*.png)</string> + </property> + </item> + <item> + <property name="text"> + <string>Jpeg Image (*.jpg)</string> + </property> + </item> + <item> + <property name="text"> + <string>Original (*.pdf)</string> + </property> + </item> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Dimensions</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLineEdit" name="width"/> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string> X </string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="height"/> + </item> + </layout> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QCheckBox" name="keepAspect"> + <property name="text"> + <string>Keep aspect ratio</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ExportDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ExportDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/latexprocess.cpp b/src/gui/latexprocess.cpp new file mode 100644 index 0000000..59db9ea --- /dev/null +++ b/src/gui/latexprocess.cpp @@ -0,0 +1,169 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include "latexprocess.h" +#include "tikzit.h" + +#include <QDebug> +#include <QStandardPaths> +#include <QTemporaryDir> +#include <QStringList> +#include <QSettings> + +LatexProcess::LatexProcess(PreviewWindow *preview, QObject *parent) : QObject(parent) +{ + _preview = preview; + _output = preview->outputTextEdit(); + + _proc = new QProcess(this); + _proc->setProcessChannelMode(QProcess::MergedChannels); + _proc->setWorkingDirectory(_workingDir.path()); + + connect(_proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput())); + connect(_proc, SIGNAL(finished(int)), this, SLOT(finished(int))); + + // for debug purposes + //_workingDir.setAutoRemove(false); +} + +void LatexProcess::makePreview(QString tikz) +{ + QSettings settings("tikzit", "tikzit"); + _preview->setStatus(PreviewWindow::Running); + _output->clear(); + + if (!_workingDir.isValid()) { + _output->appendPlainText("COULD NOT WRITE TO TEMP DIR: " + _workingDir.path() + "\n"); + return; + } + + _output->appendPlainText("USING TEMP DIR: " + _workingDir.path() + "\n"); + + QString pdflatex; + + if (settings.value("auto-detect-pdflatex", true).toBool()) { + _output->appendPlainText("SEARCHING FOR pdflatex IN:"); + _output->appendPlainText(qgetenv("PATH")); + _output->appendPlainText("\n"); + pdflatex = QStandardPaths::findExecutable("pdflatex"); + if (pdflatex.isEmpty()) { + // if pdflatex is not in PATH, we are probably on mac or windows, so try common + // install directories. + _output->appendPlainText("NOT FOUND IN PATH, TRYING:"); + + QStringList texDirs; + // common macOS tex directories: + texDirs << "/Library/TeX/texbin"; + texDirs << "/usr/texbin"; + texDirs << "/usr/local/bin"; + texDirs << "/sw/bin"; + + // common windows tex directories + texDirs << "C:\\Program Files\\MiKTeX 2.9\\miktex\\bin"; + texDirs << "C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64"; + texDirs << "C:\\Program Files\\MiKTeX 2.8\\miktex\\bin"; + texDirs << "C:\\Program Files\\MiKTeX 2.8\\miktex\\bin\\x64"; + texDirs << "C:\\Program Files\\MiKTeX 2.7\\miktex\\bin"; + texDirs << "C:\\Program Files\\MiKTeX 2.7\\miktex\\bin\\x64"; + + _output->appendPlainText(texDirs.join(":")); + pdflatex = QStandardPaths::findExecutable("pdflatex", texDirs); + } + + if (pdflatex.isEmpty()) { + _output->appendPlainText("pdflatex NOT FOUND, ABORTING.\n"); + _preview->setStatus(PreviewWindow::Failed); + return; + } else { + _output->appendPlainText("FOUND: " + pdflatex + "\n"); + } + } else { + _output->appendPlainText("USING pdflatex:\n"); + pdflatex = settings.value("pdflatex-path", "/usr/bin/pdflatex").toString(); + _output->appendPlainText(pdflatex + "\n"); + } + + // copy tikzit.sty to preview dir + QFile::copy(":/tex/sample/tikzit.sty", _workingDir.path() + "/tikzit.sty"); + + // write out the file containing the tikz picture + QFile f(_workingDir.path() + "/preview.tex"); + f.open(QIODevice::WriteOnly); + QTextStream tex(&f); + tex << "\\documentclass{article}\n"; + tex << "\\usepackage{tikzit}\n"; + tex << "\\tikzstyle{every picture}=[tikzfig]\n"; + tex << "\\usepackage[graphics,active,tightpage]{preview}\n"; + tex << "\\PreviewEnvironment{tikzpicture}\n"; + + // copy active *.tikzstyles file to preview dir + if (!tikzit->styleFile().isEmpty() && QFile::exists(tikzit->styleFilePath())) { + QFile::copy(tikzit->styleFilePath(), _workingDir.path() + "/" + tikzit->styleFile()); + tex << "\\input{" + tikzit->styleFile() + "}\n"; + + // if there is a *.tikzdefs file with the same basename, copy and include it as well + QFileInfo fi(tikzit->styleFilePath()); + QString defFile = fi.baseName() + ".tikzdefs"; + QString defFilePath = fi.absolutePath() + "/" + defFile; + if (QFile::exists(defFilePath)) { + QFile::copy(defFilePath, _workingDir.path() + "/" + defFile); + tex << "\\input{" + defFile + "}\n"; + } + } + + tex << "\\begin{document}\n\n"; + tex << tikz; + tex << "\n\n\\end{document}\n"; + + f.close(); + _proc->start(pdflatex, + QStringList() + << "-interaction=nonstopmode" + << "-halt-on-error" + << "preview.tex"); + +} + +void LatexProcess::kill() +{ + if (_proc->state() == QProcess::Running) _proc->kill(); +} + +void LatexProcess::readyReadStandardOutput() +{ + QByteArray s = _proc->readAllStandardOutput(); + _output->appendPlainText(s); +} + +void LatexProcess::finished(int exitCode) +{ + QByteArray s = _proc->readAllStandardOutput(); + _output->appendPlainText(s); + + if (exitCode == 0) { + QString pdf = _workingDir.path() + "/preview.pdf"; + _output->appendPlainText("\n\nSUCCESSFULLY GENERATED: " + pdf + "\n"); + _preview->setPdf(pdf); + _preview->setStatus(PreviewWindow::Success); + emit previewFinished(); + } else { + _output->appendPlainText("\n\npdflatex RETURNED AN ERROR\n"); + _preview->setStatus(PreviewWindow::Failed); + emit previewFinished(); + } +} diff --git a/src/gui/latexprocess.h b/src/gui/latexprocess.h new file mode 100644 index 0000000..9853883 --- /dev/null +++ b/src/gui/latexprocess.h @@ -0,0 +1,56 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +/*! + * Run pdflatex and dump its output to the appropriate tab of + * the PreviewWindow. + */ + +#ifndef LATEXPROCESS_H +#define LATEXPROCESS_H + +#include "previewwindow.h" + +#include <QObject> +#include <QProcess> +#include <QTemporaryDir> +#include <QPlainTextEdit> + +class LatexProcess : public QObject +{ + Q_OBJECT +public: + explicit LatexProcess(PreviewWindow *preview, QObject *parent = nullptr); + void makePreview(QString tikz); + void kill(); + +private: + QTemporaryDir _workingDir; + PreviewWindow *_preview; + QPlainTextEdit *_output; + QProcess *_proc; + +public slots: + void readyReadStandardOutput(); + void finished(int exitCode); + +signals: + void previewFinished(); +}; + +#endif // LATEXPROCESS_H diff --git a/src/gui/mainmenu.cpp b/src/gui/mainmenu.cpp index 8166c59..6f4f8db 100644 --- a/src/gui/mainmenu.cpp +++ b/src/gui/mainmenu.cpp @@ -17,6 +17,7 @@ */ #include "mainmenu.h" +#include "preferencedialog.h" #include "tikzit.h" #include <QDebug> @@ -33,6 +34,8 @@ MainMenu::MainMenu() ui.actionCheck_for_updates_automatically->setChecked(settings.value("check-for-updates").toBool()); ui.actionCheck_for_updates_automatically->blockSignals(false); } + + updateRecentFiles(); } void MainMenu::addDocks(QMenu *m) @@ -48,6 +51,31 @@ QAction *MainMenu::updatesAction() return ui.actionCheck_for_updates_automatically; } +void MainMenu::updateRecentFiles() +{ + QSettings settings("tikzit", "tikzit"); + ui.menuOpen_Recent->clear(); + + QStringList recentFiles = settings.value("recent-files").toStringList(); + //qDebug() << "update:" << recentFiles; + + QAction *action; + foreach (QString f, recentFiles) { + QFileInfo fi(f); + action = new QAction(fi.fileName(), ui.menuOpen_Recent); + action->setData(f); + ui.menuOpen_Recent->addAction(action); + connect(action, SIGNAL(triggered()), + this, SLOT(openRecent())); + } + + ui.menuOpen_Recent->addSeparator(); + action = new QAction("Clear List", ui.menuOpen_Recent); + connect(action, SIGNAL(triggered()), + tikzit, SLOT(clearRecentFiles())); + ui.menuOpen_Recent->addAction(action); +} + // File void MainMenu::on_actionNew_triggered() { @@ -82,6 +110,15 @@ void MainMenu::on_actionExit_triggered() tikzit->quit(); } +void MainMenu::openRecent() +{ + if (sender() != nullptr) { + if (QAction *action = dynamic_cast<QAction*>(sender())) { + tikzit->open(action->data().toString()); + } + } +} + // Edit void MainMenu::on_actionUndo_triggered() @@ -228,6 +265,18 @@ void MainMenu::on_actionJump_to_Selection_triggered() } } +void MainMenu::on_actionRun_LaTeX_triggered() +{ + tikzit->makePreview(); +} + +void MainMenu::on_actionPreferences_triggered() +{ + PreferenceDialog *d = new PreferenceDialog(this); + d->exec(); + d->deleteLater(); +} + // View void MainMenu::on_actionZoom_In_triggered() @@ -260,5 +309,5 @@ void MainMenu::on_actionCheck_for_updates_automatically_triggered() void MainMenu::on_actionCheck_now_triggered() { - tikzit->checkForUpdates(); + tikzit->checkForUpdates(true); } diff --git a/src/gui/mainmenu.h b/src/gui/mainmenu.h index c14a284..4d672cd 100644 --- a/src/gui/mainmenu.h +++ b/src/gui/mainmenu.h @@ -30,6 +30,7 @@ public: MainMenu(); void addDocks(QMenu *m); QAction *updatesAction(); + void updateRecentFiles(); private: Ui::MainMenu ui; @@ -43,6 +44,8 @@ public slots: void on_actionSave_As_triggered(); void on_actionExit_triggered(); + void openRecent(); + // Edit void on_actionUndo_triggered(); void on_actionRedo_triggered(); @@ -63,10 +66,12 @@ public slots: void on_actionExtendLeft_triggered(); void on_actionExtendRight_triggered(); - // Tikz + // Tools void on_actionParse_triggered(); void on_actionRevert_triggered(); void on_actionJump_to_Selection_triggered(); + void on_actionRun_LaTeX_triggered(); + void on_actionPreferences_triggered(); // View void on_actionZoom_In_triggered(); diff --git a/src/gui/mainmenu.ui b/src/gui/mainmenu.ui index 0481c1d..08067aa 100644 --- a/src/gui/mainmenu.ui +++ b/src/gui/mainmenu.ui @@ -14,8 +14,14 @@ <property name="title"> <string>File</string> </property> + <widget class="QMenu" name="menuOpen_Recent"> + <property name="title"> + <string>Open Recent</string> + </property> + </widget> <addaction name="actionNew"/> <addaction name="actionOpen"/> + <addaction name="menuOpen_Recent"/> <addaction name="separator"/> <addaction name="actionClose"/> <addaction name="actionSave"/> @@ -69,11 +75,14 @@ </widget> <widget class="QMenu" name="menuTikz"> <property name="title"> - <string>Tikz</string> + <string>Tools</string> </property> <addaction name="actionParse"/> <addaction name="actionRevert"/> <addaction name="actionJump_to_Selection"/> + <addaction name="actionRun_LaTeX"/> + <addaction name="separator"/> + <addaction name="actionPreferences"/> </widget> <widget class="QMenu" name="menuView"> <property name="title"> @@ -197,7 +206,7 @@ </action> <action name="actionParse"> <property name="text"> - <string>Parse Tikz</string> + <string>Parse TikZ</string> </property> <property name="shortcut"> <string>Ctrl+T</string> @@ -226,7 +235,10 @@ </action> <action name="actionRevert"> <property name="text"> - <string>Revert Tikz</string> + <string>Revert TikZ</string> + </property> + <property name="shortcut"> + <string>Ctrl+Alt+T</string> </property> </action> <action name="actionJump_to_Selection"> @@ -335,6 +347,24 @@ <string>About</string> </property> </action> + <action name="actionRun_LaTeX"> + <property name="text"> + <string>Make Preview</string> + </property> + <property name="shortcut"> + <string>Ctrl+R</string> + </property> + </action> + <action name="actionClear_Menu"> + <property name="text"> + <string>Clear Menu</string> + </property> + </action> + <action name="actionPreferences"> + <property name="text"> + <string>Preferences...</string> + </property> + </action> <addaction name="menuFile"/> <addaction name="menuEdit"/> <addaction name="menuView"/> diff --git a/src/gui/preferencedialog.cpp b/src/gui/preferencedialog.cpp new file mode 100644 index 0000000..06159af --- /dev/null +++ b/src/gui/preferencedialog.cpp @@ -0,0 +1,111 @@ +#include "preferencedialog.h" +#include "ui_preferencedialog.h" + +#include <QColorDialog> +#include <QFileDialog> +#include <QSettings> + +PreferenceDialog::PreferenceDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PreferenceDialog) +{ + ui->setupUi(this); + QSettings settings("tikzit", "tikzit"); + ui->autoPdflatex->setChecked(true); + + if (!settings.value("auto-detect-pdflatex").isNull()) + ui->autoPdflatex->setChecked(settings.value("auto-detect-pdflatex").toBool()); + if (!settings.value("pdflatex-path").isNull()) + ui->pdflatexPath->setText(settings.value("pdflatex-path").toString()); + + + setColor(ui->axesColor, settings.value("grid-color-axes", + QColor(220,220,240)).value<QColor>()); + setColor(ui->majorColor, settings.value("grid-color-major", + QColor(240,240,250)).value<QColor>()); + setColor(ui->minorColor, settings.value("grid-color-minor", + QColor(250,250,255)).value<QColor>()); + + + connect(ui->axesColor, SIGNAL(clicked()), this, SLOT(colorClick())); + connect(ui->majorColor, SIGNAL(clicked()), this, SLOT(colorClick())); + connect(ui->minorColor, SIGNAL(clicked()), this, SLOT(colorClick())); +} + +PreferenceDialog::~PreferenceDialog() +{ + delete ui; +} + +void PreferenceDialog::accept() +{ + QSettings settings("tikzit", "tikzit"); + settings.setValue("auto-detect-pdflatex", ui->autoPdflatex->isChecked()); + settings.setValue("pdflatex-path", ui->pdflatexPath->text()); + settings.setValue("grid-color-axes", color(ui->axesColor)); + settings.setValue("grid-color-major", color(ui->majorColor)); + settings.setValue("grid-color-minor", color(ui->minorColor)); + QDialog::accept(); +} + +void PreferenceDialog::on_resetColors_clicked() +{ + setColor(ui->axesColor, QColor(220,220,240)); + setColor(ui->majorColor, QColor(240,240,250)); + setColor(ui->minorColor, QColor(250,250,255)); +} + +void PreferenceDialog::colorClick() +{ + if (QPushButton *btn = dynamic_cast<QPushButton*>(sender())) { + QColor col = QColorDialog::getColor( + color(btn), + this, + "Set color", + QColorDialog::DontUseNativeDialog); + if (col.isValid()) setColor(btn, col); + } +} + +void PreferenceDialog::on_autoPdflatex_stateChanged(int state) +{ + ui->pdflatexPath->setEnabled(state != Qt::Checked); + ui->browsePdflatex->setEnabled(state != Qt::Checked); +} + +void PreferenceDialog::on_browsePdflatex_clicked() +{ + QSettings settings("tikzit", "tikzit"); + + QFileDialog dialog; + dialog.setWindowTitle(tr("pdflatex Path")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setLabelText(QFileDialog::Accept, "Select"); + + QFileInfo fi(ui->pdflatexPath->text()); + if (!fi.absolutePath().isEmpty()) { + dialog.setDirectory(fi.absolutePath()); + dialog.selectFile(fi.baseName()); + } + + dialog.setOption(QFileDialog::DontUseNativeDialog); + + if (dialog.exec()) { + ui->pdflatexPath->setText(QDir::toNativeSeparators(dialog.selectedFiles()[0])); + } +} + +void PreferenceDialog::setColor(QPushButton *btn, QColor col) +{ + QPalette pal = btn->palette(); + pal.setColor(QPalette::Button, col); + btn->setPalette(pal); + btn->update(); +} + +QColor PreferenceDialog::color(QPushButton *btn) +{ + QPalette pal = btn->palette(); + return pal.color(QPalette::Button); +} diff --git a/src/gui/preferencedialog.h b/src/gui/preferencedialog.h new file mode 100644 index 0000000..9da8ae6 --- /dev/null +++ b/src/gui/preferencedialog.h @@ -0,0 +1,31 @@ +#ifndef PREFERENCEDIALOG_H +#define PREFERENCEDIALOG_H + +#include <QDialog> + +namespace Ui { +class PreferenceDialog; +} + +class PreferenceDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PreferenceDialog(QWidget *parent = nullptr); + ~PreferenceDialog() override; + +protected slots: + void accept() override; + void colorClick(); + void on_resetColors_clicked(); + void on_autoPdflatex_stateChanged(int state); + void on_browsePdflatex_clicked(); + +private: + Ui::PreferenceDialog *ui; + QColor color(QPushButton *btn); + void setColor(QPushButton *btn, QColor col); +}; + +#endif // PREFERENCEDIALOG_H diff --git a/src/gui/preferencedialog.ui b/src/gui/preferencedialog.ui new file mode 100644 index 0000000..9a32e7d --- /dev/null +++ b/src/gui/preferencedialog.ui @@ -0,0 +1,272 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PreferenceDialog</class> + <widget class="QDialog" name="PreferenceDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>345</width> + <height>176</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>pdflatex Location</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLineEdit" name="pdflatexPath"/> + </item> + <item> + <widget class="QToolButton" name="browsePdflatex"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="autoPdflatex"> + <property name="text"> + <string>Automatically detect pdflatex</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Grid colors</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QFrame" name="frame"> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="axesColor"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Axes</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QFrame" name="frame_2"> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="majorColor"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Major</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QFrame" name="frame_3"> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="minorColor"> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <property name="text"> + <string/> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Minor</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="resetColors"> + <property name="text"> + <string>Reset colors</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PreferenceDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>PreferenceDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/gui/previewwindow.cpp b/src/gui/previewwindow.cpp new file mode 100644 index 0000000..2f47efd --- /dev/null +++ b/src/gui/previewwindow.cpp @@ -0,0 +1,208 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#include "previewwindow.h" +#include "ui_previewwindow.h" + +#include "tikzit.h" +#include "latexprocess.h" +#include "exportdialog.h" + +#include <QLabel> +#include <QImage> +#include <QPixmap> +#include <QDebug> +#include <QSettings> +#include <QTemporaryDir> +#include <QFile> +#include <QTextStream> +#include <QStandardPaths> +#include <QMessageBox> +#include <cmath> +#include <QMovie> +#include <QAction> + +PreviewWindow::PreviewWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::PreviewWindow) +{ + QSettings settings("tikzit", "tikzit"); + ui->setupUi(this); + + QVariant geom = settings.value("geometry-preview"); + + if (geom.isValid()) { + restoreGeometry(geom.toByteArray()); + } + + _doc = nullptr; + + _loader = new QLabel(ui->tabWidget->tabBar()); + _loader->setMinimumSize(QSize(16,16)); + _loader->setMaximumSize(QSize(16,16)); + _loader->setAutoFillBackground(false); + ui->tabWidget->tabBar()->setTabButton(1, QTabBar::RightSide, _loader); + + connect(ui->tabWidget, SIGNAL(currentChanged(int)), + this, SLOT(render())); + + render(); +} + +void PreviewWindow::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu menu(this); + QAction *act; + + act = new QAction("Export Image..."); + connect(act, SIGNAL(triggered()), this, SLOT(exportImage())); + menu.addAction(act); + + act = new QAction("Copy to Clipboard"); + connect(act, SIGNAL(triggered()), this, SLOT(copyImageToClipboard())); + menu.addAction(act); + + menu.exec(event->globalPos()); +} + +PdfDocument *PreviewWindow::doc() const +{ + return _doc; +} + +PreviewWindow::~PreviewWindow() +{ + delete ui; +} + +void PreviewWindow::setPdf(QString file) +{ + // use loadFromData to avoid holding a lock on the PDF file in windows + //QFile f(file); + //f.open(QFile::ReadOnly); + //QByteArray data = f.readAll(); + //f.close(); + PdfDocument *newDoc = new PdfDocument(file, this); + + if (newDoc->isValid()) { + PdfDocument *oldDoc = _doc; + _doc = newDoc; + if (oldDoc != nullptr) delete oldDoc; + render(); + } else { + QMessageBox::warning(nullptr, + "Could not read PDF", + "Could not read: '" + file + "'."); + delete newDoc; + } +} + +QPlainTextEdit *PreviewWindow::outputTextEdit() +{ + return ui->output; +} + +void PreviewWindow::setStatus(PreviewWindow::Status status) +{ + QMovie *oldMovie = _loader->movie(); + if (status == PreviewWindow::Running) { + // loader.gif and loader@2x.gif derived from: + // https://commons.wikimedia.org/wiki/Throbbers#/media/File:Linux_Ubuntu_Loader.gif + // licensed GNU Free Documentation License v1.2 + QMovie *movie = new QMovie( + (devicePixelRatioF() > 1.0) ? ":images/loader@2x.gif" : ":images/loader.gif", + QByteArray(), _loader); + _loader->setPixmap(QPixmap()); + _loader->setMovie(movie); + movie->start(); + } else if (status == PreviewWindow::Success) { + _loader->setMovie(nullptr); + QIcon accept(":images/dialog-accept.svg"); + //accept.setDevicePixelRatio(devicePixelRatio()); + _loader->setPixmap(accept.pixmap(QSize(16,16))); + } else if (status == PreviewWindow::Failed) { + _loader->setMovie(nullptr); + QIcon error(":images/dialog-error.svg"); + //error.setDevicePixelRatio(devicePixelRatio()); + _loader->setPixmap(error.pixmap(QSize(16,16))); + } + + if (oldMovie != nullptr) oldMovie->deleteLater(); + + + _loader->repaint(); +} + +void PreviewWindow::closeEvent(QCloseEvent *e) { + QSettings settings("tikzit", "tikzit"); + settings.setValue("geometry-preview", saveGeometry()); + QDialog::closeEvent(e); +} + +void PreviewWindow::resizeEvent(QResizeEvent *e) { + render(); + QDialog::resizeEvent(e); +} + +void PreviewWindow::showEvent(QShowEvent *e) { + render(); + QDialog::showEvent(e); +} + +void PreviewWindow::render() { + if (_doc != nullptr) { + _doc->renderTo(ui->pdf, + ui->scrollArea->visibleRegion().boundingRect()); + ui->pdf->repaint(); + } +} + +void PreviewWindow::exportImage() +{ + QSettings settings("tikzit", "tikzit"); + if (_doc == nullptr) return; + ExportDialog *d = new ExportDialog(this); + int ret = d->exec(); + if (ret == QDialog::Accepted) { + bool success; + if (d->fileFormat() == ExportDialog::PDF) { + success = _doc->exportPdf(d->filePath()); + } else { + success = _doc->exportImage( + d->filePath(), + (d->fileFormat() == ExportDialog::PNG) ? "PNG" : "JPG", + d->size()); + } + + if (!success) { + QMessageBox::warning(this, + "Error", + "Could not write to: '" + d->filePath() + + "'. Check file permissions or choose a new location."); + } + } +} + +void PreviewWindow::copyImageToClipboard() +{ + if (_doc != nullptr) { + _doc->copyImageToClipboard(_doc->size() * 4); + } +} + + diff --git a/src/gui/previewwindow.h b/src/gui/previewwindow.h new file mode 100644 index 0000000..a14303b --- /dev/null +++ b/src/gui/previewwindow.h @@ -0,0 +1,72 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +/*! + * Displays a LaTeX-generated PDF preview using Poppler. The right-click + * menu has options for exporting to file or clipboard. + */ + +#ifndef PREVIEWWINDOW_H +#define PREVIEWWINDOW_H + +#include "pdfdocument.h" + +#include <QDialog> +#include <QLabel> +#include <QPlainTextEdit> +#include <QContextMenuEvent> +#include <poppler/qt5/poppler-qt5.h> + +namespace Ui { +class PreviewWindow; +} + +class PreviewWindow : public QDialog +{ + Q_OBJECT + +public: + enum Status { + Running, Success, Failed + }; + explicit PreviewWindow(QWidget *parent = nullptr); + ~PreviewWindow() override; + void setPdf(QString file); + QString preparePreview(QString tikz); + QPlainTextEdit *outputTextEdit(); + void setStatus(Status status); + + PdfDocument *doc() const; + +public slots: + void render(); + void exportImage(); + void copyImageToClipboard(); + +protected: + void resizeEvent(QResizeEvent *e) override; + void showEvent(QShowEvent *e) override; + void closeEvent(QCloseEvent *e) override; + void contextMenuEvent(QContextMenuEvent *event) override; +private: + Ui::PreviewWindow *ui; + PdfDocument *_doc; + QLabel *_loader; +}; + +#endif // PREVIEWWINDOW_H diff --git a/src/gui/previewwindow.ui b/src/gui/previewwindow.ui new file mode 100644 index 0000000..aa49980 --- /dev/null +++ b/src/gui/previewwindow.ui @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PreviewWindow</class> + <widget class="QDialog" name="PreviewWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>603</width> + <height>480</height> + </rect> + </property> + <property name="windowTitle"> + <string>Preview</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <property name="documentMode"> + <bool>true</bool> + </property> + <property name="tabsClosable"> + <bool>false</bool> + </property> + <widget class="QWidget" name="pdfTab"> + <attribute name="title"> + <string>PDF</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>595</width> + <height>451</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLabel" name="pdf"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="outputTab"> + <attribute name="title"> + <string>Output</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QPlainTextEdit" name="output"/> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/gui/styleeditor.cpp b/src/gui/styleeditor.cpp index 29192d6..e2ade45 100644 --- a/src/gui/styleeditor.cpp +++ b/src/gui/styleeditor.cpp @@ -1,10 +1,30 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + #include <QColorDialog> #include <QDebug> #include <QMessageBox> #include "tikzit.h" #include "styleeditor.h" +#include "delimitedstringvalidator.h" #include "ui_styleeditor.h" +#include "delimitedstringitemdelegate.h" StyleEditor::StyleEditor(QWidget *parent) : QMainWindow(parent), @@ -18,6 +38,14 @@ StyleEditor::StyleEditor(QWidget *parent) : ui->leftArrow << ui->rightArrow << ui->properties; + DelimitedStringValidator *v = new DelimitedStringValidator(this); + ui->name->setValidator(v); + ui->category->lineEdit()->setValidator(v); + ui->shape->lineEdit()->setValidator(v); + + DelimitedStringItemDelegate *delegate = new DelimitedStringItemDelegate(ui->properties); + ui->properties->setItemDelegate(delegate); + setWindowIcon(QIcon(":/images/tikzit.png")); _styles = nullptr; _activeStyle = nullptr; @@ -44,40 +72,6 @@ StyleEditor::StyleEditor(QWidget *parent) : SIGNAL(currentIndexChanged(int)), this, SLOT(shapeChanged())); - // setup the color dialog to display only the named colors that tikzit/xcolor knows - // about as "standard colors". - for (int i = 0; i < 48; ++i) { - QColorDialog::setStandardColor(i, QColor(Qt::white)); - } - - // grayscale in column 1 - int pos = 0; - for (int i=0; i < 5; ++i) { - QColorDialog::setStandardColor(pos, tikzit->colorByIndex(i)); - pos += 1; - } - - // rainbow in column 2 - pos = 6; - for (int i=5; i < 11; ++i) { - QColorDialog::setStandardColor(pos, tikzit->colorByIndex(i)); - pos += 1; - } - - // brown/green/teal spectrum in column 3 - pos = 12; - for (int i=11; i < 16; ++i) { - QColorDialog::setStandardColor(pos, tikzit->colorByIndex(i)); - pos += 1; - } - - // pinks in column 4 - pos = 18; - for (int i=16; i < 19; ++i) { - QColorDialog::setStandardColor(pos, tikzit->colorByIndex(i)); - pos += 1; - } - refreshDisplay(); } diff --git a/src/gui/styleeditor.h b/src/gui/styleeditor.h index 4bae7db..2c35d56 100644 --- a/src/gui/styleeditor.h +++ b/src/gui/styleeditor.h @@ -1,3 +1,25 @@ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +/*! + * A GUI editor for .tikzstyles files. + */ + #ifndef STYLEEDITOR_H #define STYLEEDITOR_H @@ -17,8 +39,8 @@ class StyleEditor : public QMainWindow Q_OBJECT public: - explicit StyleEditor(QWidget *parent = 0); - ~StyleEditor(); + explicit StyleEditor(QWidget *parent = nullptr); + ~StyleEditor() override; void open(); void save(); diff --git a/src/gui/tikzscene.cpp b/src/gui/tikzscene.cpp index c061221..31d5bf6 100644 --- a/src/gui/tikzscene.cpp +++ b/src/gui/tikzscene.cpp @@ -28,14 +28,15 @@ #include <QClipboard> #include <QInputDialog> #include <cmath> +#include <delimitedstringvalidator.h> TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent) : QGraphicsScene(parent), _tikzDocument(tikzDocument), _tools(tools), _styles(styles) { - _modifyEdgeItem = 0; - _edgeStartNodeItem = 0; + _modifyEdgeItem = nullptr; + _edgeStartNodeItem = nullptr; _drawEdgeItem = new QGraphicsLineItem(); _rubberBandItem = new QGraphicsRectItem(); _enabled = true; @@ -43,7 +44,7 @@ TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, setSceneRect(-1000,-1000,2000,2000); QPen pen; - pen.setColor(QColor::fromRgbF(0.5f, 0.0f, 0.5f)); + pen.setColor(QColor::fromRgbF(0.5, 0.0, 0.5)); //pen.setWidth(3.0f); pen.setCosmetic(true); _drawEdgeItem->setPen(pen); @@ -51,7 +52,7 @@ TikzScene::TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, _drawEdgeItem->setVisible(false); addItem(_drawEdgeItem); - pen.setColor(QColor::fromRgbF(0.6f, 0.6f, 0.8f)); + pen.setColor(QColor::fromRgbF(0.6, 0.6, 0.8)); //pen.setWidth(3.0f); //QVector<qreal> dash; //dash << 4.0 << 4.0; @@ -110,7 +111,7 @@ void TikzScene::graphReplaced() void TikzScene::extendSelectionUp() { bool found = false; - float m = 0.0f; + qreal m = 0.0; foreach (Node *n, getSelectedNodes()) { if (!found) { m = n->point().y(); @@ -128,7 +129,7 @@ void TikzScene::extendSelectionUp() void TikzScene::extendSelectionDown() { bool found = false; - float m = 0.0f; + qreal m = 0.0; foreach (Node *n, getSelectedNodes()) { if (!found) { m = n->point().y(); @@ -146,7 +147,7 @@ void TikzScene::extendSelectionDown() void TikzScene::extendSelectionLeft() { bool found = false; - float m = 0.0f; + qreal m = 0.0; foreach (Node *n, getSelectedNodes()) { if (!found) { m = n->point().x(); @@ -164,7 +165,7 @@ void TikzScene::extendSelectionLeft() void TikzScene::extendSelectionRight() { bool found = false; - float m = 0.0f; + qreal m = 0.0; foreach (Node *n, getSelectedNodes()) { if (!found) { m = n->point().x(); @@ -266,7 +267,7 @@ void TikzScene::mousePressEvent(QGraphicsSceneMouseEvent *event) } } - if (_modifyEdgeItem != 0) { + if (_modifyEdgeItem != nullptr) { // store for undo purposes Edge *e = _modifyEdgeItem->edge(); _oldBend = e->bend(); @@ -337,15 +338,15 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) switch (_tools->currentTool()) { case ToolPalette::SELECT: - if (_modifyEdgeItem != 0) { + if (_modifyEdgeItem != nullptr) { Edge *e = _modifyEdgeItem->edge(); // dragging a control point QPointF src = toScreen(e->source()->point()); QPointF targ = toScreen(e->target()->point()); - float dx1 = targ.x() - src.x(); - float dy1 = targ.y() - src.y(); - float dx2, dy2; + qreal dx1 = targ.x() - src.x(); + qreal dy1 = targ.y() - src.y(); + qreal dx2, dy2; if (_firstControlPoint) { dx2 = mousePos.x() - src.x(); dy2 = mousePos.y() - src.y(); @@ -354,25 +355,26 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) dy2 = mousePos.y() - targ.y(); } - float baseDist = sqrt(dx1*dx1 + dy1*dy1); - float handleDist = sqrt(dx2*dx2 + dy2*dy2); - float wcoarseness = 0.1f; + qreal baseDist = sqrt(dx1*dx1 + dy1*dy1); + qreal handleDist = sqrt(dx2*dx2 + dy2*dy2); + qreal wcoarseness = 0.1; if (!e->isSelfLoop()) { - if (baseDist != 0) { + if (baseDist != 0.0) { e->setWeight(roundToNearest(wcoarseness, handleDist/baseDist)); } else { e->setWeight(roundToNearest(wcoarseness, handleDist/GLOBAL_SCALEF)); } } - float control_angle = atan2(-dy2, dx2); + qreal control_angle = atan2(-dy2, dx2); int bcoarseness = 15; + qreal bcoarsenessi = 1.0/15.0; if(e->basicBendMode()) { - float bnd; - float base_angle = atan2(-dy1, dx1); + qreal bnd; + qreal base_angle = atan2(-dy1, dx1); if (_firstControlPoint) { bnd = base_angle - control_angle; } else { @@ -380,12 +382,10 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (bnd > M_PI) bnd -= 2*M_PI; } - e->setBend(round(bnd * (180.0f / M_PI) * (1.0f / (float)bcoarseness)) * bcoarseness); + e->setBend(static_cast<int>(round(bnd * (180.0 / M_PI) * bcoarsenessi)) * bcoarseness); } else { - int bnd = round(control_angle * (180.0f / M_PI) * - (1.0f / (float)bcoarseness)) * - bcoarseness; + int bnd = static_cast<int>(round(control_angle * (180.0 / M_PI) * bcoarsenessi)) * bcoarseness; if (_firstControlPoint) { // TODO: enable moving both control points // if ([theEvent modifierFlags] & NSAlternateKeyMask) { @@ -428,7 +428,7 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) NodeItem *ni = _nodeItems[n]; // in (rare) cases, the graph can change while we are dragging - if (ni != 0) { + if (ni != nullptr) { ni->setPos(toScreen(_oldNodePositions[n]) + shift); ni->writePos(); } @@ -454,7 +454,7 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) break; case ToolPalette::EDGE: if (_drawEdgeItem->isVisible()) { - _edgeEndNodeItem = 0; + _edgeEndNodeItem = nullptr; foreach (QGraphicsItem *gi, items(mousePos)) { if (NodeItem *ni = dynamic_cast<NodeItem*>(gi)){ _edgeEndNodeItem = ni; @@ -462,7 +462,7 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } QPointF p1 = _drawEdgeItem->line().p1(); - QPointF p2 = (_edgeEndNodeItem != 0) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos; + QPointF p2 = (_edgeEndNodeItem != nullptr) ? toScreen(_edgeEndNodeItem->node()->point()) : mousePos; QLineF line(p1, p2); _drawEdgeItem->setLine(line); @@ -482,11 +482,11 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) switch (_tools->currentTool()) { case ToolPalette::SELECT: - if (_modifyEdgeItem != 0) { + if (_modifyEdgeItem != nullptr) { // finished dragging a control point Edge *e = _modifyEdgeItem->edge(); - if (_oldWeight != e->weight() || + if (!almostEqual(_oldWeight, e->weight()) || _oldBend != e->bend() || _oldInAngle != e->inAngle() || _oldOutAngle != e->outAngle()) @@ -495,7 +495,7 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) _tikzDocument->undoStack()->push(cmd); } - _modifyEdgeItem = 0; + _modifyEdgeItem = nullptr; } else { // otherwise, process mouse move normally QGraphicsScene::mouseReleaseEvent(event); @@ -517,7 +517,7 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QPointF shift = mousePos - _mouseDownPos; shift = QPointF(round(shift.x()/GRID_SEP)*GRID_SEP, round(shift.y()/GRID_SEP)*GRID_SEP); - if (shift.x() != 0 || shift.y() != 0) { + if (shift.x() != 0.0 || shift.y() != 0.0) { QMap<Node*,QPointF> newNodePositions; foreach (QGraphicsItem *gi, selectedItems()) { @@ -557,14 +557,14 @@ void TikzScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) break; case ToolPalette::EDGE: // add an edge - if (_edgeStartNodeItem != 0 && _edgeEndNodeItem != 0) { + if (_edgeStartNodeItem != nullptr && _edgeEndNodeItem != nullptr) { Edge *e = new Edge(_edgeStartNodeItem->node(), _edgeEndNodeItem->node(), _tikzDocument); e->setStyleName(_styles->activeEdgeStyleName()); AddEdgeCommand *cmd = new AddEdgeCommand(this, e); _tikzDocument->undoStack()->push(cmd); } - _edgeStartNodeItem = 0; - _edgeEndNodeItem = 0; + _edgeStartNodeItem = nullptr; + _edgeEndNodeItem = nullptr; _drawEdgeItem->setVisible(false); break; case ToolPalette::CROP: @@ -613,19 +613,19 @@ void TikzScene::keyPressEvent(QKeyEvent *event) if (event->modifiers() & Qt::ControlModifier) { QPointF delta(0,0); - float shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0f : 10.0f; + qreal shift = (event->modifiers() & Qt::ShiftModifier) ? 1.0 : 10.0; switch(event->key()) { case Qt::Key_Left: - delta.setX(-0.025f * shift); + delta.setX(-0.025 * shift); break; case Qt::Key_Right: - delta.setX(0.025f * shift); + delta.setX(0.025 * shift); break; case Qt::Key_Up: - delta.setY(0.025f * shift); + delta.setY(0.025 * shift); break; case Qt::Key_Down: - delta.setY(-0.025f * shift); + delta.setY(-0.025 * shift); break; } @@ -665,16 +665,23 @@ void TikzScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) } break; } else if (NodeItem *ni = dynamic_cast<NodeItem*>(it)) { - bool ok; - QString newLabel = QInputDialog::getText(views()[0], tr("Node label"), - tr("Label:"), QLineEdit::Normal, - ni->node()->label(), &ok); - if (ok) { + QInputDialog *d = new QInputDialog(views()[0]); + d->setLabelText(tr("Label:")); + d->setTextValue(ni->node()->label()); + d->setWindowTitle(tr("Node label")); + + if (QLineEdit *le = d->findChild<QLineEdit*>()) { + le->setValidator(new DelimitedStringValidator(le)); + } + + if (d->exec()) { QMap<Node*,QString> oldLabels; oldLabels.insert(ni->node(), ni->node()->label()); - ChangeLabelCommand *cmd = new ChangeLabelCommand(this, oldLabels, newLabel); + ChangeLabelCommand *cmd = new ChangeLabelCommand(this, oldLabels, d->textValue()); _tikzDocument->undoStack()->push(cmd); } + + d->deleteLater(); break; } } @@ -767,7 +774,7 @@ void TikzScene::pasteFromClipboard() QRectF srcRect = g->realBbox(); QRectF tgtRect = graph()->realBbox(); - QPointF shift(tgtRect.right() - srcRect.left(), 0.0f); + QPointF shift(tgtRect.right() - srcRect.left(), 0.0); if (shift.x() > 0) { foreach (Node *n, g->nodes()) { @@ -890,7 +897,7 @@ void TikzScene::refreshAdjacentEdges(QList<Node*> nodes) EdgeItem *ei = _edgeItems[e]; // the list "nodes" can be out of date, e.g. if the graph changes while dragging - if (ei != 0) { + if (ei != nullptr) { if (nodes.contains(ei->edge()->source()) || nodes.contains(ei->edge()->target())) { ei->edge()->updateControls(); ei->readPos(); diff --git a/src/gui/tikzscene.h b/src/gui/tikzscene.h index 2a3e988..e8ea2c6 100644 --- a/src/gui/tikzscene.h +++ b/src/gui/tikzscene.h @@ -44,7 +44,7 @@ class TikzScene : public QGraphicsScene Q_OBJECT public: TikzScene(TikzDocument *tikzDocument, ToolPalette *tools, StylePalette *styles, QObject *parent); - ~TikzScene(); + ~TikzScene() override; Graph *graph(); QMap<Node*,NodeItem*> &nodeItems(); QMap<Edge*,EdgeItem*> &edgeItems(); @@ -108,7 +108,7 @@ private: bool _draggingNodes; QMap<Node*,QPointF> _oldNodePositions; - float _oldWeight; + qreal _oldWeight; int _oldBend; int _oldInAngle; int _oldOutAngle; diff --git a/src/gui/tikzview.cpp b/src/gui/tikzview.cpp index 52a32cf..5b0f09c 100644 --- a/src/gui/tikzview.cpp +++ b/src/gui/tikzview.cpp @@ -21,6 +21,7 @@ #include <QDebug> #include <QScrollBar> +#include <QSettings> TikzView::TikzView(QWidget *parent) : QGraphicsView(parent) { @@ -53,6 +54,7 @@ void TikzView::setScene(QGraphicsScene *scene) void TikzView::drawBackground(QPainter *painter, const QRectF &rect) { + QSettings settings("tikzit", "tikzit"); QGraphicsView::drawBackground(painter, rect); // draw a gray background if disabled TikzScene *sc = static_cast<TikzScene*>(scene()); @@ -63,13 +65,13 @@ void TikzView::drawBackground(QPainter *painter, const QRectF &rect) QPen pen1; //pen1.setWidthF(0.5); pen1.setCosmetic(true); - pen1.setColor(QColor(250,250,255)); + pen1.setColor(settings.value("grid-color-minor", QColor(250,250,255)).value<QColor>()); QPen pen2 = pen1; - pen2.setColor(QColor(240,240,250)); + pen2.setColor(settings.value("grid-color-major", QColor(240,240,250)).value<QColor>()); QPen pen3 = pen1; - pen3.setColor(QColor(220,220,240)); + pen3.setColor(settings.value("grid-color-axes", QColor(220,220,240)).value<QColor>()); painter->setPen(pen1); diff --git a/src/gui/undocommands.cpp b/src/gui/undocommands.cpp index f713582..8a00536 100644 --- a/src/gui/undocommands.cpp +++ b/src/gui/undocommands.cpp @@ -80,7 +80,7 @@ void MoveCommand::redo() } EdgeBendCommand::EdgeBendCommand(TikzScene *scene, Edge *edge, - float oldWeight, int oldBend, + qreal oldWeight, int oldBend, int oldInAngle, int oldOutAngle, QUndoCommand *parent) : GraphUpdateCommand(scene, parent), _edge(edge), @@ -405,7 +405,7 @@ void ChangeLabelCommand::undo() foreach (Node *n, _oldLabels.keys()) { n->setLabel(_oldLabels[n]); NodeItem *ni = _scene->nodeItems()[n]; - if (ni != 0) ni->updateBounds(); + if (ni != nullptr) ni->updateBounds(); } GraphUpdateCommand::undo(); @@ -416,7 +416,7 @@ void ChangeLabelCommand::redo() foreach (Node *n, _oldLabels.keys()) { n->setLabel(_newLabel); NodeItem *ni = _scene->nodeItems()[n]; - if (ni != 0) ni->updateBounds(); + if (ni != nullptr) ni->updateBounds(); } GraphUpdateCommand::redo(); diff --git a/src/gui/undocommands.h b/src/gui/undocommands.h index dc60549..ff51c90 100644 --- a/src/gui/undocommands.h +++ b/src/gui/undocommands.h @@ -36,7 +36,7 @@ class GraphUpdateCommand : public QUndoCommand { public: explicit GraphUpdateCommand(TikzScene *scene, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; protected: @@ -49,7 +49,7 @@ public: explicit MoveCommand(TikzScene *scene, QMap<Node*,QPointF> oldNodePositions, QMap<Node*,QPointF> newNodePositions, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -61,18 +61,18 @@ class EdgeBendCommand : public GraphUpdateCommand { public: explicit EdgeBendCommand(TikzScene *scene, Edge *edge, - float oldWeight, int oldBend, + qreal oldWeight, int oldBend, int oldInAngle, int oldOutAngle, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: Edge *_edge; - float _oldWeight; + qreal _oldWeight; int _oldBend; int _oldInAngle; int _oldOutAngle; - float _newWeight; + qreal _newWeight; int _newBend; int _newInAngle; int _newOutAngle; @@ -85,7 +85,7 @@ public: QMap<int,Node*> deleteNodes, QMap<int,Edge*> deleteEdges, QSet<Edge*> selEdges, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -98,7 +98,7 @@ class AddNodeCommand : public GraphUpdateCommand { public: explicit AddNodeCommand(TikzScene *scene, Node *node, QRectF newBounds, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -110,7 +110,7 @@ private: class AddEdgeCommand : public GraphUpdateCommand { public: - explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0); + explicit AddEdgeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -120,7 +120,7 @@ private: class ChangeEdgeModeCommand : public GraphUpdateCommand { public: - explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = 0); + explicit ChangeEdgeModeCommand(TikzScene *scene, Edge *edge, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -130,7 +130,7 @@ private: class ApplyStyleToNodesCommand : public GraphUpdateCommand { public: - explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0); + explicit ApplyStyleToNodesCommand(TikzScene *scene, QString style, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -141,7 +141,7 @@ private: class ApplyStyleToEdgesCommand : public GraphUpdateCommand { public: - explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = 0); + explicit ApplyStyleToEdgesCommand(TikzScene *scene, QString style, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -152,7 +152,7 @@ private: class PasteCommand : public GraphUpdateCommand { public: - explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = 0); + explicit PasteCommand(TikzScene *scene, Graph *graph, QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -167,7 +167,7 @@ public: explicit ChangeLabelCommand(TikzScene *scene, QMap<Node*,QString> oldLabels, QString newLabel, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -181,7 +181,7 @@ public: explicit ReplaceGraphCommand(TikzScene *scene, Graph *oldGraph, Graph *newGraph, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -195,7 +195,7 @@ public: explicit ReflectNodesCommand(TikzScene *scene, QSet<Node*> nodes, bool horizontal, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -209,7 +209,7 @@ public: explicit RotateNodesCommand(TikzScene *scene, QSet<Node*> nodes, bool clockwise, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: @@ -225,7 +225,7 @@ public: const QVector<Node*> &newNodeOrder, const QVector<Edge*> &oldEdgeOrder, const QVector<Edge*> &newEdgeOrder, - QUndoCommand *parent = 0); + QUndoCommand *parent = nullptr); void undo() override; void redo() override; private: |