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