]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiInclude.cpp
math stuff
[lyx.git] / src / frontends / qt4 / GuiInclude.cpp
1 /**
2  * \file GuiInclude.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author John Levon
8  * \author Angus Leeming
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiInclude.h"
16
17 #include "frontend_helpers.h"
18
19 #include "Buffer.h"
20 #include "Format.h"
21 #include "FuncRequest.h"
22 #include "gettext.h"
23 #include "LyXRC.h"
24
25 #include "qt_helpers.h"
26 #include "LyXRC.h"
27
28 #include "support/os.h"
29 #include "support/lstrings.h"
30 #include "support/FileFilterList.h"
31 #include "support/filetools.h"
32
33 #include "insets/InsetListingsParams.h"
34 #include "insets/InsetInclude.h"
35
36 #include <QPushButton>
37 #include <QCheckBox>
38 #include <QCloseEvent>
39 #include <QLineEdit>
40
41 #include <utility>
42
43 using std::string;
44 using std::vector;
45 using std::pair;
46 using std::string;
47
48
49 namespace lyx {
50 namespace frontend {
51
52 using support::FileFilterList;
53 using support::FileName;
54 using support::isFileReadable;
55 using support::makeAbsPath;
56 using support::onlyPath;
57 using support::os::internal_path;
58 using support::prefixIs;
59 using support::getStringFromVector;
60 using support::getVectorFromString;
61
62
63 GuiInclude::GuiInclude(LyXView & lv)
64         : GuiDialog(lv, "include"), Controller(this), params_("include")
65 {
66         setupUi(this);
67         setViewTitle(_("Child Document"));
68         setController(this, false);
69
70         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
71         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
72
73         connect(visiblespaceCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
74         connect(filenameED, SIGNAL(textChanged(const QString &)),
75                 this, SLOT(change_adaptor()));
76         connect(editPB, SIGNAL(clicked()), this, SLOT(edit()));
77         connect(browsePB, SIGNAL(clicked()), this, SLOT(browse()));
78         connect(typeCO, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
79         connect(typeCO, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
80         connect(previewCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
81         connect(captionLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
82         connect(labelLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
83         connect(listingsED, SIGNAL(textChanged()), this, SLOT(change_adaptor()));
84         connect(listingsED, SIGNAL(textChanged()), this, SLOT(set_listings_msg()));
85         connect(bypassCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
86         connect(bypassCB, SIGNAL(clicked()), this, SLOT(set_listings_msg()));
87
88         setFocusProxy(filenameED);
89
90         bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
91         bc().setOK(okPB);
92         bc().setCancel(closePB);
93         bc().addReadOnly(filenameED);
94         bc().addReadOnly(browsePB);
95         bc().addReadOnly(visiblespaceCB);
96         bc().addReadOnly(typeCO);
97         bc().addReadOnly(listingsED);
98
99         bc().addCheckedLineEdit(filenameED, filenameLA);
100 }
101
102
103 void GuiInclude::change_adaptor()
104 {
105         changed();
106 }
107
108
109 docstring GuiInclude::validate_listings_params()
110 {
111         // use a cache here to avoid repeated validation
112         // of the same parameters
113         static string param_cache = string();
114         static docstring msg_cache = docstring();
115         
116         if (typeCO->currentIndex() != 3 || bypassCB->isChecked())
117                 return docstring();
118
119         string params = fromqstr(listingsED->toPlainText());
120         if (params != param_cache) {
121                 param_cache = params;
122                 msg_cache = InsetListingsParams(params).validate();
123         }
124         return msg_cache;
125 }
126
127
128 void GuiInclude::set_listings_msg()
129 {
130         static bool isOK = true;
131         docstring msg = validate_listings_params();
132         if (msg.empty()) {
133                 if (isOK)
134                         return;
135                 isOK = true;
136                 listingsTB->setPlainText(
137                         qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
138         } else {
139                 isOK = false;
140                 listingsTB->setPlainText(toqstr(msg));
141         }
142 }
143
144
145 void GuiInclude::closeEvent(QCloseEvent * e)
146 {
147         slotClose();
148         e->accept();
149 }
150
151
152 void GuiInclude::typeChanged(int v)
153 {
154         switch (v) {
155                 //case Include
156                 case 0:
157                         visiblespaceCB->setEnabled(false);
158                         visiblespaceCB->setChecked(false);
159                         previewCB->setEnabled(false);
160                         previewCB->setChecked(false);
161                         listingsGB->setEnabled(false);
162                         break;
163                 //case Input
164                 case 1:
165                         visiblespaceCB->setEnabled(false);
166                         visiblespaceCB->setChecked(false);
167                         previewCB->setEnabled(true);
168                         listingsGB->setEnabled(false);
169                         break;
170                 //case listings
171                 case 3:
172                         visiblespaceCB->setEnabled(false);
173                         visiblespaceCB->setChecked(false);
174                         previewCB->setEnabled(false);
175                         previewCB->setChecked(false);
176                         listingsGB->setEnabled(true);
177                         break;
178                 //case Verbatim
179                 default:
180                         visiblespaceCB->setEnabled(true);
181                         previewCB->setEnabled(false);
182                         previewCB->setChecked(false);
183                         listingsGB->setEnabled(false);
184                         break;
185         }
186         //see this thread 
187         //  http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg118471.html
188         //for the reason this is here.
189         okPB->setDefault(true);
190 }
191
192
193 void GuiInclude::updateContents()
194 {
195         filenameED->setText(toqstr(params_["filename"]));
196
197         visiblespaceCB->setChecked(false);
198         visiblespaceCB->setEnabled(false);
199         previewCB->setChecked(false);
200         previewCB->setEnabled(false);
201         listingsGB->setEnabled(false);
202         captionLE->clear();
203         labelLE->clear();
204         listingsED->clear();
205         listingsTB->setPlainText(
206                 qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
207
208         string cmdname = params_.getCmdName();
209         if (cmdname != "include" &&
210             cmdname != "verbatiminput" &&
211             cmdname != "verbatiminput*" &&
212                 cmdname != "lstinputlisting")
213                 cmdname = "input";
214
215         if (cmdname == "include") {
216                 typeCO->setCurrentIndex(0);
217
218         } else if (cmdname == "input") {
219                 typeCO->setCurrentIndex(1);
220                 previewCB->setEnabled(true);
221                 previewCB->setChecked(params_.preview());
222
223         } else if (cmdname == "verbatiminput*") {
224                 typeCO->setCurrentIndex(2);
225                 visiblespaceCB->setEnabled(true);
226                 visiblespaceCB->setChecked(true);
227
228         } else if (cmdname == "verbatiminput") {
229                 typeCO->setCurrentIndex(2);
230                 visiblespaceCB->setEnabled(true);
231
232         } else if (cmdname == "lstinputlisting") {
233                 typeCO->setCurrentIndex(3);
234                 listingsGB->setEnabled(true);
235                 listingsED->setEnabled(true);
236                 InsetListingsParams par(params_.getOptions());
237                 // extract caption and label and put them into their respective editboxes
238                 vector<string> pars = getVectorFromString(par.separatedParams(), "\n");
239                 for (vector<string>::iterator it = pars.begin();
240                         it != pars.end(); ++it) {
241                         if (prefixIs(*it, "caption=")) {
242                                 string cap = it->substr(8);
243                                 if (cap[0] == '{' && cap[cap.size() - 1] == '}') {
244                                         captionLE->setText(toqstr(cap.substr(1, cap.size() - 2)));
245                                         *it = "";
246                                 } 
247                         } else if (prefixIs(*it, "label=")) {
248                                 string lbl = it->substr(6);
249                                 if (lbl[0] == '{' && lbl[lbl.size()-1] == '}') {
250                                         labelLE->setText(toqstr(lbl.substr(1, lbl.size() - 2)));
251                                         *it = "";
252                                 }
253                         }
254                 }
255                 // the rest is put to the extra edit box.
256                 string extra = getStringFromVector(pars);
257                 listingsED->setPlainText(toqstr(InsetListingsParams(extra).separatedParams()));
258         }
259 }
260
261
262 void GuiInclude::applyView()
263 {
264         params_["filename"] = from_utf8(internal_path(fromqstr(filenameED->text())));
265         params_.preview(previewCB->isChecked());
266
267         int const item = typeCO->currentIndex();
268         if (item == 0) {
269                 params_.setCmdName("include");
270         } else if (item == 1) {
271                 params_.setCmdName("input");
272         } else if (item == 3) {
273                 params_.setCmdName("lstinputlisting");
274                 // the parameter string should have passed validation
275                 InsetListingsParams par(fromqstr(listingsED->toPlainText()));
276                 string caption = fromqstr(captionLE->text());
277                 string label = fromqstr(labelLE->text());
278                 if (!caption.empty())
279                         par.addParam("caption", "{" + caption + "}");
280                 if (!label.empty())
281                         par.addParam("label", "{" + label + "}");
282                 params_.setOptions(par.params());
283         } else {
284                 if (visiblespaceCB->isChecked())
285                         params_.setCmdName("verbatiminput*");
286                 else
287                         params_.setCmdName("verbatiminput");
288         }
289 }
290
291
292 void GuiInclude::browse()
293 {
294         Type type;
295
296         int const item = typeCO->currentIndex();
297         if (item == 0)
298                 type = INCLUDE;
299         else if (item == 1)
300                 type = INPUT;
301         else if (item == 2)
302                 type = VERBATIM;
303         else
304                 type = LISTINGS;
305
306         docstring const & name = browse(qstring_to_ucs4(filenameED->text()), type);
307         if (!name.empty())
308                 filenameED->setText(toqstr(name));
309 }
310
311
312 void GuiInclude::edit()
313 {
314         if (isValid()) {
315                 string const file = fromqstr(filenameED->text());
316                 slotOK();
317                 edit(file);
318         }
319 }
320
321
322 bool GuiInclude::isValid()
323 {
324         return !filenameED->text().isEmpty() && validate_listings_params().empty();
325 }
326
327
328 bool GuiInclude::initialiseParams(string const & data)
329 {
330         InsetIncludeMailer::string2params(data, params_);
331         return true;
332 }
333
334
335 void GuiInclude::clearParams()
336 {
337         params_.clear();
338 }
339
340
341 void GuiInclude::dispatchParams()
342 {
343         dispatch(FuncRequest(getLfun(), InsetIncludeMailer::params2string(params_)));
344 }
345
346
347 docstring GuiInclude::browse(docstring const & in_name, Type in_type) const
348 {
349         docstring const title = _("Select document to include");
350
351         // input TeX, verbatim, or LyX file ?
352         FileFilterList filters;
353         switch (in_type) {
354         case INCLUDE:
355         case INPUT:
356                 filters = FileFilterList(_("LaTeX/LyX Documents (*.tex *.lyx)"));
357                 break;
358         case VERBATIM:
359                 break;
360         case LISTINGS:
361                 break;
362         }
363
364         pair<docstring, docstring> dir1(_("Documents|#o#O"),
365                 from_utf8(lyxrc.document_path));
366
367         docstring const docpath = from_utf8(onlyPath(buffer().fileName()));
368
369         return browseRelFile(in_name, docpath, title,
370                              filters, false, dir1);
371 }
372
373
374 void GuiInclude::edit(string const & file)
375 {
376         string const ext = support::getExtension(file);
377         if (ext == "lyx")
378                 dispatch(FuncRequest(LFUN_BUFFER_CHILD_OPEN, file));
379         else
380                 // tex file or other text file in verbatim mode
381                 formats.edit(buffer(), 
382                         FileName(makeAbsPath(file, onlyPath(buffer().fileName()))),
383                         "text");
384 }
385
386
387 Dialog * createGuiInclude(LyXView & lv) { return new GuiInclude(lv); }
388
389
390 } // namespace frontend
391 } // namespace lyx
392
393 #include "GuiInclude_moc.cpp"