Skip to content

Commit 3ef779e

Browse files
author
Samuel Weiser
committed
Watchers added, workdir changed to template dir, log cleared on recompile
1 parent b7e3220 commit 3ef779e

File tree

2 files changed

+140
-26
lines changed

2 files changed

+140
-26
lines changed

mainwindow.cpp

Lines changed: 127 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,32 @@
1313
#include <QTemporaryFile>
1414
#include <QFile>
1515
#include <iostream>
16+
#include <string>
17+
#include <thread>
18+
#include <chrono>
1619

1720
#include <QtCore/QDebug>
1821
#undef QT_NO_DEBUG
1922
#include <kdebug.h>
2023

24+
QString getFilePath(QTemporaryDir* dir, const char* file) {
25+
QString path(dir->path());
26+
path.append("/");
27+
path.append(file);
28+
return path;
29+
}
2130

2231
void MainWindow::textChanged(KTextEditor::Document *document) {
2332
(void)document;
2433
refreshTimer->start(1000);
34+
watchme(texdir.path());
35+
}
36+
37+
void MainWindow::documentSaved(KTextEditor::Document *document, bool saveas) {
38+
(void)document;
39+
(void)saveas;
40+
std::cout << "Document saved" << std::endl;
41+
usersaved = true;
2542
}
2643

2744
void MainWindow::render() { render(display->getScale()); }
@@ -57,39 +74,54 @@ void MainWindow::render(double scale) {
5774
}
5875

5976
void MainWindow::compile() {
77+
usersaved = false;
6078
QSettings settings;
6179
QString program = settings.value("compiler", "pdflatex").toString();
80+
6281
QStringList arguments;
6382
QTemporaryDir tmpdir;
6483
tmpdir.setAutoRemove(true);
6584

6685
if (program == "pdflatex") {
6786
arguments << "-halt-on-error";
6887
}
69-
if(dir->path() == "") {
88+
if(!dir || dir->path() == "") {
7089
return;
7190
}
7291
if(texdir.absolutePath() == "") {
7392
std::cout << "need a temporary directory" << std::endl;
7493
texdir = QFileInfo(tmpdir.path());
7594
}
76-
77-
arguments << dir->filePath("_livetikz_preview.tex");
95+
QFileInfo templateDir = QFileInfo(templateFile.path());
96+
if (templateDir.absolutePath() == "") {
97+
workdir = texdir;
98+
} else {
99+
workdir = templateDir;
100+
}
101+
102+
QString odir("--output-directory=");
103+
odir.append(dir->path());
104+
arguments << odir;
105+
106+
arguments << getFilePath(dir, "_livetikz_preview.tex");
107+
108+
std::cout << "Compiler arguments: " << arguments.join(QChar(' ')).toStdString() << std::endl;
109+
std::cout << "Compiler workdir: " << workdir.absolutePath().toStdString() << std::endl;
78110

79-
std::cout << "Arguments: " << dir->filePath("_livetikz_preview.tex").toStdString() << std::endl;
80-
std::cout << "WD: " << texdir.absolutePath().toStdString() << std::endl;
81-
82111
renderProcess = new QProcess(this);
83-
renderProcess->setWorkingDirectory(texdir.absolutePath());
112+
//~ renderProcess->setWorkingDirectory(texdir.absolutePath());
113+
renderProcess->setWorkingDirectory(workdir.absolutePath());
114+
clearLog();
84115
renderProcess->start(program, arguments);
85116

86117
log->setText("Compiling...");
87118
renderOutput = "";
88119
connect(renderProcess, SIGNAL(finished(int)), this, SLOT(renderFinished(int)));
89-
connect(renderProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(renderFailed(QProcess::ProcessError)));
120+
//connect(renderProcess, SIGNAL(errorOccurred(QProcess::ProcessError)), this, SLOT(renderFailed(QProcess::ProcessError)));
90121
connect(renderProcess, SIGNAL(readyReadStandardError()), this, SLOT(updateLog()));
91122
connect(renderProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(updateLog()));
92-
123+
connect(&templateWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(handleTemplateChanged(const QString&)));
124+
93125
connect(killButton, SIGNAL(clicked()), renderProcess, SLOT(kill()));
94126
killButton->setVisible(true);
95127
}
@@ -101,7 +133,8 @@ void MainWindow::refresh() {
101133
}
102134

103135
if (dir->isValid()) {
104-
QFile file(dir->filePath("_livetikz_preview.tex"));
136+
//~ QFile file(dir->filePath("_livetikz_preview.tex"));
137+
QFile file(getFilePath(dir, "_livetikz_preview.tex"));
105138

106139
if (file.open(QIODevice::ReadWrite | QIODevice::Text)) {
107140
QTextStream out(&file);
@@ -148,11 +181,16 @@ void MainWindow::refresh() {
148181
}
149182
}
150183
} else if(dir) {
184+
std::cout << "Deleting invalid dir" << dir->path().toStdString() << std::endl;
151185
delete dir;
152186
dir = NULL;
153187
}
154188
}
155189

