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