]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTexinfo.cpp
* FileName::fileContents(): new argument to define the file encoding.
[lyx.git] / src / frontends / qt4 / GuiTexinfo.cpp
1 /**
2  * \file GuiTexinfo.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Herbert Voß
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiTexinfo.h"
15
16 #include "FuncRequest.h"
17 #include "support/debug.h"
18
19 #include "support/filetools.h"
20 #include "support/FileName.h"
21 #include "support/lstrings.h"
22
23 #include "qt_helpers.h"
24
25 #include <QCloseEvent>
26 #include <QCheckBox>
27 #include <QListWidget>
28 #include <QPushButton>
29
30 #include <fstream>
31 #include <algorithm>
32
33 using std::string;
34 using std::vector;
35 using std::endl;
36
37 namespace lyx {
38 namespace frontend {
39
40 using support::FileName;
41 using support::contains;
42 using support::split;
43 using support::token;
44 using support::getExtension;
45 using support::libFileSearch;
46 using support::onlyFilename;
47
48 static string texFileFromList(string const & file, string const & type)
49 {
50         string file_ = file;
51         // do we need to add the suffix?
52         if (!(getExtension(file) == type))
53                 file_ += '.' + type;
54
55         lyxerr << "Searching for file " << file_ << endl;
56
57         string lstfile = type + "Files.lst";
58         if (type == "cls")
59                 lstfile = "clsFiles.lst";
60         else if (type == "sty")
61                 lstfile = "styFiles.lst";
62         else if (type == "bst")
63                 lstfile = "bstFiles.lst";
64         else if (type == "bib")
65                 lstfile = "bibFiles.lst";
66         FileName const abslstfile = libFileSearch(string(), lstfile);
67         if (abslstfile.empty()) {
68                 lyxerr << "File `'" << lstfile << "' not found." << endl;
69                 return string();
70         }
71         // FIXME UNICODE
72         string const allClasses = to_utf8(abslstfile.fileContents("UTF-8"));
73         int entries = 0;
74         string classfile = token(allClasses, '\n', entries);
75         int count = 0;
76         while ((!contains(classfile, file) ||
77                 (onlyFilename(classfile) != file)) &&
78                 (++count < 1000)) {
79                 classfile = token(allClasses, '\n', ++entries);
80         }
81
82         // now we have filename with full path
83         lyxerr << "with full path: " << classfile << endl;
84
85         return classfile;
86 }
87
88
89 GuiTexInfo::GuiTexInfo(GuiView & lv)
90         : GuiDialog(lv, "texinfo")
91 {
92         setupUi(this);
93         setViewTitle(_("TeX Information"));
94
95         warningPosted = false;
96         activeStyle = ClsType;
97
98         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
99
100         connect(viewPB, SIGNAL(clicked()), this, SLOT(viewClicked()));
101         connect(whatStyleCO, SIGNAL(activated(QString)),
102                 this, SLOT(enableViewPB()));
103         connect(whatStyleCO, SIGNAL(activated(int)), this, SLOT(updateView()));
104         connect(pathCB, SIGNAL(stateChanged(int)), this, SLOT(updateView()));
105         connect(rescanPB, SIGNAL(clicked()), this, SLOT(enableViewPB()));
106         connect(rescanPB, SIGNAL(clicked()), this, SLOT(rescanClicked()));
107         connect(fileListLW, SIGNAL(itemClicked(QListWidgetItem *)),
108                 this, SLOT(enableViewPB()));
109         connect(fileListLW, SIGNAL(itemSelectionChanged()),
110                 this, SLOT(enableViewPB()));
111
112         updateStyles(ClsType);
113
114         bc().setPolicy(ButtonPolicy::OkCancelPolicy);
115         bc().setCancel(closePB);
116 }
117
118
119 void GuiTexInfo::change_adaptor()
120 {
121         changed();
122 }
123
124
125 void GuiTexInfo::closeEvent(QCloseEvent * e)
126 {
127         slotClose();
128         e->accept();
129 }
130
131
132 void GuiTexInfo::rescanClicked()
133 {
134         // build new *Files.lst
135         rescanTexStyles();
136         updateStyles();
137         enableViewPB();
138 }
139
140
141 void GuiTexInfo::viewClicked()
142 {
143         size_t const fitem = fileListLW->currentRow();
144         vector<string> const & data = texdata_[activeStyle];
145         string file = data[fitem];
146         if (!pathCB->isChecked())
147                 file = texFileFromList(data[fitem], fileType(activeStyle));
148         viewFile(file);
149 }
150
151
152 void GuiTexInfo::updateView()
153 {
154         // takes advantage of enum order
155         updateStyles(static_cast<TexFileType>(whatStyleCO->currentIndex()));
156         enableViewPB();
157 }
158
159
160 void GuiTexInfo::enableViewPB()
161 {
162         viewPB->setEnabled(fileListLW->currentRow() > -1);
163 }
164
165
166 void GuiTexInfo::updateStyles(TexFileType type)
167 {
168         ContentsType & data = texdata_[type];
169
170         static string filenames[] = { "clsFile.lst", "styFiles.lst", "bstFiles.lst" };
171         string filename = filenames[type];
172
173         getTexFileList(filename, data);
174         if (data.empty()) {
175                 // build filelists of all availabe bst/cls/sty-files.
176                 // Done through kpsewhich and an external script,
177                 // saved in *Files.lst
178                 rescanTexStyles();
179                 getTexFileList(filename, data);
180         }
181         bool const withFullPath = pathCB->isChecked();
182         if (withFullPath)
183                 return;
184         vector<string>::iterator it1  = data.begin();
185         vector<string>::iterator end1 = data.end();
186         for (; it1 != end1; ++it1)
187                 *it1 = support::onlyFilename(*it1);
188
189         // sort on filename only (no path)
190         std::sort(data.begin(), data.end());
191
192         fileListLW->clear();
193         ContentsType::const_iterator it  = data.begin();
194         ContentsType::const_iterator end = data.end();
195         for (; it != end; ++it)
196                 fileListLW->addItem(toqstr(*it));
197
198         activeStyle = type;
199 }
200
201
202 void GuiTexInfo::updateStyles()
203 {
204         updateStyles(activeStyle);
205 }
206
207
208 void GuiTexInfo::viewFile(string const & filename) const
209 {
210         dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + filename));
211 }
212
213
214 /// get a class with full path from the list
215 string GuiTexInfo::classOptions(string const & classname) const
216 {
217         FileName const filename(texFileFromList(classname, "cls"));
218         if (filename.empty())
219                 return string();
220         string optionList;
221         std::ifstream is(filename.toFilesystemEncoding().c_str());
222         while (is) {
223                 string s;
224                 is >> s;
225                 if (contains(s, "DeclareOption")) {
226                         s = s.substr(s.find("DeclareOption"));
227                         s = split(s, '{');              // cut front
228                         s = token(s, '}', 0);           // cut end
229                         optionList += (s + '\n');
230                 }
231         }
232         return optionList;
233 }
234
235
236 string GuiTexInfo::fileType(TexFileType type) const
237 {
238         // takes advantage of enum order
239         static string const ext[] = { "cls", "sty", "bst" };
240         return ext[type];
241 }
242
243
244 Dialog * createGuiTexInfo(GuiView & lv) { return new GuiTexInfo(lv); }
245
246
247 } // namespace frontend
248 } // namespace lyx
249
250
251 #include "GuiTexinfo_moc.cpp"