~ubuntu-branches/ubuntu/precise/ipe/precise

« back to all changes in this revision

Viewing changes to src/ipemodel/ipemodel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2005-02-24 22:09:16 UTC
  • mfrom: (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050224220916-9vxiiqjz066r5489
Tags: 6.0pre23-2
debian/control: Ipe should depend on exact version of libipe.
Closes: #296771.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// --------------------------------------------------------------------
 
2
// The Ipe document, with PDF support
 
3
// --------------------------------------------------------------------
 
4
/*
 
5
 
 
6
    This file is part of the extensible drawing editor Ipe.
 
7
    Copyright (C) 1993-2004  Otfried Cheong
 
8
 
 
9
    Ipe is free software; you can redistribute it and/or modify it
 
10
    under the terms of the GNU General Public License as published by
 
11
    the Free Software Foundation; either version 2 of the License, or
 
12
    (at your option) any later version.
 
13
 
 
14
    As a special exception, you have permission to link Ipe with the
 
15
    CGAL library and distribute executables, as long as you follow the
 
16
    requirements of the Gnu General Public License in regard to all of
 
17
    the software in the executable aside from CGAL.
 
18
 
 
19
    Ipe is distributed in the hope that it will be useful, but WITHOUT
 
20
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
21
    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 
22
    License for more details.
 
23
 
 
24
    You should have received a copy of the GNU General Public License
 
25
    along with Ipe; if not, you can find it at
 
26
    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
 
27
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
28
 
 
29
*/
 
30
 
 
31
#include "ipemodel.h"
 
32
 
 
33
#include "ipeprefs.h"
 
34
#include "ipeq.h"
 
35
 
 
36
#include "ipelatex.h"
 
37
 
 
38
#include <qbuffer.h>
 
39
#include <qfile.h>
 
40
#include <qdir.h>
 
41
#include <qtextstream.h>
 
42
 
 
43
// --------------------------------------------------------------------
 
44
 
 
45
/*! \class IpeModel
 
46
  \brief Support for loading/saving/running Latex on IpeDocument.
 
47
 
 
48
  This class supports running pdflatex to generate the PDF output for
 
49
  text objects, and adds I/O using QFile's to IpeDocument.
 
50
 
 
51
  All members of the class are static.
 
52
 
 
53
 */
 
54
 
 
55
IpeDocument *IpeModel::New(const QString &fname, int &reason)
 
56
{
 
57
  QFile f(fname);
 
58
  reason = -1;
 
59
  if (!f.open(IO_ReadOnly))
 
60
    return 0;
 
61
  XmlQSource source(&f);
 
62
  IpeDocument::TFormat format = IpeDocument::FileFormat(source);
 
63
  f.at(0); // rewind
 
64
  IpeDocument *self = IpeDocument::New(source, format, reason);
 
65
  f.close();
 
66
  return self;
 
67
}
 
68
 
 
69
bool IpeModel::Save(const IpeDocument *doc, const QString &fname,
 
70
                    IpeString creator, IpeDocument::TFormat format,
 
71
                    uint flags)
 
72
{
 
73
  QFile f(fname);
 
74
  if (!f.open(IO_WriteOnly))
 
75
    return 0;
 
76
  IpeQStream stream(&f);
 
77
  bool result = doc->Save(stream, creator, format, flags,
 
78
                          IpePreferences::Static()->iCompressLevel);
 
79
  f.close();
 
80
  return result;
 
81
}
 
82
 
 
83
bool IpeModel::AddStyleSheet(IpeDocument *doc, const QString &fname)
 
84
{
 
85
  QFile file(fname);
 
86
  if (!file.open(IO_ReadOnly))
 
87
    return false;
 
88
  XmlQSource source(&file);
 
89
  bool result = doc->AddStyleSheet(source);
 
90
  file.close();
 
91
  return result;
 
92
}
 
93
 
 
94
// --------------------------------------------------------------------
 
95
 
 
96
//! Run PdfLatex
 
97
/*! Prepend \a styleDirs to Latex include path. */
 
98
int IpeModel::RunLatex(IpeDocument *doc, bool needLatex,
 
99
                       const QStringList &styleDirs, QString &texLog)
 
100
{
 
101
  IpePreferences *prefs = IpePreferences::Static();
 
102
  texLog = QString::null;
 
103
  IpeLatex converter;
 
104
  int count = 0;
 
105
  for (IpeDocument::iterator it = doc->begin(); it != doc->end(); ++it)
 
106
    count += converter.ScanPage(*it);
 
107
  if (count == 0)
 
108
    return ErrNoText;
 
109
  // First we need a temporary directory
 
110
  QDir temp = QDir(prefs->iLatexDir);
 
111
  if (!temp.exists())
 
112
    // create Pdflatex directory if it doesn't exist
 
113
    QDir().mkdir(temp.absPath());
 
114
  if (!temp.exists())
 
115
    return ErrNoDir;
 
116
 
 
117
  QString texFile = temp.filePath("text.tex");
 
118
  QString pdfFile = temp.filePath("text.pdf");
 
119
  QString logFile = temp.filePath("text.log");
 
120
  QFile::remove(logFile);
 
121
 
 
122
  QFile file(texFile);
 
123
  if(!file.open(IO_WriteOnly))
 
124
    return -1;
 
125
  IpeQStream stream(&file);
 
126
  int err = converter.CreateLatexSource(stream, doc->Properties().iPreamble,
 
127
                                        doc->StyleSheet());
 
128
  file.close();
 
129
 
 
130
  if (err < 0)
 
131
    return ErrWritingSource;
 
132
  if (err == 0 && !needLatex)
 
133
    return ErrAlreadyHaveForm;
 
134
  // Latex source has been prepared correctly
 
135
 
 
136
  // set up TEXINPUTS (but special handling for MikTeX below)
 
137
  QCString ti = "TEXINPUTS=";
 
138
  bool putTi = false;
 
139
  if (styleDirs.count() > 0) {
 
140
    putTi = true;
 
141
    for (uint i = 0; i < styleDirs.count(); ++i)
 
142
      ti.append((styleDirs[i] + ":").local8Bit());
 
143
  }
 
144
  if (!prefs->iTexInputs.empty()) {
 
145
    putTi = true;
 
146
    ti.append(prefs->iTexInputs.CString());
 
147
  }
 
148
  if (putTi)
 
149
    putenv(qstrdup(ti.data()));
 
150
 
 
151
#ifdef WIN32
 
152
  QString s = temp.filePath("runlatex.bat");
 
153
  QFile f(s);
 
154
  f.open(IO_WriteOnly);
 
155
  QTextStream batFile(&f);
 
156
  QString dirPath = QDir::convertSeparators(temp.path());
 
157
  if (dirPath.length() > 2 && dirPath[1] == ':')
 
158
    batFile << dirPath.left(2) << "\r\n";
 
159
  batFile << "cd \"" << dirPath << "\"\r\n";
 
160
  batFile << "\"" << prefs->iPdfLatex << "\"";
 
161
  if (prefs->iMikTeX) {
 
162
    for (uint i = 0; i < styleDirs.count(); ++i) {
 
163
      batFile << " -include-directory=\""
 
164
             << QDir::convertSeparators(styleDirs[i]) << "\"";
 
165
    }
 
166
  }
 
167
  batFile << " text.tex\r\n";
 
168
  f.close();
 
169
  s = "call \"" + QDir::convertSeparators(s) + "\"";
 
170
  system(s.local8Bit());
 
171
#else
 
172
  QCString s = "cd " + QFile::encodeName(temp.path()) + "; " +
 
173
    QFile::encodeName(prefs->iPdfLatex) + " text.tex";
 
174
  system(s.data());
 
175
#endif
 
176
  // Check log file for Pdflatex version and errors
 
177
  QFile log(logFile);
 
178
  if (!log.open(IO_ReadOnly))
 
179
    return ErrLatex;
 
180
  texLog = QString(log.readAll());
 
181
  log.close();
 
182
  if (texLog.left(14) != "This is pdfTeX" &&
 
183
      texLog.left(15) != "This is pdfeTeX")
 
184
    return ErrLatex;
 
185
  prefs->iMikTeX = (texLog.left(80).find("MikTeX") >= 0);
 
186
  int i = texLog.find('-');
 
187
  if (i < 0)
 
188
    return ErrLatex;
 
189
  QString version = texLog.mid(i+1, 30);
 
190
  ipeDebug("pdfTeX version %s", version.latin1());
 
191
  if (version[0] == '1' && '0' <= version[1] && version[1] <= '3')
 
192
    return ErrOldPdfLatex;
 
193
  if (version.left(2) == "14" && version.left(3) < "14f")
 
194
    return ErrOldPdfLatex;
 
195
  // Check for error
 
196
  if (texLog.find("\n!") >= 0)
 
197
    return ErrLatex;
 
198
 
 
199
  QFile pdfF(pdfFile);
 
200
  if (!pdfF.open(IO_ReadOnly))
 
201
    return false;
 
202
  XmlQSource source(&pdfF);
 
203
  if (converter.ReadPdf(source) && converter.UpdateTextObjects()) {
 
204
    doc->SetFontPool(converter.TakeFontPool());
 
205
    ipeDebug("Pdflatex run completed successfully");
 
206
    return ErrNone;
 
207
  }
 
208
  return ErrLatexOutput;
 
209
}
 
210
 
 
211
// --------------------------------------------------------------------