3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Jürgen Spitzmüller
9 * Full author contact details are available in file CREDITS.
14 #include "QListings.h"
16 #include "qt_helpers.h"
17 #include "controllers/ControlListings.h"
18 #include "insets/InsetListingsParams.h"
21 #include "support/convert.h"
22 #include "support/lstrings.h"
25 #include <QCloseEvent>
26 #include <QPushButton>
28 #include <QRegExpValidator>
33 using lyx::support::findToken;
34 using lyx::support::getVectorFromString;
35 using lyx::support::getStringFromVector;
36 using lyx::support::prefixIs;
37 using lyx::support::suffixIs;
38 using lyx::support::contains;
43 /////////////////////////////////////////////////////////////////////
47 /////////////////////////////////////////////////////////////////////
50 char const * languages[] =
51 { "no language", "ABAP", "ACSL", "Ada", "ALGOL", "C", "C++", "Caml", "Clean", "Cobol",
52 "Comal 80", "csh", "Delphi", "Eiffel", "Elan", "Euphoria", "Fortran", "Haskell",
53 "HTML", "IDL", "Java", "Lisp", "Logo", "make", "Mathematica", "Matlab", "Mercury",
54 "Miranda", "ML", "Modula-2", "Oberon-2", "OCL", "Pascal", "Perl", "PHP", "PL/I", "POV",
55 "Prolog", "Python", "R", "S", "SAS", "SHELXL", "Simula", "tcl", "SQL", "TeX", "VBScript",
58 char const * languages_gui[] =
59 { N_("No language"), "ABAP", "ACSL", "Ada", "ALGOL", "C", "C++", "Caml", "Clean", "Cobol",
60 "Comal 80", "csh", "Delphi", "Eiffel", "Elan", "Euphoria", "Fortran", "Haskell",
61 "HTML", "IDL", "Java", "Lisp", "Logo", "make", "Mathematica", "Matlab", "Mercury",
62 "Miranda", "ML", "Modula-2", "Oberon-2", "OCL", "Pascal", "Perl", "PHP", "PL/I", "POV",
63 "Prolog", "Python", "R", "S", "SAS", "SHELXL", "Simula", "tcl", "SQL", "TeX", "VBScript",
66 char const * font_sizes[] =
67 { "default", "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
70 char const * font_sizes_gui[] =
71 { N_("Default"), N_("Tiny"), N_("Smallest"), N_("Smaller"), N_("Small"), N_("Normal"),
72 N_("Large"), N_("Larger"), "" };
74 char const * font_styles[] =
75 { "default", "rmfamily", "ttfamily", "sffamily", "" };
77 char const * font_styles_gui[] =
78 { N_("Default"), N_("Roman"), N_("Typewriter"), N_("Sans Serif"), "" };
82 QListingsDialog::QListingsDialog(QListings * form)
87 connect(okPB, SIGNAL(clicked()), form, SLOT(slotOK()));
88 connect(applyPB, SIGNAL(clicked()), form_, SLOT(slotApply()));
89 connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose()));
91 connect(languageCO, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor()));
92 connect(inlineCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
93 connect(floatCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
94 connect(placementLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
95 connect(numberSideCO, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor()));
96 connect(numberStepLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
97 connect(numberFontSizeCO, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor()));
98 connect(firstlineLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
99 connect(lastlineLE, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor()));
100 connect(fontsizeCO, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor()));
101 connect(fontstyleCO, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor()));
102 connect(breaklinesCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
103 connect(spaceCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
104 connect(extendedcharsCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
106 connect(listingsED, SIGNAL(textChanged()), this, SLOT(change_adaptor()));
107 connect(listingsED, SIGNAL(textChanged()), this, SLOT(validate_listings_params()));
109 for (int n = 0; languages[n][0]; ++n)
110 languageCO->addItem(languages_gui[n]);
112 for (int n = 0; font_styles[n][0]; ++n)
113 fontstyleCO->addItem(font_styles_gui[n]);
115 for (int n = 0; font_sizes[n][0]; ++n) {
116 QString font = toqstr(font_sizes_gui[n]);
117 fontsizeCO->addItem(font);
118 numberFontSizeCO->addItem(font);
122 numberStepLE->setValidator(new QIntValidator(0, 1000000, this));
123 firstlineLE->setValidator(new QIntValidator(0, 1000000, this));
124 lastlineLE->setValidator(new QIntValidator(0, 1000000, this));
125 placementLE->setValidator(new QRegExpValidator(QRegExp("[tbph]*"), this));
129 void QListingsDialog::closeEvent(QCloseEvent * e)
136 void QListingsDialog::change_adaptor()
142 string QListingsDialog::construct_params()
144 string language = languages[languageCO->currentIndex()];
146 bool float_ = floatCB->isChecked();
148 if (placementLE->isEnabled())
149 placement = fromqstr(placementLE->text());
152 switch (numberSideCO->currentIndex()) {
160 numberSide = "right";
166 string stepnumber = fromqstr(numberStepLE->text());
167 string numberfontsize = font_sizes[numberFontSizeCO->currentIndex()];
168 string firstline = fromqstr(firstlineLE->text());
169 string lastline = fromqstr(lastlineLE->text());
171 string fontsize = font_sizes[fontsizeCO->currentIndex()];
172 string fontstyle = font_styles[fontstyleCO->currentIndex()];
174 if (fontsize != "default")
175 basicstyle = "\\" + fontsize;
176 if (fontstyle != "default")
177 basicstyle += "\\" + fontstyle;
178 bool breakline = breaklinesCB->isChecked();
179 bool space = spaceCB->isChecked();
180 bool extendedchars = extendedcharsCB->isChecked();
181 string extra = fromqstr(listingsED->toPlainText());
184 InsetListingsParams par;
185 if (language != "no language" && !contains(extra, "language="))
186 par.addParam("language", language);
188 par.addParam("float", "");
189 if (!placement.empty())
190 par.addParam("floatplacement", placement);
191 if (numberSide != "none")
192 par.addParam("numbers", numberSide);
193 if (numberfontsize != "default" && numberSide != "none")
194 par.addParam("numberstyle", "\\" + numberfontsize);
195 if (!stepnumber.empty() && numberSide != "none")
196 par.addParam("stepnumber", stepnumber);
197 if (!firstline.empty())
198 par.addParam("firstline", firstline);
199 if (!lastline.empty())
200 par.addParam("lastline", lastline);
201 if (!basicstyle.empty())
202 par.addParam("basicstyle", basicstyle);
204 par.addParam("breaklines", "true");
206 par.addParam("showspaces", "true");
208 par.addParam("extendedchars", "true");
209 par.addParams(extra);
214 void QListingsDialog::validate_listings_params()
216 static bool isOK = true;
218 InsetListingsParams par(construct_params());
221 listingsTB->setPlainText(
222 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
223 okPB->setEnabled(true);
224 applyPB->setEnabled(true);
226 } catch (invalidParam & e) {
228 listingsTB->setPlainText(e.what());
229 okPB->setEnabled(false);
230 applyPB->setEnabled(false);
235 void QListingsDialog::on_floatCB_stateChanged(int state)
237 if (state == Qt::Checked) {
238 inlineCB->setChecked(false);
239 placementLE->setEnabled(true);
241 placementLE->setEnabled(false);
245 void QListingsDialog::on_inlineCB_stateChanged(int state)
247 if (state == Qt::Checked) {
248 floatCB->setChecked(false);
249 placementLE->setEnabled(false);
254 void QListingsDialog::on_numberSideCO_currentIndexChanged(int index)
256 numberStepLE->setEnabled(index > 0);
257 numberFontSizeCO->setEnabled(index > 0);
261 /////////////////////////////////////////////////////////////////////
265 /////////////////////////////////////////////////////////////////////
267 typedef QController<ControlListings, QView<QListingsDialog> > listings_wrap_base_class;
269 QListings::QListings(Dialog & parent)
270 : listings_wrap_base_class(parent, _("Program Listings Settings"))
275 void QListings::build_dialog()
277 dialog_.reset(new QListingsDialog(this));
279 bcview().setOK(dialog_->okPB);
280 bcview().setApply(dialog_->applyPB);
281 bcview().setCancel(dialog_->closePB);
282 dialog_->listingsTB->setPlainText(
283 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
289 void QListings::apply()
291 InsetListingsParams & params = controller().params();
292 params.setInline(dialog_->inlineCB->isChecked());
293 params.setParams(dialog_->construct_params());
294 controller().setParams(params);
300 string plainParam(std::string const & par)
302 // remove enclosing braces
303 if (prefixIs(par, "{") && suffixIs(par, "}"))
304 return par.substr(1, par.size() - 2);
311 void QListings::update_contents()
313 // set default values
314 dialog_->listingsTB->setPlainText(
315 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
316 dialog_->languageCO->setCurrentIndex(findToken(languages, "no language"));
317 dialog_->floatCB->setChecked(false);
318 dialog_->placementLE->clear();
319 dialog_->numberSideCO->setCurrentIndex(0);
320 dialog_->numberStepLE->clear();
321 dialog_->numberFontSizeCO->setCurrentIndex(findToken(font_sizes, "default"));
322 dialog_->firstlineLE->clear();
323 dialog_->lastlineLE->clear();
324 dialog_->fontstyleCO->setCurrentIndex(findToken(font_styles, "default"));
325 dialog_->fontsizeCO->setCurrentIndex(findToken(font_sizes, "default"));
326 dialog_->breaklinesCB->setChecked(false);
327 dialog_->spaceCB->setChecked(false);
328 dialog_->extendedcharsCB->setChecked(false);
330 // set values from param string
331 InsetListingsParams & params = controller().params();
332 dialog_->inlineCB->setChecked(params.isInline());
333 if (params.isInline()) {
334 dialog_->floatCB->setChecked(false);
335 dialog_->placementLE->setEnabled(false);
337 // break other parameters and set values
338 vector<string> pars = getVectorFromString(params.separatedParams(), "\n");
339 // process each of them
340 for (vector<string>::iterator it = pars.begin();
341 it != pars.end(); ++it) {
342 if (prefixIs(*it, "language=")) {
343 int n = findToken(languages, plainParam(it->substr(9)));
345 dialog_->languageCO->setEnabled(true);
346 dialog_->languageCO->setCurrentIndex(n);
350 // a known language that is not in the gui
351 dialog_->languageCO->setEnabled(false);
352 } else if (prefixIs(*it, "floatplacement=")) {
353 dialog_->floatCB->setChecked(true);
354 dialog_->placementLE->setEnabled(true);
355 dialog_->placementLE->setText(
356 toqstr(plainParam(it->substr(15))));
357 dialog_->inlineCB->setChecked(false);
359 } else if (prefixIs(*it, "float")) {
360 dialog_->floatCB->setChecked(true);
361 dialog_->inlineCB->setChecked(false);
362 dialog_->placementLE->setEnabled(true);
363 if (prefixIs(*it, "float="))
364 dialog_->placementLE->setText(
365 toqstr(plainParam(it->substr(6))));
367 } else if (prefixIs(*it, "numbers=")) {
368 string s = plainParam(it->substr(8));
372 else if (s == "right")
374 dialog_->numberSideCO->setCurrentIndex(n);
376 } else if (prefixIs(*it, "stepnumber=")) {
377 dialog_->numberStepLE->setText(
378 toqstr(plainParam(it->substr(11))));
380 } else if (prefixIs(*it, "numberstyle=")) {
381 string par = plainParam(it->substr(12));
382 int n = findToken(font_sizes, par.substr(1));
384 dialog_->numberFontSizeCO->setCurrentIndex(n);
386 } else if (prefixIs(*it, "firstline=")) {
387 dialog_->firstlineLE->setText(
388 toqstr(plainParam(it->substr(10))));
390 } else if (prefixIs(*it, "lastline=")) {
391 dialog_->lastlineLE->setText(
392 toqstr(plainParam(it->substr(9))));
394 } else if (prefixIs(*it, "basicstyle=")) {
397 for (int n = 0; font_styles[n][0]; ++n) {
398 string const s = font_styles[n];
399 if (contains(*it, "\\" + s)) {
404 for (int n = 0; font_sizes[n][0]; ++n) {
405 string const s = font_sizes[n];
406 if (contains(*it, "\\" + s)) {
411 if (plainParam(it->substr(11)) == style + size
412 || plainParam(it->substr(11)) == size + style) {
413 if (!style.empty()) {
414 int n = findToken(font_styles, style.substr(1));
416 dialog_->fontstyleCO->setCurrentIndex(n);
419 int n = findToken(font_sizes, size.substr(1));
421 dialog_->fontsizeCO->setCurrentIndex(n);
425 } else if (prefixIs(*it, "breaklines=")) {
426 dialog_->breaklinesCB->setChecked(contains(*it, "true"));
428 } else if (prefixIs(*it, "showspaces=")) {
429 dialog_->spaceCB->setChecked(contains(*it, "true"));
431 } else if (prefixIs(*it, "extendedchars=")) {
432 dialog_->extendedcharsCB->setChecked(contains(*it, "true"));
437 dialog_->numberStepLE->setEnabled(dialog_->numberSideCO->currentIndex() > 0);
438 dialog_->numberFontSizeCO->setEnabled(dialog_->numberSideCO->currentIndex() > 0);
439 // parameters that can be handled by widgets are cleared
440 // the rest is put to the extra edit box.
441 string extra = getStringFromVector(pars);
442 dialog_->listingsED->setPlainText(toqstr(InsetListingsParams(extra).separatedParams()));
446 } // namespace frontend
450 #include "QListings_moc.cpp"