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