]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTexinfo.cpp
87778271257efc9ab2a0705150957fb762e9131d
[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                 (support::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         bc().setPolicy(ButtonPolicy::OkCancelPolicy);
103         bc().setCancel(closePB);
104 }
105
106
107 void GuiTexInfo::change_adaptor()
108 {
109         changed();
110 }
111
112
113 void GuiTexInfo::rescanClicked()
114 {
115         // build new *Files.lst
116         rescanTexStyles();
117         updateStyles();
118         enableViewPB();
119 }
120
121
122 void GuiTexInfo::viewClicked()
123 {
124         size_t const fitem = fileListLW->currentRow();
125         vector<string> const & data = texdata_[activeStyle];
126         string file = data[fitem];
127         if (!pathCB->isChecked())
128                 file = texFileFromList(data[fitem], fileType(activeStyle));
129         viewFile(file);
130 }
131
132
133 void GuiTexInfo::updateView()
134 {
135         // takes advantage of enum order
136         updateStyles(static_cast<TexFileType>(whatStyleCO->currentIndex()));
137         enableViewPB();
138 }
139
140
141 void GuiTexInfo::enableViewPB()
142 {
143         viewPB->setEnabled(fileListLW->currentRow() > -1);
144 }
145
146
147 void GuiTexInfo::updateStyles(TexFileType type)
148 {
149         ContentsType & data = texdata_[type];
150
151         static string filenames[] = { "clsFiles.lst", "styFiles.lst", "bstFiles.lst" };
152         string filename = filenames[type];
153
154         getTexFileList(filename, data);
155         if (data.empty()) {
156                 // build filelists of all availabe bst/cls/sty-files.
157                 // Done through kpsewhich and an external script,
158                 // saved in *Files.lst
159                 rescanTexStyles();
160                 getTexFileList(filename, data);
161         }
162         if (!pathCB->isChecked()) {
163                 vector<string>::iterator it1  = data.begin();
164                 vector<string>::iterator end1 = data.end();
165                 for (; it1 != end1; ++it1)
166                         *it1 = support::onlyFilename(*it1);
167         }
168         // sort on filename only (no path)
169         sort(data.begin(), data.end());
170
171         fileListLW->clear();
172         ContentsType::const_iterator it  = data.begin();
173         ContentsType::const_iterator end = data.end();
174         for (; it != end; ++it)
175                 fileListLW->addItem(toqstr(*it));
176
177         activeStyle = type;
178 }
179
180
181 void GuiTexInfo::updateStyles()
182 {
183         updateStyles(activeStyle);
184 }
185
186
187 void GuiTexInfo::viewFile(string const & filename) const
188 {
189         dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + filename));
190 }
191
192
193 /// get a class with full path from the list
194 string GuiTexInfo::classOptions(string const & classname) const
195 {
196         FileName const filename(texFileFromList(classname, "cls"));
197         if (filename.empty())
198                 return string();
199         string optionList;
200         ifstream is(filename.toFilesystemEncoding().c_str());
201         while (is) {
202                 string s;
203                 is >> s;
204                 if (contains(s, "DeclareOption")) {
205                         s = s.substr(s.find("DeclareOption"));
206                         s = split(s, '{');              // cut front
207                         s = token(s, '}', 0);           // cut end
208                         optionList += (s + '\n');
209                 }
210         }
211         return optionList;
212 }
213
214
215 string GuiTexInfo::fileType(TexFileType type) const
216 {
217         // takes advantage of enum order
218         static string const ext[] = { "cls", "sty", "bst" };
219         return ext[type];
220 }
221
222
223 Dialog * createGuiTexInfo(GuiView & lv) { return new GuiTexInfo(lv); }
224
225
226 } // namespace frontend
227 } // namespace lyx
228
229
230 #include "GuiTexinfo_moc.cpp"