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