~ubuntu-branches/ubuntu/maverick/scribus-ng/maverick-backports

« back to all changes in this revision

Viewing changes to scribus/pageitem_latexframe.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oleksandr Moskalenko
  • Date: 2009-02-09 09:25:18 UTC
  • mfrom: (5.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090209092518-iqsxmh3pjspgrdyd
Tags: 1.3.5.dfsg~svn20090208-2
debian/control: Use "type-handling -n arm,armel,armeb any" to generate the
list of architectures to build on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
 
3
to the COPYING file provided with the program. Following this notice may exist
 
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
 
5
for which a new license (GPL+exception) is in place.
 
6
*/
 
7
/***************************************************************************
 
8
                                                pageitem_latexframe.cpp  -  description
 
9
                                                -------------------
 
10
        begin                : Mon May 28 2007
 
11
        copyright            : (C) 2007 by Hermann Kraus
 
12
        email                : hermann@physiklaborant.de
 
13
***************************************************************************/
 
14
 
 
15
/***************************************************************************
 
16
*                                                                         *
 
17
*   This program is free software; you can redistribute it and/or modify  *
 
18
*   it under the terms of the GNU General Public License as published by  *
 
19
*   the Free Software Foundation; either version 2 of the License, or     *
 
20
*   (at your option) any later version.                                   *
 
21
*                                                                         *
 
22
***************************************************************************/
 
23
 
 
24
#include "pageitem_latexframe.h"
 
25
 
 
26
#include <QDebug>
 
27
#include <QTemporaryFile>
 
28
 
 
29
#include "prefsmanager.h"
 
30
#include "scpainter.h"
 
31
#include "scraction.h"
 
32
#include "scribus.h"
 
33
#include "scribusdoc.h"
 
34
#include "undomanager.h"
 
35
#include "undostate.h"
 
36
#include "latexeditor.h"
 
37
#include "latexhelpers.h"
 
38
#include "util.h"
 
39
 
 
40
PageItem_LatexFrame::PageItem_LatexFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, QString fill, QString outline)
 
41
                : PageItem_ImageFrame(pa, x, y, w, h, w2, fill, outline)
 
42
{
 
43
        setUPixmap(Um::ILatexFrame);
 
44
        AnName = tr("Render") + QString::number(m_Doc->TotalItems);
 
45
        setUName(AnName);
 
46
        
 
47
        imgValid = false;
 
48
        m_usePreamble = true;
 
49
        err = 0;
 
50
        internalEditor = 0;
 
51
        killed = false;
 
52
        
 
53
        config = 0;
 
54
        if (PrefsManager::instance()->latexConfigs().count() > 0)
 
55
                setConfigFile(PrefsManager::instance()->latexConfigs()[0]);
 
56
 
 
57
        latex = new QProcess();
 
58
        connect(latex, SIGNAL(finished(int, QProcess::ExitStatus)),
 
59
                this, SLOT(updateImage(int, QProcess::ExitStatus)));
 
60
        connect(latex, SIGNAL(error(QProcess::ProcessError)),
 
61
                this, SLOT(latexError(QProcess::ProcessError)));
 
62
        latex->setProcessChannelMode(QProcess::MergedChannels);
 
63
        
 
64
        QTemporaryFile *tempfile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_render_XXXXXX");
 
65
        tempfile->open();
 
66
        tempFileBase = getLongPathName(tempfile->fileName());
 
67
        tempfile->setAutoRemove(false);
 
68
        tempfile->close();
 
69
        delete tempfile;
 
70
        Q_ASSERT(!tempFileBase.isEmpty());
 
71
        
 
72
        m_dpi = 0;
 
73
}
 
74
 
 
75
PageItem_LatexFrame::~PageItem_LatexFrame()
 
76
{
 
77
        if (internalEditor) delete internalEditor;
 
78
        
 
79
        latex->disconnect();
 
80
        if (latex->state() != QProcess::NotRunning) {
 
81
                killed = true;
 
82
                latex->terminate();
 
83
                latex->waitForFinished(500);
 
84
                if (latex->state() != QProcess::NotRunning) {
 
85
                        latex->kill();
 
86
                        latex->waitForFinished(500);
 
87
                }
 
88
        }
 
89
        deleteImageFile();
 
90
        delete latex;
 
91
}
 
