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