190+
void MainWindow::clearLog() {
191+
renderOutput = QString();
192+
}
193+
156194
void MainWindow::appendLog(QString str) {
157195
renderOutput += str;
158196
log->setText(renderOutput);
@@ -165,6 +203,7 @@ void MainWindow::appendLog(QString str) {
165203
void MainWindow::updateLog() {
166204
if (renderProcess) {
167205
appendLog(renderProcess->readAllStandardOutput());
206+
appendLog(renderProcess->readAllStandardError());
168207
}
169208
}
170209

@@ -188,24 +227,24 @@ void MainWindow::renderFinished(int code) {
188227
delete currentDoc;
189228
currentDoc = NULL;
190229

191-
QFile pdf_file(QDir::cleanPath(texdir.absolutePath() + QDir::separator() + "_livetikz_preview.pdf"));
192-
if (pdf_file.exists()) {
193-
QFile::rename(QDir::cleanPath(texdir.absolutePath() + QDir::separator() + "_livetikz_preview.pdf"), dir->filePath("_livetikz_preview.pdf"));
194-
currentDoc = Poppler::Document::load(dir->filePath("_livetikz_preview.pdf"));
230+
//~ QFile pdf_file(QDir::cleanPath(getFilePworkdir.absolutePath() + QDir::separator() + "_livetikz_preview.pdf"));
231+
//~ if (pdf_file.exists()) {
232+
//~ QFile::rename(QDir::cleanPath(texdir.absolutePath() + QDir::separator() + "_livetikz_preview.pdf"), dir->filePath("_livetikz_preview.pdf"));
233+
//~ QFile::rename(QDir::cleanPath(workdir.absolutePath() + QDir::separator() + "_livetikz_preview.pdf"), getFilePath(dir, "_livetikz_preview.pdf"));
234+
//~ currentDoc = Poppler::Document::load(dir->filePath("_livetikz_preview.pdf"));
235+
QFile::remove(getFilePath(dir, "livetikz_preview.pdf"));
236+
QFile::rename(getFilePath(dir, "_livetikz_preview.pdf"), getFilePath(dir, "livetikz_preview.pdf"));
237+
238+
currentDoc = Poppler::Document::load(getFilePath(dir, "livetikz_preview.pdf"));
195239
if (currentDoc) {
196240
currentDoc->setRenderHint(Poppler::Document::TextAntialiasing);
197241
currentDoc->setRenderHint(Poppler::Document::Antialiasing);
198242
currentDoc->setRenderHint(Poppler::Document::TextHinting);
199243
currentDoc->setRenderHint(Poppler::Document::TextSlightHinting);
200244
currentDoc->setRenderHint(Poppler::Document::ThinLineSolid);
201-
202245
render();
203246
}
204-
}
205-
206-
dir->remove();
207-
delete dir;
208-
dir = NULL;
247+
//~ }
209248

210249
renderProcess = NULL;
211250
}
@@ -220,6 +259,7 @@ MainWindow::MainWindow() : currentDoc(NULL), renderProcess(NULL), currentPage(0)
220259

221260
dir = NULL;
222261
templateFile = QUrl(settings.value("template", "").toString());
262+
updateTemplate(templateFile.path());
223263
templateLabel->setText(templateFile.url(QUrl::PreferLocalFile));
224264

225265
doc->setHighlightingMode("Latex");
@@ -237,7 +277,10 @@ MainWindow::MainWindow() : currentDoc(NULL), renderProcess(NULL), currentPage(0)
237277

238278
connect((QObject *)doc, SIGNAL(textChanged(KTextEditor::Document *)), this,
239279
SLOT(textChanged(KTextEditor::Document *)));
240-
connect(templateLabel, SIGNAL(textEdited(const QString&)), this, SLOT(updateTemplate(const QString&)));
280+
connect(templateLabel, SIGNAL(textEdited(const QString&)), this,
281+
SLOT(updateTemplate(const QString&)));
282+
connect((QObject *)doc, SIGNAL(documentSavedOrUploaded(KTextEditor::Document *, bool)), this,
283+
SLOT(documentSaved(KTextEditor::Document *, bool)));
241284
}
242285

243286
void MainWindow::showCompilerSelection() {
@@ -252,15 +295,51 @@ void MainWindow::showCompilerSelection() {
252295
}
253296
}
254297

255-
MainWindow::~MainWindow() {}
298+
MainWindow::~MainWindow() {
299+
/* remove temp dir */
300+
if (dir) {
301+
dir->remove();
302+
delete dir;
303+
dir = NULL;
304+
}
305+
if (texfileWatcher) {
306+
delete texfileWatcher;
307+
texfileWatcher = NULL;
308+
}
309+
}
310+
311+
void MainWindow::watchme(const QString& filename) {
312+
if (texfileWatcher) {
313+
/* We're already watching */
314+
return;
315+
}
316+
/* Some editors delete and re-create files on save.
317+
* This somehow breaks our watcher. On re-watching, the event is
318+
* fired twice, then three times ...
319+
* To avoid this, completely destroy and re-connect the watcher.
320+
*/
321+
texfileWatcher = new QFileSystemWatcher();
322+
connect(texfileWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(handleTexfileChanged(const QString&)));
323+
324+
std::cout << "Watching " << filename.toStdString() << std::endl;
325+
int retry_count = 10;
326+
while(!texfileWatcher->addPath(filename) && retry_count--) {
327+
/* If the file has not been re-created yet, wait some time */
328+
std::this_thread::sleep_for(std::chrono::milliseconds(100));
329+
std::cout << "Retrying to watch..." << std::endl;
330+
}
331+
}
256332

257333
void MainWindow::load(const QUrl &url) {
258-
texdir = QFileInfo(url.toLocalFile());
259-
katePart->openUrl(url);
334+
std::cout << "Loading " << url.toString().toStdString() << std::endl;
335+
texdir = QFileInfo(url.toLocalFile());
336+
watchme(url.toLocalFile());
337+
katePart->openUrl(url);
260338
}
261339

262340
void MainWindow::setupActions() {
263341
KStandardAction::open(this, SLOT(load()), actionCollection());
342+
//KStandardAction::save(this, SLOT(save()), actionCollection());
264343
KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollection());
265344
}
266345

