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