]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiTexinfo.cpp
pimpl not needed here
[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 "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         string const allClasses = abslstfile.fileContents();
72         int entries = 0;
73         string classfile = token(allClasses, '\n', entries);
74         int count = 0;
75         while ((!contains(classfile, file) ||
76                 (onlyFilename(classfile) != file)) &&
77                 (++count < 1000)) {
78                 classfile = token(allClasses, '\n', ++entries);
79         }
80
81         // now we have filename with full path
82         lyxerr << "with full path: " << classfile << endl;
83
84         return classfile;
85 }
86
87
88 GuiTexInfo::GuiTexInfo(LyXView & lv)
89         : GuiDialog(lv, "texinfo")
90 {
91         setupUi(this);
92         setViewTitle(_("TeX Information"));
93
94         warningPosted = false;
95         activeStyle = ClsType;
96
97         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
98
99         connect(viewPB, SIGNAL(clicked()), this, SLOT(viewClicked()));
100         connect(whatStyleCO, SIGNAL(activated(QString)),
101                 this, SLOT(enableViewPB()));
102         connect(whatStyleCO, SIGNAL(activated(int)), this, SLOT(updateView()));
103         connect(pathCB, SIGNAL(stateChanged(int)), this, SLOT(updateView()));
104         connect(rescanPB, SIGNAL(clicked()), this, SLOT(enableViewPB()));
105         connect(rescanPB, SIGNAL(clicked()), this, SLOT(rescanClicked()));
106         connect(fileListLW, SIGNAL(itemClicked(QListWidgetItem *)),
107                 this, SLOT(enableViewPB()));
108         connect(fileListLW, SIGNAL(itemSelectionChanged()),
109                 this, SLOT(enableViewPB()));
110
111         updateStyles(ClsType);
112
113         bc().setPolicy(ButtonPolicy::OkCancelPolicy);
114         bc().setCancel(closePB);
115 }
116
117
118 void GuiTexInfo::change_adaptor()
119 {
120         changed();
121 }
122
123
124 void GuiTexInfo::closeEvent(QCloseEvent * e)
125 {
126         slotClose();
127         e->accept();
128 }
129
130
131 void GuiTexInfo::rescanClicked()
132 {
133         // build new *Files.lst
134         rescanTexStyles();
135         updateStyles();
136         enableViewPB();
137 }
138
139
140 void GuiTexInfo::viewClicked()
141 {
142         size_t const fitem = fileListLW->currentRow();
143         vector<string> const & data = texdata_[activeStyle];
144         string file = data[fitem];
145         if (!pathCB->isChecked())
146                 file = texFileFromList(data[fitem], fileType(activeStyle));
147         viewFile(file);
148 }
149
150
151 void GuiTexInfo::updateView()
152 {
153         // takes advantage of enum order
154         updateStyles(static_cast<TexFileType>(whatStyleCO->currentIndex()));
155         enableViewPB();
156 }
157
158
159 void GuiTexInfo::enableViewPB()
160 {
161         viewPB->setEnabled(fileListLW->currentRow() > -1);
162 }
163
164
165 void GuiTexInfo::updateStyles(TexFileType type)
166 {
167         ContentsType & data = texdata_[type];
168
169         static string filenames[] = { "clsFile.lst", "styFiles.lst", "bstFiles.lst" };
170         string filename = filenames[type];
171
172         getTexFileList(filename, data);
173         if (data.empty()) {
174                 // build filelists of all availabe bst/cls/sty-files.
175                 // Done through kpsewhich and an external script,
176                 // saved in *Files.lst
177                 rescanTexStyles();
178                 getTexFileList(filename, data);
179         }
180         bool const withFullPath = pathCB->isChecked();
181         if (withFullPath)
182                 return;
183         vector<string>::iterator it1  = data.begin();
184         vector<string>::iterator end1 = data.end();
185         for (; it1 != end1; ++it1)
186                 *it1 = support::onlyFilename(*it1);
187
188         // sort on filename only (no path)
189         std::sort(data.begin(), data.end());
190
191         fileListLW->clear();
192         ContentsType::const_iterator it  = data.begin();
193         ContentsType::const_iterator end = data.end();
194         for (; it != end; ++it)
195                 fileListLW->addItem(toqstr(*it));
196
197         activeStyle = type;
198 }
199
200
201 void GuiTexInfo::updateStyles()
202 {
203         updateStyles(activeStyle);
204 }
205
206
207 void GuiTexInfo::viewFile(string const & filename) const
208 {
209         dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + filename));
210 }
211
212
213 /// get a class with full path from the list
214 string GuiTexInfo::classOptions(string const & classname) const
215 {
216         FileName const filename(texFileFromList(classname, "cls"));
217         if (filename.empty())
218                 return string();
219         string optionList;
220         std::ifstream is(filename.toFilesystemEncoding().c_str());
221         while (is) {
222                 string s;
223                 is >> s;
224                 if (contains(s, "DeclareOption")) {
225                         s = s.substr(s.find("DeclareOption"));
226                         s = split(s, '{');              // cut front
227                         s = token(s, '}', 0);           // cut end
228                         optionList += (s + '\n');
229                 }
230         }
231         return optionList;
232 }
233
234
235 string GuiTexInfo::fileType(TexFileType type) const
236 {
237         // takes advantage of enum order
238         static string const ext[] = { "cls", "sty", "bst" };
239         return ext[type];
240 }
241
242
243 Dialog * createGuiTexInfo(LyXView & lv) { return new GuiTexInfo(lv); }
244
245
246 } // namespace frontend
247 } // namespace lyx
248
249
250 #include "GuiTexinfo_moc.cpp"