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"
34 #include "FuncRequest.h"
36 #include "LaTeXFeatures.h"
38 #include "LayoutModuleList.h"
40 #include "ModuleList.h"
41 #include "OutputParams.h"
42 #include "PDFOptions.h"
43 #include "qt_helpers.h"
46 #include "insets/InsetListingsParams.h"
48 #include "support/debug.h"
49 #include "support/FileName.h"
50 #include "support/filetools.h"
51 #include "support/gettext.h"
52 #include "support/lstrings.h"
54 #include "frontends/alert.h"
56 #include <QAbstractItemModel>
57 #include <QCloseEvent>
58 #include <QFontDatabase>
60 #include <QTextCursor>
71 using namespace lyx::support;
76 char const * const tex_graphics[] =
78 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
79 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
80 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
81 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
86 char const * const tex_graphics_gui[] =
88 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
89 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
90 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
91 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
92 "XeTeX", N_("None"), ""
96 char const * const tex_fonts_roman[] =
98 "default", "cmr", "lmodern", "ae", "times", "palatino",
99 "charter", "newcent", "bookman", "utopia", "beraserif",
100 "ccfonts", "chancery", ""
104 char const * tex_fonts_roman_gui[] =
106 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
107 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
108 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
109 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
114 char const * const tex_fonts_sans[] =
116 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
120 char const * tex_fonts_sans_gui[] =
122 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
123 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
127 char const * const tex_fonts_monospaced[] =
129 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
133 char const * tex_fonts_monospaced_gui[] =
135 N_("Default"), N_("Computer Modern Typewriter"),
136 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
137 N_("LuxiMono"), N_("CM Typewriter Light"), ""
141 char const * backref_opts[] =
143 "false", "section", "slide", "page", ""
147 char const * backref_opts_gui[] =
149 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
153 vector<pair<string, QString> > pagestyles;
156 } // anonymous namespace
161 // used when sorting the textclass list.
162 class less_textclass_avail_desc
163 : public binary_function<string, string, int>
166 bool operator()(string const & lhs, string const & rhs) const
168 // Ordering criteria:
169 // 1. Availability of text class
170 // 2. Description (lexicographic)
171 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
172 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
173 int const rel = compare_no_case(
174 translateIfPossible(from_utf8(tc1.description())),
175 translateIfPossible(from_utf8(tc2.description())));
176 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
177 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && rel < 0);
186 vector<string> getRequiredList(string const & modName)
188 LyXModule const * const mod = moduleList[modName];
190 return vector<string>(); //empty such thing
191 return mod->getRequiredModules();
195 vector<string> getExcludedList(string const & modName)
197 LyXModule const * const mod = moduleList[modName];
199 return vector<string>(); //empty such thing
200 return mod->getExcludedModules();
204 docstring getModuleDescription(string const & modName)
206 LyXModule const * const mod = moduleList[modName];
208 return _("Module not found!");
210 return translateIfPossible(from_utf8(mod->getDescription()));
214 vector<string> getPackageList(string const & modName)
216 LyXModule const * const mod = moduleList[modName];
218 return vector<string>(); //empty such thing
219 return mod->getPackageList();
223 bool isModuleAvailable(string const & modName)
225 LyXModule * mod = moduleList[modName];
228 return mod->isAvailable();
231 } // anonymous namespace
234 /////////////////////////////////////////////////////////////////////
236 // ModuleSelectionManager
238 /////////////////////////////////////////////////////////////////////
240 /// SelectionManager for use with modules
241 class ModuleSelectionManager : public GuiSelectionManager
245 ModuleSelectionManager(
246 QListView * availableLV,
247 QListView * selectedLV,
251 QPushButton * downPB,
252 GuiIdListModel * availableModel,
253 GuiIdListModel * selectedModel,
254 GuiDocument const * container)
255 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
256 upPB, downPB, availableModel, selectedModel), container_(container)
259 void updateProvidedModules(LayoutModuleList const & pm)
260 { provided_modules_ = pm.list(); }
262 void updateExcludedModules(LayoutModuleList const & em)
263 { excluded_modules_ = em.list(); }
266 virtual void updateAddPB();
268 virtual void updateUpPB();
270 virtual void updateDownPB();
272 virtual void updateDelPB();
273 /// returns availableModel as a GuiIdListModel
274 GuiIdListModel * getAvailableModel()
276 return dynamic_cast<GuiIdListModel *>(availableModel);
278 /// returns selectedModel as a GuiIdListModel
279 GuiIdListModel * getSelectedModel()
281 return dynamic_cast<GuiIdListModel *>(selectedModel);
283 /// keeps a list of the modules the text class provides
284 std::list<std::string> provided_modules_;
286 std::list<std::string> excluded_modules_;
288 GuiDocument const * container_;
291 void ModuleSelectionManager::updateAddPB()
293 int const arows = availableModel->rowCount();
294 QModelIndexList const avail_sels =
295 availableLV->selectionModel()->selectedIndexes();
297 // disable if there aren't any modules (?), if none of them is chosen
298 // in the dialog, or if the chosen one is already selected for use.
299 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
300 addPB->setEnabled(false);
304 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
305 string const modname = getAvailableModel()->getIDString(idx.row());
308 container_->params().moduleCanBeAdded(modname);
309 addPB->setEnabled(enable);
313 void ModuleSelectionManager::updateDownPB()
315 int const srows = selectedModel->rowCount();
317 downPB->setEnabled(false);
320 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
321 int const curRow = curidx.row();
322 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
323 downPB->setEnabled(false);
327 // determine whether immediately succeding element requires this one
328 string const curmodname = getSelectedModel()->getIDString(curRow);
329 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
331 vector<string> reqs = getRequiredList(nextmodname);
333 // if it doesn't require anything....
335 downPB->setEnabled(true);
339 // Enable it if this module isn't required.
340 // FIXME This should perhaps be more flexible and check whether, even
341 // if the next one is required, there is also an earlier one that will do.
343 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
346 void ModuleSelectionManager::updateUpPB()
348 int const srows = selectedModel->rowCount();
350 upPB->setEnabled(false);
354 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
355 int curRow = curIdx.row();
356 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
357 upPB->setEnabled(false);
360 string const curmodname = getSelectedModel()->getIDString(curRow);
362 // determine whether immediately preceding element is required by this one
363 vector<string> reqs = getRequiredList(curmodname);
365 // if this one doesn't require anything....
367 upPB->setEnabled(true);
372 // Enable it if the preceding module isn't required.
373 // NOTE This is less flexible than it might be. We could check whether, even
374 // if the previous one is required, there is an earlier one that would do.
375 string const premod = getSelectedModel()->getIDString(curRow - 1);
376 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
379 void ModuleSelectionManager::updateDelPB()
381 int const srows = selectedModel->rowCount();
383 deletePB->setEnabled(false);
387 QModelIndex const & curidx =
388 selectedLV->selectionModel()->currentIndex();
389 int const curRow = curidx.row();
390 if (curRow < 0 || curRow >= srows) { // invalid index?
391 deletePB->setEnabled(false);
395 string const curmodname = getSelectedModel()->getIDString(curRow);
397 // We're looking here for a reason NOT to enable the button. If we
398 // find one, we disable it and return. If we don't, we'll end up at
399 // the end of the function, and then we enable it.
400 for (int i = curRow + 1; i < srows; ++i) {
401 string const thisMod = getSelectedModel()->getIDString(i);
402 vector<string> reqs = getRequiredList(thisMod);
403 //does this one require us?
404 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
408 // OK, so this module requires us
409 // is there an EARLIER module that also satisfies the require?
410 // NOTE We demand that it be earlier to keep the list of modules
411 // consistent with the rule that a module must be proceeded by a
412 // required module. There would be more flexible ways to proceed,
413 // but that would be a lot more complicated, and the logic here is
414 // already complicated. (That's why I've left the debugging code.)
415 // lyxerr << "Testing " << thisMod << std::endl;
416 bool foundone = false;
417 for (int j = 0; j < curRow; ++j) {
418 string const mod = getSelectedModel()->getIDString(j);
419 // lyxerr << "In loop: Testing " << mod << std::endl;
420 // do we satisfy the require?
421 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
422 // lyxerr << mod << " does the trick." << std::endl;
427 // did we find a module to satisfy the require?
429 // lyxerr << "No matching module found." << std::endl;
430 deletePB->setEnabled(false);
434 // lyxerr << "All's well that ends well." << std::endl;
435 deletePB->setEnabled(true);
439 /////////////////////////////////////////////////////////////////////
443 /////////////////////////////////////////////////////////////////////
445 PreambleModule::PreambleModule() : current_id_(0)
447 // This is not a memory leak. The object will be destroyed
449 (void) new LaTeXHighlighter(preambleTE->document());
450 setFocusProxy(preambleTE);
451 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
455 void PreambleModule::update(BufferParams const & params, BufferId id)
457 QString preamble = toqstr(params.preamble);
458 // Nothing to do if the params and preamble are unchanged.
459 if (id == current_id_
460 && preamble == preambleTE->document()->toPlainText())
463 QTextCursor cur = preambleTE->textCursor();
464 // Save the coords before switching to the new one.
465 preamble_coords_[current_id_] =
466 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
468 // Save the params address for further use.
470 preambleTE->document()->setPlainText(preamble);
471 Coords::const_iterator it = preamble_coords_.find(current_id_);
472 if (it == preamble_coords_.end())
473 // First time we open this one.
474 preamble_coords_[current_id_] = make_pair(0, 0);
476 // Restore saved coords.
477 QTextCursor cur = preambleTE->textCursor();
478 cur.setPosition(it->second.first);
479 preambleTE->setTextCursor(cur);
480 preambleTE->verticalScrollBar()->setValue(it->second.second);
485 void PreambleModule::apply(BufferParams & params)
487 params.preamble = fromqstr(preambleTE->document()->toPlainText());
491 void PreambleModule::closeEvent(QCloseEvent * e)
493 // Save the coords before closing.
494 QTextCursor cur = preambleTE->textCursor();
495 preamble_coords_[current_id_] =
496 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
501 /////////////////////////////////////////////////////////////////////
505 /////////////////////////////////////////////////////////////////////
508 GuiDocument::GuiDocument(GuiView & lv)
509 : GuiDialog(lv, "document", qt_("Document Settings"))
513 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
514 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
515 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
516 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
518 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
519 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
521 // Manage the restore, ok, apply, restore and cancel/close buttons
522 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
524 bc().setApply(applyPB);
525 bc().setCancel(closePB);
526 bc().setRestore(restorePB);
528 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
530 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
531 this, SLOT(change_adaptor()));
532 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
533 this, SLOT(setLSpacing(int)));
534 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
535 this, SLOT(change_adaptor()));
536 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
537 this, SLOT(change_adaptor()));
538 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
539 this, SLOT(change_adaptor()));
540 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
541 this, SLOT(change_adaptor()));
542 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
543 this, SLOT(change_adaptor()));
544 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
545 this, SLOT(change_adaptor()));
546 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
547 this, SLOT(setSkip(int)));
548 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
549 this, SLOT(enableSkip(bool)));
550 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
551 this, SLOT(change_adaptor()));
552 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
553 this, SLOT(setColSep()));
554 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
555 this, SLOT(change_adaptor()));
556 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
557 this, SLOT(change_adaptor()));
558 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
559 this, SLOT(setListingsMessage()));
560 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
561 this, SLOT(setListingsMessage()));
562 textLayoutModule->listingsTB->setPlainText(
563 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
564 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
565 textLayoutModule->lspacingLE));
566 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
567 textLayoutModule->skipLE));
569 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
570 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
571 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
572 textLayoutModule->skipCO->addItem(qt_("Length"));
573 // remove the %-items from the unit choice
574 textLayoutModule->skipLengthCO->noPercents();
575 textLayoutModule->lspacingCO->insertItem(
576 Spacing::Single, qt_("Single"));
577 textLayoutModule->lspacingCO->insertItem(
578 Spacing::Onehalf, qt_("OneHalf"));
579 textLayoutModule->lspacingCO->insertItem(
580 Spacing::Double, qt_("Double"));
581 textLayoutModule->lspacingCO->insertItem(
582 Spacing::Other, qt_("Custom"));
584 // initialize the length validator
585 bc().addCheckedLineEdit(textLayoutModule->skipLE);
588 outputModule = new UiWidget<Ui::OutputUi>;
590 connect(outputModule->xetexCB, SIGNAL(clicked()),
591 this, SLOT(change_adaptor()));
592 connect(outputModule->xetexCB, SIGNAL(toggled(bool)),
593 this, SLOT(xetexChanged(bool)));
594 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
595 this, SLOT(change_adaptor()));
598 fontModule = new UiWidget<Ui::FontUi>;
599 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
600 this, SLOT(change_adaptor()));
601 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
602 this, SLOT(romanChanged(int)));
603 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
604 this, SLOT(change_adaptor()));
605 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
606 this, SLOT(sansChanged(int)));
607 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
608 this, SLOT(change_adaptor()));
609 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
610 this, SLOT(ttChanged(int)));
611 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
612 this, SLOT(change_adaptor()));
613 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
614 this, SLOT(change_adaptor()));
615 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
616 this, SLOT(change_adaptor()));
617 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
618 this, SLOT(change_adaptor()));
619 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
620 this, SLOT(change_adaptor()));
621 connect(fontModule->fontScCB, SIGNAL(clicked()),
622 this, SLOT(change_adaptor()));
623 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
624 this, SLOT(change_adaptor()));
628 fontModule->fontsizeCO->addItem(qt_("Default"));
629 fontModule->fontsizeCO->addItem(qt_("10"));
630 fontModule->fontsizeCO->addItem(qt_("11"));
631 fontModule->fontsizeCO->addItem(qt_("12"));
633 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
634 fontModule->fontsDefaultCO->addItem(
635 qt_(GuiDocument::fontfamilies_gui[n]));
638 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
640 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
641 this, SLOT(setCustomPapersize(int)));
642 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
643 this, SLOT(setCustomPapersize(int)));
644 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
645 this, SLOT(portraitChanged()));
646 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
647 this, SLOT(change_adaptor()));
648 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
649 this, SLOT(change_adaptor()));
650 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
651 this, SLOT(change_adaptor()));
652 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
653 this, SLOT(change_adaptor()));
654 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
655 this, SLOT(change_adaptor()));
656 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
657 this, SLOT(change_adaptor()));
658 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
659 this, SLOT(change_adaptor()));
660 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
661 this, SLOT(change_adaptor()));
662 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
663 this, SLOT(change_adaptor()));
665 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
666 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
667 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
668 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
669 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
670 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
671 pageLayoutModule->paperheightL);
672 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
673 pageLayoutModule->paperwidthL);
676 QComboBox * cb = pageLayoutModule->papersizeCO;
677 cb->addItem(qt_("Default"));
678 cb->addItem(qt_("Custom"));
679 cb->addItem(qt_("US letter"));
680 cb->addItem(qt_("US legal"));
681 cb->addItem(qt_("US executive"));
682 cb->addItem(qt_("A3"));
683 cb->addItem(qt_("A4"));
684 cb->addItem(qt_("A5"));
685 cb->addItem(qt_("B3"));
686 cb->addItem(qt_("B4"));
687 cb->addItem(qt_("B5"));
688 // remove the %-items from the unit choice
689 pageLayoutModule->paperwidthUnitCO->noPercents();
690 pageLayoutModule->paperheightUnitCO->noPercents();
691 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
692 pageLayoutModule->paperheightLE));
693 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
694 pageLayoutModule->paperwidthLE));
697 marginsModule = new UiWidget<Ui::MarginsUi>;
699 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
700 this, SLOT(setCustomMargins(bool)));
701 connect(marginsModule->marginCB, SIGNAL(clicked()),
702 this, SLOT(change_adaptor()));
703 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
704 this, SLOT(change_adaptor()));
705 connect(marginsModule->topUnit, SIGNAL(activated(int)),
706 this, SLOT(change_adaptor()));
707 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
708 this, SLOT(change_adaptor()));
709 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
710 this, SLOT(change_adaptor()));
711 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
712 this, SLOT(change_adaptor()));
713 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
714 this, SLOT(change_adaptor()));
715 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
716 this, SLOT(change_adaptor()));
717 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
718 this, SLOT(change_adaptor()));
719 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
720 this, SLOT(change_adaptor()));
721 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
722 this, SLOT(change_adaptor()));
723 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
724 this, SLOT(change_adaptor()));
725 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
726 this, SLOT(change_adaptor()));
727 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
728 this, SLOT(change_adaptor()));
729 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
730 this, SLOT(change_adaptor()));
731 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
732 this, SLOT(change_adaptor()));
733 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
734 this, SLOT(change_adaptor()));
735 marginsModule->topLE->setValidator(unsignedLengthValidator(
736 marginsModule->topLE));
737 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
738 marginsModule->bottomLE));
739 marginsModule->innerLE->setValidator(unsignedLengthValidator(
740 marginsModule->innerLE));
741 marginsModule->outerLE->setValidator(unsignedLengthValidator(
742 marginsModule->outerLE));
743 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
744 marginsModule->headsepLE));
745 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
746 marginsModule->headheightLE));
747 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
748 marginsModule->footskipLE));
749 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
750 marginsModule->columnsepLE));
752 bc().addCheckedLineEdit(marginsModule->topLE,
753 marginsModule->topL);
754 bc().addCheckedLineEdit(marginsModule->bottomLE,
755 marginsModule->bottomL);
756 bc().addCheckedLineEdit(marginsModule->innerLE,
757 marginsModule->innerL);
758 bc().addCheckedLineEdit(marginsModule->outerLE,
759 marginsModule->outerL);
760 bc().addCheckedLineEdit(marginsModule->headsepLE,
761 marginsModule->headsepL);
762 bc().addCheckedLineEdit(marginsModule->headheightLE,
763 marginsModule->headheightL);
764 bc().addCheckedLineEdit(marginsModule->footskipLE,
765 marginsModule->footskipL);
766 bc().addCheckedLineEdit(marginsModule->columnsepLE,
767 marginsModule->columnsepL);
770 langModule = new UiWidget<Ui::LanguageUi>;
772 connect(langModule->languageCO, SIGNAL(activated(int)),
773 this, SLOT(change_adaptor()));
774 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
775 this, SLOT(change_adaptor()));
776 connect(langModule->otherencodingRB, SIGNAL(clicked()),
777 this, SLOT(change_adaptor()));
778 connect(langModule->encodingCO, SIGNAL(activated(int)),
779 this, SLOT(change_adaptor()));
780 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
781 this, SLOT(change_adaptor()));
783 QAbstractItemModel * language_model = guiApp->languageModel();
784 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
785 language_model->sort(0);
786 langModule->languageCO->setModel(language_model);
788 // Always put the default encoding in the first position.
789 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
790 QStringList encodinglist;
791 Encodings::const_iterator it = encodings.begin();
792 Encodings::const_iterator const end = encodings.end();
793 for (; it != end; ++it)
794 encodinglist.append(qt_(it->guiName()));
796 langModule->encodingCO->addItems(encodinglist);
798 langModule->quoteStyleCO->addItem(qt_("``text''"));
799 langModule->quoteStyleCO->addItem(qt_("''text''"));
800 langModule->quoteStyleCO->addItem(qt_(",,text``"));
801 langModule->quoteStyleCO->addItem(qt_(",,text''"));
802 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
803 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
806 numberingModule = new UiWidget<Ui::NumberingUi>;
808 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
809 this, SLOT(change_adaptor()));
810 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
811 this, SLOT(change_adaptor()));
812 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
813 this, SLOT(updateNumbering()));
814 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
815 this, SLOT(updateNumbering()));
816 numberingModule->tocTW->setColumnCount(3);
817 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
818 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
819 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
822 biblioModule = new UiWidget<Ui::BiblioUi>;
823 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
824 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
825 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
826 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
828 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
829 this, SLOT(change_adaptor()));
830 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
831 this, SLOT(change_adaptor()));
832 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
833 this, SLOT(change_adaptor()));
834 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
835 this, SLOT(change_adaptor()));
836 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
837 this, SLOT(change_adaptor()));
839 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
840 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
841 biblioModule->citeStyleCO->setCurrentIndex(0);
844 mathsModule = new UiWidget<Ui::MathsUi>;
845 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
846 mathsModule->amsCB, SLOT(setDisabled(bool)));
847 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
848 mathsModule->esintCB, SLOT(setDisabled(bool)));
850 connect(mathsModule->amsCB, SIGNAL(clicked()),
851 this, SLOT(change_adaptor()));
852 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
853 this, SLOT(change_adaptor()));
854 connect(mathsModule->esintCB, SIGNAL(clicked()),
855 this, SLOT(change_adaptor()));
856 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
857 this, SLOT(change_adaptor()));
859 latexModule = new UiWidget<Ui::LaTeXUi>;
861 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
862 this, SLOT(change_adaptor()));
863 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
864 this, SLOT(change_adaptor()));
865 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
866 this, SLOT(change_adaptor()));
867 connect(latexModule->classCO, SIGNAL(activated(int)),
868 this, SLOT(classChanged()));
869 connect(latexModule->classCO, SIGNAL(activated(int)),
870 this, SLOT(change_adaptor()));
871 connect(latexModule->layoutPB, SIGNAL(clicked()),
872 this, SLOT(browseLayout()));
873 connect(latexModule->layoutPB, SIGNAL(clicked()),
874 this, SLOT(change_adaptor()));
875 connect(latexModule->childDocGB, SIGNAL(clicked()),
876 this, SLOT(change_adaptor()));
877 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
878 this, SLOT(change_adaptor()));
879 connect(latexModule->childDocPB, SIGNAL(clicked()),
880 this, SLOT(browseMaster()));
882 // postscript drivers
883 for (int n = 0; tex_graphics[n][0]; ++n) {
884 QString enc = qt_(tex_graphics_gui[n]);
885 latexModule->psdriverCO->addItem(enc);
888 latexModule->classCO->setModel(&classes_model_);
889 LayoutFileList const & bcl = LayoutFileList::get();
890 vector<LayoutFileIndex> classList = bcl.classList();
891 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
893 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
894 vector<LayoutFileIndex>::const_iterator cen = classList.end();
895 for (int i = 0; cit != cen; ++cit, ++i) {
896 LayoutFile const & tc = bcl[*cit];
897 docstring item = (tc.isTeXClassAvailable()) ?
898 from_utf8(tc.description()) :
899 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
900 classes_model_.insertRow(i, toqstr(item), *cit);
904 branchesModule = new GuiBranches;
905 connect(branchesModule, SIGNAL(changed()),
906 this, SLOT(change_adaptor()));
909 preambleModule = new PreambleModule;
910 connect(preambleModule, SIGNAL(changed()),
911 this, SLOT(change_adaptor()));
914 bulletsModule = new BulletsModule;
915 connect(bulletsModule, SIGNAL(changed()),
916 this, SLOT(change_adaptor()));
919 modulesModule = new UiWidget<Ui::ModulesUi>;
922 new ModuleSelectionManager(modulesModule->availableLV,
923 modulesModule->selectedLV,
924 modulesModule->addPB, modulesModule->deletePB,
925 modulesModule->upPB, modulesModule->downPB,
926 availableModel(), selectedModel(), this);
927 connect(selectionManager, SIGNAL(updateHook()),
928 this, SLOT(updateModuleInfo()));
929 connect(selectionManager, SIGNAL(updateHook()),
930 this, SLOT(change_adaptor()));
931 connect(selectionManager, SIGNAL(selectionChanged()),
932 this, SLOT(modulesChanged()));
935 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
937 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
938 this, SLOT(change_adaptor()));
939 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
940 this, SLOT(change_adaptor()));
941 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
942 this, SLOT(change_adaptor()));
943 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
944 this, SLOT(change_adaptor()));
945 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
946 this, SLOT(change_adaptor()));
947 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
948 this, SLOT(change_adaptor()));
949 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
950 this, SLOT(change_adaptor()));
951 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
952 this, SLOT(change_adaptor()));
953 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
954 this, SLOT(change_adaptor()));
955 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
956 this, SLOT(change_adaptor()));
957 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
958 this, SLOT(change_adaptor()));
959 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
960 this, SLOT(change_adaptor()));
961 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
962 this, SLOT(change_adaptor()));
963 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
964 this, SLOT(change_adaptor()));
965 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
966 this, SLOT(change_adaptor()));
967 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
968 this, SLOT(change_adaptor()));
970 for (int i = 0; backref_opts[i][0]; ++i)
971 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
974 floatModule = new FloatPlacement;
975 connect(floatModule, SIGNAL(changed()),
976 this, SLOT(change_adaptor()));
978 docPS->addPanel(latexModule, qt_("Document Class"));
979 docPS->addPanel(modulesModule, qt_("Modules"));
980 docPS->addPanel(fontModule, qt_("Fonts"));
981 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
982 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
983 docPS->addPanel(marginsModule, qt_("Page Margins"));
984 docPS->addPanel(langModule, qt_("Language"));
985 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
986 docPS->addPanel(biblioModule, qt_("Bibliography"));
987 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
988 docPS->addPanel(mathsModule, qt_("Math Options"));
989 docPS->addPanel(floatModule, qt_("Float Placement"));
990 docPS->addPanel(bulletsModule, qt_("Bullets"));
991 docPS->addPanel(branchesModule, qt_("Branches"));
992 docPS->addPanel(outputModule, qt_("Output"));
993 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
994 docPS->setCurrentPanel(qt_("Document Class"));
995 // FIXME: hack to work around resizing bug in Qt >= 4.2
996 // bug verified with Qt 4.2.{0-3} (JSpitzm)
997 #if QT_VERSION >= 0x040200
998 docPS->updateGeometry();
1003 void GuiDocument::showPreamble()
1005 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1009 void GuiDocument::saveDefaultClicked()
1015 void GuiDocument::useDefaultsClicked()
1021 void GuiDocument::change_adaptor()
1027 QString GuiDocument::validateListingsParameters()
1029 // use a cache here to avoid repeated validation
1030 // of the same parameters
1031 static string param_cache;
1032 static QString msg_cache;
1034 if (textLayoutModule->bypassCB->isChecked())
1037 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1038 if (params != param_cache) {
1039 param_cache = params;
1040 msg_cache = toqstr(InsetListingsParams(params).validate());
1046 void GuiDocument::setListingsMessage()
1048 static bool isOK = true;
1049 QString msg = validateListingsParameters();
1050 if (msg.isEmpty()) {
1054 // listingsTB->setTextColor("black");
1055 textLayoutModule->listingsTB->setPlainText(
1056 qt_("Input listings parameters on the right. "
1057 "Enter ? for a list of parameters."));
1060 // listingsTB->setTextColor("red");
1061 textLayoutModule->listingsTB->setPlainText(msg);
1066 void GuiDocument::setLSpacing(int item)
1068 textLayoutModule->lspacingLE->setEnabled(item == 3);
1072 void GuiDocument::setSkip(int item)
1074 bool const enable = (item == 3);
1075 textLayoutModule->skipLE->setEnabled(enable);
1076 textLayoutModule->skipLengthCO->setEnabled(enable);
1080 void GuiDocument::enableSkip(bool skip)
1082 textLayoutModule->skipCO->setEnabled(skip);
1083 textLayoutModule->skipLE->setEnabled(skip);
1084 textLayoutModule->skipLengthCO->setEnabled(skip);
1086 setSkip(textLayoutModule->skipCO->currentIndex());
1090 void GuiDocument::portraitChanged()
1092 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1096 void GuiDocument::setMargins(bool custom)
1098 bool const extern_geometry =
1099 documentClass().provides("geometry");
1100 marginsModule->marginCB->setEnabled(!extern_geometry);
1101 if (extern_geometry) {
1102 marginsModule->marginCB->setChecked(false);
1103 setCustomMargins(true);
1106 marginsModule->marginCB->setChecked(custom);
1107 setCustomMargins(custom);
1111 void GuiDocument::setCustomPapersize(int papersize)
1113 bool const custom = (papersize == 1);
1115 pageLayoutModule->paperwidthL->setEnabled(custom);
1116 pageLayoutModule->paperwidthLE->setEnabled(custom);
1117 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1118 pageLayoutModule->paperheightL->setEnabled(custom);
1119 pageLayoutModule->paperheightLE->setEnabled(custom);
1120 pageLayoutModule->paperheightLE->setFocus();
1121 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1125 void GuiDocument::setColSep()
1127 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1131 void GuiDocument::setCustomMargins(bool custom)
1133 marginsModule->topL->setEnabled(!custom);
1134 marginsModule->topLE->setEnabled(!custom);
1135 marginsModule->topUnit->setEnabled(!custom);
1137 marginsModule->bottomL->setEnabled(!custom);
1138 marginsModule->bottomLE->setEnabled(!custom);
1139 marginsModule->bottomUnit->setEnabled(!custom);
1141 marginsModule->innerL->setEnabled(!custom);
1142 marginsModule->innerLE->setEnabled(!custom);
1143 marginsModule->innerUnit->setEnabled(!custom);
1145 marginsModule->outerL->setEnabled(!custom);
1146 marginsModule->outerLE->setEnabled(!custom);
1147 marginsModule->outerUnit->setEnabled(!custom);
1149 marginsModule->headheightL->setEnabled(!custom);
1150 marginsModule->headheightLE->setEnabled(!custom);
1151 marginsModule->headheightUnit->setEnabled(!custom);
1153 marginsModule->headsepL->setEnabled(!custom);
1154 marginsModule->headsepLE->setEnabled(!custom);
1155 marginsModule->headsepUnit->setEnabled(!custom);
1157 marginsModule->footskipL->setEnabled(!custom);
1158 marginsModule->footskipLE->setEnabled(!custom);
1159 marginsModule->footskipUnit->setEnabled(!custom);
1161 bool const enableColSep = !custom &&
1162 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1163 marginsModule->columnsepL->setEnabled(enableColSep);
1164 marginsModule->columnsepLE->setEnabled(enableColSep);
1165 marginsModule->columnsepUnit->setEnabled(enableColSep);
1169 void GuiDocument::xetexChanged(bool xetex)
1172 updateDefaultFormat();
1173 langModule->encodingCO->setEnabled(!xetex &&
1174 !langModule->defaultencodingRB->isChecked());
1175 langModule->defaultencodingRB->setEnabled(!xetex);
1176 langModule->otherencodingRB->setEnabled(!xetex);
1178 fontModule->fontsDefaultCO->setEnabled(!xetex);
1179 fontModule->fontsDefaultLA->setEnabled(!xetex);
1180 fontModule->cjkFontLE->setEnabled(!xetex);
1181 fontModule->cjkFontLA->setEnabled(!xetex);
1184 font = tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1185 bool scaleable = providesScale(font);
1186 fontModule->scaleSansSB->setEnabled(scaleable);
1187 fontModule->scaleSansLA->setEnabled(scaleable);
1189 font = tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1190 scaleable = providesScale(font);
1191 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1192 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1194 font = tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1195 fontModule->fontScCB->setEnabled(providesSC(font));
1196 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1200 void GuiDocument::updateFontsize(string const & items, string const & sel)
1202 fontModule->fontsizeCO->clear();
1203 fontModule->fontsizeCO->addItem(qt_("Default"));
1205 for (int n = 0; !token(items,'|',n).empty(); ++n)
1206 fontModule->fontsizeCO->
1207 addItem(toqstr(token(items,'|',n)));
1209 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1210 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1211 fontModule->fontsizeCO->setCurrentIndex(n);
1218 void GuiDocument::updateFontlist()
1220 fontModule->fontsRomanCO->clear();
1221 fontModule->fontsSansCO->clear();
1222 fontModule->fontsTypewriterCO->clear();
1224 // With XeTeX, we have access to all system fonts, but not the LaTeX fonts
1225 if (outputModule->xetexCB->isChecked()) {
1226 fontModule->fontsRomanCO->addItem(qt_("Default"));
1227 fontModule->fontsSansCO->addItem(qt_("Default"));
1228 fontModule->fontsTypewriterCO->addItem(qt_("Default"));
1230 QFontDatabase fontdb;
1231 QStringList families(fontdb.families());
1232 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
1233 fontModule->fontsRomanCO->addItem(*it);
1234 fontModule->fontsSansCO->addItem(*it);
1235 fontModule->fontsTypewriterCO->addItem(*it);
1240 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
1241 QString font = qt_(tex_fonts_roman_gui[n]);
1242 if (!isFontAvailable(tex_fonts_roman[n]))
1243 font += qt_(" (not installed)");
1244 fontModule->fontsRomanCO->addItem(font);
1246 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
1247 QString font = qt_(tex_fonts_sans_gui[n]);
1248 if (!isFontAvailable(tex_fonts_sans[n]))
1249 font += qt_(" (not installed)");
1250 fontModule->fontsSansCO->addItem(font);
1252 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
1253 QString font = qt_(tex_fonts_monospaced_gui[n]);
1254 if (!isFontAvailable(tex_fonts_monospaced[n]))
1255 font += qt_(" (not installed)");
1256 fontModule->fontsTypewriterCO->addItem(font);
1261 void GuiDocument::romanChanged(int item)
1263 if (outputModule->xetexCB->isChecked())
1265 string const font = tex_fonts_roman[item];
1266 fontModule->fontScCB->setEnabled(providesSC(font));
1267 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1271 void GuiDocument::sansChanged(int item)
1273 if (outputModule->xetexCB->isChecked())
1275 string const font = tex_fonts_sans[item];
1276 bool scaleable = providesScale(font);
1277 fontModule->scaleSansSB->setEnabled(scaleable);
1278 fontModule->scaleSansLA->setEnabled(scaleable);
1282 void GuiDocument::ttChanged(int item)
1284 if (outputModule->xetexCB->isChecked())
1286 string const font = tex_fonts_monospaced[item];
1287 bool scaleable = providesScale(font);
1288 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1289 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1293 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1296 pageLayoutModule->pagestyleCO->clear();
1297 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1299 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1300 string style = token(items, '|', n);
1301 QString style_gui = qt_(style);
1302 pagestyles.push_back(pair<string, QString>(style, style_gui));
1303 pageLayoutModule->pagestyleCO->addItem(style_gui);
1306 if (sel == "default") {
1307 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1313 for (size_t i = 0; i < pagestyles.size(); ++i)
1314 if (pagestyles[i].first == sel)
1315 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1318 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1322 void GuiDocument::browseLayout()
1324 QString const label1 = qt_("Layouts|#o#O");
1325 QString const dir1 = toqstr(lyxrc.document_path);
1326 QStringList const filter(qt_("LyX Layout (*.layout)"));
1327 QString file = browseRelFile(QString(), bufferFilepath(),
1328 qt_("Local layout file"), filter, false,
1331 if (!file.endsWith(".layout"))
1334 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1335 fromqstr(bufferFilepath()));
1337 int const ret = Alert::prompt(_("Local layout file"),
1338 _("The layout file you have selected is a local layout\n"
1339 "file, not one in the system or user directory. Your\n"
1340 "document may not work with this layout if you do not\n"
1341 "keep the layout file in the document directory."),
1342 1, 1, _("&Set Layout"), _("&Cancel"));
1346 // load the layout file
1347 LayoutFileList & bcl = LayoutFileList::get();
1348 string classname = layoutFile.onlyFileName();
1349 // this will update an existing layout if that layout has been loaded before.
1350 LayoutFileIndex name = bcl.addLocalLayout(
1351 classname.substr(0, classname.size() - 7),
1352 layoutFile.onlyPath().absFilename());
1355 Alert::error(_("Error"),
1356 _("Unable to read local layout file."));
1360 // do not trigger classChanged if there is no change.
1361 if (latexModule->classCO->currentText() == toqstr(name))
1365 int idx = latexModule->classCO->findText(toqstr(name));
1367 classes_model_.insertRow(0, toqstr(name), name);
1368 latexModule->classCO->setCurrentIndex(0);
1370 latexModule->classCO->setCurrentIndex(idx);
1376 void GuiDocument::browseMaster()
1378 QString const title = qt_("Select master document");
1379 QString const dir1 = toqstr(lyxrc.document_path);
1380 QString const old = latexModule->childDocLE->text();
1381 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1382 QStringList const filter(qt_("LyX Files (*.lyx)"));
1383 QString file = browseRelFile(old, docpath, title, filter, false,
1384 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1386 latexModule->childDocLE->setText(file);
1390 void GuiDocument::classChanged()
1392 int idx = latexModule->classCO->currentIndex();
1395 string const classname = classes_model_.getIDString(idx);
1397 // check whether the selected modules have changed.
1398 bool modules_changed = false;
1399 unsigned int const srows = selectedModel()->rowCount();
1400 if (srows != bp_.getModules().size())
1401 modules_changed = true;
1403 list<string>::const_iterator mit = bp_.getModules().begin();
1404 list<string>::const_iterator men = bp_.getModules().end();
1405 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1406 if (selectedModel()->getIDString(i) != *mit) {
1407 modules_changed = true;
1412 if (modules_changed || lyxrc.auto_reset_options) {
1413 if (applyPB->isEnabled()) {
1414 int const ret = Alert::prompt(_("Unapplied changes"),
1415 _("Some changes in the dialog were not yet applied.\n"
1416 "If you do not apply now, they will be lost after this action."),
1417 1, 1, _("&Apply"), _("&Dismiss"));
1423 // We load the TextClass as soon as it is selected. This is
1424 // necessary so that other options in the dialog can be updated
1425 // according to the new class. Note, however, that, if you use
1426 // the scroll wheel when sitting on the combo box, we'll load a
1427 // lot of TextClass objects very quickly....
1428 if (!bp_.setBaseClass(classname)) {
1429 Alert::error(_("Error"), _("Unable to set document class."));
1432 if (lyxrc.auto_reset_options)
1433 bp_.useClassDefaults();
1435 // With the introduction of modules came a distinction between the base
1436 // class and the document class. The former corresponds to the main layout
1437 // file; the latter is that plus the modules (or the document-specific layout,
1438 // or whatever else there could be). Our parameters come from the document
1439 // class. So when we set the base class, we also need to recreate the document
1440 // class. Otherwise, we still have the old one.
1441 bp_.makeDocumentClass();
1447 // This is an insanely complicated attempt to make this sort of thing
1448 // work with RTL languages.
1449 docstring formatStrVec(vector<string> const & v, docstring const & s)
1451 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1455 return from_utf8(v[0]);
1456 if (v.size() == 2) {
1457 docstring retval = _("%1$s and %2$s");
1458 retval = subst(retval, _("and"), s);
1459 return bformat(retval, from_utf8(v[0]), from_utf8(v[1]));
1461 // The idea here is to format all but the last two items...
1462 int const vSize = v.size();
1463 docstring t2 = _("%1$s, %2$s");
1464 docstring retval = from_utf8(v[0]);
1465 for (int i = 1; i < vSize - 2; ++i)
1466 retval = bformat(t2, retval, from_utf8(v[i]));
1467 //...and then to plug them, and the last two, into this schema
1468 docstring t = _("%1$s, %2$s, and %3$s");
1469 t = subst(t, _("and"), s);
1470 return bformat(t, retval, from_utf8(v[vSize - 2]), from_utf8(v[vSize - 1]));
1473 vector<string> idsToNames(vector<string> const & idList)
1475 vector<string> retval;
1476 vector<string>::const_iterator it = idList.begin();
1477 vector<string>::const_iterator end = idList.end();
1478 for (; it != end; ++it) {
1479 LyXModule const * const mod = moduleList[*it];
1481 retval.push_back(*it + " (Unavailable)");
1483 retval.push_back(mod->getName());
1490 void GuiDocument::modulesToParams(BufferParams & bp)
1492 // update list of loaded modules
1493 bp.clearLayoutModules();
1494 int const srows = modules_sel_model_.rowCount();
1495 for (int i = 0; i < srows; ++i)
1496 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1498 // update the list of removed modules
1499 bp.clearRemovedModules();
1500 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
1501 list<string>::const_iterator rit = reqmods.begin();
1502 list<string>::const_iterator ren = reqmods.end();
1504 // check each of the default modules
1505 for (; rit != ren; rit++) {
1506 list<string>::const_iterator mit = bp.getModules().begin();
1507 list<string>::const_iterator men = bp.getModules().end();
1509 for (; mit != men; mit++) {
1516 // the module isn't present so must have been removed by the user
1517 bp.addRemovedModule(*rit);
1522 void GuiDocument::modulesChanged()
1524 modulesToParams(bp_);
1525 bp_.makeDocumentClass();
1530 void GuiDocument::updateModuleInfo()
1532 selectionManager->update();
1534 //Module description
1535 bool const focus_on_selected = selectionManager->selectedFocused();
1536 QListView const * const lv =
1537 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1538 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1539 modulesModule->infoML->document()->clear();
1542 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1543 GuiIdListModel const & id_model =
1544 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1545 string const modName = id_model.getIDString(idx.row());
1546 docstring desc = getModuleDescription(modName);
1548 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
1549 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1552 desc += _("Module provided by document class.");
1555 vector<string> pkglist = getPackageList(modName);
1556 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1557 if (!pkgdesc.empty()) {
1560 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1563 pkglist = getRequiredList(modName);
1564 if (!pkglist.empty()) {
1565 vector<string> const reqdescs = idsToNames(pkglist);
1566 pkgdesc = formatStrVec(reqdescs, _("or"));
1569 desc += bformat(_("Module required: %1$s."), pkgdesc);
1572 pkglist = getExcludedList(modName);
1573 if (!pkglist.empty()) {
1574 vector<string> const reqdescs = idsToNames(pkglist);
1575 pkgdesc = formatStrVec(reqdescs, _( "and"));
1578 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1581 if (!isModuleAvailable(modName)) {
1584 desc += _("WARNING: Some required packages are unavailable!");
1587 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1591 void GuiDocument::updateNumbering()
1593 DocumentClass const & tclass = documentClass();
1595 numberingModule->tocTW->setUpdatesEnabled(false);
1596 numberingModule->tocTW->clear();
1598 int const depth = numberingModule->depthSL->value();
1599 int const toc = numberingModule->tocSL->value();
1600 QString const no = qt_("No");
1601 QString const yes = qt_("Yes");
1602 QTreeWidgetItem * item = 0;
1604 DocumentClass::const_iterator lit = tclass.begin();
1605 DocumentClass::const_iterator len = tclass.end();
1606 for (; lit != len; ++lit) {
1607 int const toclevel = lit->toclevel;
1608 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1609 item = new QTreeWidgetItem(numberingModule->tocTW);
1610 item->setText(0, toqstr(translateIfPossible(lit->name())));
1611 item->setText(1, (toclevel <= depth) ? yes : no);
1612 item->setText(2, (toclevel <= toc) ? yes : no);
1616 numberingModule->tocTW->setUpdatesEnabled(true);
1617 numberingModule->tocTW->update();
1621 void GuiDocument::updateDefaultFormat()
1623 // make a copy in order to consider unapplied changes
1624 Buffer * tmpbuf = const_cast<Buffer *>(&buffer());
1625 tmpbuf->params().useXetex = outputModule->xetexCB->isChecked();
1626 int idx = latexModule->classCO->currentIndex();
1628 string const classname = classes_model_.getIDString(idx);
1629 tmpbuf->params().setBaseClass(classname);
1630 tmpbuf->params().makeDocumentClass();
1632 outputModule->defaultFormatCO->blockSignals(true);
1633 outputModule->defaultFormatCO->clear();
1634 outputModule->defaultFormatCO->addItem(qt_("Default"),
1635 QVariant(QString("default")));
1636 typedef vector<Format const *> Formats;
1637 Formats formats = tmpbuf->exportableFormats(true);
1638 Formats::const_iterator cit = formats.begin();
1639 Formats::const_iterator end = formats.end();
1640 for (; cit != end; ++cit)
1641 outputModule->defaultFormatCO->addItem(qt_((*cit)->prettyname()),
1642 QVariant(toqstr((*cit)->name())));
1643 outputModule->defaultFormatCO->blockSignals(false);
1647 void GuiDocument::applyView()
1650 preambleModule->apply(bp_);
1653 bp_.setCiteEngine(ENGINE_BASIC);
1655 if (biblioModule->citeNatbibRB->isChecked()) {
1656 bool const use_numerical_citations =
1657 biblioModule->citeStyleCO->currentIndex();
1658 if (use_numerical_citations)
1659 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1661 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1663 } else if (biblioModule->citeJurabibRB->isChecked())
1664 bp_.setCiteEngine(ENGINE_JURABIB);
1667 biblioModule->bibtopicCB->isChecked();
1669 // language & quotes
1670 if (langModule->defaultencodingRB->isChecked()) {
1671 bp_.inputenc = "auto";
1673 int i = langModule->encodingCO->currentIndex();
1675 bp_.inputenc = "default";
1677 QString const enc_gui =
1678 langModule->encodingCO->currentText();
1679 Encodings::const_iterator it = encodings.begin();
1680 Encodings::const_iterator const end = encodings.end();
1682 for (; it != end; ++it) {
1683 if (qt_(it->guiName()) == enc_gui) {
1684 bp_.inputenc = it->latexName();
1690 // should not happen
1691 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1692 bp_.inputenc = "default";
1697 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1698 switch (langModule->quoteStyleCO->currentIndex()) {
1700 lga = InsetQuotes::EnglishQuotes;
1703 lga = InsetQuotes::SwedishQuotes;
1706 lga = InsetQuotes::GermanQuotes;
1709 lga = InsetQuotes::PolishQuotes;
1712 lga = InsetQuotes::FrenchQuotes;
1715 lga = InsetQuotes::DanishQuotes;
1718 bp_.quotes_language = lga;
1720 QString const lang = langModule->languageCO->itemData(
1721 langModule->languageCO->currentIndex()).toString();
1722 bp_.language = languages.getLanguage(fromqstr(lang));
1725 if (bp_.documentClass().hasTocLevels()) {
1726 bp_.tocdepth = numberingModule->tocSL->value();
1727 bp_.secnumdepth = numberingModule->depthSL->value();
1731 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1732 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1733 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1734 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1737 bp_.graphicsDriver =
1738 tex_graphics[latexModule->psdriverCO->currentIndex()];
1741 int idx = latexModule->classCO->currentIndex();
1743 string const classname = classes_model_.getIDString(idx);
1744 bp_.setBaseClass(classname);
1748 modulesToParams(bp_);
1750 if (mathsModule->amsautoCB->isChecked()) {
1751 bp_.use_amsmath = BufferParams::package_auto;
1753 if (mathsModule->amsCB->isChecked())
1754 bp_.use_amsmath = BufferParams::package_on;
1756 bp_.use_amsmath = BufferParams::package_off;
1759 if (mathsModule->esintautoCB->isChecked())
1760 bp_.use_esint = BufferParams::package_auto;
1762 if (mathsModule->esintCB->isChecked())
1763 bp_.use_esint = BufferParams::package_on;
1765 bp_.use_esint = BufferParams::package_off;
1768 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1769 bp_.pagestyle = "default";
1771 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1772 for (size_t i = 0; i != pagestyles.size(); ++i)
1773 if (pagestyles[i].second == style_gui)
1774 bp_.pagestyle = pagestyles[i].first;
1777 switch (textLayoutModule->lspacingCO->currentIndex()) {
1779 bp_.spacing().set(Spacing::Single);
1782 bp_.spacing().set(Spacing::Onehalf);
1785 bp_.spacing().set(Spacing::Double);
1788 bp_.spacing().set(Spacing::Other,
1789 fromqstr(textLayoutModule->lspacingLE->text()));
1793 if (textLayoutModule->twoColumnCB->isChecked())
1798 // text should have passed validation
1799 bp_.listings_params =
1800 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1802 if (textLayoutModule->indentRB->isChecked())
1803 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1805 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1807 switch (textLayoutModule->skipCO->currentIndex()) {
1809 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1812 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1815 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1820 widgetsToLength(textLayoutModule->skipLE,
1821 textLayoutModule->skipLengthCO)
1827 // DocumentDefskipCB assures that this never happens
1828 // so Assert then !!! - jbl
1829 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1834 fromqstr(latexModule->optionsLE->text());
1836 bp_.use_default_options =
1837 latexModule->defaultOptionsCB->isChecked();
1839 if (latexModule->childDocGB->isChecked())
1841 fromqstr(latexModule->childDocLE->text());
1843 bp_.master = string();
1845 bp_.float_placement = floatModule->get();
1848 bp_.defaultOutputFormat = fromqstr(outputModule->defaultFormatCO->itemData(
1849 outputModule->defaultFormatCO->currentIndex()).toString());
1851 bool const xetex = outputModule->xetexCB->isChecked();
1852 bp_.useXetex = xetex;
1856 if (fontModule->fontsRomanCO->currentIndex() == 0)
1857 bp_.fontsRoman = "default";
1860 fromqstr(fontModule->fontsRomanCO->currentText());
1862 if (fontModule->fontsSansCO->currentIndex() == 0)
1863 bp_.fontsSans = "default";
1866 fromqstr(fontModule->fontsSansCO->currentText());
1868 if (fontModule->fontsTypewriterCO->currentIndex() == 0)
1869 bp_.fontsTypewriter = "default";
1871 bp_.fontsTypewriter =
1872 fromqstr(fontModule->fontsTypewriterCO->currentText());
1875 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1878 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1880 bp_.fontsTypewriter =
1881 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1885 fromqstr(fontModule->cjkFontLE->text());
1887 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1889 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1891 bp_.fontsSC = fontModule->fontScCB->isChecked();
1893 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1896 bp_.fontsDefaultFamily = "default";
1898 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1899 fontModule->fontsDefaultCO->currentIndex()];
1901 if (fontModule->fontsizeCO->currentIndex() == 0)
1902 bp_.fontsize = "default";
1905 fromqstr(fontModule->fontsizeCO->currentText());
1908 bp_.papersize = PAPER_SIZE(
1909 pageLayoutModule->papersizeCO->currentIndex());
1911 // custom, A3, B3 and B4 paper sizes need geometry
1912 int psize = pageLayoutModule->papersizeCO->currentIndex();
1913 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1915 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1916 pageLayoutModule->paperwidthUnitCO);
1918 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1919 pageLayoutModule->paperheightUnitCO);
1921 if (pageLayoutModule->facingPagesCB->isChecked())
1922 bp_.sides = TwoSides;
1924 bp_.sides = OneSide;
1926 if (pageLayoutModule->landscapeRB->isChecked())
1927 bp_.orientation = ORIENTATION_LANDSCAPE;
1929 bp_.orientation = ORIENTATION_PORTRAIT;
1932 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1935 Ui::MarginsUi const * m = marginsModule;
1937 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1938 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1939 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1940 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1941 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1942 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1943 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1944 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1946 branchesModule->apply(bp_);
1949 PDFOptions & pdf = bp_.pdfoptions();
1950 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1951 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1952 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1953 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1954 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1956 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1957 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1958 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1959 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1961 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1962 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1963 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1964 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1966 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1967 if (pdfSupportModule->fullscreenCB->isChecked())
1968 pdf.pagemode = pdf.pagemode_fullscreen;
1970 pdf.pagemode.clear();
1971 pdf.quoted_options = pdf.quoted_options_check(
1972 fromqstr(pdfSupportModule->optionsLE->text()));
1976 void GuiDocument::paramsToDialog()
1978 // set the default unit
1979 Length::UNIT const defaultUnit = Length::defaultUnit();
1982 preambleModule->update(bp_, id());
1985 biblioModule->citeDefaultRB->setChecked(
1986 bp_.citeEngine() == ENGINE_BASIC);
1988 biblioModule->citeNatbibRB->setChecked(
1989 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1990 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1992 biblioModule->citeStyleCO->setCurrentIndex(
1993 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1995 biblioModule->citeJurabibRB->setChecked(
1996 bp_.citeEngine() == ENGINE_JURABIB);
1998 biblioModule->bibtopicCB->setChecked(
2001 // language & quotes
2002 int const pos = langModule->languageCO->findData(toqstr(
2003 bp_.language->lang()));
2004 langModule->languageCO->setCurrentIndex(pos);
2006 langModule->quoteStyleCO->setCurrentIndex(
2007 bp_.quotes_language);
2009 bool default_enc = true;
2010 if (bp_.inputenc != "auto") {
2011 default_enc = false;
2012 if (bp_.inputenc == "default") {
2013 langModule->encodingCO->setCurrentIndex(0);
2016 Encodings::const_iterator it = encodings.begin();
2017 Encodings::const_iterator const end = encodings.end();
2018 for (; it != end; ++it) {
2019 if (it->latexName() == bp_.inputenc) {
2020 enc_gui = it->guiName();
2024 int const i = langModule->encodingCO->findText(
2027 langModule->encodingCO->setCurrentIndex(i);
2029 // unknown encoding. Set to default.
2033 langModule->defaultencodingRB->setChecked(default_enc);
2034 langModule->otherencodingRB->setChecked(!default_enc);
2037 int const min_toclevel = documentClass().min_toclevel();
2038 int const max_toclevel = documentClass().max_toclevel();
2039 if (documentClass().hasTocLevels()) {
2040 numberingModule->setEnabled(true);
2041 numberingModule->depthSL->setMinimum(min_toclevel - 1);
2042 numberingModule->depthSL->setMaximum(max_toclevel);
2043 numberingModule->depthSL->setValue(bp_.secnumdepth);
2044 numberingModule->tocSL->setMaximum(min_toclevel - 1);
2045 numberingModule->tocSL->setMaximum(max_toclevel);
2046 numberingModule->tocSL->setValue(bp_.tocdepth);
2049 numberingModule->setEnabled(false);
2050 numberingModule->tocTW->clear();
2054 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
2055 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
2056 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
2057 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
2058 bulletsModule->init();
2061 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
2063 latexModule->psdriverCO->setCurrentIndex(nitem);
2066 mathsModule->amsCB->setChecked(
2067 bp_.use_amsmath == BufferParams::package_on);
2068 mathsModule->amsautoCB->setChecked(
2069 bp_.use_amsmath == BufferParams::package_auto);
2071 mathsModule->esintCB->setChecked(
2072 bp_.use_esint == BufferParams::package_on);
2073 mathsModule->esintautoCB->setChecked(
2074 bp_.use_esint == BufferParams::package_auto);
2076 switch (bp_.spacing().getSpace()) {
2077 case Spacing::Other: nitem = 3; break;
2078 case Spacing::Double: nitem = 2; break;
2079 case Spacing::Onehalf: nitem = 1; break;
2080 case Spacing::Default: case Spacing::Single: nitem = 0; break;
2084 string const & layoutID = bp_.baseClassID();
2085 setLayoutComboByIDString(layoutID);
2087 updatePagestyle(documentClass().opt_pagestyle(),
2090 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
2091 if (bp_.spacing().getSpace() == Spacing::Other) {
2092 textLayoutModule->lspacingLE->setText(
2093 toqstr(bp_.spacing().getValueAsString()));
2097 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
2098 textLayoutModule->indentRB->setChecked(true);
2100 textLayoutModule->skipRB->setChecked(true);
2103 switch (bp_.getDefSkip().kind()) {
2104 case VSpace::SMALLSKIP:
2107 case VSpace::MEDSKIP:
2110 case VSpace::BIGSKIP:
2113 case VSpace::LENGTH:
2116 string const length = bp_.getDefSkip().asLyXCommand();
2117 lengthToWidgets(textLayoutModule->skipLE,
2118 textLayoutModule->skipLengthCO,
2119 length, defaultUnit);
2126 textLayoutModule->skipCO->setCurrentIndex(skip);
2129 textLayoutModule->twoColumnCB->setChecked(
2132 // break listings_params to multiple lines
2134 InsetListingsParams(bp_.listings_params).separatedParams();
2135 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2137 if (!bp_.options.empty()) {
2138 latexModule->optionsLE->setText(
2139 toqstr(bp_.options));
2141 latexModule->optionsLE->setText(QString());
2145 latexModule->defaultOptionsCB->setChecked(
2146 bp_.use_default_options);
2147 updateSelectedModules();
2148 selectionManager->updateProvidedModules(
2149 bp_.baseClass()->providedModules());
2150 selectionManager->updateExcludedModules(
2151 bp_.baseClass()->excludedModules());
2153 if (!documentClass().options().empty()) {
2154 latexModule->defaultOptionsLE->setText(
2155 toqstr(documentClass().options()));
2157 latexModule->defaultOptionsLE->setText(
2158 toqstr(_("[No options predefined]")));
2161 latexModule->defaultOptionsLE->setEnabled(
2162 bp_.use_default_options
2163 && !documentClass().options().empty());
2165 latexModule->defaultOptionsCB->setEnabled(
2166 !documentClass().options().empty());
2168 if (!bp_.master.empty()) {
2169 latexModule->childDocGB->setChecked(true);
2170 latexModule->childDocLE->setText(
2171 toqstr(bp_.master));
2173 latexModule->childDocLE->setText(QString());
2174 latexModule->childDocGB->setChecked(false);
2177 floatModule->set(bp_.float_placement);
2180 // update combobox with formats
2181 updateDefaultFormat();
2182 int index = outputModule->defaultFormatCO->findData(toqstr(
2183 bp_.defaultOutputFormat));
2184 // set to default if format is not found
2187 outputModule->defaultFormatCO->setCurrentIndex(index);
2188 outputModule->xetexCB->setEnabled(bp_.baseClass()->outputType() == lyx::LATEX);
2189 outputModule->xetexCB->setChecked(
2190 bp_.baseClass()->outputType() == lyx::LATEX && bp_.useXetex);
2193 updateFontsize(documentClass().opt_fontsize(),
2197 for (int i = 0; i < fontModule->fontsRomanCO->count(); ++i) {
2198 if (fontModule->fontsRomanCO->itemText(i) == toqstr(bp_.fontsRoman)) {
2199 fontModule->fontsRomanCO->setCurrentIndex(i);
2204 for (int i = 0; i < fontModule->fontsSansCO->count(); ++i) {
2205 if (fontModule->fontsSansCO->itemText(i) == toqstr(bp_.fontsSans)) {
2206 fontModule->fontsSansCO->setCurrentIndex(i);
2210 for (int i = 0; i < fontModule->fontsTypewriterCO->count(); ++i) {
2211 if (fontModule->fontsTypewriterCO->itemText(i) ==
2212 toqstr(bp_.fontsTypewriter)) {
2213 fontModule->fontsTypewriterCO->setCurrentIndex(i);
2218 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2220 fontModule->fontsRomanCO->setCurrentIndex(n);
2224 n = findToken(tex_fonts_sans, bp_.fontsSans);
2226 fontModule->fontsSansCO->setCurrentIndex(n);
2230 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2232 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2237 if (!bp_.fontsCJK.empty())
2238 fontModule->cjkFontLE->setText(
2239 toqstr(bp_.fontsCJK));
2241 fontModule->cjkFontLE->setText(QString());
2243 fontModule->fontScCB->setChecked(bp_.fontsSC);
2244 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2245 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2246 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2248 int nn = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2250 fontModule->fontsDefaultCO->setCurrentIndex(nn);
2253 bool const extern_geometry =
2254 documentClass().provides("geometry");
2255 int const psize = bp_.papersize;
2256 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2257 setCustomPapersize(!extern_geometry && psize);
2258 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
2260 bool const landscape =
2261 bp_.orientation == ORIENTATION_LANDSCAPE;
2262 pageLayoutModule->landscapeRB->setChecked(landscape);
2263 pageLayoutModule->portraitRB->setChecked(!landscape);
2264 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
2265 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
2267 pageLayoutModule->facingPagesCB->setChecked(
2268 bp_.sides == TwoSides);
2271 lengthToWidgets(pageLayoutModule->paperwidthLE,
2272 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2274 lengthToWidgets(pageLayoutModule->paperheightLE,
2275 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2278 Ui::MarginsUi * m = marginsModule;
2280 setMargins(!bp_.use_geometry);
2282 lengthToWidgets(m->topLE, m->topUnit,
2283 bp_.topmargin, defaultUnit);
2285 lengthToWidgets(m->bottomLE, m->bottomUnit,
2286 bp_.bottommargin, defaultUnit);
2288 lengthToWidgets(m->innerLE, m->innerUnit,
2289 bp_.leftmargin, defaultUnit);
2291 lengthToWidgets(m->outerLE, m->outerUnit,
2292 bp_.rightmargin, defaultUnit);
2294 lengthToWidgets(m->headheightLE, m->headheightUnit,
2295 bp_.headheight, defaultUnit);
2297 lengthToWidgets(m->headsepLE, m->headsepUnit,
2298 bp_.headsep, defaultUnit);
2300 lengthToWidgets(m->footskipLE, m->footskipUnit,
2301 bp_.footskip, defaultUnit);
2303 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2304 bp_.columnsep, defaultUnit);
2306 branchesModule->update(bp_);
2309 PDFOptions const & pdf = bp_.pdfoptions();
2310 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2311 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2312 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2313 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2314 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2316 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2317 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2318 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2320 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2322 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2323 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2324 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2325 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2327 nn = findToken(backref_opts, pdf.backref);
2329 pdfSupportModule->backrefCO->setCurrentIndex(nn);
2331 pdfSupportModule->fullscreenCB->setChecked
2332 (pdf.pagemode == pdf.pagemode_fullscreen);
2334 pdfSupportModule->optionsLE->setText(
2335 toqstr(pdf.quoted_options));
2337 // Make sure that the bc is in the INITIAL state
2338 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
2343 void GuiDocument::saveDocDefault()
2345 // we have to apply the params first
2351 void GuiDocument::updateAvailableModules()
2353 modules_av_model_.clear();
2354 list<modInfoStruct> const & modInfoList = getModuleInfo();
2355 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2356 list<modInfoStruct>::const_iterator men = modInfoList.end();
2357 for (int i = 0; mit != men; ++mit, ++i)
2358 modules_av_model_.insertRow(i, mit->name, mit->id,
2363 void GuiDocument::updateSelectedModules()
2365 modules_sel_model_.clear();
2366 list<modInfoStruct> const selModList = getSelectedModules();
2367 list<modInfoStruct>::const_iterator mit = selModList.begin();
2368 list<modInfoStruct>::const_iterator men = selModList.end();
2369 for (int i = 0; mit != men; ++mit, ++i)
2370 modules_sel_model_.insertRow(i, mit->name, mit->id,
2375 void GuiDocument::updateContents()
2377 // Nothing to do here as the document settings is not cursor dependant.
2382 void GuiDocument::useClassDefaults()
2384 if (applyPB->isEnabled()) {
2385 int const ret = Alert::prompt(_("Unapplied changes"),
2386 _("Some changes in the dialog were not yet applied.\n"
2387 "If you do not apply now, they will be lost after this action."),
2388 1, 1, _("&Apply"), _("&Dismiss"));
2393 int idx = latexModule->classCO->currentIndex();
2394 string const classname = classes_model_.getIDString(idx);
2395 if (!bp_.setBaseClass(classname)) {
2396 Alert::error(_("Error"), _("Unable to set document class."));
2399 bp_.useClassDefaults();
2404 void GuiDocument::setLayoutComboByIDString(string const & idString)
2406 int idx = classes_model_.findIDString(idString);
2408 Alert::warning(_("Can't set layout!"),
2409 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2411 latexModule->classCO->setCurrentIndex(idx);
2415 bool GuiDocument::isValid()
2417 return validateListingsParameters().isEmpty()
2418 && (textLayoutModule->skipCO->currentIndex() != 3
2419 || !textLayoutModule->skipLE->text().isEmpty());
2423 char const * const GuiDocument::fontfamilies[5] = {
2424 "default", "rmdefault", "sfdefault", "ttdefault", ""
2428 char const * GuiDocument::fontfamilies_gui[5] = {
2429 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2433 bool GuiDocument::initialiseParams(string const &)
2435 BufferView const * view = bufferview();
2437 bp_ = BufferParams();
2441 bp_ = view->buffer().params();
2443 updateAvailableModules();
2444 //FIXME It'd be nice to make sure here that the selected
2445 //modules are consistent: That required modules are actually
2446 //selected, and that we don't have conflicts. If so, we could
2447 //at least pop up a warning.
2453 void GuiDocument::clearParams()
2455 bp_ = BufferParams();
2459 BufferId GuiDocument::id() const
2461 BufferView const * const view = bufferview();
2462 return view? &view->buffer() : 0;
2466 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2468 return moduleNames_;
2472 list<GuiDocument::modInfoStruct> const
2473 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
2475 LayoutModuleList::const_iterator it = mods.begin();
2476 LayoutModuleList::const_iterator end = mods.end();
2477 list<modInfoStruct> mInfo;
2478 for (; it != end; ++it) {
2481 LyXModule * mod = moduleList[*it];
2484 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2486 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2493 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2495 return makeModuleInfo(params().getModules());
2499 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2501 return makeModuleInfo(params().baseClass()->providedModules());
2505 DocumentClass const & GuiDocument::documentClass() const
2507 return bp_.documentClass();
2511 static void dispatch_bufferparams(Dialog const & dialog,
2512 BufferParams const & bp, FuncCode lfun)
2515 ss << "\\begin_header\n";
2517 ss << "\\end_header\n";
2518 dialog.dispatch(FuncRequest(lfun, ss.str()));
2522 void GuiDocument::dispatchParams()
2524 // This must come first so that a language change is correctly noticed
2527 // Apply the BufferParams. Note that this will set the base class
2528 // and then update the buffer's layout.
2529 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2531 if (!params().master.empty()) {
2532 FileName const master_file = support::makeAbsPath(params().master,
2533 support::onlyPath(buffer().absFileName()));
2534 if (isLyXFilename(master_file.absFilename())) {
2535 Buffer * master = checkAndLoadLyXFile(master_file);
2537 if (master->isChild(const_cast<Buffer *>(&buffer())))
2538 const_cast<Buffer &>(buffer()).setParent(master);
2540 Alert::warning(_("Assigned master does not include this file"),
2541 bformat(_("You must include this file in the document\n"
2542 "'%1$s' in order to use the master document\n"
2543 "feature."), from_utf8(params().master)));
2545 Alert::warning(_("Could not load master"),
2546 bformat(_("The master document '%1$s'\n"
2547 "could not be loaded."),
2548 from_utf8(params().master)));
2552 // Generate the colours requested by each new branch.
2553 BranchList & branchlist = params().branchlist();
2554 if (!branchlist.empty()) {
2555 BranchList::const_iterator it = branchlist.begin();
2556 BranchList::const_iterator const end = branchlist.end();
2557 for (; it != end; ++it) {
2558 docstring const & current_branch = it->branch();
2559 Branch const * branch = branchlist.find(current_branch);
2560 string const x11hexname = X11hexname(branch->color());
2561 // display the new color
2562 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2563 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2566 // Open insets of selected branches, close deselected ones
2567 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2570 // FIXME: If we used an LFUN, we would not need those two lines:
2571 BufferView * bv = const_cast<BufferView *>(bufferview());
2572 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2576 void GuiDocument::setLanguage() const
2578 Language const * const newL = bp_.language;
2579 if (buffer().params().language == newL)
2582 string const & lang_name = newL->lang();
2583 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2587 void GuiDocument::saveAsDefault() const
2589 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2593 bool GuiDocument::isFontAvailable(string const & font) const
2595 if (font == "default" || font == "cmr"
2596 || font == "cmss" || font == "cmtt")
2597 // these are standard
2599 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2600 return LaTeXFeatures::isAvailable("lmodern");
2601 if (font == "times" || font == "palatino"
2602 || font == "helvet" || font == "courier")
2603 return LaTeXFeatures::isAvailable("psnfss");
2604 if (font == "cmbr" || font == "cmtl")
2605 return LaTeXFeatures::isAvailable("cmbright");
2606 if (font == "utopia")
2607 return LaTeXFeatures::isAvailable("utopia")
2608 || LaTeXFeatures::isAvailable("fourier");
2609 if (font == "beraserif" || font == "berasans"
2610 || font == "beramono")
2611 return LaTeXFeatures::isAvailable("bera");
2612 return LaTeXFeatures::isAvailable(font);
2616 bool GuiDocument::providesOSF(string const & font) const
2618 if (outputModule->xetexCB->isChecked())
2619 // FIXME: we should check if the fonts really
2620 // have OSF support. But how?
2623 return isFontAvailable("eco");
2624 if (font == "palatino")
2625 return isFontAvailable("mathpazo");
2630 bool GuiDocument::providesSC(string const & font) const
2632 if (outputModule->xetexCB->isChecked())
2634 if (font == "palatino")
2635 return isFontAvailable("mathpazo");
2636 if (font == "utopia")
2637 return isFontAvailable("fourier");
2642 bool GuiDocument::providesScale(string const & font) const
2644 if (outputModule->xetexCB->isChecked())
2646 return font == "helvet" || font == "luximono"
2647 || font == "berasans" || font == "beramono";
2651 void GuiDocument::loadModuleInfo()
2653 moduleNames_.clear();
2654 LyXModuleList::const_iterator it = moduleList.begin();
2655 LyXModuleList::const_iterator end = moduleList.end();
2656 for (; it != end; ++it) {
2660 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2661 // this is supposed to give us the first sentence of the description
2664 toqstr(translateIfPossible(from_utf8(it->getDescription())));
2665 int const pos = desc.indexOf(".");
2667 desc.truncate(pos + 1);
2668 m.description = desc;
2669 moduleNames_.push_back(m);
2674 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2677 } // namespace frontend
2680 #include "moc_GuiDocument.cpp"