]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiPrefs.cpp
next one
[lyx.git] / src / frontends / qt4 / GuiPrefs.cpp
1 /**
2  * \file GuiPrefs.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 "GuiPrefs.h"
14
15 #include "qt_helpers.h"
16 #include "GuiApplication.h"
17
18 #include "BufferList.h"
19 #include "Color.h"
20 #include "ConverterCache.h"
21 #include "debug.h"
22 #include "Font.h"
23 #include "FuncRequest.h"
24 #include "gettext.h"
25 #include "GuiFontExample.h"
26 #include "PanelStack.h"
27 #include "paper.h"
28 #include "Session.h"
29
30 #include "support/lstrings.h"
31 #include "support/os.h"
32 #include "support/FileFilterList.h"
33
34 #include "frontend_helpers.h"
35
36 #include "frontends/alert.h"
37 #include "frontends/Application.h"
38
39 #include <QCheckBox>
40 #include <QColorDialog>
41 #include <QFontDatabase>
42 #include <QLineEdit>
43 #include <QPushButton>
44 #include <QSpinBox>
45 #include <QString>
46 #include <QValidator>
47 #include <QCloseEvent>
48
49 #include <iomanip>
50 #include <sstream>
51 #include <algorithm>
52 #include <utility>
53
54 using namespace Ui;
55
56 using std::endl;
57 using std::ostringstream;
58 using std::pair;
59 using std::string;
60 using std::vector;
61
62 namespace lyx {
63 namespace frontend {
64
65 using support::compare_ascii_no_case;
66 using support::os::external_path;
67 using support::os::external_path_list;
68 using support::os::internal_path;
69 using support::os::internal_path_list;
70 using support::FileFilterList;
71
72
73 /////////////////////////////////////////////////////////////////////
74 //
75 // Helpers
76 //
77 /////////////////////////////////////////////////////////////////////
78
79 template<class A>
80 static size_t findPos_helper(std::vector<A> const & vec, A const & val)
81 {
82         typedef typename std::vector<A>::const_iterator Cit;
83
84         Cit it = std::find(vec.begin(), vec.end(), val);
85         if (it == vec.end())
86                 return 0;
87         return std::distance(vec.begin(), it);
88 }
89
90
91 static std::pair<string, string> parseFontName(string const & name)
92 {
93         string::size_type const idx = name.find('[');
94         if (idx == string::npos || idx == 0)
95                 return make_pair(name, string());
96         return make_pair(name.substr(0, idx - 1),
97                          name.substr(idx + 1, name.size() - idx - 2));
98 }
99
100
101 static void setComboxFont(QComboBox * cb, string const & family,
102         string const & foundry)
103 {
104         QString fontname = toqstr(family);
105         if (!foundry.empty())
106                 fontname += " [" + toqstr(foundry) + ']';
107
108         for (int i = 0; i < cb->count(); ++i) {
109                 if (cb->itemText(i) == fontname) {
110                         cb->setCurrentIndex(i);
111                         return;
112                 }
113         }
114
115         // Try matching without foundry name
116
117         // We count in reverse in order to prefer the Xft foundry
118         for (int i = cb->count(); --i >= 0;) {
119                 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
120                 if (compare_ascii_no_case(tmp.first, family) == 0) {
121                         cb->setCurrentIndex(i);
122                         return;
123                 }
124         }
125
126         // family alone can contain e.g. "Helvetica [Adobe]"
127         pair<string, string> tmpfam = parseFontName(family);
128
129         // We count in reverse in order to prefer the Xft foundry
130         for (int i = cb->count() - 1; i >= 0; --i) {
131                 pair<string, string> tmp = parseFontName(fromqstr(cb->itemText(i)));
132                 if (compare_ascii_no_case(tmp.first, tmpfam.first) == 0) {
133                         cb->setCurrentIndex(i);
134                         return;
135                 }
136         }
137
138         // Bleh, default fonts, and the names couldn't be found. Hack
139         // for bug 1063.
140
141         QFont font;
142         font.setKerning(false);
143
144         if (family == theApp()->romanFontName()) {
145                 font.setStyleHint(QFont::Serif);
146                 font.setFamily(family.c_str());
147         } else if (family == theApp()->sansFontName()) {
148                 font.setStyleHint(QFont::SansSerif);
149                 font.setFamily(family.c_str());
150         } else if (family == theApp()->typewriterFontName()) {
151                 font.setStyleHint(QFont::TypeWriter);
152                 font.setFamily(family.c_str());
153         } else {
154                 lyxerr << "FAILED to find the default font: '"
155                        << foundry << "', '" << family << '\''<< endl;
156                 return;
157         }
158
159         QFontInfo info(font);
160         pair<string, string> tmp = parseFontName(fromqstr(info.family()));
161         string const & default_font_name = tmp.first;
162         lyxerr << "Apparent font is " << default_font_name << endl;
163
164         for (int i = 0; i < cb->count(); ++i) {
165                 lyxerr << "Looking at " << fromqstr(cb->itemText(i)) << endl;
166                 if (compare_ascii_no_case(fromqstr(cb->itemText(i)),
167                                     default_font_name) == 0) {
168                         cb->setCurrentIndex(i);
169                         return;
170                 }
171         }
172
173         lyxerr << "FAILED to find the font: '"
174                << foundry << "', '" << family << '\'' <<endl;
175 }
176
177
178 /////////////////////////////////////////////////////////////////////
179 //
180 // PrefPlaintext
181 //
182 /////////////////////////////////////////////////////////////////////
183
184 PrefPlaintext::PrefPlaintext(QWidget * parent)
185         : PrefModule(_("Plain text"), 0, parent)
186 {
187         setupUi(this);
188         connect(plaintextLinelengthSB, SIGNAL(valueChanged(int)),
189                 this, SIGNAL(changed()));
190         connect(plaintextRoffED, SIGNAL(textChanged(const QString&)),
191                 this, SIGNAL(changed()));
192 }
193
194
195 void PrefPlaintext::apply(LyXRC & rc) const
196 {
197         rc.plaintext_linelen = plaintextLinelengthSB->value();
198         rc.plaintext_roff_command = fromqstr(plaintextRoffED->text());
199 }
200
201
202 void PrefPlaintext::update(LyXRC const & rc)
203 {
204         plaintextLinelengthSB->setValue(rc.plaintext_linelen);
205         plaintextRoffED->setText(toqstr(rc.plaintext_roff_command));
206 }
207
208
209 /////////////////////////////////////////////////////////////////////
210 //
211 // PrefDate
212 //
213 /////////////////////////////////////////////////////////////////////
214
215 PrefDate::PrefDate(QWidget * parent)
216         : PrefModule(_("Date format"), 0, parent)
217 {
218         setupUi(this);
219         connect(DateED, SIGNAL(textChanged(const QString &)),
220                 this, SIGNAL(changed()));
221 }
222
223
224 void PrefDate::apply(LyXRC & rc) const
225 {
226         rc.date_insert_format = fromqstr(DateED->text());
227 }
228
229
230 void PrefDate::update(LyXRC const & rc)
231 {
232         DateED->setText(toqstr(rc.date_insert_format));
233 }
234
235
236 /////////////////////////////////////////////////////////////////////
237 //
238 // PrefKeyboard
239 //
240 /////////////////////////////////////////////////////////////////////
241
242 PrefKeyboard::PrefKeyboard(GuiPreferences * form, QWidget * parent)
243         : PrefModule(_("Keyboard"), form, parent)
244 {
245         setupUi(this);
246
247         connect(keymapCB, SIGNAL(clicked()),
248                 this, SIGNAL(changed()));
249         connect(firstKeymapED, SIGNAL(textChanged(const QString&)),
250                 this, SIGNAL(changed()));
251         connect(secondKeymapED, SIGNAL(textChanged(const QString&)),
252                 this, SIGNAL(changed()));
253 }
254
255
256 void PrefKeyboard::apply(LyXRC & rc) const
257 {
258         // FIXME: can derive CB from the two EDs
259         rc.use_kbmap = keymapCB->isChecked();
260         rc.primary_kbmap = internal_path(fromqstr(firstKeymapED->text()));
261         rc.secondary_kbmap = internal_path(fromqstr(secondKeymapED->text()));
262 }
263
264
265 void PrefKeyboard::update(LyXRC const & rc)
266 {
267         // FIXME: can derive CB from the two EDs
268         keymapCB->setChecked(rc.use_kbmap);
269         firstKeymapED->setText(toqstr(external_path(rc.primary_kbmap)));
270         secondKeymapED->setText(toqstr(external_path(rc.secondary_kbmap)));
271 }
272
273
274 QString PrefKeyboard::testKeymap(QString keymap)
275 {
276         return toqstr(form_->browsekbmap(from_utf8(internal_path(fromqstr(keymap)))));
277 }
278
279
280 void PrefKeyboard::on_firstKeymapPB_clicked(bool)
281 {
282         QString const file = testKeymap(firstKeymapED->text());
283         if (!file.isEmpty())
284                 firstKeymapED->setText(file);
285 }
286
287
288 void PrefKeyboard::on_secondKeymapPB_clicked(bool)
289 {
290         QString const file = testKeymap(secondKeymapED->text());
291         if (!file.isEmpty())
292                 secondKeymapED->setText(file);
293 }
294
295
296 void PrefKeyboard::on_keymapCB_toggled(bool keymap)
297 {
298         firstKeymapLA->setEnabled(keymap);
299         secondKeymapLA->setEnabled(keymap);
300         firstKeymapED->setEnabled(keymap);
301         secondKeymapED->setEnabled(keymap);
302         firstKeymapPB->setEnabled(keymap);
303         secondKeymapPB->setEnabled(keymap);
304 }
305
306
307 /////////////////////////////////////////////////////////////////////
308 //
309 // PrefLatex
310 //
311 /////////////////////////////////////////////////////////////////////
312
313 PrefLatex::PrefLatex(GuiPreferences * form, QWidget * parent)
314         : PrefModule(_("LaTeX"), form, parent)
315 {
316         setupUi(this);
317         connect(latexEncodingED, SIGNAL(textChanged(const QString&)),
318                 this, SIGNAL(changed()));
319         connect(latexChecktexED, SIGNAL(textChanged(const QString&)),
320                 this, SIGNAL(changed()));
321         connect(latexBibtexED, SIGNAL(textChanged(const QString&)),
322                 this, SIGNAL(changed()));
323         connect(latexIndexED, SIGNAL(textChanged(const QString&)),
324                 this, SIGNAL(changed()));
325         connect(latexAutoresetCB, SIGNAL(clicked()),
326                 this, SIGNAL(changed()));
327         connect(latexDviPaperED, SIGNAL(textChanged(const QString&)),
328                 this, SIGNAL(changed()));
329         connect(latexPaperSizeCO, SIGNAL(activated(int)),
330                 this, SIGNAL(changed()));
331
332 #if defined(__CYGWIN__) || defined(_WIN32)
333         pathCB->setVisible(true);
334         connect(pathCB, SIGNAL(clicked()), 
335                 this, SIGNAL(changed()));
336 #else
337         pathCB->setVisible(false);
338 #endif
339 }
340
341
342 void PrefLatex::apply(LyXRC & rc) const
343 {
344         rc.fontenc = fromqstr(latexEncodingED->text());
345         rc.chktex_command = fromqstr(latexChecktexED->text());
346         rc.bibtex_command = fromqstr(latexBibtexED->text());
347         rc.index_command = fromqstr(latexIndexED->text());
348         rc.auto_reset_options = latexAutoresetCB->isChecked();
349         rc.view_dvi_paper_option = fromqstr(latexDviPaperED->text());
350         rc.default_papersize =
351                 form_->toPaperSize(latexPaperSizeCO->currentIndex());
352 #if defined(__CYGWIN__) || defined(_WIN32)
353         rc.windows_style_tex_paths = pathCB->isChecked();
354 #endif
355 }
356
357
358 void PrefLatex::update(LyXRC const & rc)
359 {
360         latexEncodingED->setText(toqstr(rc.fontenc));
361         latexChecktexED->setText(toqstr(rc.chktex_command));
362         latexBibtexED->setText(toqstr(rc.bibtex_command));
363         latexIndexED->setText(toqstr(rc.index_command));
364         latexAutoresetCB->setChecked(rc.auto_reset_options);
365         latexDviPaperED->setText(toqstr(rc.view_dvi_paper_option));
366         latexPaperSizeCO->setCurrentIndex(
367                 form_->fromPaperSize(rc.default_papersize));
368 #if defined(__CYGWIN__) || defined(_WIN32)
369         pathCB->setChecked(rc.windows_style_tex_paths);
370 #endif
371 }
372
373
374 /////////////////////////////////////////////////////////////////////
375 //
376 // PrefScreenFonts
377 //
378 /////////////////////////////////////////////////////////////////////
379
380 PrefScreenFonts::PrefScreenFonts(GuiPreferences * form, QWidget * parent)
381         : PrefModule(_("Screen fonts"), form, parent)
382 {
383         setupUi(this);
384
385         connect(screenRomanCO, SIGNAL(activated(const QString&)),
386                 this, SLOT(select_roman(const QString&)));
387         connect(screenSansCO, SIGNAL(activated(const QString&)),
388                 this, SLOT(select_sans(const QString&)));
389         connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
390                 this, SLOT(select_typewriter(const QString&)));
391
392         QFontDatabase fontdb;
393         QStringList families(fontdb.families());
394         for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
395                 screenRomanCO->addItem(*it);
396                 screenSansCO->addItem(*it);
397                 screenTypewriterCO->addItem(*it);
398         }
399         connect(screenRomanCO, SIGNAL(activated(const QString&)),
400                 this, SIGNAL(changed()));
401         connect(screenSansCO, SIGNAL(activated(const QString&)),
402                 this, SIGNAL(changed()));
403         connect(screenTypewriterCO, SIGNAL(activated(const QString&)),
404                 this, SIGNAL(changed()));
405         connect(screenZoomSB, SIGNAL(valueChanged(int)),
406                 this, SIGNAL(changed()));
407         connect(screenDpiSB, SIGNAL(valueChanged(int)),
408                 this, SIGNAL(changed()));
409         connect(screenTinyED, SIGNAL(textChanged(const QString&)),
410                 this, SIGNAL(changed()));
411         connect(screenSmallestED, SIGNAL(textChanged(const QString&)),
412                 this, SIGNAL(changed()));
413         connect(screenSmallerED, SIGNAL(textChanged(const QString&)),
414                 this, SIGNAL(changed()));
415         connect(screenSmallED, SIGNAL(textChanged(const QString&)),
416                 this, SIGNAL(changed()));
417         connect(screenNormalED, SIGNAL(textChanged(const QString&)),
418                 this, SIGNAL(changed()));
419         connect(screenLargeED, SIGNAL(textChanged(const QString&)),
420                 this, SIGNAL(changed()));
421         connect(screenLargerED, SIGNAL(textChanged(const QString&)),
422                 this, SIGNAL(changed()));
423         connect(screenLargestED, SIGNAL(textChanged(const QString&)),
424                 this, SIGNAL(changed()));
425         connect(screenHugeED, SIGNAL(textChanged(const QString&)),
426                 this, SIGNAL(changed()));
427         connect(screenHugerED, SIGNAL(textChanged(const QString&)),
428                 this, SIGNAL(changed()));
429
430         screenTinyED->setValidator(new QDoubleValidator(screenTinyED));
431         screenSmallestED->setValidator(new QDoubleValidator(screenSmallestED));
432         screenSmallerED->setValidator(new QDoubleValidator(screenSmallerED));
433         screenSmallED->setValidator(new QDoubleValidator(screenSmallED));
434         screenNormalED->setValidator(new QDoubleValidator(screenNormalED));
435         screenLargeED->setValidator(new QDoubleValidator(screenLargeED));
436         screenLargerED->setValidator(new QDoubleValidator(screenLargerED));
437         screenLargestED->setValidator(new QDoubleValidator(screenLargestED));
438         screenHugeED->setValidator(new QDoubleValidator(screenHugeED));
439         screenHugerED->setValidator(new QDoubleValidator(screenHugerED));
440 }
441
442
443 void PrefScreenFonts::apply(LyXRC & rc) const
444 {
445         LyXRC const oldrc(rc);
446
447         boost::tie(rc.roman_font_name, rc.roman_font_foundry)
448                 = parseFontName(fromqstr(screenRomanCO->currentText()));
449         boost::tie(rc.sans_font_name, rc.sans_font_foundry) =
450                 parseFontName(fromqstr(screenSansCO->currentText()));
451         boost::tie(rc.typewriter_font_name, rc.typewriter_font_foundry) =
452                 parseFontName(fromqstr(screenTypewriterCO->currentText()));
453
454         rc.zoom = screenZoomSB->value();
455         rc.dpi = screenDpiSB->value();
456         rc.font_sizes[Font::SIZE_TINY] = fromqstr(screenTinyED->text());
457         rc.font_sizes[Font::SIZE_SCRIPT] = fromqstr(screenSmallestED->text());
458         rc.font_sizes[Font::SIZE_FOOTNOTE] = fromqstr(screenSmallerED->text());
459         rc.font_sizes[Font::SIZE_SMALL] = fromqstr(screenSmallED->text());
460         rc.font_sizes[Font::SIZE_NORMAL] = fromqstr(screenNormalED->text());
461         rc.font_sizes[Font::SIZE_LARGE] = fromqstr(screenLargeED->text());
462         rc.font_sizes[Font::SIZE_LARGER] = fromqstr(screenLargerED->text());
463         rc.font_sizes[Font::SIZE_LARGEST] = fromqstr(screenLargestED->text());
464         rc.font_sizes[Font::SIZE_HUGE] = fromqstr(screenHugeED->text());
465         rc.font_sizes[Font::SIZE_HUGER] = fromqstr(screenHugerED->text());
466
467         if (rc.font_sizes != oldrc.font_sizes
468                 || rc.roman_font_name != oldrc.roman_font_name
469                 || rc.sans_font_name != oldrc.sans_font_name
470                 || rc.typewriter_font_name != oldrc.typewriter_font_name
471                 || rc.zoom != oldrc.zoom || rc.dpi != oldrc.dpi) {
472                 form_->updateScreenFonts();
473         }
474 }
475
476
477 void PrefScreenFonts::update(LyXRC const & rc)
478 {
479         setComboxFont(screenRomanCO, rc.roman_font_name,
480                         rc.roman_font_foundry);
481         setComboxFont(screenSansCO, rc.sans_font_name,
482                         rc.sans_font_foundry);
483         setComboxFont(screenTypewriterCO, rc.typewriter_font_name,
484                         rc.typewriter_font_foundry);
485
486         select_roman(screenRomanCO->currentText());
487         select_sans(screenSansCO->currentText());
488         select_typewriter(screenTypewriterCO->currentText());
489
490         screenZoomSB->setValue(rc.zoom);
491         screenDpiSB->setValue(rc.dpi);
492         screenTinyED->setText(toqstr(rc.font_sizes[Font::SIZE_TINY]));
493         screenSmallestED->setText(toqstr(rc.font_sizes[Font::SIZE_SCRIPT]));
494         screenSmallerED->setText(toqstr(rc.font_sizes[Font::SIZE_FOOTNOTE]));
495         screenSmallED->setText(toqstr(rc.font_sizes[Font::SIZE_SMALL]));
496         screenNormalED->setText(toqstr(rc.font_sizes[Font::SIZE_NORMAL]));
497         screenLargeED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGE]));
498         screenLargerED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGER]));
499         screenLargestED->setText(toqstr(rc.font_sizes[Font::SIZE_LARGEST]));
500         screenHugeED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGE]));
501         screenHugerED->setText(toqstr(rc.font_sizes[Font::SIZE_HUGER]));
502 }
503
504 void PrefScreenFonts::select_roman(const QString& name)
505 {
506         screenRomanFE->set(QFont(name), name);
507 }
508
509
510 void PrefScreenFonts::select_sans(const QString& name)
511 {
512         screenSansFE->set(QFont(name), name);
513 }
514
515
516 void PrefScreenFonts::select_typewriter(const QString& name)
517 {
518         screenTypewriterFE->set(QFont(name), name);
519 }
520
521
522 /////////////////////////////////////////////////////////////////////
523 //
524 // PrefColors
525 //
526 /////////////////////////////////////////////////////////////////////
527
528 namespace {
529
530 struct ColorSorter
531 {
532         bool operator()(Color::color const & lhs, Color::color const & rhs) const {
533                 return lcolor.getGUIName(lhs) < lcolor.getGUIName(rhs);
534         }
535 };
536
537 } // namespace anon
538
539 PrefColors::PrefColors(GuiPreferences * form, QWidget * parent)
540         : PrefModule( _("Colors"), form, parent)
541 {
542         setupUi(this);
543
544         // FIXME: all of this initialization should be put into the controller.
545         // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
546         // for some discussion of why that is not trivial.
547         QPixmap icon(32, 32);
548         for (int i = 0; i < Color::ignore; ++i) {
549                 Color::color lc = static_cast<Color::color>(i);
550                 if (lc == Color::none
551                         || lc == Color::black
552                         || lc == Color::white
553                         || lc == Color::red
554                         || lc == Color::green
555                         || lc == Color::blue
556                         || lc == Color::cyan
557                         || lc == Color::magenta
558                         || lc == Color::yellow
559                         || lc == Color::inherit
560                         || lc == Color::ignore) continue;
561
562                 lcolors_.push_back(lc);
563         }
564         std::sort(lcolors_.begin(), lcolors_.end(), ColorSorter());
565         vector<Color_color>::const_iterator cit = lcolors_.begin();
566         vector<Color_color>::const_iterator const end = lcolors_.end();
567         for (; cit != end; ++cit) {
568                         (void) new QListWidgetItem(QIcon(icon),
569                         toqstr(lcolor.getGUIName(*cit)), lyxObjectsLW);
570         }
571         curcolors_.resize(lcolors_.size());
572         newcolors_.resize(lcolors_.size());
573         // End initialization
574
575         connect(colorChangePB, SIGNAL(clicked()),
576                 this, SLOT(change_color()));
577         connect(lyxObjectsLW, SIGNAL(itemSelectionChanged()),
578                 this, SLOT(change_lyxObjects_selection()));
579         connect(lyxObjectsLW, SIGNAL(itemActivated(QListWidgetItem*)),
580                 this, SLOT(change_color()));
581 }
582
583
584 void PrefColors::apply(LyXRC & /*rc*/) const
585 {
586         for (unsigned int i = 0; i < lcolors_.size(); ++i)
587                 if (curcolors_[i] != newcolors_[i])
588                         form_->setColor(lcolors_[i], fromqstr(newcolors_[i]));
589 }
590
591
592 void PrefColors::update(LyXRC const & /*rc*/)
593 {
594         for (unsigned int i = 0; i < lcolors_.size(); ++i) {
595                 QColor color = QColor(guiApp->colorCache().get(lcolors_[i]));
596                 QPixmap coloritem(32, 32);
597                 coloritem.fill(color);
598                 lyxObjectsLW->item(i)->setIcon(QIcon(coloritem));
599                 newcolors_[i] = curcolors_[i] = color.name();
600         }
601         change_lyxObjects_selection();
602 }
603
604 void PrefColors::change_color()
605 {
606         int const row = lyxObjectsLW->currentRow();
607
608         // just to be sure
609         if (row < 0)
610                 return;
611
612         QString const color = newcolors_[row];
613         QColor c = QColorDialog::getColor(QColor(color), qApp->focusWidget());
614
615         if (c.isValid() && c.name() != color) {
616                 newcolors_[row] = c.name();
617                 QPixmap coloritem(32, 32);
618                 coloritem.fill(c);
619                 lyxObjectsLW->currentItem()->setIcon(QIcon(coloritem));
620                 // emit signal
621                 changed();
622         }
623 }
624
625 void PrefColors::change_lyxObjects_selection()
626 {
627         colorChangePB->setDisabled(lyxObjectsLW->currentRow() < 0);
628 }
629
630
631 /////////////////////////////////////////////////////////////////////
632 //
633 // PrefDisplay
634 //
635 /////////////////////////////////////////////////////////////////////
636
637 PrefDisplay::PrefDisplay(QWidget * parent)
638         : PrefModule(_("Graphics"), 0, parent)
639 {
640         setupUi(this);
641         connect(instantPreviewCO, SIGNAL(activated(int)),
642                 this, SIGNAL(changed()));
643         connect(displayGraphicsCO, SIGNAL(activated(int)),
644                 this, SIGNAL(changed()));
645 }
646
647
648 void PrefDisplay::apply(LyXRC & rc) const
649 {
650         switch (instantPreviewCO->currentIndex()) {
651                 case 0: rc.preview = LyXRC::PREVIEW_OFF; break;
652                 case 1: rc.preview = LyXRC::PREVIEW_NO_MATH; break;
653                 case 2: rc.preview = LyXRC::PREVIEW_ON; break;
654         }
655
656         lyx::graphics::DisplayType dtype;
657         switch (displayGraphicsCO->currentIndex()) {
658                 case 3: dtype = lyx::graphics::NoDisplay; break;
659                 case 2: dtype = lyx::graphics::ColorDisplay; break;
660                 case 1: dtype = lyx::graphics::GrayscaleDisplay;        break;
661                 case 0: dtype = lyx::graphics::MonochromeDisplay; break;
662                 default: dtype = lyx::graphics::GrayscaleDisplay;
663         }
664         rc.display_graphics = dtype;
665
666         // FIXME!! The graphics cache no longer has a changeDisplay method.
667 #if 0
668         if (old_value != rc.display_graphics) {
669                 lyx::graphics::GCache & gc = lyx::graphics::GCache::get();
670                 gc.changeDisplay();
671         }
672 #endif
673 }
674
675
676 void PrefDisplay::update(LyXRC const & rc)
677 {
678         switch (rc.preview) {
679         case LyXRC::PREVIEW_OFF:
680                 instantPreviewCO->setCurrentIndex(0);
681                 break;
682         case LyXRC::PREVIEW_NO_MATH :
683                 instantPreviewCO->setCurrentIndex(1);
684                 break;
685         case LyXRC::PREVIEW_ON :
686                 instantPreviewCO->setCurrentIndex(2);
687                 break;
688         }
689
690         int item = 2;
691         switch (rc.display_graphics) {
692                 case lyx::graphics::NoDisplay:          item = 3; break;
693                 case lyx::graphics::ColorDisplay:       item = 2; break;
694                 case lyx::graphics::GrayscaleDisplay:   item = 1; break;
695                 case lyx::graphics::MonochromeDisplay:  item = 0; break;
696                 default: break;
697         }
698         displayGraphicsCO->setCurrentIndex(item);
699 }
700
701
702 /////////////////////////////////////////////////////////////////////
703 //
704 // PrefPaths
705 //
706 /////////////////////////////////////////////////////////////////////
707
708 PrefPaths::PrefPaths(GuiPreferences * form, QWidget * parent)
709         : PrefModule(_("Paths"), form, parent)
710 {
711         setupUi(this);
712         connect(templateDirPB, SIGNAL(clicked()), this, SLOT(select_templatedir()));
713         connect(tempDirPB, SIGNAL(clicked()), this, SLOT(select_tempdir()));
714         connect(backupDirPB, SIGNAL(clicked()), this, SLOT(select_backupdir()));
715         connect(workingDirPB, SIGNAL(clicked()), this, SLOT(select_workingdir()));
716         connect(lyxserverDirPB, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
717         connect(workingDirED, SIGNAL(textChanged(const QString&)),
718                 this, SIGNAL(changed()));
719         connect(templateDirED, SIGNAL(textChanged(const QString&)),
720                 this, SIGNAL(changed()));
721         connect(backupDirED, SIGNAL(textChanged(const QString&)),
722                 this, SIGNAL(changed()));
723         connect(tempDirED, SIGNAL(textChanged(const QString&)),
724                 this, SIGNAL(changed()));
725         connect(lyxserverDirED, SIGNAL(textChanged(const QString&)),
726                 this, SIGNAL(changed()));
727         connect(pathPrefixED, SIGNAL(textChanged(const QString&)),
728                 this, SIGNAL(changed()));
729 }
730
731
732 void PrefPaths::apply(LyXRC & rc) const
733 {
734         rc.document_path = internal_path(fromqstr(workingDirED->text()));
735         rc.template_path = internal_path(fromqstr(templateDirED->text()));
736         rc.backupdir_path = internal_path(fromqstr(backupDirED->text()));
737         rc.tempdir_path = internal_path(fromqstr(tempDirED->text()));
738         rc.path_prefix = internal_path_list(fromqstr(pathPrefixED->text()));
739         // FIXME: should be a checkbox only
740         rc.lyxpipes = internal_path(fromqstr(lyxserverDirED->text()));
741 }
742
743
744 void PrefPaths::update(LyXRC const & rc)
745 {
746         workingDirED->setText(toqstr(external_path(rc.document_path)));
747         templateDirED->setText(toqstr(external_path(rc.template_path)));
748         backupDirED->setText(toqstr(external_path(rc.backupdir_path)));
749         tempDirED->setText(toqstr(external_path(rc.tempdir_path)));
750         pathPrefixED->setText(toqstr(external_path_list(rc.path_prefix)));
751         // FIXME: should be a checkbox only
752         lyxserverDirED->setText(toqstr(external_path(rc.lyxpipes)));
753 }
754
755
756 void PrefPaths::select_templatedir()
757 {
758         docstring file(form_->browsedir(
759                 from_utf8(internal_path(fromqstr(templateDirED->text()))),
760                 _("Select a document templates directory")));
761         if (!file.empty())
762                 templateDirED->setText(toqstr(file));
763 }
764
765
766 void PrefPaths::select_tempdir()
767 {
768         docstring file(form_->browsedir(
769                 from_utf8(internal_path(fromqstr(tempDirED->text()))),
770                 _("Select a temporary directory")));
771         if (!file.empty())
772                 tempDirED->setText(toqstr(file));
773 }
774
775
776 void PrefPaths::select_backupdir()
777 {
778         docstring file(form_->browsedir(
779                 from_utf8(internal_path(fromqstr(backupDirED->text()))),
780                 _("Select a backups directory")));
781         if (!file.empty())
782                 backupDirED->setText(toqstr(file));
783 }
784
785
786 void PrefPaths::select_workingdir()
787 {
788         docstring file(form_->browsedir(
789                 from_utf8(internal_path(fromqstr(workingDirED->text()))),
790                 _("Select a document directory")));
791         if (!file.empty())
792                 workingDirED->setText(toqstr(file));
793 }
794
795
796 void PrefPaths::select_lyxpipe()
797 {
798         docstring file(form_->browse(
799                 from_utf8(internal_path(fromqstr(lyxserverDirED->text()))),
800                 _("Give a filename for the LyX server pipe")));
801         if (!file.empty())
802                 lyxserverDirED->setText(toqstr(file));
803 }
804
805
806 /////////////////////////////////////////////////////////////////////
807 //
808 // PrefSpellchecker
809 //
810 /////////////////////////////////////////////////////////////////////
811
812 PrefSpellchecker::PrefSpellchecker(GuiPreferences * form, QWidget * parent)
813         : PrefModule(_("Spellchecker"), form, parent)
814 {
815         setupUi(this);
816
817         connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
818 #if defined (USE_ISPELL)
819         connect(spellCommandCO, SIGNAL(activated(int)),
820                 this, SIGNAL(changed()));
821 #else
822         spellCommandCO->setEnabled(false);
823 #endif
824         connect(altLanguageED, SIGNAL(textChanged(const QString&)),
825                 this, SIGNAL(changed()));
826         connect(escapeCharactersED, SIGNAL(textChanged(const QString&)),
827                 this, SIGNAL(changed()));
828         connect(persDictionaryED, SIGNAL(textChanged(const QString&)),
829                 this, SIGNAL(changed()));
830         connect(compoundWordCB, SIGNAL(clicked()),
831                 this, SIGNAL(changed()));
832         connect(inputEncodingCB, SIGNAL(clicked()),
833                 this, SIGNAL(changed()));
834
835         spellCommandCO->addItem(qt_("ispell"));
836         spellCommandCO->addItem(qt_("aspell"));
837         spellCommandCO->addItem(qt_("hspell"));
838 #ifdef USE_PSPELL
839         spellCommandCO->addItem(qt_("pspell (library)"));
840 #else
841 #ifdef USE_ASPELL
842         spellCommandCO->addItem(qt_("aspell (library)"));
843 #endif
844 #endif
845 }
846
847
848 void PrefSpellchecker::apply(LyXRC & rc) const
849 {
850         switch (spellCommandCO->currentIndex()) {
851                 case 0:
852                 case 1:
853                 case 2:
854                         rc.use_spell_lib = false;
855                         rc.isp_command = fromqstr(spellCommandCO->currentText());
856                         break;
857                 case 3:
858                         rc.use_spell_lib = true;
859                         break;
860         }
861
862         // FIXME: remove isp_use_alt_lang
863         rc.isp_alt_lang = fromqstr(altLanguageED->text());
864         rc.isp_use_alt_lang = !rc.isp_alt_lang.empty();
865         // FIXME: remove isp_use_esc_chars
866         rc.isp_esc_chars = fromqstr(escapeCharactersED->text());
867         rc.isp_use_esc_chars = !rc.isp_esc_chars.empty();
868         // FIXME: remove isp_use_pers_dict
869         rc.isp_pers_dict = internal_path(fromqstr(persDictionaryED->text()));
870         rc.isp_use_pers_dict = !rc.isp_pers_dict.empty();
871         rc.isp_accept_compound = compoundWordCB->isChecked();
872         rc.isp_use_input_encoding = inputEncodingCB->isChecked();
873 }
874
875
876 void PrefSpellchecker::update(LyXRC const & rc)
877 {
878         spellCommandCO->setCurrentIndex(0);
879
880         if (rc.isp_command == "ispell") {
881                 spellCommandCO->setCurrentIndex(0);
882         } else if (rc.isp_command == "aspell") {
883                 spellCommandCO->setCurrentIndex(1);
884         } else if (rc.isp_command == "hspell") {
885                 spellCommandCO->setCurrentIndex(2);
886         }
887
888         if (rc.use_spell_lib) {
889 #if defined(USE_ASPELL) || defined(USE_PSPELL)
890                 spellCommandCO->setCurrentIndex(3);
891 #endif
892         }
893
894         // FIXME: remove isp_use_alt_lang
895         altLanguageED->setText(toqstr(rc.isp_alt_lang));
896         // FIXME: remove isp_use_esc_chars
897         escapeCharactersED->setText(toqstr(rc.isp_esc_chars));
898         // FIXME: remove isp_use_pers_dict
899         persDictionaryED->setText(toqstr(external_path(rc.isp_pers_dict)));
900         compoundWordCB->setChecked(rc.isp_accept_compound);
901         inputEncodingCB->setChecked(rc.isp_use_input_encoding);
902 }
903
904
905 void PrefSpellchecker::select_dict()
906 {
907         docstring file(form_->browsedict(
908                 from_utf8(internal_path(fromqstr(persDictionaryED->text())))));
909         if (!file.empty())
910                 persDictionaryED->setText(toqstr(file));
911 }
912
913
914
915 /////////////////////////////////////////////////////////////////////
916 //
917 // PrefConverters
918 //
919 /////////////////////////////////////////////////////////////////////
920
921
922 PrefConverters::PrefConverters(GuiPreferences * form, QWidget * parent)
923         : PrefModule(_("Converters"), form, parent)
924 {
925         setupUi(this);
926
927         connect(converterNewPB, SIGNAL(clicked()),
928                 this, SLOT(update_converter()));
929         connect(converterRemovePB, SIGNAL(clicked()),
930                 this, SLOT(remove_converter()));
931         connect(converterModifyPB, SIGNAL(clicked()),
932                 this, SLOT(update_converter()));
933         connect(convertersLW, SIGNAL(currentRowChanged(int)),
934                 this, SLOT(switch_converter()));
935         connect(converterFromCO, SIGNAL(activated(const QString&)),
936                 this, SLOT(converter_changed()));
937         connect(converterToCO, SIGNAL(activated(const QString&)),
938                 this, SLOT(converter_changed()));
939         connect(converterED, SIGNAL(textEdited(const QString&)),
940                 this, SLOT(converter_changed()));
941         connect(converterFlagED, SIGNAL(textEdited(const QString&)),
942                 this, SLOT(converter_changed()));
943         connect(converterNewPB, SIGNAL(clicked()),
944                 this, SIGNAL(changed()));
945         connect(converterRemovePB, SIGNAL(clicked()),
946                 this, SIGNAL(changed()));
947         connect(converterModifyPB, SIGNAL(clicked()),
948                 this, SIGNAL(changed()));
949         connect(maxAgeLE, SIGNAL(textEdited(const QString&)),
950                 this, SIGNAL(changed()));
951
952         maxAgeLE->setValidator(new QDoubleValidator(maxAgeLE));
953         //converterDefGB->setFocusProxy(convertersLW);
954 }
955
956
957 void PrefConverters::apply(LyXRC & rc) const
958 {
959         rc.use_converter_cache = cacheCB->isChecked();
960         rc.converter_cache_maxage = int(maxAgeLE->text().toDouble() * 86400.0);
961 }
962
963
964 void PrefConverters::update(LyXRC const & rc)
965 {
966         cacheCB->setChecked(rc.use_converter_cache);
967         QString max_age;
968         max_age.setNum(double(rc.converter_cache_maxage) / 86400.0, 'g', 6);
969         maxAgeLE->setText(max_age);
970         updateGui();
971 }
972
973
974 void PrefConverters::updateGui()
975 {
976         form_->formats().sort();
977         form_->converters().update(form_->formats());
978         // save current selection
979         QString current = converterFromCO->currentText()
980                 + " -> " + converterToCO->currentText();
981
982         converterFromCO->clear();
983         converterToCO->clear();
984
985         Formats::const_iterator cit = form_->formats().begin();
986         Formats::const_iterator end = form_->formats().end();
987         for (; cit != end; ++cit) {
988                 converterFromCO->addItem(toqstr(cit->prettyname()));
989                 converterToCO->addItem(toqstr(cit->prettyname()));
990         }
991
992         // currentRowChanged(int) is also triggered when updating the listwidget
993         // block signals to avoid unnecessary calls to switch_converter()
994         convertersLW->blockSignals(true);
995         convertersLW->clear();
996
997         Converters::const_iterator ccit = form_->converters().begin();
998         Converters::const_iterator cend = form_->converters().end();
999         for (; ccit != cend; ++ccit) {
1000                 std::string const name =
1001                         ccit->From->prettyname() + " -> " + ccit->To->prettyname();
1002                 int type = form_->converters().getNumber(ccit->From->name(), ccit->To->name());
1003                 new QListWidgetItem(toqstr(name), convertersLW, type);
1004         }
1005         convertersLW->sortItems(Qt::AscendingOrder);
1006         convertersLW->blockSignals(false);
1007
1008         // restore selection
1009         if (!current.isEmpty()) {
1010                 QList<QListWidgetItem *> const item =
1011                         convertersLW->findItems(current, Qt::MatchExactly);
1012                 if (!item.isEmpty())
1013                         convertersLW->setCurrentItem(item.at(0));
1014         }
1015
1016         // select first element if restoring failed
1017         if (convertersLW->currentRow() == -1)
1018                 convertersLW->setCurrentRow(0);
1019
1020         updateButtons();
1021 }
1022
1023
1024 void PrefConverters::switch_converter()
1025 {
1026         int const cnr = convertersLW->currentItem()->type();
1027         Converter const & c(form_->converters().get(cnr));
1028         converterFromCO->setCurrentIndex(form_->formats().getNumber(c.from));
1029         converterToCO->setCurrentIndex(form_->formats().getNumber(c.to));
1030         converterED->setText(toqstr(c.command));
1031         converterFlagED->setText(toqstr(c.flags));
1032
1033         updateButtons();
1034 }
1035
1036
1037 void PrefConverters::converter_changed()
1038 {
1039         updateButtons();
1040 }
1041
1042
1043 void PrefConverters::updateButtons()
1044 {
1045         Format const & from = form_->formats().get(converterFromCO->currentIndex());
1046         Format const & to = form_->formats().get(converterToCO->currentIndex());
1047         int const sel = form_->converters().getNumber(from.name(), to.name());
1048         bool const known = !(sel < 0);
1049         bool const valid = !(converterED->text().isEmpty()
1050                 || from.name() == to.name());
1051
1052         int const cnr = convertersLW->currentItem()->type();
1053         Converter const & c(form_->converters().get(cnr));
1054         string const old_command = c.command;
1055         string const old_flag = c.flags;
1056         string const new_command(fromqstr(converterED->text()));
1057         string const new_flag(fromqstr(converterFlagED->text()));
1058
1059         bool modified = ((old_command != new_command) || (old_flag != new_flag));
1060
1061         converterModifyPB->setEnabled(valid && known && modified);
1062         converterNewPB->setEnabled(valid && !known);
1063         converterRemovePB->setEnabled(known);
1064
1065         maxAgeLE->setEnabled(cacheCB->isChecked());
1066         maxAgeLA->setEnabled(cacheCB->isChecked());
1067 }
1068
1069
1070 // FIXME: user must
1071 // specify unique from/to or it doesn't appear. This is really bad UI
1072 // this is why we can use the same function for both new and modify
1073 void PrefConverters::update_converter()
1074 {
1075         Format const & from = form_->formats().get(converterFromCO->currentIndex());
1076         Format const & to = form_->formats().get(converterToCO->currentIndex());
1077         string const flags = fromqstr(converterFlagED->text());
1078         string const command = fromqstr(converterED->text());
1079
1080         Converter const * old =
1081                 form_->converters().getConverter(from.name(), to.name());
1082         form_->converters().add(from.name(), to.name(), command, flags);
1083
1084         if (!old)
1085                 form_->converters().updateLast(form_->formats());
1086
1087         updateGui();
1088
1089         // Remove all files created by this converter from the cache, since
1090         // the modified converter might create different files.
1091         ConverterCache::get().remove_all(from.name(), to.name());
1092 }
1093
1094
1095 void PrefConverters::remove_converter()
1096 {
1097         Format const & from = form_->formats().get(converterFromCO->currentIndex());
1098         Format const & to = form_->formats().get(converterToCO->currentIndex());
1099         form_->converters().erase(from.name(), to.name());
1100
1101         updateGui();
1102
1103         // Remove all files created by this converter from the cache, since
1104         // a possible new converter might create different files.
1105         ConverterCache::get().remove_all(from.name(), to.name());
1106 }
1107
1108
1109 void PrefConverters::on_cacheCB_stateChanged(int state)
1110 {
1111         maxAgeLE->setEnabled(state == Qt::Checked);
1112         maxAgeLA->setEnabled(state == Qt::Checked);
1113         changed();
1114 }
1115
1116
1117 /////////////////////////////////////////////////////////////////////
1118 //
1119 // PrefFileformats
1120 //
1121 /////////////////////////////////////////////////////////////////////
1122 FormatValidator::FormatValidator(QWidget * parent, Formats const & f) 
1123         : QValidator(parent), formats_(f)
1124 {
1125 }
1126
1127
1128 void FormatValidator::fixup(QString & input) const
1129 {
1130         Formats::const_iterator cit = formats_.begin();
1131         Formats::const_iterator end = formats_.end();
1132         for (; cit != end; ++cit) {
1133                 string const name = str(cit);
1134                 if (distance(formats_.begin(), cit) == nr()) {
1135                         input = toqstr(name);
1136                         return;
1137
1138                 }
1139         }
1140 }
1141
1142
1143 QValidator::State FormatValidator::validate(QString & input, int & /*pos*/) const
1144 {
1145         Formats::const_iterator cit = formats_.begin();
1146         Formats::const_iterator end = formats_.end();
1147         bool unknown = true;
1148         for (; unknown && cit != end; ++cit) {
1149                 string const name = str(cit);
1150                 if (distance(formats_.begin(), cit) != nr())
1151                         unknown = toqstr(name) != input;
1152         }
1153
1154         if (unknown && !input.isEmpty()) 
1155                 return QValidator::Acceptable;
1156         else
1157                 return QValidator::Intermediate;
1158 }
1159
1160
1161 int FormatValidator::nr() const
1162 {
1163         QComboBox * p = qobject_cast<QComboBox *>(parent());
1164         return p->itemData(p->currentIndex()).toInt();
1165 }
1166
1167
1168 FormatNameValidator::FormatNameValidator(QWidget * parent, Formats const & f) 
1169         : FormatValidator(parent, f)
1170 {
1171 }
1172
1173 std::string FormatNameValidator::str(Formats::const_iterator it) const
1174 {
1175         return it->name();
1176 }
1177
1178
1179 FormatPrettynameValidator::FormatPrettynameValidator(QWidget * parent, Formats const & f) 
1180         : FormatValidator(parent, f)
1181 {
1182 }
1183
1184
1185 std::string FormatPrettynameValidator::str(Formats::const_iterator it) const
1186 {
1187         return it->prettyname();
1188 }
1189
1190
1191 PrefFileformats::PrefFileformats(GuiPreferences * form, QWidget * parent)
1192         : PrefModule(_("File formats"), form, parent)
1193 {
1194         setupUi(this);
1195         formatED->setValidator(new FormatNameValidator(formatsCB, form_->formats()));
1196         formatsCB->setValidator(new FormatPrettynameValidator(formatsCB, form_->formats()));
1197
1198         connect(documentCB, SIGNAL(clicked()),
1199                 this, SLOT(setFlags()));
1200         connect(vectorCB, SIGNAL(clicked()),
1201                 this, SLOT(setFlags()));
1202         connect(formatsCB->lineEdit(), SIGNAL(editingFinished()),
1203                 this, SLOT(updatePrettyname()));
1204         connect(formatsCB->lineEdit(), SIGNAL(textEdited(const QString &)),
1205                 this, SIGNAL(changed()));
1206 }
1207
1208
1209 void PrefFileformats::apply(LyXRC & /*rc*/) const
1210 {
1211 }
1212
1213
1214 void PrefFileformats::update(LyXRC const & /*rc*/)
1215 {
1216         updateView();
1217 }
1218
1219
1220 void PrefFileformats::updateView()
1221 {
1222         QString const current = formatsCB->currentText();
1223
1224         // update combobox with formats
1225         formatsCB->blockSignals(true);
1226         formatsCB->clear();
1227         form_->formats().sort();
1228         Formats::const_iterator cit = form_->formats().begin();
1229         Formats::const_iterator end = form_->formats().end();
1230         for (; cit != end; ++cit)
1231                 formatsCB->addItem(toqstr(cit->prettyname()),
1232                                                         QVariant(form_->formats().getNumber(cit->name())) );
1233
1234         // restore selection
1235         int const item = formatsCB->findText(current, Qt::MatchExactly);
1236         formatsCB->setCurrentIndex(item < 0 ? 0 : item);
1237         on_formatsCB_currentIndexChanged(item < 0 ? 0 : item);
1238         formatsCB->blockSignals(false);
1239 }
1240
1241
1242 void PrefFileformats::on_formatsCB_currentIndexChanged(int i)
1243 {
1244         int const nr = formatsCB->itemData(i).toInt();
1245         Format const f = form_->formats().get(nr);
1246
1247         formatED->setText(toqstr(f.name()));
1248         copierED->setText(toqstr(form_->movers().command(f.name())));
1249         extensionED->setText(toqstr(f.extension()));
1250         shortcutED->setText(toqstr(f.shortcut()));
1251         viewerED->setText(toqstr(f.viewer()));
1252         editorED->setText(toqstr(f.editor()));
1253         documentCB->setChecked((f.documentFormat()));
1254         vectorCB->setChecked((f.vectorFormat()));
1255 }
1256
1257
1258 void PrefFileformats::setFlags()
1259 {
1260         int flags = Format::none;
1261         if (documentCB->isChecked())
1262                 flags |= Format::document;
1263         if (vectorCB->isChecked())
1264                 flags |= Format::vector;
1265         currentFormat().setFlags(flags);
1266         changed();
1267 }
1268
1269
1270 void PrefFileformats::on_copierED_textEdited(const QString & s)
1271 {
1272         string const fmt = fromqstr(formatED->text());
1273         form_->movers().set(fmt, fromqstr(s));
1274         changed();
1275 }
1276
1277
1278 void PrefFileformats::on_extensionED_textEdited(const QString & s)
1279 {
1280         currentFormat().setExtension(fromqstr(s));
1281         changed();
1282 }
1283
1284 void PrefFileformats::on_viewerED_textEdited(const QString & s)
1285 {
1286         currentFormat().setViewer(fromqstr(s));
1287         changed();
1288 }
1289
1290
1291 void PrefFileformats::on_editorED_textEdited(const QString & s)
1292 {
1293         currentFormat().setEditor(fromqstr(s));
1294         changed();
1295 }
1296
1297
1298 void PrefFileformats::on_shortcutED_textEdited(const QString & s)
1299 {
1300         currentFormat().setShortcut(fromqstr(s));
1301         changed();
1302 }
1303
1304
1305 void PrefFileformats::on_formatED_editingFinished()
1306 {
1307         string const newname = fromqstr(formatED->displayText());
1308         if (newname == currentFormat().name())
1309                 return;
1310
1311         currentFormat().setName(newname);
1312         changed();
1313 }
1314
1315
1316 void PrefFileformats::on_formatED_textChanged(const QString &)
1317 {
1318         QString t = formatED->text();
1319         int p = 0;
1320         bool valid = formatED->validator()->validate(t, p) == QValidator::Acceptable;
1321         setValid(formatLA, valid);
1322 }
1323
1324
1325 void PrefFileformats::on_formatsCB_editTextChanged(const QString &)
1326 {
1327         QString t = formatsCB->currentText();
1328         int p = 0;
1329         bool valid = formatsCB->validator()->validate(t, p) == QValidator::Acceptable;
1330         setValid(formatsLA, valid);
1331 }
1332
1333
1334 void PrefFileformats::updatePrettyname()
1335 {
1336         string const newname = fromqstr(formatsCB->currentText());
1337         if (newname == currentFormat().prettyname())
1338                 return;
1339
1340         currentFormat().setPrettyname(newname);
1341         formatsChanged();
1342         updateView();
1343         changed();
1344 }
1345
1346
1347 Format & PrefFileformats::currentFormat()
1348 {
1349         int const i = formatsCB->currentIndex();
1350         int const nr = formatsCB->itemData(i).toInt();
1351         return form_->formats().get(nr);
1352 }
1353
1354
1355 void PrefFileformats::on_formatNewPB_clicked()
1356 {
1357         form_->formats().add("", "", "", "", "", "", Format::none);
1358         updateView();
1359         formatsCB->setCurrentIndex(0);
1360         formatsCB->setFocus(Qt::OtherFocusReason);
1361 }
1362
1363
1364 void PrefFileformats::on_formatRemovePB_clicked()
1365 {
1366         int const i = formatsCB->currentIndex();
1367         int const nr = formatsCB->itemData(i).toInt();
1368         string const current_text = form_->formats().get(nr).name();
1369         if (form_->converters().formatIsUsed(current_text)) {
1370                 Alert::error(_("Format in use"),
1371                              _("Cannot remove a Format used by a Converter. "
1372                                             "Remove the converter first."));
1373                 return;
1374         }
1375
1376         form_->formats().erase(current_text);
1377         formatsChanged();
1378         updateView();
1379         on_formatsCB_editTextChanged(formatsCB->currentText());
1380         changed();
1381 }
1382
1383
1384 /////////////////////////////////////////////////////////////////////
1385 //
1386 // PrefLanguage
1387 //
1388 /////////////////////////////////////////////////////////////////////
1389
1390 PrefLanguage::PrefLanguage(QWidget * parent)
1391         : PrefModule(_("Language"), 0, parent)
1392 {
1393         setupUi(this);
1394
1395         connect(rtlCB, SIGNAL(clicked()),
1396                 this, SIGNAL(changed()));
1397         connect(markForeignCB, SIGNAL(clicked()),
1398                 this, SIGNAL(changed()));
1399         connect(autoBeginCB, SIGNAL(clicked()),
1400                 this, SIGNAL(changed()));
1401         connect(autoEndCB, SIGNAL(clicked()),
1402                 this, SIGNAL(changed()));
1403         connect(useBabelCB, SIGNAL(clicked()),
1404                 this, SIGNAL(changed()));
1405         connect(globalCB, SIGNAL(clicked()),
1406                 this, SIGNAL(changed()));
1407         connect(languagePackageED, SIGNAL(textChanged(const QString&)),
1408                 this, SIGNAL(changed()));
1409         connect(startCommandED, SIGNAL(textChanged(const QString&)),
1410                 this, SIGNAL(changed()));
1411         connect(endCommandED, SIGNAL(textChanged(const QString&)),
1412                 this, SIGNAL(changed()));
1413         connect(defaultLanguageCO, SIGNAL(activated(int)),
1414                 this, SIGNAL(changed()));
1415
1416         defaultLanguageCO->clear();
1417
1418         // store the lang identifiers for later
1419         std::vector<LanguagePair> const langs = frontend::getLanguageData(false);
1420         std::vector<LanguagePair>::const_iterator lit  = langs.begin();
1421         std::vector<LanguagePair>::const_iterator lend = langs.end();
1422         lang_.clear();
1423         for (; lit != lend; ++lit) {
1424                 defaultLanguageCO->addItem(toqstr(lit->first));
1425                 lang_.push_back(lit->second);
1426         }
1427 }
1428
1429
1430 void PrefLanguage::apply(LyXRC & rc) const
1431 {
1432         // FIXME: remove rtl_support bool
1433         rc.rtl_support = rtlCB->isChecked();
1434         rc.mark_foreign_language = markForeignCB->isChecked();
1435         rc.language_auto_begin = autoBeginCB->isChecked();
1436         rc.language_auto_end = autoEndCB->isChecked();
1437         rc.language_use_babel = useBabelCB->isChecked();
1438         rc.language_global_options = globalCB->isChecked();
1439         rc.language_package = fromqstr(languagePackageED->text());
1440         rc.language_command_begin = fromqstr(startCommandED->text());
1441         rc.language_command_end = fromqstr(endCommandED->text());
1442         rc.default_language = lang_[defaultLanguageCO->currentIndex()];
1443 }
1444
1445
1446 void PrefLanguage::update(LyXRC const & rc)
1447 {
1448         // FIXME: remove rtl_support bool
1449         rtlCB->setChecked(rc.rtl_support);
1450         markForeignCB->setChecked(rc.mark_foreign_language);
1451         autoBeginCB->setChecked(rc.language_auto_begin);
1452         autoEndCB->setChecked(rc.language_auto_end);
1453         useBabelCB->setChecked(rc.language_use_babel);
1454         globalCB->setChecked(rc.language_global_options);
1455         languagePackageED->setText(toqstr(rc.language_package));
1456         startCommandED->setText(toqstr(rc.language_command_begin));
1457         endCommandED->setText(toqstr(rc.language_command_end));
1458
1459         int const pos = int(findPos_helper(lang_, rc.default_language));
1460         defaultLanguageCO->setCurrentIndex(pos);
1461 }
1462
1463
1464 /////////////////////////////////////////////////////////////////////
1465 //
1466 // PrefPrinter
1467 //
1468 /////////////////////////////////////////////////////////////////////
1469
1470 PrefPrinter::PrefPrinter(QWidget * parent)
1471         : PrefModule(_("Printer"), 0, parent)
1472 {
1473         setupUi(this);
1474
1475         connect(printerAdaptCB, SIGNAL(clicked()),
1476                 this, SIGNAL(changed()));
1477         connect(printerCommandED, SIGNAL(textChanged(const QString&)),
1478                 this, SIGNAL(changed()));
1479         connect(printerNameED, SIGNAL(textChanged(const QString&)),
1480                 this, SIGNAL(changed()));
1481         connect(printerPageRangeED, SIGNAL(textChanged(const QString&)),
1482                 this, SIGNAL(changed()));
1483         connect(printerCopiesED, SIGNAL(textChanged(const QString&)),
1484                 this, SIGNAL(changed()));
1485         connect(printerReverseED, SIGNAL(textChanged(const QString&)),
1486                 this, SIGNAL(changed()));
1487         connect(printerToPrinterED, SIGNAL(textChanged(const QString&)),
1488                 this, SIGNAL(changed()));
1489         connect(printerExtensionED, SIGNAL(textChanged(const QString&)),
1490                 this, SIGNAL(changed()));
1491         connect(printerSpoolCommandED, SIGNAL(textChanged(const QString&)),
1492                 this, SIGNAL(changed()));
1493         connect(printerPaperTypeED, SIGNAL(textChanged(const QString&)),
1494                 this, SIGNAL(changed()));
1495         connect(printerEvenED, SIGNAL(textChanged(const QString&)),
1496                 this, SIGNAL(changed()));
1497         connect(printerOddED, SIGNAL(textChanged(const QString&)),
1498                 this, SIGNAL(changed()));
1499         connect(printerCollatedED, SIGNAL(textChanged(const QString&)),
1500                 this, SIGNAL(changed()));
1501         connect(printerLandscapeED, SIGNAL(textChanged(const QString&)),
1502                 this, SIGNAL(changed()));
1503         connect(printerToFileED, SIGNAL(textChanged(const QString&)),
1504                 this, SIGNAL(changed()));
1505         connect(printerExtraED, SIGNAL(textChanged(const QString&)),
1506                 this, SIGNAL(changed()));
1507         connect(printerSpoolPrefixED, SIGNAL(textChanged(const QString&)),
1508                 this, SIGNAL(changed()));
1509         connect(printerPaperSizeED, SIGNAL(textChanged(const QString&)),
1510                 this, SIGNAL(changed()));
1511 }
1512
1513
1514 void PrefPrinter::apply(LyXRC & rc) const
1515 {
1516         rc.print_adapt_output = printerAdaptCB->isChecked();
1517         rc.print_command = fromqstr(printerCommandED->text());
1518         rc.printer = fromqstr(printerNameED->text());
1519
1520         rc.print_pagerange_flag = fromqstr(printerPageRangeED->text());
1521         rc.print_copies_flag = fromqstr(printerCopiesED->text());
1522         rc.print_reverse_flag = fromqstr(printerReverseED->text());
1523         rc.print_to_printer = fromqstr(printerToPrinterED->text());
1524         rc.print_file_extension = fromqstr(printerExtensionED->text());
1525         rc.print_spool_command = fromqstr(printerSpoolCommandED->text());
1526         rc.print_paper_flag = fromqstr(printerPaperTypeED->text());
1527         rc.print_evenpage_flag = fromqstr(printerEvenED->text());
1528         rc.print_oddpage_flag = fromqstr(printerOddED->text());
1529         rc.print_collcopies_flag = fromqstr(printerCollatedED->text());
1530         rc.print_landscape_flag = fromqstr(printerLandscapeED->text());
1531         rc.print_to_file = internal_path(fromqstr(printerToFileED->text()));
1532         rc.print_extra_options = fromqstr(printerExtraED->text());
1533         rc.print_spool_printerprefix = fromqstr(printerSpoolPrefixED->text());
1534         rc.print_paper_dimension_flag = fromqstr(printerPaperSizeED->text());
1535 }
1536
1537
1538 void PrefPrinter::update(LyXRC const & rc)
1539 {
1540         printerAdaptCB->setChecked(rc.print_adapt_output);
1541         printerCommandED->setText(toqstr(rc.print_command));
1542         printerNameED->setText(toqstr(rc.printer));
1543
1544         printerPageRangeED->setText(toqstr(rc.print_pagerange_flag));
1545         printerCopiesED->setText(toqstr(rc.print_copies_flag));
1546         printerReverseED->setText(toqstr(rc.print_reverse_flag));
1547         printerToPrinterED->setText(toqstr(rc.print_to_printer));
1548         printerExtensionED->setText(toqstr(rc.print_file_extension));
1549         printerSpoolCommandED->setText(toqstr(rc.print_spool_command));
1550         printerPaperTypeED->setText(toqstr(rc.print_paper_flag));
1551         printerEvenED->setText(toqstr(rc.print_evenpage_flag));
1552         printerOddED->setText(toqstr(rc.print_oddpage_flag));
1553         printerCollatedED->setText(toqstr(rc.print_collcopies_flag));
1554         printerLandscapeED->setText(toqstr(rc.print_landscape_flag));
1555         printerToFileED->setText(toqstr(external_path(rc.print_to_file)));
1556         printerExtraED->setText(toqstr(rc.print_extra_options));
1557         printerSpoolPrefixED->setText(toqstr(rc.print_spool_printerprefix));
1558         printerPaperSizeED->setText(toqstr(rc.print_paper_dimension_flag));
1559 }
1560
1561
1562 /////////////////////////////////////////////////////////////////////
1563 //
1564 // PrefUserInterface
1565 //
1566 /////////////////////////////////////////////////////////////////////
1567
1568 PrefUserInterface::PrefUserInterface(GuiPreferences * form, QWidget * parent)
1569         : PrefModule(_("User interface"), form, parent)
1570 {
1571         setupUi(this);
1572
1573         connect(autoSaveCB, SIGNAL(toggled(bool)),
1574                 autoSaveSB, SLOT(setEnabled(bool)));
1575         connect(autoSaveCB, SIGNAL(toggled(bool)),
1576                 TextLabel1, SLOT(setEnabled(bool)));
1577         connect(uiFilePB, SIGNAL(clicked()),
1578                 this, SLOT(select_ui()));
1579         connect(bindFilePB, SIGNAL(clicked()),
1580                 this, SLOT(select_bind()));
1581         connect(uiFileED, SIGNAL(textChanged(const QString &)),
1582                 this, SIGNAL(changed()));
1583         connect(bindFileED, SIGNAL(textChanged(const QString &)),
1584                 this, SIGNAL(changed()));
1585         connect(restoreCursorCB, SIGNAL(clicked()),
1586                 this, SIGNAL(changed()));
1587         connect(loadSessionCB, SIGNAL(clicked()),
1588                 this, SIGNAL(changed()));
1589         connect(loadWindowSizeCB, SIGNAL(clicked()),
1590                 this, SIGNAL(changed()));
1591         connect(loadWindowLocationCB, SIGNAL(clicked()),
1592                 this, SIGNAL(changed()));
1593         connect(windowWidthSB, SIGNAL(valueChanged(int)),
1594                 this, SIGNAL(changed()));
1595         connect(windowHeightSB, SIGNAL(valueChanged(int)),
1596                 this, SIGNAL(changed()));
1597         connect(cursorFollowsCB, SIGNAL(clicked()),
1598                 this, SIGNAL(changed()));
1599         connect(autoSaveSB, SIGNAL(valueChanged(int)),
1600                 this, SIGNAL(changed()));
1601         connect(autoSaveCB, SIGNAL(clicked()),
1602                 this, SIGNAL(changed()));
1603         connect(lastfilesSB, SIGNAL(valueChanged(int)),
1604                 this, SIGNAL(changed()));
1605         lastfilesSB->setMaximum(maxlastfiles);
1606 }
1607
1608
1609 void PrefUserInterface::apply(LyXRC & rc) const
1610 {
1611         rc.ui_file = internal_path(fromqstr(uiFileED->text()));
1612         rc.bind_file = internal_path(fromqstr(bindFileED->text()));
1613         rc.use_lastfilepos = restoreCursorCB->isChecked();
1614         rc.load_session = loadSessionCB->isChecked();
1615         if (loadWindowSizeCB->isChecked()) {
1616                 rc.geometry_width = 0;
1617                 rc.geometry_height = 0;
1618         } else {
1619                 rc.geometry_width = windowWidthSB->value();
1620                 rc.geometry_height = windowHeightSB->value();
1621         }
1622         rc.geometry_xysaved = loadWindowLocationCB->isChecked();
1623         rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
1624         rc.autosave = autoSaveSB->value() * 60;
1625         rc.make_backup = autoSaveCB->isChecked();
1626         rc.num_lastfiles = lastfilesSB->value();
1627 }
1628
1629
1630 void PrefUserInterface::update(LyXRC const & rc)
1631 {
1632         uiFileED->setText(toqstr(external_path(rc.ui_file)));
1633         bindFileED->setText(toqstr(external_path(rc.bind_file)));
1634         restoreCursorCB->setChecked(rc.use_lastfilepos);
1635         loadSessionCB->setChecked(rc.load_session);
1636         bool loadWindowSize = rc.geometry_width == 0 && rc.geometry_height == 0;
1637         loadWindowSizeCB->setChecked(loadWindowSize);
1638         if (!loadWindowSize) {
1639                 windowWidthSB->setValue(rc.geometry_width);
1640                 windowHeightSB->setValue(rc.geometry_height);
1641         }
1642         loadWindowLocationCB->setChecked(rc.geometry_xysaved);
1643         cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
1644         // convert to minutes
1645         int mins(rc.autosave / 60);
1646         if (rc.autosave && !mins)
1647                 mins = 1;
1648         autoSaveSB->setValue(mins);
1649         autoSaveCB->setChecked(rc.make_backup);
1650         lastfilesSB->setValue(rc.num_lastfiles);
1651 }
1652
1653
1654 void PrefUserInterface::select_ui()
1655 {
1656         docstring const name =
1657                 from_utf8(internal_path(fromqstr(uiFileED->text())));
1658         docstring file = form_->browseUI(name);
1659         if (!file.empty())
1660                 uiFileED->setText(toqstr(file));
1661 }
1662
1663
1664 void PrefUserInterface::select_bind()
1665 {
1666         docstring const name =
1667                 from_utf8(internal_path(fromqstr(bindFileED->text())));
1668         docstring file = form_->browsebind(name);
1669         if (!file.empty())
1670                 bindFileED->setText(toqstr(file));
1671 }
1672
1673
1674 void PrefUserInterface::on_loadWindowSizeCB_toggled(bool loadwindowsize)
1675 {
1676         windowWidthLA->setDisabled(loadwindowsize);
1677         windowHeightLA->setDisabled(loadwindowsize);
1678         windowWidthSB->setDisabled(loadwindowsize);
1679         windowHeightSB->setDisabled(loadwindowsize);
1680 }
1681
1682
1683 PrefIdentity::PrefIdentity(QWidget * parent)
1684         : PrefModule(_("Identity"), 0, parent)
1685 {
1686         setupUi(this);
1687
1688         connect(nameED, SIGNAL(textChanged(const QString&)),
1689                 this, SIGNAL(changed()));
1690         connect(emailED, SIGNAL(textChanged(const QString&)),
1691                 this, SIGNAL(changed()));
1692 }
1693
1694
1695 void PrefIdentity::apply(LyXRC & rc) const
1696 {
1697         rc.user_name = fromqstr(nameED->text());
1698         rc.user_email = fromqstr(emailED->text());
1699 }
1700
1701
1702 void PrefIdentity::update(LyXRC const & rc)
1703 {
1704         nameED->setText(toqstr(rc.user_name));
1705         emailED->setText(toqstr(rc.user_email));
1706 }
1707
1708
1709
1710 /////////////////////////////////////////////////////////////////////
1711 //
1712 // GuiPreferences
1713 //
1714 /////////////////////////////////////////////////////////////////////
1715
1716 GuiPreferences::GuiPreferences(LyXView & lv)
1717         : GuiDialog(lv, "prefs"), Controller(this), update_screen_font_(false)
1718 {
1719         setupUi(this);
1720         setViewTitle(_("Preferences"));
1721         setController(this, false);
1722
1723         QDialog::setModal(false);
1724
1725         connect(savePB, SIGNAL(clicked()), this, SLOT(slotOK()));
1726         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
1727         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
1728         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
1729
1730         add(new PrefUserInterface(this));
1731         add(new PrefScreenFonts(this));
1732         add(new PrefColors(this));
1733         add(new PrefDisplay);
1734         add(new PrefKeyboard(this));
1735
1736         add(new PrefPaths(this));
1737
1738         add(new PrefIdentity);
1739
1740         add(new PrefLanguage);
1741         add(new PrefSpellchecker(this));
1742
1743         add(new PrefPrinter);
1744         add(new PrefDate);
1745         add(new PrefPlaintext);
1746         add(new PrefLatex(this));
1747
1748         PrefConverters * converters = new PrefConverters(this);
1749         PrefFileformats * formats = new PrefFileformats(this);
1750         connect(formats, SIGNAL(formatsChanged()),
1751                         converters, SLOT(updateGui()));
1752         add(converters);
1753         add(formats);
1754
1755         prefsPS->setCurrentPanel(_("User interface"));
1756 // FIXME: hack to work around resizing bug in Qt >= 4.2
1757 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1758 #if QT_VERSION >= 0x040200
1759         prefsPS->updateGeometry();
1760 #endif
1761
1762         bc().setPolicy(ButtonPolicy::PreferencesPolicy);
1763         bc().setOK(savePB);
1764         bc().setApply(applyPB);
1765         bc().setCancel(closePB);
1766         bc().setRestore(restorePB);
1767 }
1768
1769
1770 void GuiPreferences::add(PrefModule * module)
1771 {
1772         BOOST_ASSERT(module);
1773         prefsPS->addPanel(module, module->title());
1774         connect(module, SIGNAL(changed()), this, SLOT(change_adaptor()));
1775         modules_.push_back(module);
1776 }
1777
1778
1779 void GuiPreferences::closeEvent(QCloseEvent * e)
1780 {
1781         slotClose();
1782         e->accept();
1783 }
1784
1785
1786 void GuiPreferences::change_adaptor()
1787 {
1788         changed();
1789 }
1790
1791
1792 void GuiPreferences::apply(LyXRC & rc) const
1793 {
1794         size_t end = modules_.size();
1795         for (size_t i = 0; i != end; ++i)
1796                 modules_[i]->apply(rc);
1797 }
1798
1799
1800 void GuiPreferences::updateRc(LyXRC const & rc)
1801 {
1802         size_t const end = modules_.size();
1803         for (size_t i = 0; i != end; ++i)
1804                 modules_[i]->update(rc);
1805 }
1806
1807
1808 void GuiPreferences::applyView()
1809 {
1810         apply(rc());
1811 }
1812
1813
1814 void GuiPreferences::updateContents()
1815 {
1816         updateRc(rc());
1817 }
1818
1819
1820 bool GuiPreferences::initialiseParams(std::string const &)
1821 {
1822         rc_ = lyxrc;
1823         formats_ = lyx::formats;
1824         converters_ = theConverters();
1825         converters_.update(formats_);
1826         movers_ = theMovers();
1827         colors_.clear();
1828         update_screen_font_ = false;
1829
1830         return true;
1831 }
1832
1833
1834 void GuiPreferences::dispatchParams()
1835 {
1836         ostringstream ss;
1837         rc_.write(ss, true);
1838         dispatch(FuncRequest(LFUN_LYXRC_APPLY, ss.str())); 
1839         // FIXME: these need lfuns
1840         // FIXME UNICODE
1841         theBufferList().setCurrentAuthor(from_utf8(rc_.user_name), from_utf8(rc_.user_email));
1842
1843         lyx::formats = formats_;
1844
1845         theConverters() = converters_;
1846         theConverters().update(lyx::formats);
1847         theConverters().buildGraph();
1848
1849         theMovers() = movers_;
1850
1851         vector<string>::const_iterator it = colors_.begin();
1852         vector<string>::const_iterator const end = colors_.end();
1853         for (; it != end; ++it)
1854                 dispatch(FuncRequest(LFUN_SET_COLOR, *it));
1855         colors_.clear();
1856
1857         if (update_screen_font_) {
1858                 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
1859                 update_screen_font_ = false;
1860         }
1861
1862         // The Save button has been pressed
1863         if (dialog().isClosing()) {
1864                 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE));
1865         }
1866 }
1867
1868
1869 void GuiPreferences::setColor(Color_color col, string const & hex)
1870 {
1871         colors_.push_back(lcolor.getLyXName(col) + ' ' + hex);
1872 }
1873
1874
1875 void GuiPreferences::updateScreenFonts()
1876 {
1877         update_screen_font_ = true;
1878 }
1879
1880
1881 docstring const GuiPreferences::browsebind(docstring const & file) const
1882 {
1883         return browseLibFile(from_ascii("bind"), file, from_ascii("bind"),
1884                              _("Choose bind file"),
1885                              FileFilterList(_("LyX bind files (*.bind)")));
1886 }
1887
1888
1889 docstring const GuiPreferences::browseUI(docstring const & file) const
1890 {
1891         return browseLibFile(from_ascii("ui"), file, from_ascii("ui"),
1892                              _("Choose UI file"),
1893                              FileFilterList(_("LyX UI files (*.ui)")));
1894 }
1895
1896
1897 docstring const GuiPreferences::browsekbmap(docstring const & file) const
1898 {
1899         return browseLibFile(from_ascii("kbd"), file, from_ascii("kmap"),
1900                              _("Choose keyboard map"),
1901                              FileFilterList(_("LyX keyboard maps (*.kmap)")));
1902 }
1903
1904
1905 docstring const GuiPreferences::browsedict(docstring const & file) const
1906 {
1907         if (lyxrc.use_spell_lib)
1908                 return browseFile(file,
1909                                   _("Choose personal dictionary"),
1910                                   FileFilterList(_("*.pws")));
1911         else
1912                 return browseFile(file,
1913                                   _("Choose personal dictionary"),
1914                                   FileFilterList(_("*.ispell")));
1915 }
1916
1917
1918 docstring const GuiPreferences::browse(docstring const & file,
1919                                   docstring const & title) const
1920 {
1921         return browseFile(file, title, FileFilterList(), true);
1922 }
1923
1924
1925 docstring const GuiPreferences::browsedir(docstring const & path,
1926                                      docstring const & title) const
1927 {
1928         return browseDir(path, title);
1929 }
1930
1931
1932 // We support less paper sizes than the document dialog
1933 // Therefore this adjustment is needed.
1934 PAPER_SIZE GuiPreferences::toPaperSize(int i) const
1935 {
1936         switch (i) {
1937         case 0:
1938                 return PAPER_DEFAULT;
1939         case 1:
1940                 return PAPER_USLETTER;
1941         case 2:
1942                 return PAPER_USLEGAL;
1943         case 3:
1944                 return PAPER_USEXECUTIVE;
1945         case 4:
1946                 return PAPER_A3;
1947         case 5:
1948                 return PAPER_A4;
1949         case 6:
1950                 return PAPER_A5;
1951         case 7:
1952                 return PAPER_B5;
1953         default:
1954                 // should not happen
1955                 return PAPER_DEFAULT;
1956         }
1957 }
1958
1959
1960 int GuiPreferences::fromPaperSize(PAPER_SIZE papersize) const
1961 {
1962         switch (papersize) {
1963         case PAPER_DEFAULT:
1964                 return 0;
1965         case PAPER_USLETTER:
1966                 return 1;
1967         case PAPER_USLEGAL:
1968                 return 2;
1969         case PAPER_USEXECUTIVE:
1970                 return 3;
1971         case PAPER_A3:
1972                 return 4;
1973         case PAPER_A4:
1974                 return 5;
1975         case PAPER_A5:
1976                 return 6;
1977         case PAPER_B5:
1978                 return 7;
1979         default:
1980                 // should not happen
1981                 return 0;
1982         }
1983 }
1984
1985
1986 Dialog * createGuiPreferences(LyXView & lv) { return new GuiPreferences(lv); }
1987
1988
1989 } // namespace frontend
1990 } // namespace lyx
1991
1992 #include "GuiPrefs_moc.cpp"