@@ -350,9 +429,33 @@ void MainWindow::setupEditor() {
350429

351430
void MainWindow::load() { load(QFileDialog::getOpenFileUrl()); }
352431

432+
void MainWindow::handleTemplateChanged(const QString& filename) {
433+
std::cout << filename.toStdString() << " changed." << std::endl;
434+
updateTemplate(filename);
435+
}
436+
437+
void MainWindow::handleTexfileChanged(const QString& filename) {
438+
if (!usersaved) {
439+
std::cout << "Texfile " << filename.toStdString() << " externally changed." << std::endl;
440+
/* Reloading */
441+
katePart->openUrl(QUrl(QUrl::fromUserInput(filename)));
442+
}
443+
/* Always re-watch file */
444+
if (texfileWatcher) {
445+
delete texfileWatcher;
446+
texfileWatcher = NULL;
447+
}
448+
watchme(filename);
449+
}
450+
353451
void MainWindow::updateTemplate(const QString& filename) {
354452
QSettings settings;
453+
QUrl oldTemplateFile = QUrl(settings.value("template", "").toString());
454+
templateWatcher.removePath(oldTemplateFile.path());
455+
355456
templateFile = QUrl::fromUserInput(filename);
457+
std::cout << "Loading template " << templateFile.path().toStdString() << std::endl;
458+
templateWatcher.addPath(templateFile.path());
356459
settings.setValue("template", filename);
357460
refresh();
358461
}

mainwindow.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <QSplitter>
1818
#include <QTemporaryFile>
1919
#include <QTemporaryDir>
20+
#include <QFileSystemWatcher>
2021
#include <QTextEdit>
2122
#include <QTextCursor>
2223
#include <QTimer>
@@ -36,13 +37,17 @@ public slots:
3637
void load(const QUrl &url);
3738
void load();
3839
void textChanged(KTextEditor::Document *document);
40+
void documentSaved(KTextEditor::Document *document, bool saveas);
3941
void refresh();
4042
void browse();
4143
void render(double scale);
4244
void renderFinished(int code);
4345
void renderFailed(QProcess::ProcessError);
4446
void showCompilerSelection();
4547
void updateLog();
48+
void watchme(const QString& filename);
49+
void handleTemplateChanged(const QString& filename);
50+
void handleTexfileChanged(const QString& filename);
4651
void gotoPreviousImage();
4752
void gotoNextImage();
4853
void updateTemplate(const QString& filename);
@@ -55,7 +60,8 @@ public slots:
5560

5661
void render();
5762
void compile();
58-
63+
64+
void clearLog();
5965
void appendLog(QString str);
6066

6167

@@ -72,6 +78,7 @@ public slots:
7278
KTextEditor::Document *doc;
7379
ZoomScrollImage *display;
7480
QFileInfo texdir;
81+
QFileInfo workdir;
7582
QTemporaryDir* dir;
7683
Poppler::Document *currentDoc;
7784

@@ -85,14 +92,18 @@ public slots:
8592
QPushButton *browseButton;
8693

8794
QPushButton* killButton;
88-
95+
96+
QFileSystemWatcher templateWatcher;
97+
QFileSystemWatcher *texfileWatcher;
98+
8999
QProcess *renderProcess;
90100
QString renderOutput;
91101

92102
QAction* nextImage;
93103
QAction* prevImage;
94104

95105
int currentPage;
106+
bool usersaved;
96107
};
97108

98109
#endif

0 commit comments

Comments
 (0)