]> git.lyx.org Git - lyx.git/blob - src/lyxtextclasslist.C
John's Layout Tabular UI improvements and Martins fixes to clearing the
[lyx.git] / src / lyxtextclasslist.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2001 The LyX Team.
8  *
9  * ======================================================
10  */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "lyxtextclasslist.h"
19 #include "lyxtextclass.h"
20 #include "debug.h"
21 #include "lyxlex.h"
22 #include "gettext.h"
23
24 #include "frontends/Alert.h"
25
26 #include "support/lyxfunctional.h"
27 #include "support/LAssert.h"
28 #include "support/filetools.h"
29
30 #include <utility>
31
32 using lyx::layout_type;
33 using lyx::textclass_type;
34 using std::pair;
35 using std::make_pair;
36 using std::endl;
37
38
39 // Gets textclass number from name
40 pair<bool, textclass_type> const
41 LyXTextClassList::NumberOfClass(string const & textclass) const
42 {
43         ClassList::const_iterator cit =
44                 find_if(classlist.begin(), classlist.end(),
45                         lyx::compare_memfun(&LyXTextClass::name, textclass));
46         return cit != classlist.end() ?
47                 make_pair(true, textclass_type(cit - classlist.begin())) :
48                 make_pair(false, textclass_type(0));
49 }
50
51
52 // Gets layout structure from style number and textclass number
53 LyXLayout const &
54 LyXTextClassList::Style(textclass_type textclass,
55                         layout_type layout) const
56 {
57         classlist[textclass].load();
58         if (layout < classlist[textclass].numLayouts())
59                 return classlist[textclass][layout];
60         return classlist[textclass][0];
61 }
62
63
64 // Gets layout number from name and textclass number
65 pair<bool, layout_type> const
66 LyXTextClassList::NumberOfLayout(textclass_type textclass,
67                                  string const & name) const
68 {
69         classlist[textclass].load();
70         for (unsigned int i = 0; i < classlist[textclass].numLayouts(); ++i) {
71                 if (classlist[textclass][i].name() == name)
72                         return make_pair(true, i);
73         }
74         return make_pair(false, layout_type(0)); // not found
75 }
76
77
78 // Gets a layout (style) name from layout number and textclass number
79 string const &
80 LyXTextClassList::NameOfLayout(textclass_type textclass,
81                           layout_type layout) const
82 {
83         static string const dummy("dummy");
84         classlist[textclass].load();
85         if (layout < classlist[textclass].numLayouts())
86                 return classlist[textclass][layout].name();
87         return dummy;
88 }
89
90
91 // Gets a textclass name from number
92 string const &
93 LyXTextClassList::NameOfClass(textclass_type number) const
94 {
95         static string const dummy("dummy");
96         if (classlist.empty()) {
97                 return dummy;
98         }
99         lyx::Assert(number < classlist.size());
100         return classlist[number].name();
101 }
102
103
104 // Gets a textclass latexname from number
105 string const &
106 LyXTextClassList::LatexnameOfClass(textclass_type number) const
107 {
108         static string const dummy("dummy");
109         classlist[number].load();
110         if (classlist.empty()) {
111                 return dummy;
112         }
113         lyx::Assert(number < classlist.size());
114         return classlist[number].latexname();
115 }
116
117
118 // Gets a textclass description from number
119 string const &
120 LyXTextClassList::DescOfClass(textclass_type number) const
121 {
122         static string const dummy("dummy");
123         if (classlist.empty()) {
124                 return dummy;
125         }
126         lyx::Assert(number < classlist.size());
127         return classlist[number].description();
128 }
129
130
131 // Gets a textclass structure from number
132 LyXTextClass const &
133 LyXTextClassList::TextClass(textclass_type textclass) const
134 {
135         classlist[textclass].load();
136         if (textclass < classlist.size())
137                 return classlist[textclass];
138         else
139                 return classlist[0];
140 }
141
142
143 void LyXTextClassList::Add(LyXTextClass const & t)
144 {
145         classlist.push_back(t);
146 }
147
148
149 // used when sorting the textclass list.
150 class less_textclass_desc {
151 public:
152         int operator()(LyXTextClass const & tc1, LyXTextClass const & tc2) {
153                 return tc1.description() < tc2.description();
154         }
155 };
156
157
158 // Reads LyX textclass definitions according to textclass config file
159 bool LyXTextClassList::Read ()
160 {
161         LyXLex lex(0, 0);
162         string real_file = LibFileSearch("", "textclass.lst");
163         lyxerr[Debug::TCLASS] << "Reading textclasses from `"
164                               << real_file << "'" << endl;
165
166         if (real_file.empty()) {
167                 lyxerr << "LyXTextClassList::Read: unable to find "
168                         "textclass file  `" << MakeDisplayPath(real_file, 1000)
169                        << "'. Exiting." << endl;
170
171                 Alert::alert(_("LyX wasn't able to find its layout descriptions!"),
172                            _("Check that the file \"textclass.lst\""),
173                            _("is installed correctly. Sorry, has to exit :-("));
174                 return false;
175                 // This causes LyX to end... Not a desirable behaviour. Lgb
176                 // What do you propose? That the user gets a file dialog
177                 // and is allowed to hunt for the file? (Asger)
178                 // more that we have a layout for minimal.cls statically
179                 // compiled in... (Lgb)
180         }
181
182         if (!lex.setFile(real_file)) {
183                 lyxerr << "LyXTextClassList::Read: "
184                         "lyxlex was not able to set file: "
185                        << real_file << endl;
186         }
187         
188         if (!lex.isOK()) {
189                 lyxerr << "LyXTextClassList::Read: unable to open "
190                         "textclass file  `" << MakeDisplayPath(real_file, 1000)
191                        << "'\nCheck your installation. LyX can't continue."
192                        << endl;
193                 return false;
194         }
195
196         bool finished = false;
197         // Parse config-file
198         lyxerr[Debug::TCLASS] << "Starting parsing of textclass.lst" << endl;
199         while (lex.isOK() && !finished) {
200                 lyxerr[Debug::TCLASS] << "\tline by line" << endl;
201                 switch (lex.lex()) {
202                 case LyXLex::LEX_FEOF:
203                         finished = true;
204                         break;
205                 default:
206                         string const fname = lex.getString();
207                         lyxerr[Debug::TCLASS] << "Fname: " << fname << endl;
208                         if (lex.next()) {
209                                 string const clname = lex.getString();
210                                 lyxerr[Debug::TCLASS]
211                                         << "Clname: " << clname << endl;
212                                 if (lex.next()) {
213                                               string const desc = lex.getString();
214                                               lyxerr[Debug::TCLASS]
215                                                       << "Desc: " << desc << endl;
216                                               // This code is run when we have
217                                               // fname, clname and desc
218                                               LyXTextClass tmpl(fname,
219                                                                 clname,
220                                                                 desc);
221                                               if (lyxerr.
222                                                   debugging(Debug::TCLASS)) {
223                                                       tmpl.load();
224                                               }
225                                               Add (tmpl);
226                                 }
227                         }
228                 }
229         }
230         lyxerr[Debug::TCLASS] << "End of parsing of textclass.lst" << endl;
231
232         if (classlist.empty()) {
233                 lyxerr << "LyXTextClassList::Read: no textclasses found!"
234                        << endl;
235                 Alert::alert(_("LyX wasn't able to find any layout description!"),
236                            _("Check the contents of the file \"textclass.lst\""),
237                            _("Sorry, has to exit :-("));
238                 return false;
239         }
240         // Ok everything loaded ok, now sort the list.
241         sort(classlist.begin(), classlist.end(), less_textclass_desc());
242         return true;
243 }
244
245         
246 /* Load textclass
247    Returns false if this fails
248 */
249 bool LyXTextClassList::Load(textclass_type number) const
250 {
251         bool result = true;
252         if (number < classlist.size()) {
253                 classlist[number].load();
254                 if (classlist[number].numLayouts() == 0) {
255                         result = false;
256                 }
257         } else {
258                 result = false;
259         }
260         return result;
261 }
262
263
264 // Global variable: textclass table.
265 LyXTextClassList textclasslist;
266
267 // Reads the style files
268 void LyXSetStyle()
269 {
270         lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration...\n";
271         
272         if (!textclasslist.Read()) {
273                 lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured "
274                         "during parsing.\n             Exiting." << endl;
275                 exit(1);
276         }
277
278         lyxerr[Debug::TCLASS] << "LyXSetStyle: configuration parsed." << endl;
279 }