3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
16 #include "ColorCache.h"
17 #include "FileDialog.h"
18 #include "GuiApplication.h"
19 #include "GuiFontExample.h"
20 #include "GuiFontLoader.h"
21 #include "GuiKeySymbol.h"
22 #include "qt_helpers.h"
24 #include "BufferList.h"
27 #include "ConverterCache.h"
28 #include "FontEnums.h"
29 #include "FuncRequest.h"
31 #include "KeySequence.h"
33 #include "LyXAction.h"
34 #include "PanelStack.h"
38 #include "support/debug.h"
39 #include "support/FileName.h"
40 #include "support/filetools.h"
41 #include "support/foreach.h"
42 #include "support/gettext.h"
43 #include "support/lstrings.h"
44 #include "support/os.h"
45 #include "support/Package.h"
47 #include "graphics/GraphicsTypes.h"
49 #include "frontends/alert.h"
50 #include "frontends/Application.h"
51 #include "frontends/FontLoader.h"
53 #include <QAbstractItemModel>
55 #include <QColorDialog>
56 #include <QFontDatabase>
57 #include <QHeaderView>
59 #include <QMessageBox>
60 #include <QPixmapCache>
61 #include <QPushButton>
64 #include <QTreeWidget>
65 #include <QTreeWidgetItem>
75 using namespace lyx::support
;
76 using namespace lyx::support::os
;
81 /////////////////////////////////////////////////////////////////////
85 /////////////////////////////////////////////////////////////////////
87 /** Launch a file dialog and return the chosen file.
88 filename: a suggested filename.
89 title: the title of the dialog.
91 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
93 QString
browseFile(QString
const & filename
,
94 QString
const & title
,
95 QStringList
const & filters
,
97 QString
const & label1
= QString(),
98 QString
const & dir1
= QString(),
99 QString
const & label2
= QString(),
100 QString
const & dir2
= QString(),
101 QString
const & fallback_dir
= QString())
103 QString lastPath
= ".";
104 if (!filename
.isEmpty())
105 lastPath
= onlyPath(filename
);
106 else if(!fallback_dir
.isEmpty())
107 lastPath
= fallback_dir
;
109 FileDialog
dlg(title
, LFUN_SELECT_FILE_SYNC
);
110 dlg
.setButton2(label1
, dir1
);
111 dlg
.setButton2(label2
, dir2
);
113 FileDialog::Result result
;
116 result
= dlg
.save(lastPath
, filters
, onlyFilename(filename
));
118 result
= dlg
.open(lastPath
, filters
, onlyFilename(filename
));
120 return result
.second
;
124 /** Wrapper around browseFile which tries to provide a filename
125 * relative to the user or system directory. The dir, name and ext
126 * parameters have the same meaning as in the
127 * support::LibFileSearch function.
129 QString
browseLibFile(QString
const & dir
,
130 QString
const & name
,
132 QString
const & title
,
133 QStringList
const & filters
)
136 QString
const label1
= qt_("System files|#S#s");
138 toqstr(addName(package().system_support().absFilename(), fromqstr(dir
)));
140 QString
const label2
= qt_("User files|#U#u");
142 toqstr(addName(package().user_support().absFilename(), fromqstr(dir
)));
144 QString
const result
= browseFile(toqstr(
145 libFileSearch(dir
, name
, ext
).absFilename()),
146 title
, filters
, false, dir1
, dir2
, QString(), QString(), dir1
);
148 // remove the extension if it is the default one
150 if (getExtension(result
) == ext
)
151 noextresult
= removeExtension(result
);
153 noextresult
= result
;
155 // remove the directory, if it is the default one
156 QString
const file
= onlyFilename(noextresult
);
157 if (toqstr(libFileSearch(dir
, file
, ext
).absFilename()) == result
)
164 /** Launch a file dialog and return the chosen directory.
165 pathname: a suggested pathname.
166 title: the title of the dialog.
167 dir1 = (name, dir), dir2 = (name, dir): extra buttons on the dialog.
169 QString
browseDir(QString
const & pathname
,
170 QString
const & title
,
171 QString
const & label1
= QString(),
172 QString
const & dir1
= QString(),
173 QString
const & label2
= QString(),
174 QString
const & dir2
= QString())
176 QString lastPath
= ".";
177 if (!pathname
.isEmpty())
178 lastPath
= onlyPath(pathname
);
180 FileDialog
dlg(title
, LFUN_SELECT_FILE_SYNC
);
181 dlg
.setButton1(label1
, dir1
);
182 dlg
.setButton2(label2
, dir2
);
184 FileDialog::Result
const result
=
185 dlg
.opendir(lastPath
, onlyFilename(pathname
));
187 return result
.second
;
191 } // namespace frontend
194 QString
browseRelFile(QString
const & filename
, QString
const & refpath
,
195 QString
const & title
, QStringList
const & filters
, bool save
,
196 QString
const & label1
, QString
const & dir1
,
197 QString
const & label2
, QString
const & dir2
)
199 QString
const fname
= makeAbsPath(filename
, refpath
);
202 QString
const outname
=
203 frontend::browseFile(fname
, title
, filters
, save
, label1
, dir1
, label2
, dir2
);
205 QString
const reloutname
=
206 toqstr(makeRelPath(qstring_to_ucs4(outname
), qstring_to_ucs4(refpath
)));
208 if (reloutname
.startsWith("../"))
216 /////////////////////////////////////////////////////////////////////
220 /////////////////////////////////////////////////////////////////////
224 string
const catLookAndFeel
= N_("Look & Feel");
225 string
const catEditing
= N_("Editing");
226 string
const catLanguage
= N_("Language Settings");
227 string
const catOutput
= N_("Output");
228 string
const catFiles
= N_("File Handling");
230 static void parseFontName(QString
const & mangled0
,
231 string
& name
, string
& foundry
)
233 string mangled
= fromqstr(mangled0
);
234 size_t const idx
= mangled
.find('[');
235 if (idx
== string::npos
|| idx
== 0) {
239 name
= mangled
.substr(0, idx
- 1),
240 foundry
= mangled
.substr(idx
+ 1, mangled
.size() - idx
- 2);
245 static void setComboxFont(QComboBox
* cb
, string
const & family
,
246 string
const & foundry
)
248 QString fontname
= toqstr(family
);
249 if (!foundry
.empty())
250 fontname
+= " [" + toqstr(foundry
) + ']';
252 for (int i
= 0; i
!= cb
->count(); ++i
) {
253 if (cb
->itemText(i
) == fontname
) {
254 cb
->setCurrentIndex(i
);
259 // Try matching without foundry name
261 // We count in reverse in order to prefer the Xft foundry
262 for (int i
= cb
->count(); --i
>= 0;) {
263 string name
, foundry
;
264 parseFontName(cb
->itemText(i
), name
, foundry
);
265 if (compare_ascii_no_case(name
, family
) == 0) {
266 cb
->setCurrentIndex(i
);
271 // family alone can contain e.g. "Helvetica [Adobe]"
272 string tmpname
, tmpfoundry
;
273 parseFontName(toqstr(family
), tmpname
, tmpfoundry
);
275 // We count in reverse in order to prefer the Xft foundry
276 for (int i
= cb
->count(); --i
>= 0; ) {
277 string name
, foundry
;
278 parseFontName(cb
->itemText(i
), name
, foundry
);
279 if (compare_ascii_no_case(name
, foundry
) == 0) {
280 cb
->setCurrentIndex(i
);
285 // Bleh, default fonts, and the names couldn't be found. Hack
289 font
.setKerning(false);
291 QString
const font_family
= toqstr(family
);
292 if (font_family
== guiApp
->romanFontName()) {
293 font
.setStyleHint(QFont::Serif
);
294 font
.setFamily(font_family
);
295 } else if (font_family
== guiApp
->sansFontName()) {
296 font
.setStyleHint(QFont::SansSerif
);
297 font
.setFamily(font_family
);
298 } else if (font_family
== guiApp
->typewriterFontName()) {
299 font
.setStyleHint(QFont::TypeWriter
);
300 font
.setFamily(font_family
);
302 LYXERR0("FAILED to find the default font: '"
303 << foundry
<< "', '" << family
<< '\'');
307 QFontInfo
info(font
);
308 string default_font_name
, dummyfoundry
;
309 parseFontName(info
.family(), default_font_name
, dummyfoundry
);
310 LYXERR0("Apparent font is " << default_font_name
);
312 for (int i
= 0; i
< cb
->count(); ++i
) {
313 LYXERR0("Looking at " << cb
->itemText(i
));
314 if (compare_ascii_no_case(fromqstr(cb
->itemText(i
)),
315 default_font_name
) == 0) {
316 cb
->setCurrentIndex(i
);
321 LYXERR0("FAILED to find the font: '"
322 << foundry
<< "', '" << family
<< '\'');
327 /////////////////////////////////////////////////////////////////////
331 /////////////////////////////////////////////////////////////////////
333 PrefPlaintext::PrefPlaintext(GuiPreferences
* form
)
334 : PrefModule(qt_(catOutput
), qt_("Plain text"), form
)
337 connect(plaintextLinelengthSB
, SIGNAL(valueChanged(int)),
338 this, SIGNAL(changed()));
342 void PrefPlaintext::apply(LyXRC
& rc
) const
344 rc
.plaintext_linelen
= plaintextLinelengthSB
->value();
348 void PrefPlaintext::update(LyXRC
const & rc
)
350 plaintextLinelengthSB
->setValue(rc
.plaintext_linelen
);
354 /////////////////////////////////////////////////////////////////////
358 /////////////////////////////////////////////////////////////////////
360 class StrftimeValidator
: public QValidator
363 StrftimeValidator(QWidget
*);
364 QValidator::State
validate(QString
& input
, int & pos
) const;
368 StrftimeValidator::StrftimeValidator(QWidget
* parent
)
374 QValidator::State
StrftimeValidator::validate(QString
& input
, int & /*pos*/) const
376 if (is_valid_strftime(fromqstr(input
)))
377 return QValidator::Acceptable
;
379 return QValidator::Intermediate
;
383 /////////////////////////////////////////////////////////////////////
387 /////////////////////////////////////////////////////////////////////
389 PrefDate::PrefDate(GuiPreferences
* form
)
390 : PrefModule(qt_(catOutput
), qt_("Date format"), form
)
393 DateED
->setValidator(new StrftimeValidator(DateED
));
394 connect(DateED
, SIGNAL(textChanged(QString
)),
395 this, SIGNAL(changed()));
399 void PrefDate::on_DateED_textChanged(const QString
&)
401 QString t
= DateED
->text();
403 bool valid
= DateED
->validator()->validate(t
, p
)
404 == QValidator::Acceptable
;
405 setValid(DateLA
, valid
);
409 void PrefDate::apply(LyXRC
& rc
) const
411 rc
.date_insert_format
= fromqstr(DateED
->text());
415 void PrefDate::update(LyXRC
const & rc
)
417 DateED
->setText(toqstr(rc
.date_insert_format
));
421 /////////////////////////////////////////////////////////////////////
425 /////////////////////////////////////////////////////////////////////
427 PrefInput::PrefInput(GuiPreferences
* form
)
428 : PrefModule(qt_(catEditing
), qt_("Keyboard/Mouse"), form
)
432 connect(keymapCB
, SIGNAL(clicked()),
433 this, SIGNAL(changed()));
434 connect(firstKeymapED
, SIGNAL(textChanged(QString
)),
435 this, SIGNAL(changed()));
436 connect(secondKeymapED
, SIGNAL(textChanged(QString
)),
437 this, SIGNAL(changed()));
438 connect(mouseWheelSpeedSB
, SIGNAL(valueChanged(double)),
439 this, SIGNAL(changed()));
443 void PrefInput::apply(LyXRC
& rc
) const
445 // FIXME: can derive CB from the two EDs
446 rc
.use_kbmap
= keymapCB
->isChecked();
447 rc
.primary_kbmap
= internal_path(fromqstr(firstKeymapED
->text()));
448 rc
.secondary_kbmap
= internal_path(fromqstr(secondKeymapED
->text()));
449 rc
.mouse_wheel_speed
= mouseWheelSpeedSB
->value();
453 void PrefInput::update(LyXRC
const & rc
)
455 // FIXME: can derive CB from the two EDs
456 keymapCB
->setChecked(rc
.use_kbmap
);
457 firstKeymapED
->setText(toqstr(external_path(rc
.primary_kbmap
)));
458 secondKeymapED
->setText(toqstr(external_path(rc
.secondary_kbmap
)));
459 mouseWheelSpeedSB
->setValue(rc
.mouse_wheel_speed
);
463 QString
PrefInput::testKeymap(QString
const & keymap
)
465 return form_
->browsekbmap(internalPath(keymap
));
469 void PrefInput::on_firstKeymapPB_clicked(bool)
471 QString
const file
= testKeymap(firstKeymapED
->text());
473 firstKeymapED
->setText(file
);
477 void PrefInput::on_secondKeymapPB_clicked(bool)
479 QString
const file
= testKeymap(secondKeymapED
->text());
481 secondKeymapED
->setText(file
);
485 void PrefInput::on_keymapCB_toggled(bool keymap
)
487 firstKeymapLA
->setEnabled(keymap
);
488 secondKeymapLA
->setEnabled(keymap
);
489 firstKeymapED
->setEnabled(keymap
);
490 secondKeymapED
->setEnabled(keymap
);
491 firstKeymapPB
->setEnabled(keymap
);
492 secondKeymapPB
->setEnabled(keymap
);
496 /////////////////////////////////////////////////////////////////////
500 /////////////////////////////////////////////////////////////////////
502 PrefCompletion::PrefCompletion(GuiPreferences
* form
)
503 : PrefModule(qt_(catEditing
), qt_("Input Completion"), form
)
507 connect(inlineDelaySB
, SIGNAL(valueChanged(double)),
508 this, SIGNAL(changed()));
509 connect(inlineMathCB
, SIGNAL(clicked()),
510 this, SIGNAL(changed()));
511 connect(inlineTextCB
, SIGNAL(clicked()),
512 this, SIGNAL(changed()));
513 connect(inlineDotsCB
, SIGNAL(clicked()),
514 this, SIGNAL(changed()));
515 connect(popupDelaySB
, SIGNAL(valueChanged(double)),
516 this, SIGNAL(changed()));
517 connect(popupMathCB
, SIGNAL(clicked()),
518 this, SIGNAL(changed()));
519 connect(popupTextCB
, SIGNAL(clicked()),
520 this, SIGNAL(changed()));
521 connect(popupAfterCompleteCB
, SIGNAL(clicked()),
522 this, SIGNAL(changed()));
523 connect(cursorTextCB
, SIGNAL(clicked()),
524 this, SIGNAL(changed()));
528 void PrefCompletion::on_inlineTextCB_clicked()
530 on_popupTextCB_clicked();
534 void PrefCompletion::on_popupTextCB_clicked()
536 cursorTextCB
->setEnabled(
537 popupTextCB
->isChecked() || inlineTextCB
->isChecked());
541 void PrefCompletion::apply(LyXRC
& rc
) const
543 rc
.completion_inline_delay
= inlineDelaySB
->value();
544 rc
.completion_inline_math
= inlineMathCB
->isChecked();
545 rc
.completion_inline_text
= inlineTextCB
->isChecked();
546 rc
.completion_inline_dots
= inlineDotsCB
->isChecked() ? 13 : -1;
547 rc
.completion_popup_delay
= popupDelaySB
->value();
548 rc
.completion_popup_math
= popupMathCB
->isChecked();
549 rc
.completion_popup_text
= popupTextCB
->isChecked();
550 rc
.completion_cursor_text
= cursorTextCB
->isChecked();
551 rc
.completion_popup_after_complete
=
552 popupAfterCompleteCB
->isChecked();
556 void PrefCompletion::update(LyXRC
const & rc
)
558 inlineDelaySB
->setValue(rc
.completion_inline_delay
);
559 inlineMathCB
->setChecked(rc
.completion_inline_math
);
560 inlineTextCB
->setChecked(rc
.completion_inline_text
);
561 inlineDotsCB
->setChecked(rc
.completion_inline_dots
!= -1);
562 popupDelaySB
->setValue(rc
.completion_popup_delay
);
563 popupMathCB
->setChecked(rc
.completion_popup_math
);
564 popupTextCB
->setChecked(rc
.completion_popup_text
);
565 cursorTextCB
->setChecked(rc
.completion_cursor_text
);
566 popupAfterCompleteCB
->setChecked(rc
.completion_popup_after_complete
);
567 on_popupTextCB_clicked();
572 /////////////////////////////////////////////////////////////////////
576 /////////////////////////////////////////////////////////////////////
578 PrefLatex::PrefLatex(GuiPreferences
* form
)
579 : PrefModule(qt_(catOutput
), qt_("LaTeX"), form
)
582 connect(latexEncodingED
, SIGNAL(textChanged(QString
)),
583 this, SIGNAL(changed()));
584 connect(latexChecktexED
, SIGNAL(textChanged(QString
)),
585 this, SIGNAL(changed()));
586 connect(latexBibtexCO
, SIGNAL(activated(int)),
587 this, SIGNAL(changed()));
588 connect(latexBibtexED
, SIGNAL(textChanged(QString
)),
589 this, SIGNAL(changed()));
590 connect(latexJBibtexED
, SIGNAL(textChanged(QString
)),
591 this, SIGNAL(changed()));
592 connect(latexIndexCO
, SIGNAL(activated(int)),
593 this, SIGNAL(changed()));
594 connect(latexIndexED
, SIGNAL(textChanged(QString
)),
595 this, SIGNAL(changed()));
596 connect(latexJIndexED
, SIGNAL(textChanged(QString
)),
597 this, SIGNAL(changed()));
598 connect(latexAutoresetCB
, SIGNAL(clicked()),
599 this, SIGNAL(changed()));
600 connect(latexDviPaperED
, SIGNAL(textChanged(QString
)),
601 this, SIGNAL(changed()));
602 connect(latexPaperSizeCO
, SIGNAL(activated(int)),
603 this, SIGNAL(changed()));
605 #if defined(__CYGWIN__) || defined(_WIN32)
606 pathCB
->setVisible(true);
607 connect(pathCB
, SIGNAL(clicked()),
608 this, SIGNAL(changed()));
610 pathCB
->setVisible(false);
615 void PrefLatex::on_latexBibtexCO_activated(int n
)
617 QString
const bibtex
= latexBibtexCO
->itemData(n
).toString();
618 if (bibtex
.isEmpty()) {
619 latexBibtexED
->clear();
620 latexBibtexOptionsLA
->setText(qt_("C&ommand:"));
623 for (vector
<string
>::const_iterator it
= bibtex_alternatives
.begin();
624 it
!= bibtex_alternatives
.end(); ++it
) {
625 QString
const bib
= toqstr(*it
);
626 int ind
= bib
.indexOf(" ");
627 QString sel_command
= bib
.left(ind
);
628 QString sel_options
= bib
;
629 sel_options
.remove(0, ind
);
630 if (bibtex
== sel_command
) {
632 latexBibtexED
->clear();
634 latexBibtexED
->setText(sel_options
.trimmed());
637 latexBibtexOptionsLA
->setText(qt_("&Options:"));
641 void PrefLatex::on_latexIndexCO_activated(int n
)
643 QString
const index
= latexIndexCO
->itemData(n
).toString();
644 if (index
.isEmpty()) {
645 latexIndexED
->clear();
646 latexIndexOptionsLA
->setText(qt_("Co&mmand:"));
649 for (vector
<string
>::const_iterator it
= index_alternatives
.begin();
650 it
!= index_alternatives
.end(); ++it
) {
651 QString
const idx
= toqstr(*it
);
652 int ind
= idx
.indexOf(" ");
653 QString sel_command
= idx
.left(ind
);
654 QString sel_options
= idx
;
655 sel_options
.remove(0, ind
);
656 if (index
== sel_command
) {
658 latexIndexED
->clear();
660 latexIndexED
->setText(sel_options
.trimmed());
663 latexIndexOptionsLA
->setText(qt_("Op&tions:"));
667 void PrefLatex::apply(LyXRC
& rc
) const
669 QString
const bibtex
= latexBibtexCO
->itemData(
670 latexBibtexCO
->currentIndex()).toString();
671 if (bibtex
.isEmpty())
672 rc
.bibtex_command
= fromqstr(latexBibtexED
->text());
674 rc
.bibtex_command
= fromqstr(bibtex
) + " " + fromqstr(latexBibtexED
->text());
676 QString
const index
= latexIndexCO
->itemData(
677 latexIndexCO
->currentIndex()).toString();
679 rc
.index_command
= fromqstr(latexIndexED
->text());
681 rc
.index_command
= fromqstr(index
) + " " + fromqstr(latexIndexED
->text());
683 rc
.fontenc
= fromqstr(latexEncodingED
->text());
684 rc
.chktex_command
= fromqstr(latexChecktexED
->text());
685 rc
.jbibtex_command
= fromqstr(latexJBibtexED
->text());
686 rc
.jindex_command
= fromqstr(latexJIndexED
->text());
687 rc
.nomencl_command
= fromqstr(latexNomenclED
->text());
688 rc
.auto_reset_options
= latexAutoresetCB
->isChecked();
689 rc
.view_dvi_paper_option
= fromqstr(latexDviPaperED
->text());
690 rc
.default_papersize
=
691 form_
->toPaperSize(latexPaperSizeCO
->currentIndex());
692 #if defined(__CYGWIN__) || defined(_WIN32)
693 rc
.windows_style_tex_paths
= pathCB
->isChecked();
698 void PrefLatex::update(LyXRC
const & rc
)
700 latexBibtexCO
->clear();
702 latexBibtexCO
->addItem(qt_("Custom"), QString());
703 for (vector
<string
>::const_iterator it
= rc
.bibtex_alternatives
.begin();
704 it
!= rc
.bibtex_alternatives
.end(); ++it
) {
705 QString
const command
= toqstr(*it
).left(toqstr(*it
).indexOf(" "));
706 latexBibtexCO
->addItem(command
, command
);
709 bibtex_alternatives
= rc
.bibtex_alternatives
;
711 QString
const bib
= toqstr(rc
.bibtex_command
);
712 int ind
= bib
.indexOf(" ");
713 QString sel_command
= bib
.left(ind
);
714 QString sel_options
= bib
;
715 sel_options
.remove(0, ind
);
717 int pos
= latexBibtexCO
->findData(sel_command
);
719 latexBibtexCO
->setCurrentIndex(pos
);
720 latexBibtexED
->setText(sel_options
.trimmed());
721 latexBibtexOptionsLA
->setText(qt_("&Options:"));
723 latexBibtexED
->setText(toqstr(rc
.bibtex_command
));
724 latexBibtexCO
->setCurrentIndex(0);
725 latexBibtexOptionsLA
->setText(qt_("C&ommand:"));
728 latexIndexCO
->clear();
730 latexIndexCO
->addItem(qt_("Custom"), QString());
731 for (vector
<string
>::const_iterator it
= rc
.index_alternatives
.begin();
732 it
!= rc
.index_alternatives
.end(); ++it
) {
733 QString
const command
= toqstr(*it
).left(toqstr(*it
).indexOf(" "));
734 latexIndexCO
->addItem(command
, command
);
737 index_alternatives
= rc
.index_alternatives
;
739 QString
const idx
= toqstr(rc
.index_command
);
740 ind
= idx
.indexOf(" ");
741 sel_command
= idx
.left(ind
);
743 sel_options
.remove(0, ind
);
745 pos
= latexIndexCO
->findData(sel_command
);
747 latexIndexCO
->setCurrentIndex(pos
);
748 latexIndexED
->setText(sel_options
.trimmed());
749 latexIndexOptionsLA
->setText(qt_("Op&tions:"));
751 latexIndexED
->setText(toqstr(rc
.index_command
));
752 latexIndexCO
->setCurrentIndex(0);
753 latexIndexOptionsLA
->setText(qt_("Co&mmand:"));
756 latexEncodingED
->setText(toqstr(rc
.fontenc
));
757 latexChecktexED
->setText(toqstr(rc
.chktex_command
));
758 latexJBibtexED
->setText(toqstr(rc
.jbibtex_command
));
759 latexJIndexED
->setText(toqstr(rc
.jindex_command
));
760 latexNomenclED
->setText(toqstr(rc
.nomencl_command
));
761 latexAutoresetCB
->setChecked(rc
.auto_reset_options
);
762 latexDviPaperED
->setText(toqstr(rc
.view_dvi_paper_option
));
763 latexPaperSizeCO
->setCurrentIndex(
764 form_
->fromPaperSize(rc
.default_papersize
));
765 #if defined(__CYGWIN__) || defined(_WIN32)
766 pathCB
->setChecked(rc
.windows_style_tex_paths
);
771 /////////////////////////////////////////////////////////////////////
775 /////////////////////////////////////////////////////////////////////
777 PrefScreenFonts::PrefScreenFonts(GuiPreferences
* form
)
778 : PrefModule(qt_(catLookAndFeel
), qt_("Screen fonts"), form
)
782 connect(screenRomanCO
, SIGNAL(activated(QString
)),
783 this, SLOT(select_roman(QString
)));
784 connect(screenSansCO
, SIGNAL(activated(QString
)),
785 this, SLOT(select_sans(QString
)));
786 connect(screenTypewriterCO
, SIGNAL(activated(QString
)),
787 this, SLOT(select_typewriter(QString
)));
789 QFontDatabase fontdb
;
790 QStringList
families(fontdb
.families());
791 for (QStringList::Iterator it
= families
.begin(); it
!= families
.end(); ++it
) {
792 screenRomanCO
->addItem(*it
);
793 screenSansCO
->addItem(*it
);
794 screenTypewriterCO
->addItem(*it
);
796 connect(screenRomanCO
, SIGNAL(activated(QString
)),
797 this, SIGNAL(changed()));
798 connect(screenSansCO
, SIGNAL(activated(QString
)),
799 this, SIGNAL(changed()));
800 connect(screenTypewriterCO
, SIGNAL(activated(QString
)),
801 this, SIGNAL(changed()));
802 connect(screenZoomSB
, SIGNAL(valueChanged(int)),
803 this, SIGNAL(changed()));
804 connect(screenDpiSB
, SIGNAL(valueChanged(int)),
805 this, SIGNAL(changed()));
806 connect(screenTinyED
, SIGNAL(textChanged(QString
)),
807 this, SIGNAL(changed()));
808 connect(screenSmallestED
, SIGNAL(textChanged(QString
)),
809 this, SIGNAL(changed()));
810 connect(screenSmallerED
, SIGNAL(textChanged(QString
)),
811 this, SIGNAL(changed()));
812 connect(screenSmallED
, SIGNAL(textChanged(QString
)),
813 this, SIGNAL(changed()));
814 connect(screenNormalED
, SIGNAL(textChanged(QString
)),
815 this, SIGNAL(changed()));
816 connect(screenLargeED
, SIGNAL(textChanged(QString
)),
817 this, SIGNAL(changed()));
818 connect(screenLargerED
, SIGNAL(textChanged(QString
)),
819 this, SIGNAL(changed()));
820 connect(screenLargestED
, SIGNAL(textChanged(QString
)),
821 this, SIGNAL(changed()));
822 connect(screenHugeED
, SIGNAL(textChanged(QString
)),
823 this, SIGNAL(changed()));
824 connect(screenHugerED
, SIGNAL(textChanged(QString
)),
825 this, SIGNAL(changed()));
826 connect(pixmapCacheCB
, SIGNAL(toggled(bool)),
827 this, SIGNAL(changed()));
829 screenTinyED
->setValidator(new QDoubleValidator(screenTinyED
));
830 screenSmallestED
->setValidator(new QDoubleValidator(screenSmallestED
));
831 screenSmallerED
->setValidator(new QDoubleValidator(screenSmallerED
));
832 screenSmallED
->setValidator(new QDoubleValidator(screenSmallED
));
833 screenNormalED
->setValidator(new QDoubleValidator(screenNormalED
));
834 screenLargeED
->setValidator(new QDoubleValidator(screenLargeED
));
835 screenLargerED
->setValidator(new QDoubleValidator(screenLargerED
));
836 screenLargestED
->setValidator(new QDoubleValidator(screenLargestED
));
837 screenHugeED
->setValidator(new QDoubleValidator(screenHugeED
));
838 screenHugerED
->setValidator(new QDoubleValidator(screenHugerED
));
842 void PrefScreenFonts::apply(LyXRC
& rc
) const
844 LyXRC
const oldrc
= rc
;
846 parseFontName(screenRomanCO
->currentText(),
847 rc
.roman_font_name
, rc
.roman_font_foundry
);
848 parseFontName(screenSansCO
->currentText(),
849 rc
.sans_font_name
, rc
.sans_font_foundry
);
850 parseFontName(screenTypewriterCO
->currentText(),
851 rc
.typewriter_font_name
, rc
.typewriter_font_foundry
);
853 rc
.zoom
= screenZoomSB
->value();
854 rc
.dpi
= screenDpiSB
->value();
855 rc
.font_sizes
[FONT_SIZE_TINY
] = fromqstr(screenTinyED
->text());
856 rc
.font_sizes
[FONT_SIZE_SCRIPT
] = fromqstr(screenSmallestED
->text());
857 rc
.font_sizes
[FONT_SIZE_FOOTNOTE
] = fromqstr(screenSmallerED
->text());
858 rc
.font_sizes
[FONT_SIZE_SMALL
] = fromqstr(screenSmallED
->text());
859 rc
.font_sizes
[FONT_SIZE_NORMAL
] = fromqstr(screenNormalED
->text());
860 rc
.font_sizes
[FONT_SIZE_LARGE
] = fromqstr(screenLargeED
->text());
861 rc
.font_sizes
[FONT_SIZE_LARGER
] = fromqstr(screenLargerED
->text());
862 rc
.font_sizes
[FONT_SIZE_LARGEST
] = fromqstr(screenLargestED
->text());
863 rc
.font_sizes
[FONT_SIZE_HUGE
] = fromqstr(screenHugeED
->text());
864 rc
.font_sizes
[FONT_SIZE_HUGER
] = fromqstr(screenHugerED
->text());
865 rc
.use_pixmap_cache
= pixmapCacheCB
->isChecked();
867 if (rc
.font_sizes
!= oldrc
.font_sizes
868 || rc
.roman_font_name
!= oldrc
.roman_font_name
869 || rc
.sans_font_name
!= oldrc
.sans_font_name
870 || rc
.typewriter_font_name
!= oldrc
.typewriter_font_name
871 || rc
.zoom
!= oldrc
.zoom
|| rc
.dpi
!= oldrc
.dpi
) {
872 // The global QPixmapCache is used in GuiPainter to cache text
873 // painting so we must reset it in case any of the above
874 // parameter is changed.
875 QPixmapCache::clear();
876 guiApp
->fontLoader().update();
877 form_
->updateScreenFonts();
882 void PrefScreenFonts::update(LyXRC
const & rc
)
884 setComboxFont(screenRomanCO
, rc
.roman_font_name
,
885 rc
.roman_font_foundry
);
886 setComboxFont(screenSansCO
, rc
.sans_font_name
,
887 rc
.sans_font_foundry
);
888 setComboxFont(screenTypewriterCO
, rc
.typewriter_font_name
,
889 rc
.typewriter_font_foundry
);
891 select_roman(screenRomanCO
->currentText());
892 select_sans(screenSansCO
->currentText());
893 select_typewriter(screenTypewriterCO
->currentText());
895 screenZoomSB
->setValue(rc
.zoom
);
896 screenDpiSB
->setValue(rc
.dpi
);
897 screenTinyED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_TINY
]));
898 screenSmallestED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_SCRIPT
]));
899 screenSmallerED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_FOOTNOTE
]));
900 screenSmallED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_SMALL
]));
901 screenNormalED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_NORMAL
]));
902 screenLargeED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_LARGE
]));
903 screenLargerED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_LARGER
]));
904 screenLargestED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_LARGEST
]));
905 screenHugeED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_HUGE
]));
906 screenHugerED
->setText(toqstr(rc
.font_sizes
[FONT_SIZE_HUGER
]));
908 pixmapCacheCB
->setChecked(rc
.use_pixmap_cache
);
909 #if defined(Q_WS_X11)
910 pixmapCacheCB
->setEnabled(false);
916 void PrefScreenFonts::select_roman(const QString
& name
)
918 screenRomanFE
->set(QFont(name
), name
);
922 void PrefScreenFonts::select_sans(const QString
& name
)
924 screenSansFE
->set(QFont(name
), name
);
928 void PrefScreenFonts::select_typewriter(const QString
& name
)
930 screenTypewriterFE
->set(QFont(name
), name
);
934 /////////////////////////////////////////////////////////////////////
938 /////////////////////////////////////////////////////////////////////
944 bool operator()(ColorCode lhs
, ColorCode rhs
) const {
946 compare_no_case(lcolor
.getGUIName(lhs
), lcolor
.getGUIName(rhs
)) < 0;
952 PrefColors::PrefColors(GuiPreferences
* form
)
953 : PrefModule(qt_(catLookAndFeel
), qt_("Colors"), form
)
957 // FIXME: all of this initialization should be put into the controller.
958 // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg113301.html
959 // for some discussion of why that is not trivial.
960 QPixmap
icon(32, 32);
961 for (int i
= 0; i
< Color_ignore
; ++i
) {
962 ColorCode lc
= static_cast<ColorCode
>(i
);
970 || lc
== Color_magenta
971 || lc
== Color_yellow
972 || lc
== Color_inherit
973 || lc
== Color_ignore
) continue;
975 lcolors_
.push_back(lc
);
977 sort(lcolors_
.begin(), lcolors_
.end(), ColorSorter());
978 vector
<ColorCode
>::const_iterator cit
= lcolors_
.begin();
979 vector
<ColorCode
>::const_iterator
const end
= lcolors_
.end();
980 for (; cit
!= end
; ++cit
) {
981 (void) new QListWidgetItem(QIcon(icon
),
982 toqstr(lcolor
.getGUIName(*cit
)), lyxObjectsLW
);
984 curcolors_
.resize(lcolors_
.size());
985 newcolors_
.resize(lcolors_
.size());
986 // End initialization
988 connect(colorChangePB
, SIGNAL(clicked()),
989 this, SLOT(change_color()));
990 connect(lyxObjectsLW
, SIGNAL(itemSelectionChanged()),
991 this, SLOT(change_lyxObjects_selection()));
992 connect(lyxObjectsLW
, SIGNAL(itemActivated(QListWidgetItem
*)),
993 this, SLOT(change_color()));
997 void PrefColors::apply(LyXRC
& /*rc*/) const
999 for (unsigned int i
= 0; i
< lcolors_
.size(); ++i
)
1000 if (curcolors_
[i
] != newcolors_
[i
])
1001 form_
->setColor(lcolors_
[i
], newcolors_
[i
]);
1005 void PrefColors::update(LyXRC
const & /*rc*/)
1007 for (unsigned int i
= 0; i
< lcolors_
.size(); ++i
) {
1008 QColor color
= QColor(guiApp
->colorCache().get(lcolors_
[i
]));
1009 QPixmap
coloritem(32, 32);
1010 coloritem
.fill(color
);
1011 lyxObjectsLW
->item(i
)->setIcon(QIcon(coloritem
));
1012 newcolors_
[i
] = curcolors_
[i
] = color
.name();
1014 change_lyxObjects_selection();
1018 void PrefColors::change_color()
1020 int const row
= lyxObjectsLW
->currentRow();
1026 QString
const color
= newcolors_
[row
];
1027 QColor c
= QColorDialog::getColor(QColor(color
), qApp
->focusWidget());
1029 if (c
.isValid() && c
.name() != color
) {
1030 newcolors_
[row
] = c
.name();
1031 QPixmap
coloritem(32, 32);
1033 lyxObjectsLW
->currentItem()->setIcon(QIcon(coloritem
));
1039 void PrefColors::change_lyxObjects_selection()
1041 colorChangePB
->setDisabled(lyxObjectsLW
->currentRow() < 0);
1045 /////////////////////////////////////////////////////////////////////
1049 /////////////////////////////////////////////////////////////////////
1051 PrefDisplay::PrefDisplay(GuiPreferences
* form
)
1052 : PrefModule(qt_(catLookAndFeel
), qt_("Graphics"), form
)
1055 connect(displayGraphicsCB
, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
1056 connect(instantPreviewCO
, SIGNAL(activated(int)), this, SIGNAL(changed()));
1060 void PrefDisplay::apply(LyXRC
& rc
) const
1062 switch (instantPreviewCO
->currentIndex()) {
1063 case 0: rc
.preview
= LyXRC::PREVIEW_OFF
; break;
1064 case 1: rc
.preview
= LyXRC::PREVIEW_NO_MATH
; break;
1065 case 2: rc
.preview
= LyXRC::PREVIEW_ON
; break;
1068 rc
.display_graphics
= displayGraphicsCB
->isChecked();
1070 // FIXME!! The graphics cache no longer has a changeDisplay method.
1072 if (old_value
!= rc
.display_graphics
) {
1073 graphics::GCache
& gc
= graphics::GCache::get();
1080 void PrefDisplay::update(LyXRC
const & rc
)
1082 switch (rc
.preview
) {
1083 case LyXRC::PREVIEW_OFF
:
1084 instantPreviewCO
->setCurrentIndex(0);
1086 case LyXRC::PREVIEW_NO_MATH
:
1087 instantPreviewCO
->setCurrentIndex(1);
1089 case LyXRC::PREVIEW_ON
:
1090 instantPreviewCO
->setCurrentIndex(2);
1094 displayGraphicsCB
->setChecked(rc
.display_graphics
);
1095 instantPreviewCO
->setEnabled(rc
.display_graphics
);
1099 /////////////////////////////////////////////////////////////////////
1103 /////////////////////////////////////////////////////////////////////
1105 PrefPaths::PrefPaths(GuiPreferences
* form
)
1106 : PrefModule(QString(), qt_("Paths"), form
)
1109 connect(exampleDirPB
, SIGNAL(clicked()), this, SLOT(select_exampledir()));
1110 connect(templateDirPB
, SIGNAL(clicked()), this, SLOT(select_templatedir()));
1111 connect(tempDirPB
, SIGNAL(clicked()), this, SLOT(select_tempdir()));
1112 connect(backupDirPB
, SIGNAL(clicked()), this, SLOT(select_backupdir()));
1113 connect(workingDirPB
, SIGNAL(clicked()), this, SLOT(select_workingdir()));
1114 connect(lyxserverDirPB
, SIGNAL(clicked()), this, SLOT(select_lyxpipe()));
1115 connect(thesaurusDirPB
, SIGNAL(clicked()), this, SLOT(select_thesaurusdir()));
1116 connect(workingDirED
, SIGNAL(textChanged(QString
)),
1117 this, SIGNAL(changed()));
1118 connect(exampleDirED
, SIGNAL(textChanged(QString
)),
1119 this, SIGNAL(changed()));
1120 connect(templateDirED
, SIGNAL(textChanged(QString
)),
1121 this, SIGNAL(changed()));
1122 connect(backupDirED
, SIGNAL(textChanged(QString
)),
1123 this, SIGNAL(changed()));
1124 connect(tempDirED
, SIGNAL(textChanged(QString
)),
1125 this, SIGNAL(changed()));
1126 connect(lyxserverDirED
, SIGNAL(textChanged(QString
)),
1127 this, SIGNAL(changed()));
1128 connect(thesaurusDirED
, SIGNAL(textChanged(QString
)),
1129 this, SIGNAL(changed()));
1130 connect(pathPrefixED
, SIGNAL(textChanged(QString
)),
1131 this, SIGNAL(changed()));
1135 void PrefPaths::apply(LyXRC
& rc
) const
1137 rc
.document_path
= internal_path(fromqstr(workingDirED
->text()));
1138 rc
.example_path
= internal_path(fromqstr(exampleDirED
->text()));
1139 rc
.template_path
= internal_path(fromqstr(templateDirED
->text()));
1140 rc
.backupdir_path
= internal_path(fromqstr(backupDirED
->text()));
1141 rc
.tempdir_path
= internal_path(fromqstr(tempDirED
->text()));
1142 rc
.thesaurusdir_path
= internal_path(fromqstr(thesaurusDirED
->text()));
1143 rc
.path_prefix
= internal_path_list(fromqstr(pathPrefixED
->text()));
1144 // FIXME: should be a checkbox only
1145 rc
.lyxpipes
= internal_path(fromqstr(lyxserverDirED
->text()));
1149 void PrefPaths::update(LyXRC
const & rc
)
1151 workingDirED
->setText(toqstr(external_path(rc
.document_path
)));
1152 exampleDirED
->setText(toqstr(external_path(rc
.example_path
)));
1153 templateDirED
->setText(toqstr(external_path(rc
.template_path
)));
1154 backupDirED
->setText(toqstr(external_path(rc
.backupdir_path
)));
1155 tempDirED
->setText(toqstr(external_path(rc
.tempdir_path
)));
1156 thesaurusDirED
->setText(toqstr(external_path(rc
.thesaurusdir_path
)));
1157 pathPrefixED
->setText(toqstr(external_path_list(rc
.path_prefix
)));
1158 // FIXME: should be a checkbox only
1159 lyxserverDirED
->setText(toqstr(external_path(rc
.lyxpipes
)));
1163 void PrefPaths::select_exampledir()
1165 QString file
= browseDir(internalPath(exampleDirED
->text()),
1166 qt_("Select directory for example files"));
1167 if (!file
.isEmpty())
1168 exampleDirED
->setText(file
);
1172 void PrefPaths::select_templatedir()
1174 QString file
= browseDir(internalPath(templateDirED
->text()),
1175 qt_("Select a document templates directory"));
1176 if (!file
.isEmpty())
1177 templateDirED
->setText(file
);
1181 void PrefPaths::select_tempdir()
1183 QString file
= browseDir(internalPath(tempDirED
->text()),
1184 qt_("Select a temporary directory"));
1185 if (!file
.isEmpty())
1186 tempDirED
->setText(file
);
1190 void PrefPaths::select_backupdir()
1192 QString file
= browseDir(internalPath(backupDirED
->text()),
1193 qt_("Select a backups directory"));
1194 if (!file
.isEmpty())
1195 backupDirED
->setText(file
);
1199 void PrefPaths::select_workingdir()
1201 QString file
= browseDir(internalPath(workingDirED
->text()),
1202 qt_("Select a document directory"));
1203 if (!file
.isEmpty())
1204 workingDirED
->setText(file
);
1208 void PrefPaths::select_thesaurusdir()
1210 QString file
= browseDir(internalPath(thesaurusDirED
->text()),
1211 qt_("Set the path to the thesaurus dictionaries"));
1212 if (!file
.isEmpty())
1213 thesaurusDirED
->setText(file
);
1217 void PrefPaths::select_lyxpipe()
1219 QString file
= form_
->browse(internalPath(lyxserverDirED
->text()),
1220 qt_("Give a filename for the LyX server pipe"));
1221 if (!file
.isEmpty())
1222 lyxserverDirED
->setText(file
);
1226 /////////////////////////////////////////////////////////////////////
1230 /////////////////////////////////////////////////////////////////////
1232 PrefSpellchecker::PrefSpellchecker(GuiPreferences
* form
)
1233 : PrefModule(qt_(catLanguage
), qt_("Spellchecker"), form
)
1237 connect(persDictionaryPB
, SIGNAL(clicked()), this, SLOT(select_dict()));
1239 connect(altLanguageED
, SIGNAL(textChanged(QString
)),
1240 this, SIGNAL(changed()));
1241 connect(escapeCharactersED
, SIGNAL(textChanged(QString
)),
1242 this, SIGNAL(changed()));
1243 connect(persDictionaryED
, SIGNAL(textChanged(QString
)),
1244 this, SIGNAL(changed()));
1245 connect(compoundWordCB
, SIGNAL(clicked()),
1246 this, SIGNAL(changed()));
1247 connect(inputEncodingCB
, SIGNAL(clicked()),
1248 this, SIGNAL(changed()));
1249 connect(spellcheckContinuouslyCB
, SIGNAL(clicked()),
1250 this, SIGNAL(changed()));
1254 void PrefSpellchecker::apply(LyXRC
& rc
) const
1256 // FIXME: remove spellchecker_use_alt_lang
1257 rc
.spellchecker_alt_lang
= fromqstr(altLanguageED
->text());
1258 rc
.spellchecker_use_alt_lang
= !rc
.spellchecker_alt_lang
.empty();
1259 // FIXME: remove spellchecker_use_esc_chars
1260 rc
.spellchecker_esc_chars
= fromqstr(escapeCharactersED
->text());
1261 rc
.spellchecker_use_esc_chars
= !rc
.spellchecker_esc_chars
.empty();
1262 // FIXME: remove spellchecker_use_pers_dict
1263 rc
.spellchecker_pers_dict
= internal_path(fromqstr(persDictionaryED
->text()));
1264 rc
.spellchecker_use_pers_dict
= !rc
.spellchecker_pers_dict
.empty();
1265 rc
.spellchecker_accept_compound
= compoundWordCB
->isChecked();
1266 rc
.spellchecker_use_input_encoding
= inputEncodingCB
->isChecked();
1267 rc
.spellcheck_continuously
= spellcheckContinuouslyCB
->isChecked();
1271 void PrefSpellchecker::update(LyXRC
const & rc
)
1273 // FIXME: remove spellchecker_use_alt_lang
1274 altLanguageED
->setText(toqstr(rc
.spellchecker_alt_lang
));
1275 // FIXME: remove spellchecker_use_esc_chars
1276 escapeCharactersED
->setText(toqstr(rc
.spellchecker_esc_chars
));
1277 // FIXME: remove spellchecker_use_pers_dict
1278 persDictionaryED
->setText(toqstr(external_path(rc
.spellchecker_pers_dict
)));
1279 compoundWordCB
->setChecked(rc
.spellchecker_accept_compound
);
1280 inputEncodingCB
->setChecked(rc
.spellchecker_use_input_encoding
);
1281 spellcheckContinuouslyCB
->setChecked(rc
.spellcheck_continuously
);
1285 void PrefSpellchecker::select_dict()
1287 QString file
= form_
->browsedict(internalPath(persDictionaryED
->text()));
1288 if (!file
.isEmpty())
1289 persDictionaryED
->setText(file
);
1294 /////////////////////////////////////////////////////////////////////
1298 /////////////////////////////////////////////////////////////////////
1301 PrefConverters::PrefConverters(GuiPreferences
* form
)
1302 : PrefModule(qt_(catFiles
), qt_("Converters"), form
)
1306 connect(converterNewPB
, SIGNAL(clicked()),
1307 this, SLOT(update_converter()));
1308 connect(converterRemovePB
, SIGNAL(clicked()),
1309 this, SLOT(remove_converter()));
1310 connect(converterModifyPB
, SIGNAL(clicked()),
1311 this, SLOT(update_converter()));
1312 connect(convertersLW
, SIGNAL(currentRowChanged(int)),
1313 this, SLOT(switch_converter()));
1314 connect(converterFromCO
, SIGNAL(activated(QString
)),
1315 this, SLOT(converter_changed()));
1316 connect(converterToCO
, SIGNAL(activated(QString
)),
1317 this, SLOT(converter_changed()));
1318 connect(converterED
, SIGNAL(textEdited(QString
)),
1319 this, SLOT(converter_changed()));
1320 connect(converterFlagED
, SIGNAL(textEdited(QString
)),
1321 this, SLOT(converter_changed()));
1322 connect(converterNewPB
, SIGNAL(clicked()),
1323 this, SIGNAL(changed()));
1324 connect(converterRemovePB
, SIGNAL(clicked()),
1325 this, SIGNAL(changed()));
1326 connect(converterModifyPB
, SIGNAL(clicked()),
1327 this, SIGNAL(changed()));
1328 connect(maxAgeLE
, SIGNAL(textEdited(QString
)),
1329 this, SIGNAL(changed()));
1331 maxAgeLE
->setValidator(new QDoubleValidator(maxAgeLE
));
1332 //converterDefGB->setFocusProxy(convertersLW);
1336 void PrefConverters::apply(LyXRC
& rc
) const
1338 rc
.use_converter_cache
= cacheCB
->isChecked();
1339 rc
.converter_cache_maxage
= int(maxAgeLE
->text().toDouble() * 86400.0);
1343 void PrefConverters::update(LyXRC
const & rc
)
1345 cacheCB
->setChecked(rc
.use_converter_cache
);
1347 max_age
.setNum(double(rc
.converter_cache_maxage
) / 86400.0, 'g', 6);
1348 maxAgeLE
->setText(max_age
);
1353 void PrefConverters::updateGui()
1355 form_
->formats().sort();
1356 form_
->converters().update(form_
->formats());
1357 // save current selection
1358 QString current
= converterFromCO
->currentText()
1359 + " -> " + converterToCO
->currentText();
1361 converterFromCO
->clear();
1362 converterToCO
->clear();
1364 Formats::const_iterator cit
= form_
->formats().begin();
1365 Formats::const_iterator end
= form_
->formats().end();
1366 for (; cit
!= end
; ++cit
) {
1367 converterFromCO
->addItem(qt_(cit
->prettyname()));
1368 converterToCO
->addItem(qt_(cit
->prettyname()));
1371 // currentRowChanged(int) is also triggered when updating the listwidget
1372 // block signals to avoid unnecessary calls to switch_converter()
1373 convertersLW
->blockSignals(true);
1374 convertersLW
->clear();
1376 Converters::const_iterator ccit
= form_
->converters().begin();
1377 Converters::const_iterator cend
= form_
->converters().end();
1378 for (; ccit
!= cend
; ++ccit
) {
1379 QString
const name
=
1380 qt_(ccit
->From
->prettyname()) + " -> " + qt_(ccit
->To
->prettyname());
1381 int type
= form_
->converters().getNumber(ccit
->From
->name(), ccit
->To
->name());
1382 new QListWidgetItem(name
, convertersLW
, type
);
1384 convertersLW
->sortItems(Qt::AscendingOrder
);
1385 convertersLW
->blockSignals(false);
1387 // restore selection
1388 if (!current
.isEmpty()) {
1389 QList
<QListWidgetItem
*> const item
=
1390 convertersLW
->findItems(current
, Qt::MatchExactly
);
1391 if (!item
.isEmpty())
1392 convertersLW
->setCurrentItem(item
.at(0));
1395 // select first element if restoring failed
1396 if (convertersLW
->currentRow() == -1)
1397 convertersLW
->setCurrentRow(0);
1403 void PrefConverters::switch_converter()
1405 int const cnr
= convertersLW
->currentItem()->type();
1406 Converter
const & c(form_
->converters().get(cnr
));
1407 converterFromCO
->setCurrentIndex(form_
->formats().getNumber(c
.from
));
1408 converterToCO
->setCurrentIndex(form_
->formats().getNumber(c
.to
));
1409 converterED
->setText(toqstr(c
.command
));
1410 converterFlagED
->setText(toqstr(c
.flags
));
1416 void PrefConverters::converter_changed()
1422 void PrefConverters::updateButtons()
1424 Format
const & from
= form_
->formats().get(converterFromCO
->currentIndex());
1425 Format
const & to
= form_
->formats().get(converterToCO
->currentIndex());
1426 int const sel
= form_
->converters().getNumber(from
.name(), to
.name());
1427 bool const known
= sel
>= 0;
1428 bool const valid
= !(converterED
->text().isEmpty()
1429 || from
.name() == to
.name());
1431 int const cnr
= convertersLW
->currentItem()->type();
1432 Converter
const & c
= form_
->converters().get(cnr
);
1433 string
const old_command
= c
.command
;
1434 string
const old_flag
= c
.flags
;
1435 string
const new_command
= fromqstr(converterED
->text());
1436 string
const new_flag
= fromqstr(converterFlagED
->text());
1438 bool modified
= (old_command
!= new_command
|| old_flag
!= new_flag
);
1440 converterModifyPB
->setEnabled(valid
&& known
&& modified
);
1441 converterNewPB
->setEnabled(valid
&& !known
);
1442 converterRemovePB
->setEnabled(known
);
1444 maxAgeLE
->setEnabled(cacheCB
->isChecked());
1445 maxAgeLA
->setEnabled(cacheCB
->isChecked());
1450 // specify unique from/to or it doesn't appear. This is really bad UI
1451 // this is why we can use the same function for both new and modify
1452 void PrefConverters::update_converter()
1454 Format
const & from
= form_
->formats().get(converterFromCO
->currentIndex());
1455 Format
const & to
= form_
->formats().get(converterToCO
->currentIndex());
1456 string
const flags
= fromqstr(converterFlagED
->text());
1457 string
const command
= fromqstr(converterED
->text());
1459 Converter
const * old
=
1460 form_
->converters().getConverter(from
.name(), to
.name());
1461 form_
->converters().add(from
.name(), to
.name(), command
, flags
);
1464 form_
->converters().updateLast(form_
->formats());
1468 // Remove all files created by this converter from the cache, since
1469 // the modified converter might create different files.
1470 ConverterCache::get().remove_all(from
.name(), to
.name());
1474 void PrefConverters::remove_converter()
1476 Format
const & from
= form_
->formats().get(converterFromCO
->currentIndex());
1477 Format
const & to
= form_
->formats().get(converterToCO
->currentIndex());
1478 form_
->converters().erase(from
.name(), to
.name());
1482 // Remove all files created by this converter from the cache, since
1483 // a possible new converter might create different files.
1484 ConverterCache::get().remove_all(from
.name(), to
.name());
1488 void PrefConverters::on_cacheCB_stateChanged(int state
)
1490 maxAgeLE
->setEnabled(state
== Qt::Checked
);
1491 maxAgeLA
->setEnabled(state
== Qt::Checked
);
1496 /////////////////////////////////////////////////////////////////////
1500 /////////////////////////////////////////////////////////////////////
1502 class FormatValidator
: public QValidator
1505 FormatValidator(QWidget
*, Formats
const & f
);
1506 void fixup(QString
& input
) const;
1507 QValidator::State
validate(QString
& input
, int & pos
) const;
1509 virtual QString
toString(Format
const & format
) const = 0;
1511 Formats
const & formats_
;
1515 FormatValidator::FormatValidator(QWidget
* parent
, Formats
const & f
)
1516 : QValidator(parent
), formats_(f
)
1521 void FormatValidator::fixup(QString
& input
) const
1523 Formats::const_iterator cit
= formats_
.begin();
1524 Formats::const_iterator end
= formats_
.end();
1525 for (; cit
!= end
; ++cit
) {
1526 QString
const name
= toString(*cit
);
1527 if (distance(formats_
.begin(), cit
) == nr()) {
1535 QValidator::State
FormatValidator::validate(QString
& input
, int & /*pos*/) const
1537 Formats::const_iterator cit
= formats_
.begin();
1538 Formats::const_iterator end
= formats_
.end();
1539 bool unknown
= true;
1540 for (; unknown
&& cit
!= end
; ++cit
) {
1541 QString
const name
= toString(*cit
);
1542 if (distance(formats_
.begin(), cit
) != nr())
1543 unknown
= name
!= input
;
1546 if (unknown
&& !input
.isEmpty())
1547 return QValidator::Acceptable
;
1549 return QValidator::Intermediate
;
1553 int FormatValidator::nr() const
1555 QComboBox
* p
= qobject_cast
<QComboBox
*>(parent());
1556 return p
->itemData(p
->currentIndex()).toInt();
1560 /////////////////////////////////////////////////////////////////////
1562 // FormatNameValidator
1564 /////////////////////////////////////////////////////////////////////
1566 class FormatNameValidator
: public FormatValidator
1569 FormatNameValidator(QWidget
* parent
, Formats
const & f
)
1570 : FormatValidator(parent
, f
)
1573 QString
toString(Format
const & format
) const
1575 return toqstr(format
.name());
1580 /////////////////////////////////////////////////////////////////////
1582 // FormatPrettynameValidator
1584 /////////////////////////////////////////////////////////////////////
1586 class FormatPrettynameValidator
: public FormatValidator
1589 FormatPrettynameValidator(QWidget
* parent
, Formats
const & f
)
1590 : FormatValidator(parent
, f
)
1593 QString
toString(Format
const & format
) const
1595 return qt_(format
.prettyname());
1600 /////////////////////////////////////////////////////////////////////
1604 /////////////////////////////////////////////////////////////////////
1606 PrefFileformats::PrefFileformats(GuiPreferences
* form
)
1607 : PrefModule(qt_(catFiles
), qt_("File formats"), form
)
1610 formatED
->setValidator(new FormatNameValidator(formatsCB
, form_
->formats()));
1611 formatsCB
->setValidator(new FormatPrettynameValidator(formatsCB
, form_
->formats()));
1613 connect(documentCB
, SIGNAL(clicked()),
1614 this, SLOT(setFlags()));
1615 connect(vectorCB
, SIGNAL(clicked()),
1616 this, SLOT(setFlags()));
1617 connect(formatsCB
->lineEdit(), SIGNAL(editingFinished()),
1618 this, SLOT(updatePrettyname()));
1619 connect(formatsCB
->lineEdit(), SIGNAL(textEdited(QString
)),
1620 this, SIGNAL(changed()));
1621 connect(defaultFormatCB
, SIGNAL(activated(QString
)),
1622 this, SIGNAL(changed()));
1628 string
const l10n_shortcut(string
const prettyname
, string
const shortcut
)
1630 if (shortcut
.empty())
1633 string l10n_format
=
1634 to_utf8(_(prettyname
+ '|' + shortcut
));
1635 return split(l10n_format
, '|');
1638 }; // namespace anon
1641 void PrefFileformats::apply(LyXRC
& rc
) const
1643 QString
const default_format
= defaultFormatCB
->itemData(
1644 defaultFormatCB
->currentIndex()).toString();
1645 rc
.default_view_format
= fromqstr(default_format
);
1649 void PrefFileformats::update(LyXRC
const & rc
)
1651 bool const init
= defaultFormatCB
->currentText().isEmpty();
1654 int const pos
= defaultFormatCB
->findData(toqstr(
1655 rc
.default_view_format
));
1656 defaultFormatCB
->setCurrentIndex(pos
);
1661 void PrefFileformats::updateView()
1663 QString
const current
= formatsCB
->currentText();
1664 QString
const current_def
= defaultFormatCB
->currentText();
1666 // update comboboxes with formats
1667 formatsCB
->blockSignals(true);
1668 defaultFormatCB
->blockSignals(true);
1670 defaultFormatCB
->clear();
1671 form_
->formats().sort();
1672 Formats::const_iterator cit
= form_
->formats().begin();
1673 Formats::const_iterator end
= form_
->formats().end();
1674 for (; cit
!= end
; ++cit
) {
1675 formatsCB
->addItem(qt_(cit
->prettyname()),
1676 QVariant(form_
->formats().getNumber(cit
->name())));
1677 if (form_
->converters().isReachable("latex", cit
->name())
1678 || form_
->converters().isReachable("pdflatex", cit
->name()))
1679 defaultFormatCB
->addItem(qt_(cit
->prettyname()),
1680 QVariant(toqstr(cit
->name())));
1683 // restore selection
1684 int item
= formatsCB
->findText(current
, Qt::MatchExactly
);
1685 formatsCB
->setCurrentIndex(item
< 0 ? 0 : item
);
1686 on_formatsCB_currentIndexChanged(item
< 0 ? 0 : item
);
1687 item
= defaultFormatCB
->findText(current_def
, Qt::MatchExactly
);
1688 defaultFormatCB
->setCurrentIndex(item
< 0 ? 0 : item
);
1689 formatsCB
->blockSignals(false);
1690 defaultFormatCB
->blockSignals(false);
1694 void PrefFileformats::on_formatsCB_currentIndexChanged(int i
)
1696 int const nr
= formatsCB
->itemData(i
).toInt();
1697 Format
const f
= form_
->formats().get(nr
);
1699 formatED
->setText(toqstr(f
.name()));
1700 copierED
->setText(toqstr(form_
->movers().command(f
.name())));
1701 extensionED
->setText(toqstr(f
.extension()));
1702 shortcutED
->setText(
1703 toqstr(l10n_shortcut(f
.prettyname(), f
.shortcut())));
1704 viewerED
->setText(toqstr(f
.viewer()));
1705 editorED
->setText(toqstr(f
.editor()));
1706 documentCB
->setChecked((f
.documentFormat()));
1707 vectorCB
->setChecked((f
.vectorFormat()));
1711 void PrefFileformats::setFlags()
1713 int flags
= Format::none
;
1714 if (documentCB
->isChecked())
1715 flags
|= Format::document
;
1716 if (vectorCB
->isChecked())
1717 flags
|= Format::vector
;
1718 currentFormat().setFlags(flags
);
1723 void PrefFileformats::on_copierED_textEdited(const QString
& s
)
1725 string
const fmt
= fromqstr(formatED
->text());
1726 form_
->movers().set(fmt
, fromqstr(s
));
1731 void PrefFileformats::on_extensionED_textEdited(const QString
& s
)
1733 currentFormat().setExtension(fromqstr(s
));
1737 void PrefFileformats::on_viewerED_textEdited(const QString
& s
)
1739 currentFormat().setViewer(fromqstr(s
));
1744 void PrefFileformats::on_editorED_textEdited(const QString
& s
)
1746 currentFormat().setEditor(fromqstr(s
));
1751 void PrefFileformats::on_shortcutED_textEdited(const QString
& s
)
1753 string
const new_shortcut
= fromqstr(s
);
1754 if (new_shortcut
== l10n_shortcut(currentFormat().prettyname(),
1755 currentFormat().shortcut()))
1757 currentFormat().setShortcut(new_shortcut
);
1762 void PrefFileformats::on_formatED_editingFinished()
1764 string
const newname
= fromqstr(formatED
->displayText());
1765 if (newname
== currentFormat().name())
1768 currentFormat().setName(newname
);
1773 void PrefFileformats::on_formatED_textChanged(const QString
&)
1775 QString t
= formatED
->text();
1777 bool valid
= formatED
->validator()->validate(t
, p
) == QValidator::Acceptable
;
1778 setValid(formatLA
, valid
);
1782 void PrefFileformats::on_formatsCB_editTextChanged(const QString
&)
1784 QString t
= formatsCB
->currentText();
1786 bool valid
= formatsCB
->validator()->validate(t
, p
) == QValidator::Acceptable
;
1787 setValid(formatsLA
, valid
);
1791 void PrefFileformats::updatePrettyname()
1793 QString
const newname
= formatsCB
->currentText();
1794 if (newname
== qt_(currentFormat().prettyname()))
1797 currentFormat().setPrettyname(fromqstr(newname
));
1804 Format
& PrefFileformats::currentFormat()
1806 int const i
= formatsCB
->currentIndex();
1807 int const nr
= formatsCB
->itemData(i
).toInt();
1808 return form_
->formats().get(nr
);
1812 void PrefFileformats::on_formatNewPB_clicked()
1814 form_
->formats().add("", "", "", "", "", "", Format::none
);
1816 formatsCB
->setCurrentIndex(0);
1817 formatsCB
->setFocus(Qt::OtherFocusReason
);
1821 void PrefFileformats::on_formatRemovePB_clicked()
1823 int const i
= formatsCB
->currentIndex();
1824 int const nr
= formatsCB
->itemData(i
).toInt();
1825 string
const current_text
= form_
->formats().get(nr
).name();
1826 if (form_
->converters().formatIsUsed(current_text
)) {
1827 Alert::error(_("Format in use"),
1828 _("Cannot remove a Format used by a Converter. "
1829 "Remove the converter first."));
1833 form_
->formats().erase(current_text
);
1836 on_formatsCB_editTextChanged(formatsCB
->currentText());
1841 /////////////////////////////////////////////////////////////////////
1845 /////////////////////////////////////////////////////////////////////
1847 PrefLanguage::PrefLanguage(GuiPreferences
* form
)
1848 : PrefModule(qt_(catLanguage
), qt_("Language"), form
)
1852 connect(rtlGB
, SIGNAL(clicked()),
1853 this, SIGNAL(changed()));
1854 connect(visualCursorRB
, SIGNAL(clicked()),
1855 this, SIGNAL(changed()));
1856 connect(logicalCursorRB
, SIGNAL(clicked()),
1857 this, SIGNAL(changed()));
1858 connect(markForeignCB
, SIGNAL(clicked()),
1859 this, SIGNAL(changed()));
1860 connect(autoBeginCB
, SIGNAL(clicked()),
1861 this, SIGNAL(changed()));
1862 connect(autoEndCB
, SIGNAL(clicked()),
1863 this, SIGNAL(changed()));
1864 connect(useBabelCB
, SIGNAL(clicked()),
1865 this, SIGNAL(changed()));
1866 connect(globalCB
, SIGNAL(clicked()),
1867 this, SIGNAL(changed()));
1868 connect(languagePackageED
, SIGNAL(textChanged(QString
)),
1869 this, SIGNAL(changed()));
1870 connect(startCommandED
, SIGNAL(textChanged(QString
)),
1871 this, SIGNAL(changed()));
1872 connect(endCommandED
, SIGNAL(textChanged(QString
)),
1873 this, SIGNAL(changed()));
1874 connect(uiLanguageCO
, SIGNAL(activated(int)),
1875 this, SIGNAL(changed()));
1877 uiLanguageCO
->clear();
1879 QAbstractItemModel
* language_model
= guiApp
->languageModel();
1880 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
1881 language_model
->sort(0);
1883 // FIXME: This is wrong, we need filter this list based on the available
1885 uiLanguageCO
->blockSignals(true);
1886 uiLanguageCO
->addItem(qt_("Default"), toqstr("auto"));
1887 for (int i
= 0; i
!= language_model
->rowCount(); ++i
) {
1888 QModelIndex index
= language_model
->index(i
, 0);
1889 uiLanguageCO
->addItem(index
.data(Qt::DisplayRole
).toString(),
1890 index
.data(Qt::UserRole
).toString());
1892 uiLanguageCO
->blockSignals(false);
1896 void PrefLanguage::on_uiLanguageCO_currentIndexChanged(int)
1898 QMessageBox::information(this, qt_("LyX needs to be restarted!"),
1899 qt_("The change of user interface language will be fully "
1900 "effective only after a restart."));
1904 void PrefLanguage::apply(LyXRC
& rc
) const
1906 // FIXME: remove rtl_support bool
1907 rc
.rtl_support
= rtlGB
->isChecked();
1908 rc
.visual_cursor
= rtlGB
->isChecked() && visualCursorRB
->isChecked();
1909 rc
.mark_foreign_language
= markForeignCB
->isChecked();
1910 rc
.language_auto_begin
= autoBeginCB
->isChecked();
1911 rc
.language_auto_end
= autoEndCB
->isChecked();
1912 rc
.language_use_babel
= useBabelCB
->isChecked();
1913 rc
.language_global_options
= globalCB
->isChecked();
1914 rc
.language_package
= fromqstr(languagePackageED
->text());
1915 rc
.language_command_begin
= fromqstr(startCommandED
->text());
1916 rc
.language_command_end
= fromqstr(endCommandED
->text());
1917 rc
.gui_language
= fromqstr(
1918 uiLanguageCO
->itemData(uiLanguageCO
->currentIndex()).toString());
1922 void PrefLanguage::update(LyXRC
const & rc
)
1924 // FIXME: remove rtl_support bool
1925 rtlGB
->setChecked(rc
.rtl_support
);
1926 if (rc
.visual_cursor
)
1927 visualCursorRB
->setChecked(true);
1929 logicalCursorRB
->setChecked(true);
1930 markForeignCB
->setChecked(rc
.mark_foreign_language
);
1931 autoBeginCB
->setChecked(rc
.language_auto_begin
);
1932 autoEndCB
->setChecked(rc
.language_auto_end
);
1933 useBabelCB
->setChecked(rc
.language_use_babel
);
1934 globalCB
->setChecked(rc
.language_global_options
);
1935 languagePackageED
->setText(toqstr(rc
.language_package
));
1936 startCommandED
->setText(toqstr(rc
.language_command_begin
));
1937 endCommandED
->setText(toqstr(rc
.language_command_end
));
1939 int pos
= uiLanguageCO
->findData(toqstr(rc
.gui_language
));
1940 uiLanguageCO
->blockSignals(true);
1941 uiLanguageCO
->setCurrentIndex(pos
);
1942 uiLanguageCO
->blockSignals(false);
1946 /////////////////////////////////////////////////////////////////////
1950 /////////////////////////////////////////////////////////////////////
1952 PrefPrinter::PrefPrinter(GuiPreferences
* form
)
1953 : PrefModule(qt_(catOutput
), qt_("Printer"), form
)
1957 connect(printerAdaptCB
, SIGNAL(clicked()),
1958 this, SIGNAL(changed()));
1959 connect(printerCommandED
, SIGNAL(textChanged(QString
)),
1960 this, SIGNAL(changed()));
1961 connect(printerNameED
, SIGNAL(textChanged(QString
)),
1962 this, SIGNAL(changed()));
1963 connect(printerPageRangeED
, SIGNAL(textChanged(QString
)),
1964 this, SIGNAL(changed()));
1965 connect(printerCopiesED
, SIGNAL(textChanged(QString
)),
1966 this, SIGNAL(changed()));
1967 connect(printerReverseED
, SIGNAL(textChanged(QString
)),
1968 this, SIGNAL(changed()));
1969 connect(printerToPrinterED
, SIGNAL(textChanged(QString
)),
1970 this, SIGNAL(changed()));
1971 connect(printerExtensionED
, SIGNAL(textChanged(QString
)),
1972 this, SIGNAL(changed()));
1973 connect(printerSpoolCommandED
, SIGNAL(textChanged(QString
)),
1974 this, SIGNAL(changed()));
1975 connect(printerPaperTypeED
, SIGNAL(textChanged(QString
)),
1976 this, SIGNAL(changed()));
1977 connect(printerEvenED
, SIGNAL(textChanged(QString
)),
1978 this, SIGNAL(changed()));
1979 connect(printerOddED
, SIGNAL(textChanged(QString
)),
1980 this, SIGNAL(changed()));
1981 connect(printerCollatedED
, SIGNAL(textChanged(QString
)),
1982 this, SIGNAL(changed()));
1983 connect(printerLandscapeED
, SIGNAL(textChanged(QString
)),
1984 this, SIGNAL(changed()));
1985 connect(printerToFileED
, SIGNAL(textChanged(QString
)),
1986 this, SIGNAL(changed()));
1987 connect(printerExtraED
, SIGNAL(textChanged(QString
)),
1988 this, SIGNAL(changed()));
1989 connect(printerSpoolPrefixED
, SIGNAL(textChanged(QString
)),
1990 this, SIGNAL(changed()));
1991 connect(printerPaperSizeED
, SIGNAL(textChanged(QString
)),
1992 this, SIGNAL(changed()));
1996 void PrefPrinter::apply(LyXRC
& rc
) const
1998 rc
.print_adapt_output
= printerAdaptCB
->isChecked();
1999 rc
.print_command
= fromqstr(printerCommandED
->text());
2000 rc
.printer
= fromqstr(printerNameED
->text());
2002 rc
.print_pagerange_flag
= fromqstr(printerPageRangeED
->text());
2003 rc
.print_copies_flag
= fromqstr(printerCopiesED
->text());
2004 rc
.print_reverse_flag
= fromqstr(printerReverseED
->text());
2005 rc
.print_to_printer
= fromqstr(printerToPrinterED
->text());
2006 rc
.print_file_extension
= fromqstr(printerExtensionED
->text());
2007 rc
.print_spool_command
= fromqstr(printerSpoolCommandED
->text());
2008 rc
.print_paper_flag
= fromqstr(printerPaperTypeED
->text());
2009 rc
.print_evenpage_flag
= fromqstr(printerEvenED
->text());
2010 rc
.print_oddpage_flag
= fromqstr(printerOddED
->text());
2011 rc
.print_collcopies_flag
= fromqstr(printerCollatedED
->text());
2012 rc
.print_landscape_flag
= fromqstr(printerLandscapeED
->text());
2013 rc
.print_to_file
= internal_path(fromqstr(printerToFileED
->text()));
2014 rc
.print_extra_options
= fromqstr(printerExtraED
->text());
2015 rc
.print_spool_printerprefix
= fromqstr(printerSpoolPrefixED
->text());
2016 rc
.print_paper_dimension_flag
= fromqstr(printerPaperSizeED
->text());
2020 void PrefPrinter::update(LyXRC
const & rc
)
2022 printerAdaptCB
->setChecked(rc
.print_adapt_output
);
2023 printerCommandED
->setText(toqstr(rc
.print_command
));
2024 printerNameED
->setText(toqstr(rc
.printer
));
2026 printerPageRangeED
->setText(toqstr(rc
.print_pagerange_flag
));
2027 printerCopiesED
->setText(toqstr(rc
.print_copies_flag
));
2028 printerReverseED
->setText(toqstr(rc
.print_reverse_flag
));
2029 printerToPrinterED
->setText(toqstr(rc
.print_to_printer
));
2030 printerExtensionED
->setText(toqstr(rc
.print_file_extension
));
2031 printerSpoolCommandED
->setText(toqstr(rc
.print_spool_command
));
2032 printerPaperTypeED
->setText(toqstr(rc
.print_paper_flag
));
2033 printerEvenED
->setText(toqstr(rc
.print_evenpage_flag
));
2034 printerOddED
->setText(toqstr(rc
.print_oddpage_flag
));
2035 printerCollatedED
->setText(toqstr(rc
.print_collcopies_flag
));
2036 printerLandscapeED
->setText(toqstr(rc
.print_landscape_flag
));
2037 printerToFileED
->setText(toqstr(external_path(rc
.print_to_file
)));
2038 printerExtraED
->setText(toqstr(rc
.print_extra_options
));
2039 printerSpoolPrefixED
->setText(toqstr(rc
.print_spool_printerprefix
));
2040 printerPaperSizeED
->setText(toqstr(rc
.print_paper_dimension_flag
));
2044 /////////////////////////////////////////////////////////////////////
2046 // PrefUserInterface
2048 /////////////////////////////////////////////////////////////////////
2050 PrefUserInterface::PrefUserInterface(GuiPreferences
* form
)
2051 : PrefModule(qt_(catLookAndFeel
), qt_("User interface"), form
)
2055 connect(autoSaveCB
, SIGNAL(toggled(bool)),
2056 autoSaveSB
, SLOT(setEnabled(bool)));
2057 connect(autoSaveCB
, SIGNAL(toggled(bool)),
2058 TextLabel1
, SLOT(setEnabled(bool)));
2059 connect(openDocumentsInTabsCB
, SIGNAL(clicked()),
2060 this, SIGNAL(changed()));
2061 connect(uiFilePB
, SIGNAL(clicked()),
2062 this, SLOT(select_ui()));
2063 connect(uiFileED
, SIGNAL(textChanged(QString
)),
2064 this, SIGNAL(changed()));
2065 connect(restoreCursorCB
, SIGNAL(clicked()),
2066 this, SIGNAL(changed()));
2067 connect(loadSessionCB
, SIGNAL(clicked()),
2068 this, SIGNAL(changed()));
2069 connect(allowGeometrySessionCB
, SIGNAL(clicked()),
2070 this, SIGNAL(changed()));
2071 connect(autoSaveSB
, SIGNAL(valueChanged(int)),
2072 this, SIGNAL(changed()));
2073 connect(autoSaveCB
, SIGNAL(clicked()),
2074 this, SIGNAL(changed()));
2075 connect(lastfilesSB
, SIGNAL(valueChanged(int)),
2076 this, SIGNAL(changed()));
2077 connect(tooltipCB
, SIGNAL(toggled(bool)),
2078 this, SIGNAL(changed()));
2079 lastfilesSB
->setMaximum(maxlastfiles
);
2083 void PrefUserInterface::apply(LyXRC
& rc
) const
2085 rc
.ui_file
= internal_path(fromqstr(uiFileED
->text()));
2086 rc
.use_lastfilepos
= restoreCursorCB
->isChecked();
2087 rc
.load_session
= loadSessionCB
->isChecked();
2088 rc
.allow_geometry_session
= allowGeometrySessionCB
->isChecked();
2089 rc
.autosave
= autoSaveSB
->value() * 60;
2090 rc
.make_backup
= autoSaveCB
->isChecked();
2091 rc
.num_lastfiles
= lastfilesSB
->value();
2092 rc
.use_tooltip
= tooltipCB
->isChecked();
2093 rc
.open_buffers_in_tabs
= openDocumentsInTabsCB
->isChecked();
2097 void PrefUserInterface::update(LyXRC
const & rc
)
2099 uiFileED
->setText(toqstr(external_path(rc
.ui_file
)));
2100 restoreCursorCB
->setChecked(rc
.use_lastfilepos
);
2101 loadSessionCB
->setChecked(rc
.load_session
);
2102 allowGeometrySessionCB
->setChecked(rc
.allow_geometry_session
);
2103 // convert to minutes
2104 int mins(rc
.autosave
/ 60);
2105 if (rc
.autosave
&& !mins
)
2107 autoSaveSB
->setValue(mins
);
2108 autoSaveCB
->setChecked(rc
.make_backup
);
2109 lastfilesSB
->setValue(rc
.num_lastfiles
);
2110 tooltipCB
->setChecked(rc
.use_tooltip
);
2111 openDocumentsInTabsCB
->setChecked(rc
.open_buffers_in_tabs
);
2115 void PrefUserInterface::select_ui()
2117 QString file
= form_
->browseUI(internalPath(uiFileED
->text()));
2118 if (!file
.isEmpty())
2119 uiFileED
->setText(file
);
2123 void PrefUserInterface::on_clearSessionPB_clicked()
2125 guiApp
->clearSession();
2130 /////////////////////////////////////////////////////////////////////
2134 /////////////////////////////////////////////////////////////////////
2136 PrefEdit::PrefEdit(GuiPreferences
* form
)
2137 : PrefModule(qt_(catEditing
), qt_("Control"), form
)
2141 connect(cursorFollowsCB
, SIGNAL(clicked()),
2142 this, SIGNAL(changed()));
2143 connect(scrollBelowCB
, SIGNAL(clicked()),
2144 this, SIGNAL(changed()));
2145 connect(sortEnvironmentsCB
, SIGNAL(clicked()),
2146 this, SIGNAL(changed()));
2147 connect(groupEnvironmentsCB
, SIGNAL(clicked()),
2148 this, SIGNAL(changed()));
2149 connect(macroEditStyleCO
, SIGNAL(activated(int)),
2150 this, SIGNAL(changed()));
2151 connect(fullscreenLimitGB
, SIGNAL(clicked()),
2152 this, SIGNAL(changed()));
2153 connect(fullscreenWidthSB
, SIGNAL(valueChanged(int)),
2154 this, SIGNAL(changed()));
2155 connect(toggleTabbarCB
, SIGNAL(toggled(bool)),
2156 this, SIGNAL(changed()));
2157 connect(toggleScrollbarCB
, SIGNAL(toggled(bool)),
2158 this, SIGNAL(changed()));
2159 connect(toggleToolbarsCB
, SIGNAL(toggled(bool)),
2160 this, SIGNAL(changed()));
2164 void PrefEdit::apply(LyXRC
& rc
) const
2166 rc
.cursor_follows_scrollbar
= cursorFollowsCB
->isChecked();
2167 rc
.scroll_below_document
= scrollBelowCB
->isChecked();
2168 rc
.sort_layouts
= sortEnvironmentsCB
->isChecked();
2169 rc
.group_layouts
= groupEnvironmentsCB
->isChecked();
2170 switch (macroEditStyleCO
->currentIndex()) {
2171 case 0: rc
.macro_edit_style
= LyXRC::MACRO_EDIT_INLINE_BOX
; break;
2172 case 1: rc
.macro_edit_style
= LyXRC::MACRO_EDIT_INLINE
; break;
2173 case 2: rc
.macro_edit_style
= LyXRC::MACRO_EDIT_LIST
; break;
2175 rc
.full_screen_toolbars
= toggleToolbarsCB
->isChecked();
2176 rc
.full_screen_scrollbar
= toggleScrollbarCB
->isChecked();
2177 rc
.full_screen_tabbar
= toggleTabbarCB
->isChecked();
2178 rc
.full_screen_width
= fullscreenWidthSB
->value();
2179 rc
.full_screen_limit
= fullscreenLimitGB
->isChecked();
2183 void PrefEdit::update(LyXRC
const & rc
)
2185 cursorFollowsCB
->setChecked(rc
.cursor_follows_scrollbar
);
2186 scrollBelowCB
->setChecked(rc
.scroll_below_document
);
2187 sortEnvironmentsCB
->setChecked(rc
.sort_layouts
);
2188 groupEnvironmentsCB
->setChecked(rc
.group_layouts
);
2189 macroEditStyleCO
->setCurrentIndex(rc
.macro_edit_style
);
2190 toggleScrollbarCB
->setChecked(rc
.full_screen_scrollbar
);
2191 toggleToolbarsCB
->setChecked(rc
.full_screen_toolbars
);
2192 toggleTabbarCB
->setChecked(rc
.full_screen_tabbar
);
2193 fullscreenWidthSB
->setValue(rc
.full_screen_width
);
2194 fullscreenLimitGB
->setChecked(rc
.full_screen_limit
);
2198 /////////////////////////////////////////////////////////////////////
2202 /////////////////////////////////////////////////////////////////////
2205 GuiShortcutDialog::GuiShortcutDialog(QWidget
* parent
) : QDialog(parent
)
2207 Ui::shortcutUi::setupUi(this);
2208 QDialog::setModal(true);
2212 PrefShortcuts::PrefShortcuts(GuiPreferences
* form
)
2213 : PrefModule(qt_(catEditing
), qt_("Shortcuts"), form
)
2217 shortcutsTW
->setColumnCount(2);
2218 shortcutsTW
->headerItem()->setText(0, qt_("Function"));
2219 shortcutsTW
->headerItem()->setText(1, qt_("Shortcut"));
2220 shortcutsTW
->setSortingEnabled(true);
2221 // Multi-selection can be annoying.
2222 // shortcutsTW->setSelectionMode(QAbstractItemView::MultiSelection);
2224 connect(bindFilePB
, SIGNAL(clicked()),
2225 this, SLOT(select_bind()));
2226 connect(bindFileED
, SIGNAL(textChanged(QString
)),
2227 this, SIGNAL(changed()));
2228 connect(removePB
, SIGNAL(clicked()),
2229 this, SIGNAL(changed()));
2231 shortcut_
= new GuiShortcutDialog(this);
2232 shortcut_bc_
.setPolicy(ButtonPolicy::OkCancelPolicy
);
2233 shortcut_bc_
.setOK(shortcut_
->okPB
);
2234 shortcut_bc_
.setCancel(shortcut_
->cancelPB
);
2236 connect(shortcut_
->okPB
, SIGNAL(clicked()),
2237 shortcut_
, SLOT(accept()));
2238 connect(shortcut_
->okPB
, SIGNAL(clicked()),
2239 this, SIGNAL(changed()));
2240 connect(shortcut_
->cancelPB
, SIGNAL(clicked()),
2241 shortcut_
, SLOT(reject()));
2242 connect(shortcut_
->clearPB
, SIGNAL(clicked()),
2243 this, SLOT(shortcut_clearPB_pressed()));
2244 connect(shortcut_
->removePB
, SIGNAL(clicked()),
2245 this, SLOT(shortcut_removePB_pressed()));
2246 connect(shortcut_
->okPB
, SIGNAL(clicked()),
2247 this, SLOT(shortcut_okPB_pressed()));
2248 connect(shortcut_
->cancelPB
, SIGNAL(clicked()),
2249 this, SLOT(shortcut_cancelPB_pressed()));
2253 void PrefShortcuts::apply(LyXRC
& rc
) const
2255 rc
.bind_file
= internal_path(fromqstr(bindFileED
->text()));
2256 // write user_bind and user_unbind to .lyx/bind/user.bind
2257 FileName
bind_dir(addPath(package().user_support().absFilename(), "bind"));
2258 if (!bind_dir
.exists() && !bind_dir
.createDirectory(0777)) {
2259 lyxerr
<< "LyX could not create the user bind directory '"
2260 << bind_dir
<< "'. All user-defined key bindings will be lost." << endl
;
2263 if (!bind_dir
.isDirWritable()) {
2264 lyxerr
<< "LyX could not write to the user bind directory '"
2265 << bind_dir
<< "'. All user-defined key bindings will be lost." << endl
;
2268 FileName
user_bind_file(bind_dir
.absFilename() + "/user.bind");
2269 user_unbind_
.write(user_bind_file
.toFilesystemEncoding(), false, true);
2270 user_bind_
.write(user_bind_file
.toFilesystemEncoding(), true, false);
2271 // immediately apply the keybindings. Why this is not done before?
2272 // The good thing is that the menus are updated automatically.
2273 theTopLevelKeymap().clear();
2274 theTopLevelKeymap().read("site");
2275 theTopLevelKeymap().read(rc
.bind_file
);
2276 theTopLevelKeymap().read("user");
2280 void PrefShortcuts::update(LyXRC
const & rc
)
2282 bindFileED
->setText(toqstr(external_path(rc
.bind_file
)));
2284 system_bind_
.clear();
2286 user_unbind_
.clear();
2287 system_bind_
.read("site");
2288 system_bind_
.read(rc
.bind_file
);
2289 // \unbind in user.bind is added to user_unbind_
2290 user_bind_
.read("user", &user_unbind_
);
2291 updateShortcutsTW();
2295 void PrefShortcuts::updateShortcutsTW()
2297 shortcutsTW
->clear();
2299 editItem_
= new QTreeWidgetItem(shortcutsTW
);
2300 editItem_
->setText(0, qt_("Cursor, Mouse and Editing functions"));
2301 editItem_
->setFlags(editItem_
->flags() & ~Qt::ItemIsSelectable
);
2303 mathItem_
= new QTreeWidgetItem(shortcutsTW
);
2304 mathItem_
->setText(0, qt_("Mathematical Symbols"));
2305 mathItem_
->setFlags(mathItem_
->flags() & ~Qt::ItemIsSelectable
);
2307 bufferItem_
= new QTreeWidgetItem(shortcutsTW
);
2308 bufferItem_
->setText(0, qt_("Document and Window"));
2309 bufferItem_
->setFlags(bufferItem_
->flags() & ~Qt::ItemIsSelectable
);
2311 layoutItem_
= new QTreeWidgetItem(shortcutsTW
);
2312 layoutItem_
->setText(0, qt_("Font, Layouts and Textclasses"));
2313 layoutItem_
->setFlags(layoutItem_
->flags() & ~Qt::ItemIsSelectable
);
2315 systemItem_
= new QTreeWidgetItem(shortcutsTW
);
2316 systemItem_
->setText(0, qt_("System and Miscellaneous"));
2317 systemItem_
->setFlags(systemItem_
->flags() & ~Qt::ItemIsSelectable
);
2319 // listBindings(unbound=true) lists all bound and unbound lfuns
2320 // Items in this list is tagged by its source.
2321 KeyMap::BindingList bindinglist
= system_bind_
.listBindings(true,
2323 KeyMap::BindingList user_bindinglist
= user_bind_
.listBindings(false,
2325 KeyMap::BindingList user_unbindinglist
= user_unbind_
.listBindings(false,
2326 KeyMap::UserUnbind
);
2327 bindinglist
.insert(bindinglist
.end(), user_bindinglist
.begin(),
2328 user_bindinglist
.end());
2329 bindinglist
.insert(bindinglist
.end(), user_unbindinglist
.begin(),
2330 user_unbindinglist
.end());
2332 KeyMap::BindingList::const_iterator it
= bindinglist
.begin();
2333 KeyMap::BindingList::const_iterator it_end
= bindinglist
.end();
2334 for (; it
!= it_end
; ++it
)
2335 insertShortcutItem(it
->request
, it
->sequence
, KeyMap::ItemType(it
->tag
));
2337 shortcutsTW
->sortItems(0, Qt::AscendingOrder
);
2338 QList
<QTreeWidgetItem
*> items
= shortcutsTW
->selectedItems();
2339 removePB
->setEnabled(!items
.isEmpty() && !items
[0]->text(1).isEmpty());
2340 modifyPB
->setEnabled(!items
.isEmpty());
2342 shortcutsTW
->resizeColumnToContents(0);
2346 void PrefShortcuts::setItemType(QTreeWidgetItem
* item
, KeyMap::ItemType tag
)
2348 item
->setData(0, Qt::UserRole
, QVariant(tag
));
2352 case KeyMap::System
:
2354 case KeyMap::UserBind
:
2357 case KeyMap::UserUnbind
:
2358 font
.setStrikeOut(true);
2360 // this item is not displayed now.
2361 case KeyMap::UserExtraUnbind
:
2362 font
.setStrikeOut(true);
2366 item
->setFont(1, font
);
2370 QTreeWidgetItem
* PrefShortcuts::insertShortcutItem(FuncRequest
const & lfun
,
2371 KeySequence
const & seq
, KeyMap::ItemType tag
)
2373 FuncCode action
= lfun
.action
;
2374 string
const action_name
= lyxaction
.getActionName(action
);
2375 QString
const lfun_name
= toqstr(from_utf8(action_name
)
2376 + ' ' + lfun
.argument());
2377 QString
const shortcut
= toqstr(seq
.print(KeySequence::ForGui
));
2378 KeyMap::ItemType item_tag
= tag
;
2380 QTreeWidgetItem
* newItem
= 0;
2381 // for unbind items, try to find an existing item in the system bind list
2382 if (tag
== KeyMap::UserUnbind
) {
2383 QList
<QTreeWidgetItem
*> const items
= shortcutsTW
->findItems(lfun_name
,
2384 Qt::MatchFlags(Qt::MatchExactly
| Qt::MatchRecursive
), 0);
2385 for (int i
= 0; i
< items
.size(); ++i
) {
2386 if (items
[i
]->text(1) == shortcut
)
2390 // if not found, this unbind item is KeyMap::UserExtraUnbind
2391 // Such an item is not displayed to avoid confusion (what is
2392 // unmatched removed?).
2394 item_tag
= KeyMap::UserExtraUnbind
;
2399 switch(lyxaction
.getActionType(action
)) {
2400 case LyXAction::Hidden
:
2402 case LyXAction::Edit
:
2403 newItem
= new QTreeWidgetItem(editItem_
);
2405 case LyXAction::Math
:
2406 newItem
= new QTreeWidgetItem(mathItem_
);
2408 case LyXAction::Buffer
:
2409 newItem
= new QTreeWidgetItem(bufferItem_
);
2411 case LyXAction::Layout
:
2412 newItem
= new QTreeWidgetItem(layoutItem_
);
2414 case LyXAction::System
:
2415 newItem
= new QTreeWidgetItem(systemItem_
);
2418 // this should not happen
2419 newItem
= new QTreeWidgetItem(shortcutsTW
);
2423 newItem
->setText(0, lfun_name
);
2424 newItem
->setText(1, shortcut
);
2425 // record BindFile representation to recover KeySequence when needed.
2426 newItem
->setData(1, Qt::UserRole
, toqstr(seq
.print(KeySequence::BindFile
)));
2427 setItemType(newItem
, item_tag
);
2432 void PrefShortcuts::on_shortcutsTW_itemSelectionChanged()
2434 QList
<QTreeWidgetItem
*> items
= shortcutsTW
->selectedItems();
2435 removePB
->setEnabled(!items
.isEmpty() && !items
[0]->text(1).isEmpty());
2436 modifyPB
->setEnabled(!items
.isEmpty());
2437 if (items
.isEmpty())
2440 KeyMap::ItemType tag
=
2441 static_cast<KeyMap::ItemType
>(items
[0]->data(0, Qt::UserRole
).toInt());
2442 if (tag
== KeyMap::UserUnbind
)
2443 removePB
->setText(qt_("Res&tore"));
2445 removePB
->setText(qt_("Remo&ve"));
2449 void PrefShortcuts::on_shortcutsTW_itemDoubleClicked()
2455 void PrefShortcuts::modifyShortcut()
2457 QTreeWidgetItem
* item
= shortcutsTW
->currentItem();
2458 if (item
->flags() & Qt::ItemIsSelectable
) {
2459 shortcut_
->lfunLE
->setText(item
->text(0));
2460 save_lfun_
= item
->text(0);
2461 shortcut_
->shortcutWG
->setText(item
->text(1));
2463 seq
.parse(fromqstr(item
->data(1, Qt::UserRole
).toString()));
2464 shortcut_
->shortcutWG
->setKeySequence(seq
);
2465 shortcut_
->shortcutWG
->setFocus();
2471 void PrefShortcuts::removeShortcut()
2473 // it seems that only one item can be selected, but I am
2474 // removing all selected items anyway.
2475 QList
<QTreeWidgetItem
*> items
= shortcutsTW
->selectedItems();
2476 for (int i
= 0; i
< items
.size(); ++i
) {
2477 string shortcut
= fromqstr(items
[i
]->data(1, Qt::UserRole
).toString());
2478 string lfun
= fromqstr(items
[i
]->text(0));
2479 FuncRequest func
= lyxaction
.lookupFunc(lfun
);
2480 KeyMap::ItemType tag
=
2481 static_cast<KeyMap::ItemType
>(items
[i
]->data(0, Qt::UserRole
).toInt());
2484 case KeyMap::System
: {
2485 // for system bind, we do not touch the item
2486 // but add an user unbind item
2487 user_unbind_
.bind(shortcut
, func
);
2488 setItemType(items
[i
], KeyMap::UserUnbind
);
2489 removePB
->setText(qt_("Res&tore"));
2492 case KeyMap::UserBind
: {
2493 // for user_bind, we remove this bind
2494 QTreeWidgetItem
* parent
= items
[i
]->parent();
2495 int itemIdx
= parent
->indexOfChild(items
[i
]);
2496 parent
->takeChild(itemIdx
);
2498 shortcutsTW
->scrollToItem(parent
->child(itemIdx
- 1));
2500 shortcutsTW
->scrollToItem(parent
);
2501 user_bind_
.unbind(shortcut
, func
);
2504 case KeyMap::UserUnbind
: {
2505 // for user_unbind, we remove the unbind, and the item
2506 // become KeyMap::System again.
2507 user_unbind_
.unbind(shortcut
, func
);
2508 setItemType(items
[i
], KeyMap::System
);
2509 removePB
->setText(qt_("Remo&ve"));
2512 case KeyMap::UserExtraUnbind
: {
2513 // for user unbind that is not in system bind file,
2514 // remove this unbind file
2515 QTreeWidgetItem
* parent
= items
[i
]->parent();
2516 parent
->takeChild(parent
->indexOfChild(items
[i
]));
2517 user_unbind_
.unbind(shortcut
, func
);
2524 void PrefShortcuts::select_bind()
2526 QString file
= form_
->browsebind(internalPath(bindFileED
->text()));
2527 if (!file
.isEmpty()) {
2528 bindFileED
->setText(file
);
2529 system_bind_
= KeyMap();
2530 system_bind_
.read(fromqstr(file
));
2531 updateShortcutsTW();
2536 void PrefShortcuts::on_modifyPB_pressed()
2542 void PrefShortcuts::on_newPB_pressed()
2544 shortcut_
->lfunLE
->clear();
2545 shortcut_
->shortcutWG
->reset();
2546 save_lfun_
= QString();
2551 void PrefShortcuts::on_removePB_pressed()
2557 void PrefShortcuts::on_searchLE_textEdited()
2559 if (searchLE
->text().isEmpty()) {
2560 // show all hidden items
2561 QTreeWidgetItemIterator
it(shortcutsTW
, QTreeWidgetItemIterator::Hidden
);
2563 shortcutsTW
->setItemHidden(*it
++, false);
2566 // search both columns
2567 QList
<QTreeWidgetItem
*> matched
= shortcutsTW
->findItems(searchLE
->text(),
2568 Qt::MatchFlags(Qt::MatchContains
| Qt::MatchRecursive
), 0);
2569 matched
+= shortcutsTW
->findItems(searchLE
->text(),
2570 Qt::MatchFlags(Qt::MatchContains
| Qt::MatchRecursive
), 1);
2572 // hide everyone (to avoid searching in matched QList repeatedly
2573 QTreeWidgetItemIterator
it(shortcutsTW
, QTreeWidgetItemIterator::Selectable
);
2575 shortcutsTW
->setItemHidden(*it
++, true);
2576 // show matched items
2577 for (int i
= 0; i
< matched
.size(); ++i
) {
2578 shortcutsTW
->setItemHidden(matched
[i
], false);
2579 shortcutsTW
->setItemExpanded(matched
[i
]->parent(), true);
2584 docstring
makeCmdString(FuncRequest
const & f
)
2586 docstring actionStr
= from_ascii(lyxaction
.getActionName(f
.action
));
2587 if (!f
.argument().empty())
2588 actionStr
+= " " + f
.argument();
2593 void PrefShortcuts::shortcut_okPB_pressed()
2595 QString
const new_lfun
= shortcut_
->lfunLE
->text();
2596 FuncRequest func
= lyxaction
.lookupFunc(fromqstr(new_lfun
));
2598 if (func
.action
== LFUN_UNKNOWN_ACTION
) {
2599 Alert::error(_("Failed to create shortcut"),
2600 _("Unknown or invalid LyX function"));
2604 KeySequence k
= shortcut_
->shortcutWG
->getKeySequence();
2605 if (k
.length() == 0) {
2606 Alert::error(_("Failed to create shortcut"),
2607 _("Invalid or empty key sequence"));
2611 // check to see if there's been any change
2612 FuncRequest oldBinding
= system_bind_
.getBinding(k
);
2613 if (oldBinding
.action
== LFUN_UNKNOWN_ACTION
)
2614 oldBinding
= user_bind_
.getBinding(k
);
2615 if (oldBinding
== func
) {
2616 docstring
const actionStr
= makeCmdString(func
);
2617 Alert::error(_("Failed to create shortcut"),
2618 bformat(_("Shortcut `%1$s' is already bound to:\n%2$s"),
2619 k
.print(KeySequence::ForGui
), actionStr
));
2623 // make sure this key isn't already bound---and, if so, not unbound
2624 FuncCode
const unbind
= user_unbind_
.getBinding(k
).action
;
2625 if (oldBinding
.action
!= LFUN_UNKNOWN_ACTION
&& unbind
== LFUN_UNKNOWN_ACTION
)
2627 // FIXME Perhaps we should offer to over-write the old shortcut?
2628 // If so, we'll need to remove it from our list, etc.
2629 docstring
const actionStr
= makeCmdString(oldBinding
);
2630 Alert::error(_("Failed to create shortcut"),
2631 bformat(_("Shortcut `%1$s' is already bound to:\n%2$s\n"
2632 "You need to remove that binding before creating a new one."),
2633 k
.print(KeySequence::ForGui
), actionStr
));
2637 if (!save_lfun_
.isEmpty() && new_lfun
== save_lfun_
)
2638 // real modification of the lfun's shortcut,
2639 // so remove the previous one
2642 QTreeWidgetItem
* item
= insertShortcutItem(func
, k
, KeyMap::UserBind
);
2644 user_bind_
.bind(&k
, func
);
2645 shortcutsTW
->sortItems(0, Qt::AscendingOrder
);
2646 shortcutsTW
->setItemExpanded(item
->parent(), true);
2647 shortcutsTW
->scrollToItem(item
);
2649 Alert::error(_("Failed to create shortcut"),
2650 _("Can not insert shortcut to the list"));
2656 void PrefShortcuts::shortcut_cancelPB_pressed()
2658 shortcut_
->shortcutWG
->reset();
2662 void PrefShortcuts::shortcut_clearPB_pressed()
2664 shortcut_
->shortcutWG
->reset();
2668 void PrefShortcuts::shortcut_removePB_pressed()
2670 shortcut_
->shortcutWG
->removeFromSequence();
2674 /////////////////////////////////////////////////////////////////////
2678 /////////////////////////////////////////////////////////////////////
2680 PrefIdentity::PrefIdentity(GuiPreferences
* form
)
2681 : PrefModule(QString(), qt_("Identity"), form
)
2685 connect(nameED
, SIGNAL(textChanged(QString
)),
2686 this, SIGNAL(changed()));
2687 connect(emailED
, SIGNAL(textChanged(QString
)),
2688 this, SIGNAL(changed()));
2692 void PrefIdentity::apply(LyXRC
& rc
) const
2694 rc
.user_name
= fromqstr(nameED
->text());
2695 rc
.user_email
= fromqstr(emailED
->text());
2699 void PrefIdentity::update(LyXRC
const & rc
)
2701 nameED
->setText(toqstr(rc
.user_name
));
2702 emailED
->setText(toqstr(rc
.user_email
));
2707 /////////////////////////////////////////////////////////////////////
2711 /////////////////////////////////////////////////////////////////////
2713 GuiPreferences::GuiPreferences(GuiView
& lv
)
2714 : GuiDialog(lv
, "prefs", qt_("Preferences")), update_screen_font_(false)
2718 QDialog::setModal(false);
2720 connect(savePB
, SIGNAL(clicked()), this, SLOT(slotOK()));
2721 connect(applyPB
, SIGNAL(clicked()), this, SLOT(slotApply()));
2722 connect(closePB
, SIGNAL(clicked()), this, SLOT(slotClose()));
2723 connect(restorePB
, SIGNAL(clicked()), this, SLOT(slotRestore()));
2725 addModule(new PrefUserInterface(this));
2726 addModule(new PrefEdit(this));
2727 addModule(new PrefShortcuts(this));
2728 addModule(new PrefScreenFonts(this));
2729 addModule(new PrefColors(this));
2730 addModule(new PrefDisplay(this));
2731 addModule(new PrefInput(this));
2732 addModule(new PrefCompletion(this));
2734 addModule(new PrefPaths(this));
2736 addModule(new PrefIdentity(this));
2738 addModule(new PrefLanguage(this));
2739 addModule(new PrefSpellchecker(this));
2741 addModule(new PrefPrinter(this));
2742 PrefDate
* dateFormat
= new PrefDate(this);
2743 addModule(dateFormat
);
2744 addModule(new PrefPlaintext(this));
2745 addModule(new PrefLatex(this));
2747 PrefConverters
* converters
= new PrefConverters(this);
2748 PrefFileformats
* formats
= new PrefFileformats(this);
2749 connect(formats
, SIGNAL(formatsChanged()),
2750 converters
, SLOT(updateGui()));
2751 addModule(converters
);
2754 prefsPS
->setCurrentPanel(qt_("User interface"));
2755 // FIXME: hack to work around resizing bug in Qt >= 4.2
2756 // bug verified with Qt 4.2.{0-3} (JSpitzm)
2757 #if QT_VERSION >= 0x040200
2758 prefsPS
->updateGeometry();
2761 bc().setPolicy(ButtonPolicy::PreferencesPolicy
);
2763 bc().setApply(applyPB
);
2764 bc().setCancel(closePB
);
2765 bc().setRestore(restorePB
);
2767 // initialize the strftime validator
2768 bc().addCheckedLineEdit(dateFormat
->DateED
);
2772 void GuiPreferences::addModule(PrefModule
* module
)
2774 LASSERT(module
, return);
2775 if (module
->category().isEmpty())
2776 prefsPS
->addPanel(module
, module
->title());
2778 prefsPS
->addPanel(module
, module
->title(), module
->category());
2779 connect(module
, SIGNAL(changed()), this, SLOT(change_adaptor()));
2780 modules_
.push_back(module
);
2784 void GuiPreferences::change_adaptor()
2790 void GuiPreferences::apply(LyXRC
& rc
) const
2792 size_t end
= modules_
.size();
2793 for (size_t i
= 0; i
!= end
; ++i
)
2794 modules_
[i
]->apply(rc
);
2798 void GuiPreferences::updateRc(LyXRC
const & rc
)
2800 size_t const end
= modules_
.size();
2801 for (size_t i
= 0; i
!= end
; ++i
)
2802 modules_
[i
]->update(rc
);
2806 void GuiPreferences::applyView()
2811 bool GuiPreferences::initialiseParams(string
const &)
2814 formats_
= lyx::formats
;
2815 converters_
= theConverters();
2816 converters_
.update(formats_
);
2817 movers_
= theMovers();
2819 update_screen_font_
= false;
2822 // Make sure that the bc is in the INITIAL state
2823 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE
))
2830 void GuiPreferences::dispatchParams()
2833 rc_
.write(ss
, true);
2834 dispatch(FuncRequest(LFUN_LYXRC_APPLY
, ss
.str()));
2835 // FIXME: these need lfuns
2837 theBufferList().setCurrentAuthor(from_utf8(rc_
.user_name
), from_utf8(rc_
.user_email
));
2839 lyx::formats
= formats_
;
2841 theConverters() = converters_
;
2842 theConverters().update(lyx::formats
);
2843 theConverters().buildGraph();
2845 theMovers() = movers_
;
2847 vector
<string
>::const_iterator it
= colors_
.begin();
2848 vector
<string
>::const_iterator
const end
= colors_
.end();
2849 for (; it
!= end
; ++it
)
2850 dispatch(FuncRequest(LFUN_SET_COLOR
, *it
));
2853 if (update_screen_font_
) {
2854 dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE
));
2855 update_screen_font_
= false;
2858 // The Save button has been pressed
2860 dispatch(FuncRequest(LFUN_PREFERENCES_SAVE
));
2864 void GuiPreferences::setColor(ColorCode col
, QString
const & hex
)
2866 colors_
.push_back(lcolor
.getLyXName(col
) + ' ' + fromqstr(hex
));
2870 void GuiPreferences::updateScreenFonts()
2872 update_screen_font_
= true;
2876 QString
GuiPreferences::browsebind(QString
const & file
) const
2878 return browseLibFile("bind", file
, "bind", qt_("Choose bind file"),
2879 QStringList(qt_("LyX bind files (*.bind)")));
2883 QString
GuiPreferences::browseUI(QString
const & file
) const
2885 return browseLibFile("ui", file
, "ui", qt_("Choose UI file"),
2886 QStringList(qt_("LyX UI files (*.ui)")));
2890 QString
GuiPreferences::browsekbmap(QString
const & file
) const
2892 return browseLibFile("kbd", file
, "kmap", qt_("Choose keyboard map"),
2893 QStringList(qt_("LyX keyboard maps (*.kmap)")));
2897 QString
GuiPreferences::browsedict(QString
const & file
) const
2899 return browseFile(file
, qt_("Choose personal dictionary"),
2900 QStringList(qt_("*.pws")));
2904 QString
GuiPreferences::browse(QString
const & file
,
2905 QString
const & title
) const
2907 return browseFile(file
, title
, QStringList(), true);
2911 // We support less paper sizes than the document dialog
2912 // Therefore this adjustment is needed.
2913 PAPER_SIZE
GuiPreferences::toPaperSize(int i
) const
2917 return PAPER_DEFAULT
;
2919 return PAPER_USLETTER
;
2921 return PAPER_USLEGAL
;
2923 return PAPER_USEXECUTIVE
;
2933 // should not happen
2934 return PAPER_DEFAULT
;
2939 int GuiPreferences::fromPaperSize(PAPER_SIZE papersize
) const
2941 switch (papersize
) {
2944 case PAPER_USLETTER
:
2948 case PAPER_USEXECUTIVE
:
2959 // should not happen
2965 Dialog
* createGuiPreferences(GuiView
& lv
) { return new GuiPreferences(lv
); }
2968 } // namespace frontend
2971 #include "moc_GuiPrefs.cpp"