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