]> git.lyx.org Git - lyx.git/blob - src/format.C
4f85ce34e9f8b669ad07b3d10c9162a8ee2332b0
[lyx.git] / src / format.C
1 /**
2  * \file format.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Dekel Tsur
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include "config.h"
12 #include "format.h"
13 #include "lyxrc.h"
14 #include "debug.h"
15 #include "lyx_cb.h" // for ShowMessage() ... to be removed?
16 #include "gettext.h"
17 #include "LString.h"
18
19 #include "frontends/Alert.h" //to be removed?
20
21 #include "support/filetools.h"
22 #include "support/path.h"
23 #include "support/systemcall.h"
24 #include "support/lyxfunctional.h"
25
26
27 namespace {
28
29 string const token_from("$$i");
30 string const token_path("$$p");
31
32 } //namespace anon
33
34 bool operator<(Format const & a, Format const & b)
35 {
36         // use the compare_ascii_no_case instead of compare_no_case,
37         // because in turkish, 'i' is not the lowercase version of 'I',
38         // and thus turkish locale breaks parsing of tags.
39
40         return compare_ascii_no_case(a.prettyname(), b.prettyname()) < 0;
41 }
42
43 Format::Format(string const & n, string const & e, string const & p,
44        string const & s, string const & v): name_(n),
45                                             extension_(e),
46                                             prettyname_(p),
47                                             shortcut_(s),
48                                             viewer_(v)
49 {}
50
51
52 bool Format::dummy() const
53 {
54         return extension().empty();
55 }
56
57
58 bool Format::isChildFormat() const
59 {
60         if (name_.empty())
61                 return false;
62         return isdigit(name_[name_.length() - 1]);
63 }
64
65
66 string const Format::parentFormat() const
67 {
68         return name_.substr(0, name_.length() - 1);
69 }
70
71
72 // This method should return a reference, and throw an exception
73 // if the format named name cannot be found (Lgb)
74 Format const * Formats::getFormat(string const & name) const
75 {
76         FormatList::const_iterator cit =
77                 find_if(formatlist.begin(), formatlist.end(),
78                         lyx::compare_memfun(&Format::name, name));
79         if (cit != formatlist.end())
80                 return &(*cit);
81         else
82                 return 0;
83 }
84
85
86 int Formats::getNumber(string const & name) const
87 {
88         FormatList::const_iterator cit =
89                 find_if(formatlist.begin(), formatlist.end(),
90                         lyx::compare_memfun(&Format::name, name));
91         if (cit != formatlist.end())
92                 return cit - formatlist.begin();
93         else
94                 return -1;
95 }
96
97
98 void Formats::add(string const & name)
99 {
100         if (!getFormat(name))
101                 add(name, name, name, string());
102 }
103
104
105 void Formats::add(string const & name, string const & extension,
106                   string const & prettyname, string const & shortcut)
107 {
108         FormatList::iterator it =
109                 find_if(formatlist.begin(), formatlist.end(),
110                         lyx::compare_memfun(&Format::name, name));
111         if (it == formatlist.end())
112                 formatlist.push_back(Format(name, extension, prettyname,
113                                             shortcut, ""));
114         else {
115                 string viewer = it->viewer();
116                 *it = Format(name, extension, prettyname, shortcut, viewer);
117         }
118 }
119
120
121 void Formats::erase(string const & name)
122 {
123         FormatList::iterator it =
124                 find_if(formatlist.begin(), formatlist.end(),
125                         lyx::compare_memfun(&Format::name, name));
126         if (it != formatlist.end())
127                 formatlist.erase(it);
128 }
129
130
131 void Formats::sort()
132 {
133         std::sort(formatlist.begin(), formatlist.end());
134 }
135
136
137 void Formats::setViewer(string const & name, string const & command)
138 {
139         add(name);
140         FormatList::iterator it =
141                 find_if(formatlist.begin(), formatlist.end(),
142                         lyx::compare_memfun(&Format::name, name));
143         if (it != formatlist.end())
144                 it->setViewer(command);
145 }
146
147
148 bool Formats::view(Buffer const * buffer, string const & filename,
149                    string const & format_name) const
150 {
151         if (filename.empty())
152                 return false;
153
154         Format const * format = getFormat(format_name);
155         if (format && format->viewer().empty() &&
156             format->isChildFormat())
157                 format = getFormat(format->parentFormat());
158         if (!format || format->viewer().empty()) {
159 // I believe this is the wrong place to show alerts, it should be done by
160 // the caller (this should be "utility" code
161                 Alert::error(_("Cannot view file"),
162                         bformat(_("No information for viewing %1$s"),
163                                 prettyName(format_name)));
164                 return false;
165         }
166
167         string command = format->viewer();
168
169         if (format_name == "dvi" &&
170             !lyxrc.view_dvi_paper_option.empty()) {
171                 command += ' ' + lyxrc.view_dvi_paper_option;
172                 string paper_size = papersize(buffer);
173                 if (paper_size == "letter")
174                         paper_size = "us";
175                 command += ' ' + paper_size;
176                 if (buffer->params.orientation
177                     == BufferParams::ORIENTATION_LANDSCAPE)
178                         command += 'r';
179         }
180
181         if (!contains(command, token_from))
182                 command += ' ' + token_from;
183
184         command = subst(command, token_from,
185                         QuoteName(OnlyFilename(filename)));
186         command = subst(command, token_path, QuoteName(OnlyPath(filename)));
187
188         lyxerr[Debug::FILES] << "Executing command: " << command << std::endl;
189         ShowMessage(buffer, _("Executing command:"), command);
190
191         Path p(OnlyPath(filename));
192         Systemcall one;
193         int const res = one.startscript(Systemcall::DontWait, command);
194
195         if (res) {
196                 Alert::error(_("Cannot view file"),
197                              bformat(_("An error occurred whilst running %1$s"),
198                                command.substr(0, 50)));
199                 return false;
200         }
201         return true;
202 }
203
204
205 string const Formats::prettyName(string const & name) const
206 {
207         Format const * format = getFormat(name);
208         if (format)
209                 return format->prettyname();
210         else
211                 return name;
212 }
213
214
215 string const Formats::extension(string const & name) const
216 {
217         Format const * format = getFormat(name);
218         if (format)
219                 return format->extension();
220         else
221                 return name;
222 }
223
224
225 string const papersize(Buffer const * buffer)
226 {
227         char real_papersize = buffer->params.papersize;
228         if (real_papersize == BufferParams::PAPER_DEFAULT)
229                 real_papersize = lyxrc.default_papersize;
230
231         switch (real_papersize) {
232         case BufferParams::PAPER_A3PAPER:
233                 return "a3";
234         case BufferParams::PAPER_A4PAPER:
235                 return "a4";
236         case BufferParams::PAPER_A5PAPER:
237                 return "a5";
238         case BufferParams::PAPER_B5PAPER:
239                 return "b5";
240         case BufferParams::PAPER_EXECUTIVEPAPER:
241                 return "foolscap";
242         case BufferParams::PAPER_LEGALPAPER:
243                 return "legal";
244         case BufferParams::PAPER_USLETTER:
245         default:
246                 return "letter";
247         }
248 }
249
250
251 Formats formats;
252
253 Formats system_formats;