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