92
 
 
93
void PageItem_LatexFrame::clearContents()
 
94
{
 
95
        PageItem_ImageFrame::clearContents();
 
96
        formulaText = "";
 
97
        appStdout = "";
 
98
        err = 0;
 
99
        imgValid = false;
 
100
}
 
101
 
 
102
void PageItem_LatexFrame::deleteImageFile()
 
103
{
 
104
        QFileInfo fi(tempFileBase);
 
105
        QDir dir = fi.absoluteDir();
 
106
        QStringList filter;
 
107
        
 
108
        filter << fi.fileName() + "*";
 
109
        Q_ASSERT(!fi.fileName().isEmpty());
 
110
        Q_ASSERT(!fi.fileName().contains("/"));
 
111
        Q_ASSERT(!fi.fileName().contains("\\"));
 
112
        QStringList files;
 
113
        files = dir.entryList(filter);
 
114
        foreach (QString file, files) {
 
115
                Q_ASSERT(file.startsWith("scribus_temp"));
 
116
                dir.remove(file);
 
117
        }
 
118
        imgValid = false;
 
119
}
 
120
 
 
121
void PageItem_LatexFrame::DrawObj_Item(ScPainter *p, QRectF e, double sc)
 
122
{
 
123
        layout();
 
124
        if (!imgValid && !err)
 
125
        {
 
126
                //Draw indicator that latex is running
 
127
                p->setBrush(Qt::white);
 
128
                p->setPen(Qt::green, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 
129
                p->drawLine(FPoint(0, 0), FPoint(Width, Height));
 
130
                p->drawText(QRectF(0.0, 0.0, Width, Height), tr("Rendering..."));
 
131
        }
 
132
        else if (err)
 
133
        {
 
134
                //Draw error indicator
 
135
                p->setBrush(Qt::white);
 
136
                p->setPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 
137
                p->drawLine(FPoint(0, 0), FPoint(Width, Height));
 
138
                p->drawLine(FPoint(0, Height), FPoint(Width, 0));
 
139
                p->drawText(QRectF(0.0, 0.0, Width, Height), tr("Render Error"));
 
140
        }
 
141
        else
 
142
        {
 
143
                //Just pass it to ImageFrame
 
144
                PageItem_ImageFrame::DrawObj_Item(p, e, sc);
 
145
        }
 
146
}
 
147
 
 
148
void PageItem_LatexFrame::updateImage(int exitCode, QProcess::ExitStatus exitStatus)
 
149
{
 
150
        appStdout = latex->readAllStandardOutput();
 
151
        err = exitCode;
 
152
        
 
153
        emit latexFinished();
 
154
        emit stateChanged(latex->state());
 
155
        
 
156
        static bool firstWarning = true;
 
157
        if (exitCode) {
 
158
                imgValid = false;
 
159
                if (firstWarning && !killed)
 
160
                {
 
161
                        QMessageBox::critical(0, tr("Error"), "<qt>" + 
 
162
                                tr("Running the external application failed!")
 
163
                                + "</qt>", 1, 0, 0);
 
164
                        firstWarning = false;
 
165
                }
 
166
                qCritical() << "RENDER FRAME: updateImage():" << tr("Running the external application failed!");
 
167
                killed = false;
 
168
                update(); //Show error marker
 
169
                return;
 
170
        }
 
171
        else
 
172
        {
 
173
                firstWarning = true;
 
174
        }
 
175
        imgValid = true;
 
176
 
 
177
        //Save state and restore afterwards
 
178
        bool do_update = PictureIsAvailable;
 
179
        double scaleX = 72.0, scaleY = 72.0, offX = 0.0, offY = 0.0;
 
180
        if (do_update) {
 
181
                scaleX = LocalScX * pixm.imgInfo.xres;
 
182
                scaleY = LocalScY * pixm.imgInfo.yres;
 
183
                offX   = LocalX   / pixm.imgInfo.xres;
 
184
                offY   = LocalY   / pixm.imgInfo.yres;
 
185
        }
 
186
        PageItem_ImageFrame::loadImage(imageFile, true, realDpi());
 
187
        if (PrefsManager::instance()->latexForceDpi()) 
 
188
        {
 
189
                pixm.imgInfo.xres = pixm.imgInfo.yres = realDpi();
 
190
        }
 
191
        
 
192
        if (do_update) 
 
193
        {
 
194
                //Restoring parameters
 
195
                LocalScX = scaleX / pixm.imgInfo.xres; //Account for dpi changes!
 
196
                LocalScY = scaleY / pixm.imgInfo.yres;
 
197
                LocalX   = offX   * pixm.imgInfo.xres;
 
198
                LocalY   = offY   * pixm.imgInfo.yres;
 
199
        } 
 
200
        else 
 
201
        {
 
202
                //Setting sane defaults
 
203
                LocalX = LocalY = 0;
 
204
                LocalScX = 72.0/pixm.imgInfo.xres;
 
205
                LocalScY = 72.0/pixm.imgInfo.yres;
 
206
        }
 
207
        emit imageOffsetScale(LocalScX, LocalScY, LocalX, LocalY );
 
208
        
 
209
        update();
 
210
}
 
211
 
 
212
 
 
213
void PageItem_LatexFrame::runApplication()
 
214
{
 
215
        imgValid = false;
 
216
        err = 0;
 
217
        killed = false;
 
218
        
 
219
        static bool firstWarningTmpfile = true;
 
220
        static bool firstWarningLatexMissing = true;
 
221
 
 
222
        if (!config)
 
223
        {
 
224
                qCritical() << "RENDER FRAME:" << tr("No configuration defined to run the application!");
 
225
                return;
 
226
        }
 
227
        
 
228
        QFile tempfile(tempFileBase);
 
229
        if (!tempfile.open(QIODevice::Truncate|QIODevice::WriteOnly)) {
 
230
                err = 0xffff;
 
231
                update(); //Show error marker
 
232
                if (firstWarningTmpfile)
 
233
                {
 
234
                        QMessageBox::critical(0, tr("Error"), "<qt>" +
 
235
                                                                  tr("Could not create a temporary file to run the application!") 
 
236
                                                                  + "</qt>", 1, 0, 0);
 
237
                        firstWarningTmpfile = false;
 
238
                }
 
239
                qCritical() << "RENDER FRAME:" << tr("Could not create a temporary file to run the application!");
 
240
                //Don't know how to continue as it's impossible to create tempfile
 
241
                return;
 
242
        }
 
243
        else
 
244
        {
 
245
                firstWarningTmpfile = true;
 
246
        }
 
247
        
 
248
        QString full_command = config->executable();
 
249
        
 
250
        if (full_command.isEmpty()) {
 
251
                err = 0xffff;
 
252
                update(); //Show error marker
 
253
                if (firstWarningLatexMissing)
 
254
                {
 
255
                        QMessageBox::critical(0, tr("Error"),
 
256
                                                                         "<qt>" + tr("The config file didn't specify a executable path!") +
 
257
                                                                         "</qt>",1, 0, 0);
 
258
                        firstWarningLatexMissing = false;
 
259
                }
 
260
        qCritical() << "RENDER FRAME:" << tr("The config file didn't specify a executable path!");
 
261
                return;
 
262
        }
 
263
        else
 
264
        {
 
265
                firstWarningLatexMissing = true;
 
266
        }
 
267
 
 
268
        full_command.replace("%dpi", QString::number(realDpi()));
 
269
        if (full_command.contains("%file")) {
 
270
                full_command.replace("%file", QString("\"%1\"").arg(QDir::toNativeSeparators(tempFileBase)));
 
271
        } else {
 
272
                full_command = full_command + QString(" \"%1\"").arg(QDir::toNativeSeparators(tempFileBase));
 
273
        }
 
274
        full_command.replace("%dir", QString("\"%1\"").arg(QDir::toNativeSeparators(QDir::tempPath())));
 
275
        latex->setWorkingDirectory(QDir::tempPath());
 
276
 
 
277
        double lDpi = realDpi()/72.0;
 
278
        full_command.replace("$scribus_height_px$", QString::number(qRound(Height*lDpi)));
 
279
        full_command.replace("$scribus_width_px$",  QString::number(qRound(Width*lDpi)));
 
280
        QMapIterator<QString, QString> i(editorProperties);
 
281
        while (i.hasNext())
 
282
        {
 
283
                i.next();
 
284
                full_command.replace("$scribus_"+i.key()+"$", i.value());
 
285
        }
 
286
        
 
287
        imageFile = tempFileBase + config->imageExtension();
 
288
 
 
289
        writeFileContents(&tempfile);
 
290
        tempfile.close();
 
291
        
 
292
        latex->start(full_command);
 
293
        emit stateChanged(QProcess::Starting);
 
294
}
 
295
 
 
296
void PageItem_LatexFrame::runEditor()
 
297
{
 
298
        if (!internalEditor) {
 
299
                internalEditor = new LatexEditor(this);
 
300
                internalEditor->startEditor();
 
301
        } else if (internalEditor->isVisible()) {
 
302
                internalEditor->activateWindow();
 
303
                internalEditor->raise();
 
304
        } else {
 
305
                internalEditor->startEditor();
 
306
        }
 
307
}
 
308
 
 
309
void PageItem_LatexFrame::rerunApplication(bool updateDisplay)
 
310
{
 
311
        if (latex->state() != QProcess::NotRunning) {
 
312
                killed = true;
 
313
                latex->terminate();
 
314
                latex->waitForFinished(500);
 
315
                if (latex->state() != QProcess::NotRunning) {
 
316
                        //Still not terminated?
 
317
                        latex->kill();
 
318
                        latex->waitForFinished(500);
 
319
                }
 
320
        }
 
321
        runApplication();
 
322
        if (updateDisplay) this->update();
 
323
}
 
324
 
 
325
 
 
326
void PageItem_LatexFrame::writeFileContents(QFile *tempfile)
 
327
{
 
328
        QString tmp(formulaText);
 
329
        double scaleX, scaleY, realW, realH, offsetX, offsetY;
 
330
        double lDpi = realDpi()/72.0;
 
331
        scaleX = LocalScX*lDpi;
 
332
        scaleY = LocalScY*lDpi;
 
333
        offsetX = LocalX*LocalScX;
 
334
        offsetY = LocalY*LocalScY;
 
335
        realW = Width/scaleX - LocalX/lDpi;
 
336
        realH = Height/scaleY - LocalY/lDpi;
 
337
        if (!tmp.contains("$scribus_noprepost$") && m_usePreamble) {
 
338
                tmp = config->preamble() + tmp + config->postamble();
 
339
        }
 
340
        tmp.replace(QString("$scribus_width$"), QString::number(Width));
 
341
        tmp.replace(QString("$scribus_width_px$"), QString::number(qRound(Width*lDpi)));
 
342
        tmp.replace(QString("$scribus_width_inch$"), QString::number(Width/72.0));
 
343
        tmp.replace(QString("$scribus_height$"), QString::number(Height));
 
344
        tmp.replace(QString("$scribus_height_px$"), QString::number(qRound(Height*lDpi)));
 
345
        tmp.replace(QString("$scribus_height_inch$"), QString::number(Height/72.0));
 
346
        tmp.replace(QString("$scribus_realwidth$"), QString::number(realW));
 
347
        tmp.replace(QString("$scribus_realwidth_px$"), QString::number(qRound(realW*lDpi)));
 
348
        tmp.replace(QString("$scribus_realheight$"), QString::number(realH));
 
349
        tmp.replace(QString("$scribus_realheight_px$"), QString::number(qRound(realH*lDpi)));
 
350
        tmp.replace(QString("$scribus_offsetX$"), QString::number(offsetX));
 
351
        tmp.replace(QString("$scribus_offsetX_px$"), QString::number(qRound(offsetX*lDpi)));
 
352
        tmp.replace(QString("$scribus_offsetY$"), QString::number(offsetY));
 
353
        tmp.replace(QString("$scribus_offsetY$"), QString::number(qRound(offsetY*lDpi)));
 
354
        tmp.replace(QString("$scribus_scaleX$"), QString::number(scaleX));
 
355
        tmp.replace(QString("$scribus_scaleY$"), QString::number(scaleY));
 
356
        tmp.replace(QString("$scribus_dpi$"), QString::number(realDpi()));
 
357
        tmp.replace(QString("$scribus_file$"), tempFileBase);
 
358
        tmp.replace(QString("$scribus_dir$"), QDir::tempPath());
 
359
        QMapIterator<QString, QString> i(editorProperties);
 
360
        while (i.hasNext()) {
 
361
                i.next();
 
362
                tmp.replace("$scribus_"+i.key()+"$", i.value());
 
363
        }
 
364
        tempfile->write(tmp.toUtf8());
 
365
}
 
366
 
 
367
bool PageItem_LatexFrame::setFormula(QString formula, bool undoable)
 
368
{
 
369
        if (formula == formulaText) {
 
370
                //Nothing changed
 
371
                return false;
 
372
        }
 
373
        imgValid = false;
 
374
        err = 0;
 
375
        if (UndoManager::undoEnabled() && undoable)
 
376
        {
 
377
                SimpleState *ss = new SimpleState(Um::ChangeFormula, "", Um::IChangeFormula);
 
378
                ss->set("CHANGE_FORMULA", "change_formula");
 
379
                ss->set("OLD_FORMULA", formulaText);
 
380
                ss->set("NEW_FORMULA", formula);
 
381
                undoManager->action(this, ss);
 
382
        } else if (!undoable) {
 
383
                emit formulaAutoUpdate(formulaText, formula);
 
384
        }
 
385
        formulaText = formula;
 
386
        return true;
 
387
}
 
388
 
 
389
void PageItem_LatexFrame::latexError(QProcess::ProcessError error)
 
390
{
 
391
        err = 0xffff;
 
392
        update(); //Show error marker
 
393
        static bool firstWarning = true;
 
394
        if (killed) {
 
395
                killed = false;
 
396
                update();
 
397
                //Don't show errors caused by killing processes
 
398
                return; 
 
399
        }
 
400
        if (firstWarning)
 
401
        {
 
402
                if (latex->error() == QProcess::FailedToStart) {
 
403
                        QMessageBox::critical(0, tr("Error"), "<qt>" +
 
404
                                                                  tr("The application \"%1\" failed to start!").
 
405
                                                                  arg(config->executable())
 
406
                                                                  + "</qt>", 1, 0, 0);
 
407
                } else {
 
408
                        QMessageBox::critical(0, tr("Error"), "<qt>" +
 
409
                                        tr("The application \"%1\" crashed!").arg(config->executable())
 
410
                                        + "</qt>", 1, 0, 0);
 
411
                }
 
412
                firstWarning = false;
 
413
        }
 
414
        qCritical() << "RENDER FRAME: latexError():" << 
 
415
                        tr("Running the application \"%1\" failed!").arg(config->executable()) << latex->error();
 
416
}
 
417
 
 
418
 
 
419
QString PageItem_LatexFrame::application() const
 
420
{
 
421
        return config ? config->executable() : tr("No application defined");
 
422
}
 
423
 
 
424
QString PageItem_LatexFrame::configFile() const
 
425
{
 
426
        return configFilename;
 
427
}
 
428
 
 
429
int PageItem_LatexFrame::realDpi() const
 
430
{
 
431
        if (m_dpi) {
 
432
                return m_dpi;
 
433
        } else {
 
434
                return PrefsManager::instance()->latexResolution();
 
435
        }
 
436
}
 
437
 
 
438
void PageItem_LatexFrame::setDpi(int newDpi)
 
439
{
 
440
        m_dpi = newDpi;
 
441
}
 
442
 
 
443
void PageItem_LatexFrame::setConfigFile(QString newConfig, bool relative)
 
444
{
 
445
        if (relative) {
 
446
                QFileInfo fi;
 
447
                QStringList configs = PrefsManager::instance()->latexConfigs();
 
448
                foreach (QString config, configs) {
 
449
                        fi.setFile(config);
 
450
                        if (newConfig == fi.fileName()) {
 
451
                                newConfig = config;
 
452
                                break;
 
453
                        }
 
454
                }
 
455
        }
 
456
 
 
457
        if (configFilename == newConfig) return;
 
458
        
 
459
        bool unchanged = formulaText.isEmpty();
 
460
        if (config && (formulaText == config->emptyFrameText())) {
 
461
                unchanged = true;
 
462
        }
 
463
        
 
464
        configFilename = newConfig;
 
465
        config = LatexConfigCache::instance()->parser(configFilename);
 
466
        
 
467
        //Initialize with default values
 
468
        QString key;
 
469
        QMapIterator<QString, QString> i(config->properties);
 
470
        while (i.hasNext()) {
 
471
                i.next();
 
472
                key = i.key();
 
473
                if (!editorProperties.contains(key)) {
 
474
                        editorProperties[key] = i.value();
 
475
                }
 
476
        }
 
477
        QString newFormula;
 
478
        if (unchanged) {
 
479
                if (PrefsManager::instance()->latexStartWithEmptyFrames()) {
 
480
                        newFormula = "";
 
481
                } else {
 
482
                        newFormula = config->emptyFrameText();
 
483
                }
 
484
                emit formulaAutoUpdate(formulaText, newFormula);
 
485
                formulaText = newFormula;
 
486
        }
 
487
        
 
488
        emit applicationChanged();
 
489
}
 
490
 
 
491
void PageItem_LatexFrame::killProcess()
 
492
{
 
493
        killed = true;
 
494
        latex->kill();
 
495
}
 
496
 
 
497
void PageItem_LatexFrame::restore(UndoState *state, bool isUndo)
 
498
{
 
499
        SimpleState *ss = dynamic_cast<SimpleState*>(state);
 
500
        if (!ss) {
 
501
                PageItem_ImageFrame::restore(state, isUndo);
 
502
                return;
 
503
        }
 
504
        if (ss->contains("CHANGE_FORMULA")) {
 
505
                if (isUndo) {
 
506
                        setFormula(ss->get("OLD_FORMULA"), false);
 
507
                } else {
 
508
                        setFormula(ss->get("NEW_FORMULA"), false);
 
509
                }
 
510
        } else {
 
511
                PageItem_ImageFrame::restore(state, isUndo);
 
512
        }
 
513
}
 
514
 
 
515
 
 
516
void PageItem_LatexFrame::setUsePreamble(bool useP) 
 
517
{
 
518
        m_usePreamble = useP;
 
519
}
 
520
 
 
521
void PageItem_LatexFrame::layout()
 
522
{
 
523
        if (!invalid) return;
 
524
        invalid = false;
 
525
        
 
526
        if (Width == lastWidth && Height == lastHeight) return;
 
527
        lastWidth = Width;
 
528
        lastHeight = Height;
 
529
        
 
530
        rerunApplication(false);
 
531
}
 
532
 
 
533
void PageItem_LatexFrame::applicableActions(QStringList & actionList)
 
534
{
 
535
        actionList << "itemImageIsVisible";
 
536
        actionList << "itemPreviewFull";
 
537
        actionList << "itemPreviewLow";
 
538
        actionList << "itemPreviewNormal";
 
539
        actionList << "itemUpdateImage";
 
540
        actionList << "editEditRenderSource";
 
541
        if (PictureIsAvailable)
 
542
        {
 
543
                /*if (!isTableItem)
 
544
                        actionList << "itemAdjustFrameToImage";*/
 
545
                actionList << "editClearContents";
 
546
                actionList << "editCopyContents";
 
547
        }
 
548
        if (doc()->scMW()->contentsBuffer.sourceType==PageItem::LatexFrame)
 
549
        {
 
550
                actionList << "editPasteContents";
 
551
                actionList << "editPasteContentsAbs";
 
552
        }
 
553
}
 
554
 
 
555
QString PageItem_LatexFrame::infoDescription()
 
556
{
 
557
        QString htmlText;
 
558
        htmlText.append("<h2>"+tr("Render Frame") + "</h2><table>");
 
559
        htmlText.append("<tr><th align=\"right\">" + tr("Application") + ": </th><td>" + application());
 
560
        htmlText.append("</td></tr><tr><th align=\"right\">" + tr("DPI") + ": </th><td>" +
 
561
                         QString::number(realDpi()));
 
562
        htmlText.append("</td></tr><tr><th align=\"right\">" + tr("State") + ": </th><td>");
 
563
        if (latex->state() == QProcess::NotRunning) {
 
564
                if (error()) {
 
565
                        htmlText.append(tr("Error"));
 
566
                } else {
 
567
                        htmlText.append(tr("Finished"));
 
568
                }
 
569
        } else {
 
570
                htmlText.append(tr("Running"));
 
571
        }
 
572
        htmlText.append("</td></tr></table><hr>");
 
573
        htmlText.append(PageItem::infoDescription());
 
574
        return htmlText;
 
575
}
 
576