diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/latexprocess.cpp | 98 | ||||
-rw-r--r-- | src/gui/latexprocess.h | 33 | ||||
-rw-r--r-- | src/gui/mainmenu.cpp | 7 | ||||
-rw-r--r-- | src/gui/mainmenu.h | 1 | ||||
-rw-r--r-- | src/gui/mainmenu.ui | 9 | ||||
-rw-r--r-- | src/gui/previewwindow.cpp | 122 | ||||
-rw-r--r-- | src/gui/previewwindow.h | 35 | ||||
-rw-r--r-- | src/gui/previewwindow.ui | 77 |
8 files changed, 381 insertions, 1 deletions
diff --git a/src/gui/latexprocess.cpp b/src/gui/latexprocess.cpp new file mode 100644 index 0000000..20b22a4 --- /dev/null +++ b/src/gui/latexprocess.cpp @@ -0,0 +1,98 @@ +#include "latexprocess.h" +#include "tikzit.h" + +#include <QDebug> +#include <QStandardPaths> +#include <QTemporaryDir> + +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) +{ + _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"); + _output->appendPlainText("SEARCHING FOR pdflatex IN:"); + _output->appendPlainText(qgetenv("PATH")); + _output->appendPlainText("\n"); + + + QString pdflatex = QStandardPaths::findExecutable("pdflatex"); + if (pdflatex.isEmpty()) { + _output->appendPlainText("pdflatex NOT FOUND, ABORTING.\n"); + return; + } + + _output->appendPlainText("FOUND: " + pdflatex + "\n"); + + // copy active *.tikzstyles file to preview dir + if (!tikzit->styleFile().isEmpty() && QFile::exists(tikzit->styleFilePath())) { + QFile::copy(tikzit->styleFilePath(), _workingDir.path() + "/" + tikzit->styleFile()); + } + + // 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 << "\\usepackage[graphics,active,tightpage]{preview}\n"; + tex << "\\PreviewEnvironment{tikzpicture}\n"; + tex << "\\input{" + tikzit->styleFile() + "}\n"; + tex << "\\begin{document}\n\n"; + tex << tikz; + tex << "\n\n\\end{document}\n"; + + f.close(); + _proc->start(pdflatex, QStringList() << "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); + emit previewFinished(); + } else { + _output->appendPlainText("\n\npdflatex RETURNED AN ERROR\n"); + emit previewFinished(); + } +} diff --git a/src/gui/latexprocess.h b/src/gui/latexprocess.h new file mode 100644 index 0000000..dc815f2 --- /dev/null +++ b/src/gui/latexprocess.h @@ -0,0 +1,33 @@ +#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..6f6ab00 100644 --- a/src/gui/mainmenu.cpp +++ b/src/gui/mainmenu.cpp @@ -228,6 +228,11 @@ void MainMenu::on_actionJump_to_Selection_triggered() } } +void MainMenu::on_actionRun_LaTeX_triggered() +{ + tikzit->makePreview(); +} + // View void MainMenu::on_actionZoom_In_triggered() @@ -260,5 +265,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..e1477b4 100644 --- a/src/gui/mainmenu.h +++ b/src/gui/mainmenu.h @@ -67,6 +67,7 @@ public slots: void on_actionParse_triggered(); void on_actionRevert_triggered(); void on_actionJump_to_Selection_triggered(); + void on_actionRun_LaTeX_triggered(); // View void on_actionZoom_In_triggered(); diff --git a/src/gui/mainmenu.ui b/src/gui/mainmenu.ui index 0481c1d..58a2ff0 100644 --- a/src/gui/mainmenu.ui +++ b/src/gui/mainmenu.ui @@ -74,6 +74,7 @@ <addaction name="actionParse"/> <addaction name="actionRevert"/> <addaction name="actionJump_to_Selection"/> + <addaction name="actionRun_LaTeX"/> </widget> <widget class="QMenu" name="menuView"> <property name="title"> @@ -335,6 +336,14 @@ <string>About</string> </property> </action> + <action name="actionRun_LaTeX"> + <property name="text"> + <string>Run LaTeX</string> + </property> + <property name="shortcut"> + <string>Ctrl+R</string> + </property> + </action> <addaction name="menuFile"/> <addaction name="menuEdit"/> <addaction name="menuView"/> diff --git a/src/gui/previewwindow.cpp b/src/gui/previewwindow.cpp new file mode 100644 index 0000000..724a951 --- /dev/null +++ b/src/gui/previewwindow.cpp @@ -0,0 +1,122 @@ +#include "previewwindow.h" +#include "ui_previewwindow.h" + +#include "tikzit.h" +#include "latexprocess.h" + +#include <QLabel> +#include <QImage> +#include <QPixmap> +#include <QDebug> +#include <QSettings> +#include <QTemporaryDir> +#include <QFile> +#include <QTextStream> +#include <QStandardPaths> +#include <QMessageBox> +#include <cmath> + +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; + _page = nullptr; + //setPdf("/home/aleks/ak-algebras.pdf"); + + //qDebug() << "preview dir:" << preparePreview("foo"); + + render(); +} + +PreviewWindow::~PreviewWindow() +{ + delete ui; +} + +void PreviewWindow::setPdf(QString file) +{ + Poppler::Document *oldDoc = _doc; + + // 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(); + Poppler::Document *newDoc = Poppler::Document::loadFromData(data); + + if (!newDoc) { + QMessageBox::warning(nullptr, + "Could not read PDF", + "Could not read: '" + file + "'."); + return; + } + + _doc = newDoc; + _doc->setRenderHint(Poppler::Document::Antialiasing); + _doc->setRenderHint(Poppler::Document::TextAntialiasing); + _doc->setRenderHint(Poppler::Document::TextHinting ); + _page = _doc->page(0); + render(); + + if (oldDoc != nullptr) delete oldDoc; +} + +QPlainTextEdit *PreviewWindow::outputTextEdit() +{ + return ui->output; +} + +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 (_page == nullptr) return; + + QSizeF size = _page->pageSizeF(); + + qreal ratio = devicePixelRatioF(); + QRect rect = ui->scrollArea->visibleRegion().boundingRect(); + int w = static_cast<int>(ratio * (rect.width() - 20)); + int h = static_cast<int>(ratio * (rect.height() - 20)); + qreal scale = fmin(static_cast<qreal>(w) / size.width(), + static_cast<qreal>(h) / size.height()); + + + int dpi = static_cast<int>(scale * 72.0); + int w1 = static_cast<int>(scale * size.width()); + int h1 = static_cast<int>(scale * size.height()); + + // qDebug() << "visible width:" << w; + // qDebug() << "visible height:" << h; + // qDebug() << "doc width:" << size.width(); + // qDebug() << "doc height:" << size.height(); + // qDebug() << "scale:" << scale; + // qDebug() << "dpi:" << dpi; + + QPixmap pm = QPixmap::fromImage(_page->renderToImage(dpi, dpi, (w1 - w)/2, (h1 - h)/2, w, h)); + pm.setDevicePixelRatio(ratio); + ui->pdf->setPixmap(pm); +} diff --git a/src/gui/previewwindow.h b/src/gui/previewwindow.h new file mode 100644 index 0000000..c850ce9 --- /dev/null +++ b/src/gui/previewwindow.h @@ -0,0 +1,35 @@ +#ifndef PREVIEWWINDOW_H +#define PREVIEWWINDOW_H + +#include <QDialog> +#include <QPlainTextEdit> +#include <poppler/qt5/poppler-qt5.h> + +namespace Ui { +class PreviewWindow; +} + +class PreviewWindow : public QDialog +{ + Q_OBJECT + +public: + explicit PreviewWindow(QWidget *parent = nullptr); + ~PreviewWindow(); + void setPdf(QString file); + QString preparePreview(QString tikz); + QPlainTextEdit *outputTextEdit(); + +protected: + void resizeEvent(QResizeEvent *e); + void showEvent(QShowEvent *e); + void closeEvent(QCloseEvent *e); + +private: + Ui::PreviewWindow *ui; + void render(); + Poppler::Document *_doc; + Poppler::Page *_page; +}; + +#endif // PREVIEWWINDOW_H diff --git a/src/gui/previewwindow.ui b/src/gui/previewwindow.ui new file mode 100644 index 0000000..394fc41 --- /dev/null +++ b/src/gui/previewwindow.ui @@ -0,0 +1,77 @@ +<?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"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="pdfTab"> + <attribute name="title"> + <string>PDF</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <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>561</width> + <height>413</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> |