]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiListings.cpp
a0bf60f310ce39b85bca3cf91d06e3db3b93eeef
[lyx.git] / src / frontends / qt4 / GuiListings.cpp
1 /**
2  * \file GuiListings.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Bo Peng
7  * \author Jürgen Spitzmüller
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiListings.h"
15
16 #include "ControlListings.h"
17 #include "qt_helpers.h"
18 #include "insets/InsetListingsParams.h"
19 #include "debug.h"
20
21 #include "support/convert.h"
22 #include "support/lstrings.h"
23
24 #include <QLineEdit>
25 #include <QCloseEvent>
26 #include <QPushButton>
27 #include <QValidator>
28 #include <QRegExpValidator>
29
30
31 using std::string;
32 using std::vector;
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;
39
40 namespace lyx {
41 namespace frontend {
42
43 /////////////////////////////////////////////////////////////////////
44 //
45 // GuiListingsDialog
46 //
47 /////////////////////////////////////////////////////////////////////
48
49
50 char const * languages[] =
51 { "no language", "ABAP", "ACSL", "Ada", "ALGOL", "Assembler", "Awk", "bash", "Basic", "C",
52   "C++", "Caml", "Clean", "Cobol", "Comal 80", "command.com", "Comsol", "csh", "Delphi",
53   "Eiffel", "Elan", "Euphoria", "Fortran", "Gnuplot", "Haskell", "HTML", "IDL", "inform",
54   "Java", "JVMIS", "ksh", "Lingo", "Lisp", "Logo", "make", "Mathematica", "Matlab", "Mercury",
55   "MetaPost", "Miranda", "ML", "Modula-2", "MuPAD", "NASTRAN", "Oberon-2", "OCL", "Octave",
56   "Oz", "Pascal", "Perl", "PHP", "PL/I", "Plasm", "PostScript", "POV", "Prolog", "Promela",
57   "PSTricks", "Python", "R", "Reduce", "Rexx", "RSL", "Ruby", "S", "SAS", "Scilab", "sh",
58   "SHELXL", "Simula", "tcl", "SPARQL", "SQL", "tcl", "TeX", "VBScript", "Verilog", "VHDL",
59   "VRML", "XML", "XSLT", "" };
60
61
62 char const * languages_gui[] =
63 { N_("No language"), "ABAP", "ACSL", "Ada", "ALGOL", "Assembler", "Awk", "bash", "Basic",
64   "C", "C++", "Caml", "Clean", "Cobol", "Comal 80", "command.com", "Comsol", "csh", "Delphi",
65   "Eiffel", "Elan", "Euphoria", "Fortran", "Gnuplot", "Haskell", "HTML", "IDL", "inform",
66   "Java", "JVMIS", "ksh", "Lingo", "Lisp", "Logo", "make", "Mathematica", "Matlab", "Mercury",
67   "MetaPost", "Miranda", "ML", "Modula-2", "MuPAD", "NASTRAN", "Oberon-2", "OCL", "Octave",
68   "Oz", "Pascal", "Perl", "PHP", "PL/I", "Plasm", "PostScript", "POV", "Prolog", "Promela",
69   "PSTricks", "Python", "R", "Reduce", "Rexx", "RSL", "Ruby", "S", "SAS", "Scilab", "sh",
70   "SHELXL", "Simula", "tcl", "SPARQL", "SQL", "tcl", "TeX", "VBScript", "Verilog", "VHDL",
71   "VRML", "XML", "XSLT", "" };
72
73
74 struct dialect_info {
75         /// the dialect
76         char const * dialect;
77         /// the associated language
78         char const * language;
79         /// representation of the dialect in the gui
80         char const * gui;
81         /// is this the default dialect?
82         bool is_default;
83 };
84
85
86 dialect_info const dialects[] = {
87         { "R/2 4.3", "ABAP", "R/2 4.3", false },
88         { "R/2 5.0", "ABAP", "R/2 5.0", false },
89         { "R/3 3.1", "ABAP", "R/3 3.1", false },
90         { "R/3 4.6C", "ABAP", "R/3 4.6C", false },
91         { "R/3 6.10", "ABAP", "R/3 6.10", true },
92         { "2005", "Ada", "2005", true },
93         { "83", "Ada", "83", false },
94         { "95", "Ada", "95", false },
95         { "60", "Algol", "60", false },
96         { "68", "Algol", "68", true },
97         { "Motorola68k", "Assembler", "Motorola 68xxx", false },
98         { "x86masm", "Assembler", "x86 (MASM)", false },
99         { "gnu", "Awk", "gnu", true },
100         { "POSIX", "Awk", "POSIX", false },
101         { "Visual", "Basic", "Visual", false },
102         { "ANSI", "C", "ANSI", true },
103         { "Handel", "C", "Handel", false },
104         { "Objective", "C", "Objective", false },
105         { "Sharp", "C", "Sharp", false },
106         { "ANSI", "C++", "ANSI", false },
107         { "GNU", "C++", "GNU", false },
108         { "ISO", "C++", "ISO", true },
109         { "Visual", "C++", "Visual", false },
110         { "light", "Caml", "light", true },
111         { "Objective", "Caml", "Objective", false },
112         { "1974", "Cobol", "1974", false },
113         { "1985", "Cobol", "1985", true },
114         { "ibm", "Cobol", "IBM", false },
115         { "WinXP", "command.com", "Windows XP", true },
116         { "77", "Fortran", "77", false },
117         { "90", "Fortran", "90", false },
118         { "95", "Fortran", "95", true },
119         { "CORBA", "IDL", "CORBA", false },
120         { "AspectJ", "Java", "Aspect J", false },
121         { "Auto", "Lisp", "Auto", false },
122         { "gnu", "make", "gnu", false },
123         { "1.0", "Mathematica", "1.0", false },
124         { "3.0", "Mathematica", "3.0", false },
125         { "5.2", "Mathematica", "5.2", true },
126         { "decorative", "OCL", "decorative", false },
127         { "OMG", "OCL", "OMG", true },
128         { "Borland6", "Pascal", "Borland 6", false },
129         { "Standard", "Pascal", "Standard", true },
130         { "XSC", "Pascal", "XSC", false },
131         { "PLUS", "S", "PLUS", false },
132         { "67", "Simula", "67", true },
133         { "CII", "Simula", "CII", false },
134         { "DEC", "Simula", "DEC", false },
135         { "IBM", "Simula", "IBM", false },
136         { "tk", "tcl", "tk", false },
137         { "AlLaTeX", "TeX", "AlLaTeX", false },
138         { "common", "TeX", "common", false },
139         { "LaTeX", "TeX", "LaTeX", false },
140         { "plain", "TeX", "plain", true },
141         { "primitive", "TeX", "primitive", false },
142         { "AMS", "VHDL", "AMS", false },
143         { "97", "VRML", "97", true }
144 };
145
146
147 size_t const nr_dialects = sizeof(dialects) / sizeof(dialect_info);
148
149
150 char const * font_sizes[] =
151 { "default", "tiny", "scriptsize", "footnotesize", "small", "normalsize", "large",
152   "Large", "" };
153
154 char const * font_sizes_gui[] =
155 { N_("Default"), N_("Tiny"), N_("Smallest"), N_("Smaller"), N_("Small"), N_("Normal"),
156   N_("Large"), N_("Larger"), "" };
157
158 char const * font_styles[] =
159 { "default", "rmfamily", "ttfamily", "sffamily", "" };
160
161 char const * font_styles_gui[] =
162 { N_("Default"), N_("Roman"), N_("Typewriter"), N_("Sans Serif"), "" };
163
164
165
166 GuiListingsDialog::GuiListingsDialog(LyXView & lv)
167         : GuiDialog(lv, "listings")
168 {
169         setupUi(this);
170         setViewTitle(_("Program Listing Settings"));
171         setController(new ControlListings(*this));
172
173         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
174         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
175         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
176
177         connect(languageCO, SIGNAL(currentIndexChanged(int)),
178                 this, SLOT(change_adaptor()));
179         connect(dialectCO, SIGNAL(currentIndexChanged(int)),
180                 this, SLOT(change_adaptor()));
181         connect(inlineCB, SIGNAL(clicked()),
182                 this, SLOT(change_adaptor()));
183         connect(floatCB, SIGNAL(clicked()),
184                 this, SLOT(change_adaptor()));
185         connect(placementLE, SIGNAL(textChanged(const QString&)),
186                 this, SLOT(change_adaptor()));
187         connect(numberSideCO, SIGNAL(currentIndexChanged(int)),
188                 this, SLOT(change_adaptor()));
189         connect(numberStepLE, SIGNAL(textChanged(const QString&)),
190                 this, SLOT(change_adaptor()));
191         connect(numberFontSizeCO, SIGNAL(currentIndexChanged(int)),
192                 this, SLOT(change_adaptor()));
193         connect(firstlineLE, SIGNAL(textChanged(const QString&)),
194                 this, SLOT(change_adaptor()));
195         connect(lastlineLE, SIGNAL(textChanged(const QString&)),
196                 this, SLOT(change_adaptor()));
197         connect(fontsizeCO, SIGNAL(currentIndexChanged(int)),
198                 this, SLOT(change_adaptor()));
199         connect(fontstyleCO, SIGNAL(currentIndexChanged(int)),
200                 this, SLOT(change_adaptor()));
201         connect(breaklinesCB, SIGNAL(clicked()),
202                 this, SLOT(change_adaptor()));
203         connect(spaceCB, SIGNAL(clicked()),
204                 this, SLOT(change_adaptor()));
205         connect(spaceInStringCB, SIGNAL(clicked()),
206                 this, SLOT(change_adaptor()));
207         connect(extendedcharsCB, SIGNAL(clicked()),
208                 this, SLOT(change_adaptor()));
209
210         connect(listingsED,  SIGNAL(textChanged()),
211                 this, SLOT(change_adaptor()));
212         connect(listingsED,  SIGNAL(textChanged()),
213                 this, SLOT(set_listings_msg()));
214         connect(bypassCB, SIGNAL(clicked()),
215                 this, SLOT(change_adaptor()));
216         connect(bypassCB, SIGNAL(clicked()),
217                 this, SLOT(set_listings_msg()));
218
219         for (int n = 0; languages[n][0]; ++n)
220                 languageCO->addItem(qt_(languages_gui[n]));
221
222         for (int n = 0; font_styles[n][0]; ++n)
223                 fontstyleCO->addItem(qt_(font_styles_gui[n]));
224
225         for (int n = 0; font_sizes[n][0]; ++n) {
226                 QString font = qt_(font_sizes_gui[n]);
227                 fontsizeCO->addItem(font);
228                 numberFontSizeCO->addItem(font);
229         }
230
231         // set validators
232         numberStepLE->setValidator(new QIntValidator(0, 1000000, this));
233         firstlineLE->setValidator(new QIntValidator(0, 1000000, this));
234         lastlineLE->setValidator(new QIntValidator(0, 1000000, this));
235         placementLE->setValidator(new QRegExpValidator(QRegExp("[\\*tbph]*"), this));
236
237         bc().setOK(okPB);
238         bc().setApply(applyPB);
239         bc().setCancel(closePB);
240         listingsTB->setPlainText(
241                 qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
242
243         update_contents();
244
245 }
246
247
248 ControlListings & GuiListingsDialog::controller() const
249 {
250         return static_cast<ControlListings &>(GuiDialog::controller());
251 }
252
253
254 void GuiListingsDialog::closeEvent(QCloseEvent * e)
255 {
256         slotWMHide();
257         e->accept();
258 }
259
260
261 void GuiListingsDialog::change_adaptor()
262 {
263         changed();
264 }
265
266
267 string GuiListingsDialog::construct_params()
268 {
269         string language = languages[languageCO->currentIndex()];
270         string dialect;
271         string const dialect_gui = fromqstr(dialectCO->currentText());
272         if (dialectCO->currentIndex() > 0) {
273                 for (size_t i = 0; i < nr_dialects; ++i) {
274                         if (dialect_gui == dialects[i].gui
275                         && dialects[i].language == language
276                         && !dialects[i].is_default) {
277                                 dialect = dialects[i].dialect;
278                                 break;
279                         }
280                 }
281         }
282
283         bool float_ = floatCB->isChecked();
284         string placement;
285         if (placementLE->isEnabled())
286                 placement = fromqstr(placementLE->text());
287
288         string numberSide;
289         switch (numberSideCO->currentIndex()) {
290         case 0:
291                 numberSide = "none";
292                 break;
293         case 1:
294                 numberSide = "left";
295                 break;
296         case 2:
297                 numberSide = "right";
298                 break;
299         default:
300                 numberSide = "none";
301                 break;
302         }
303         string stepnumber = fromqstr(numberStepLE->text());
304         string numberfontsize = font_sizes[numberFontSizeCO->currentIndex()];
305         string firstline = fromqstr(firstlineLE->text());
306         string lastline = fromqstr(lastlineLE->text());
307
308         string fontsize = font_sizes[fontsizeCO->currentIndex()];
309         string fontstyle = font_styles[fontstyleCO->currentIndex()];
310         string basicstyle;
311         if (fontsize != "default")
312                 basicstyle = "\\" + fontsize;
313         if (fontstyle != "default")
314                 basicstyle += "\\" + fontstyle;
315         bool breakline = breaklinesCB->isChecked();
316         bool space = spaceCB->isChecked();
317         bool spaceInString = spaceInStringCB->isChecked();
318         bool extendedchars = extendedcharsCB->isChecked();
319         string extra = fromqstr(listingsED->toPlainText());
320
321         // compose a string
322         InsetListingsParams par;
323         if (language != "no language" && !contains(extra, "language=")) {
324                 if (dialect.empty())
325                         par.addParam("language", language);
326                 else
327                         par.addParam("language", "{[" + dialect + "]" + language + "}");
328         }
329         // this dialog uses float=placement instead of float,floatplacement=placement
330         // because float accepts *tbph and floatplacement accepts bph.
331         // our placement textedit is actually for the float parameter
332         if (float_)
333                 par.addParam("float", placement);
334         if (numberSide != "none")
335                 par.addParam("numbers", numberSide);
336         if (numberfontsize != "default" && numberSide != "none")
337                 par.addParam("numberstyle", "\\" + numberfontsize);
338         if (!stepnumber.empty() && numberSide != "none")
339                 par.addParam("stepnumber", stepnumber);
340         if (!firstline.empty())
341                 par.addParam("firstline", firstline);
342         if (!lastline.empty())
343                 par.addParam("lastline", lastline);
344         if (!basicstyle.empty())
345                 par.addParam("basicstyle", basicstyle);
346         if (breakline)
347                 par.addParam("breaklines", "true");
348         if (space)
349                 par.addParam("showspaces", "true");
350         if (!spaceInString)
351                 par.addParam("showstringspaces", "false");
352         if (extendedchars)
353                 par.addParam("extendedchars", "true");
354         par.addParams(extra);
355         return par.params();
356 }
357
358
359 docstring GuiListingsDialog::validate_listings_params()
360 {
361         // use a cache here to avoid repeated validation
362         // of the same parameters
363         static string param_cache = string();
364         static docstring msg_cache = docstring();
365         
366         if (bypassCB->isChecked())
367                 return docstring();
368
369         string params = construct_params();
370         if (params != param_cache) {
371                 param_cache = params;
372                 msg_cache = InsetListingsParams(params).validate();
373         }
374         return msg_cache;
375 }
376
377
378 void GuiListingsDialog::set_listings_msg()
379 {
380         static bool isOK = true;
381         docstring msg = validate_listings_params();
382         if (msg.empty()) {
383                 if (isOK)
384                         return;
385                 isOK = true;
386                 listingsTB->setPlainText(
387                         qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
388         } else {
389                 isOK = false;
390                 listingsTB->setPlainText(toqstr(msg));
391         }
392 }
393
394
395 void GuiListingsDialog::on_floatCB_stateChanged(int state)
396 {
397         if (state == Qt::Checked) {
398                 inlineCB->setChecked(false);
399                 placementLE->setEnabled(true);
400         } else
401                 placementLE->setEnabled(false);
402 }
403
404
405 void GuiListingsDialog::on_inlineCB_stateChanged(int state)
406 {
407         if (state == Qt::Checked) {
408                 floatCB->setChecked(false);
409                 placementLE->setEnabled(false);
410         }
411 }
412
413
414 void GuiListingsDialog::on_numberSideCO_currentIndexChanged(int index)
415 {
416         numberStepLE->setEnabled(index > 0);
417         numberFontSizeCO->setEnabled(index > 0);
418 }
419
420
421 void GuiListingsDialog::on_languageCO_currentIndexChanged(int index)
422 {
423         dialectCO->clear();
424         // 0 is "no dialect"
425         int default_dialect = 0;
426         dialectCO->addItem(qt_("No dialect"));
427         string const language = languages[index];
428
429         for (size_t i = 0; i < nr_dialects; ++i) {
430                 if (language == dialects[i].language) {
431                         dialectCO->addItem(qt_(dialects[i].gui));
432                         if (dialects[i].is_default)
433                                 default_dialect =
434                                         dialectCO->findText(qt_(dialects[i].gui));
435                 }
436         }
437         dialectCO->setCurrentIndex(default_dialect);
438         dialectCO->setEnabled(dialectCO->count() > 1);
439 }
440
441
442 void GuiListingsDialog::applyView()
443 {
444         InsetListingsParams & params = controller().params();
445         params.setInline(inlineCB->isChecked());
446         params.setParams(construct_params());
447         controller().setParams(params);
448 }
449
450
451 static string plainParam(std::string const & par)
452 {
453         // remove enclosing braces
454         if (prefixIs(par, "{") && suffixIs(par, "}"))
455                 return par.substr(1, par.size() - 2);
456         return par;
457 }
458
459
460 void GuiListingsDialog::update_contents()
461 {
462         // set default values
463         listingsTB->setPlainText(
464                 qt_("Input listing parameters on the right. Enter ? for a list of parameters."));
465         languageCO->setCurrentIndex(findToken(languages, "no language"));
466         dialectCO->setCurrentIndex(0);
467         floatCB->setChecked(false);
468         placementLE->clear();
469         numberSideCO->setCurrentIndex(0);
470         numberStepLE->clear();
471         numberFontSizeCO->setCurrentIndex(findToken(font_sizes, "default"));
472         firstlineLE->clear();
473         lastlineLE->clear();
474         fontstyleCO->setCurrentIndex(findToken(font_styles, "default"));
475         fontsizeCO->setCurrentIndex(findToken(font_sizes, "default"));
476         breaklinesCB->setChecked(false);
477         spaceCB->setChecked(false);
478         spaceInStringCB->setChecked(true);
479         extendedcharsCB->setChecked(false);
480
481         // set values from param string
482         InsetListingsParams & params = controller().params();
483         inlineCB->setChecked(params.isInline());
484         if (params.isInline()) {
485                 floatCB->setChecked(false);
486                 placementLE->setEnabled(false);
487         }
488         // break other parameters and set values
489         vector<string> pars = getVectorFromString(params.separatedParams(), "\n");
490         // process each of them
491         for (vector<string>::iterator it = pars.begin();
492             it != pars.end(); ++it) {
493                 if (prefixIs(*it, "language=")) {
494                         string arg = plainParam(it->substr(9));
495                         // has dialect?
496                         string language;
497                         string dialect;
498                         bool in_gui = false;
499                         if (prefixIs(arg, "[") && contains(arg, "]")) {
500                                 string::size_type end_dialect = arg.find("]");
501                                 dialect = arg.substr(1, end_dialect - 1);
502                                 language = arg.substr(end_dialect + 1);
503                         } else
504                                 language = arg;
505                         int n = findToken(languages, language);
506                         if (n >= 0) {
507                                 languageCO->setCurrentIndex(n);
508                                 in_gui = true;
509                         }
510                         // on_languageCO_currentIndexChanged should have set dialects
511                         if (!dialect.empty()) {
512                                 string dialect_gui;
513                                 for (size_t i = 0; i < nr_dialects; ++i) {
514                                         if (dialect == dialects[i].dialect
515                                             && dialects[i].language == language) {
516                                                 dialect_gui = dialects[i].gui;
517                                                 break;
518                                         }
519                                 }
520                                 n = dialectCO->findText(qt_(dialect_gui));
521                                 if (n >= 0)
522                                         dialectCO->setCurrentIndex(n);
523                                 else
524                                         in_gui = false;
525                         }
526                         if (in_gui)
527                                 *it = "";
528                         languageCO->setEnabled(in_gui);
529                         dialectCO->setEnabled(
530                                 in_gui && dialectCO->count() > 1);
531                 } else if (prefixIs(*it, "float")) {
532                         floatCB->setChecked(true);
533                         inlineCB->setChecked(false);
534                         placementLE->setEnabled(true);
535                         if (prefixIs(*it, "float="))
536                                 placementLE->setText(
537                                         toqstr(plainParam(it->substr(6))));
538                         *it = "";
539                 } else if (prefixIs(*it, "numbers=")) {
540                         string s = plainParam(it->substr(8));
541                         int n = 0;
542                         if (s == "left")
543                                 n = 1;
544                         else if (s == "right")
545                                 n = 2;
546                         numberSideCO->setCurrentIndex(n);
547                         *it = "";
548                 } else if (prefixIs(*it, "stepnumber=")) {
549                         numberStepLE->setText(
550                                 toqstr(plainParam(it->substr(11))));
551                         *it = "";
552                 } else if (prefixIs(*it, "numberstyle=")) {
553                         string par = plainParam(it->substr(12));
554                         int n = findToken(font_sizes, par.substr(1));
555                         if (n >= 0)
556                                 numberFontSizeCO->setCurrentIndex(n);
557                         *it = "";
558                 } else if (prefixIs(*it, "firstline=")) {
559                         firstlineLE->setText(
560                                 toqstr(plainParam(it->substr(10))));
561                         *it = "";
562                 } else if (prefixIs(*it, "lastline=")) {
563                         lastlineLE->setText(
564                                 toqstr(plainParam(it->substr(9))));
565                         *it = "";
566                 } else if (prefixIs(*it, "basicstyle=")) {
567                         string style;
568                         string size;
569                         for (int n = 0; font_styles[n][0]; ++n) {
570                                 string const s = font_styles[n];
571                                 if (contains(*it, "\\" + s)) {
572                                         style = "\\" + s;
573                                         break;
574                                 }
575                         }
576                         for (int n = 0; font_sizes[n][0]; ++n) {
577                                 string const s = font_sizes[n];
578                                 if (contains(*it, "\\" + s)) {
579                                         size = "\\" + s;
580                                         break;
581                                 }
582                         }
583                         if (plainParam(it->substr(11)) == style + size
584                             || plainParam(it->substr(11)) == size + style) {
585                                 if (!style.empty()) {
586                                         int n = findToken(font_styles, style.substr(1));
587                                         if (n >= 0)
588                                                 fontstyleCO->setCurrentIndex(n);
589                                 }
590                                 if (!size.empty()) {
591                                         int n = findToken(font_sizes, size.substr(1));
592                                         if (n >= 0)
593                                                 fontsizeCO->setCurrentIndex(n);
594                                 }
595                                 *it = "";
596                         }
597                 } else if (prefixIs(*it, "breaklines=")) {
598                         breaklinesCB->setChecked(contains(*it, "true"));
599                         *it = "";
600                 } else if (prefixIs(*it, "showspaces=")) {
601                         spaceCB->setChecked(contains(*it, "true"));
602                         *it = "";
603                 } else if (prefixIs(*it, "showstringspaces=")) {
604                         spaceInStringCB->setChecked(contains(*it, "true"));
605                         *it = "";
606                 } else if (prefixIs(*it, "extendedchars=")) {
607                         extendedcharsCB->setChecked(contains(*it, "true"));
608                         *it = "";
609                 }
610         }
611
612         numberStepLE->setEnabled(numberSideCO->currentIndex() > 0);
613         numberFontSizeCO->setEnabled(numberSideCO->currentIndex() > 0);
614         // parameters that can be handled by widgets are cleared
615         // the rest is put to the extra edit box.
616         string extra = getStringFromVector(pars);
617         listingsED->setPlainText(toqstr(InsetListingsParams(extra).separatedParams()));
618 }
619
620
621 bool GuiListingsDialog::isValid()
622 {
623         return validate_listings_params().empty();
624 }
625
626
627 } // namespace frontend
628 } // namespace lyx
629
630
631 #include "GuiListings_moc.cpp"