2 * \file GuiDocument.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Richard Heck (modules)
9 * Full author contact details are available in file CREDITS.
14 #include "GuiDocument.h"
16 #include "GuiApplication.h"
17 #include "GuiBranches.h"
18 #include "GuiSelectionManager.h"
19 #include "LaTeXHighlighter.h"
20 #include "LengthCombo.h"
21 #include "PanelStack.h"
22 #include "Validator.h"
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
28 #include "BufferParams.h"
29 #include "BufferView.h"
32 #include "FloatPlacement.h"
33 #include "FuncRequest.h"
35 #include "LaTeXFeatures.h"
37 #include "LyXRC.h" // defaultUnit
38 #include "ModuleList.h"
39 #include "OutputParams.h"
40 #include "PDFOptions.h"
41 #include "qt_helpers.h"
44 #include "insets/InsetListingsParams.h"
46 #include "support/debug.h"
47 #include "support/FileName.h"
48 #include "support/filetools.h"
49 #include "support/gettext.h"
50 #include "support/lstrings.h"
52 #include "frontends/alert.h"
54 #include <QAbstractItemModel>
55 #include <QCloseEvent>
57 #include <QTextCursor>
68 using namespace lyx::support;
73 char const * const tex_graphics[] =
75 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
76 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
77 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
78 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
83 char const * const tex_graphics_gui[] =
85 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
86 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
87 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
88 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
89 "XeTeX", N_("None"), ""
93 char const * const tex_fonts_roman[] =
95 "default", "cmr", "lmodern", "ae", "times", "palatino",
96 "charter", "newcent", "bookman", "utopia", "beraserif",
97 "ccfonts", "chancery", ""
101 char const * tex_fonts_roman_gui[] =
103 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
104 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
105 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
106 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
111 char const * const tex_fonts_sans[] =
113 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
117 char const * tex_fonts_sans_gui[] =
119 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
120 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
124 char const * const tex_fonts_monospaced[] =
126 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
130 char const * tex_fonts_monospaced_gui[] =
132 N_("Default"), N_("Computer Modern Typewriter"),
133 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
134 N_("LuxiMono"), N_("CM Typewriter Light"), ""
138 char const * backref_opts[] =
140 "false", "section", "slide", "page", ""
144 char const * backref_opts_gui[] =
146 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
150 vector<pair<string, QString> > pagestyles;
153 } // anonymous namespace
158 // used when sorting the textclass list.
159 class less_textclass_avail_desc
160 : public binary_function<string, string, int>
163 bool operator()(string const & lhs, string const & rhs) const
165 // Ordering criteria:
166 // 1. Availability of text class
167 // 2. Description (lexicographic)
168 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
169 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
170 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
171 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
172 translateIfPossible(from_utf8(tc1.description()))
173 < translateIfPossible(from_utf8(tc2.description())));
182 vector<string> getRequiredList(string const & modName)
184 LyXModule const * const mod = moduleList[modName];
186 return vector<string>(); //empty such thing
187 return mod->getRequiredModules();
191 vector<string> getExcludedList(string const & modName)
193 LyXModule const * const mod = moduleList[modName];
195 return vector<string>(); //empty such thing
196 return mod->getExcludedModules();
200 docstring getModuleDescription(string const & modName)
202 LyXModule const * const mod = moduleList[modName];
204 return _("Module not found!");
206 return translateIfPossible(from_utf8(mod->getDescription()));
210 vector<string> getPackageList(string const & modName)
212 LyXModule const * const mod = moduleList[modName];
214 return vector<string>(); //empty such thing
215 return mod->getPackageList();
219 bool isModuleAvailable(string const & modName)
221 LyXModule * mod = moduleList[modName];
224 return mod->isAvailable();
227 } // anonymous namespace
230 /////////////////////////////////////////////////////////////////////
232 // ModuleSelectionManager
234 /////////////////////////////////////////////////////////////////////
236 /// SelectionManager for use with modules
237 class ModuleSelectionManager : public GuiSelectionManager
241 ModuleSelectionManager(
242 QListView * availableLV,
243 QListView * selectedLV,
247 QPushButton * downPB,
248 GuiIdListModel * availableModel,
249 GuiIdListModel * selectedModel,
250 GuiDocument const * container)
251 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
252 upPB, downPB, availableModel, selectedModel), container_(container)
255 void updateProvidedModules(std::list<std::string> const & pm)
256 { provided_modules_ = pm; }
258 void updateExcludedModules(std::list<std::string> const & em)
259 { excluded_modules_ = em; }
262 virtual void updateAddPB();
264 virtual void updateUpPB();
266 virtual void updateDownPB();
268 virtual void updateDelPB();
269 /// returns availableModel as a GuiIdListModel
270 GuiIdListModel * getAvailableModel()
272 return dynamic_cast<GuiIdListModel *>(availableModel);
274 /// returns selectedModel as a GuiIdListModel
275 GuiIdListModel * getSelectedModel()
277 return dynamic_cast<GuiIdListModel *>(selectedModel);
279 /// keeps a list of the modules the text class provides
280 std::list<std::string> provided_modules_;
282 std::list<std::string> excluded_modules_;
284 GuiDocument const * container_;
287 void ModuleSelectionManager::updateAddPB()
289 int const arows = availableModel->rowCount();
290 QModelIndexList const avail_sels =
291 availableLV->selectionModel()->selectedIndexes();
293 // disable if there aren't any modules (?), if none of them is chosen
294 // in the dialog, or if the chosen one is already selected for use.
295 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
296 addPB->setEnabled(false);
300 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
301 string const modname = getAvailableModel()->getIDString(idx.row());
304 container_->params().moduleCanBeAdded(modname);
305 addPB->setEnabled(enable);
309 void ModuleSelectionManager::updateDownPB()
311 int const srows = selectedModel->rowCount();
313 downPB->setEnabled(false);
316 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
317 int const curRow = curidx.row();
318 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
319 downPB->setEnabled(false);
323 // determine whether immediately succeding element requires this one
324 string const curmodname = getSelectedModel()->getIDString(curRow);
325 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
327 vector<string> reqs = getRequiredList(nextmodname);
329 // if it doesn't require anything....
331 downPB->setEnabled(true);
335 // Enable it if this module isn't required.
336 // FIXME This should perhaps be more flexible and check whether, even
337 // if the next one is required, there is also an earlier one that will do.
339 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
342 void ModuleSelectionManager::updateUpPB()
344 int const srows = selectedModel->rowCount();
346 upPB->setEnabled(false);
350 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
351 int curRow = curIdx.row();
352 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
353 upPB->setEnabled(false);
356 string const curmodname = getSelectedModel()->getIDString(curRow);
358 // determine whether immediately preceding element is required by this one
359 vector<string> reqs = getRequiredList(curmodname);
361 // if this one doesn't require anything....
363 upPB->setEnabled(true);
368 // Enable it if the preceding module isn't required.
369 // NOTE This is less flexible than it might be. We could check whether, even
370 // if the previous one is required, there is an earlier one that would do.
371 string const premod = getSelectedModel()->getIDString(curRow - 1);
372 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
375 void ModuleSelectionManager::updateDelPB()
377 int const srows = selectedModel->rowCount();
379 deletePB->setEnabled(false);
383 QModelIndex const & curidx =
384 selectedLV->selectionModel()->currentIndex();
385 int const curRow = curidx.row();
386 if (curRow < 0 || curRow >= srows) { // invalid index?
387 deletePB->setEnabled(false);
391 string const curmodname = getSelectedModel()->getIDString(curRow);
393 // We're looking here for a reason NOT to enable the button. If we
394 // find one, we disable it and return. If we don't, we'll end up at
395 // the end of the function, and then we enable it.
396 for (int i = curRow + 1; i < srows; ++i) {
397 string const thisMod = getSelectedModel()->getIDString(i);
398 vector<string> reqs = getRequiredList(thisMod);
399 //does this one require us?
400 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
404 // OK, so this module requires us
405 // is there an EARLIER module that also satisfies the require?
406 // NOTE We demand that it be earlier to keep the list of modules
407 // consistent with the rule that a module must be proceeded by a
408 // required module. There would be more flexible ways to proceed,
409 // but that would be a lot more complicated, and the logic here is
410 // already complicated. (That's why I've left the debugging code.)
411 // lyxerr << "Testing " << thisMod << std::endl;
412 bool foundone = false;
413 for (int j = 0; j < curRow; ++j) {
414 string const mod = getSelectedModel()->getIDString(j);
415 // lyxerr << "In loop: Testing " << mod << std::endl;
416 // do we satisfy the require?
417 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
418 // lyxerr << mod << " does the trick." << std::endl;
423 // did we find a module to satisfy the require?
425 // lyxerr << "No matching module found." << std::endl;
426 deletePB->setEnabled(false);
430 // lyxerr << "All's well that ends well." << std::endl;
431 deletePB->setEnabled(true);
435 /////////////////////////////////////////////////////////////////////
439 /////////////////////////////////////////////////////////////////////
441 PreambleModule::PreambleModule() : current_id_(0)
443 // This is not a memory leak. The object will be destroyed
445 (void) new LaTeXHighlighter(preambleTE->document());
446 setFocusProxy(preambleTE);
447 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
451 void PreambleModule::update(BufferParams const & params, BufferId id)
453 QString preamble = toqstr(params.preamble);
454 // Nothing to do if the params and preamble are unchanged.
455 if (id == current_id_
456 && preamble == preambleTE->document()->toPlainText())
459 QTextCursor cur = preambleTE->textCursor();
460 // Save the coords before switching to the new one.
461 preamble_coords_[current_id_] =
462 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
464 // Save the params address for further use.
466 preambleTE->document()->setPlainText(preamble);
467 Coords::const_iterator it = preamble_coords_.find(current_id_);
468 if (it == preamble_coords_.end())
469 // First time we open this one.
470 preamble_coords_[current_id_] = make_pair(0, 0);
472 // Restore saved coords.
473 QTextCursor cur = preambleTE->textCursor();
474 cur.setPosition(it->second.first);
475 preambleTE->setTextCursor(cur);
476 preambleTE->verticalScrollBar()->setValue(it->second.second);
481 void PreambleModule::apply(BufferParams & params)
483 params.preamble = fromqstr(preambleTE->document()->toPlainText());
487 void PreambleModule::closeEvent(QCloseEvent * e)
489 // Save the coords before closing.
490 QTextCursor cur = preambleTE->textCursor();
491 preamble_coords_[current_id_] =
492 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
497 /////////////////////////////////////////////////////////////////////
501 /////////////////////////////////////////////////////////////////////
504 GuiDocument::GuiDocument(GuiView & lv)
505 : GuiDialog(lv, "document", qt_("Document Settings"))
509 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
510 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
511 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
512 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
514 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
515 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
517 // Manage the restore, ok, apply, restore and cancel/close buttons
518 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
520 bc().setApply(applyPB);
521 bc().setCancel(closePB);
522 bc().setRestore(restorePB);
524 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
526 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
527 this, SLOT(change_adaptor()));
528 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
529 this, SLOT(setLSpacing(int)));
530 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
531 this, SLOT(change_adaptor()));
532 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
533 this, SLOT(change_adaptor()));
534 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
535 this, SLOT(change_adaptor()));
536 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
537 this, SLOT(change_adaptor()));
538 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
539 this, SLOT(change_adaptor()));
540 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
541 this, SLOT(change_adaptor()));
542 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
543 this, SLOT(setSkip(int)));
544 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
545 this, SLOT(enableSkip(bool)));
546 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
547 this, SLOT(change_adaptor()));
548 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
549 this, SLOT(setColSep()));
550 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
551 this, SLOT(change_adaptor()));
552 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
553 this, SLOT(change_adaptor()));
554 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
555 this, SLOT(setListingsMessage()));
556 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
557 this, SLOT(setListingsMessage()));
558 textLayoutModule->listingsTB->setPlainText(
559 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
560 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
561 textLayoutModule->lspacingLE));
562 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
563 textLayoutModule->skipLE));
565 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
566 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
567 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
568 textLayoutModule->skipCO->addItem(qt_("Length"));
569 // remove the %-items from the unit choice
570 textLayoutModule->skipLengthCO->noPercents();
571 textLayoutModule->lspacingCO->insertItem(
572 Spacing::Single, qt_("Single"));
573 textLayoutModule->lspacingCO->insertItem(
574 Spacing::Onehalf, qt_("OneHalf"));
575 textLayoutModule->lspacingCO->insertItem(
576 Spacing::Double, qt_("Double"));
577 textLayoutModule->lspacingCO->insertItem(
578 Spacing::Other, qt_("Custom"));
580 // initialize the length validator
581 bc().addCheckedLineEdit(textLayoutModule->skipLE);
583 fontModule = new UiWidget<Ui::FontUi>;
585 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
586 this, SLOT(change_adaptor()));
587 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
588 this, SLOT(romanChanged(int)));
589 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
590 this, SLOT(change_adaptor()));
591 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
592 this, SLOT(sansChanged(int)));
593 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
594 this, SLOT(change_adaptor()));
595 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
596 this, SLOT(ttChanged(int)));
597 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
598 this, SLOT(change_adaptor()));
599 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
600 this, SLOT(change_adaptor()));
601 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
602 this, SLOT(change_adaptor()));
603 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
604 this, SLOT(change_adaptor()));
605 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
606 this, SLOT(change_adaptor()));
607 connect(fontModule->fontScCB, SIGNAL(clicked()),
608 this, SLOT(change_adaptor()));
609 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
610 this, SLOT(change_adaptor()));
612 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
613 QString font = qt_(tex_fonts_roman_gui[n]);
614 if (!isFontAvailable(tex_fonts_roman[n]))
615 font += qt_(" (not installed)");
616 fontModule->fontsRomanCO->addItem(font);
618 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
619 QString font = qt_(tex_fonts_sans_gui[n]);
620 if (!isFontAvailable(tex_fonts_sans[n]))
621 font += qt_(" (not installed)");
622 fontModule->fontsSansCO->addItem(font);
624 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
625 QString font = qt_(tex_fonts_monospaced_gui[n]);
626 if (!isFontAvailable(tex_fonts_monospaced[n]))
627 font += qt_(" (not installed)");
628 fontModule->fontsTypewriterCO->addItem(font);
631 fontModule->fontsizeCO->addItem(qt_("Default"));
632 fontModule->fontsizeCO->addItem(qt_("10"));
633 fontModule->fontsizeCO->addItem(qt_("11"));
634 fontModule->fontsizeCO->addItem(qt_("12"));
636 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
637 fontModule->fontsDefaultCO->addItem(
638 qt_(GuiDocument::fontfamilies_gui[n]));
641 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
643 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
644 this, SLOT(setCustomPapersize(int)));
645 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
646 this, SLOT(setCustomPapersize(int)));
647 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
648 this, SLOT(portraitChanged()));
649 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
650 this, SLOT(change_adaptor()));
651 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
652 this, SLOT(change_adaptor()));
653 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
654 this, SLOT(change_adaptor()));
655 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
656 this, SLOT(change_adaptor()));
657 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
658 this, SLOT(change_adaptor()));
659 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
660 this, SLOT(change_adaptor()));
661 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
662 this, SLOT(change_adaptor()));
663 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
664 this, SLOT(change_adaptor()));
665 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
666 this, SLOT(change_adaptor()));
668 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
669 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
670 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
671 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
672 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
673 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
674 pageLayoutModule->paperheightL);
675 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
676 pageLayoutModule->paperwidthL);
679 QComboBox * cb = pageLayoutModule->papersizeCO;
680 cb->addItem(qt_("Default"));
681 cb->addItem(qt_("Custom"));
682 cb->addItem(qt_("US letter"));
683 cb->addItem(qt_("US legal"));
684 cb->addItem(qt_("US executive"));
685 cb->addItem(qt_("A3"));
686 cb->addItem(qt_("A4"));
687 cb->addItem(qt_("A5"));
688 cb->addItem(qt_("B3"));
689 cb->addItem(qt_("B4"));
690 cb->addItem(qt_("B5"));
691 // remove the %-items from the unit choice
692 pageLayoutModule->paperwidthUnitCO->noPercents();
693 pageLayoutModule->paperheightUnitCO->noPercents();
694 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
695 pageLayoutModule->paperheightLE));
696 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
697 pageLayoutModule->paperwidthLE));
700 marginsModule = new UiWidget<Ui::MarginsUi>;
702 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
703 this, SLOT(setCustomMargins(bool)));
704 connect(marginsModule->marginCB, SIGNAL(clicked()),
705 this, SLOT(change_adaptor()));
706 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
707 this, SLOT(change_adaptor()));
708 connect(marginsModule->topUnit, SIGNAL(activated(int)),
709 this, SLOT(change_adaptor()));
710 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
711 this, SLOT(change_adaptor()));
712 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
713 this, SLOT(change_adaptor()));
714 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
715 this, SLOT(change_adaptor()));
716 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
717 this, SLOT(change_adaptor()));
718 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
719 this, SLOT(change_adaptor()));
720 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
721 this, SLOT(change_adaptor()));
722 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
723 this, SLOT(change_adaptor()));
724 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
725 this, SLOT(change_adaptor()));
726 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
727 this, SLOT(change_adaptor()));
728 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
729 this, SLOT(change_adaptor()));
730 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
731 this, SLOT(change_adaptor()));
732 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
733 this, SLOT(change_adaptor()));
734 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
735 this, SLOT(change_adaptor()));
736 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
737 this, SLOT(change_adaptor()));
738 marginsModule->topLE->setValidator(unsignedLengthValidator(
739 marginsModule->topLE));
740 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
741 marginsModule->bottomLE));
742 marginsModule->innerLE->setValidator(unsignedLengthValidator(
743 marginsModule->innerLE));
744 marginsModule->outerLE->setValidator(unsignedLengthValidator(
745 marginsModule->outerLE));
746 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
747 marginsModule->headsepLE));
748 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
749 marginsModule->headheightLE));
750 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
751 marginsModule->footskipLE));
752 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
753 marginsModule->columnsepLE));
755 bc().addCheckedLineEdit(marginsModule->topLE,
756 marginsModule->topL);
757 bc().addCheckedLineEdit(marginsModule->bottomLE,
758 marginsModule->bottomL);
759 bc().addCheckedLineEdit(marginsModule->innerLE,
760 marginsModule->innerL);
761 bc().addCheckedLineEdit(marginsModule->outerLE,
762 marginsModule->outerL);
763 bc().addCheckedLineEdit(marginsModule->headsepLE,
764 marginsModule->headsepL);
765 bc().addCheckedLineEdit(marginsModule->headheightLE,
766 marginsModule->headheightL);
767 bc().addCheckedLineEdit(marginsModule->footskipLE,
768 marginsModule->footskipL);
769 bc().addCheckedLineEdit(marginsModule->columnsepLE,
770 marginsModule->columnsepL);
773 langModule = new UiWidget<Ui::LanguageUi>;
775 connect(langModule->languageCO, SIGNAL(activated(int)),
776 this, SLOT(change_adaptor()));
777 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
778 this, SLOT(change_adaptor()));
779 connect(langModule->otherencodingRB, SIGNAL(clicked()),
780 this, SLOT(change_adaptor()));
781 connect(langModule->encodingCO, SIGNAL(activated(int)),
782 this, SLOT(change_adaptor()));
783 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
784 this, SLOT(change_adaptor()));
786 QAbstractItemModel * language_model = guiApp->languageModel();
787 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
788 language_model->sort(0);
789 langModule->languageCO->setModel(language_model);
791 // Always put the default encoding in the first position.
792 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
793 QStringList encodinglist;
794 Encodings::const_iterator it = encodings.begin();
795 Encodings::const_iterator const end = encodings.end();
796 for (; it != end; ++it)
797 encodinglist.append(qt_(it->guiName()));
799 langModule->encodingCO->addItems(encodinglist);
801 langModule->quoteStyleCO->addItem(qt_("``text''"));
802 langModule->quoteStyleCO->addItem(qt_("''text''"));
803 langModule->quoteStyleCO->addItem(qt_(",,text``"));
804 langModule->quoteStyleCO->addItem(qt_(",,text''"));
805 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
806 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
809 numberingModule = new UiWidget<Ui::NumberingUi>;
811 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
812 this, SLOT(change_adaptor()));
813 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
814 this, SLOT(change_adaptor()));
815 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
816 this, SLOT(updateNumbering()));
817 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
818 this, SLOT(updateNumbering()));
819 numberingModule->tocTW->setColumnCount(3);
820 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
821 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
822 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
825 biblioModule = new UiWidget<Ui::BiblioUi>;
826 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
827 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
828 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
829 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
831 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
832 this, SLOT(change_adaptor()));
833 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
834 this, SLOT(change_adaptor()));
835 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
836 this, SLOT(change_adaptor()));
837 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
838 this, SLOT(change_adaptor()));
839 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
840 this, SLOT(change_adaptor()));
842 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
843 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
844 biblioModule->citeStyleCO->setCurrentIndex(0);
847 mathsModule = new UiWidget<Ui::MathsUi>;
848 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
849 mathsModule->amsCB, SLOT(setDisabled(bool)));
850 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
851 mathsModule->esintCB, SLOT(setDisabled(bool)));
853 connect(mathsModule->amsCB, SIGNAL(clicked()),
854 this, SLOT(change_adaptor()));
855 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
856 this, SLOT(change_adaptor()));
857 connect(mathsModule->esintCB, SIGNAL(clicked()),
858 this, SLOT(change_adaptor()));
859 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
860 this, SLOT(change_adaptor()));
862 latexModule = new UiWidget<Ui::LaTeXUi>;
864 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
865 this, SLOT(change_adaptor()));
866 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
867 this, SLOT(change_adaptor()));
868 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
869 this, SLOT(change_adaptor()));
870 connect(latexModule->classCO, SIGNAL(activated(int)),
871 this, SLOT(classChanged()));
872 connect(latexModule->classCO, SIGNAL(activated(int)),
873 this, SLOT(change_adaptor()));
874 connect(latexModule->layoutPB, SIGNAL(clicked()),
875 this, SLOT(browseLayout()));
876 connect(latexModule->layoutPB, SIGNAL(clicked()),
877 this, SLOT(change_adaptor()));
878 connect(latexModule->childDocGB, SIGNAL(clicked()),
879 this, SLOT(change_adaptor()));
880 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
881 this, SLOT(change_adaptor()));
882 connect(latexModule->childDocPB, SIGNAL(clicked()),
883 this, SLOT(browseMaster()));
885 // postscript drivers
886 for (int n = 0; tex_graphics[n][0]; ++n) {
887 QString enc = qt_(tex_graphics_gui[n]);
888 latexModule->psdriverCO->addItem(enc);
891 latexModule->classCO->setModel(&classes_model_);
892 LayoutFileList const & bcl = LayoutFileList::get();
893 vector<LayoutFileIndex> classList = bcl.classList();
894 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
896 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
897 vector<LayoutFileIndex>::const_iterator cen = classList.end();
898 for (int i = 0; cit != cen; ++cit, ++i) {
899 LayoutFile const & tc = bcl[*cit];
900 docstring item = (tc.isTeXClassAvailable()) ?
901 from_utf8(tc.description()) :
902 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
903 classes_model_.insertRow(i, toqstr(item), *cit);
907 branchesModule = new GuiBranches;
908 connect(branchesModule, SIGNAL(changed()),
909 this, SLOT(change_adaptor()));
912 preambleModule = new PreambleModule;
913 connect(preambleModule, SIGNAL(changed()),
914 this, SLOT(change_adaptor()));
917 bulletsModule = new BulletsModule;
918 connect(bulletsModule, SIGNAL(changed()),
919 this, SLOT(change_adaptor()));
922 modulesModule = new UiWidget<Ui::ModulesUi>;
925 new ModuleSelectionManager(modulesModule->availableLV,
926 modulesModule->selectedLV,
927 modulesModule->addPB, modulesModule->deletePB,
928 modulesModule->upPB, modulesModule->downPB,
929 availableModel(), selectedModel(), this);
930 connect(selectionManager, SIGNAL(updateHook()),
931 this, SLOT(updateModuleInfo()));
932 connect(selectionManager, SIGNAL(updateHook()),
933 this, SLOT(change_adaptor()));
934 connect(selectionManager, SIGNAL(selectionChanged()),
935 this, SLOT(modulesChanged()));
938 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
940 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
941 this, SLOT(change_adaptor()));
942 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
943 this, SLOT(change_adaptor()));
944 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
945 this, SLOT(change_adaptor()));
946 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
947 this, SLOT(change_adaptor()));
948 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
949 this, SLOT(change_adaptor()));
950 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
951 this, SLOT(change_adaptor()));
952 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
953 this, SLOT(change_adaptor()));
954 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
955 this, SLOT(change_adaptor()));
956 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
957 this, SLOT(change_adaptor()));
958 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
959 this, SLOT(change_adaptor()));
960 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
961 this, SLOT(change_adaptor()));
962 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
963 this, SLOT(change_adaptor()));
964 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
965 this, SLOT(change_adaptor()));
966 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
967 this, SLOT(change_adaptor()));
968 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
969 this, SLOT(change_adaptor()));
970 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
971 this, SLOT(change_adaptor()));
973 for (int i = 0; backref_opts[i][0]; ++i)
974 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
977 floatModule = new FloatPlacement;
978 connect(floatModule, SIGNAL(changed()),
979 this, SLOT(change_adaptor()));
981 docPS->addPanel(latexModule, qt_("Document Class"));
982 docPS->addPanel(modulesModule, qt_("Modules"));
983 docPS->addPanel(fontModule, qt_("Fonts"));
984 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
985 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
986 docPS->addPanel(marginsModule, qt_("Page Margins"));
987 docPS->addPanel(langModule, qt_("Language"));
988 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
989 docPS->addPanel(biblioModule, qt_("Bibliography"));
990 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
991 docPS->addPanel(mathsModule, qt_("Math Options"));
992 docPS->addPanel(floatModule, qt_("Float Placement"));
993 docPS->addPanel(bulletsModule, qt_("Bullets"));
994 docPS->addPanel(branchesModule, qt_("Branches"));
995 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
996 docPS->setCurrentPanel(qt_("Document Class"));
997 // FIXME: hack to work around resizing bug in Qt >= 4.2
998 // bug verified with Qt 4.2.{0-3} (JSpitzm)
999 #if QT_VERSION >= 0x040200
1000 docPS->updateGeometry();
1005 void GuiDocument::showPreamble()
1007 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1011 void GuiDocument::saveDefaultClicked()
1017 void GuiDocument::useDefaultsClicked()
1023 void GuiDocument::change_adaptor()
1029 QString GuiDocument::validateListingsParameters()
1031 // use a cache here to avoid repeated validation
1032 // of the same parameters
1033 static string param_cache;
1034 static QString msg_cache;
1036 if (textLayoutModule->bypassCB->isChecked())
1039 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1040 if (params != param_cache) {
1041 param_cache = params;
1042 msg_cache = toqstr(InsetListingsParams(params).validate());
1048 void GuiDocument::setListingsMessage()
1050 static bool isOK = true;
1051 QString msg = validateListingsParameters();
1052 if (msg.isEmpty()) {
1056 // listingsTB->setTextColor("black");
1057 textLayoutModule->listingsTB->setPlainText(
1058 qt_("Input listings parameters on the right. "
1059 "Enter ? for a list of parameters."));
1062 // listingsTB->setTextColor("red");
1063 textLayoutModule->listingsTB->setPlainText(msg);
1068 void GuiDocument::setLSpacing(int item)
1070 textLayoutModule->lspacingLE->setEnabled(item == 3);
1074 void GuiDocument::setSkip(int item)
1076 bool const enable = (item == 3);
1077 textLayoutModule->skipLE->setEnabled(enable);
1078 textLayoutModule->skipLengthCO->setEnabled(enable);
1082 void GuiDocument::enableSkip(bool skip)
1084 textLayoutModule->skipCO->setEnabled(skip);
1085 textLayoutModule->skipLE->setEnabled(skip);
1086 textLayoutModule->skipLengthCO->setEnabled(skip);
1088 setSkip(textLayoutModule->skipCO->currentIndex());
1091 void GuiDocument::portraitChanged()
1093 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1096 void GuiDocument::setMargins(bool custom)
1098 marginsModule->marginCB->setChecked(custom);
1099 setCustomMargins(custom);
1103 void GuiDocument::setCustomPapersize(int papersize)
1105 bool const custom = (papersize == 1);
1107 pageLayoutModule->paperwidthL->setEnabled(custom);
1108 pageLayoutModule->paperwidthLE->setEnabled(custom);
1109 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1110 pageLayoutModule->paperheightL->setEnabled(custom);
1111 pageLayoutModule->paperheightLE->setEnabled(custom);
1112 pageLayoutModule->paperheightLE->setFocus();
1113 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1117 void GuiDocument::setColSep()
1119 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1123 void GuiDocument::setCustomMargins(bool custom)
1125 marginsModule->topL->setEnabled(!custom);
1126 marginsModule->topLE->setEnabled(!custom);
1127 marginsModule->topUnit->setEnabled(!custom);
1129 marginsModule->bottomL->setEnabled(!custom);
1130 marginsModule->bottomLE->setEnabled(!custom);
1131 marginsModule->bottomUnit->setEnabled(!custom);
1133 marginsModule->innerL->setEnabled(!custom);
1134 marginsModule->innerLE->setEnabled(!custom);
1135 marginsModule->innerUnit->setEnabled(!custom);
1137 marginsModule->outerL->setEnabled(!custom);
1138 marginsModule->outerLE->setEnabled(!custom);
1139 marginsModule->outerUnit->setEnabled(!custom);
1141 marginsModule->headheightL->setEnabled(!custom);
1142 marginsModule->headheightLE->setEnabled(!custom);
1143 marginsModule->headheightUnit->setEnabled(!custom);
1145 marginsModule->headsepL->setEnabled(!custom);
1146 marginsModule->headsepLE->setEnabled(!custom);
1147 marginsModule->headsepUnit->setEnabled(!custom);
1149 marginsModule->footskipL->setEnabled(!custom);
1150 marginsModule->footskipLE->setEnabled(!custom);
1151 marginsModule->footskipUnit->setEnabled(!custom);
1153 bool const enableColSep = !custom &&
1154 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1155 marginsModule->columnsepL->setEnabled(enableColSep);
1156 marginsModule->columnsepLE->setEnabled(enableColSep);
1157 marginsModule->columnsepUnit->setEnabled(enableColSep);
1161 void GuiDocument::updateFontsize(string const & items, string const & sel)
1163 fontModule->fontsizeCO->clear();
1164 fontModule->fontsizeCO->addItem(qt_("Default"));
1166 for (int n = 0; !token(items,'|',n).empty(); ++n)
1167 fontModule->fontsizeCO->
1168 addItem(toqstr(token(items,'|',n)));
1170 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1171 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1172 fontModule->fontsizeCO->setCurrentIndex(n);
1179 void GuiDocument::romanChanged(int item)
1181 string const font = tex_fonts_roman[item];
1182 fontModule->fontScCB->setEnabled(providesSC(font));
1183 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1187 void GuiDocument::sansChanged(int item)
1189 string const font = tex_fonts_sans[item];
1190 bool scaleable = providesScale(font);
1191 fontModule->scaleSansSB->setEnabled(scaleable);
1192 fontModule->scaleSansLA->setEnabled(scaleable);
1196 void GuiDocument::ttChanged(int item)
1198 string const font = tex_fonts_monospaced[item];
1199 bool scaleable = providesScale(font);
1200 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1201 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1205 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1208 pageLayoutModule->pagestyleCO->clear();
1209 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1211 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1212 string style = token(items, '|', n);
1213 QString style_gui = qt_(style);
1214 pagestyles.push_back(pair<string, QString>(style, style_gui));
1215 pageLayoutModule->pagestyleCO->addItem(style_gui);
1218 if (sel == "default") {
1219 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1225 for (size_t i = 0; i < pagestyles.size(); ++i)
1226 if (pagestyles[i].first == sel)
1227 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1230 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1234 void GuiDocument::browseLayout()
1236 QString const label1 = qt_("Layouts|#o#O");
1237 QString const dir1 = toqstr(lyxrc.document_path);
1238 QStringList const filter(qt_("LyX Layout (*.layout)"));
1239 QString file = browseRelFile(QString(), bufferFilepath(),
1240 qt_("Local layout file"), filter, false,
1243 if (!file.endsWith(".layout"))
1246 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1247 fromqstr(bufferFilepath()));
1249 int const ret = Alert::prompt(_("Local layout file"),
1250 _("The layout file you have selected is a local layout\n"
1251 "file, not one in the system or user directory. Your\n"
1252 "document may not work with this layout if you do not\n"
1253 "keep the layout file in the document directory."),
1254 1, 1, _("&Set Layout"), _("&Cancel"));
1258 // load the layout file
1259 LayoutFileList & bcl = LayoutFileList::get();
1260 string classname = layoutFile.onlyFileName();
1261 // this will update an existing layout if that layout has been loaded before.
1262 LayoutFileIndex name = bcl.addLocalLayout(
1263 classname.substr(0, classname.size() - 7),
1264 layoutFile.onlyPath().absFilename());
1267 Alert::error(_("Error"),
1268 _("Unable to read local layout file."));
1272 // do not trigger classChanged if there is no change.
1273 if (latexModule->classCO->currentText() == toqstr(name))
1277 int idx = latexModule->classCO->findText(toqstr(name));
1279 classes_model_.insertRow(0, toqstr(name), name);
1280 latexModule->classCO->setCurrentIndex(0);
1282 latexModule->classCO->setCurrentIndex(idx);
1288 void GuiDocument::browseMaster()
1290 QString const title = qt_("Select master document");
1291 QString const dir1 = toqstr(lyxrc.document_path);
1292 QString const old = latexModule->childDocLE->text();
1293 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1294 QStringList const filter(qt_("LyX Files (*.lyx)"));
1295 QString file = browseRelFile(old, docpath, title, filter, false,
1296 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1298 latexModule->childDocLE->setText(file);
1302 void GuiDocument::classChanged()
1304 int idx = latexModule->classCO->currentIndex();
1307 string const classname = classes_model_.getIDString(idx);
1309 // check whether the selected modules have changed.
1310 bool modules_changed = false;
1311 unsigned int const srows = selectedModel()->rowCount();
1312 if (srows != bp_.getModules().size())
1313 modules_changed = true;
1315 list<string>::const_iterator mit = bp_.getModules().begin();
1316 list<string>::const_iterator men = bp_.getModules().end();
1317 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1318 if (selectedModel()->getIDString(i) != *mit) {
1319 modules_changed = true;
1324 if (modules_changed || lyxrc.auto_reset_options) {
1325 if (applyPB->isEnabled()) {
1326 int const ret = Alert::prompt(_("Unapplied changes"),
1327 _("Some changes in the dialog were not yet applied.\n"
1328 "If you do not apply now, they will be lost after this action."),
1329 1, 1, _("&Apply"), _("&Dismiss"));
1335 // We load the TextClass as soon as it is selected. This is
1336 // necessary so that other options in the dialog can be updated
1337 // according to the new class. Note, however, that, if you use
1338 // the scroll wheel when sitting on the combo box, we'll load a
1339 // lot of TextClass objects very quickly....
1340 if (!bp_.setBaseClass(classname)) {
1341 Alert::error(_("Error"), _("Unable to set document class."));
1344 if (lyxrc.auto_reset_options)
1345 bp_.useClassDefaults();
1347 // With the introduction of modules came a distinction between the base
1348 // class and the document class. The former corresponds to the main layout
1349 // file; the latter is that plus the modules (or the document-specific layout,
1350 // or whatever else there could be). Our parameters come from the document
1351 // class. So when we set the base class, we also need to recreate the document
1352 // class. Otherwise, we still have the old one.
1353 bp_.makeDocumentClass();
1359 // This is an insanely complicated attempt to make this sort of thing
1360 // work with RTL languages.
1361 docstring formatStrVec(vector<string> const & v, docstring const & s)
1363 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1367 return from_utf8(v[0]);
1368 if (v.size() == 2) {
1369 docstring retval = _("%1$s and %2$s");
1370 retval = subst(retval, _("and"), s);
1371 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1373 // The idea here is to format all but the last two items...
1374 int const vSize = v.size();
1375 docstring t2 = _("%1$s, %2$s");
1376 docstring retval = from_utf8(v[0]);
1377 for (int i = 1; i < vSize - 2; ++i)
1378 retval = bformat(t2, retval, from_utf8(v[i]));
1379 //...and then to plug them, and the last two, into this schema
1380 docstring t = _("%1$s, %2$s, and %3$s");
1381 t = subst(t, _("and"), s);
1382 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1385 vector<string> idsToNames(vector<string> const & idList)
1387 vector<string> retval;
1388 vector<string>::const_iterator it = idList.begin();
1389 vector<string>::const_iterator end = idList.end();
1390 for (; it != end; ++it) {
1391 LyXModule const * const mod = moduleList[*it];
1393 retval.push_back(*it + " (Unavailable)");
1395 retval.push_back(mod->getName());
1402 void GuiDocument::modulesToParams(BufferParams & bp)
1404 // update list of loaded modules
1405 bp.clearLayoutModules();
1406 int const srows = modules_sel_model_.rowCount();
1407 for (int i = 0; i < srows; ++i)
1408 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1410 // update the list of removed modules
1411 bp.clearRemovedModules();
1412 list<string> const & reqmods = bp.baseClass()->defaultModules();
1413 list<string>::const_iterator rit = reqmods.begin();
1414 list<string>::const_iterator ren = reqmods.end();
1416 // check each of the default modules
1417 for (; rit != ren; rit++) {
1418 list<string>::const_iterator mit = bp.getModules().begin();
1419 list<string>::const_iterator men = bp.getModules().end();
1421 for (; mit != men; mit++) {
1428 // the module isn't present so must have been removed by the user
1429 bp.addRemovedModule(*rit);
1434 void GuiDocument::modulesChanged()
1436 modulesToParams(bp_);
1437 bp_.makeDocumentClass();
1442 void GuiDocument::updateModuleInfo()
1444 selectionManager->update();
1446 //Module description
1447 bool const focus_on_selected = selectionManager->selectedFocused();
1448 QListView const * const lv =
1449 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1450 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1451 modulesModule->infoML->document()->clear();
1454 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1455 GuiIdListModel const & id_model =
1456 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1457 string const modName = id_model.getIDString(idx.row());
1458 docstring desc = getModuleDescription(modName);
1460 list<string> const & provmods = bp_.baseClass()->providedModules();
1461 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1464 desc += _("Module provided by document class.");
1467 vector<string> pkglist = getPackageList(modName);
1468 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1469 if (!pkgdesc.empty()) {
1472 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1475 pkglist = getRequiredList(modName);
1476 if (!pkglist.empty()) {
1477 vector<string> const reqdescs = idsToNames(pkglist);
1478 pkgdesc = formatStrVec(reqdescs, _("or"));
1481 desc += bformat(_("Module required: %1$s."), pkgdesc);
1484 pkglist = getExcludedList(modName);
1485 if (!pkglist.empty()) {
1486 vector<string> const reqdescs = idsToNames(pkglist);
1487 pkgdesc = formatStrVec(reqdescs, _( "and"));
1490 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1493 if (!isModuleAvailable(modName)) {
1496 desc += _("WARNING: Some required packages are unavailable!");
1499 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1503 void GuiDocument::updateNumbering()
1505 DocumentClass const & tclass = documentClass();
1507 numberingModule->tocTW->setUpdatesEnabled(false);
1508 numberingModule->tocTW->clear();
1510 int const depth = numberingModule->depthSL->value();
1511 int const toc = numberingModule->tocSL->value();
1512 QString const no = qt_("No");
1513 QString const yes = qt_("Yes");
1514 QTreeWidgetItem * item = 0;
1516 DocumentClass::const_iterator lit = tclass.begin();
1517 DocumentClass::const_iterator len = tclass.end();
1518 for (; lit != len; ++lit) {
1519 int const toclevel = lit->toclevel;
1520 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1521 item = new QTreeWidgetItem(numberingModule->tocTW);
1522 item->setText(0, toqstr(translateIfPossible(lit->name())));
1523 item->setText(1, (toclevel <= depth) ? yes : no);
1524 item->setText(2, (toclevel <= toc) ? yes : no);
1528 numberingModule->tocTW->setUpdatesEnabled(true);
1529 numberingModule->tocTW->update();
1533 void GuiDocument::applyView()
1536 preambleModule->apply(bp_);
1539 bp_.setCiteEngine(ENGINE_BASIC);
1541 if (biblioModule->citeNatbibRB->isChecked()) {
1542 bool const use_numerical_citations =
1543 biblioModule->citeStyleCO->currentIndex();
1544 if (use_numerical_citations)
1545 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1547 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1549 } else if (biblioModule->citeJurabibRB->isChecked())
1550 bp_.setCiteEngine(ENGINE_JURABIB);
1553 biblioModule->bibtopicCB->isChecked();
1555 // language & quotes
1556 if (langModule->defaultencodingRB->isChecked()) {
1557 bp_.inputenc = "auto";
1559 int i = langModule->encodingCO->currentIndex();
1561 bp_.inputenc = "default";
1563 QString const enc_gui =
1564 langModule->encodingCO->currentText();
1565 Encodings::const_iterator it = encodings.begin();
1566 Encodings::const_iterator const end = encodings.end();
1568 for (; it != end; ++it) {
1569 if (qt_(it->guiName()) == enc_gui) {
1570 bp_.inputenc = it->latexName();
1576 // should not happen
1577 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1578 bp_.inputenc = "default";
1583 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1584 switch (langModule->quoteStyleCO->currentIndex()) {
1586 lga = InsetQuotes::EnglishQuotes;
1589 lga = InsetQuotes::SwedishQuotes;
1592 lga = InsetQuotes::GermanQuotes;
1595 lga = InsetQuotes::PolishQuotes;
1598 lga = InsetQuotes::FrenchQuotes;
1601 lga = InsetQuotes::DanishQuotes;
1604 bp_.quotes_language = lga;
1606 QString const lang = langModule->languageCO->itemData(
1607 langModule->languageCO->currentIndex()).toString();
1608 bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1611 if (bp_.documentClass().hasTocLevels()) {
1612 bp_.tocdepth = numberingModule->tocSL->value();
1613 bp_.secnumdepth = numberingModule->depthSL->value();
1617 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1618 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1619 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1620 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1623 bp_.graphicsDriver =
1624 tex_graphics[latexModule->psdriverCO->currentIndex()];
1627 int idx = latexModule->classCO->currentIndex();
1629 string const classname = classes_model_.getIDString(idx);
1630 bp_.setBaseClass(classname);
1634 modulesToParams(bp_);
1636 if (mathsModule->amsautoCB->isChecked()) {
1637 bp_.use_amsmath = BufferParams::package_auto;
1639 if (mathsModule->amsCB->isChecked())
1640 bp_.use_amsmath = BufferParams::package_on;
1642 bp_.use_amsmath = BufferParams::package_off;
1645 if (mathsModule->esintautoCB->isChecked())
1646 bp_.use_esint = BufferParams::package_auto;
1648 if (mathsModule->esintCB->isChecked())
1649 bp_.use_esint = BufferParams::package_on;
1651 bp_.use_esint = BufferParams::package_off;
1654 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1655 bp_.pagestyle = "default";
1657 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1658 for (size_t i = 0; i != pagestyles.size(); ++i)
1659 if (pagestyles[i].second == style_gui)
1660 bp_.pagestyle = pagestyles[i].first;
1663 switch (textLayoutModule->lspacingCO->currentIndex()) {
1665 bp_.spacing().set(Spacing::Single);
1668 bp_.spacing().set(Spacing::Onehalf);
1671 bp_.spacing().set(Spacing::Double);
1674 bp_.spacing().set(Spacing::Other,
1675 fromqstr(textLayoutModule->lspacingLE->text()));
1679 if (textLayoutModule->twoColumnCB->isChecked())
1684 // text should have passed validation
1685 bp_.listings_params =
1686 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1688 if (textLayoutModule->indentRB->isChecked())
1689 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1691 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1693 switch (textLayoutModule->skipCO->currentIndex()) {
1695 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1698 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1701 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1706 widgetsToLength(textLayoutModule->skipLE,
1707 textLayoutModule->skipLengthCO)
1713 // DocumentDefskipCB assures that this never happens
1714 // so Assert then !!! - jbl
1715 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1720 fromqstr(latexModule->optionsLE->text());
1722 bp_.use_default_options =
1723 latexModule->defaultOptionsCB->isChecked();
1725 if (latexModule->childDocGB->isChecked())
1727 fromqstr(latexModule->childDocLE->text());
1729 bp_.master = string();
1731 bp_.float_placement = floatModule->get();
1735 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1738 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1740 bp_.fontsTypewriter =
1741 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1744 fromqstr(fontModule->cjkFontLE->text());
1746 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1748 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1750 bp_.fontsSC = fontModule->fontScCB->isChecked();
1752 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1754 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1755 fontModule->fontsDefaultCO->currentIndex()];
1757 if (fontModule->fontsizeCO->currentIndex() == 0)
1758 bp_.fontsize = "default";
1761 fromqstr(fontModule->fontsizeCO->currentText());
1764 bp_.papersize = PAPER_SIZE(
1765 pageLayoutModule->papersizeCO->currentIndex());
1767 // custom, A3, B3 and B4 paper sizes need geometry
1768 int psize = pageLayoutModule->papersizeCO->currentIndex();
1769 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1771 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1772 pageLayoutModule->paperwidthUnitCO);
1774 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1775 pageLayoutModule->paperheightUnitCO);
1777 if (pageLayoutModule->facingPagesCB->isChecked())
1778 bp_.sides = TwoSides;
1780 bp_.sides = OneSide;
1782 if (pageLayoutModule->landscapeRB->isChecked())
1783 bp_.orientation = ORIENTATION_LANDSCAPE;
1785 bp_.orientation = ORIENTATION_PORTRAIT;
1788 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1791 Ui::MarginsUi const * m = marginsModule;
1793 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1794 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1795 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1796 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1797 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1798 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1799 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1800 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1802 branchesModule->apply(bp_);
1805 PDFOptions & pdf = bp_.pdfoptions();
1806 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1807 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1808 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1809 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1810 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1812 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1813 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1814 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1815 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1817 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1818 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1819 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1820 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1822 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1823 if (pdfSupportModule->fullscreenCB->isChecked())
1824 pdf.pagemode = pdf.pagemode_fullscreen;
1826 pdf.pagemode.clear();
1827 pdf.quoted_options = pdf.quoted_options_check(
1828 fromqstr(pdfSupportModule->optionsLE->text()));
1832 void GuiDocument::paramsToDialog()
1834 // set the default unit
1835 Length::UNIT defaultUnit = Length::CM;
1836 switch (lyxrc.default_papersize) {
1837 case PAPER_DEFAULT: break;
1839 case PAPER_USLETTER:
1841 case PAPER_USEXECUTIVE:
1842 defaultUnit = Length::IN;
1851 defaultUnit = Length::CM;
1858 preambleModule->update(bp_, id());
1861 biblioModule->citeDefaultRB->setChecked(
1862 bp_.citeEngine() == ENGINE_BASIC);
1864 biblioModule->citeNatbibRB->setChecked(
1865 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1866 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1868 biblioModule->citeStyleCO->setCurrentIndex(
1869 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1871 biblioModule->citeJurabibRB->setChecked(
1872 bp_.citeEngine() == ENGINE_JURABIB);
1874 biblioModule->bibtopicCB->setChecked(
1877 // language & quotes
1878 int const pos = langModule->languageCO->findData(toqstr(
1879 bp_.language->lang()));
1880 langModule->languageCO->setCurrentIndex(pos);
1882 langModule->quoteStyleCO->setCurrentIndex(
1883 bp_.quotes_language);
1885 bool default_enc = true;
1886 if (bp_.inputenc != "auto") {
1887 default_enc = false;
1888 if (bp_.inputenc == "default") {
1889 langModule->encodingCO->setCurrentIndex(0);
1892 Encodings::const_iterator it = encodings.begin();
1893 Encodings::const_iterator const end = encodings.end();
1894 for (; it != end; ++it) {
1895 if (it->latexName() == bp_.inputenc) {
1896 enc_gui = it->guiName();
1900 int const i = langModule->encodingCO->findText(
1903 langModule->encodingCO->setCurrentIndex(i);
1905 // unknown encoding. Set to default.
1909 langModule->defaultencodingRB->setChecked(default_enc);
1910 langModule->otherencodingRB->setChecked(!default_enc);
1913 int const min_toclevel = documentClass().min_toclevel();
1914 int const max_toclevel = documentClass().max_toclevel();
1915 if (documentClass().hasTocLevels()) {
1916 numberingModule->setEnabled(true);
1917 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1918 numberingModule->depthSL->setMaximum(max_toclevel);
1919 numberingModule->depthSL->setValue(bp_.secnumdepth);
1920 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1921 numberingModule->tocSL->setMaximum(max_toclevel);
1922 numberingModule->tocSL->setValue(bp_.tocdepth);
1925 numberingModule->setEnabled(false);
1926 numberingModule->tocTW->clear();
1930 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1931 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1932 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1933 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1934 bulletsModule->init();
1937 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1939 latexModule->psdriverCO->setCurrentIndex(nitem);
1942 mathsModule->amsCB->setChecked(
1943 bp_.use_amsmath == BufferParams::package_on);
1944 mathsModule->amsautoCB->setChecked(
1945 bp_.use_amsmath == BufferParams::package_auto);
1947 mathsModule->esintCB->setChecked(
1948 bp_.use_esint == BufferParams::package_on);
1949 mathsModule->esintautoCB->setChecked(
1950 bp_.use_esint == BufferParams::package_auto);
1952 switch (bp_.spacing().getSpace()) {
1953 case Spacing::Other: nitem = 3; break;
1954 case Spacing::Double: nitem = 2; break;
1955 case Spacing::Onehalf: nitem = 1; break;
1956 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1960 string const & layoutID = bp_.baseClassID();
1961 setLayoutComboByIDString(layoutID);
1963 updatePagestyle(documentClass().opt_pagestyle(),
1966 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1967 if (bp_.spacing().getSpace() == Spacing::Other) {
1968 textLayoutModule->lspacingLE->setText(
1969 toqstr(bp_.spacing().getValueAsString()));
1973 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1974 textLayoutModule->indentRB->setChecked(true);
1976 textLayoutModule->skipRB->setChecked(true);
1979 switch (bp_.getDefSkip().kind()) {
1980 case VSpace::SMALLSKIP:
1983 case VSpace::MEDSKIP:
1986 case VSpace::BIGSKIP:
1989 case VSpace::LENGTH:
1992 string const length = bp_.getDefSkip().asLyXCommand();
1993 lengthToWidgets(textLayoutModule->skipLE,
1994 textLayoutModule->skipLengthCO,
1995 length, defaultUnit);
2002 textLayoutModule->skipCO->setCurrentIndex(skip);
2005 textLayoutModule->twoColumnCB->setChecked(
2008 // break listings_params to multiple lines
2010 InsetListingsParams(bp_.listings_params).separatedParams();
2011 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2013 if (!bp_.options.empty()) {
2014 latexModule->optionsLE->setText(
2015 toqstr(bp_.options));
2017 latexModule->optionsLE->setText(QString());
2021 latexModule->defaultOptionsCB->setChecked(
2022 bp_.use_default_options);
2023 updateSelectedModules();
2024 selectionManager->updateProvidedModules(
2025 bp_.baseClass()->providedModules());
2026 selectionManager->updateExcludedModules(
2027 bp_.baseClass()->excludedModules());
2029 if (!documentClass().options().empty()) {
2030 latexModule->defaultOptionsLE->setText(
2031 toqstr(documentClass().options()));
2033 latexModule->defaultOptionsLE->setText(
2034 toqstr(_("[No options predefined]")));
2037 latexModule->defaultOptionsLE->setEnabled(
2038 bp_.use_default_options
2039 && !documentClass().options().empty());
2041 latexModule->defaultOptionsCB->setEnabled(
2042 !documentClass().options().empty());
2044 if (!bp_.master.empty()) {
2045 latexModule->childDocGB->setChecked(true);
2046 latexModule->childDocLE->setText(
2047 toqstr(bp_.master));
2049 latexModule->childDocLE->setText(QString());
2050 latexModule->childDocGB->setChecked(false);
2053 floatModule->set(bp_.float_placement);
2056 updateFontsize(documentClass().opt_fontsize(),
2059 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2061 fontModule->fontsRomanCO->setCurrentIndex(n);
2065 n = findToken(tex_fonts_sans, bp_.fontsSans);
2067 fontModule->fontsSansCO->setCurrentIndex(n);
2071 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2073 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2077 if (!bp_.fontsCJK.empty())
2078 fontModule->cjkFontLE->setText(
2079 toqstr(bp_.fontsCJK));
2081 fontModule->cjkFontLE->setText(QString());
2083 fontModule->fontScCB->setChecked(bp_.fontsSC);
2084 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2085 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2086 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2087 n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2089 fontModule->fontsDefaultCO->setCurrentIndex(n);
2092 int const psize = bp_.papersize;
2093 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2094 setCustomPapersize(psize);
2096 bool const landscape =
2097 bp_.orientation == ORIENTATION_LANDSCAPE;
2098 pageLayoutModule->landscapeRB->setChecked(landscape);
2099 pageLayoutModule->portraitRB->setChecked(!landscape);
2101 pageLayoutModule->facingPagesCB->setChecked(
2102 bp_.sides == TwoSides);
2105 lengthToWidgets(pageLayoutModule->paperwidthLE,
2106 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2108 lengthToWidgets(pageLayoutModule->paperheightLE,
2109 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2112 Ui::MarginsUi * m = marginsModule;
2114 setMargins(!bp_.use_geometry);
2116 lengthToWidgets(m->topLE, m->topUnit,
2117 bp_.topmargin, defaultUnit);
2119 lengthToWidgets(m->bottomLE, m->bottomUnit,
2120 bp_.bottommargin, defaultUnit);
2122 lengthToWidgets(m->innerLE, m->innerUnit,
2123 bp_.leftmargin, defaultUnit);
2125 lengthToWidgets(m->outerLE, m->outerUnit,
2126 bp_.rightmargin, defaultUnit);
2128 lengthToWidgets(m->headheightLE, m->headheightUnit,
2129 bp_.headheight, defaultUnit);
2131 lengthToWidgets(m->headsepLE, m->headsepUnit,
2132 bp_.headsep, defaultUnit);
2134 lengthToWidgets(m->footskipLE, m->footskipUnit,
2135 bp_.footskip, defaultUnit);
2137 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2138 bp_.columnsep, defaultUnit);
2140 branchesModule->update(bp_);
2143 PDFOptions const & pdf = bp_.pdfoptions();
2144 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2145 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2146 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2147 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2148 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2150 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2151 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2152 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2154 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2156 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2157 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2158 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2159 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2161 n = findToken(backref_opts, pdf.backref);
2163 pdfSupportModule->backrefCO->setCurrentIndex(n);
2165 pdfSupportModule->fullscreenCB->setChecked
2166 (pdf.pagemode == pdf.pagemode_fullscreen);
2168 pdfSupportModule->optionsLE->setText(
2169 toqstr(pdf.quoted_options));
2175 void GuiDocument::saveDocDefault()
2177 // we have to apply the params first
2183 void GuiDocument::updateAvailableModules()
2185 modules_av_model_.clear();
2186 list<modInfoStruct> const & modInfoList = getModuleInfo();
2187 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2188 list<modInfoStruct>::const_iterator men = modInfoList.end();
2189 for (int i = 0; mit != men; ++mit, ++i)
2190 modules_av_model_.insertRow(i, mit->name, mit->id,
2195 void GuiDocument::updateSelectedModules()
2197 modules_sel_model_.clear();
2198 list<modInfoStruct> const selModList = getSelectedModules();
2199 list<modInfoStruct>::const_iterator mit = selModList.begin();
2200 list<modInfoStruct>::const_iterator men = selModList.end();
2201 for (int i = 0; mit != men; ++mit, ++i)
2202 modules_sel_model_.insertRow(i, mit->name, mit->id,
2207 void GuiDocument::updateContents()
2209 // Nothing to do here as the document settings is not cursor dependant.
2214 void GuiDocument::useClassDefaults()
2216 if (applyPB->isEnabled()) {
2217 int const ret = Alert::prompt(_("Unapplied changes"),
2218 _("Some changes in the dialog were not yet applied.\n"
2219 "If you do not apply now, they will be lost after this action."),
2220 1, 1, _("&Apply"), _("&Dismiss"));
2225 int idx = latexModule->classCO->currentIndex();
2226 string const classname = classes_model_.getIDString(idx);
2227 if (!bp_.setBaseClass(classname)) {
2228 Alert::error(_("Error"), _("Unable to set document class."));
2231 bp_.useClassDefaults();
2236 void GuiDocument::setLayoutComboByIDString(string const & idString)
2238 int idx = classes_model_.findIDString(idString);
2240 Alert::warning(_("Can't set layout!"),
2241 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2243 latexModule->classCO->setCurrentIndex(idx);
2247 bool GuiDocument::isValid()
2249 return validateListingsParameters().isEmpty()
2250 && (textLayoutModule->skipCO->currentIndex() != 3
2251 || !textLayoutModule->skipLE->text().isEmpty());
2255 char const * const GuiDocument::fontfamilies[5] = {
2256 "default", "rmdefault", "sfdefault", "ttdefault", ""
2260 char const * GuiDocument::fontfamilies_gui[5] = {
2261 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2265 bool GuiDocument::initialiseParams(string const &)
2267 BufferView const * view = bufferview();
2269 bp_ = BufferParams();
2273 bp_ = view->buffer().params();
2275 updateAvailableModules();
2276 //FIXME It'd be nice to make sure here that the selected
2277 //modules are consistent: That required modules are actually
2278 //selected, and that we don't have conflicts. If so, we could
2279 //at least pop up a warning.
2285 void GuiDocument::clearParams()
2287 bp_ = BufferParams();
2291 BufferId GuiDocument::id() const
2293 BufferView const * const view = bufferview();
2294 return view? &view->buffer() : 0;
2298 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2300 return moduleNames_;
2304 list<GuiDocument::modInfoStruct> const
2305 GuiDocument::makeModuleInfo(list<string> const & mods)
2307 list<string>::const_iterator it = mods.begin();
2308 list<string>::const_iterator end = mods.end();
2309 list<modInfoStruct> mInfo;
2310 for (; it != end; ++it) {
2313 LyXModule * mod = moduleList[*it];
2316 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2318 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2325 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2327 return makeModuleInfo(params().getModules());
2331 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2333 return makeModuleInfo(params().baseClass()->providedModules());
2337 DocumentClass const & GuiDocument::documentClass() const
2339 return bp_.documentClass();
2343 static void dispatch_bufferparams(Dialog const & dialog,
2344 BufferParams const & bp, FuncCode lfun)
2347 ss << "\\begin_header\n";
2349 ss << "\\end_header\n";
2350 dialog.dispatch(FuncRequest(lfun, ss.str()));
2354 void GuiDocument::dispatchParams()
2356 // This must come first so that a language change is correctly noticed
2359 // Apply the BufferParams. Note that this will set the base class
2360 // and then update the buffer's layout.
2361 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2363 if (!params().master.empty()) {
2364 FileName const master_file = support::makeAbsPath(params().master,
2365 support::onlyPath(buffer().absFileName()));
2366 if (isLyXFilename(master_file.absFilename())) {
2367 Buffer * master = checkAndLoadLyXFile(master_file);
2368 const_cast<Buffer &>(buffer()).setParent(master);
2372 // Generate the colours requested by each new branch.
2373 BranchList & branchlist = params().branchlist();
2374 if (!branchlist.empty()) {
2375 BranchList::const_iterator it = branchlist.begin();
2376 BranchList::const_iterator const end = branchlist.end();
2377 for (; it != end; ++it) {
2378 docstring const & current_branch = it->branch();
2379 Branch const * branch = branchlist.find(current_branch);
2380 string const x11hexname = X11hexname(branch->color());
2381 // display the new color
2382 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2383 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2386 // Open insets of selected branches, close deselected ones
2387 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2390 // FIXME: If we used an LFUN, we would not need those two lines:
2391 BufferView * bv = const_cast<BufferView *>(bufferview());
2392 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2396 void GuiDocument::setLanguage() const
2398 Language const * const newL = bp_.language;
2399 if (buffer().params().language == newL)
2402 string const & lang_name = newL->lang();
2403 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2407 void GuiDocument::saveAsDefault() const
2409 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2413 bool GuiDocument::isFontAvailable(string const & font) const
2415 if (font == "default" || font == "cmr"
2416 || font == "cmss" || font == "cmtt")
2417 // these are standard
2419 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2420 return LaTeXFeatures::isAvailable("lmodern");
2421 if (font == "times" || font == "palatino"
2422 || font == "helvet" || font == "courier")
2423 return LaTeXFeatures::isAvailable("psnfss");
2424 if (font == "cmbr" || font == "cmtl")
2425 return LaTeXFeatures::isAvailable("cmbright");
2426 if (font == "utopia")
2427 return LaTeXFeatures::isAvailable("utopia")
2428 || LaTeXFeatures::isAvailable("fourier");
2429 if (font == "beraserif" || font == "berasans"
2430 || font == "beramono")
2431 return LaTeXFeatures::isAvailable("bera");
2432 return LaTeXFeatures::isAvailable(font);
2436 bool GuiDocument::providesOSF(string const & font) const
2439 return isFontAvailable("eco");
2440 if (font == "palatino")
2441 return isFontAvailable("mathpazo");
2446 bool GuiDocument::providesSC(string const & font) const
2448 if (font == "palatino")
2449 return isFontAvailable("mathpazo");
2450 if (font == "utopia")
2451 return isFontAvailable("fourier");
2456 bool GuiDocument::providesScale(string const & font) const
2458 return font == "helvet" || font == "luximono"
2459 || font == "berasans" || font == "beramono";
2463 void GuiDocument::loadModuleInfo()
2465 moduleNames_.clear();
2466 LyXModuleList::const_iterator it = moduleList.begin();
2467 LyXModuleList::const_iterator end = moduleList.end();
2468 for (; it != end; ++it) {
2472 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2473 // this is supposed to give us the first sentence of the description
2476 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2477 int const pos = desc.indexOf(".");
2479 desc.truncate(pos + 1);
2480 m.description = desc;
2481 moduleNames_.push_back(m);
2486 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2489 } // namespace frontend
2492 #include "moc_GuiDocument.cpp"